├── .editorconfig ├── .eslintrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── import.js ├── index.d.ts ├── index.js ├── lib └── tzdata.js ├── package-lock.json ├── package.json ├── tests ├── Dockerfile ├── test-constructors.js ├── test-setters.js └── test-vs-local.js └── timezone-mock.sublime-project /.editorconfig: -------------------------------------------------------------------------------- 1 | ; editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | 8 | [*.js] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true 4 | }, 5 | "globals": { 6 | "window": true 7 | }, 8 | "extends": "eslint:recommended", 9 | "rules": { 10 | "accessor-pairs": "error", 11 | "array-bracket-newline": ["error", "consistent"], // JE 12 | "array-bracket-spacing": [ 13 | "error", 14 | "never" 15 | ], 16 | "array-callback-return": "error", 17 | "array-element-newline": "off", 18 | "arrow-body-style": "error", 19 | "arrow-parens": [ 20 | "error", 21 | "always" 22 | ], 23 | "arrow-spacing": [ 24 | "error", 25 | { 26 | "before": true, 27 | "after": true 28 | } 29 | ], 30 | "block-scoped-var": "error", 31 | "block-spacing": "error", 32 | "brace-style": [ 33 | "error", 34 | "1tbs", 35 | { 36 | "allowSingleLine": false 37 | } 38 | ], 39 | "callback-return": "error", 40 | "camelcase": "off", 41 | "capitalized-comments": "off", 42 | "class-methods-use-this": "error", 43 | "comma-dangle": [ 44 | "error", 45 | "only-multiline" 46 | ], 47 | "comma-spacing": "error", 48 | "comma-style": [ 49 | "error", 50 | "last" 51 | ], 52 | "complexity": "off", 53 | "computed-property-spacing": [ 54 | "error", 55 | "never" 56 | ], 57 | "consistent-return": [ 58 | "error", 59 | { 60 | "treatUndefinedAsUnspecified": true, 61 | } 62 | ], 63 | "consistent-this": "off", // JE 64 | "constructor-super": "error", 65 | "curly": "error", 66 | "default-case": "error", 67 | "dot-location": [ 68 | "error", 69 | "property" 70 | ], 71 | "dot-notation": "error", 72 | "eol-last": "error", 73 | "eqeqeq": [ 74 | "error", 75 | "smart" 76 | ], 77 | "for-direction": "error", 78 | "func-call-spacing": "error", 79 | "func-name-matching": "error", 80 | "func-names": "off", // JE 81 | "func-style": [ 82 | "error", 83 | "declaration", 84 | { 85 | "allowArrowFunctions": true 86 | } 87 | ], 88 | "function-paren-newline": "off", // JE 89 | "generator-star-spacing": "error", 90 | "global-require": "error", 91 | "guard-for-in": "off", 92 | "handle-callback-err": "error", 93 | "id-blacklist": "error", 94 | "id-length": "off", 95 | "id-match": [ 96 | "error", 97 | "^([a-z]+([A-Z][a-z]+))*|([a-z]([a-z_]*[a-z])?)$", 98 | ], 99 | "implicit-arrow-linebreak": [ 100 | "error", 101 | "beside" 102 | ], 103 | "indent": [ 104 | "error", 105 | 2, 106 | { 107 | "ArrayExpression": "first", 108 | "CallExpression": { 109 | "arguments": 1, // JE "first" 110 | }, 111 | "FunctionDeclaration": { 112 | "parameters": 1, // JE "first" 113 | }, 114 | "FunctionExpression": { 115 | "parameters": 1, // JE "first" 116 | }, 117 | "MemberExpression": "off", 118 | "ObjectExpression": 1, // "first", 119 | "SwitchCase": 1 120 | } 121 | ], 122 | "indent-legacy": "off", 123 | "init-declarations": "off", //["error", "always"], 124 | "jsx-quotes": "error", 125 | "key-spacing": [ 126 | "error", 127 | { 128 | "mode": "strict" 129 | } 130 | ], 131 | "keyword-spacing": [ 132 | "error", 133 | { 134 | "after": true, 135 | "before": true 136 | } 137 | ], 138 | "line-comment-position": "off", 139 | "linebreak-style": [ 140 | "error", 141 | "unix" 142 | ], 143 | "lines-around-comment": "off", // JE 144 | "lines-around-directive": "error", 145 | "lines-between-class-members": "off", // JE 146 | "max-classes-per-file": "off", // JE 147 | "max-depth": "error", 148 | "max-len": [ 149 | "error", 150 | { 151 | "code": 120, 152 | "ignorePattern": "^// Flags:", 153 | "ignoreRegExpLiterals": true, 154 | "ignoreUrls": true, 155 | "tabWidth": 2 156 | } 157 | ], 158 | "max-lines": "off", 159 | "max-lines-per-function": "off", 160 | "max-nested-callbacks": "error", 161 | "max-params": "off", 162 | "max-statements": "off", 163 | "max-statements-per-line": "error", 164 | "multiline-comment-style": [ 165 | "error", 166 | "separate-lines" 167 | ], 168 | "multiline-ternary": ["error", "always-multiline"], 169 | "new-cap": "error", 170 | "new-parens": "error", 171 | "newline-after-var": "off", 172 | "newline-before-return": "off", 173 | "newline-per-chained-call": "off", 174 | "no-alert": "error", 175 | "no-array-constructor": "error", 176 | "no-async-promise-executor": "error", 177 | "no-await-in-loop": "error", 178 | "no-bitwise": "off", // FRVR Voxel 179 | "no-buffer-constructor": "error", 180 | "no-caller": "error", 181 | "no-catch-shadow": "error", 182 | "no-class-assign": "error", 183 | "no-confusing-arrow": "error", 184 | "no-console": "off", // JE 185 | "no-const-assign": "error", 186 | "no-constant-condition": "off", // JE 187 | "no-control-regex": "error", 188 | "no-continue": "off", // JE 189 | "no-debugger": "error", 190 | "no-delete-var": "error", 191 | "no-div-regex": "error", 192 | "no-dupe-args": "error", 193 | "no-dupe-class-members": "error", 194 | "no-dupe-keys": "error", 195 | "no-duplicate-case": "error", 196 | "no-duplicate-imports": "error", 197 | "no-else-return": "error", 198 | "no-empty-character-class": "error", 199 | "no-empty-function": "error", 200 | "no-eq-null": "error", 201 | "no-eval": "error", 202 | "no-ex-assign": "error", 203 | "no-extend-native": "off", 204 | "no-extra-bind": "error", 205 | "no-extra-boolean-cast": "error", 206 | "no-extra-label": "error", 207 | "no-extra-parens": [ 208 | "error", 209 | "functions", // JE: Complains about useful parens for readability 210 | ], 211 | "no-extra-semi": "error", 212 | "no-fallthrough": "error", 213 | "no-floating-decimal": "error", 214 | "no-func-assign": "error", 215 | "no-global-assign": "error", 216 | "no-implicit-coercion": "error", 217 | "no-implicit-globals": "error", 218 | "no-implied-eval": "error", 219 | "no-inline-comments": "off", 220 | "no-invalid-regexp": "error", 221 | "no-invalid-this": "error", 222 | "no-irregular-whitespace": "error", 223 | "no-iterator": "error", 224 | "no-label-var": "error", 225 | "no-labels": "error", 226 | "no-lone-blocks": "error", 227 | "no-lonely-if": "off", // JE 228 | "no-loop-func": "error", 229 | "no-magic-numbers": "off", 230 | "no-misleading-character-class": "error", 231 | "no-mixed-operators": [ 232 | "error", 233 | { 234 | "groups": [ 235 | ["+", "-", "|", "||"], 236 | ["*", "/", "&", "&&", "^", "<<", ">>", ">>>"], 237 | ["==", "!=", "===", "!==", ">", ">=", "<", "<="], 238 | ], 239 | "allowSamePrecedence": true, 240 | } 241 | ], 242 | "no-mixed-requires": "error", 243 | "no-mixed-spaces-and-tabs": "error", 244 | "no-multi-assign": "off", 245 | "no-multi-spaces": [ 246 | "error", 247 | { 248 | "ignoreEOLComments": true 249 | } 250 | ], 251 | "no-multi-str": "error", 252 | "no-multiple-empty-lines": [ 253 | "error", 254 | { 255 | "max": 2, 256 | "maxEOF": 0, 257 | "maxBOF": 1 258 | } 259 | ], 260 | "no-native-reassign": "error", 261 | "no-negated-condition": "off", // JE: Makes nested ternaries more readable 262 | "no-negated-in-lhs": "error", 263 | "no-nested-ternary": "off", // JE 264 | "no-new": "error", 265 | "no-new-func": "error", 266 | "no-new-object": "error", 267 | "no-new-require": "error", 268 | "no-new-symbol": "error", 269 | "no-new-wrappers": "error", 270 | "no-obj-calls": "error", 271 | "no-octal": "error", 272 | "no-octal-escape": "error", 273 | "no-param-reassign": "off", 274 | "no-path-concat": "error", 275 | "no-plusplus": "off", // JE 276 | "no-process-env": "off", // JE 277 | "no-process-exit": "off", // JE 278 | "no-proto": "error", 279 | "no-prototype-builtins": "error", 280 | "no-redeclare": "error", 281 | "no-restricted-globals": "error", 282 | "no-restricted-imports": "error", 283 | "no-restricted-modules": "error", 284 | "no-restricted-properties": "error", 285 | "no-restricted-syntax": "error", 286 | "no-return-assign": "error", 287 | "no-return-await": "error", 288 | "no-script-url": "error", 289 | "no-self-assign": "error", 290 | "no-self-compare": "error", 291 | "no-sequences": "error", 292 | "no-shadow": [ 293 | "error", 294 | { 295 | "allow": ["next", "done", "err"], 296 | } 297 | ], 298 | "no-shadow-restricted-names": "error", 299 | "no-spaced-func": "error", 300 | "no-sync": "off", // JE 301 | "no-tabs": "error", 302 | "no-template-curly-in-string": "error", 303 | "no-ternary": "off", // JE 304 | "no-this-before-super": "error", 305 | "no-throw-literal": "error", 306 | "no-trailing-spaces": "error", 307 | "no-undef": [ 308 | "error", 309 | { 310 | "typeof": true 311 | } 312 | ], 313 | "no-undef-init": "error", 314 | "no-undefined": "off", 315 | "no-underscore-dangle": "off", 316 | "no-unexpected-multiline": "error", 317 | "no-unmodified-loop-condition": "error", 318 | "no-unneeded-ternary": "error", 319 | "no-unreachable": "error", 320 | "no-unsafe-finally": "error", 321 | "no-unsafe-negation": "error", 322 | "no-unused-expressions": "error", 323 | "no-unused-labels": "error", 324 | "no-unused-vars": [ 325 | "error", 326 | { 327 | "args": "none" 328 | } 329 | ], 330 | "no-use-before-define": [ 331 | "error", 332 | { 333 | "classes": true, 334 | "functions": true, 335 | "variables": true 336 | } 337 | ], 338 | "no-useless-call": "error", 339 | "no-useless-computed-key": "error", 340 | "no-useless-concat": "error", 341 | "no-useless-constructor": "error", 342 | "no-useless-escape": "error", 343 | "no-useless-rename": "error", 344 | "no-useless-return": "error", 345 | "no-var": "off", 346 | "no-void": "off", 347 | "no-warning-comments": "off", // JE: Allow TODO: 348 | "no-whitespace-before-property": "error", 349 | "no-with": "error", 350 | "nonblock-statement-body-position": "error", 351 | "object-curly-newline": "error", 352 | "object-curly-spacing": [ 353 | "error", 354 | "always" 355 | ], 356 | "object-shorthand": "off", 357 | "one-var": ["error", { 358 | "var": "never", 359 | "let": "never", 360 | "const": "never", 361 | "separateRequires": true, 362 | }], 363 | "one-var-declaration-per-line": "error", 364 | "operator-assignment": "error", 365 | "operator-linebreak": [ 366 | "error", 367 | "after", 368 | // { "overrides": { "?": "ignore", ":": "ignore" } } 369 | ], 370 | "padded-blocks": "off", 371 | "padding-line-between-statements": "error", 372 | "prefer-arrow-callback": "off", 373 | "prefer-const": "off", 374 | "prefer-destructuring": "off", 375 | "prefer-numeric-literals": "error", 376 | "prefer-promise-reject-errors": "error", 377 | "prefer-reflect": "off", // JE 378 | "prefer-rest-params": "off", 379 | "prefer-spread": "off", 380 | "prefer-template": "off", 381 | "quote-props": [ 382 | "error", 383 | "consistent" 384 | ], 385 | "quotes": [ 386 | "error", 387 | "single", 388 | { 389 | "avoidEscape": true 390 | } 391 | ], 392 | "radix": "error", 393 | "require-atomic-updates": "error", 394 | "require-await": "error", 395 | "require-jsdoc": "off", 396 | "require-unicode-regexp": "off", // JE: Hasn't caught anything useful, generates bigger code 397 | "rest-spread-spacing": "error", 398 | "semi": "error", 399 | "semi-spacing": "error", 400 | "semi-style": [ 401 | "error", 402 | "last" 403 | ], 404 | "sort-imports": "error", 405 | "sort-keys": "off", 406 | "sort-vars": "error", 407 | "space-before-blocks": [ 408 | "error", 409 | "always" 410 | ], 411 | "space-before-function-paren": [ 412 | "error", 413 | { 414 | "anonymous": "ignore", 415 | "named": "never", 416 | "asyncArrow": "always" 417 | } 418 | ], 419 | "space-in-parens": [ 420 | "error", 421 | "never" 422 | ], 423 | "space-infix-ops": "off", 424 | "space-unary-ops": "error", 425 | "spaced-comment": [ 426 | "error", 427 | "always", 428 | { 429 | "block": { 430 | "balanced": true 431 | }, 432 | "exceptions": [ 433 | "-", "/" 434 | ] 435 | } 436 | ], 437 | "strict": "off", 438 | "switch-colon-spacing": "error", 439 | "symbol-description": "error", 440 | "template-curly-spacing": [ 441 | "error", 442 | "never" 443 | ], 444 | "template-tag-spacing": "error", 445 | "unicode-bom": [ 446 | "error", 447 | "never" 448 | ], 449 | "use-isnan": "error", 450 | "valid-jsdoc": "error", 451 | "valid-typeof": "error", 452 | "vars-on-top": "off", // JE 453 | "wrap-iife": "error", 454 | "wrap-regex": "error", 455 | "yield-star-spacing": "error", 456 | "yoda": [ 457 | "error", 458 | "never" 459 | ] 460 | 461 | } 462 | } 463 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.sublime-workspace 3 | out.txt 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.sublime-* 3 | tests 4 | import.js 5 | .editorconfig 6 | .jshintrc 7 | .eslintrc 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Jimb Esser 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | timezone-mock 2 | ================ 3 | 4 | A JavaScript library to mock the local timezone. 5 | 6 | This module is useful for testing that code works correctly when run in 7 | other timezones, especially those which have Daylight Saving Time if the 8 | timezone of your test system does not. 9 | 10 | When `register` is called, it replaces the global Date constructor with 11 | a mocked Date object which behaves as if it is in the specified timezone. 12 | 13 | Note: Future timezone transitions are likely to change due to laws, etc. Make 14 | sure to always test using specific dates in the past. The timezone data used by 15 | `timezone-mock 1.0.4+` should be up accurate for all times through the end of 2018. 16 | 17 | Note: Node v8.0.0 changed how the string "YYYY-MM-DDTHH:MM:SS" is interpreted. 18 | It was previously interpreted as a UTC date, but now is a local date. If your 19 | code is using dates of this format, results will be inconsistent. timezone-mock 20 | treats them as a local date, so that it behaves consistently with new versions 21 | of Node, but that means if you run the tests in here on old versions of node, 22 | or use the mock on old versions of node, the tests may not be accurate (just 23 | for parsing dates in the aforementioned format). 24 | 25 | 26 | Usage Example 27 | ============= 28 | 29 | ```javascript 30 | var assert = require('assert'); 31 | var timezone_mock = require('timezone-mock'); 32 | 33 | function buggyCode() { 34 | // This function is potentially a bug since it's interpreting a string in 35 | // the local timezone, which will behave differently depending on which 36 | // system it is ran on. 37 | return new Date('2015-01-01 12:00:00').getTime(); 38 | } 39 | var result_local = buggyCode(); 40 | timezone_mock.register('US/Pacific'); 41 | var result_pacific = buggyCode(); 42 | timezone_mock.register('US/Eastern'); 43 | var result_eastern = buggyCode(); 44 | assert.equal(result_local, result_pacific); // Might fail 45 | assert.equal(result_pacific, result_eastern); // Definitely fails 46 | 47 | ``` 48 | 49 | API 50 | === 51 | * `timezone_mock.register(timezone)` - Replace the global Date object with a mocked one for 52 | the specified timezone. Defaults to 'US/Pacific' if no timezone is specified. 53 | * `timezone_mock.unregister()` - Return to normal Date object behavior 54 | * `timezone_mock._Date` - access to the original Date object for testing. Available after `register` is called, and it's the Date 55 | object of the provided global/window context. 56 | * `timezone_mock.options({ fallbackFn })` - Option to provide a fallback function when `timezone-mock` fails to parse. 57 | 58 | Supported Timezones 59 | =================== 60 | Currently supported timezones are: 61 | * US/Pacific 62 | * US/Eastern 63 | * Brazil/East 64 | * UTC 65 | * Europe/London 66 | * Australia/Adelaide 67 | 68 | I found that testing on these were enough to ensure code worked in 69 | all timezones (important factor is to test on a timezone with Daylight Saving 70 | Time if your local timezone does not). Brazil/East has the unique characteristic 71 | of having the DST transition happen right at midnight, so code that sets a Date 72 | object to midnight on a particular day and then does operations on that Date 73 | object is especially vulnerable in that timezone. Europe/London is included as 74 | a timezone that is a positive offset from UTC, and Australia/Adelaide as one that 75 | has a large positive and non-integral offset (+9.5/+10.5). 76 | 77 | Supported GMT Offsets 78 | ===================== 79 | Note: the `Etc/GMT` timezones work the opposite of how one might expect, the `Etc/GMT+5` timezone is equivalent to US Eastern Standard Time (UTC-5). 80 | 81 | Currently supported GMT offsets are: 82 | * Etc/GMT+12 83 | * Etc/GMT+11 84 | * Etc/GMT+10 85 | * Etc/GMT+9 86 | * Etc/GMT+8 87 | * Etc/GMT+7 88 | * Etc/GMT+6 89 | * Etc/GMT+5 90 | * Etc/GMT+4 91 | * Etc/GMT+3 92 | * Etc/GMT+2 93 | * Etc/GMT+1 94 | * Etc/GMT+0 95 | * Etc/GMT 96 | * Etc/GMT-0 97 | * Etc/GMT-1 98 | * Etc/GMT-2 99 | * Etc/GMT-3 100 | * Etc/GMT-4 101 | * Etc/GMT-5 102 | * Etc/GMT-6 103 | * Etc/GMT-7 104 | * Etc/GMT-8 105 | * Etc/GMT-9 106 | * Etc/GMT-10 107 | * Etc/GMT-11 108 | * Etc/GMT-12 109 | * Etc/GMT-13 110 | * Etc/GMT-14 111 | 112 | GMT offsets can be used to test if UTC times fall on particular local calendar days. 113 | Note: `Etc/GMT+0`, `Etc/GMT`, and `Etc/GMT-0` all represent the same offset and are 114 | equivalent to the `UTC` time zone. 115 | 116 | Status 117 | ====== 118 | 119 | The behavior of `toLocaleString()` has changed in v1.3.0 to more closely match Node's 120 | behavior, but only works on Node v14+. Use v1.2.2 for the old behavior. See note below. 121 | 122 | Most Date member functions are supported except for some conversions to 123 | locale-specific date strings. These are mocked in a way that may only work 124 | reliably on Node v14+. Note that using locale-specific formatting is often 125 | device- and browser-dependant, so any use of these in tests may indicate a 126 | potential bug. 127 | 128 | With non-DST timezones, it should behave identically to the native Javascript 129 | Date object. With DST timezones, it may sometimes behave slightly differently 130 | when given an ambiguous date string (e.g. "2014-11-02 01:00:00" in "US/Pacific", 131 | is treated as 1AM PDT instead of 1AM PST - same clock time, utc timestamp off by 132 | an hour). 133 | -------------------------------------------------------------------------------- /import.js: -------------------------------------------------------------------------------- 1 | /* eslint-env es6 */ 2 | // Usage: Run and copy into tzdata.js 3 | // node import.js /usr/share/zoneinfo/SystemV/PST8PDT > out.txt 4 | // node import.js /usr/share/zoneinfo/SystemV/EST5EDT > out.txt 5 | // node import.js /usr/share/zoneinfo/America/Sao_Paulo > out.txt 6 | // node import.js /usr/share/zoneinfo/Australia/Adelaide > out.txt 7 | const assert = require('assert'); 8 | const fs = require('fs'); 9 | 10 | assert(process.argv[2]); 11 | let tzfile = fs.readFileSync(process.argv[2]); 12 | 13 | let idx = 0; 14 | 15 | let magic = tzfile.toString('ascii', 0, 4); 16 | idx += 4; 17 | assert(magic === 'TZif'); 18 | 19 | let version = tzfile.readUInt8(idx++); 20 | assert(version === 0x32); 21 | 22 | idx += 15; 23 | let values = []; 24 | for (let ii = 0; ii < 6; ++ii) { 25 | values[ii] = tzfile.readUInt32BE(idx); 26 | idx += 4; 27 | } 28 | let [tzh_ttisgmtcnt, tzh_ttisstdcnt, tzh_leapcnt, tzh_timecnt, tzh_typecnt, tzh_charcnt] = values; 29 | // console.log(`tzh_ttisgmtcnt:${tzh_ttisgmtcnt} tzh_ttisstdcnt:${tzh_ttisstdcnt} tzh_leapcnt:${tzh_leapcnt} ` + 30 | // `tzh_timecnt:${tzh_timecnt} tzh_typecnt:${tzh_typecnt} tzh_charcnt:${tzh_charcnt}`); 31 | 32 | let transitions = []; 33 | for (let ii = 0; ii < tzh_timecnt; ++ii) { 34 | transitions.push({ time: tzfile.readUInt32BE(idx) }); 35 | idx += 4; 36 | } 37 | 38 | for (let ii = 0; ii < tzh_timecnt; ++ii) { 39 | transitions[ii].which = tzfile.readUInt8(idx++); 40 | } 41 | transitions.sort(function (a, b) { 42 | return a.time - b.time; 43 | }); 44 | 45 | let ttinfos = []; 46 | for (let ii = 0; ii < tzh_typecnt; ++ii) { 47 | let ttinfo = {}; 48 | ttinfo.tt_gmtoff = tzfile.readInt32BE(idx); 49 | idx += 4; 50 | ttinfo.tt_isdst = tzfile.readUInt8(idx++); 51 | ttinfo.tt_abbrind = tzfile.readUInt8(idx++); 52 | ttinfos.push(ttinfo); 53 | } 54 | 55 | let abbr = tzfile.toString('ascii', idx, idx + tzh_charcnt); 56 | idx += tzh_charcnt; 57 | for (let ii = 0; ii < ttinfos.length; ++ii) { 58 | ttinfos[ii].tt_abbr = abbr.slice(ttinfos[ii].tt_abbrind).split('\0')[0]; 59 | } 60 | 61 | for (let ii = 0; ii < tzh_leapcnt; ++ii) { 62 | /* let time = */tzfile.readUInt32BE(idx); 63 | idx += 4; 64 | /* let total_leap_seconds = */tzfile.readUInt32BE(idx); 65 | idx += 4; 66 | } 67 | 68 | assert(!tzh_ttisstdcnt || tzh_ttisstdcnt === tzh_typecnt); 69 | for (let ii = 0; ii < tzh_ttisstdcnt; ++ii) { 70 | ttinfos[ii].isstd = tzfile.readUInt8(idx++); 71 | } 72 | 73 | assert(!tzh_ttisgmtcnt || tzh_ttisgmtcnt === tzh_typecnt); 74 | for (let ii = 0; ii < tzh_ttisgmtcnt; ++ii) { 75 | ttinfos[ii].isgmt = tzfile.readUInt8(idx++); 76 | } 77 | 78 | // console.log(JSON.stringify(transitions, undefined, 2)); 79 | // console.log(JSON.stringify(ttinfos, undefined, 2)); 80 | 81 | let cuttoff = new Date('2038').getTime() / 1000; // Things get weird after this in the Linux data, ignore it 82 | transitions = transitions.filter((trans) => trans.time < cuttoff); 83 | 84 | // add transitions for the first and last timestamps if the time zone doesn't have DST transitions 85 | if (!transitions.length) { 86 | transitions.push({ time: 0, which: 0 }); 87 | transitions.push({ time: Infinity, which: 0 }); 88 | } 89 | 90 | let named = {}; 91 | let out = { 92 | names: [], 93 | transitions: [], 94 | }; 95 | for (let ii = 0; ii < transitions.length; ++ii) { 96 | let trans = transitions[ii]; 97 | let ttinfo = ttinfos[trans.which]; 98 | let offs = ttinfo.tt_gmtoff / 3600; 99 | out.transitions.push(trans.time, offs); 100 | if (!named[offs]) { 101 | out.names.push(offs, ttinfo.tt_abbr); 102 | named[offs] = true; 103 | } 104 | } 105 | 106 | if (out.transitions[0]) { 107 | // Assume alternating and start at the other 108 | out.transitions.splice(0, 0, 0, out.transitions[3]); 109 | } 110 | 111 | const zoneName = process.argv[2].split('zoneinfo/')[1]; 112 | // console.log(out); 113 | console.log(''); 114 | console.log(` '${zoneName}': {`); 115 | console.log(` names: [${out.names.map((v) => (typeof v === 'string' ? `'${v}'` : v)).join(', ')}],`); 116 | console.log(' transitions: ['); 117 | for (let ii = 0; ii < out.transitions.length; ii += 2) { 118 | console.log(` ${out.transitions[ii]}, ${out.transitions[ii + 1]},`); 119 | } 120 | console.log(' ],\n },'); 121 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | interface Options { 2 | fallbackFn: (date: any) => Date; 3 | } 4 | 5 | interface DateHoldingGlobal { 6 | Date: typeof Date; 7 | } 8 | 9 | export type TimeZone = 10 | 'Australia/Adelaide' | 11 | 'Brazil/East' | 12 | 'Europe/London' | 13 | 'US/Eastern' | 14 | 'US/Pacific' | 15 | 'UTC' | 16 | 'Etc/GMT+12' | 17 | 'Etc/GMT+11' | 18 | 'Etc/GMT+10' | 19 | 'Etc/GMT+9' | 20 | 'Etc/GMT+8' | 21 | 'Etc/GMT+7' | 22 | 'Etc/GMT+6' | 23 | 'Etc/GMT+5' | 24 | 'Etc/GMT+4' | 25 | 'Etc/GMT+3' | 26 | 'Etc/GMT+2' | 27 | 'Etc/GMT+1' | 28 | 'Etc/GMT+0' | 29 | 'Etc/GMT' | 30 | 'Etc/GMT-0' | 31 | 'Etc/GMT-1' | 32 | 'Etc/GMT-2' | 33 | 'Etc/GMT-3' | 34 | 'Etc/GMT-4' | 35 | 'Etc/GMT-5' | 36 | 'Etc/GMT-6' | 37 | 'Etc/GMT-7' | 38 | 'Etc/GMT-8' | 39 | 'Etc/GMT-9' | 40 | 'Etc/GMT-10' | 41 | 'Etc/GMT-11' | 42 | 'Etc/GMT-12' | 43 | 'Etc/GMT-13' | 44 | 'Etc/GMT-14'; 45 | 46 | export function options(options: Options): void; 47 | export function register(zone: TimeZone, glob?: DateHoldingGlobal): void; 48 | export function unregister(glob?: DateHoldingGlobal): void; 49 | export const _Date: typeof Date; 50 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var tzdata = require('./lib/tzdata.js'); 5 | exports.tzdata = tzdata; 6 | 7 | var _Date = null; 8 | exports._Date = Date; 9 | 10 | var mockDateOptions = {}; 11 | 12 | var timezone; 13 | 14 | var weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 15 | var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec']; 16 | 17 | var HOUR = 60 * 60 * 1000; 18 | 19 | var date_iso_8601_regex = /^\d\d\d\d(-\d\d(-\d\d(T\d\d:\d\d(:\d\d)?(\.\d\d\d)?(\d\d\d)?(Z|[+-]\d\d:?\d\d))?)?)?$/; 20 | var date_with_offset = /^\d\d\d\d-\d\d-\d\d( \d\d:\d\d:\d\d(\.\d\d\d)? )?(Z|(-|\+|)\d\d:\d\d)$/; 21 | var date_rfc_2822_regex = /^\d\d-\w\w\w-\d\d\d\d \d\d:\d\d:\d\d (\+|-)\d\d\d\d$/; 22 | var local_date_regex = /^\d\d\d\d-\d\d-\d\d[T ]\d\d:\d\d(:\d\d(\.\d\d\d)?)?$/; 23 | var local_GMT_regex = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d\d \w\w\w \d\d\d\d \d\d:\d\d:\d\d GMT$/ 24 | 25 | function MockDate(param) { 26 | if (arguments.length === 0) { 27 | this.d = new _Date(); 28 | } else if (arguments.length === 1) { 29 | if (param instanceof MockDate) { 30 | this.d = new _Date(param.d); 31 | } else if (typeof param === 'string') { 32 | if (param.match(date_iso_8601_regex) || 33 | param.match(date_with_offset) || 34 | param.match(date_rfc_2822_regex) || 35 | param.match(local_GMT_regex) || 36 | param === '' 37 | ) { 38 | this.d = new _Date(param); 39 | } else if (param.match(local_date_regex)) { 40 | this.d = new _Date(); 41 | this.fromLocal(new _Date(param.replace(' ', 'T') + 'Z')); 42 | } else if (mockDateOptions.fallbackFn) { 43 | this.d = mockDateOptions.fallbackFn(param); 44 | } else { 45 | assert.ok(false, 'Unhandled date format passed to MockDate constructor: ' + param); 46 | } 47 | } else if (typeof param === 'number' || param === null || param === undefined) { 48 | this.d = new _Date(param); 49 | } else if (mockDateOptions.fallbackFn) { 50 | this.d = mockDateOptions.fallbackFn(param); 51 | } else { 52 | assert.ok(false, 'Unhandled type passed to MockDate constructor: ' + typeof param); 53 | } 54 | } else { 55 | this.d = new _Date(); 56 | this.fromLocal(new _Date(_Date.UTC.apply(null, arguments))); 57 | } 58 | } 59 | 60 | // eslint-disable-next-line consistent-return 61 | MockDate.prototype.calcTZO = function (ts) { 62 | var data = tzdata[timezone]; 63 | assert.ok(data, 'Unsupported timezone: ' + timezone); 64 | ts = (ts || this.d.getTime()) / 1000; 65 | if (Number.isNaN(ts)) { 66 | return NaN; 67 | } 68 | for (var ii = 2; ii < data.transitions.length; ii += 2) { 69 | if (data.transitions[ii] > ts) { 70 | return -data.transitions[ii - 1]; 71 | } 72 | } 73 | // note: should never reach here! 74 | assert.ok(false, ts); 75 | }; 76 | 77 | function passthrough(fn) { 78 | MockDate.prototype[fn] = function () { 79 | var real_date; 80 | if (this instanceof MockDate) { 81 | real_date = this.d; 82 | } else if (this instanceof _Date) { 83 | // console.log calls our prototype to format regular Date objects! 84 | // This should only be hit while debugging MockDate itself though, as 85 | // there should be no _Date objects in user code when using MockDate. 86 | real_date = this; 87 | } else { 88 | assert(false, 'Unexpected object type'); 89 | } 90 | return real_date[fn].apply(real_date, arguments); 91 | }; 92 | } 93 | function localgetter(fn) { 94 | MockDate.prototype[fn] = function () { 95 | if (Number.isNaN(this.d.getTime())) { 96 | return NaN; 97 | } 98 | var d = new _Date(this.d.getTime() - this.calcTZO() * HOUR); 99 | return d['getUTC' + fn.slice(3)](); 100 | }; 101 | } 102 | MockDate.prototype.fromLocal = function (d) { 103 | // From a Date object in the fake-timezone where the returned UTC values are 104 | // meant to be interpreted as local values. 105 | this.d.setTime(d.getTime() + this.calcTZO(d.getTime() + this.calcTZO(d.getTime()) * HOUR) * HOUR); 106 | }; 107 | function localsetter(fn) { 108 | MockDate.prototype[fn] = function () { 109 | var d = new _Date(this.d.getTime() - this.calcTZO() * HOUR); 110 | d['setUTC' + fn.slice(3)].apply(d, arguments); 111 | this.fromLocal(d); 112 | return this.getTime(); 113 | }; 114 | } 115 | [ 116 | 'getUTCDate', 117 | 'getUTCDay', 118 | 'getUTCFullYear', 119 | 'getUTCHours', 120 | 'getUTCMilliseconds', 121 | 'getUTCMinutes', 122 | 'getUTCMonth', 123 | 'getUTCSeconds', 124 | 'getTime', 125 | 'setTime', 126 | 'setUTCDate', 127 | 'setUTCFullYear', 128 | 'setUTCHours', 129 | 'setUTCMilliseconds', 130 | 'setUTCMinutes', 131 | 'setUTCMonth', 132 | 'setUTCSeconds', 133 | 'toGMTString', 134 | 'toISOString', 135 | 'toJSON', 136 | 'toUTCString', 137 | 'valueOf', 138 | ].forEach(passthrough); 139 | [ 140 | 'getDate', 141 | 'getDay', 142 | 'getFullYear', 143 | 'getHours', 144 | 'getMilliseconds', 145 | 'getMinutes', 146 | 'getMonth', 147 | 'getSeconds', 148 | ].forEach(localgetter); 149 | [ 150 | 'setDate', 151 | 'setFullYear', 152 | 'setHours', 153 | 'setMilliseconds', 154 | 'setMinutes', 155 | 'setMonth', 156 | 'setSeconds', 157 | ].forEach(localsetter); 158 | 159 | MockDate.prototype.getYear = function () { 160 | return this.getFullYear() - 1900; 161 | }; 162 | 163 | MockDate.prototype.setYear = function (yr) { 164 | if (yr < 1900) { 165 | return this.setFullYear(1900 + yr); 166 | } 167 | return this.setFullYear(yr); 168 | }; 169 | 170 | MockDate.parse = function (dateString) { 171 | return new MockDate(dateString).getTime(); 172 | }; 173 | 174 | MockDate.prototype.getTimezoneOffset = function () { 175 | if (Number.isNaN(this.d.getTime())) { 176 | return NaN; 177 | } 178 | return this.calcTZO() * 60; 179 | }; 180 | 181 | MockDate.prototype.toString = function () { 182 | if (this instanceof _Date) { 183 | // someone, like util.inspect, calling Date.prototype.toString.call(foo) 184 | return _Date.prototype.toString.call(this); 185 | } 186 | if (Number.isNaN(this.d.getTime())) { 187 | return new _Date('').toString(); 188 | } 189 | var str = [this.d.toISOString() + ' UTC (MockDate: GMT']; 190 | var tzo = -this.calcTZO(); 191 | if (tzo < 0) { 192 | str.push('-'); 193 | tzo *= -1; 194 | } else { 195 | str.push('+'); 196 | } 197 | str.push(Math.floor(tzo).toString().padStart(2, '0')); 198 | tzo -= Math.floor(tzo); 199 | if (tzo) { 200 | str.push(tzo * 60); 201 | } else { 202 | str.push('00'); 203 | } 204 | str.push(')'); 205 | return str.join(''); 206 | }; 207 | 208 | MockDate.now = function () { return _Date.now() }; 209 | 210 | MockDate.UTC = function () { return _Date.UTC.apply(_Date, arguments) }; 211 | 212 | MockDate.prototype.toDateString = function () { 213 | if (Number.isNaN(this.d.getTime())) { 214 | return new _Date('').toDateString(); 215 | } 216 | return weekDays[this.getDay()] + ' ' + months[this.getMonth()] + ' ' + 217 | this.getDate().toString().padStart(2, '0') + ' ' + this.getFullYear(); 218 | }; 219 | 220 | MockDate.prototype.toLocaleString = function (locales, options) { 221 | options = Object.assign({ timeZone: timezone }, options); 222 | var time = this.d.getTime(); 223 | if (Number.isNaN(time)) { 224 | return new _Date('').toDateString(); 225 | } 226 | return new _Date(time).toLocaleString(locales, options); 227 | }; 228 | 229 | MockDate.prototype.toLocaleDateString = function (locales, options) { 230 | options = Object.assign({ timeZone: timezone }, options); 231 | var time = this.d.getTime(); 232 | if (Number.isNaN(time)) { 233 | return new _Date('').toDateString(); 234 | } 235 | return new _Date(time).toLocaleDateString(locales, options); 236 | }; 237 | 238 | MockDate.prototype.toLocaleTimeString = function (locales, options) { 239 | options = Object.assign({ timeZone: timezone }, options); 240 | var time = this.d.getTime(); 241 | if (Number.isNaN(time)) { 242 | return new _Date('').toDateString(); 243 | } 244 | return new _Date(time).toLocaleTimeString(locales, options); 245 | }; 246 | 247 | // TODO: 248 | // 'toTimeString', 249 | 250 | function options(opts) { 251 | mockDateOptions = opts || {}; 252 | } 253 | exports.options = options; 254 | 255 | var orig_object_toString; 256 | function mockDateObjectToString() { 257 | if (this instanceof MockDate) { 258 | // Look just like a regular Date to anything doing very low-level Object.prototype.toString calls 259 | // See: https://github.com/Jimbly/timezone-mock/issues/48 260 | return '[object Date]'; 261 | } 262 | return orig_object_toString.call(this); 263 | } 264 | 265 | function register(new_timezone, glob) { 266 | if (!glob) { 267 | if (typeof window !== 'undefined') { 268 | glob = window; 269 | } else { 270 | glob = global; 271 | } 272 | } 273 | timezone = new_timezone || 'US/Pacific'; 274 | if (glob.Date !== MockDate) { 275 | _Date = glob.Date; 276 | exports._Date = glob.Date; 277 | } 278 | glob.Date = MockDate; 279 | if (!orig_object_toString) { 280 | orig_object_toString = Object.prototype.toString; 281 | Object.prototype.toString = mockDateObjectToString; 282 | } 283 | } 284 | exports.register = register; 285 | 286 | function unregister(glob) { 287 | if (!glob) { 288 | if (typeof window !== 'undefined') { 289 | glob = window; 290 | } else { 291 | glob = global; 292 | } 293 | } 294 | if (glob.Date === MockDate) { 295 | assert(_Date); 296 | glob.Date = _Date; 297 | } 298 | } 299 | exports.unregister = unregister; 300 | -------------------------------------------------------------------------------- /lib/tzdata.js: -------------------------------------------------------------------------------- 1 | // Generated this data from mysql_tzinfo_to_sql included with MySQL and the 2 | // tzinfo file on OSX. 3 | 4 | module.exports = { 5 | 'UTC': { 6 | names: [0, 'UTC'], 7 | transitions: [0, 0, Infinity, 0], 8 | }, 9 | 'Europe/London': { 10 | names: [0, 'GMT', 1, 'BST'], 11 | transitions: [ 12 | 0, 0, 13 | 69818400, 1, 14 | 89172000, 0, 15 | 101268000, 1, 16 | 120621600, 0, 17 | 132717600, 1, 18 | 152071200, 0, 19 | 164167200, 1, 20 | 183520800, 0, 21 | 196221600, 1, 22 | 214970400, 0, 23 | 227671200, 1, 24 | 246420000, 0, 25 | 259120800, 1, 26 | 278474400, 0, 27 | 290570400, 1, 28 | 309924000, 0, 29 | 322020000, 1, 30 | 341373600, 0, 31 | 354675600, 1, 32 | 372819600, 0, 33 | 386125200, 1, 34 | 404269200, 0, 35 | 417574800, 1, 36 | 435718800, 0, 37 | 449024400, 1, 38 | 467773200, 0, 39 | 481078800, 1, 40 | 499222800, 0, 41 | 512528400, 1, 42 | 530672400, 0, 43 | 543978000, 1, 44 | 562122000, 0, 45 | 575427600, 1, 46 | 593571600, 0, 47 | 606877200, 1, 48 | 625626000, 0, 49 | 638326800, 1, 50 | 657075600, 0, 51 | 670381200, 1, 52 | 688525200, 0, 53 | 701830800, 1, 54 | 719974800, 0, 55 | 733280400, 1, 56 | 751424400, 0, 57 | 764730000, 1, 58 | 782874000, 0, 59 | 796179600, 1, 60 | 814323600, 0, 61 | 820454400, 0, 62 | 828234000, 1, 63 | 846378000, 0, 64 | 859683600, 1, 65 | 877827600, 0, 66 | 891133200, 1, 67 | 909277200, 0, 68 | 922582800, 1, 69 | 941331600, 0, 70 | 954032400, 1, 71 | 972781200, 0, 72 | 985482000, 1, 73 | 1004230800, 0, 74 | 1017536400, 1, 75 | 1035680400, 0, 76 | 1048986000, 1, 77 | 1067130000, 0, 78 | 1080435600, 1, 79 | 1099184400, 0, 80 | 1111885200, 1, 81 | 1130634000, 0, 82 | 1143334800, 1, 83 | 1162083600, 0, 84 | 1174784400, 1, 85 | 1193533200, 0, 86 | 1206838800, 1, 87 | 1224982800, 0, 88 | 1238288400, 1, 89 | 1256432400, 0, 90 | 1269738000, 1, 91 | 1288486800, 0, 92 | 1301187600, 1, 93 | 1319936400, 0, 94 | 1332637200, 1, 95 | 1351386000, 0, 96 | 1364691600, 1, 97 | 1382835600, 0, 98 | 1396141200, 1, 99 | 1414285200, 0, 100 | 1427590800, 1, 101 | 1445734800, 0, 102 | 1459040400, 1, 103 | 1477789200, 0, 104 | 1490490000, 1, 105 | 1509238800, 0, 106 | 1521939600, 1, 107 | 1540688400, 0, 108 | 1553994000, 1, 109 | 1572138000, 0, 110 | 1585443600, 1, 111 | 1603587600, 0, 112 | 1616893200, 1, 113 | 1635642000, 0, 114 | 1648342800, 1, 115 | 1667091600, 0, 116 | 1679792400, 1, 117 | 1698541200, 0, 118 | 1711846800, 1, 119 | 1729990800, 0, 120 | 1743296400, 1, 121 | 1761440400, 0, 122 | 1774746000, 1, 123 | 1792890000, 0, 124 | 1806195600, 1, 125 | 1824944400, 0, 126 | 1837645200, 1, 127 | 1856394000, 0, 128 | 1869094800, 1, 129 | 1887843600, 0, 130 | 1901149200, 1, 131 | 1919293200, 0, 132 | 1932598800, 1, 133 | 1950742800, 0, 134 | 1964048400, 1, 135 | 1982797200, 0, 136 | 1995498000, 1, 137 | 2014246800, 0, 138 | 2026947600, 1, 139 | 2045696400, 0, 140 | 2058397200, 1, 141 | 2077146000, 0, 142 | 2090451600, 1, 143 | 2108595600, 0, 144 | 2121901200, 1, 145 | 2140045200, 0, 146 | ], 147 | }, 148 | 'US/Pacific': { 149 | names: [-7, 'PDT', -8, 'PST'], 150 | transitions: [ 151 | 0, -8, 152 | 9972000, -7, 153 | 25693200, -8, 154 | 41421600, -7, 155 | 57747600, -8, 156 | 73476000, -7, 157 | 89197200, -8, 158 | 104925600, -7, 159 | 120646800, -8, 160 | 126698400, -7, 161 | 152096400, -8, 162 | 162381600, -7, 163 | 183546000, -8, 164 | 199274400, -7, 165 | 215600400, -8, 166 | 230724000, -7, 167 | 247050000, -8, 168 | 262778400, -7, 169 | 278499600, -8, 170 | 294228000, -7, 171 | 309949200, -8, 172 | 325677600, -7, 173 | 341398800, -8, 174 | 357127200, -7, 175 | 372848400, -8, 176 | 388576800, -7, 177 | 404902800, -8, 178 | 420026400, -7, 179 | 436352400, -8, 180 | 452080800, -7, 181 | 467802000, -8, 182 | 483530400, -7, 183 | 499251600, -8, 184 | 514980000, -7, 185 | 530701200, -8, 186 | 544615200, -7, 187 | 562150800, -8, 188 | 576064800, -7, 189 | 594205200, -8, 190 | 607514400, -7, 191 | 625654800, -8, 192 | 638964000, -7, 193 | 657104400, -8, 194 | 671018400, -7, 195 | 688554000, -8, 196 | 702468000, -7, 197 | 720003600, -8, 198 | 733917600, -7, 199 | 752058000, -8, 200 | 765367200, -7, 201 | 783507600, -8, 202 | 796816800, -7, 203 | 814957200, -8, 204 | 828871200, -7, 205 | 846406800, -8, 206 | 860320800, -7, 207 | 877856400, -8, 208 | 891770400, -7, 209 | 909306000, -8, 210 | 923220000, -7, 211 | 941360400, -8, 212 | 954669600, -7, 213 | 972810000, -8, 214 | 986119200, -7, 215 | 1004259600, -8, 216 | 1018173600, -7, 217 | 1035709200, -8, 218 | 1049623200, -7, 219 | 1067158800, -8, 220 | 1081072800, -7, 221 | 1099213200, -8, 222 | 1112522400, -7, 223 | 1130662800, -8, 224 | 1143972000, -7, 225 | 1162112400, -8, 226 | 1173607200, -7, 227 | 1194166800, -8, 228 | 1205056800, -7, 229 | 1225616400, -8, 230 | 1236506400, -7, 231 | 1257066000, -8, 232 | 1268560800, -7, 233 | 1289120400, -8, 234 | 1300010400, -7, 235 | 1320570000, -8, 236 | 1331460000, -7, 237 | 1352019600, -8, 238 | 1362909600, -7, 239 | 1383469200, -8, 240 | 1394359200, -7, 241 | 1414918800, -8, 242 | 1425808800, -7, 243 | 1446368400, -8, 244 | 1457863200, -7, 245 | 1478422800, -8, 246 | 1489312800, -7, 247 | 1509872400, -8, 248 | 1520762400, -7, 249 | 1541322000, -8, 250 | 1552212000, -7, 251 | 1572771600, -8, 252 | 1583661600, -7, 253 | 1604221200, -8, 254 | 1615716000, -7, 255 | 1636275600, -8, 256 | 1647165600, -7, 257 | 1667725200, -8, 258 | 1678615200, -7, 259 | 1699174800, -8, 260 | 1710064800, -7, 261 | 1730624400, -8, 262 | 1741514400, -7, 263 | 1762074000, -8, 264 | 1772964000, -7, 265 | 1793523600, -8, 266 | 1805018400, -7, 267 | 1825578000, -8, 268 | 1836468000, -7, 269 | 1857027600, -8, 270 | 1867917600, -7, 271 | 1888477200, -8, 272 | 1899367200, -7, 273 | 1919926800, -8, 274 | 1930816800, -7, 275 | 1951376400, -8, 276 | 1962871200, -7, 277 | 1983430800, -8, 278 | 1994320800, -7, 279 | 2014880400, -8, 280 | 2025770400, -7, 281 | 2046330000, -8, 282 | 2057220000, -7, 283 | 2077779600, -8, 284 | 2088669600, -7, 285 | 2109229200, -8, 286 | 2120119200, -7, 287 | 2140678800, -8, 288 | ], 289 | }, 290 | 'US/Eastern': { 291 | names: [-4, 'EDT', -5, 'EST'], 292 | transitions: [ 293 | 0, -5, 294 | 9961200, -4, 295 | 25682400, -5, 296 | 41410800, -4, 297 | 57736800, -5, 298 | 73465200, -4, 299 | 89186400, -5, 300 | 104914800, -4, 301 | 120636000, -5, 302 | 126687600, -4, 303 | 152085600, -5, 304 | 162370800, -4, 305 | 183535200, -5, 306 | 199263600, -4, 307 | 215589600, -5, 308 | 230713200, -4, 309 | 247039200, -5, 310 | 262767600, -4, 311 | 278488800, -5, 312 | 294217200, -4, 313 | 309938400, -5, 314 | 325666800, -4, 315 | 341388000, -5, 316 | 357116400, -4, 317 | 372837600, -5, 318 | 388566000, -4, 319 | 404892000, -5, 320 | 420015600, -4, 321 | 436341600, -5, 322 | 452070000, -4, 323 | 467791200, -5, 324 | 483519600, -4, 325 | 499240800, -5, 326 | 514969200, -4, 327 | 530690400, -5, 328 | 544604400, -4, 329 | 562140000, -5, 330 | 576054000, -4, 331 | 594194400, -5, 332 | 607503600, -4, 333 | 625644000, -5, 334 | 638953200, -4, 335 | 657093600, -5, 336 | 671007600, -4, 337 | 688543200, -5, 338 | 702457200, -4, 339 | 719992800, -5, 340 | 733906800, -4, 341 | 752047200, -5, 342 | 765356400, -4, 343 | 783496800, -5, 344 | 796806000, -4, 345 | 814946400, -5, 346 | 828860400, -4, 347 | 846396000, -5, 348 | 860310000, -4, 349 | 877845600, -5, 350 | 891759600, -4, 351 | 909295200, -5, 352 | 923209200, -4, 353 | 941349600, -5, 354 | 954658800, -4, 355 | 972799200, -5, 356 | 986108400, -4, 357 | 1004248800, -5, 358 | 1018162800, -4, 359 | 1035698400, -5, 360 | 1049612400, -4, 361 | 1067148000, -5, 362 | 1081062000, -4, 363 | 1099202400, -5, 364 | 1112511600, -4, 365 | 1130652000, -5, 366 | 1143961200, -4, 367 | 1162101600, -5, 368 | 1173596400, -4, 369 | 1194156000, -5, 370 | 1205046000, -4, 371 | 1225605600, -5, 372 | 1236495600, -4, 373 | 1257055200, -5, 374 | 1268550000, -4, 375 | 1289109600, -5, 376 | 1299999600, -4, 377 | 1320559200, -5, 378 | 1331449200, -4, 379 | 1352008800, -5, 380 | 1362898800, -4, 381 | 1383458400, -5, 382 | 1394348400, -4, 383 | 1414908000, -5, 384 | 1425798000, -4, 385 | 1446357600, -5, 386 | 1457852400, -4, 387 | 1478412000, -5, 388 | 1489302000, -4, 389 | 1509861600, -5, 390 | 1520751600, -4, 391 | 1541311200, -5, 392 | 1552201200, -4, 393 | 1572760800, -5, 394 | 1583650800, -4, 395 | 1604210400, -5, 396 | 1615705200, -4, 397 | 1636264800, -5, 398 | 1647154800, -4, 399 | 1667714400, -5, 400 | 1678604400, -4, 401 | 1699164000, -5, 402 | 1710054000, -4, 403 | 1730613600, -5, 404 | 1741503600, -4, 405 | 1762063200, -5, 406 | 1772953200, -4, 407 | 1793512800, -5, 408 | 1805007600, -4, 409 | 1825567200, -5, 410 | 1836457200, -4, 411 | 1857016800, -5, 412 | 1867906800, -4, 413 | 1888466400, -5, 414 | 1899356400, -4, 415 | 1919916000, -5, 416 | 1930806000, -4, 417 | 1951365600, -5, 418 | 1962860400, -4, 419 | 1983420000, -5, 420 | 1994310000, -4, 421 | 2014869600, -5, 422 | 2025759600, -4, 423 | 2046319200, -5, 424 | 2057209200, -4, 425 | 2077768800, -5, 426 | 2088658800, -4, 427 | 2109218400, -5, 428 | 2120108400, -4, 429 | 2140668000, -5, 430 | ], 431 | }, 432 | 'Brazil/East': { 433 | names: [-2, '-02', -3, '-03'], 434 | transitions: [ 435 | 0, -3, 436 | 499748400, -2, 437 | 511236000, -3, 438 | 530593200, -2, 439 | 540266400, -3, 440 | 562129200, -2, 441 | 571197600, -3, 442 | 592974000, -2, 443 | 602042400, -3, 444 | 624423600, -2, 445 | 634701600, -3, 446 | 656478000, -2, 447 | 666756000, -3, 448 | 687927600, -2, 449 | 697600800, -3, 450 | 719982000, -2, 451 | 728445600, -3, 452 | 750826800, -2, 453 | 761709600, -3, 454 | 782276400, -2, 455 | 793159200, -3, 456 | 813726000, -2, 457 | 824004000, -3, 458 | 844570800, -2, 459 | 856058400, -3, 460 | 876106800, -2, 461 | 888717600, -3, 462 | 908074800, -2, 463 | 919562400, -3, 464 | 938919600, -2, 465 | 951616800, -3, 466 | 970974000, -2, 467 | 982461600, -3, 468 | 1003028400, -2, 469 | 1013911200, -3, 470 | 1036292400, -2, 471 | 1045360800, -3, 472 | 1066532400, -2, 473 | 1076810400, -3, 474 | 1099364400, -2, 475 | 1108864800, -3, 476 | 1129431600, -2, 477 | 1140314400, -3, 478 | 1162695600, -2, 479 | 1172368800, -3, 480 | 1192330800, -2, 481 | 1203213600, -3, 482 | 1224385200, -2, 483 | 1234663200, -3, 484 | 1255834800, -2, 485 | 1266717600, -3, 486 | 1287284400, -2, 487 | 1298167200, -3, 488 | 1318734000, -2, 489 | 1330221600, -3, 490 | 1350788400, -2, 491 | 1361066400, -3, 492 | 1382238000, -2, 493 | 1392516000, -3, 494 | 1413687600, -2, 495 | 1424570400, -3, 496 | 1445137200, -2, 497 | 1456020000, -3, 498 | 1476586800, -2, 499 | 1487469600, -3, 500 | 1508036400, -2, 501 | 1518919200, -3, 502 | 1541300400, -2, 503 | 1550368800, -3, 504 | 1572750000, -2, 505 | 1581818400, -3, 506 | 1604199600, -2, 507 | 1613872800, -3, 508 | 1636254000, -2, 509 | 1645322400, -3, 510 | 1667703600, -2, 511 | 1677376800, -3, 512 | 1699153200, -2, 513 | 1708221600, -3, 514 | 1730602800, -2, 515 | 1739671200, -3, 516 | 1762052400, -2, 517 | 1771725600, -3, 518 | 1793502000, -2, 519 | 1803175200, -3, 520 | 1825556400, -2, 521 | 1834624800, -3, 522 | 1857006000, -2, 523 | 1866074400, -3, 524 | 1888455600, -2, 525 | 1897524000, -3, 526 | 1919905200, -2, 527 | 1928973600, -3, 528 | 1951354800, -2, 529 | 1960423200, -3, 530 | 1983409200, -2, 531 | 1992477600, -3, 532 | 2014858800, -2, 533 | 2024532000, -3, 534 | 2046308400, -2, 535 | 2055376800, -3, 536 | 2077758000, -2, 537 | 2086826400, -3, 538 | 2109207600, -2, 539 | 2118880800, -3, 540 | 2140657200, -2, 541 | ], 542 | }, 543 | 'Australia/Adelaide': { 544 | names: [10.5, 'ACDT', 9.5, 'ACST'], 545 | transitions: [ 546 | 0, 9.5, 547 | 57688200, 10.5, 548 | 67969800, 9.5, 549 | 89137800, 10.5, 550 | 100024200, 9.5, 551 | 120587400, 10.5, 552 | 131473800, 9.5, 553 | 152037000, 10.5, 554 | 162923400, 9.5, 555 | 183486600, 10.5, 556 | 194977800, 9.5, 557 | 215541000, 10.5, 558 | 226427400, 9.5, 559 | 246990600, 10.5, 560 | 257877000, 9.5, 561 | 278440200, 10.5, 562 | 289326600, 9.5, 563 | 309889800, 10.5, 564 | 320776200, 9.5, 565 | 341339400, 10.5, 566 | 352225800, 9.5, 567 | 372789000, 10.5, 568 | 384280200, 9.5, 569 | 404843400, 10.5, 570 | 415729800, 9.5, 571 | 436293000, 10.5, 572 | 447179400, 9.5, 573 | 467742600, 10.5, 574 | 478629000, 9.5, 575 | 499192200, 10.5, 576 | 511288200, 9.5, 577 | 530037000, 10.5, 578 | 542737800, 9.5, 579 | 562091400, 10.5, 580 | 574792200, 9.5, 581 | 594145800, 10.5, 582 | 606241800, 9.5, 583 | 625595400, 10.5, 584 | 637691400, 9.5, 585 | 657045000, 10.5, 586 | 667931400, 9.5, 587 | 688494600, 10.5, 588 | 701195400, 9.5, 589 | 719944200, 10.5, 590 | 731435400, 9.5, 591 | 751998600, 10.5, 592 | 764094600, 9.5, 593 | 783448200, 10.5, 594 | 796149000, 9.5, 595 | 814897800, 10.5, 596 | 828203400, 9.5, 597 | 846347400, 10.5, 598 | 859653000, 9.5, 599 | 877797000, 10.5, 600 | 891102600, 9.5, 601 | 909246600, 10.5, 602 | 922552200, 9.5, 603 | 941301000, 10.5, 604 | 954001800, 9.5, 605 | 972750600, 10.5, 606 | 985451400, 9.5, 607 | 1004200200, 10.5, 608 | 1017505800, 9.5, 609 | 1035649800, 10.5, 610 | 1048955400, 9.5, 611 | 1067099400, 10.5, 612 | 1080405000, 9.5, 613 | 1099153800, 10.5, 614 | 1111854600, 9.5, 615 | 1130603400, 10.5, 616 | 1143909000, 9.5, 617 | 1162053000, 10.5, 618 | 1174753800, 9.5, 619 | 1193502600, 10.5, 620 | 1207413000, 9.5, 621 | 1223137800, 10.5, 622 | 1238862600, 9.5, 623 | 1254587400, 10.5, 624 | 1270312200, 9.5, 625 | 1286037000, 10.5, 626 | 1301761800, 9.5, 627 | 1317486600, 10.5, 628 | 1333211400, 9.5, 629 | 1349541000, 10.5, 630 | 1365265800, 9.5, 631 | 1380990600, 10.5, 632 | 1396715400, 9.5, 633 | 1412440200, 10.5, 634 | 1428165000, 9.5, 635 | 1443889800, 10.5, 636 | 1459614600, 9.5, 637 | 1475339400, 10.5, 638 | 1491064200, 9.5, 639 | 1506789000, 10.5, 640 | 1522513800, 9.5, 641 | 1538843400, 10.5, 642 | 1554568200, 9.5, 643 | 1570293000, 10.5, 644 | 1586017800, 9.5, 645 | 1601742600, 10.5, 646 | 1617467400, 9.5, 647 | 1633192200, 10.5, 648 | 1648917000, 9.5, 649 | 1664641800, 10.5, 650 | 1680366600, 9.5, 651 | 1696091400, 10.5, 652 | 1712421000, 9.5, 653 | 1728145800, 10.5, 654 | 1743870600, 9.5, 655 | 1759595400, 10.5, 656 | 1775320200, 9.5, 657 | 1791045000, 10.5, 658 | 1806769800, 9.5, 659 | 1822494600, 10.5, 660 | 1838219400, 9.5, 661 | 1853944200, 10.5, 662 | 1869669000, 9.5, 663 | 1885998600, 10.5, 664 | 1901723400, 9.5, 665 | 1917448200, 10.5, 666 | 1933173000, 9.5, 667 | 1948897800, 10.5, 668 | 1964622600, 9.5, 669 | 1980347400, 10.5, 670 | 1996072200, 9.5, 671 | 2011797000, 10.5, 672 | 2027521800, 9.5, 673 | 2043246600, 10.5, 674 | 2058971400, 9.5, 675 | 2075301000, 10.5, 676 | 2091025800, 9.5, 677 | 2106750600, 10.5, 678 | 2122475400, 9.5, 679 | 2138200200, 10.5, 680 | ], 681 | }, 682 | 'Etc/GMT+12': { 683 | names: [-12, '-12'], 684 | transitions: [ 685 | 0, -12, 686 | Infinity, -12, 687 | ], 688 | }, 689 | 'Etc/GMT+11': { 690 | names: [-11, '-11'], 691 | transitions: [ 692 | 0, -11, 693 | Infinity, -11, 694 | ], 695 | }, 696 | 'Etc/GMT+10': { 697 | names: [-10, '-10'], 698 | transitions: [ 699 | 0, -10, 700 | Infinity, -10, 701 | ], 702 | }, 703 | 'Etc/GMT+9': { 704 | names: [-9, '-09'], 705 | transitions: [ 706 | 0, -9, 707 | Infinity, -9, 708 | ], 709 | }, 710 | 'Etc/GMT+8': { 711 | names: [-8, '-08'], 712 | transitions: [ 713 | 0, -8, 714 | Infinity, -8, 715 | ], 716 | }, 717 | 'Etc/GMT+7': { 718 | names: [-7, '-07'], 719 | transitions: [ 720 | 0, -7, 721 | Infinity, -7, 722 | ], 723 | }, 724 | 'Etc/GMT+6': { 725 | names: [-6, '-06'], 726 | transitions: [ 727 | 0, -6, 728 | Infinity, -6, 729 | ], 730 | }, 731 | 'Etc/GMT+5': { 732 | names: [-5, '-05'], 733 | transitions: [ 734 | 0, -5, 735 | Infinity, -5, 736 | ], 737 | }, 738 | 'Etc/GMT+4': { 739 | names: [-4, '-04'], 740 | transitions: [ 741 | 0, -4, 742 | Infinity, -4, 743 | ], 744 | }, 745 | 'Etc/GMT+3': { 746 | names: [-3, '-03'], 747 | transitions: [ 748 | 0, -3, 749 | Infinity, -3, 750 | ], 751 | }, 752 | 'Etc/GMT+2': { 753 | names: [-2, '-02'], 754 | transitions: [ 755 | 0, -2, 756 | Infinity, -2, 757 | ], 758 | }, 759 | 'Etc/GMT+1': { 760 | names: [-1, '-01'], 761 | transitions: [ 762 | 0, -1, 763 | Infinity, -1, 764 | ], 765 | }, 766 | 'Etc/GMT+0': { 767 | names: [0, 'GMT'], 768 | transitions: [ 769 | 0, 0, 770 | Infinity, 0, 771 | ], 772 | }, 773 | 'Etc/GMT': { 774 | names: [0, 'GMT'], 775 | transitions: [ 776 | 0, 0, 777 | Infinity, 0, 778 | ], 779 | }, 780 | 'Etc/GMT-0': { 781 | names: [0, 'GMT'], 782 | transitions: [ 783 | 0, 0, 784 | Infinity, 0, 785 | ], 786 | }, 787 | 'Etc/GMT-1': { 788 | names: [1, '+01'], 789 | transitions: [ 790 | 0, 1, 791 | Infinity, 1, 792 | ], 793 | }, 794 | 'Etc/GMT-2': { 795 | names: [2, '+02'], 796 | transitions: [ 797 | 0, 2, 798 | Infinity, 2, 799 | ], 800 | }, 801 | 'Etc/GMT-3': { 802 | names: [3, '+03'], 803 | transitions: [ 804 | 0, 3, 805 | Infinity, 3, 806 | ], 807 | }, 808 | 'Etc/GMT-4': { 809 | names: [4, '+04'], 810 | transitions: [ 811 | 0, 4, 812 | Infinity, 4, 813 | ], 814 | }, 815 | 'Etc/GMT-5': { 816 | names: [5, '+05'], 817 | transitions: [ 818 | 0, 5, 819 | Infinity, 5, 820 | ], 821 | }, 822 | 'Etc/GMT-6': { 823 | names: [6, '+06'], 824 | transitions: [ 825 | 0, 6, 826 | Infinity, 6, 827 | ], 828 | }, 829 | 'Etc/GMT-7': { 830 | names: [7, '+07'], 831 | transitions: [ 832 | 0, 7, 833 | Infinity, 7, 834 | ], 835 | }, 836 | 'Etc/GMT-8': { 837 | names: [8, '+08'], 838 | transitions: [ 839 | 0, 8, 840 | Infinity, 8, 841 | ], 842 | }, 843 | 'Etc/GMT-9': { 844 | names: [9, '+09'], 845 | transitions: [ 846 | 0, 9, 847 | Infinity, 9, 848 | ], 849 | }, 850 | 'Etc/GMT-10': { 851 | names: [10, '+10'], 852 | transitions: [ 853 | 0, 10, 854 | Infinity, 10, 855 | ], 856 | }, 857 | 'Etc/GMT-11': { 858 | names: [11, '+11'], 859 | transitions: [ 860 | 0, 11, 861 | Infinity, 11, 862 | ], 863 | }, 864 | 'Etc/GMT-12': { 865 | names: [12, '+12'], 866 | transitions: [ 867 | 0, 12, 868 | Infinity, 12, 869 | ], 870 | }, 871 | 'Etc/GMT-13': { 872 | names: [13, '+13'], 873 | transitions: [ 874 | 0, 13, 875 | Infinity, 13, 876 | ], 877 | }, 878 | 'Etc/GMT-14': { 879 | names: [14, '+14'], 880 | transitions: [ 881 | 0, 14, 882 | Infinity, 14, 883 | ], 884 | }, 885 | }; 886 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "timezone-mock", 3 | "version": "1.3.5", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.8.3", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", 10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", 11 | "dev": true, 12 | "requires": { 13 | "@babel/highlight": "^7.8.3" 14 | } 15 | }, 16 | "@babel/highlight": { 17 | "version": "7.8.3", 18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", 19 | "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", 20 | "dev": true, 21 | "requires": { 22 | "chalk": "^2.0.0", 23 | "esutils": "^2.0.2", 24 | "js-tokens": "^4.0.0" 25 | } 26 | }, 27 | "acorn": { 28 | "version": "7.1.0", 29 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", 30 | "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", 31 | "dev": true 32 | }, 33 | "acorn-jsx": { 34 | "version": "5.1.0", 35 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", 36 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", 37 | "dev": true 38 | }, 39 | "ajv": { 40 | "version": "6.11.0", 41 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", 42 | "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", 43 | "dev": true, 44 | "requires": { 45 | "fast-deep-equal": "^3.1.1", 46 | "fast-json-stable-stringify": "^2.0.0", 47 | "json-schema-traverse": "^0.4.1", 48 | "uri-js": "^4.2.2" 49 | } 50 | }, 51 | "ansi-escapes": { 52 | "version": "4.3.0", 53 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", 54 | "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", 55 | "dev": true, 56 | "requires": { 57 | "type-fest": "^0.8.1" 58 | } 59 | }, 60 | "ansi-regex": { 61 | "version": "5.0.0", 62 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 63 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 64 | "dev": true 65 | }, 66 | "ansi-styles": { 67 | "version": "3.2.1", 68 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 69 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 70 | "dev": true, 71 | "requires": { 72 | "color-convert": "^1.9.0" 73 | } 74 | }, 75 | "argparse": { 76 | "version": "1.0.10", 77 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 78 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 79 | "dev": true, 80 | "requires": { 81 | "sprintf-js": "~1.0.2" 82 | } 83 | }, 84 | "astral-regex": { 85 | "version": "1.0.0", 86 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 87 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 88 | "dev": true 89 | }, 90 | "balanced-match": { 91 | "version": "1.0.0", 92 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 93 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 94 | "dev": true 95 | }, 96 | "brace-expansion": { 97 | "version": "1.1.11", 98 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 99 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 100 | "dev": true, 101 | "requires": { 102 | "balanced-match": "^1.0.0", 103 | "concat-map": "0.0.1" 104 | } 105 | }, 106 | "callsites": { 107 | "version": "3.1.0", 108 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 109 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 110 | "dev": true 111 | }, 112 | "chalk": { 113 | "version": "2.4.2", 114 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 115 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 116 | "dev": true, 117 | "requires": { 118 | "ansi-styles": "^3.2.1", 119 | "escape-string-regexp": "^1.0.5", 120 | "supports-color": "^5.3.0" 121 | } 122 | }, 123 | "chardet": { 124 | "version": "0.7.0", 125 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 126 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 127 | "dev": true 128 | }, 129 | "cli-cursor": { 130 | "version": "3.1.0", 131 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 132 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 133 | "dev": true, 134 | "requires": { 135 | "restore-cursor": "^3.1.0" 136 | } 137 | }, 138 | "cli-width": { 139 | "version": "2.2.0", 140 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 141 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 142 | "dev": true 143 | }, 144 | "color-convert": { 145 | "version": "1.9.3", 146 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 147 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 148 | "dev": true, 149 | "requires": { 150 | "color-name": "1.1.3" 151 | } 152 | }, 153 | "color-name": { 154 | "version": "1.1.3", 155 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 156 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 157 | "dev": true 158 | }, 159 | "concat-map": { 160 | "version": "0.0.1", 161 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 162 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 163 | "dev": true 164 | }, 165 | "cross-spawn": { 166 | "version": "6.0.5", 167 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 168 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 169 | "dev": true, 170 | "requires": { 171 | "nice-try": "^1.0.4", 172 | "path-key": "^2.0.1", 173 | "semver": "^5.5.0", 174 | "shebang-command": "^1.2.0", 175 | "which": "^1.2.9" 176 | }, 177 | "dependencies": { 178 | "semver": { 179 | "version": "5.7.1", 180 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 181 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 182 | "dev": true 183 | } 184 | } 185 | }, 186 | "debug": { 187 | "version": "4.1.1", 188 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 189 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 190 | "dev": true, 191 | "requires": { 192 | "ms": "^2.1.1" 193 | } 194 | }, 195 | "deep-is": { 196 | "version": "0.1.3", 197 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 198 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 199 | "dev": true 200 | }, 201 | "doctrine": { 202 | "version": "3.0.0", 203 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 204 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 205 | "dev": true, 206 | "requires": { 207 | "esutils": "^2.0.2" 208 | } 209 | }, 210 | "emoji-regex": { 211 | "version": "8.0.0", 212 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 213 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 214 | "dev": true 215 | }, 216 | "escape-string-regexp": { 217 | "version": "1.0.5", 218 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 219 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 220 | "dev": true 221 | }, 222 | "eslint": { 223 | "version": "6.8.0", 224 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 225 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 226 | "dev": true, 227 | "requires": { 228 | "@babel/code-frame": "^7.0.0", 229 | "ajv": "^6.10.0", 230 | "chalk": "^2.1.0", 231 | "cross-spawn": "^6.0.5", 232 | "debug": "^4.0.1", 233 | "doctrine": "^3.0.0", 234 | "eslint-scope": "^5.0.0", 235 | "eslint-utils": "^1.4.3", 236 | "eslint-visitor-keys": "^1.1.0", 237 | "espree": "^6.1.2", 238 | "esquery": "^1.0.1", 239 | "esutils": "^2.0.2", 240 | "file-entry-cache": "^5.0.1", 241 | "functional-red-black-tree": "^1.0.1", 242 | "glob-parent": "^5.0.0", 243 | "globals": "^12.1.0", 244 | "ignore": "^4.0.6", 245 | "import-fresh": "^3.0.0", 246 | "imurmurhash": "^0.1.4", 247 | "inquirer": "^7.0.0", 248 | "is-glob": "^4.0.0", 249 | "js-yaml": "^3.13.1", 250 | "json-stable-stringify-without-jsonify": "^1.0.1", 251 | "levn": "^0.3.0", 252 | "lodash": "^4.17.14", 253 | "minimatch": "^3.0.4", 254 | "mkdirp": "^0.5.1", 255 | "natural-compare": "^1.4.0", 256 | "optionator": "^0.8.3", 257 | "progress": "^2.0.0", 258 | "regexpp": "^2.0.1", 259 | "semver": "^6.1.2", 260 | "strip-ansi": "^5.2.0", 261 | "strip-json-comments": "^3.0.1", 262 | "table": "^5.2.3", 263 | "text-table": "^0.2.0", 264 | "v8-compile-cache": "^2.0.3" 265 | } 266 | }, 267 | "eslint-scope": { 268 | "version": "5.0.0", 269 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", 270 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", 271 | "dev": true, 272 | "requires": { 273 | "esrecurse": "^4.1.0", 274 | "estraverse": "^4.1.1" 275 | } 276 | }, 277 | "eslint-utils": { 278 | "version": "1.4.3", 279 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 280 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 281 | "dev": true, 282 | "requires": { 283 | "eslint-visitor-keys": "^1.1.0" 284 | } 285 | }, 286 | "eslint-visitor-keys": { 287 | "version": "1.1.0", 288 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 289 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 290 | "dev": true 291 | }, 292 | "espree": { 293 | "version": "6.1.2", 294 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", 295 | "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", 296 | "dev": true, 297 | "requires": { 298 | "acorn": "^7.1.0", 299 | "acorn-jsx": "^5.1.0", 300 | "eslint-visitor-keys": "^1.1.0" 301 | } 302 | }, 303 | "esprima": { 304 | "version": "4.0.1", 305 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 306 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 307 | "dev": true 308 | }, 309 | "esquery": { 310 | "version": "1.0.1", 311 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 312 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 313 | "dev": true, 314 | "requires": { 315 | "estraverse": "^4.0.0" 316 | } 317 | }, 318 | "esrecurse": { 319 | "version": "4.2.1", 320 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 321 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 322 | "dev": true, 323 | "requires": { 324 | "estraverse": "^4.1.0" 325 | } 326 | }, 327 | "estraverse": { 328 | "version": "4.3.0", 329 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 330 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 331 | "dev": true 332 | }, 333 | "esutils": { 334 | "version": "2.0.3", 335 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 336 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 337 | "dev": true 338 | }, 339 | "external-editor": { 340 | "version": "3.1.0", 341 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 342 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 343 | "dev": true, 344 | "requires": { 345 | "chardet": "^0.7.0", 346 | "iconv-lite": "^0.4.24", 347 | "tmp": "^0.0.33" 348 | } 349 | }, 350 | "fast-deep-equal": { 351 | "version": "3.1.1", 352 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 353 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", 354 | "dev": true 355 | }, 356 | "fast-json-stable-stringify": { 357 | "version": "2.1.0", 358 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 359 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 360 | "dev": true 361 | }, 362 | "fast-levenshtein": { 363 | "version": "2.0.6", 364 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 365 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 366 | "dev": true 367 | }, 368 | "figures": { 369 | "version": "3.1.0", 370 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", 371 | "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", 372 | "dev": true, 373 | "requires": { 374 | "escape-string-regexp": "^1.0.5" 375 | } 376 | }, 377 | "file-entry-cache": { 378 | "version": "5.0.1", 379 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 380 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 381 | "dev": true, 382 | "requires": { 383 | "flat-cache": "^2.0.1" 384 | } 385 | }, 386 | "flat-cache": { 387 | "version": "2.0.1", 388 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 389 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 390 | "dev": true, 391 | "requires": { 392 | "flatted": "^2.0.0", 393 | "rimraf": "2.6.3", 394 | "write": "1.0.3" 395 | } 396 | }, 397 | "flatted": { 398 | "version": "2.0.1", 399 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 400 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 401 | "dev": true 402 | }, 403 | "fs.realpath": { 404 | "version": "1.0.0", 405 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 406 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 407 | "dev": true 408 | }, 409 | "functional-red-black-tree": { 410 | "version": "1.0.1", 411 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 412 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 413 | "dev": true 414 | }, 415 | "glob": { 416 | "version": "7.1.6", 417 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 418 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 419 | "dev": true, 420 | "requires": { 421 | "fs.realpath": "^1.0.0", 422 | "inflight": "^1.0.4", 423 | "inherits": "2", 424 | "minimatch": "^3.0.4", 425 | "once": "^1.3.0", 426 | "path-is-absolute": "^1.0.0" 427 | } 428 | }, 429 | "glob-parent": { 430 | "version": "5.1.0", 431 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 432 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 433 | "dev": true, 434 | "requires": { 435 | "is-glob": "^4.0.1" 436 | } 437 | }, 438 | "globals": { 439 | "version": "12.3.0", 440 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", 441 | "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", 442 | "dev": true, 443 | "requires": { 444 | "type-fest": "^0.8.1" 445 | } 446 | }, 447 | "has-flag": { 448 | "version": "3.0.0", 449 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 450 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 451 | "dev": true 452 | }, 453 | "iconv-lite": { 454 | "version": "0.4.24", 455 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 456 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 457 | "dev": true, 458 | "requires": { 459 | "safer-buffer": ">= 2.1.2 < 3" 460 | } 461 | }, 462 | "ignore": { 463 | "version": "4.0.6", 464 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 465 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 466 | "dev": true 467 | }, 468 | "import-fresh": { 469 | "version": "3.2.1", 470 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 471 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 472 | "dev": true, 473 | "requires": { 474 | "parent-module": "^1.0.0", 475 | "resolve-from": "^4.0.0" 476 | } 477 | }, 478 | "imurmurhash": { 479 | "version": "0.1.4", 480 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 481 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 482 | "dev": true 483 | }, 484 | "inflight": { 485 | "version": "1.0.6", 486 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 487 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 488 | "dev": true, 489 | "requires": { 490 | "once": "^1.3.0", 491 | "wrappy": "1" 492 | } 493 | }, 494 | "inherits": { 495 | "version": "2.0.4", 496 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 497 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 498 | "dev": true 499 | }, 500 | "inquirer": { 501 | "version": "7.0.4", 502 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", 503 | "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", 504 | "dev": true, 505 | "requires": { 506 | "ansi-escapes": "^4.2.1", 507 | "chalk": "^2.4.2", 508 | "cli-cursor": "^3.1.0", 509 | "cli-width": "^2.0.0", 510 | "external-editor": "^3.0.3", 511 | "figures": "^3.0.0", 512 | "lodash": "^4.17.15", 513 | "mute-stream": "0.0.8", 514 | "run-async": "^2.2.0", 515 | "rxjs": "^6.5.3", 516 | "string-width": "^4.1.0", 517 | "strip-ansi": "^5.1.0", 518 | "through": "^2.3.6" 519 | } 520 | }, 521 | "is-extglob": { 522 | "version": "2.1.1", 523 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 524 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 525 | "dev": true 526 | }, 527 | "is-fullwidth-code-point": { 528 | "version": "3.0.0", 529 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 530 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 531 | "dev": true 532 | }, 533 | "is-glob": { 534 | "version": "4.0.1", 535 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 536 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 537 | "dev": true, 538 | "requires": { 539 | "is-extglob": "^2.1.1" 540 | } 541 | }, 542 | "is-promise": { 543 | "version": "2.1.0", 544 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 545 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 546 | "dev": true 547 | }, 548 | "isexe": { 549 | "version": "2.0.0", 550 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 551 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 552 | "dev": true 553 | }, 554 | "js-tokens": { 555 | "version": "4.0.0", 556 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 557 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 558 | "dev": true 559 | }, 560 | "js-yaml": { 561 | "version": "3.13.1", 562 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 563 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 564 | "dev": true, 565 | "requires": { 566 | "argparse": "^1.0.7", 567 | "esprima": "^4.0.0" 568 | } 569 | }, 570 | "json-schema-traverse": { 571 | "version": "0.4.1", 572 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 573 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 574 | "dev": true 575 | }, 576 | "json-stable-stringify-without-jsonify": { 577 | "version": "1.0.1", 578 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 579 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 580 | "dev": true 581 | }, 582 | "levn": { 583 | "version": "0.3.0", 584 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 585 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 586 | "dev": true, 587 | "requires": { 588 | "prelude-ls": "~1.1.2", 589 | "type-check": "~0.3.2" 590 | } 591 | }, 592 | "lodash": { 593 | "version": "4.17.15", 594 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 595 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 596 | "dev": true 597 | }, 598 | "mimic-fn": { 599 | "version": "2.1.0", 600 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 601 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 602 | "dev": true 603 | }, 604 | "minimatch": { 605 | "version": "3.0.4", 606 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 607 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 608 | "dev": true, 609 | "requires": { 610 | "brace-expansion": "^1.1.7" 611 | } 612 | }, 613 | "minimist": { 614 | "version": "0.0.8", 615 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 616 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 617 | "dev": true 618 | }, 619 | "mkdirp": { 620 | "version": "0.5.1", 621 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 622 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 623 | "dev": true, 624 | "requires": { 625 | "minimist": "0.0.8" 626 | } 627 | }, 628 | "ms": { 629 | "version": "2.1.2", 630 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 631 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 632 | "dev": true 633 | }, 634 | "mute-stream": { 635 | "version": "0.0.8", 636 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 637 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 638 | "dev": true 639 | }, 640 | "natural-compare": { 641 | "version": "1.4.0", 642 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 643 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 644 | "dev": true 645 | }, 646 | "nice-try": { 647 | "version": "1.0.5", 648 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 649 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 650 | "dev": true 651 | }, 652 | "once": { 653 | "version": "1.4.0", 654 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 655 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 656 | "dev": true, 657 | "requires": { 658 | "wrappy": "1" 659 | } 660 | }, 661 | "onetime": { 662 | "version": "5.1.0", 663 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 664 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 665 | "dev": true, 666 | "requires": { 667 | "mimic-fn": "^2.1.0" 668 | } 669 | }, 670 | "optionator": { 671 | "version": "0.8.3", 672 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 673 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 674 | "dev": true, 675 | "requires": { 676 | "deep-is": "~0.1.3", 677 | "fast-levenshtein": "~2.0.6", 678 | "levn": "~0.3.0", 679 | "prelude-ls": "~1.1.2", 680 | "type-check": "~0.3.2", 681 | "word-wrap": "~1.2.3" 682 | } 683 | }, 684 | "os-tmpdir": { 685 | "version": "1.0.2", 686 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 687 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 688 | "dev": true 689 | }, 690 | "parent-module": { 691 | "version": "1.0.1", 692 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 693 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 694 | "dev": true, 695 | "requires": { 696 | "callsites": "^3.0.0" 697 | } 698 | }, 699 | "path-is-absolute": { 700 | "version": "1.0.1", 701 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 702 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 703 | "dev": true 704 | }, 705 | "path-key": { 706 | "version": "2.0.1", 707 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 708 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 709 | "dev": true 710 | }, 711 | "prelude-ls": { 712 | "version": "1.1.2", 713 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 714 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 715 | "dev": true 716 | }, 717 | "progress": { 718 | "version": "2.0.3", 719 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 720 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 721 | "dev": true 722 | }, 723 | "punycode": { 724 | "version": "2.1.1", 725 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 726 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 727 | "dev": true 728 | }, 729 | "regexpp": { 730 | "version": "2.0.1", 731 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 732 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 733 | "dev": true 734 | }, 735 | "resolve-from": { 736 | "version": "4.0.0", 737 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 738 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 739 | "dev": true 740 | }, 741 | "restore-cursor": { 742 | "version": "3.1.0", 743 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 744 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 745 | "dev": true, 746 | "requires": { 747 | "onetime": "^5.1.0", 748 | "signal-exit": "^3.0.2" 749 | } 750 | }, 751 | "rimraf": { 752 | "version": "2.6.3", 753 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 754 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 755 | "dev": true, 756 | "requires": { 757 | "glob": "^7.1.3" 758 | } 759 | }, 760 | "run-async": { 761 | "version": "2.3.0", 762 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 763 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 764 | "dev": true, 765 | "requires": { 766 | "is-promise": "^2.1.0" 767 | } 768 | }, 769 | "rxjs": { 770 | "version": "6.5.4", 771 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 772 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 773 | "dev": true, 774 | "requires": { 775 | "tslib": "^1.9.0" 776 | } 777 | }, 778 | "safer-buffer": { 779 | "version": "2.1.2", 780 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 781 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 782 | "dev": true 783 | }, 784 | "semver": { 785 | "version": "6.3.0", 786 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 787 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 788 | "dev": true 789 | }, 790 | "shebang-command": { 791 | "version": "1.2.0", 792 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 793 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 794 | "dev": true, 795 | "requires": { 796 | "shebang-regex": "^1.0.0" 797 | } 798 | }, 799 | "shebang-regex": { 800 | "version": "1.0.0", 801 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 802 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 803 | "dev": true 804 | }, 805 | "signal-exit": { 806 | "version": "3.0.2", 807 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 808 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 809 | "dev": true 810 | }, 811 | "slice-ansi": { 812 | "version": "2.1.0", 813 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 814 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 815 | "dev": true, 816 | "requires": { 817 | "ansi-styles": "^3.2.0", 818 | "astral-regex": "^1.0.0", 819 | "is-fullwidth-code-point": "^2.0.0" 820 | }, 821 | "dependencies": { 822 | "is-fullwidth-code-point": { 823 | "version": "2.0.0", 824 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 825 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 826 | "dev": true 827 | } 828 | } 829 | }, 830 | "sprintf-js": { 831 | "version": "1.0.3", 832 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 833 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 834 | "dev": true 835 | }, 836 | "string-width": { 837 | "version": "4.2.0", 838 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 839 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 840 | "dev": true, 841 | "requires": { 842 | "emoji-regex": "^8.0.0", 843 | "is-fullwidth-code-point": "^3.0.0", 844 | "strip-ansi": "^6.0.0" 845 | }, 846 | "dependencies": { 847 | "strip-ansi": { 848 | "version": "6.0.0", 849 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 850 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 851 | "dev": true, 852 | "requires": { 853 | "ansi-regex": "^5.0.0" 854 | } 855 | } 856 | } 857 | }, 858 | "strip-ansi": { 859 | "version": "5.2.0", 860 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 861 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 862 | "dev": true, 863 | "requires": { 864 | "ansi-regex": "^4.1.0" 865 | }, 866 | "dependencies": { 867 | "ansi-regex": { 868 | "version": "4.1.0", 869 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 870 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 871 | "dev": true 872 | } 873 | } 874 | }, 875 | "strip-json-comments": { 876 | "version": "3.0.1", 877 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 878 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 879 | "dev": true 880 | }, 881 | "supports-color": { 882 | "version": "5.5.0", 883 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 884 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 885 | "dev": true, 886 | "requires": { 887 | "has-flag": "^3.0.0" 888 | } 889 | }, 890 | "table": { 891 | "version": "5.4.6", 892 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 893 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 894 | "dev": true, 895 | "requires": { 896 | "ajv": "^6.10.2", 897 | "lodash": "^4.17.14", 898 | "slice-ansi": "^2.1.0", 899 | "string-width": "^3.0.0" 900 | }, 901 | "dependencies": { 902 | "emoji-regex": { 903 | "version": "7.0.3", 904 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 905 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 906 | "dev": true 907 | }, 908 | "is-fullwidth-code-point": { 909 | "version": "2.0.0", 910 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 911 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 912 | "dev": true 913 | }, 914 | "string-width": { 915 | "version": "3.1.0", 916 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 917 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 918 | "dev": true, 919 | "requires": { 920 | "emoji-regex": "^7.0.1", 921 | "is-fullwidth-code-point": "^2.0.0", 922 | "strip-ansi": "^5.1.0" 923 | } 924 | } 925 | } 926 | }, 927 | "text-table": { 928 | "version": "0.2.0", 929 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 930 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 931 | "dev": true 932 | }, 933 | "through": { 934 | "version": "2.3.8", 935 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 936 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 937 | "dev": true 938 | }, 939 | "tmp": { 940 | "version": "0.0.33", 941 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 942 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 943 | "dev": true, 944 | "requires": { 945 | "os-tmpdir": "~1.0.2" 946 | } 947 | }, 948 | "tslib": { 949 | "version": "1.10.0", 950 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 951 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 952 | "dev": true 953 | }, 954 | "type-check": { 955 | "version": "0.3.2", 956 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 957 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 958 | "dev": true, 959 | "requires": { 960 | "prelude-ls": "~1.1.2" 961 | } 962 | }, 963 | "type-fest": { 964 | "version": "0.8.1", 965 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 966 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 967 | "dev": true 968 | }, 969 | "uri-js": { 970 | "version": "4.2.2", 971 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 972 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 973 | "dev": true, 974 | "requires": { 975 | "punycode": "^2.1.0" 976 | } 977 | }, 978 | "v8-compile-cache": { 979 | "version": "2.1.0", 980 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", 981 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", 982 | "dev": true 983 | }, 984 | "which": { 985 | "version": "1.3.1", 986 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 987 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 988 | "dev": true, 989 | "requires": { 990 | "isexe": "^2.0.0" 991 | } 992 | }, 993 | "word-wrap": { 994 | "version": "1.2.3", 995 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 996 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 997 | "dev": true 998 | }, 999 | "wrappy": { 1000 | "version": "1.0.2", 1001 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1002 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1003 | "dev": true 1004 | }, 1005 | "write": { 1006 | "version": "1.0.3", 1007 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1008 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1009 | "dev": true, 1010 | "requires": { 1011 | "mkdirp": "^0.5.1" 1012 | } 1013 | } 1014 | } 1015 | } 1016 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "timezone-mock", 3 | "version": "1.3.6", 4 | "description": "A JavaScript library to mock the local timezone.", 5 | "main": "index.js", 6 | "types": "index.d.ts", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/Jimbly/timezone-mock.git" 10 | }, 11 | "keywords": [ 12 | "timezone", 13 | "mock", 14 | "date", 15 | "dst", 16 | "daylight", 17 | "saving", 18 | "savings", 19 | "time" 20 | ], 21 | "author": "Jimb Esser (https://github.com/Jimbly/)", 22 | "license": "MIT", 23 | "bugs": { 24 | "url": "https://github.com/Jimbly/timezone-mock/issues" 25 | }, 26 | "homepage": "https://github.com/Jimbly/timezone-mock", 27 | "devDependencies": { 28 | "eslint": "^6.8.0" 29 | }, 30 | "scripts": { 31 | "test": "node tests/test-constructors.js", 32 | "lint": "eslint index.js" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tests/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM buildpack-deps:jessie-curl 2 | WORKDIR /root 3 | 4 | ENV NVM_DIR /usr/local/nvm 5 | ENV NODE_VER=9.11.1 6 | 7 | RUN set -ex; \ 8 | apt-get update && apt-get install --force-yes -y --no-install-recommends \ 9 | git-core \ 10 | build-essential wget && \ 11 | echo $NODE_VER > ~/.nvmrc && \ 12 | curl https://raw.githubusercontent.com/creationix/nvm/v0.23.3/install.sh | bash && \ 13 | echo 'source $NVM_DIR/nvm.sh' >> /etc/profile && \ 14 | /bin/bash -l -c "nvm install;" "nvm use;" && \ 15 | echo 'pushd /root >/dev/null && nvm use && popd > /dev/null' >> ~/.bashrc && \ 16 | git clone https://github.com/wolfcw/libfaketime.git && \ 17 | cd /root/libfaketime/src && \ 18 | make install && \ 19 | rm -rf /var/lib/apt/lists/* && \ 20 | rm -rf /root/libfaketime 21 | 22 | RUN cp /usr/share/zoneinfo/America/Los_Angeles /etc/localtime 23 | 24 | ENV LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 25 | ENV FAKETIME_NO_CACHE=1 26 | ENV FAKETIME="2018-01-01 12:00:00" 27 | WORKDIR /C/src/timezone-mock/tests 28 | 29 | -------------------------------------------------------------------------------- /tests/test-constructors.js: -------------------------------------------------------------------------------- 1 | /* eslint-env es6 */ 2 | // This test should pass regardless of what timezone your local machine is in 3 | 4 | var assert = require('assert'); 5 | var timezone_mock = require('..'); 6 | 7 | var test = global.test || function (name, tst) { 8 | console.log('TEST:', name, '...'); 9 | tst(); 10 | console.log(' PASSED!'); 11 | }; 12 | 13 | function isMockDate(d) { 14 | return typeof d.fromLocal === 'function'; 15 | } 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | // This test must be first 19 | test('unregister without register', function() { 20 | assert.ok(!isMockDate(new Date())); 21 | timezone_mock.unregister(); 22 | assert.ok(!isMockDate(new Date())); 23 | timezone_mock.register(); 24 | assert.ok(isMockDate(new Date())); 25 | timezone_mock.unregister(); 26 | assert.ok(!isMockDate(new Date())); 27 | }); 28 | 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | test('"simple" date constructors', function() { 32 | timezone_mock.register(); 33 | assert.ok(new Date()); 34 | assert.ok(new Date(null)); 35 | 36 | assert.ok(new Date('')); 37 | assert.ok(new Date('').toString() === 'Invalid Date'); 38 | assert.ok(Number.isNaN(new Date('').getHours())); 39 | assert.equal(new Date(1627943659743).toString(), '2021-08-02T22:34:19.743Z UTC (MockDate: GMT-0700)'); 40 | assert.equal(Object.prototype.toString.call(new Date(1627943659743)), '[object Date]'); 41 | assert.equal(Object.prototype.toString.call(undefined), '[object Undefined]'); 42 | 43 | var invalidDateMadeValid = new Date(''); 44 | assert.ok(invalidDateMadeValid.setTime(12345) === 12345); 45 | assert.ok(!Number.isNaN(invalidDateMadeValid.getHours())); 46 | }); 47 | 48 | ////////////////////////////////////////////////////////////////////////// 49 | test('date constructors as used by local timezone mode in node-mysql (local strings)', function() { 50 | var test_str = '2015-01-01 01:23:45.678'; 51 | timezone_mock.register('UTC'); 52 | assert.equal(1420104225678 - 8*60*60*1000, new Date(test_str).getTime()); 53 | assert.equal(1420104225678 - 8*60*60*1000, new Date(2015, 0, 1, 1, 23, 45, 678).getTime()); 54 | timezone_mock.register('US/Pacific'); 55 | assert.equal(1420104225678, new Date(test_str).getTime()); 56 | assert.equal(1420104225678, new Date(2015, 0, 1, 1, 23, 45, 678).getTime()); 57 | timezone_mock.register('US/Eastern'); 58 | assert.equal(1420104225678 - 3*60*60*1000, new Date(test_str).getTime()); 59 | assert.equal(1420104225678 - 3*60*60*1000, new Date(2015, 0, 1, 1, 23, 45, 678).getTime()); 60 | 61 | timezone_mock.register('US/Pacific'); 62 | test_str = '2015-03-08 01:30:00.000'; // right before entering PDT 63 | assert.equal(1425807000000, new Date(test_str).getTime()); 64 | assert.equal(new Date(test_str).getTime(), new Date(test_str).valueOf()); 65 | assert.equal(1425807000000, new Date(2015, 2, 8, 1, 30, 0, 0).getTime()); 66 | test_str = '2015-03-08 02:30:00.000'; // doesn't exist, ends up 1:30am 67 | assert.equal(1425807000000, new Date(test_str).getTime()); 68 | assert.equal(1425807000000, new Date(2015, 2, 8, 2, 30, 0, 0).getTime()); 69 | test_str = '2015-03-08 03:30:00.000'; // in PDT 70 | assert.equal(1425810600000, new Date(test_str).getTime()); 71 | assert.equal(1425810600000, new Date(2015, 2, 8, 3, 30, 0, 0).getTime()); 72 | // leaving PDT, JS Date returns 1am PDT, not 1am PST 73 | // JE: 2017-05-26, Node 6.9.1, Not sure why this was 1am PST before, no changes 74 | // to node should have changed how our mock behaves, yet, the mock is still 75 | // behaving the same as node, just they are both returning a different value 76 | // than the test previously expected, so, updating the test to reflect this. 77 | test_str = '2014-11-02 01:00:00.000'; 78 | assert.equal(1414915200000, new Date(test_str).getTime()); 79 | assert.equal(1414915200000, new Date(2014, 10, 2, 1, 0, 0, 0).getTime()); 80 | 81 | // Testing "local" constructors that look like UTC constructors, 82 | // This behavior changed on Node v8.0.0 83 | assert.equal(1420104225678, new Date('2015-01-01T01:23:45.678').getTime()); 84 | assert.equal(1420104225000, new Date('2015-01-01T01:23:45').getTime()); 85 | 86 | // supports variation of ECMAscript spec for THH:mm 87 | // https://www.ecma-international.org/ecma-262/#sec-date-time-string-format 88 | assert.equal(1414915200000, new Date('2014-11-02T01:00').getTime()); 89 | }); 90 | 91 | ///////////////////////////////// 92 | test('constructor supports time format YYYY-MM-DDZ', function() { 93 | timezone_mock.register('UTC'); 94 | assert.equal(new Date('2017-05-26Z').toLocaleTimeString('en-US'), '12:00:00 AM'); 95 | assert.equal(new Date('2017-05-26Z').toLocaleDateString('en-US'), '5/26/2017'); 96 | assert.throws(() => new Date('2017-05-26X').toLocaleTimeString('en-US')); 97 | timezone_mock.unregister(); 98 | timezone_mock.register('US/Pacific'); 99 | assert.equal(new Date('2017-05-26Z').toLocaleTimeString('en-US'), '5:00:00 PM'); 100 | assert.equal(new Date('2017-05-26Z').toLocaleDateString('en-US'), '5/25/2017'); 101 | timezone_mock.unregister(); 102 | }); 103 | 104 | ///////////////////////////////// 105 | test('constructor supports time format YYYY-MM-DDThh:mmZ', function() { 106 | timezone_mock.register('UTC'); 107 | assert.equal(new Date('2017-05-26T00:00Z').toLocaleTimeString('en-US'), '12:00:00 AM'); 108 | assert.equal(new Date('2017-05-26T00:00Z').toLocaleDateString('en-US'), '5/26/2017'); 109 | assert.throws(() => new Date('2017-05-26T00:00:Z').toLocaleTimeString('en-US')); 110 | timezone_mock.unregister(); 111 | timezone_mock.register('US/Pacific'); 112 | assert.equal(new Date('2017-05-26T00:00Z').toLocaleTimeString('en-US'), '5:00:00 PM'); 113 | assert.equal(new Date('2017-05-26T00:00Z').toLocaleDateString('en-US'), '5/25/2017'); 114 | timezone_mock.unregister(); 115 | }); 116 | 117 | ///////////////////////////////// 118 | test('constructor supports time format Fri, 27 Jul 2019 10:32:24 GMT', function() { 119 | timezone_mock.register('UTC'); 120 | assert.equal(new Date('Fri, 27 Jul 2019 10:32:24 GMT').toLocaleString('en-US'), '7/27/2019, 10:32:24 AM'); 121 | assert.throws(() => new Date('Fre, 27 Jul 2019 10:32:24 GMT').toLocaleString('en-US')); 122 | timezone_mock.unregister(); 123 | timezone_mock.register('US/Pacific'); 124 | assert.equal(new Date('Fri, 27 Jul 2019 10:32:24 GMT').toLocaleString('en-US'), '7/27/2019, 3:32:24 AM'); 125 | timezone_mock.unregister(); 126 | }); 127 | 128 | ////////////////////////////////////////////////////////////////////////// 129 | test('UTC/non-local timezone constructors', function() { 130 | assert.equal(1495821155869, new Date('2017-05-26T17:52:35.869Z').getTime()); 131 | assert.equal(1495821155869, new Date('2017-05-26T17:52:35.869000Z').getTime()); 132 | assert.equal(1495821155869, new Date('2017-05-26 17:52:35.869 Z').getTime()); 133 | assert.equal(1495821155869, new Date('2017-05-26 17:52:35.869 -00:00').getTime()); 134 | assert.equal(1495821155869, new Date('2017-05-26 17:52:35.869 +00:00').getTime()); 135 | assert.equal(1495821155869, new Date('2017-05-26 18:52:35.869 +01:00').getTime()); 136 | assert.equal(1495821155869, new Date('2017-05-26 10:52:35.869 -07:00').getTime()); 137 | assert.equal(1495821155869, new Date('2017-05-26T17:52:35.869+00:00').getTime()); 138 | assert.equal(1495821155869, new Date('2017-05-26T10:52:35.869-0700').getTime()); 139 | assert.equal(1495821155000, new Date('2017-05-26T17:52:35+00:00').getTime()); 140 | assert.equal(1495821155000, new Date('2017-05-26 17:52:35 +00:00').getTime()); 141 | assert.equal(1495821155000, new Date('2017-05-26 10:52:35 -07:00').getTime()); 142 | }); 143 | 144 | ////////////////////////////////////////////////////////////////////////// 145 | test('some generic properties about the date object', function() { 146 | assert.equal(new Date(2017, 5).getTime(), new Date(2017, 5, 1, 0, 0, 0, 0).getTime()); 147 | }); 148 | 149 | ////////////////////////////////////////////////////////////////////////// 150 | test('Brazil timezone oddities', function() { 151 | var test_str = '2017-10-15 00:00:00.000'; // Midnight on this day doesn't exist, jumps to 11PM previous day 152 | timezone_mock.register('Brazil/East'); 153 | assert.equal(1508032800000, new Date(test_str).getTime()); 154 | assert.equal(1508032800000, new Date(2017, 9, 15, 0, 0, 0, 0).getTime()); 155 | }); 156 | 157 | ////////////////////////////////////////////////////////////////////////// 158 | test('Make sure month May exists', function() { 159 | timezone_mock.register(); 160 | // Any date in May should be in May and not in June 161 | assert.equal(new Date(1588316400000).toDateString(), 'Fri May 01 2020'); 162 | // Any date after May should have the right month name 163 | assert.equal(new Date(1598964466381).toDateString(), 'Tue Sept 01 2020'); 164 | timezone_mock.unregister(); 165 | }); 166 | 167 | ////////////////////////////////////////////////////////////////////////// 168 | test('option to use a fallback function when failing to parse (issue #24)', function() { 169 | timezone_mock.unregister(); 170 | var _Date = Date; 171 | timezone_mock.options({ 172 | fallbackFn: function (date) { 173 | return new _Date(date); 174 | } 175 | }); 176 | timezone_mock.register('UTC'); 177 | assert.equal(new Date('Fri, 26 Jul 2019 10:32:24 GMT-1').toDateString(), 'Fri Jul 26 2019'); 178 | timezone_mock.unregister(); 179 | 180 | // How can we reset options? 181 | timezone_mock.options(); 182 | timezone_mock.register('UTC'); 183 | var got_error = false; 184 | try { 185 | assert.equal(new Date('Fri, 26 Jul 2019 10:32:24 GMT-1').toDateString(), 'Fri Jul 26 2019'); 186 | } catch (err) { 187 | // Expected 188 | got_error = true; 189 | } 190 | assert.equal(got_error, true); 191 | timezone_mock.unregister(); 192 | }); 193 | 194 | ////////////////////////////////////////////////////////////////////////// 195 | test('toLocaleString() works', function() { 196 | const options = { 197 | year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric' 198 | }; 199 | timezone_mock.register('UTC'); 200 | assert.equal('May 26, 2017, 5:52 PM', new Date('2017-05-26T17:52:35.869Z').toLocaleString('en-US', options)); 201 | timezone_mock.unregister(); 202 | timezone_mock.register('US/Pacific'); 203 | assert.equal('May 26, 2017, 10:52 AM', new Date('2017-05-26T17:52:35.869Z').toLocaleString('en-US', options)); 204 | timezone_mock.unregister(); 205 | timezone_mock.register('Australia/Adelaide'); 206 | assert.equal('May 27, 2017, 3:22 AM', new Date('2017-05-26T17:52:35.869Z').toLocaleString('en-US', options)); 207 | timezone_mock.unregister(); 208 | timezone_mock.register('Australia/Adelaide'); 209 | const optionsWithTz = { 210 | year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: 'numeric', timeZone: 'UTC' 211 | }; 212 | assert.equal('May 26, 2017, 5:52 PM', new Date('2017-05-26T17:52:35.869Z').toLocaleString('en-US', optionsWithTz)); 213 | timezone_mock.unregister(); 214 | }); 215 | 216 | ////////////////////////////////////////////////////////////////////////// 217 | test('toLocaleDateString() works', function() { 218 | const options = { 219 | year: 'numeric', month: 'short', day: 'numeric' 220 | }; 221 | timezone_mock.register('UTC'); 222 | assert.equal('May 26, 2017', new Date('2017-05-26T17:52:35.869Z').toLocaleDateString('en-US', options)); 223 | timezone_mock.unregister(); 224 | timezone_mock.register('US/Pacific'); 225 | assert.equal('May 26, 2017', new Date('2017-05-26T17:52:35.869Z').toLocaleDateString('en-US', options)); 226 | timezone_mock.unregister(); 227 | timezone_mock.register('Australia/Adelaide'); 228 | assert.equal('May 27, 2017', new Date('2017-05-26T17:52:35.869Z').toLocaleDateString('en-US', options)); 229 | timezone_mock.unregister(); 230 | timezone_mock.register('Australia/Adelaide'); 231 | const optionsWithTz = { 232 | year: 'numeric', month: 'short', day: 'numeric', timeZone: 'UTC' 233 | }; 234 | assert.equal('May 26, 2017', new Date('2017-05-26T17:52:35.869Z').toLocaleDateString('en-US', optionsWithTz)); 235 | timezone_mock.unregister(); 236 | }); 237 | 238 | ////////////////////////////////////////////////////////////////////////// 239 | test('toLocaleTimeString() works', function() { 240 | timezone_mock.register('UTC'); 241 | assert.equal('5:52:35 PM', new Date('2017-05-26T17:52:35.869Z').toLocaleTimeString('en-US')); 242 | timezone_mock.unregister(); 243 | timezone_mock.register('US/Pacific'); 244 | assert.equal('10:52:35 AM', new Date('2017-05-26T17:52:35.869Z').toLocaleTimeString('en-US')); 245 | timezone_mock.unregister(); 246 | timezone_mock.register('Australia/Adelaide'); 247 | assert.equal('3:22:35 AM', new Date('2017-05-26T17:52:35.869Z').toLocaleTimeString('en-US')); 248 | timezone_mock.unregister(); 249 | timezone_mock.register('Australia/Adelaide'); 250 | assert.equal('5:52:35 PM', new Date('2017-05-26T17:52:35.869Z').toLocaleTimeString('en-US', { timeZone: 'UTC' })); 251 | timezone_mock.unregister(); 252 | }); 253 | 254 | ////////////////////////////////////////////////////////////////////////// 255 | test('chained mocking', function() { 256 | timezone_mock.unregister(); 257 | // Make a mock'd date that changes Date.now() 258 | var RealDate = Date; 259 | assert.ok(!isMockDate(new RealDate())); 260 | function MyDate() { 261 | RealDate.apply(this, arguments); 262 | } 263 | MyDate.prototype = Object.create(RealDate.prototype); 264 | for (var key in Date) { 265 | MyDate[key] = Date[key]; 266 | } 267 | MyDate.now = function () { 268 | return 1234; 269 | }; 270 | global.Date = MyDate; 271 | // Register timezone_mock on top of it 272 | timezone_mock.register(); 273 | // We should get a mocked date using our mocked now function 274 | assert.ok(isMockDate(new Date())); 275 | assert.equal(Date.now(), 1234); 276 | // Unregister timezone_mock and our test mock 277 | timezone_mock.unregister(); 278 | assert.ok(!isMockDate(new Date())); 279 | assert.equal(global.Date, MyDate); 280 | global.Date = RealDate; 281 | }); 282 | -------------------------------------------------------------------------------- /tests/test-setters.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var timezone_mock = require('../'); 3 | 4 | if (!new timezone_mock._Date().toString().match(/\(PDT\)|\(PST\)|\(Pacific Daylight Time\)|\(Pacific Standard Time\)/)) { 5 | // Because we only have timezone info for a couple timezones, we can only test 6 | // this if the timezone we're mocking is the same as the system timezone. 7 | // In theory this could be extended to be able to test any timezone for which 8 | // we have timezone data. 9 | assert.ok(false, 'These tests only work if the local system timezone is Pacific'); 10 | } 11 | 12 | timezone_mock.register('US/Pacific'); 13 | 14 | var orig = new timezone_mock._Date(0); 15 | var mock = new Date(0); 16 | function doit(fn, val, fails) { 17 | var ret_orig = orig[fn](val); 18 | var ret_mock = mock[fn](val); 19 | console.log(fn, val, orig, mock); 20 | if (!fails) { 21 | assert.equal(ret_orig, ret_mock); 22 | assert.equal(orig.getTime(), mock.getTime()); 23 | assert.equal(orig.getHours(), mock.getHours()); 24 | assert.equal(orig.getTimezoneOffset(), mock.getTimezoneOffset()); 25 | } 26 | } 27 | doit('setMinutes', 30); 28 | doit('setFullYear', 2015); 29 | doit('setHours', 0); 30 | doit('setMonth', 2); 31 | doit('setDate', 1); 32 | doit('setDate', 8); 33 | // JE: 2018-04-10: These are not a valid date (setting 2:30am when clocks go from 34 | // 1:59am to 3am on that day), and for some reason we no longer behave exactly 35 | // like Node, so just disabling this test for now. 36 | doit('setHours', 2, true); 37 | doit('setHours', 3); 38 | doit('setHours', 2, true); 39 | doit('setHours', 1); 40 | 41 | doit('setMonth', 9); 42 | doit('setDate', 1); 43 | doit('setHours', 1); 44 | doit('setMonth', 10); 45 | doit('setHours', 0); 46 | doit('setHours', 1); 47 | doit('setHours', 2); 48 | doit('setHours', 1); 49 | 50 | function randInt(max) { 51 | return Math.floor(Math.random() * max); 52 | } 53 | for (var ii = 0; ii < 100000; ++ii) { 54 | switch (randInt(3)) { // eslint-disable-line default-case 55 | case 0: 56 | doit('setMonth', randInt(12)); 57 | break; 58 | case 1: 59 | doit('setDate', randInt(28) + 1); 60 | break; 61 | case 2: 62 | doit('setHours', randInt(24)); 63 | break; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /tests/test-vs-local.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'); 2 | var timezone_mock = require('../'); 3 | 4 | ////////////////////////////////////////////////////////////////////////// 5 | // Test that the mocked date behaves exactly the same as the system date when 6 | // mocking the same timezone. 7 | // JE: 2017-05-26, Node 6.9.1: This test seems to fail when specifying non- 8 | // existent dates (undefined behavior anyway), not sure if this was working 9 | // before or not. 10 | 11 | if (!new timezone_mock._Date().toString().match(/\(PDT\)|\(PST\)|\(Pacific Daylight Time\)|\(Pacific Standard Time\)/)) { 12 | // Because we only have timezone info for a couple timezones, we can only test 13 | // this if the timezone we're mocking is the same as the system timezone. 14 | // In theory this could be extended to be able to test any timezone for which 15 | // we have timezone data. 16 | assert.ok(false, 'These tests only work if the local system timezone is Pacific'); 17 | } 18 | 19 | timezone_mock.register('US/Pacific'); 20 | 21 | // function test(d) { 22 | // var ret = []; 23 | // ret.push(d.getTimezoneOffset()); 24 | // ret.push(d.getHours()); 25 | // d.setTime(new Date('2015-03-08T02:30:11.000Z').getTime()); 26 | // ret.push(d.getTimezoneOffset()); 27 | // ret.push(d.getHours()); 28 | // d.setTime(new Date('2015-03-07T02:30:11.000Z').getTime()); 29 | // ret.push(d.getTimezoneOffset()); 30 | // ret.push(d.getHours()); 31 | // d.setTime(new Date('2015-03-09T02:30:11.000Z').getTime()); 32 | // ret.push(d.getTimezoneOffset()); 33 | // ret.push(d.getHours()); 34 | // return ret; 35 | // } 36 | 37 | var orig = new timezone_mock._Date(); 38 | var mock = new Date(); 39 | 40 | function pad2(v) { 41 | return ('0' + v).slice(-2); 42 | } 43 | 44 | var ts = new Date('2013-01-01T00:00:00.000Z').getTime(); 45 | var was_ok = true; 46 | var last = ts; 47 | var end = ts + 5*365*24*60*60*1000; 48 | var ok; 49 | function check(label) { 50 | function check2(fn) { 51 | if (orig[fn]() !== mock[fn]()) { 52 | ok = false; 53 | if (was_ok) { 54 | console.log(' ' + fn + ' (' + label + ')', orig[fn](), mock[fn]()); 55 | } 56 | } 57 | } 58 | check2('getTimezoneOffset'); 59 | check2('getHours'); 60 | check2('getTime'); 61 | } 62 | for (; ts < end; ts += 13*60*1000) { 63 | orig.setTime(ts); 64 | mock.setTime(ts); 65 | assert.equal(orig.toISOString(), mock.toISOString()); 66 | ok = true; 67 | check('setTime'); 68 | var test = new timezone_mock._Date(ts); 69 | orig = new timezone_mock._Date('2015-01-01'); 70 | mock = new Date('2015-01-01'); 71 | orig.setFullYear(test.getUTCFullYear()); 72 | mock.setFullYear(test.getUTCFullYear()); 73 | orig.setMinutes(test.getUTCMinutes()); 74 | mock.setMinutes(test.getUTCMinutes()); 75 | orig.setHours(test.getUTCHours()); 76 | mock.setHours(test.getUTCHours()); 77 | check('setFullYear/Minutes/Hours'); 78 | orig.setDate(test.getUTCDate()); 79 | mock.setDate(test.getUTCDate()); 80 | check('setDate'); 81 | var str = test.getUTCFullYear() + '-' + pad2(test.getUTCMonth() + 1) + '-' + pad2(test.getUTCDate()) + ' ' + 82 | pad2(test.getUTCHours()) + ':' + pad2(test.getUTCMinutes()) + ':' + pad2(test.getUTCSeconds()); 83 | orig = new timezone_mock._Date(str); 84 | mock = new Date(str); 85 | check('constructor ' + str); 86 | if (was_ok !== ok) { 87 | console.log((ok ? 'OK ' : 'NOT OK') + ' - ' + ts + ' (' + (ts - last) + ') ' + orig.toISOString() + 88 | ' (' + orig.toLocaleString() + ')'); 89 | last = ts; 90 | was_ok = ok; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /timezone-mock.sublime-project: -------------------------------------------------------------------------------- 1 | //json5 2 | { 3 | "folders": 4 | [ 5 | { 6 | "folder_exclude_patterns": 7 | [ 8 | "node_modules" 9 | ], 10 | "file_exclude_patterns": [], 11 | "path": "." 12 | }, 13 | ], 14 | "build_systems": 15 | [ 16 | { 17 | "name": "Run Example", 18 | "file_regex": "^(?: at [^(]+\\()?([^ \n\r]+)\\:(\\d+)(?:\\:(\\d+)\\))?$", 19 | "cmd": ["node", "example.js"] 20 | } 21 | ] 22 | } 23 | --------------------------------------------------------------------------------