├── .browserslistrc ├── .editorconfig ├── .gitignore ├── .npmignore ├── .npmrc ├── .prettierrc ├── .travis.yml ├── LICENSE ├── babel.config.js ├── common.d.ts ├── package.json ├── readme.md ├── rollup.config.js ├── src ├── _internals.ts ├── amOrPm.ts ├── cookiesToObject.ts ├── countries.ts ├── countryDialCodes.ts ├── debounce.ts ├── dotAccess.ts ├── elementInView.ts ├── emitEvent.ts ├── findIndex.ts ├── flattenStr.ts ├── focusableSelectors.ts ├── forEachValue.ts ├── getAspectRatio.ts ├── getEventPath.ts ├── getFirstFocusableNode.ts ├── getFirstTabbableNode.ts ├── getFocusableNodes.ts ├── getFormFields.ts ├── getFullMonthName.ts ├── getFullWeekday.ts ├── getLastFocusableNode.ts ├── getLastTabbableNode.ts ├── getShortMonthName.ts ├── getShortWeekday.ts ├── getTabbableNodes.ts ├── htmlElements.ts ├── index.ts ├── isArrayLike.ts ├── isObject.ts ├── isPlainObject.ts ├── isPrintableChar.ts ├── looseEqual.ts ├── matchesQuery.ts ├── memoize.ts ├── mimeTypes.ts ├── monthNames.ts ├── objectIsEmpty.ts ├── observeMutations.ts ├── once.ts ├── openExternalWindow.ts ├── parseHTML.ts ├── prefixWithZero.ts ├── pxToRem.ts ├── queryFilter.ts ├── randomHash.ts ├── resetScroll.ts ├── rgbToHex.ts ├── scrollToElem.ts ├── shortMonthNames.ts ├── shortWeekdays.ts ├── sleep.ts ├── slugify.ts ├── smoothScroll.ts ├── swapKeysForValues.ts ├── tabbableSelectors.ts ├── toPx.ts ├── toSnakeCase.ts ├── trapFocus.ts ├── ua.ts ├── uniq.ts ├── unslash.ts ├── unslashEnd.ts ├── unslashStart.ts ├── wait.ts └── weekdays.ts ├── tsconfig.json └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | dist/ 63 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | package-lock=false 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "avoid", 3 | "bracketSpacing": true, 4 | "jsxBracketSameLine": false, 5 | "printWidth": 80, 6 | "proseWrap": "always", 7 | "semi": false, 8 | "singleQuote": true, 9 | "tabWidth": 2, 10 | "trailingComma": "es5", 11 | "useTabs": false 12 | } 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '10' 4 | - '8' 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present Olaolu Olawuyi 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 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | test: { 4 | presets: [ 5 | '@babel/env', 6 | { 7 | spec: true, 8 | modules: false, 9 | forceAllTransforms: true, 10 | useBuiltIns: 'usage', 11 | corejs: { 12 | version: 3, 13 | proposals: true, 14 | }, 15 | }, 16 | ], 17 | plugins: ['@babel/plugin-transform-runtime'], 18 | }, 19 | }, 20 | presets: [ 21 | [ 22 | '@babel/env', 23 | { 24 | loose: true, 25 | modules: false, 26 | }, 27 | ], 28 | ], 29 | plugins: ['@babel/plugin-proposal-object-rest-spread'], 30 | } 31 | -------------------------------------------------------------------------------- /common.d.ts: -------------------------------------------------------------------------------- 1 | declare type ValueOf = T[keyof T] 2 | declare type PlainObject = { 3 | [key: string]: T 4 | } 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mrolaolu/helpers", 3 | "license": "MIT", 4 | "files": [ 5 | "dist", 6 | "common.d.ts" 7 | ], 8 | "version": "0.3.2", 9 | "types": "dist/esm/index.d.ts", 10 | "main": "dist/cjs/index.js", 11 | "module": "dist/esm/index.js", 12 | "jsnext:main": "dist/esm/index.js", 13 | "repository": "whizkydee/helpers", 14 | "description": "Super handy JavaScript utilities for frontend development.", 15 | "author": "Olaolu Olawuyi (https://olaolu.dev)", 16 | "scripts": { 17 | "flush": "del dist", 18 | "build:esm": "rollup -c --environment ESM", 19 | "build:cjs": "rollup -c --environment CJS", 20 | "prepublishOnly": "yarn build", 21 | "build": "yarn flush && yarn build:esm && yarn build:cjs" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.6.4", 25 | "@babel/plugin-proposal-object-rest-spread": "^7.6.2", 26 | "@babel/plugin-transform-runtime": "^7.6.2", 27 | "@babel/preset-env": "^7.6.3", 28 | "@rollup/plugin-typescript": "^4.1.1", 29 | "@types/lodash": "^4.14.149", 30 | "bundlesize": "^0.18.0", 31 | "del-cli": "^3.0.0", 32 | "rollup": "^2.6.1", 33 | "rollup-plugin-babel": "^4.4.0", 34 | "rollup-plugin-commonjs": "^10.1.0", 35 | "rollup-plugin-multi-input": "^1.1.1", 36 | "tsd": "^0.11.0", 37 | "tslib": "^1.11.1", 38 | "typescript": "^3.8.3" 39 | }, 40 | "dependencies": { 41 | "safely-iterate": "^1.0.1" 42 | }, 43 | "keywords": [ 44 | "javascript", 45 | "js", 46 | "functions", 47 | "utility", 48 | "utilities", 49 | "helpers", 50 | "helper functions" 51 | ] 52 | } 53 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # [@mrolaolu/helpers](https://npm.im/@mrolaolu/helpers) 2 | 3 | 🛠 Super handy JavaScript utilities for frontend development. 4 | 5 | **Note:** This is a work in progress and as such is not well documented or 6 | ready-to-use. 7 | 8 | ## Install 9 | 10 | ```sh 11 | $ npm install @mrolaolu/helpers --save 12 | ``` 13 | 14 | ## Usage 15 | 16 | Let's say you want to use the `getFormFields` helper... 17 | 18 | ```ts 19 | import { getFormFields } from '@mrolaolu/helpers' 20 | ``` 21 | 22 | or ... 23 | 24 | ```ts 25 | import getFormFields from '@mrolaolu/helpers/dist/esm/getFormFields' 26 | ``` 27 | 28 | ```ts 29 | const formFields = getFormFields( 30 | document.getElementById('form') as HTMLFormElement 31 | ) 32 | // => { email: hello@test.io, password: Unicorns!, ... } 33 | ``` 34 | 35 | 36 | 37 | > MIT © [olaolu.dev](https://olaolu.dev)  ·  GitHub 38 | > [@whizkydee](https://github.com/whizkydee)  ·  Twitter 39 | > [@mrolaolu](https://twitter.com/mrolaolu) 40 | 41 | 42 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import path from 'path' 2 | import babel from 'rollup-plugin-babel' 3 | import defaultTsConfig from './tsconfig.json' 4 | import multiInput from 'rollup-plugin-multi-input' 5 | import typescript from '@rollup/plugin-typescript' 6 | 7 | const isCommonJS = process.env.CJS 8 | export default { 9 | external: ['safely-iterate'], 10 | input: path.resolve(__dirname, 'src/**.ts'), 11 | plugins: [ 12 | multiInput(), 13 | typescript({ 14 | ...defaultTsConfig.compilerOptions, 15 | ...{ 16 | outDir: isCommonJS ? 'dist/cjs' : 'dist/esm', 17 | exclude: defaultTsConfig.exclude, 18 | }, 19 | }), 20 | babel({ 21 | exclude: 'node_modules/**', 22 | }), 23 | ], 24 | output: { 25 | dir: isCommonJS ? 'dist/cjs' : 'dist/esm', 26 | format: isCommonJS ? 'cjs' : 'esm', 27 | exports: !isCommonJS && 'named', 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /src/_internals.ts: -------------------------------------------------------------------------------- 1 | export function slice(collection: any): any[] { 2 | return Array.prototype.slice.apply(collection) 3 | } 4 | -------------------------------------------------------------------------------- /src/amOrPm.ts: -------------------------------------------------------------------------------- 1 | export default function amOrPm(date: Date): string { 2 | let hours = date.getHours() 3 | let minutes = date.getMinutes() 4 | const period = hours >= 12 ? 'pm' : 'am' 5 | 6 | return ( 7 | (hours = (hours %= 12) || 12) + 8 | ':' + 9 | ((minutes as string | number) = minutes < 10 ? '0' + minutes : minutes) + 10 | ' ' + 11 | period 12 | ) 13 | } 14 | -------------------------------------------------------------------------------- /src/cookiesToObject.ts: -------------------------------------------------------------------------------- 1 | export default function cookiesToObject( 2 | cookies: string 3 | ): { [key: string]: any } { 4 | return cookies.split(/\s*;\s*/).reduce((acc, cur) => { 5 | let curSplitted = cur.split(/\s*=\s*/) 6 | return { 7 | ...acc, 8 | [curSplitted[0]]: curSplitted.splice(1).join('='), 9 | } 10 | }, {}) 11 | } 12 | -------------------------------------------------------------------------------- /src/countries.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | value: 'AF', 4 | label: 'Afghanistan', 5 | }, 6 | { 7 | value: 'AX', 8 | label: 'Åland Islands', 9 | }, 10 | { 11 | value: 'AL', 12 | label: 'Albania', 13 | }, 14 | { 15 | value: 'DZ', 16 | label: 'Algeria', 17 | }, 18 | { 19 | value: 'AS', 20 | label: 'American Samoa', 21 | }, 22 | { 23 | value: 'AD', 24 | label: 'Andorra', 25 | }, 26 | { 27 | value: 'AO', 28 | label: 'Angola', 29 | }, 30 | { 31 | value: 'AI', 32 | label: 'Anguilla', 33 | }, 34 | { 35 | value: 'AQ', 36 | label: 'Antarctica', 37 | }, 38 | { 39 | value: 'AG', 40 | label: 'Antigua and Barbuda', 41 | }, 42 | { 43 | value: 'AR', 44 | label: 'Argentina', 45 | }, 46 | { 47 | value: 'AM', 48 | label: 'Armenia', 49 | }, 50 | { 51 | value: 'AW', 52 | label: 'Aruba', 53 | }, 54 | { 55 | value: 'AU', 56 | label: 'Australia', 57 | }, 58 | { 59 | value: 'AT', 60 | label: 'Austria', 61 | }, 62 | { 63 | value: 'AZ', 64 | label: 'Azerbaijan', 65 | }, 66 | { 67 | value: 'BS', 68 | label: 'Bahamas', 69 | }, 70 | { 71 | value: 'BH', 72 | label: 'Bahrain', 73 | }, 74 | { 75 | value: 'BD', 76 | label: 'Bangladesh', 77 | }, 78 | { 79 | value: 'BB', 80 | label: 'Barbados', 81 | }, 82 | { 83 | value: 'BY', 84 | label: 'Belarus', 85 | }, 86 | { 87 | value: 'BE', 88 | label: 'Belgium', 89 | }, 90 | { 91 | value: 'BZ', 92 | label: 'Belize', 93 | }, 94 | { 95 | value: 'BJ', 96 | label: 'Benin', 97 | }, 98 | { 99 | value: 'BM', 100 | label: 'Bermuda', 101 | }, 102 | { 103 | value: 'BT', 104 | label: 'Bhutan', 105 | }, 106 | { 107 | value: 'BO', 108 | label: 'Bolivia', 109 | }, 110 | { 111 | value: 'BA', 112 | label: 'Bosnia and Herzegovina', 113 | }, 114 | { 115 | value: 'BW', 116 | label: 'Botswana', 117 | }, 118 | { 119 | value: 'BV', 120 | label: 'Bouvet Island', 121 | }, 122 | { 123 | value: 'BR', 124 | label: 'Brazil', 125 | }, 126 | { 127 | value: 'IO', 128 | label: 'British Indian Ocean Territory', 129 | }, 130 | { 131 | value: 'BN', 132 | label: 'Brunei Darussalam', 133 | }, 134 | { 135 | value: 'BG', 136 | label: 'Bulgaria', 137 | }, 138 | { 139 | value: 'BF', 140 | label: 'Burkina Faso', 141 | }, 142 | { 143 | value: 'BI', 144 | label: 'Burundi', 145 | }, 146 | { 147 | value: 'KH', 148 | label: 'Cambodia', 149 | }, 150 | { 151 | value: 'CM', 152 | label: 'Cameroon', 153 | }, 154 | { 155 | value: 'CA', 156 | label: 'Canada', 157 | }, 158 | { 159 | value: 'CV', 160 | label: 'Cape Verde', 161 | }, 162 | { 163 | value: 'KY', 164 | label: 'Cayman Islands', 165 | }, 166 | { 167 | value: 'CF', 168 | label: 'Central African Republic', 169 | }, 170 | { 171 | value: 'TD', 172 | label: 'Chad', 173 | }, 174 | { 175 | value: 'CL', 176 | label: 'Chile', 177 | }, 178 | { 179 | value: 'CN', 180 | label: 'China', 181 | }, 182 | { 183 | value: 'CX', 184 | label: 'Christmas Island', 185 | }, 186 | { 187 | value: 'CC', 188 | label: 'Cocos (Keeling) Islands', 189 | }, 190 | { 191 | value: 'CO', 192 | label: 'Colombia', 193 | }, 194 | { 195 | value: 'KM', 196 | label: 'Comoros', 197 | }, 198 | { 199 | value: 'CG', 200 | label: 'Congo', 201 | }, 202 | { 203 | value: 'CD', 204 | label: 'Congo, The Democratic Republic of the', 205 | }, 206 | { 207 | value: 'CK', 208 | label: 'Cook Islands', 209 | }, 210 | { 211 | value: 'CR', 212 | label: 'Costa Rica', 213 | }, 214 | { 215 | value: 'CI', 216 | label: "Cote D'Ivoire", 217 | }, 218 | { 219 | value: 'HR', 220 | label: 'Croatia', 221 | }, 222 | { 223 | value: 'CU', 224 | label: 'Cuba', 225 | }, 226 | { 227 | value: 'CY', 228 | label: 'Cyprus', 229 | }, 230 | { 231 | value: 'CZ', 232 | label: 'Czech Republic', 233 | }, 234 | { 235 | value: 'DK', 236 | label: 'Denmark', 237 | }, 238 | { 239 | value: 'DJ', 240 | label: 'Djibouti', 241 | }, 242 | { 243 | value: 'DM', 244 | label: 'Dominica', 245 | }, 246 | { 247 | value: 'DO', 248 | label: 'Dominican Republic', 249 | }, 250 | { 251 | value: 'EC', 252 | label: 'Ecuador', 253 | }, 254 | { 255 | value: 'EG', 256 | label: 'Egypt', 257 | }, 258 | { 259 | value: 'SV', 260 | label: 'El Salvador', 261 | }, 262 | { 263 | value: 'GQ', 264 | label: 'Equatorial Guinea', 265 | }, 266 | { 267 | value: 'ER', 268 | label: 'Eritrea', 269 | }, 270 | { 271 | value: 'EE', 272 | label: 'Estonia', 273 | }, 274 | { 275 | value: 'ET', 276 | label: 'Ethiopia', 277 | }, 278 | { 279 | value: 'FK', 280 | label: 'Falkland Islands (Malvinas)', 281 | }, 282 | { 283 | value: 'FO', 284 | label: 'Faroe Islands', 285 | }, 286 | { 287 | value: 'FJ', 288 | label: 'Fiji', 289 | }, 290 | { 291 | value: 'FI', 292 | label: 'Finland', 293 | }, 294 | { 295 | value: 'FR', 296 | label: 'France', 297 | }, 298 | { 299 | value: 'GF', 300 | label: 'French Guiana', 301 | }, 302 | { 303 | value: 'PF', 304 | label: 'French Polynesia', 305 | }, 306 | { 307 | value: 'TF', 308 | label: 'French Southern Territories', 309 | }, 310 | { 311 | value: 'GA', 312 | label: 'Gabon', 313 | }, 314 | { 315 | value: 'GM', 316 | label: 'Gambia', 317 | }, 318 | { 319 | value: 'GE', 320 | label: 'Georgia', 321 | }, 322 | { 323 | value: 'DE', 324 | label: 'Germany', 325 | }, 326 | { 327 | value: 'GH', 328 | label: 'Ghana', 329 | }, 330 | { 331 | value: 'GI', 332 | label: 'Gibraltar', 333 | }, 334 | { 335 | value: 'GR', 336 | label: 'Greece', 337 | }, 338 | { 339 | value: 'GL', 340 | label: 'Greenland', 341 | }, 342 | { 343 | value: 'GD', 344 | label: 'Grenada', 345 | }, 346 | { 347 | value: 'GP', 348 | label: 'Guadeloupe', 349 | }, 350 | { 351 | value: 'GU', 352 | label: 'Guam', 353 | }, 354 | { 355 | value: 'GT', 356 | label: 'Guatemala', 357 | }, 358 | { 359 | value: 'GG', 360 | label: 'Guernsey', 361 | }, 362 | { 363 | value: 'GN', 364 | label: 'Guinea', 365 | }, 366 | { 367 | value: 'GW', 368 | label: 'Guinea-Bissau', 369 | }, 370 | { 371 | value: 'GY', 372 | label: 'Guyana', 373 | }, 374 | { 375 | value: 'HT', 376 | label: 'Haiti', 377 | }, 378 | { 379 | value: 'HM', 380 | label: 'Heard Island and Mcdonald Islands', 381 | }, 382 | { 383 | value: 'VA', 384 | label: 'Holy See (Vatican City State)', 385 | }, 386 | { 387 | value: 'HN', 388 | label: 'Honduras', 389 | }, 390 | { 391 | value: 'HK', 392 | label: 'Hong Kong', 393 | }, 394 | { 395 | value: 'HU', 396 | label: 'Hungary', 397 | }, 398 | { 399 | value: 'IS', 400 | label: 'Iceland', 401 | }, 402 | { 403 | value: 'IN', 404 | label: 'India', 405 | }, 406 | { 407 | value: 'ID', 408 | label: 'Indonesia', 409 | }, 410 | { 411 | value: 'IR', 412 | label: 'Iran, Islamic Republic Of', 413 | }, 414 | { 415 | value: 'IQ', 416 | label: 'Iraq', 417 | }, 418 | { 419 | value: 'IE', 420 | label: 'Ireland', 421 | }, 422 | { 423 | value: 'IM', 424 | label: 'Isle of Man', 425 | }, 426 | { 427 | value: 'IL', 428 | label: 'Israel', 429 | }, 430 | { 431 | value: 'IT', 432 | label: 'Italy', 433 | }, 434 | { 435 | value: 'JM', 436 | label: 'Jamaica', 437 | }, 438 | { 439 | value: 'JP', 440 | label: 'Japan', 441 | }, 442 | { 443 | value: 'JE', 444 | label: 'Jersey', 445 | }, 446 | { 447 | value: 'JO', 448 | label: 'Jordan', 449 | }, 450 | { 451 | value: 'KZ', 452 | label: 'Kazakhstan', 453 | }, 454 | { 455 | value: 'KE', 456 | label: 'Kenya', 457 | }, 458 | { 459 | value: 'KI', 460 | label: 'Kiribati', 461 | }, 462 | { 463 | value: 'KP', 464 | label: "Korea, Democratic People's Republic of", 465 | }, 466 | { 467 | value: 'KR', 468 | label: 'Korea, Republic of', 469 | }, 470 | { 471 | value: 'KW', 472 | label: 'Kuwait', 473 | }, 474 | { 475 | value: 'KG', 476 | label: 'Kyrgyzstan', 477 | }, 478 | { 479 | value: 'LA', 480 | label: "Lao People's Democratic Republic", 481 | }, 482 | { 483 | value: 'LV', 484 | label: 'Latvia', 485 | }, 486 | { 487 | value: 'LB', 488 | label: 'Lebanon', 489 | }, 490 | { 491 | value: 'LS', 492 | label: 'Lesotho', 493 | }, 494 | { 495 | value: 'LR', 496 | label: 'Liberia', 497 | }, 498 | { 499 | value: 'LY', 500 | label: 'Libyan Arab Jamahiriya', 501 | }, 502 | { 503 | value: 'LI', 504 | label: 'Liechtenstein', 505 | }, 506 | { 507 | value: 'LT', 508 | label: 'Lithuania', 509 | }, 510 | { 511 | value: 'LU', 512 | label: 'Luxembourg', 513 | }, 514 | { 515 | value: 'MO', 516 | label: 'Macao', 517 | }, 518 | { 519 | value: 'MK', 520 | label: 'Macedonia, The Former Yugoslav Republic of', 521 | }, 522 | { 523 | value: 'MG', 524 | label: 'Madagascar', 525 | }, 526 | { 527 | value: 'MW', 528 | label: 'Malawi', 529 | }, 530 | { 531 | value: 'MY', 532 | label: 'Malaysia', 533 | }, 534 | { 535 | value: 'MV', 536 | label: 'Maldives', 537 | }, 538 | { 539 | value: 'ML', 540 | label: 'Mali', 541 | }, 542 | { 543 | value: 'MT', 544 | label: 'Malta', 545 | }, 546 | { 547 | value: 'MH', 548 | label: 'Marshall Islands', 549 | }, 550 | { 551 | value: 'MQ', 552 | label: 'Martinique', 553 | }, 554 | { 555 | value: 'MR', 556 | label: 'Mauritania', 557 | }, 558 | { 559 | value: 'MU', 560 | label: 'Mauritius', 561 | }, 562 | { 563 | value: 'YT', 564 | label: 'Mayotte', 565 | }, 566 | { 567 | value: 'MX', 568 | label: 'Mexico', 569 | }, 570 | { 571 | value: 'FM', 572 | label: 'Micronesia, Federated States of', 573 | }, 574 | { 575 | value: 'MD', 576 | label: 'Moldova, Republic of', 577 | }, 578 | { 579 | value: 'MC', 580 | label: 'Monaco', 581 | }, 582 | { 583 | value: 'MN', 584 | label: 'Mongolia', 585 | }, 586 | { 587 | value: 'MS', 588 | label: 'Montserrat', 589 | }, 590 | { 591 | value: 'MA', 592 | label: 'Morocco', 593 | }, 594 | { 595 | value: 'MZ', 596 | label: 'Mozambique', 597 | }, 598 | { 599 | value: 'MM', 600 | label: 'Myanmar', 601 | }, 602 | { 603 | value: 'NA', 604 | label: 'Namibia', 605 | }, 606 | { 607 | value: 'NR', 608 | label: 'Nauru', 609 | }, 610 | { 611 | value: 'NP', 612 | label: 'Nepal', 613 | }, 614 | { 615 | value: 'NL', 616 | label: 'Netherlands', 617 | }, 618 | { 619 | value: 'AN', 620 | label: 'Netherlands Antilles', 621 | }, 622 | { 623 | value: 'NC', 624 | label: 'New Caledonia', 625 | }, 626 | { 627 | value: 'NZ', 628 | label: 'New Zealand', 629 | }, 630 | { 631 | value: 'NI', 632 | label: 'Nicaragua', 633 | }, 634 | { 635 | value: 'NE', 636 | label: 'Niger', 637 | }, 638 | { 639 | value: 'NG', 640 | label: 'Nigeria', 641 | }, 642 | { 643 | value: 'NU', 644 | label: 'Niue', 645 | }, 646 | { 647 | value: 'NF', 648 | label: 'Norfolk Island', 649 | }, 650 | { 651 | value: 'MP', 652 | label: 'Northern Mariana Islands', 653 | }, 654 | { 655 | value: 'NO', 656 | label: 'Norway', 657 | }, 658 | { 659 | value: 'OM', 660 | label: 'Oman', 661 | }, 662 | { 663 | value: 'PK', 664 | label: 'Pakistan', 665 | }, 666 | { 667 | value: 'PW', 668 | label: 'Palau', 669 | }, 670 | { 671 | value: 'PS', 672 | label: 'Palestinian Territory, Occupied', 673 | }, 674 | { 675 | value: 'PA', 676 | label: 'Panama', 677 | }, 678 | { 679 | value: 'PG', 680 | label: 'Papua New Guinea', 681 | }, 682 | { 683 | value: 'PY', 684 | label: 'Paraguay', 685 | }, 686 | { 687 | value: 'PE', 688 | label: 'Peru', 689 | }, 690 | { 691 | value: 'PH', 692 | label: 'Philippines', 693 | }, 694 | { 695 | value: 'PN', 696 | label: 'Pitcairn', 697 | }, 698 | { 699 | value: 'PL', 700 | label: 'Poland', 701 | }, 702 | { 703 | value: 'PT', 704 | label: 'Portugal', 705 | }, 706 | { 707 | value: 'PR', 708 | label: 'Puerto Rico', 709 | }, 710 | { 711 | value: 'QA', 712 | label: 'Qatar', 713 | }, 714 | { 715 | value: 'RE', 716 | label: 'Reunion', 717 | }, 718 | { 719 | value: 'RO', 720 | label: 'Romania', 721 | }, 722 | { 723 | value: 'RU', 724 | label: 'Russian Federation', 725 | }, 726 | { 727 | value: 'RW', 728 | label: 'Rwanda', 729 | }, 730 | { 731 | value: 'SH', 732 | label: 'Saint Helena', 733 | }, 734 | { 735 | value: 'KN', 736 | label: 'Saint Kitts and Nevis', 737 | }, 738 | { 739 | value: 'LC', 740 | label: 'Saint Lucia', 741 | }, 742 | { 743 | value: 'PM', 744 | label: 'Saint Pierre and Miquelon', 745 | }, 746 | { 747 | value: 'VC', 748 | label: 'Saint Vincent and the Grenadines', 749 | }, 750 | { 751 | value: 'WS', 752 | label: 'Samoa', 753 | }, 754 | { 755 | value: 'SM', 756 | label: 'San Marino', 757 | }, 758 | { 759 | value: 'ST', 760 | label: 'Sao Tome and Principe', 761 | }, 762 | { 763 | value: 'SA', 764 | label: 'Saudi Arabia', 765 | }, 766 | { 767 | value: 'SN', 768 | label: 'Senegal', 769 | }, 770 | { 771 | value: 'CS', 772 | label: 'Serbia and Montenegro', 773 | }, 774 | { 775 | value: 'SC', 776 | label: 'Seychelles', 777 | }, 778 | { 779 | value: 'SL', 780 | label: 'Sierra Leone', 781 | }, 782 | { 783 | value: 'SG', 784 | label: 'Singapore', 785 | }, 786 | { 787 | value: 'SK', 788 | label: 'Slovakia', 789 | }, 790 | { 791 | value: 'SI', 792 | label: 'Slovenia', 793 | }, 794 | { 795 | value: 'SB', 796 | label: 'Solomon Islands', 797 | }, 798 | { 799 | value: 'SO', 800 | label: 'Somalia', 801 | }, 802 | { 803 | value: 'ZA', 804 | label: 'South Africa', 805 | }, 806 | { 807 | value: 'GS', 808 | label: 'South Georgia and the South Sandwich Islands', 809 | }, 810 | { 811 | value: 'ES', 812 | label: 'Spain', 813 | }, 814 | { 815 | value: 'LK', 816 | label: 'Sri Lanka', 817 | }, 818 | { 819 | value: 'SD', 820 | label: 'Sudan', 821 | }, 822 | { 823 | value: 'SR', 824 | label: 'Surilabel', 825 | }, 826 | { 827 | value: 'SJ', 828 | label: 'Svalbard and Jan Mayen', 829 | }, 830 | { 831 | value: 'SZ', 832 | label: 'Swaziland', 833 | }, 834 | { 835 | value: 'SE', 836 | label: 'Sweden', 837 | }, 838 | { 839 | value: 'CH', 840 | label: 'Switzerland', 841 | }, 842 | { 843 | value: 'SY', 844 | label: 'Syrian Arab Republic', 845 | }, 846 | { 847 | value: 'TW', 848 | label: 'Taiwan', 849 | }, 850 | { 851 | value: 'TJ', 852 | label: 'Tajikistan', 853 | }, 854 | { 855 | value: 'TZ', 856 | label: 'Tanzania, United Republic of', 857 | }, 858 | { 859 | value: 'TH', 860 | label: 'Thailand', 861 | }, 862 | { 863 | value: 'TL', 864 | label: 'Timor-Leste', 865 | }, 866 | { 867 | value: 'TG', 868 | label: 'Togo', 869 | }, 870 | { 871 | value: 'TK', 872 | label: 'Tokelau', 873 | }, 874 | { 875 | value: 'TO', 876 | label: 'Tonga', 877 | }, 878 | { 879 | value: 'TT', 880 | label: 'Trinidad and Tobago', 881 | }, 882 | { 883 | value: 'TN', 884 | label: 'Tunisia', 885 | }, 886 | { 887 | value: 'TR', 888 | label: 'Turkey', 889 | }, 890 | { 891 | value: 'TM', 892 | label: 'Turkmenistan', 893 | }, 894 | { 895 | value: 'TC', 896 | label: 'Turks and Caicos Islands', 897 | }, 898 | { 899 | value: 'TV', 900 | label: 'Tuvalu', 901 | }, 902 | { 903 | value: 'UG', 904 | label: 'Uganda', 905 | }, 906 | { 907 | value: 'UA', 908 | label: 'Ukraine', 909 | }, 910 | { 911 | value: 'AE', 912 | label: 'United Arab Emirates', 913 | }, 914 | { 915 | value: 'GB', 916 | label: 'United Kingdom', 917 | }, 918 | { 919 | value: 'US', 920 | label: 'United States', 921 | }, 922 | { 923 | value: 'UM', 924 | label: 'United States Minor Outlying Islands', 925 | }, 926 | { 927 | value: 'UY', 928 | label: 'Uruguay', 929 | }, 930 | { 931 | value: 'UZ', 932 | label: 'Uzbekistan', 933 | }, 934 | { 935 | value: 'VU', 936 | label: 'Vanuatu', 937 | }, 938 | { 939 | value: 'VE', 940 | label: 'Venezuela', 941 | }, 942 | { 943 | value: 'VN', 944 | label: 'Vietnam', 945 | }, 946 | { 947 | value: 'VG', 948 | label: 'Virgin Islands, British', 949 | }, 950 | { 951 | value: 'VI', 952 | label: 'Virgin Islands, U.S.', 953 | }, 954 | { 955 | value: 'WF', 956 | label: 'Wallis and Futuna', 957 | }, 958 | { 959 | value: 'EH', 960 | label: 'Western Sahara', 961 | }, 962 | { 963 | value: 'YE', 964 | label: 'Yemen', 965 | }, 966 | { 967 | value: 'ZM', 968 | label: 'Zambia', 969 | }, 970 | { 971 | value: 'ZW', 972 | label: 'Zimbabwe', 973 | }, 974 | ] as const 975 | -------------------------------------------------------------------------------- /src/countryDialCodes.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { label: '+93', value: 'Afghanistan' }, 3 | { label: '+355', value: 'Albania' }, 4 | { label: '+213', value: 'Algeria' }, 5 | { label: '+1', value: 'American Samoa' }, 6 | { label: '+376', value: 'Andorra' }, 7 | { label: '+244', value: 'Angola' }, 8 | { label: '+1', value: 'Anguilla' }, 9 | { label: '+1', value: 'Antigua & Barbuda' }, 10 | { label: '+54', value: 'Argentina' }, 11 | { label: '+374', value: 'Armenia' }, 12 | { label: '+297', value: 'Aruba' }, 13 | { label: '+247', value: 'Ascension Island' }, 14 | { label: '+61', value: 'Australia' }, 15 | { label: '+43', value: 'Austria' }, 16 | { label: '+994', value: 'Azerbaijan' }, 17 | { label: '+1', value: 'Bahamas' }, 18 | { label: '+973', value: 'Bahrain' }, 19 | { label: '+880', value: 'Bangladesh' }, 20 | { label: '+1', value: 'Barbados' }, 21 | { label: '+375', value: 'Belarus' }, 22 | { label: '+32', value: 'Belgium' }, 23 | { label: '+501', value: 'Belize' }, 24 | { label: '+229', value: 'Benin' }, 25 | { label: '+1', value: 'Bermuda' }, 26 | { label: '+975', value: 'Bhutan' }, 27 | { label: '+591', value: 'Bolivia' }, 28 | { label: '+387', value: 'Bosnia & Herzegovina' }, 29 | { label: '+267', value: 'Botswana' }, 30 | { label: '+55', value: 'Brazil' }, 31 | { label: '+246', value: 'British Indian Ocean Territory' }, 32 | { label: '+1', value: 'British Virgin Islands' }, 33 | { label: '+673', value: 'Brunei' }, 34 | { label: '+359', value: 'Bulgaria' }, 35 | { label: '+226', value: 'Burkina Faso' }, 36 | { label: '+257', value: 'Burundi' }, 37 | { label: '+855', value: 'Cambodia' }, 38 | { label: '+237', value: 'Cameroon' }, 39 | { label: '+1', value: 'Canada' }, 40 | { label: '+238', value: 'Cape Verde' }, 41 | { label: '+599', value: 'Caribbean Netherlands' }, 42 | { label: '+1', value: 'Cayman Islands' }, 43 | { label: '+236', value: 'Central African Republic' }, 44 | { label: '+235', value: 'Chad' }, 45 | { label: '+56', value: 'Chile' }, 46 | { label: '+86', value: 'China' }, 47 | { label: '+57', value: 'Colombia' }, 48 | { label: '+269', value: 'Comoros' }, 49 | { label: '+242', value: 'Congo - Brazzaville' }, 50 | { label: '+243', value: 'Congo - Kinshasa' }, 51 | { label: '+682', value: 'Cook Islands' }, 52 | { label: '+506', value: 'Costa Rica' }, 53 | { label: '+225', value: 'Côte d’Ivoire' }, 54 | { label: '+385', value: 'Croatia' }, 55 | { label: '+53', value: 'Cuba' }, 56 | { label: '+599', value: 'Curaçao' }, 57 | { label: '+357', value: 'Cyprus' }, 58 | { label: '+420', value: 'Czechia' }, 59 | { label: '+45', value: 'Denmark' }, 60 | { label: '+253', value: 'Djibouti' }, 61 | { label: '+1', value: 'Dominica' }, 62 | { label: '+1', value: 'Dominican Republic' }, 63 | { label: '+593', value: 'Ecuador' }, 64 | { label: '+20', value: 'Egypt' }, 65 | { label: '+503', value: 'El Salvador' }, 66 | { label: '+240', value: 'Equatorial Guinea' }, 67 | { label: '+291', value: 'Eritrea' }, 68 | { label: '+372', value: 'Estonia' }, 69 | { label: '+251', value: 'Ethiopia' }, 70 | { label: '+500', value: 'Falkland Islands (Islas Malvinas)' }, 71 | { label: '+298', value: 'Faroe Islands' }, 72 | { label: '+679', value: 'Fiji' }, 73 | { label: '+358', value: 'Finland' }, 74 | { label: '+33', value: 'France' }, 75 | { label: '+594', value: 'French Guiana' }, 76 | { label: '+689', value: 'French Polynesia' }, 77 | { label: '+241', value: 'Gabon' }, 78 | { label: '+220', value: 'Gambia' }, 79 | { label: '+995', value: 'Georgia' }, 80 | { label: '+49', value: 'Germany' }, 81 | { label: '+233', value: 'Ghana' }, 82 | { label: '+350', value: 'Gibraltar' }, 83 | { label: '+30', value: 'Greece' }, 84 | { label: '+299', value: 'Greenland' }, 85 | { label: '+1', value: 'Grenada' }, 86 | { label: '+590', value: 'Guadeloupe' }, 87 | { label: '+1', value: 'Guam' }, 88 | { label: '+502', value: 'Guatemala' }, 89 | { label: '+224', value: 'Guinea' }, 90 | { label: '+245', value: 'Guinea-Bissau' }, 91 | { label: '+592', value: 'Guyana' }, 92 | { label: '+509', value: 'Haiti' }, 93 | { label: '+504', value: 'Honduras' }, 94 | { label: '+852', value: 'Hong Kong' }, 95 | { label: '+36', value: 'Hungary' }, 96 | { label: '+354', value: 'Iceland' }, 97 | { label: '+91', value: 'India' }, 98 | { label: '+62', value: 'Indonesia' }, 99 | { label: '+98', value: 'Iran' }, 100 | { label: '+964', value: 'Iraq' }, 101 | { label: '+353', value: 'Ireland' }, 102 | { label: '+972', value: 'Israel' }, 103 | { label: '+39', value: 'Italy' }, 104 | { label: '+1', value: 'Jamaica' }, 105 | { label: '+81', value: 'Japan' }, 106 | { label: '+962', value: 'Jordan' }, 107 | { label: '+7', value: 'Kazakhstan' }, 108 | { label: '+254', value: 'Kenya' }, 109 | { label: '+686', value: 'Kiribati' }, 110 | { label: '+383', value: 'Kosovo' }, 111 | { label: '+965', value: 'Kuwait' }, 112 | { label: '+996', value: 'Kyrgyzstan' }, 113 | { label: '+856', value: 'Laos' }, 114 | { label: '+371', value: 'Latvia' }, 115 | { label: '+961', value: 'Lebanon' }, 116 | { label: '+266', value: 'Lesotho' }, 117 | { label: '+231', value: 'Liberia' }, 118 | { label: '+218', value: 'Libya' }, 119 | { label: '+423', value: 'Liechtenstein' }, 120 | { label: '+370', value: 'Lithuania' }, 121 | { label: '+352', value: 'Luxembourg' }, 122 | { label: '+853', value: 'Macau' }, 123 | { label: '+389', value: 'Macedonia (FYROM)' }, 124 | { label: '+261', value: 'Madagascar' }, 125 | { label: '+265', value: 'Malawi' }, 126 | { label: '+60', value: 'Malaysia' }, 127 | { label: '+960', value: 'Maldives' }, 128 | { label: '+223', value: 'Mali' }, 129 | { label: '+356', value: 'Malta' }, 130 | { label: '+692', value: 'Marshall Islands' }, 131 | { label: '+596', value: 'Martinique' }, 132 | { label: '+222', value: 'Mauritania' }, 133 | { label: '+230', value: 'Mauritius' }, 134 | { label: '+52', value: 'Mexico' }, 135 | { label: '+691', value: 'Micronesia' }, 136 | { label: '+373', value: 'Moldova' }, 137 | { label: '+377', value: 'Monaco' }, 138 | { label: '+976', value: 'Mongolia' }, 139 | { label: '+382', value: 'Montenegro' }, 140 | { label: '+1', value: 'Montserrat' }, 141 | { label: '+212', value: 'Morocco' }, 142 | { label: '+258', value: 'Mozambique' }, 143 | { label: '+95', value: 'Myanmar (Burma)' }, 144 | { label: '+264', value: 'Namibia' }, 145 | { label: '+674', value: 'Nauru' }, 146 | { label: '+977', value: 'Nepal' }, 147 | { label: '+31', value: 'Netherlands' }, 148 | { label: '+687', value: 'New Caledonia' }, 149 | { label: '+64', value: 'New Zealand' }, 150 | { label: '+505', value: 'Nicaragua' }, 151 | { label: '+227', value: 'Niger' }, 152 | { label: '+234', value: 'Nigeria' }, 153 | { label: '+683', value: 'Niue' }, 154 | { label: '+672', value: 'Norfolk Island' }, 155 | { label: '+850', value: 'North Korea' }, 156 | { label: '+1', value: 'Northern Mariana Islands' }, 157 | { label: '+47', value: 'Norway' }, 158 | { label: '+968', value: 'Oman' }, 159 | { label: '+92', value: 'Pakistan' }, 160 | { label: '+680', value: 'Palau' }, 161 | { label: '+970', value: 'Palestine' }, 162 | { label: '+507', value: 'Panama' }, 163 | { label: '+675', value: 'Papua New Guinea' }, 164 | { label: '+595', value: 'Paraguay' }, 165 | { label: '+51', value: 'Peru' }, 166 | { label: '+63', value: 'Philippines' }, 167 | { label: '+48', value: 'Poland' }, 168 | { label: '+351', value: 'Portugal' }, 169 | { label: '+1', value: 'Puerto Rico' }, 170 | { label: '+974', value: 'Qatar' }, 171 | { label: '+262', value: 'Réunion' }, 172 | { label: '+40', value: 'Romania' }, 173 | { label: '+7', value: 'Russia' }, 174 | { label: '+250', value: 'Rwanda' }, 175 | { label: '+685', value: 'Samoa' }, 176 | { label: '+378', value: 'San Marino' }, 177 | { label: '+239', value: 'São Tomé & Príncipe' }, 178 | { label: '+966', value: 'Saudi Arabia' }, 179 | { label: '+221', value: 'Senegal' }, 180 | { label: '+381', value: 'Serbia' }, 181 | { label: '+248', value: 'Seychelles' }, 182 | { label: '+232', value: 'Sierra Leone' }, 183 | { label: '+65', value: 'Singapore' }, 184 | { label: '+1', value: 'Sint Maarten' }, 185 | { label: '+421', value: 'Slovakia' }, 186 | { label: '+386', value: 'Slovenia' }, 187 | { label: '+677', value: 'Solomon Islands' }, 188 | { label: '+252', value: 'Somalia' }, 189 | { label: '+27', value: 'South Africa' }, 190 | { label: '+82', value: 'South Korea' }, 191 | { label: '+211', value: 'South Sudan' }, 192 | { label: '+34', value: 'Spain' }, 193 | { label: '+94', value: 'Sri Lanka' }, 194 | { label: '+590', value: 'St Barthélemy' }, 195 | { label: '+290', value: 'St Helena' }, 196 | { label: '+1', value: 'St Kitts & Nevis' }, 197 | { label: '+1', value: 'St Lucia' }, 198 | { label: '+590', value: 'St Martin' }, 199 | { label: '+508', value: 'St Pierre & Miquelon' }, 200 | { label: '+1', value: 'St Vincent & Grenadines' }, 201 | { label: '+249', value: 'Sudan' }, 202 | { label: '+597', value: 'Suriname' }, 203 | { label: '+268', value: 'Swaziland' }, 204 | { label: '+46', value: 'Sweden' }, 205 | { label: '+41', value: 'Switzerland' }, 206 | { label: '+963', value: 'Syria' }, 207 | { label: '+886', value: 'Taiwan' }, 208 | { label: '+992', value: 'Tajikistan' }, 209 | { label: '+255', value: 'Tanzania' }, 210 | { label: '+66', value: 'Thailand' }, 211 | { label: '+670', value: 'Timor-Leste' }, 212 | { label: '+228', value: 'Togo' }, 213 | { label: '+690', value: 'Tokelau' }, 214 | { label: '+676', value: 'Tonga' }, 215 | { label: '+1', value: 'Trinidad & Tobago' }, 216 | { label: '+216', value: 'Tunisia' }, 217 | { label: '+90', value: 'Turkey' }, 218 | { label: '+993', value: 'Turkmenistan' }, 219 | { label: '+1', value: 'Turks & Caicos Islands' }, 220 | { label: '+688', value: 'Tuvalu' }, 221 | { label: '+256', value: 'Uganda' }, 222 | { label: '+380', value: 'Ukraine' }, 223 | { label: '+971', value: 'United Arab Emirates' }, 224 | { label: '+44', value: 'United Kingdom' }, 225 | { label: '+1', value: 'United States' }, 226 | { label: '+598', value: 'Uruguay' }, 227 | { label: '+1', value: 'US Virgin Islands' }, 228 | { label: '+998', value: 'Uzbekistan' }, 229 | { label: '+678', value: 'Vanuatu' }, 230 | { label: '+39', value: 'Vatican City' }, 231 | { label: '+58', value: 'Venezuela' }, 232 | { label: '+84', value: 'Vietnam' }, 233 | { label: '+681', value: 'Wallis & Futuna' }, 234 | { label: '+967', value: 'Yemen' }, 235 | { label: '+260', value: 'Zambia' }, 236 | { label: '+263', value: 'Zimbabwe' }, 237 | ] as const 238 | -------------------------------------------------------------------------------- /src/debounce.ts: -------------------------------------------------------------------------------- 1 | export default function debounce void>( 2 | fn: T, 3 | ms: number = 0 4 | ): ( 5 | this: ThisParameterType, 6 | ...args: Parameters 7 | ) => ReturnType { 8 | let timeoutId: ReturnType | undefined 9 | 10 | return function ( 11 | this: ThisParameterType, 12 | ...args: Parameters 13 | ): any { 14 | clearTimeout(timeoutId!) 15 | timeoutId = setTimeout(() => fn.apply(this, args), ms) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/dotAccess.ts: -------------------------------------------------------------------------------- 1 | // TODO: Fix/improve this type definition? 2 | export default function dotAccess( 3 | obj: T, 4 | path: string 5 | ): T[keyof T] | undefined { 6 | let keyCollection: string[] = [] 7 | if (path && path.split) keyCollection = path.split('.') 8 | for (let i = 0; i < keyCollection.length && obj; i++) { 9 | obj = obj[keyCollection[i]] 10 | } 11 | return obj as T[keyof T] 12 | } 13 | -------------------------------------------------------------------------------- /src/elementInView.ts: -------------------------------------------------------------------------------- 1 | export interface Offset { 2 | top?: number 3 | right?: number 4 | bottom?: number 5 | left?: number 6 | } 7 | 8 | export interface ElementInViewOptions { 9 | threshold?: number 10 | offset?: Offset 11 | } 12 | 13 | export default function elementInView( 14 | element: HTMLElement, 15 | options?: ElementInViewOptions 16 | ): boolean { 17 | const { top, right, bottom, left, width, height, } = element.getBoundingClientRect() 18 | 19 | options = { 20 | threshold: 0, 21 | offset: { top: 0, right: 0, bottom: 0, left: 0 }, 22 | ...options, 23 | } 24 | 25 | const intersection = { 26 | t: bottom, 27 | r: window.innerWidth - left, 28 | b: window.innerHeight - top, 29 | l: right, 30 | } 31 | 32 | const threshold = { 33 | x: options.threshold! * width, 34 | y: options.threshold! * height, 35 | } 36 | 37 | return ( 38 | intersection.t > (options.offset!.top || 0) + threshold.y && 39 | intersection.r > (options.offset!.right || 0) + threshold.x && 40 | intersection.b > (options.offset!.bottom || 0) + threshold.y && 41 | intersection.l > (options.offset!.left || 0) + threshold.x 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /src/emitEvent.ts: -------------------------------------------------------------------------------- 1 | export default function emitEvent( 2 | el: HTMLElement, 3 | eventType: T, 4 | detail: CustomEventInit 5 | ): boolean { 6 | let event 7 | 8 | if (typeof CustomEvent === 'function') { 9 | event = new CustomEvent(eventType, { detail }) 10 | } else { 11 | event = document.createEvent('CustomEvent') 12 | event.initCustomEvent(eventType, true, true, detail) 13 | } 14 | 15 | return el.dispatchEvent(event) 16 | } 17 | -------------------------------------------------------------------------------- /src/findIndex.ts: -------------------------------------------------------------------------------- 1 | export default function findIndex( 2 | array: T[], 3 | predicate: (value: T, index: number, obj: T[]) => unknown, 4 | thisArg?: any 5 | ): number { 6 | if (array == null) { 7 | throw new TypeError('"array" is null or not defined') 8 | } 9 | 10 | let o = Object(array) as any[] 11 | 12 | let len = o.length >>> 0 13 | 14 | if (typeof predicate !== 'function') { 15 | throw new TypeError('predicate must be a function') 16 | } 17 | 18 | let k = 0 19 | 20 | while (k < len) { 21 | let kValue = o[k] 22 | if (predicate.call(thisArg, kValue, k, o)) { 23 | return k 24 | } 25 | k++ 26 | } 27 | 28 | return -1 29 | } 30 | -------------------------------------------------------------------------------- /src/flattenStr.ts: -------------------------------------------------------------------------------- 1 | export default function flattenStr(str: string): string { 2 | const templateRE = /([ ]+)|(\n+)/gm 3 | return str.replace(templateRE, (match, p1) => (p1 ? ' ' : '')).trim() 4 | } 5 | -------------------------------------------------------------------------------- /src/focusableSelectors.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | '*[tabindex]', 3 | 'a[href]:not([hidden])', 4 | 'area[href]:not([hidden])', 5 | 'button:not(:disabled):not([hidden])', 6 | 'embed:not([hidden])', 7 | 'iframe:not([hidden])', 8 | 'audio[controls]:not([hidden])', 9 | 'video[controls]:not([hidden])', 10 | 'input:not([type="hidden"]):not(:disabled):not([hidden])', 11 | 'object:not([hidden])', 12 | 'select:not(:disabled):not([hidden])', 13 | 'textarea:not(:disabled):not([hidden])', 14 | '*[contenteditable]:not([contenteditable="false"]):not([hidden])', 15 | ] as const 16 | -------------------------------------------------------------------------------- /src/forEachValue.ts: -------------------------------------------------------------------------------- 1 | export default function forEachValue( 2 | obj: T, 3 | callback: (value: T[keyof T], key: keyof T, obj: T) => unknown 4 | ): void { 5 | for (let key in obj) callback(obj[key], key, obj) 6 | } 7 | -------------------------------------------------------------------------------- /src/getAspectRatio.ts: -------------------------------------------------------------------------------- 1 | export default function getAspectRatio( 2 | a: number = screen.width, 3 | b: number = screen.height 4 | ): number { 5 | return b == 0 ? a : getAspectRatio(b, a % b) 6 | } 7 | -------------------------------------------------------------------------------- /src/getEventPath.ts: -------------------------------------------------------------------------------- 1 | export default function getEventPath( 2 | event: Event & { path?: EventTarget[] } 3 | ): (EventTarget | null)[] { 4 | if (!(event instanceof Event)) return [] 5 | 6 | return ( 7 | (Array.isArray(event.path) && event.path) || 8 | (typeof event.composedPath == 'function' && event.composedPath()) || 9 | (function fallback() { 10 | const path = [] 11 | let target = event.target 12 | 13 | while (target !== window && (target as HTMLElement).parentNode !== null) { 14 | path.push(target) 15 | target = (target as HTMLElement).parentNode 16 | } 17 | 18 | path.push(document, window) 19 | 20 | return path 21 | })() 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /src/getFirstFocusableNode.ts: -------------------------------------------------------------------------------- 1 | import getFocusableNodes from './getFocusableNodes' 2 | 3 | export default function getFirstFocusableNode( 4 | target: HTMLElement = document.documentElement 5 | ): HTMLElement | null { 6 | if (!(target instanceof HTMLElement)) return null 7 | const [firstFocusableNode] = getFocusableNodes(target) 8 | return firstFocusableNode || null 9 | } 10 | -------------------------------------------------------------------------------- /src/getFirstTabbableNode.ts: -------------------------------------------------------------------------------- 1 | import getTabbableNodes from './getTabbableNodes' 2 | 3 | export default function getFirstTabbableNode( 4 | target: HTMLElement = document.documentElement 5 | ): HTMLElement | null { 6 | if (!(target instanceof HTMLElement)) return null 7 | const [firstTabbableNode] = getTabbableNodes(target) 8 | return firstTabbableNode || null 9 | } 10 | -------------------------------------------------------------------------------- /src/getFocusableNodes.ts: -------------------------------------------------------------------------------- 1 | import { slice } from './_internals' 2 | import focusableSelectors from './focusableSelectors' 3 | 4 | export default function getFocusableNodes( 5 | target: HTMLElement = document.documentElement 6 | ): HTMLElement[] | never[] { 7 | if (!(target instanceof HTMLElement)) return [] 8 | const potentialCandidates: HTMLElement[] = slice( 9 | target.querySelectorAll(focusableSelectors.join()) 10 | ) 11 | 12 | return potentialCandidates.filter( 13 | elem => 14 | elem instanceof HTMLElement && 15 | window.getComputedStyle(elem).display !== 'none' 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/getFormFields.ts: -------------------------------------------------------------------------------- 1 | import { slice } from './_internals' 2 | 3 | export default function getFormFields< 4 | T extends HTMLInputElement | HTMLTextAreaElement 5 | >( 6 | elem: HTMLFormElement, 7 | selectors: string = defaultSelectors 8 | ): { 9 | [key: string]: string 10 | } { 11 | if (!(elem instanceof HTMLFormElement)) return {} 12 | 13 | const normalizeName = (v: any): string => String(v || '').replace(/\s+/g, '_') 14 | return (slice(elem.querySelectorAll(selectors)) as T[]).reduce( 15 | (acc, elem) => ({ 16 | ...acc, 17 | [normalizeName((elem as T).name)]: (elem as T).value, 18 | }), 19 | {} 20 | ) 21 | } 22 | 23 | const defaultSelectors = `input[name]:not([aria-hidden="true"]):not([type="hidden"]):not(:disabled):not([hidden]):not([type="submit"]):not([type="button"]):not([type="reset"])not([type="image"]), 24 | textarea[name]:not([aria-hidden="true"]):not([type="hidden"]):not(:disabled):not([hidden]):not([type="submit"]):not([type="button"]):not([type="reset"])not([type="image"])` 25 | -------------------------------------------------------------------------------- /src/getFullMonthName.ts: -------------------------------------------------------------------------------- 1 | import findIndex from './findIndex' 2 | import monthNames, { MonthNames } from './monthNames' 3 | import shortMonthNames, { ShortMonthNames } from './shortMonthNames' 4 | 5 | export default function getFullMonthName( 6 | value: Date | ShortMonthNames = new Date() 7 | ): MonthNames | null { 8 | if (value instanceof Date) return monthNames[value.getMonth()] 9 | const index = findIndex(shortMonthNames.slice(), name => name === value) 10 | if (index === -1) return null 11 | return monthNames[index] 12 | } 13 | -------------------------------------------------------------------------------- /src/getFullWeekday.ts: -------------------------------------------------------------------------------- 1 | import weekdays, { WeekDays } from './weekdays' 2 | import findIndex from './findIndex' 3 | import shortWeekdays, { ShortWeekdays } from './shortWeekdays' 4 | 5 | export default function getFullWeekday( 6 | value: Date | ShortWeekdays = new Date() 7 | ): WeekDays | null { 8 | if (value instanceof Date) return weekdays[value.getDay()] 9 | const index = findIndex(shortWeekdays.slice(), name => name === value) 10 | if (index === -1) return null 11 | return weekdays[index] 12 | } 13 | -------------------------------------------------------------------------------- /src/getLastFocusableNode.ts: -------------------------------------------------------------------------------- 1 | import getFocusableNodes from './getFocusableNodes' 2 | 3 | export default function getLastFocusableNode( 4 | target: HTMLElement = document.documentElement 5 | ): HTMLElement | null { 6 | if (!(target instanceof HTMLElement)) return null 7 | const focusables = getFocusableNodes(target) 8 | return focusables[focusables.length - 1] || null 9 | } 10 | -------------------------------------------------------------------------------- /src/getLastTabbableNode.ts: -------------------------------------------------------------------------------- 1 | import getTabbableNodes from './getTabbableNodes' 2 | 3 | export default function getLastTabbableNode( 4 | target: HTMLElement = document.documentElement 5 | ): HTMLElement | null { 6 | if (!(target instanceof HTMLElement)) return null 7 | const tabbables = getTabbableNodes(target) 8 | return tabbables[tabbables.length - 1] || null 9 | } 10 | -------------------------------------------------------------------------------- /src/getShortMonthName.ts: -------------------------------------------------------------------------------- 1 | import monthNames, { MonthNames } from './monthNames' 2 | import { ShortMonthNames } from './shortMonthNames' 3 | 4 | export default function getShortMonthName( 5 | value: Date | MonthNames = new Date() 6 | ): ShortMonthNames | null { 7 | let result = value 8 | if (value instanceof Date) result = monthNames[value.getMonth()] 9 | if (monthNames.indexOf(result as MonthNames) === -1) return null 10 | return (result as MonthNames).substring(0, 3) as ShortMonthNames 11 | } 12 | -------------------------------------------------------------------------------- /src/getShortWeekday.ts: -------------------------------------------------------------------------------- 1 | import weekdays, { WeekDays } from './weekdays' 2 | import { ShortWeekdays } from './shortWeekdays' 3 | 4 | export default function getShortWeekday( 5 | value: Date | WeekDays = new Date() 6 | ): ShortWeekdays | null { 7 | let result = value 8 | if (value instanceof Date) result = weekdays[value.getDay()] 9 | if (weekdays.indexOf(result as WeekDays) === -1) return null 10 | return (result as WeekDays).substring(0, 3) as ShortWeekdays 11 | } 12 | -------------------------------------------------------------------------------- /src/getTabbableNodes.ts: -------------------------------------------------------------------------------- 1 | import getFocusableNodes from './getFocusableNodes' 2 | 3 | export default function getTabbableNodes( 4 | target: HTMLElement = document.documentElement 5 | ): HTMLElement[] | never[] { 6 | return getFocusableNodes(target).filter( 7 | elem => 8 | elem instanceof HTMLElement && elem.getAttribute('tabindex') !== '-1' 9 | ) 10 | } 11 | -------------------------------------------------------------------------------- /src/htmlElements.ts: -------------------------------------------------------------------------------- 1 | const htmlElements = [ 2 | 'a', 3 | 'abbr', 4 | 'address', 5 | 'area', 6 | 'article', 7 | 'aside', 8 | 'audio', 9 | 'b', 10 | 'base', 11 | 'bdi', 12 | 'bdo', 13 | 'big', 14 | 'blockquote', 15 | 'body', 16 | 'br', 17 | 'button', 18 | 'canvas', 19 | 'caption', 20 | 'cite', 21 | 'code', 22 | 'col', 23 | 'colgroup', 24 | 'data', 25 | 'datalist', 26 | 'dd', 27 | 'del', 28 | 'details', 29 | 'dfn', 30 | 'dialog', 31 | 'div', 32 | 'dl', 33 | 'dt', 34 | 'em', 35 | 'embed', 36 | 'fieldset', 37 | 'figcaption', 38 | 'figure', 39 | 'footer', 40 | 'form', 41 | 'h1', 42 | 'h2', 43 | 'h3', 44 | 'h4', 45 | 'h5', 46 | 'h6', 47 | 'head', 48 | 'header', 49 | 'hgroup', 50 | 'hr', 51 | 'html', 52 | 'i', 53 | 'iframe', 54 | 'img', 55 | 'input', 56 | 'ins', 57 | 'kbd', 58 | 'keygen', 59 | 'label', 60 | 'legend', 61 | 'li', 62 | 'link', 63 | 'main', 64 | 'map', 65 | 'mark', 66 | 'menu', 67 | 'menuitem', 68 | 'meta', 69 | 'meter', 70 | 'nav', 71 | 'noscript', 72 | 'object', 73 | 'ol', 74 | 'optgroup', 75 | 'option', 76 | 'output', 77 | 'p', 78 | 'param', 79 | 'picture', 80 | 'pre', 81 | 'progress', 82 | 'q', 83 | 'rp', 84 | 'rt', 85 | 'ruby', 86 | 's', 87 | 'samp', 88 | 'script', 89 | 'section', 90 | 'select', 91 | 'small', 92 | 'source', 93 | 'span', 94 | 'strong', 95 | 'style', 96 | 'sub', 97 | 'summary', 98 | 'sup', 99 | 'table', 100 | 'tbody', 101 | 'td', 102 | 'textarea', 103 | 'tfoot', 104 | 'th', 105 | 'thead', 106 | 'time', 107 | 'title', 108 | 'tr', 109 | 'track', 110 | 'u', 111 | 'ul', 112 | 'var', 113 | 'video', 114 | 'wbr', 115 | 'circle', 116 | 'clipPath', 117 | 'defs', 118 | 'ellipse', 119 | 'g', 120 | 'image', 121 | 'line', 122 | 'linearGradient', 123 | 'mask', 124 | 'path', 125 | 'pattern', 126 | 'polygon', 127 | 'polyline', 128 | 'radialGradient', 129 | 'rect', 130 | 'stop', 131 | 'svg', 132 | 'text', 133 | 'tspan', 134 | ] as const 135 | 136 | type HTMLElements = typeof htmlElements[number] 137 | 138 | export { htmlElements as default, HTMLElements } 139 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /*! 2 | * @mrolaolu/helpers v0.3.2 3 | * https://github.com/whizkydee/helpers 4 | * (c) 2019-present Olaolu Olawuyi 5 | * Released under the MIT License. 6 | */ 7 | 8 | export { 9 | FileExtensions, 10 | MimeTypes, 11 | fileExtensionsMap, 12 | mimeTypesMap, 13 | getFileExtensionFromMimeType, 14 | getMimeTypeFromFileExtension, 15 | } from './mimeTypes' 16 | export { 17 | isIOS, 18 | isIE9, 19 | UA, 20 | inBrowser, 21 | isEdge, 22 | weexPlatform, 23 | isMacintosh, 24 | isAndroid, 25 | isPhantomJS, 26 | inWeex, 27 | isFF, 28 | isFirefox, 29 | isWindows, 30 | isChrome, 31 | isIE, 32 | } from './ua' 33 | export { default as amOrPm } from './amOrPm' 34 | export { default as cookiesToObject } from './cookiesToObject' 35 | export { default as countries } from './countries' 36 | export { default as countryDialCodes } from './countryDialCodes' 37 | export { default as debounce } from './debounce' 38 | export { default as dotAccess } from './dotAccess' 39 | export { 40 | Offset, 41 | ElementInViewOptions, 42 | default as elementInView, 43 | } from './elementInView' 44 | export { default as emitEvent } from './emitEvent' 45 | export { default as findIndex } from './findIndex' 46 | export { default as flattenStr } from './flattenStr' 47 | export { default as focusableSelectors } from './focusableSelectors' 48 | export { default as forEachValue } from './forEachValue' 49 | export { default as getAspectRatio } from './getAspectRatio' 50 | export { default as getEventPath } from './getEventPath' 51 | export { default as getFormFields } from './getFormFields' 52 | export { default as getFullMonthName } from './getFullMonthName' 53 | export { default as getFirstFocusableNode } from './getFirstFocusableNode' 54 | export { default as getFocusableNodes } from './getFocusableNodes' 55 | export { default as getLastFocusableNode } from './getLastFocusableNode' 56 | export { default as getFullWeekday } from './getFullWeekday' 57 | export { default as getShortMonthName } from './getShortMonthName' 58 | export { default as getShortWeekday } from './getShortWeekday' 59 | export { default as htmlElements, HTMLElements } from './htmlElements' 60 | export { default as isObject } from './isObject' 61 | export { default as isPrintableChar } from './isPrintableChar' 62 | export { default as isPlainObject } from './isPlainObject' 63 | export { default as looseEqual } from './looseEqual' 64 | export { default as matchesQuery } from './matchesQuery' 65 | export { default as memoize } from './memoize' 66 | export { default as monthNames, MonthNames } from './monthNames' 67 | export { default as objectIsEmpty } from './objectIsEmpty' 68 | export { default as observeMutations } from './observeMutations' 69 | export { default as once } from './once' 70 | export { default as openExternalWindow } from './openExternalWindow' 71 | export { default as parseHTML } from './parseHTML' 72 | export { default as prefixWithZero } from './prefixWithZero' 73 | export { default as pxToRem } from './pxToRem' 74 | export { default as queryFilter } from './queryFilter' 75 | export { default as randomHash } from './randomHash' 76 | export { default as resetScroll } from './resetScroll' 77 | export { default as rgbToHex } from './rgbToHex' 78 | export { default as scrollToElem } from './scrollToElem' 79 | export { default as shortMonthNames, ShortMonthNames } from './shortMonthNames' 80 | export { default as shortWeekdays, ShortWeekdays } from './shortWeekdays' 81 | export { default as sleep } from './sleep' 82 | export { default as slugify } from './slugify' 83 | export { default as smoothScroll } from './smoothScroll' 84 | export { default as swapKeysForValues } from './swapKeysForValues' 85 | export { default as toPx } from './toPx' 86 | export { default as trapFocus } from './trapFocus' 87 | export { default as toSnakeCase } from './toSnakeCase' 88 | export { default as uniq } from './uniq' 89 | export { default as unslash } from './unslash' 90 | export { default as unslashEnd } from './unslashEnd' 91 | export { default as unslashStart } from './unslashStart' 92 | export { default as wait } from './wait' 93 | export { default as weekdays, WeekDays } from './weekdays' 94 | export { 95 | safeEvery, 96 | safeFilter, 97 | safeFind, 98 | safeFindIndex, 99 | safeForEach, 100 | safeMap, 101 | safeReduce, 102 | safeReduceRight, 103 | safeSome, 104 | safeSort, 105 | } from 'safely-iterate' 106 | -------------------------------------------------------------------------------- /src/isArrayLike.ts: -------------------------------------------------------------------------------- 1 | export default function isArrayLike(value: any): boolean { 2 | return value != null && typeof value[Symbol.iterator] === 'function' 3 | } 4 | -------------------------------------------------------------------------------- /src/isObject.ts: -------------------------------------------------------------------------------- 1 | export default function isObject( 2 | payload: any 3 | ): payload is T { 4 | return payload !== null && typeof payload === 'object' 5 | } 6 | -------------------------------------------------------------------------------- /src/isPlainObject.ts: -------------------------------------------------------------------------------- 1 | export default function isPlainObject( 2 | payload: any 3 | ): payload is Record< 4 | PropertyKey, 5 | PropertyKey | bigint | boolean | null | object | any[] | undefined 6 | > { 7 | if (typeof payload != 'object' || payload === null) return false 8 | 9 | let proto = payload 10 | for (; Object.getPrototypeOf(proto) !== null; ) 11 | proto = Object.getPrototypeOf(proto) 12 | 13 | return Object.getPrototypeOf(payload) === proto 14 | } 15 | -------------------------------------------------------------------------------- /src/isPrintableChar.ts: -------------------------------------------------------------------------------- 1 | export default function isPrintableChar(event: KeyboardEvent): boolean { 2 | if ( 3 | !(event instanceof KeyboardEvent) || 4 | event.shiftKey || 5 | event.metaKey || 6 | event.ctrlKey || 7 | event.altKey 8 | ) { 9 | return false 10 | } 11 | 12 | return ( 13 | event.keyCode === 32 || 14 | (event.keyCode > 47 && event.keyCode < 58) || 15 | (event.keyCode > 64 && event.keyCode < 91) || 16 | (event.keyCode > 95 && event.keyCode < 112) || 17 | (event.keyCode > 185 && event.keyCode < 193) || 18 | (event.keyCode > 218 && event.keyCode < 223) 19 | ) 20 | } 21 | -------------------------------------------------------------------------------- /src/looseEqual.ts: -------------------------------------------------------------------------------- 1 | import isObject from './isObject' 2 | 3 | export default function looseEqual( 4 | a: any, 5 | b: any 6 | ): boolean { 7 | if (a === b) return true 8 | 9 | const isObjectA = isObject(a) 10 | const isObjectB = isObject(b) 11 | 12 | if (isObjectA && isObjectB) { 13 | try { 14 | const isArrayA = Array.isArray(a as any[] | T) 15 | const isArrayB = Array.isArray(b as any[] | T) 16 | 17 | if (isArrayA && isArrayB) { 18 | return ( 19 | (a as any[]).length === (b as any[]).length && 20 | (a as any[]).every((e: any, i: any) => looseEqual(e, (b as any[])[i])) 21 | ) 22 | } else if (a instanceof Date && b instanceof Date) { 23 | return a.getTime() === b.getTime() 24 | } else if (!isArrayA && !isArrayB) { 25 | const keysA = Object.keys(a as T) 26 | const keysB = Object.keys(b as T) 27 | 28 | return ( 29 | keysA.length === keysB.length && 30 | keysA.every(key => looseEqual(a[key], b[key])) 31 | ) 32 | } else { 33 | return false 34 | } 35 | } catch (e) { 36 | return false 37 | } 38 | } else if (!isObjectA && !isObjectB) { 39 | return String(a) === String(b) 40 | } else { 41 | return false 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/matchesQuery.ts: -------------------------------------------------------------------------------- 1 | export default function matchesQuery( 2 | query: string, 3 | cb?: MediaQueryListEvent 4 | ): boolean { 5 | let mql = window.matchMedia(query) 6 | if (typeof cb === 'function') { 7 | if ('onchange' in mql) mql.onchange = cb 8 | else mql!.addListener(cb) 9 | } 10 | return mql.matches 11 | } 12 | -------------------------------------------------------------------------------- /src/memoize.ts: -------------------------------------------------------------------------------- 1 | export default function memoize< 2 | T extends (...args: any[]) => void, 3 | U = never | ReturnType 4 | >( 5 | fn: T 6 | ): { 7 | (this: ThisParameterType): ReturnType 8 | cache: Map 9 | } { 10 | const cache = new Map() 11 | const result = function (this: ThisParameterType) { 12 | const value = arguments[0] 13 | return cache.has(value) 14 | ? cache.get(value) 15 | : cache.set(value, fn.call(this, value)) && cache.get(value) 16 | } 17 | result.cache = cache 18 | return result 19 | } 20 | -------------------------------------------------------------------------------- /src/mimeTypes.ts: -------------------------------------------------------------------------------- 1 | import swapKeysForValues from './swapKeysForValues' 2 | 3 | const fileExtensionsMap = { 4 | '.123': 'application/vnd.lotus-1-2-3', 5 | '.3dml': 'text/vnd.in3d.3dml', 6 | '.3g2': 'video/3gpp2', 7 | '.3gp': 'video/3gpp', 8 | '.a': 'application/octet-stream', 9 | '.aab': 'application/x-authorware-bin', 10 | '.aac': 'audio/x-aac', 11 | '.aam': 'application/x-authorware-map', 12 | '.aas': 'application/x-authorware-seg', 13 | '.abw': 'application/x-abiword', 14 | '.acc': 'application/vnd.americandynamics.acc', 15 | '.ace': 'application/x-ace-compressed', 16 | '.acu': 'application/vnd.acucobol', 17 | '.acutc': 'application/vnd.acucorp', 18 | '.adp': 'audio/adpcm', 19 | '.aep': 'application/vnd.audiograph', 20 | '.afm': 'application/x-font-type1', 21 | '.afp': 'application/vnd.ibm.modcap', 22 | '.ai': 'application/postscript', 23 | '.aif': 'audio/x-aiff', 24 | '.aifc': 'audio/x-aiff', 25 | '.aiff': 'audio/x-aiff', 26 | '.air': 'application/vnd.adobe.air-application-installer-package+zip', 27 | '.ami': 'application/vnd.amiga.ami', 28 | '.apk': 'application/vnd.android.package-archive', 29 | '.application': 'application/x-ms-application', 30 | '.apr': 'application/vnd.lotus-approach', 31 | '.asc': 'application/pgp-signature', 32 | '.asf': 'video/x-ms-asf', 33 | '.asm': 'text/x-asm', 34 | '.aso': 'application/vnd.accpac.simply.aso', 35 | '.asx': 'video/x-ms-asf', 36 | '.atc': 'application/vnd.acucorp', 37 | '.atom': 'application/atom+xml', 38 | '.atomcat': 'application/atomcat+xml', 39 | '.atomsvc': 'application/atomsvc+xml', 40 | '.atx': 'application/vnd.antix.game-component', 41 | '.au': 'audio/basic', 42 | '.avi': 'video/x-msvideo', 43 | '.aw': 'application/applixware', 44 | '.azf': 'application/vnd.airzip.filesecure.azf', 45 | '.azs': 'application/vnd.airzip.filesecure.azs', 46 | '.azw': 'application/vnd.amazon.ebook', 47 | '.bat': 'application/x-msdownload', 48 | '.bcpio': 'application/x-bcpio', 49 | '.bdf': 'application/x-font-bdf', 50 | '.bdm': 'application/vnd.syncml.dm+wbxml', 51 | '.bh2': 'application/vnd.fujitsu.oasysprs', 52 | '.bin': 'application/octet-stream', 53 | '.bmi': 'application/vnd.bmi', 54 | '.bmp': 'image/bmp', 55 | '.book': 'application/vnd.framemaker', 56 | '.box': 'application/vnd.previewsystems.box', 57 | '.boz': 'application/x-bzip2', 58 | '.bpk': 'application/octet-stream', 59 | '.btif': 'image/prs.btif', 60 | '.bz': 'application/x-bzip', 61 | '.bz2': 'application/x-bzip2', 62 | '.c': 'text/x-c', 63 | '.c4d': 'application/vnd.clonk.c4group', 64 | '.c4f': 'application/vnd.clonk.c4group', 65 | '.c4g': 'application/vnd.clonk.c4group', 66 | '.c4p': 'application/vnd.clonk.c4group', 67 | '.c4u': 'application/vnd.clonk.c4group', 68 | '.cab': 'application/vnd.ms-cab-compressed', 69 | '.car': 'application/vnd.curl.car', 70 | '.cat': 'application/vnd.ms-pki.seccat', 71 | '.cc': 'text/x-c', 72 | '.cct': 'application/x-director', 73 | '.ccxml': 'application/ccxml+xml', 74 | '.cdbcmsg': 'application/vnd.contact.cmsg', 75 | '.cdf': 'application/x-netcdf', 76 | '.cdkey': 'application/vnd.mediastation.cdkey', 77 | '.cdx': 'chemical/x-cdx', 78 | '.cdxml': 'application/vnd.chemdraw+xml', 79 | '.cdy': 'application/vnd.cinderella', 80 | '.cer': 'application/pkix-cert', 81 | '.cgm': 'image/cgm', 82 | '.chat': 'application/x-chat', 83 | '.chm': 'application/vnd.ms-htmlhelp', 84 | '.chrt': 'application/vnd.kde.kchart', 85 | '.cif': 'chemical/x-cif', 86 | '.cii': 'application/vnd.anser-web-certificate-issue-initiation', 87 | '.cil': 'application/vnd.ms-artgalry', 88 | '.cla': 'application/vnd.claymore', 89 | '.class': 'application/java-vm', 90 | '.clkk': 'application/vnd.crick.clicker.keyboard', 91 | '.clkp': 'application/vnd.crick.clicker.palette', 92 | '.clkt': 'application/vnd.crick.clicker.template', 93 | '.clkw': 'application/vnd.crick.clicker.wordbank', 94 | '.clkx': 'application/vnd.crick.clicker', 95 | '.clp': 'application/x-msclip', 96 | '.cmc': 'application/vnd.cosmocaller', 97 | '.cmdf': 'chemical/x-cmdf', 98 | '.cml': 'chemical/x-cml', 99 | '.cmp': 'application/vnd.yellowriver-custom-menu', 100 | '.cmx': 'image/x-cmx', 101 | '.cod': 'application/vnd.rim.cod', 102 | '.com': 'application/x-msdownload', 103 | '.conf': 'text/plain', 104 | '.cpio': 'application/x-cpio', 105 | '.cpp': 'text/x-c', 106 | '.cpt': 'application/mac-compactpro', 107 | '.crd': 'application/x-mscardfile', 108 | '.crl': 'application/pkix-crl', 109 | '.crt': 'application/x-x509-ca-cert', 110 | '.csh': 'application/x-csh', 111 | '.csml': 'chemical/x-csml', 112 | '.csp': 'application/vnd.commonspace', 113 | '.css': 'text/css', 114 | '.cst': 'application/x-director', 115 | '.csv': 'text/csv', 116 | '.cu': 'application/cu-seeme', 117 | '.curl': 'text/vnd.curl', 118 | '.cww': 'application/prs.cww', 119 | '.cxt': 'application/x-director', 120 | '.cxx': 'text/x-c', 121 | '.daf': 'application/vnd.mobius.daf', 122 | '.dataless': 'application/vnd.fdsn.seed', 123 | '.davmount': 'application/davmount+xml', 124 | '.dcr': 'application/x-director', 125 | '.dcurl': 'text/vnd.curl.dcurl', 126 | '.dd2': 'application/vnd.oma.dd2+xml', 127 | '.ddd': 'application/vnd.fujixerox.ddd', 128 | '.deb': 'application/x-debian-package', 129 | '.def': 'text/plain', 130 | '.deploy': 'application/octet-stream', 131 | '.der': 'application/x-x509-ca-cert', 132 | '.dfac': 'application/vnd.dreamfactory', 133 | '.dic': 'text/x-c', 134 | '.diff': 'text/plain', 135 | '.dir': 'application/x-director', 136 | '.dis': 'application/vnd.mobius.dis', 137 | '.dist': 'application/octet-stream', 138 | '.distz': 'application/octet-stream', 139 | '.djv': 'image/vnd.djvu', 140 | '.djvu': 'image/vnd.djvu', 141 | '.dll': 'application/x-msdownload', 142 | '.dmg': 'application/octet-stream', 143 | '.dms': 'application/octet-stream', 144 | '.dna': 'application/vnd.dna', 145 | '.doc': 'application/msword', 146 | '.docm': 'application/vnd.ms-word.document.macroenabled.12', 147 | '.docx': 148 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 149 | '.dot': 'application/msword', 150 | '.dotm': 'application/vnd.ms-word.template.macroenabled.12', 151 | '.dotx': 152 | 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 153 | '.dp': 'application/vnd.osgi.dp', 154 | '.dpg': 'application/vnd.dpgraph', 155 | '.dsc': 'text/prs.lines.tag', 156 | '.dtb': 'application/x-dtbook+xml', 157 | '.dtd': 'application/xml-dtd', 158 | '.dts': 'audio/vnd.dts', 159 | '.dtshd': 'audio/vnd.dts.hd', 160 | '.dump': 'application/octet-stream', 161 | '.dvi': 'application/x-dvi', 162 | '.dwf': 'model/vnd.dwf', 163 | '.dwg': 'image/vnd.dwg', 164 | '.dxf': 'image/vnd.dxf', 165 | '.dxp': 'application/vnd.spotfire.dxp', 166 | '.dxr': 'application/x-director', 167 | '.ecelp4800': 'audio/vnd.nuera.ecelp4800', 168 | '.ecelp7470': 'audio/vnd.nuera.ecelp7470', 169 | '.ecelp9600': 'audio/vnd.nuera.ecelp9600', 170 | '.ecma': 'application/ecmascript', 171 | '.edm': 'application/vnd.novadigm.edm', 172 | '.edx': 'application/vnd.novadigm.edx', 173 | '.efif': 'application/vnd.picsel', 174 | '.ei6': 'application/vnd.pg.osasli', 175 | '.elc': 'application/octet-stream', 176 | '.eml': 'message/rfc822', 177 | '.emma': 'application/emma+xml', 178 | '.eol': 'audio/vnd.digital-winds', 179 | '.eot': 'application/vnd.ms-fontobject', 180 | '.eps': 'application/postscript', 181 | '.epub': 'application/epub+zip', 182 | '.es3': 'application/vnd.eszigno3+xml', 183 | '.esf': 'application/vnd.epson.esf', 184 | '.et3': 'application/vnd.eszigno3+xml', 185 | '.etx': 'text/x-setext', 186 | '.exe': 'application/x-msdownload', 187 | '.ext': 'application/vnd.novadigm.ext', 188 | '.ez': 'application/andrew-inset', 189 | '.ez2': 'application/vnd.ezpix-album', 190 | '.ez3': 'application/vnd.ezpix-package', 191 | '.f': 'text/x-fortran', 192 | '.f4v': 'video/x-f4v', 193 | '.f77': 'text/x-fortran', 194 | '.f90': 'text/x-fortran', 195 | '.fbs': 'image/vnd.fastbidsheet', 196 | '.fdf': 'application/vnd.fdf', 197 | '.fe_launch': 'application/vnd.denovo.fcselayout-link', 198 | '.fg5': 'application/vnd.fujitsu.oasysgp', 199 | '.fgd': 'application/x-director', 200 | '.fh': 'image/x-freehand', 201 | '.fh4': 'image/x-freehand', 202 | '.fh5': 'image/x-freehand', 203 | '.fh7': 'image/x-freehand', 204 | '.fhc': 'image/x-freehand', 205 | '.fig': 'application/x-xfig', 206 | '.fli': 'video/x-fli', 207 | '.flo': 'application/vnd.micrografx.flo', 208 | '.flv': 'video/x-flv', 209 | '.flw': 'application/vnd.kde.kivio', 210 | '.flx': 'text/vnd.fmi.flexstor', 211 | '.fly': 'text/vnd.fly', 212 | '.fm': 'application/vnd.framemaker', 213 | '.fnc': 'application/vnd.frogans.fnc', 214 | '.for': 'text/x-fortran', 215 | '.fpx': 'image/vnd.fpx', 216 | '.frame': 'application/vnd.framemaker', 217 | '.fsc': 'application/vnd.fsc.weblaunch', 218 | '.fst': 'image/vnd.fst', 219 | '.ftc': 'application/vnd.fluxtime.clip', 220 | '.fti': 'application/vnd.anser-web-funds-transfer-initiation', 221 | '.fvt': 'video/vnd.fvt', 222 | '.fzs': 'application/vnd.fuzzysheet', 223 | '.g3': 'image/g3fax', 224 | '.gac': 'application/vnd.groove-account', 225 | '.gdl': 'model/vnd.gdl', 226 | '.geo': 'application/vnd.dynageo', 227 | '.gex': 'application/vnd.geometry-explorer', 228 | '.ggb': 'application/vnd.geogebra.file', 229 | '.ggt': 'application/vnd.geogebra.tool', 230 | '.ghf': 'application/vnd.groove-help', 231 | '.gif': 'image/gif', 232 | '.gim': 'application/vnd.groove-identity-message', 233 | '.gmx': 'application/vnd.gmx', 234 | '.gnumeric': 'application/x-gnumeric', 235 | '.gph': 'application/vnd.flographit', 236 | '.gqf': 'application/vnd.grafeq', 237 | '.gqs': 'application/vnd.grafeq', 238 | '.gram': 'application/srgs', 239 | '.gre': 'application/vnd.geometry-explorer', 240 | '.grv': 'application/vnd.groove-injector', 241 | '.grxml': 'application/srgs+xml', 242 | '.gsf': 'application/x-font-ghostscript', 243 | '.gtar': 'application/x-gtar', 244 | '.gtm': 'application/vnd.groove-tool-message', 245 | '.gtw': 'model/vnd.gtw', 246 | '.gv': 'text/vnd.graphviz', 247 | '.gz': 'application/x-gzip', 248 | '.h': 'text/x-c', 249 | '.h261': 'video/h261', 250 | '.h263': 'video/h263', 251 | '.h264': 'video/h264', 252 | '.hbci': 'application/vnd.hbci', 253 | '.hdf': 'application/x-hdf', 254 | '.hh': 'text/x-c', 255 | '.hlp': 'application/winhlp', 256 | '.hpgl': 'application/vnd.hp-hpgl', 257 | '.hpid': 'application/vnd.hp-hpid', 258 | '.hps': 'application/vnd.hp-hps', 259 | '.hqx': 'application/mac-binhex40', 260 | '.htke': 'application/vnd.kenameaapp', 261 | '.htm': 'text/html', 262 | '.html': 'text/html', 263 | '.hvd': 'application/vnd.yamaha.hv-dic', 264 | '.hvp': 'application/vnd.yamaha.hv-voice', 265 | '.hvs': 'application/vnd.yamaha.hv-script', 266 | '.icc': 'application/vnd.iccprofile', 267 | '.ice': 'x-conference/x-cooltalk', 268 | '.icm': 'application/vnd.iccprofile', 269 | '.ico': 'image/x-icon', 270 | '.ics': 'text/calendar', 271 | '.ief': 'image/ief', 272 | '.ifb': 'text/calendar', 273 | '.ifm': 'application/vnd.shana.informed.formdata', 274 | '.iges': 'model/iges', 275 | '.igl': 'application/vnd.igloader', 276 | '.igs': 'model/iges', 277 | '.igx': 'application/vnd.micrografx.igx', 278 | '.iif': 'application/vnd.shana.informed.interchange', 279 | '.imp': 'application/vnd.accpac.simply.imp', 280 | '.ims': 'application/vnd.ms-ims', 281 | '.in': 'text/plain', 282 | '.ipk': 'application/vnd.shana.informed.package', 283 | '.irm': 'application/vnd.ibm.rights-management', 284 | '.irp': 'application/vnd.irepository.package+xml', 285 | '.iso': 'application/octet-stream', 286 | '.itp': 'application/vnd.shana.informed.formtemplate', 287 | '.ivp': 'application/vnd.immervision-ivp', 288 | '.ivu': 'application/vnd.immervision-ivu', 289 | '.jad': 'text/vnd.sun.j2me.app-descriptor', 290 | '.jam': 'application/vnd.jam', 291 | '.jar': 'application/java-archive', 292 | '.java': 'text/x-java-source', 293 | '.jisp': 'application/vnd.jisp', 294 | '.jlt': 'application/vnd.hp-jlyt', 295 | '.jnlp': 'application/x-java-jnlp-file', 296 | '.joda': 'application/vnd.joost.joda-archive', 297 | '.jpe': 'image/jpeg', 298 | '.jpeg': 'image/jpeg', 299 | '.jpg': 'image/jpeg', 300 | '.jpgm': 'video/jpm', 301 | '.jpgv': 'video/jpeg', 302 | '.jpm': 'video/jpm', 303 | '.js': 'application/javascript', 304 | '.json': 'application/json', 305 | '.kar': 'audio/midi', 306 | '.karbon': 'application/vnd.kde.karbon', 307 | '.kfo': 'application/vnd.kde.kformula', 308 | '.kia': 'application/vnd.kidspiration', 309 | '.kil': 'application/x-killustrator', 310 | '.kml': 'application/vnd.google-earth.kml+xml', 311 | '.kmz': 'application/vnd.google-earth.kmz', 312 | '.kne': 'application/vnd.kinar', 313 | '.knp': 'application/vnd.kinar', 314 | '.kon': 'application/vnd.kde.kontour', 315 | '.kpr': 'application/vnd.kde.kpresenter', 316 | '.kpt': 'application/vnd.kde.kpresenter', 317 | '.ksh': 'text/plain', 318 | '.ksp': 'application/vnd.kde.kspread', 319 | '.ktr': 'application/vnd.kahootz', 320 | '.ktz': 'application/vnd.kahootz', 321 | '.kwd': 'application/vnd.kde.kword', 322 | '.kwt': 'application/vnd.kde.kword', 323 | '.latex': 'application/x-latex', 324 | '.lbd': 'application/vnd.llamagraphics.life-balance.desktop', 325 | '.lbe': 'application/vnd.llamagraphics.life-balance.exchange+xml', 326 | '.les': 'application/vnd.hhe.lesson-player', 327 | '.lha': 'application/octet-stream', 328 | '.link66': 'application/vnd.route66.link66+xml', 329 | '.list': 'text/plain', 330 | '.list3820': 'application/vnd.ibm.modcap', 331 | '.listafp': 'application/vnd.ibm.modcap', 332 | '.log': 'text/plain', 333 | '.lostxml': 'application/lost+xml', 334 | '.lrf': 'application/octet-stream', 335 | '.lrm': 'application/vnd.ms-lrm', 336 | '.ltf': 'application/vnd.frogans.ltf', 337 | '.lvp': 'audio/vnd.lucent.voice', 338 | '.lwp': 'application/vnd.lotus-wordpro', 339 | '.lzh': 'application/octet-stream', 340 | '.m13': 'application/x-msmediaview', 341 | '.m14': 'application/x-msmediaview', 342 | '.m1v': 'video/mpeg', 343 | '.m2a': 'audio/mpeg', 344 | '.m2v': 'video/mpeg', 345 | '.m3a': 'audio/mpeg', 346 | '.m3u': 'audio/x-mpegurl', 347 | '.m4u': 'video/vnd.mpegurl', 348 | '.m4v': 'video/x-m4v', 349 | '.ma': 'application/mathematica', 350 | '.mag': 'application/vnd.ecowin.chart', 351 | '.maker': 'application/vnd.framemaker', 352 | '.man': 'text/troff', 353 | '.mathml': 'application/mathml+xml', 354 | '.mb': 'application/mathematica', 355 | '.mbk': 'application/vnd.mobius.mbk', 356 | '.mbox': 'application/mbox', 357 | '.mc1': 'application/vnd.medcalcdata', 358 | '.mcd': 'application/vnd.mcd', 359 | '.mcurl': 'text/vnd.curl.mcurl', 360 | '.mdb': 'application/x-msaccess', 361 | '.mdi': 'image/vnd.ms-modi', 362 | '.me': 'text/troff', 363 | '.mesh': 'model/mesh', 364 | '.mfm': 'application/vnd.mfmp', 365 | '.mgz': 'application/vnd.proteus.magazine', 366 | '.mht': 'message/rfc822', 367 | '.mhtml': 'message/rfc822', 368 | '.mid': 'audio/midi', 369 | '.midi': 'audio/midi', 370 | '.mif': 'application/vnd.mif', 371 | '.mime': 'message/rfc822', 372 | '.mj2': 'video/mj2', 373 | '.mjp2': 'video/mj2', 374 | '.mlp': 'application/vnd.dolby.mlp', 375 | '.mmd': 'application/vnd.chipnuts.karaoke-mmd', 376 | '.mmf': 'application/vnd.smaf', 377 | '.mmr': 'image/vnd.fujixerox.edmics-mmr', 378 | '.mny': 'application/x-msmoney', 379 | '.mobi': 'application/x-mobipocket-ebook', 380 | '.mov': 'video/quicktime', 381 | '.movie': 'video/x-sgi-movie', 382 | '.mp2': 'audio/mpeg', 383 | '.mp2a': 'audio/mpeg', 384 | '.mp3': 'audio/mpeg', 385 | '.mp4': 'video/mp4', 386 | '.mp4a': 'audio/mp4', 387 | '.mp4s': 'application/mp4', 388 | '.mp4v': 'video/mp4', 389 | '.mpa': 'video/mpeg', 390 | '.mpc': 'application/vnd.mophun.certificate', 391 | '.mpe': 'video/mpeg', 392 | '.mpeg': 'video/mpeg', 393 | '.mpg': 'video/mpeg', 394 | '.mpg4': 'video/mp4', 395 | '.mpga': 'audio/mpeg', 396 | '.mpkg': 'application/vnd.apple.installer+xml', 397 | '.mpm': 'application/vnd.blueice.multipass', 398 | '.mpn': 'application/vnd.mophun.application', 399 | '.mpp': 'application/vnd.ms-project', 400 | '.mpt': 'application/vnd.ms-project', 401 | '.mpy': 'application/vnd.ibm.minipay', 402 | '.mqy': 'application/vnd.mobius.mqy', 403 | '.mrc': 'application/marc', 404 | '.ms': 'text/troff', 405 | '.mscml': 'application/mediaservercontrol+xml', 406 | '.mseed': 'application/vnd.fdsn.mseed', 407 | '.mseq': 'application/vnd.mseq', 408 | '.msf': 'application/vnd.epson.msf', 409 | '.msh': 'model/mesh', 410 | '.msi': 'application/x-msdownload', 411 | '.msl': 'application/vnd.mobius.msl', 412 | '.msty': 'application/vnd.muvee.style', 413 | '.mts': 'model/vnd.mts', 414 | '.mus': 'application/vnd.musician', 415 | '.musicxml': 'application/vnd.recordare.musicxml+xml', 416 | '.mvb': 'application/x-msmediaview', 417 | '.mwf': 'application/vnd.mfer', 418 | '.mxf': 'application/mxf', 419 | '.mxl': 'application/vnd.recordare.musicxml', 420 | '.mxml': 'application/xv+xml', 421 | '.mxs': 'application/vnd.triscape.mxs', 422 | '.mxu': 'video/vnd.mpegurl', 423 | '.n-gage': 'application/vnd.nokia.n-gage.symbian.install', 424 | '.nb': 'application/mathematica', 425 | '.nc': 'application/x-netcdf', 426 | '.ncx': 'application/x-dtbncx+xml', 427 | '.ngdat': 'application/vnd.nokia.n-gage.data', 428 | '.nlu': 'application/vnd.neurolanguage.nlu', 429 | '.nml': 'application/vnd.enliven', 430 | '.nnd': 'application/vnd.noblenet-directory', 431 | '.nns': 'application/vnd.noblenet-sealer', 432 | '.nnw': 'application/vnd.noblenet-web', 433 | '.npx': 'image/vnd.net-fpx', 434 | '.nsf': 'application/vnd.lotus-notes', 435 | '.nws': 'message/rfc822', 436 | '.o': 'application/octet-stream', 437 | '.oa2': 'application/vnd.fujitsu.oasys2', 438 | '.oa3': 'application/vnd.fujitsu.oasys3', 439 | '.oas': 'application/vnd.fujitsu.oasys', 440 | '.obd': 'application/x-msbinder', 441 | '.obj': 'application/octet-stream', 442 | '.oda': 'application/oda', 443 | '.odb': 'application/vnd.oasis.opendocument.database', 444 | '.odc': 'application/vnd.oasis.opendocument.chart', 445 | '.odf': 'application/vnd.oasis.opendocument.formula', 446 | '.odft': 'application/vnd.oasis.opendocument.formula-template', 447 | '.odg': 'application/vnd.oasis.opendocument.graphics', 448 | '.odi': 'application/vnd.oasis.opendocument.image', 449 | '.odp': 'application/vnd.oasis.opendocument.presentation', 450 | '.ods': 'application/vnd.oasis.opendocument.spreadsheet', 451 | '.odt': 'application/vnd.oasis.opendocument.text', 452 | '.oga': 'audio/ogg', 453 | '.ogg': 'audio/ogg', 454 | '.ogv': 'video/ogg', 455 | '.ogx': 'application/ogg', 456 | '.onepkg': 'application/onenote', 457 | '.onetmp': 'application/onenote', 458 | '.onetoc': 'application/onenote', 459 | '.onetoc2': 'application/onenote', 460 | '.opf': 'application/oebps-package+xml', 461 | '.oprc': 'application/vnd.palm', 462 | '.org': 'application/vnd.lotus-organizer', 463 | '.osf': 'application/vnd.yamaha.openscoreformat', 464 | '.osfpvg': 'application/vnd.yamaha.openscoreformat.osfpvg+xml', 465 | '.otc': 'application/vnd.oasis.opendocument.chart-template', 466 | '.otf': 'application/x-font-otf', 467 | '.otg': 'application/vnd.oasis.opendocument.graphics-template', 468 | '.oth': 'application/vnd.oasis.opendocument.text-web', 469 | '.oti': 'application/vnd.oasis.opendocument.image-template', 470 | '.otm': 'application/vnd.oasis.opendocument.text-master', 471 | '.otp': 'application/vnd.oasis.opendocument.presentation-template', 472 | '.ots': 'application/vnd.oasis.opendocument.spreadsheet-template', 473 | '.ott': 'application/vnd.oasis.opendocument.text-template', 474 | '.oxt': 'application/vnd.openofficeorg.extension', 475 | '.p': 'text/x-pascal', 476 | '.p10': 'application/pkcs10', 477 | '.p12': 'application/x-pkcs12', 478 | '.p7b': 'application/x-pkcs7-certificates', 479 | '.p7c': 'application/pkcs7-mime', 480 | '.p7m': 'application/pkcs7-mime', 481 | '.p7r': 'application/x-pkcs7-certreqresp', 482 | '.p7s': 'application/pkcs7-signature', 483 | '.pas': 'text/x-pascal', 484 | '.pbd': 'application/vnd.powerbuilder6', 485 | '.pbm': 'image/x-portable-bitmap', 486 | '.pcf': 'application/x-font-pcf', 487 | '.pcl': 'application/vnd.hp-pcl', 488 | '.pclxl': 'application/vnd.hp-pclxl', 489 | '.pct': 'image/x-pict', 490 | '.pcurl': 'application/vnd.curl.pcurl', 491 | '.pcx': 'image/x-pcx', 492 | '.pdb': 'application/vnd.palm', 493 | '.pdf': 'application/pdf', 494 | '.pfa': 'application/x-font-type1', 495 | '.pfb': 'application/x-font-type1', 496 | '.pfm': 'application/x-font-type1', 497 | '.pfr': 'application/font-tdpfr', 498 | '.pfx': 'application/x-pkcs12', 499 | '.pgm': 'image/x-portable-graymap', 500 | '.pgn': 'application/x-chess-pgn', 501 | '.pgp': 'application/pgp-encrypted', 502 | '.pic': 'image/x-pict', 503 | '.pkg': 'application/octet-stream', 504 | '.pki': 'application/pkixcmp', 505 | '.pkipath': 'application/pkix-pkipath', 506 | '.pl': 'text/plain', 507 | '.plb': 'application/vnd.3gpp.pic-bw-large', 508 | '.plc': 'application/vnd.mobius.plc', 509 | '.plf': 'application/vnd.pocketlearn', 510 | '.pls': 'application/pls+xml', 511 | '.pml': 'application/vnd.ctc-posml', 512 | '.png': 'image/png', 513 | '.pnm': 'image/x-portable-anymap', 514 | '.portpkg': 'application/vnd.macports.portpkg', 515 | '.pot': 'application/vnd.ms-powerpoint', 516 | '.potm': 'application/vnd.ms-powerpoint.template.macroenabled.12', 517 | '.potx': 518 | 'application/vnd.openxmlformats-officedocument.presentationml.template', 519 | '.ppa': 'application/vnd.ms-powerpoint', 520 | '.ppam': 'application/vnd.ms-powerpoint.addin.macroenabled.12', 521 | '.ppd': 'application/vnd.cups-ppd', 522 | '.ppm': 'image/x-portable-pixmap', 523 | '.pps': 'application/vnd.ms-powerpoint', 524 | '.ppsm': 'application/vnd.ms-powerpoint.slideshow.macroenabled.12', 525 | '.ppsx': 526 | 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 527 | '.ppt': 'application/vnd.ms-powerpoint', 528 | '.pptm': 'application/vnd.ms-powerpoint.presentation.macroenabled.12', 529 | '.pptx': 530 | 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 531 | '.pqa': 'application/vnd.palm', 532 | '.prc': 'application/x-mobipocket-ebook', 533 | '.pre': 'application/vnd.lotus-freelance', 534 | '.prf': 'application/pics-rules', 535 | '.ps': 'application/postscript', 536 | '.psb': 'application/vnd.3gpp.pic-bw-small', 537 | '.psd': 'image/vnd.adobe.photoshop', 538 | '.psf': 'application/x-font-linux-psf', 539 | '.ptid': 'application/vnd.pvi.ptid1', 540 | '.pub': 'application/x-mspublisher', 541 | '.pvb': 'application/vnd.3gpp.pic-bw-var', 542 | '.pwn': 'application/vnd.3m.post-it-notes', 543 | '.pwz': 'application/vnd.ms-powerpoint', 544 | '.py': 'text/x-python', 545 | '.pya': 'audio/vnd.ms-playready.media.pya', 546 | '.pyc': 'application/x-python-code', 547 | '.pyo': 'application/x-python-code', 548 | '.pyv': 'video/vnd.ms-playready.media.pyv', 549 | '.qam': 'application/vnd.epson.quickanime', 550 | '.qbo': 'application/vnd.intu.qbo', 551 | '.qfx': 'application/vnd.intu.qfx', 552 | '.qps': 'application/vnd.publishare-delta-tree', 553 | '.qt': 'video/quicktime', 554 | '.qwd': 'application/vnd.quark.quarkxpress', 555 | '.qwt': 'application/vnd.quark.quarkxpress', 556 | '.qxb': 'application/vnd.quark.quarkxpress', 557 | '.qxd': 'application/vnd.quark.quarkxpress', 558 | '.qxl': 'application/vnd.quark.quarkxpress', 559 | '.qxt': 'application/vnd.quark.quarkxpress', 560 | '.ra': 'audio/x-pn-realaudio', 561 | '.ram': 'audio/x-pn-realaudio', 562 | '.rar': 'application/x-rar-compressed', 563 | '.ras': 'image/x-cmu-raster', 564 | '.rcprofile': 'application/vnd.ipunplugged.rcprofile', 565 | '.rdf': 'application/rdf+xml', 566 | '.rdz': 'application/vnd.data-vision.rdz', 567 | '.rep': 'application/vnd.businessobjects', 568 | '.res': 'application/x-dtbresource+xml', 569 | '.rgb': 'image/x-rgb', 570 | '.rif': 'application/reginfo+xml', 571 | '.rl': 'application/resource-lists+xml', 572 | '.rlc': 'image/vnd.fujixerox.edmics-rlc', 573 | '.rld': 'application/resource-lists-diff+xml', 574 | '.rm': 'application/vnd.rn-realmedia', 575 | '.rmi': 'audio/midi', 576 | '.rmp': 'audio/x-pn-realaudio-plugin', 577 | '.rms': 'application/vnd.jcp.javame.midlet-rms', 578 | '.rnc': 'application/relax-ng-compact-syntax', 579 | '.roff': 'text/troff', 580 | '.rpm': 'application/x-rpm', 581 | '.rpss': 'application/vnd.nokia.radio-presets', 582 | '.rpst': 'application/vnd.nokia.radio-preset', 583 | '.rq': 'application/sparql-query', 584 | '.rs': 'application/rls-services+xml', 585 | '.rsd': 'application/rsd+xml', 586 | '.rss': 'application/rss+xml', 587 | '.rtf': 'application/rtf', 588 | '.rtx': 'text/richtext', 589 | '.s': 'text/x-asm', 590 | '.saf': 'application/vnd.yamaha.smaf-audio', 591 | '.sbml': 'application/sbml+xml', 592 | '.sc': 'application/vnd.ibm.secure-container', 593 | '.scd': 'application/x-msschedule', 594 | '.scm': 'application/vnd.lotus-screencam', 595 | '.scq': 'application/scvp-cv-request', 596 | '.scs': 'application/scvp-cv-response', 597 | '.scurl': 'text/vnd.curl.scurl', 598 | '.sda': 'application/vnd.stardivision.draw', 599 | '.sdc': 'application/vnd.stardivision.calc', 600 | '.sdd': 'application/vnd.stardivision.impress', 601 | '.sdkd': 'application/vnd.solent.sdkm+xml', 602 | '.sdkm': 'application/vnd.solent.sdkm+xml', 603 | '.sdp': 'application/sdp', 604 | '.sdw': 'application/vnd.stardivision.writer', 605 | '.see': 'application/vnd.seemail', 606 | '.seed': 'application/vnd.fdsn.seed', 607 | '.sema': 'application/vnd.sema', 608 | '.semd': 'application/vnd.semd', 609 | '.semf': 'application/vnd.semf', 610 | '.ser': 'application/java-serialized-object', 611 | '.setpay': 'application/set-payment-initiation', 612 | '.setreg': 'application/set-registration-initiation', 613 | '.sfd-hdstx': 'application/vnd.hydrostatix.sof-data', 614 | '.sfs': 'application/vnd.spotfire.sfs', 615 | '.sgl': 'application/vnd.stardivision.writer-global', 616 | '.sgm': 'text/sgml', 617 | '.sgml': 'text/sgml', 618 | '.sh': 'application/x-sh', 619 | '.shar': 'application/x-shar', 620 | '.shf': 'application/shf+xml', 621 | '.si': 'text/vnd.wap.si', 622 | '.sic': 'application/vnd.wap.sic', 623 | '.sig': 'application/pgp-signature', 624 | '.silo': 'model/mesh', 625 | '.sis': 'application/vnd.symbian.install', 626 | '.sisx': 'application/vnd.symbian.install', 627 | '.sit': 'application/x-stuffit', 628 | '.sitx': 'application/x-stuffitx', 629 | '.skd': 'application/vnd.koan', 630 | '.skm': 'application/vnd.koan', 631 | '.skp': 'application/vnd.koan', 632 | '.skt': 'application/vnd.koan', 633 | '.sl': 'text/vnd.wap.sl', 634 | '.slc': 'application/vnd.wap.slc', 635 | '.sldm': 'application/vnd.ms-powerpoint.slide.macroenabled.12', 636 | '.sldx': 'application/vnd.openxmlformats-officedocument.presentationml.slide', 637 | '.slt': 'application/vnd.epson.salt', 638 | '.smf': 'application/vnd.stardivision.math', 639 | '.smi': 'application/smil+xml', 640 | '.smil': 'application/smil+xml', 641 | '.snd': 'audio/basic', 642 | '.snf': 'application/x-font-snf', 643 | '.so': 'application/octet-stream', 644 | '.spc': 'application/x-pkcs7-certificates', 645 | '.spf': 'application/vnd.yamaha.smaf-phrase', 646 | '.spl': 'application/x-futuresplash', 647 | '.spot': 'text/vnd.in3d.spot', 648 | '.spp': 'application/scvp-vp-response', 649 | '.spq': 'application/scvp-vp-request', 650 | '.spx': 'audio/ogg', 651 | '.src': 'application/x-wais-source', 652 | '.srx': 'application/sparql-results+xml', 653 | '.sse': 'application/vnd.kodak-descriptor', 654 | '.ssf': 'application/vnd.epson.ssf', 655 | '.ssml': 'application/ssml+xml', 656 | '.stc': 'application/vnd.sun.xml.calc.template', 657 | '.std': 'application/vnd.sun.xml.draw.template', 658 | '.stf': 'application/vnd.wt.stf', 659 | '.sti': 'application/vnd.sun.xml.impress.template', 660 | '.stk': 'application/hyperstudio', 661 | '.stl': 'application/vnd.ms-pki.stl', 662 | '.str': 'application/vnd.pg.format', 663 | '.stw': 'application/vnd.sun.xml.writer.template', 664 | '.sus': 'application/vnd.sus-calendar', 665 | '.susp': 'application/vnd.sus-calendar', 666 | '.sv4cpio': 'application/x-sv4cpio', 667 | '.sv4crc': 'application/x-sv4crc', 668 | '.svd': 'application/vnd.svd', 669 | '.svg': 'image/svg+xml', 670 | '.svgz': 'image/svg+xml', 671 | '.swa': 'application/x-director', 672 | '.swf': 'application/x-shockwave-flash', 673 | '.swi': 'application/vnd.arastra.swi', 674 | '.sxc': 'application/vnd.sun.xml.calc', 675 | '.sxd': 'application/vnd.sun.xml.draw', 676 | '.sxg': 'application/vnd.sun.xml.writer.global', 677 | '.sxi': 'application/vnd.sun.xml.impress', 678 | '.sxm': 'application/vnd.sun.xml.math', 679 | '.sxw': 'application/vnd.sun.xml.writer', 680 | '.t': 'text/troff', 681 | '.tao': 'application/vnd.tao.intent-module-archive', 682 | '.tar': 'application/x-tar', 683 | '.tcap': 'application/vnd.3gpp2.tcap', 684 | '.tcl': 'application/x-tcl', 685 | '.teacher': 'application/vnd.smart.teacher', 686 | '.tex': 'application/x-tex', 687 | '.texi': 'application/x-texinfo', 688 | '.texinfo': 'application/x-texinfo', 689 | '.text': 'text/plain', 690 | '.tfm': 'application/x-tex-tfm', 691 | '.tgz': 'application/x-gzip', 692 | '.tif': 'image/tiff', 693 | '.tiff': 'image/tiff', 694 | '.tmo': 'application/vnd.tmobile-livetv', 695 | '.torrent': 'application/x-bittorrent', 696 | '.tpl': 'application/vnd.groove-tool-template', 697 | '.tpt': 'application/vnd.trid.tpt', 698 | '.tr': 'text/troff', 699 | '.tra': 'application/vnd.trueapp', 700 | '.trm': 'application/x-msterminal', 701 | '.tsv': 'text/tab-separated-values', 702 | '.ttc': 'application/x-font-ttf', 703 | '.ttf': 'application/x-font-ttf', 704 | '.twd': 'application/vnd.simtech-mindmapper', 705 | '.twds': 'application/vnd.simtech-mindmapper', 706 | '.txd': 'application/vnd.genomatix.tuxedo', 707 | '.txf': 'application/vnd.mobius.txf', 708 | '.txt': 'text/plain', 709 | '.u32': 'application/x-authorware-bin', 710 | '.udeb': 'application/x-debian-package', 711 | '.ufd': 'application/vnd.ufdl', 712 | '.ufdl': 'application/vnd.ufdl', 713 | '.umj': 'application/vnd.umajin', 714 | '.unityweb': 'application/vnd.unity', 715 | '.uoml': 'application/vnd.uoml+xml', 716 | '.uri': 'text/uri-list', 717 | '.uris': 'text/uri-list', 718 | '.urls': 'text/uri-list', 719 | '.ustar': 'application/x-ustar', 720 | '.utz': 'application/vnd.uiq.theme', 721 | '.uu': 'text/x-uuencode', 722 | '.vcd': 'application/x-cdlink', 723 | '.vcf': 'text/x-vcard', 724 | '.vcg': 'application/vnd.groove-vcard', 725 | '.vcs': 'text/x-vcalendar', 726 | '.vcx': 'application/vnd.vcx', 727 | '.vis': 'application/vnd.visionary', 728 | '.viv': 'video/vnd.vivo', 729 | '.vor': 'application/vnd.stardivision.writer', 730 | '.vox': 'application/x-authorware-bin', 731 | '.vrml': 'model/vrml', 732 | '.vsd': 'application/vnd.visio', 733 | '.vsf': 'application/vnd.vsf', 734 | '.vss': 'application/vnd.visio', 735 | '.vst': 'application/vnd.visio', 736 | '.vsw': 'application/vnd.visio', 737 | '.vtu': 'model/vnd.vtu', 738 | '.vxml': 'application/voicexml+xml', 739 | '.w3d': 'application/x-director', 740 | '.wad': 'application/x-doom', 741 | '.wav': 'audio/x-wav', 742 | '.wax': 'audio/x-ms-wax', 743 | '.wbmp': 'image/vnd.wap.wbmp', 744 | '.wbs': 'application/vnd.criticaltools.wbs+xml', 745 | '.wbxml': 'application/vnd.wap.wbxml', 746 | '.wcm': 'application/vnd.ms-works', 747 | '.wdb': 'application/vnd.ms-works', 748 | '.wiz': 'application/msword', 749 | '.wks': 'application/vnd.ms-works', 750 | '.wm': 'video/x-ms-wm', 751 | '.wma': 'audio/x-ms-wma', 752 | '.wmd': 'application/x-ms-wmd', 753 | '.wmf': 'application/x-msmetafile', 754 | '.wml': 'text/vnd.wap.wml', 755 | '.wmlc': 'application/vnd.wap.wmlc', 756 | '.wmls': 'text/vnd.wap.wmlscript', 757 | '.wmlsc': 'application/vnd.wap.wmlscriptc', 758 | '.wmv': 'video/x-ms-wmv', 759 | '.wmx': 'video/x-ms-wmx', 760 | '.wmz': 'application/x-ms-wmz', 761 | '.wpd': 'application/vnd.wordperfect', 762 | '.wpl': 'application/vnd.ms-wpl', 763 | '.wps': 'application/vnd.ms-works', 764 | '.wqd': 'application/vnd.wqd', 765 | '.wri': 'application/x-mswrite', 766 | '.wrl': 'model/vrml', 767 | '.wsdl': 'application/wsdl+xml', 768 | '.wspolicy': 'application/wspolicy+xml', 769 | '.wtb': 'application/vnd.webturbo', 770 | '.wvx': 'video/x-ms-wvx', 771 | '.x32': 'application/x-authorware-bin', 772 | '.x3d': 'application/vnd.hzn-3d-crossword', 773 | '.xap': 'application/x-silverlight-app', 774 | '.xar': 'application/vnd.xara', 775 | '.xbap': 'application/x-ms-xbap', 776 | '.xbd': 'application/vnd.fujixerox.docuworks.binder', 777 | '.xbm': 'image/x-xbitmap', 778 | '.xdm': 'application/vnd.syncml.dm+xml', 779 | '.xdp': 'application/vnd.adobe.xdp+xml', 780 | '.xdw': 'application/vnd.fujixerox.docuworks', 781 | '.xenc': 'application/xenc+xml', 782 | '.xer': 'application/patch-ops-error+xml', 783 | '.xfdf': 'application/vnd.adobe.xfdf', 784 | '.xfdl': 'application/vnd.xfdl', 785 | '.xht': 'application/xhtml+xml', 786 | '.xhtml': 'application/xhtml+xml', 787 | '.xhvml': 'application/xv+xml', 788 | '.xif': 'image/vnd.xiff', 789 | '.xla': 'application/vnd.ms-excel', 790 | '.xlam': 'application/vnd.ms-excel.addin.macroenabled.12', 791 | '.xlb': 'application/vnd.ms-excel', 792 | '.xlc': 'application/vnd.ms-excel', 793 | '.xlm': 'application/vnd.ms-excel', 794 | '.xls': 'application/vnd.ms-excel', 795 | '.xlsb': 'application/vnd.ms-excel.sheet.binary.macroenabled.12', 796 | '.xlsm': 'application/vnd.ms-excel.sheet.macroenabled.12', 797 | '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 798 | '.xlt': 'application/vnd.ms-excel', 799 | '.xltm': 'application/vnd.ms-excel.template.macroenabled.12', 800 | '.xltx': 801 | 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 802 | '.xlw': 'application/vnd.ms-excel', 803 | '.xml': 'application/xml', 804 | '.xo': 'application/vnd.olpc-sugar', 805 | '.xop': 'application/xop+xml', 806 | '.xpdl': 'application/xml', 807 | '.xpi': 'application/x-xpinstall', 808 | '.xpm': 'image/x-xpixmap', 809 | '.xpr': 'application/vnd.is-xpr', 810 | '.xps': 'application/vnd.ms-xpsdocument', 811 | '.xpw': 'application/vnd.intercon.formnet', 812 | '.xpx': 'application/vnd.intercon.formnet', 813 | '.xsl': 'application/xml', 814 | '.xslt': 'application/xslt+xml', 815 | '.xsm': 'application/vnd.syncml+xml', 816 | '.xspf': 'application/xspf+xml', 817 | '.xul': 'application/vnd.mozilla.xul+xml', 818 | '.xvm': 'application/xv+xml', 819 | '.xvml': 'application/xv+xml', 820 | '.xwd': 'image/x-xwindowdump', 821 | '.xyz': 'chemical/x-xyz', 822 | '.zaz': 'application/vnd.zzazz.deck+xml', 823 | '.zip': 'application/zip', 824 | '.zir': 'application/vnd.zul', 825 | '.zirz': 'application/vnd.zul', 826 | '.zmm': 'application/vnd.handheld-entertainment+xml', 827 | } as const 828 | 829 | type FileExtensions = keyof typeof fileExtensionsMap 830 | type MimeTypes = ValueOf 831 | 832 | // pretty fast object key-value swap. 833 | const mimeTypesMap = swapKeysForValues(fileExtensionsMap) 834 | 835 | function getFileExtensionFromMimeType( 836 | mimeType: MimeTypes 837 | ): FileExtensions | FileExtensions[] | null { 838 | if (!(mimeType in mimeTypesMap)) return null 839 | const matches = Object.keys(fileExtensionsMap) 840 | .map(ext => fileExtensionsMap[ext as FileExtensions] === mimeType && ext) 841 | .filter(Boolean) 842 | 843 | if (matches.length > 1) return matches as FileExtensions[] 844 | return matches[0] as FileExtensions 845 | } 846 | 847 | function getMimeTypeFromFileExtension( 848 | extension: FileExtensions | string 849 | ): MimeTypes | null { 850 | return ( 851 | fileExtensionsMap[extension as FileExtensions] || 852 | fileExtensionsMap[('.' + extension) as FileExtensions] || 853 | null 854 | ) 855 | } 856 | 857 | export { 858 | FileExtensions, 859 | MimeTypes, 860 | fileExtensionsMap, 861 | mimeTypesMap, 862 | getFileExtensionFromMimeType, 863 | getMimeTypeFromFileExtension, 864 | } 865 | -------------------------------------------------------------------------------- /src/monthNames.ts: -------------------------------------------------------------------------------- 1 | const monthNames = [ 2 | 'January', 3 | 'February', 4 | 'March', 5 | 'April', 6 | 'May', 7 | 'June', 8 | 'July', 9 | 'August', 10 | 'September', 11 | 'October', 12 | 'November', 13 | 'December', 14 | ] as const 15 | 16 | type MonthNames = typeof monthNames[number] 17 | export { monthNames as default, MonthNames } 18 | -------------------------------------------------------------------------------- /src/objectIsEmpty.ts: -------------------------------------------------------------------------------- 1 | import isObject from './isObject' 2 | 3 | export default function objectIsEmpty( 4 | obj: T 5 | ): boolean | TypeError { 6 | if (!isObject(obj)) throw new TypeError('Expected first argument of "objectIsEmpty" to be an actual object.') 7 | 8 | for (const prop in obj) { 9 | if (obj.hasOwnProperty(prop)) { 10 | return false 11 | } 12 | } 13 | return JSON.stringify(obj) === JSON.stringify({}) 14 | } 15 | -------------------------------------------------------------------------------- /src/observeMutations.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Runs the provided callback for each mutation on the specified element and returns the 3 | * MutationObserver instance. 4 | * 5 | * @param element - The element to watch for mutations. 6 | * @param callback - The function that should be executed on mutation. 7 | * @param options - Additional MuationRecord options. 8 | */ 9 | 10 | export default function observeMutations( 11 | element: HTMLElement, 12 | callback: Function, 13 | options?: MutationObserverInit 14 | ): MutationObserver { 15 | const observer = new MutationObserver(mutations => { 16 | for (let mutation of mutations) callback(mutation) 17 | }) 18 | 19 | observer.observe(element, { 20 | subtree: true, 21 | childList: true, 22 | attributes: true, 23 | ...options, 24 | }) 25 | return observer 26 | } 27 | -------------------------------------------------------------------------------- /src/once.ts: -------------------------------------------------------------------------------- 1 | export default function once void>( 2 | fn: T 3 | ): (this: ThisParameterType, ...args: Parameters) => ReturnType { 4 | let called = false 5 | return function (this: ThisParameterType, ...args: Parameters): any { 6 | if (called) return 7 | called = true 8 | return fn.apply(this, args) 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/openExternalWindow.ts: -------------------------------------------------------------------------------- 1 | export default function openExternalWindow(location: string): Window { 2 | let externalWindow = window.open()! 3 | externalWindow.opener = null 4 | externalWindow.location.href = location 5 | 6 | return externalWindow 7 | } 8 | -------------------------------------------------------------------------------- /src/parseHTML.ts: -------------------------------------------------------------------------------- 1 | export default function parseHTML(str: T): HTMLCollection { 2 | const mockDocument = document.implementation.createHTMLDocument() 3 | mockDocument.body.innerHTML = str 4 | return mockDocument.body.children 5 | } 6 | -------------------------------------------------------------------------------- /src/prefixWithZero.ts: -------------------------------------------------------------------------------- 1 | export default function prefixWithZero( 2 | value: string | number, 3 | onlySingleFigures = true 4 | ): string { 5 | let number = Number(value) 6 | 7 | if (!onlySingleFigures) return '0' + number 8 | return String(number < 10 ? '0' + number : number) 9 | } 10 | -------------------------------------------------------------------------------- /src/pxToRem.ts: -------------------------------------------------------------------------------- 1 | export default function pxToRem( 2 | px: number = 16, 3 | rootPx: number = 16 4 | ): string | void { 5 | if (typeof px !== 'number' || typeof rootPx !== 'number') return 6 | return (px / rootPx).toPrecision(2) + 'rem' 7 | } 8 | -------------------------------------------------------------------------------- /src/queryFilter.ts: -------------------------------------------------------------------------------- 1 | // TODO: Fix/improve this type definition 2 | export default function queryFilter< 3 | T extends any[], 4 | S extends { [key: string]: any } 5 | >(array: T, query: Partial): S[] | void { 6 | if (!Array.isArray(array) || typeof query !== 'object') return 7 | 8 | return array.filter((obj: S) => 9 | Object.keys(query).every(key => query[key] === obj[key]) 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /src/randomHash.ts: -------------------------------------------------------------------------------- 1 | export default function randomHash(): string { 2 | return (+new Date() + Math.floor(Math.random() * 10000000)).toString(36) 3 | } 4 | -------------------------------------------------------------------------------- /src/resetScroll.ts: -------------------------------------------------------------------------------- 1 | export default function resetScroll( 2 | elem: HTMLElement = document.documentElement 3 | ): void { 4 | if (!(elem instanceof HTMLElement)) return 5 | 6 | elem.scrollTop = 0 7 | elem.scrollLeft = 0 8 | } 9 | -------------------------------------------------------------------------------- /src/rgbToHex.ts: -------------------------------------------------------------------------------- 1 | export default function rgbToHex(r: number, g: number, b: number): string { 2 | return ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0') 3 | } 4 | -------------------------------------------------------------------------------- /src/scrollToElem.ts: -------------------------------------------------------------------------------- 1 | import isObject from './isObject' 2 | 3 | export default function scrollToElem( 4 | targetElem: any, 5 | debounce: number = 100, 6 | opts?: ScrollToOptions 7 | ): number | void { 8 | if (!(targetElem instanceof HTMLElement)) return 9 | 10 | const defaultOpts: ScrollToOptions = { 11 | left: 0, 12 | top: targetElem.offsetTop, 13 | behavior: 'smooth', 14 | } 15 | 16 | const doScroll = () => { 17 | window.scrollTo(Object.assign(defaultOpts, isObject(opts) ? opts : {})) 18 | } 19 | 20 | return window.setTimeout(doScroll, debounce) 21 | } 22 | -------------------------------------------------------------------------------- /src/shortMonthNames.ts: -------------------------------------------------------------------------------- 1 | const shortMonthNames = [ 2 | 'Jan', 3 | 'Feb', 4 | 'Mar', 5 | 'Apr', 6 | 'May', 7 | 'Jun', 8 | 'Jul', 9 | 'Aug', 10 | 'Sep', 11 | 'Oct', 12 | 'Nov', 13 | 'Dec', 14 | ] as const 15 | 16 | type ShortMonthNames = typeof shortMonthNames[number] 17 | export { shortMonthNames as default, ShortMonthNames } 18 | -------------------------------------------------------------------------------- /src/shortWeekdays.ts: -------------------------------------------------------------------------------- 1 | const shortWeekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const 2 | 3 | type ShortWeekdays = typeof shortWeekdays[number] 4 | export { shortWeekdays as default, ShortWeekdays } 5 | -------------------------------------------------------------------------------- /src/sleep.ts: -------------------------------------------------------------------------------- 1 | export default function sleep(ms: number = 0): Promise { 2 | return new Promise(resolve => setTimeout(resolve, ms)) 3 | } 4 | -------------------------------------------------------------------------------- /src/slugify.ts: -------------------------------------------------------------------------------- 1 | export default function slugify(string: string): string { 2 | return string 3 | .toString() 4 | .toLowerCase() 5 | .replace(/\s+/g, '-') 6 | .replace(/[^\w-]+/g, '') 7 | .replace(/--+/g, '-') 8 | .replace(/^-+/, '') 9 | .replace(/-+$/, '') 10 | } 11 | -------------------------------------------------------------------------------- /src/smoothScroll.ts: -------------------------------------------------------------------------------- 1 | export default function smoothScroll( 2 | target: HTMLElement | string, 3 | options?: ScrollIntoViewOptions 4 | ): void { 5 | if (!(target instanceof HTMLElement) && typeof target !== 'string') return 6 | 7 | if (typeof target === 'string') { 8 | target = document.querySelector(target) as HTMLElement 9 | } 10 | 11 | if (target == null) return 12 | target.scrollIntoView({ 13 | behavior: 'smooth', 14 | ...options, 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /src/swapKeysForValues.ts: -------------------------------------------------------------------------------- 1 | // TODO: Fix/improve this type definition 2 | 3 | type KeyFromValue> = { 4 | [K in keyof T]: V extends T[K] ? K : never 5 | }[keyof T] 6 | 7 | export type Swap> = { 8 | [V in T[keyof T]]: KeyFromValue 9 | } 10 | 11 | export default function swapKeysForValues< 12 | T extends Record 13 | >(obj: T): Swap { 14 | let swaped: unknown = {} 15 | for (let key in obj) (swaped as any)[obj[key]] = key 16 | return swaped as Swap 17 | } 18 | -------------------------------------------------------------------------------- /src/tabbableSelectors.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | 'a[href]:not([hidden])', 3 | 'area[href]:not([hidden])', 4 | 'button:not(:disabled):not([hidden])', 5 | 'embed:not([hidden])', 6 | 'iframe:not([hidden])', 7 | 'audio[controls]:not([hidden])', 8 | 'video[controls]:not([hidden])', 9 | 'input:not([type="hidden"]):not(:disabled):not([hidden])', 10 | 'object:not([hidden])', 11 | 'select:not(:disabled):not([hidden])', 12 | 'textarea:not(:disabled):not([hidden])', 13 | '*[tabindex]:not([tabindex="-1"]):not([hidden])', 14 | '*[contenteditable]:not([contenteditable="false"]):not([hidden])', 15 | ] 16 | -------------------------------------------------------------------------------- /src/toPx.ts: -------------------------------------------------------------------------------- 1 | export default function toPx(n: number | string = 0): string { 2 | if (typeof n !== 'number' && typeof n !== 'string') n = 0 3 | return n + 'px' 4 | } 5 | -------------------------------------------------------------------------------- /src/toSnakeCase.ts: -------------------------------------------------------------------------------- 1 | export default function toSnakeCase(str: string): string { 2 | const universalCaseRE = /[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g 3 | return String( 4 | str 5 | .match(universalCaseRE)! 6 | .map(x => x.toLowerCase()) 7 | .join('_') 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /src/trapFocus.ts: -------------------------------------------------------------------------------- 1 | import getFirstTabbableNode from './getFirstTabbableNode' 2 | import getLastTabbableNode from './getLastTabbableNode' 3 | 4 | export default function trapFocus( 5 | event: KeyboardEvent, 6 | elem: HTMLElement = document.documentElement 7 | ) { 8 | if ( 9 | !(event instanceof KeyboardEvent) || 10 | !(elem instanceof HTMLElement) || 11 | event.key !== 'Tab' 12 | ) 13 | return 14 | 15 | let firstTabbableEl = getFirstTabbableNode(elem) 16 | let lastTabbableEl = getLastTabbableNode(elem) 17 | const activateFocusTrap = () => { 18 | if (event.shiftKey) { 19 | if (document.activeElement === firstTabbableEl) { 20 | lastTabbableEl!.focus() 21 | event.preventDefault() 22 | } 23 | } else { 24 | if (document.activeElement === lastTabbableEl) { 25 | firstTabbableEl!.focus() 26 | event.preventDefault() 27 | } 28 | } 29 | } 30 | 31 | activateFocusTrap() 32 | } 33 | -------------------------------------------------------------------------------- /src/ua.ts: -------------------------------------------------------------------------------- 1 | declare var WXEnvironment: { 2 | platform: string 3 | } 4 | 5 | export const inBrowser = () => typeof window !== 'undefined' 6 | export const inWeex = () => 7 | typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform 8 | export const weexPlatform = () => 9 | inWeex() && WXEnvironment.platform.toLowerCase() 10 | export const isMacintosh = () => 11 | inBrowser() && navigator.platform.indexOf('Mac') > -1 12 | export const isWindows = () => 13 | inBrowser() && navigator.platform.indexOf('Win') > -1 14 | export const UA = inBrowser() && window.navigator.userAgent.toLowerCase() 15 | export const isIE = () => UA && /msie|trident/.test(UA) 16 | export const isIE9 = () => UA && UA.indexOf('msie 9.0') > 0 17 | export const isEdge = () => UA && UA.indexOf('edge/') > 0 18 | export const isAndroid = () => 19 | (UA && UA.indexOf('android') > 0) || weexPlatform() === 'android' 20 | export const isIOS = () => 21 | (UA && /iphone|ipad|ipod|ios/.test(UA)) || weexPlatform() === 'ios' 22 | export const isChrome = () => UA && /chrome\/\d+/.test(UA) && !isEdge() 23 | export const isPhantomJS = () => UA && /phantomjs/.test(UA) 24 | export const isFirefox = () => UA && UA.match(/firefox\/(\d+)/) 25 | export const isFF = isFirefox 26 | -------------------------------------------------------------------------------- /src/uniq.ts: -------------------------------------------------------------------------------- 1 | export default function uniq(array: ReadonlyArray): T[] { 2 | return Array.from(new Set(array)) 3 | } 4 | -------------------------------------------------------------------------------- /src/unslash.ts: -------------------------------------------------------------------------------- 1 | export default function unslash(string: string): string { 2 | return string.replace(/^\/+|\/+$/g, '') 3 | } 4 | -------------------------------------------------------------------------------- /src/unslashEnd.ts: -------------------------------------------------------------------------------- 1 | export default function unslashEnd(string: string): string { 2 | return string.replace(/\/+$/g, '') 3 | } 4 | -------------------------------------------------------------------------------- /src/unslashStart.ts: -------------------------------------------------------------------------------- 1 | export default function unslashStart(string: string): string { 2 | return string.replace(/^\/+/g, '') 3 | } 4 | -------------------------------------------------------------------------------- /src/wait.ts: -------------------------------------------------------------------------------- 1 | export default function wait( 2 | timeout: number = 0, 3 | cb: () => unknown 4 | ): number | void { 5 | if (typeof cb !== 'function') return 6 | return window.setTimeout(cb, timeout) 7 | } 8 | -------------------------------------------------------------------------------- /src/weekdays.ts: -------------------------------------------------------------------------------- 1 | const weekdays = [ 2 | 'Sunday', 3 | 'Monday', 4 | 'Tuesday', 5 | 'Wednesday', 6 | 'Thursday', 7 | 'Friday', 8 | 'Saturday', 9 | ] as const 10 | 11 | type WeekDays = typeof weekdays[number] 12 | 13 | export { weekdays as default, WeekDays } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["DOM"], 4 | "target": "es5", 5 | "downlevelIteration": true, 6 | "strict": true, 7 | "rootDir": "src", 8 | "pretty": true, 9 | "declaration": true, 10 | "esModuleInterop": true 11 | }, 12 | "exclude": ["node_modules", "dist"] 13 | } 14 | --------------------------------------------------------------------------------