├── .eslintignore ├── .eslintrc.json ├── .flowconfig ├── .gitignore ├── .release-it.json ├── README.md ├── __fixtures__ ├── existing-file │ ├── code.js │ └── output.js ├── existing-module │ ├── code.js │ └── output.js ├── expression │ ├── code.js │ └── output.js ├── node-builtin │ ├── code.js │ └── output.js ├── non-existing-file │ ├── code.js │ └── output.js ├── non-existing-module │ ├── code.js │ └── output.js └── template-literal │ ├── code.js │ └── output.js ├── __tests__ └── index.js ├── flow-typed └── npm │ └── jest_v23.x.x.js ├── index.js ├── package.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /coverage/ 3 | /__fixtures__/ 4 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "satya164", 3 | 4 | "env": { 5 | "node": true 6 | }, 7 | 8 | "rules": { 9 | "import/no-commonjs": 0 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | [include] 4 | 5 | [libs] 6 | 7 | [lints] 8 | 9 | [options] 10 | 11 | [strict] 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Node ### 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (http://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | jspm_packages/ 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | -------------------------------------------------------------------------------- /.release-it.json: -------------------------------------------------------------------------------- 1 | { 2 | "increment": "conventional:angular", 3 | "changelogCommand": "conventional-changelog -p angular | tail -n +3", 4 | "safeBump": false, 5 | "src": { 6 | "commitMessage": "chore: release %s", 7 | "tagName": "v%s" 8 | }, 9 | "npm": { 10 | "publish": true 11 | }, 12 | "github": { 13 | "release": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-optional-require 2 | 3 | Babel plugin to optionaly require modules. Useful with a bundler like [Metro](https://github.com/facebook/metro) which doesn't support optional `require` statements. 4 | 5 | This is primarily useful if you want add an dependency to your library that's optional and you want users to be able to opt-out of it to save bundle size. You can also use it in apps to load configuration files only if they exist. 6 | 7 | ## Usage 8 | 9 | Install the plugin: 10 | 11 | ```sh 12 | yarn add --dev babel-plugin-optional-require 13 | ``` 14 | 15 | Then include it in your `.babelrc`: 16 | 17 | ```json 18 | { 19 | "plugins": [ 20 | "optional-require" 21 | ] 22 | } 23 | ``` 24 | 25 | ## Options 26 | 27 | - `builtins: boolean`: Whether to resolve Node builtins. Default: `false`. 28 | - `blacklist: string[]`: List of modules we assume to be unavailable without resolving. Default: `[]`. 29 | - `whitelist: string[]`: List of modules we assume to be available without resolving. Default: `[]`. 30 | 31 | ## Example 32 | 33 | To optionally `require` a module, you need to wrap it in `try/catch`: 34 | 35 | ```js 36 | let a; 37 | 38 | try { 39 | a = require('optional-module'); 40 | } catch (e) { 41 | // Handle failure from loading the module 42 | } 43 | ``` 44 | 45 | If the module `optional-module` doesn't exist, the `require` call will be replaced with an IIFE that throws an error, so you can catch it and handle it at runtime. Otherwise, the code is left unchanged. 46 | -------------------------------------------------------------------------------- /__fixtures__/existing-file/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('./output'); 5 | } catch(e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/existing-file/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('./output'); 5 | } catch (e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/existing-module/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('resolve-from'); 5 | } catch(e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/existing-module/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('resolve-from'); 5 | } catch (e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/expression/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('some' + 'thing'); 5 | } catch (e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/expression/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = function () { 5 | throw new Error("Cannot find module 'something'"); 6 | }(); 7 | } catch (e) { 8 | a = require('something-else'); 9 | } 10 | -------------------------------------------------------------------------------- /__fixtures__/node-builtin/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('fs'); 5 | } catch (e) { 6 | a = require('path'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/node-builtin/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = function () { 5 | throw new Error("Cannot resolve builtin module 'fs'"); 6 | }(); 7 | } catch (e) { 8 | a = require('path'); 9 | } 10 | -------------------------------------------------------------------------------- /__fixtures__/non-existing-file/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('./some-file'); 5 | } catch(e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/non-existing-file/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = function () { 5 | throw new Error("Cannot find module './some-file'"); 6 | }(); 7 | } catch (e) { 8 | a = require('something-else'); 9 | } 10 | -------------------------------------------------------------------------------- /__fixtures__/non-existing-module/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require('non-existing'); 5 | } catch(e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/non-existing-module/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = function () { 5 | throw new Error("Cannot find module 'non-existing'"); 6 | }(); 7 | } catch (e) { 8 | a = require('something-else'); 9 | } 10 | -------------------------------------------------------------------------------- /__fixtures__/template-literal/code.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = require(`non-existing`); 5 | } catch (e) { 6 | a = require('something-else'); 7 | } 8 | -------------------------------------------------------------------------------- /__fixtures__/template-literal/output.js: -------------------------------------------------------------------------------- 1 | let a; 2 | 3 | try { 4 | a = function () { 5 | throw new Error("Cannot find module 'non-existing'"); 6 | }(); 7 | } catch (e) { 8 | a = require('something-else'); 9 | } 10 | -------------------------------------------------------------------------------- /__tests__/index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const path = require('path'); 4 | const { create } = require('babel-test'); 5 | const { toMatchFile } = require('jest-file-snapshot'); 6 | 7 | expect.extend({ toMatchFile }); 8 | 9 | const { fixtures } = create({ 10 | plugins: [require.resolve('../index')], 11 | }); 12 | 13 | fixtures('optional-require', path.join(__dirname, '..', '__fixtures__')); 14 | -------------------------------------------------------------------------------- /flow-typed/npm/jest_v23.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 78c200acffbcc16bba9478f5396c3a00 2 | // flow-typed version: b2980740dd/jest_v23.x.x/flow_>=v0.39.x 3 | 4 | type JestMockFn, TReturn> = { 5 | (...args: TArguments): TReturn, 6 | /** 7 | * An object for introspecting mock calls 8 | */ 9 | mock: { 10 | /** 11 | * An array that represents all calls that have been made into this mock 12 | * function. Each call is represented by an array of arguments that were 13 | * passed during the call. 14 | */ 15 | calls: Array, 16 | /** 17 | * An array that contains all the object instances that have been 18 | * instantiated from this mock function. 19 | */ 20 | instances: Array, 21 | /** 22 | * An array that contains all the object results that have been 23 | * returned by this mock function call 24 | */ 25 | results: Array<{ isThrow: boolean, value: TReturn }> 26 | }, 27 | /** 28 | * Resets all information stored in the mockFn.mock.calls and 29 | * mockFn.mock.instances arrays. Often this is useful when you want to clean 30 | * up a mock's usage data between two assertions. 31 | */ 32 | mockClear(): void, 33 | /** 34 | * Resets all information stored in the mock. This is useful when you want to 35 | * completely restore a mock back to its initial state. 36 | */ 37 | mockReset(): void, 38 | /** 39 | * Removes the mock and restores the initial implementation. This is useful 40 | * when you want to mock functions in certain test cases and restore the 41 | * original implementation in others. Beware that mockFn.mockRestore only 42 | * works when mock was created with jest.spyOn. Thus you have to take care of 43 | * restoration yourself when manually assigning jest.fn(). 44 | */ 45 | mockRestore(): void, 46 | /** 47 | * Accepts a function that should be used as the implementation of the mock. 48 | * The mock itself will still record all calls that go into and instances 49 | * that come from itself -- the only difference is that the implementation 50 | * will also be executed when the mock is called. 51 | */ 52 | mockImplementation( 53 | fn: (...args: TArguments) => TReturn 54 | ): JestMockFn, 55 | /** 56 | * Accepts a function that will be used as an implementation of the mock for 57 | * one call to the mocked function. Can be chained so that multiple function 58 | * calls produce different results. 59 | */ 60 | mockImplementationOnce( 61 | fn: (...args: TArguments) => TReturn 62 | ): JestMockFn, 63 | /** 64 | * Accepts a string to use in test result output in place of "jest.fn()" to 65 | * indicate which mock function is being referenced. 66 | */ 67 | mockName(name: string): JestMockFn, 68 | /** 69 | * Just a simple sugar function for returning `this` 70 | */ 71 | mockReturnThis(): void, 72 | /** 73 | * Accepts a value that will be returned whenever the mock function is called. 74 | */ 75 | mockReturnValue(value: TReturn): JestMockFn, 76 | /** 77 | * Sugar for only returning a value once inside your mock 78 | */ 79 | mockReturnValueOnce(value: TReturn): JestMockFn, 80 | /** 81 | * Sugar for jest.fn().mockImplementation(() => Promise.resolve(value)) 82 | */ 83 | mockResolvedValue(value: TReturn): JestMockFn>, 84 | /** 85 | * Sugar for jest.fn().mockImplementationOnce(() => Promise.resolve(value)) 86 | */ 87 | mockResolvedValueOnce(value: TReturn): JestMockFn>, 88 | /** 89 | * Sugar for jest.fn().mockImplementation(() => Promise.reject(value)) 90 | */ 91 | mockRejectedValue(value: TReturn): JestMockFn>, 92 | /** 93 | * Sugar for jest.fn().mockImplementationOnce(() => Promise.reject(value)) 94 | */ 95 | mockRejectedValueOnce(value: TReturn): JestMockFn> 96 | }; 97 | 98 | type JestAsymmetricEqualityType = { 99 | /** 100 | * A custom Jasmine equality tester 101 | */ 102 | asymmetricMatch(value: mixed): boolean 103 | }; 104 | 105 | type JestCallsType = { 106 | allArgs(): mixed, 107 | all(): mixed, 108 | any(): boolean, 109 | count(): number, 110 | first(): mixed, 111 | mostRecent(): mixed, 112 | reset(): void 113 | }; 114 | 115 | type JestClockType = { 116 | install(): void, 117 | mockDate(date: Date): void, 118 | tick(milliseconds?: number): void, 119 | uninstall(): void 120 | }; 121 | 122 | type JestMatcherResult = { 123 | message?: string | (() => string), 124 | pass: boolean 125 | }; 126 | 127 | type JestMatcher = (actual: any, expected: any) => 128 | | JestMatcherResult 129 | | Promise; 130 | 131 | type JestPromiseType = { 132 | /** 133 | * Use rejects to unwrap the reason of a rejected promise so any other 134 | * matcher can be chained. If the promise is fulfilled the assertion fails. 135 | */ 136 | rejects: JestExpectType, 137 | /** 138 | * Use resolves to unwrap the value of a fulfilled promise so any other 139 | * matcher can be chained. If the promise is rejected the assertion fails. 140 | */ 141 | resolves: JestExpectType 142 | }; 143 | 144 | /** 145 | * Jest allows functions and classes to be used as test names in test() and 146 | * describe() 147 | */ 148 | type JestTestName = string | Function; 149 | 150 | /** 151 | * Plugin: jest-styled-components 152 | */ 153 | 154 | type JestStyledComponentsMatcherValue = 155 | | string 156 | | JestAsymmetricEqualityType 157 | | RegExp 158 | | typeof undefined; 159 | 160 | type JestStyledComponentsMatcherOptions = { 161 | media?: string; 162 | modifier?: string; 163 | supports?: string; 164 | } 165 | 166 | type JestStyledComponentsMatchersType = { 167 | toHaveStyleRule( 168 | property: string, 169 | value: JestStyledComponentsMatcherValue, 170 | options?: JestStyledComponentsMatcherOptions 171 | ): void, 172 | }; 173 | 174 | /** 175 | * Plugin: jest-enzyme 176 | */ 177 | type EnzymeMatchersType = { 178 | // 5.x 179 | toBeEmpty(): void, 180 | toBePresent(): void, 181 | // 6.x 182 | toBeChecked(): void, 183 | toBeDisabled(): void, 184 | toBeEmptyRender(): void, 185 | toContainMatchingElement(selector: string): void; 186 | toContainMatchingElements(n: number, selector: string): void; 187 | toContainExactlyOneMatchingElement(selector: string): void; 188 | toContainReact(element: React$Element): void, 189 | toExist(): void, 190 | toHaveClassName(className: string): void, 191 | toHaveHTML(html: string): void, 192 | toHaveProp: ((propKey: string, propValue?: any) => void) & ((props: Object) => void), 193 | toHaveRef(refName: string): void, 194 | toHaveState: ((stateKey: string, stateValue?: any) => void) & ((state: Object) => void), 195 | toHaveStyle: ((styleKey: string, styleValue?: any) => void) & ((style: Object) => void), 196 | toHaveTagName(tagName: string): void, 197 | toHaveText(text: string): void, 198 | toHaveValue(value: any): void, 199 | toIncludeText(text: string): void, 200 | toMatchElement( 201 | element: React$Element, 202 | options?: {| ignoreProps?: boolean, verbose?: boolean |}, 203 | ): void, 204 | toMatchSelector(selector: string): void, 205 | // 7.x 206 | toHaveDisplayName(name: string): void, 207 | }; 208 | 209 | // DOM testing library extensions https://github.com/kentcdodds/dom-testing-library#custom-jest-matchers 210 | type DomTestingLibraryType = { 211 | toBeDisabled(): void, 212 | toBeEmpty(): void, 213 | toBeInTheDocument(): void, 214 | toBeVisible(): void, 215 | toContainElement(element: HTMLElement | null): void, 216 | toContainHTML(htmlText: string): void, 217 | toHaveAttribute(name: string, expectedValue?: string): void, 218 | toHaveClass(...classNames: string[]): void, 219 | toHaveFocus(): void, 220 | toHaveFormValues(expectedValues: { [name: string]: any }): void, 221 | toHaveStyle(css: string): void, 222 | toHaveTextContent(content: string | RegExp, options?: { normalizeWhitespace: boolean }): void, 223 | toBeInTheDOM(): void, 224 | }; 225 | 226 | // Jest JQuery Matchers: https://github.com/unindented/custom-jquery-matchers 227 | type JestJQueryMatchersType = { 228 | toExist(): void, 229 | toHaveLength(len: number): void, 230 | toHaveId(id: string): void, 231 | toHaveClass(className: string): void, 232 | toHaveTag(tag: string): void, 233 | toHaveAttr(key: string, val?: any): void, 234 | toHaveProp(key: string, val?: any): void, 235 | toHaveText(text: string | RegExp): void, 236 | toHaveData(key: string, val?: any): void, 237 | toHaveValue(val: any): void, 238 | toHaveCss(css: {[key: string]: any}): void, 239 | toBeChecked(): void, 240 | toBeDisabled(): void, 241 | toBeEmpty(): void, 242 | toBeHidden(): void, 243 | toBeSelected(): void, 244 | toBeVisible(): void, 245 | toBeFocused(): void, 246 | toBeInDom(): void, 247 | toBeMatchedBy(sel: string): void, 248 | toHaveDescendant(sel: string): void, 249 | toHaveDescendantWithText(sel: string, text: string | RegExp): void 250 | }; 251 | 252 | 253 | // Jest Extended Matchers: https://github.com/jest-community/jest-extended 254 | type JestExtendedMatchersType = { 255 | /** 256 | * Note: Currently unimplemented 257 | * Passing assertion 258 | * 259 | * @param {String} message 260 | */ 261 | // pass(message: string): void; 262 | 263 | /** 264 | * Note: Currently unimplemented 265 | * Failing assertion 266 | * 267 | * @param {String} message 268 | */ 269 | // fail(message: string): void; 270 | 271 | /** 272 | * Use .toBeEmpty when checking if a String '', Array [] or Object {} is empty. 273 | */ 274 | toBeEmpty(): void; 275 | 276 | /** 277 | * Use .toBeOneOf when checking if a value is a member of a given Array. 278 | * @param {Array.<*>} members 279 | */ 280 | toBeOneOf(members: any[]): void; 281 | 282 | /** 283 | * Use `.toBeNil` when checking a value is `null` or `undefined`. 284 | */ 285 | toBeNil(): void; 286 | 287 | /** 288 | * Use `.toSatisfy` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean`. 289 | * @param {Function} predicate 290 | */ 291 | toSatisfy(predicate: (n: any) => boolean): void; 292 | 293 | /** 294 | * Use `.toBeArray` when checking if a value is an `Array`. 295 | */ 296 | toBeArray(): void; 297 | 298 | /** 299 | * Use `.toBeArrayOfSize` when checking if a value is an `Array` of size x. 300 | * @param {Number} x 301 | */ 302 | toBeArrayOfSize(x: number): void; 303 | 304 | /** 305 | * Use `.toIncludeAllMembers` when checking if an `Array` contains all of the same members of a given set. 306 | * @param {Array.<*>} members 307 | */ 308 | toIncludeAllMembers(members: any[]): void; 309 | 310 | /** 311 | * Use `.toIncludeAnyMembers` when checking if an `Array` contains any of the members of a given set. 312 | * @param {Array.<*>} members 313 | */ 314 | toIncludeAnyMembers(members: any[]): void; 315 | 316 | /** 317 | * Use `.toSatisfyAll` when you want to use a custom matcher by supplying a predicate function that returns a `Boolean` for all values in an array. 318 | * @param {Function} predicate 319 | */ 320 | toSatisfyAll(predicate: (n: any) => boolean): void; 321 | 322 | /** 323 | * Use `.toBeBoolean` when checking if a value is a `Boolean`. 324 | */ 325 | toBeBoolean(): void; 326 | 327 | /** 328 | * Use `.toBeTrue` when checking a value is equal (===) to `true`. 329 | */ 330 | toBeTrue(): void; 331 | 332 | /** 333 | * Use `.toBeFalse` when checking a value is equal (===) to `false`. 334 | */ 335 | toBeFalse(): void; 336 | 337 | /** 338 | * Use .toBeDate when checking if a value is a Date. 339 | */ 340 | toBeDate(): void; 341 | 342 | /** 343 | * Use `.toBeFunction` when checking if a value is a `Function`. 344 | */ 345 | toBeFunction(): void; 346 | 347 | /** 348 | * Use `.toHaveBeenCalledBefore` when checking if a `Mock` was called before another `Mock`. 349 | * 350 | * Note: Required Jest version >22 351 | * Note: Your mock functions will have to be asynchronous to cause the timestamps inside of Jest to occur in a differentJS event loop, otherwise the mock timestamps will all be the same 352 | * 353 | * @param {Mock} mock 354 | */ 355 | toHaveBeenCalledBefore(mock: JestMockFn): void; 356 | 357 | /** 358 | * Use `.toBeNumber` when checking if a value is a `Number`. 359 | */ 360 | toBeNumber(): void; 361 | 362 | /** 363 | * Use `.toBeNaN` when checking a value is `NaN`. 364 | */ 365 | toBeNaN(): void; 366 | 367 | /** 368 | * Use `.toBeFinite` when checking if a value is a `Number`, not `NaN` or `Infinity`. 369 | */ 370 | toBeFinite(): void; 371 | 372 | /** 373 | * Use `.toBePositive` when checking if a value is a positive `Number`. 374 | */ 375 | toBePositive(): void; 376 | 377 | /** 378 | * Use `.toBeNegative` when checking if a value is a negative `Number`. 379 | */ 380 | toBeNegative(): void; 381 | 382 | /** 383 | * Use `.toBeEven` when checking if a value is an even `Number`. 384 | */ 385 | toBeEven(): void; 386 | 387 | /** 388 | * Use `.toBeOdd` when checking if a value is an odd `Number`. 389 | */ 390 | toBeOdd(): void; 391 | 392 | /** 393 | * Use `.toBeWithin` when checking if a number is in between the given bounds of: start (inclusive) and end (exclusive). 394 | * 395 | * @param {Number} start 396 | * @param {Number} end 397 | */ 398 | toBeWithin(start: number, end: number): void; 399 | 400 | /** 401 | * Use `.toBeObject` when checking if a value is an `Object`. 402 | */ 403 | toBeObject(): void; 404 | 405 | /** 406 | * Use `.toContainKey` when checking if an object contains the provided key. 407 | * 408 | * @param {String} key 409 | */ 410 | toContainKey(key: string): void; 411 | 412 | /** 413 | * Use `.toContainKeys` when checking if an object has all of the provided keys. 414 | * 415 | * @param {Array.} keys 416 | */ 417 | toContainKeys(keys: string[]): void; 418 | 419 | /** 420 | * Use `.toContainAllKeys` when checking if an object only contains all of the provided keys. 421 | * 422 | * @param {Array.} keys 423 | */ 424 | toContainAllKeys(keys: string[]): void; 425 | 426 | /** 427 | * Use `.toContainAnyKeys` when checking if an object contains at least one of the provided keys. 428 | * 429 | * @param {Array.} keys 430 | */ 431 | toContainAnyKeys(keys: string[]): void; 432 | 433 | /** 434 | * Use `.toContainValue` when checking if an object contains the provided value. 435 | * 436 | * @param {*} value 437 | */ 438 | toContainValue(value: any): void; 439 | 440 | /** 441 | * Use `.toContainValues` when checking if an object contains all of the provided values. 442 | * 443 | * @param {Array.<*>} values 444 | */ 445 | toContainValues(values: any[]): void; 446 | 447 | /** 448 | * Use `.toContainAllValues` when checking if an object only contains all of the provided values. 449 | * 450 | * @param {Array.<*>} values 451 | */ 452 | toContainAllValues(values: any[]): void; 453 | 454 | /** 455 | * Use `.toContainAnyValues` when checking if an object contains at least one of the provided values. 456 | * 457 | * @param {Array.<*>} values 458 | */ 459 | toContainAnyValues(values: any[]): void; 460 | 461 | /** 462 | * Use `.toContainEntry` when checking if an object contains the provided entry. 463 | * 464 | * @param {Array.} entry 465 | */ 466 | toContainEntry(entry: [string, string]): void; 467 | 468 | /** 469 | * Use `.toContainEntries` when checking if an object contains all of the provided entries. 470 | * 471 | * @param {Array.>} entries 472 | */ 473 | toContainEntries(entries: [string, string][]): void; 474 | 475 | /** 476 | * Use `.toContainAllEntries` when checking if an object only contains all of the provided entries. 477 | * 478 | * @param {Array.>} entries 479 | */ 480 | toContainAllEntries(entries: [string, string][]): void; 481 | 482 | /** 483 | * Use `.toContainAnyEntries` when checking if an object contains at least one of the provided entries. 484 | * 485 | * @param {Array.>} entries 486 | */ 487 | toContainAnyEntries(entries: [string, string][]): void; 488 | 489 | /** 490 | * Use `.toBeExtensible` when checking if an object is extensible. 491 | */ 492 | toBeExtensible(): void; 493 | 494 | /** 495 | * Use `.toBeFrozen` when checking if an object is frozen. 496 | */ 497 | toBeFrozen(): void; 498 | 499 | /** 500 | * Use `.toBeSealed` when checking if an object is sealed. 501 | */ 502 | toBeSealed(): void; 503 | 504 | /** 505 | * Use `.toBeString` when checking if a value is a `String`. 506 | */ 507 | toBeString(): void; 508 | 509 | /** 510 | * Use `.toEqualCaseInsensitive` when checking if a string is equal (===) to another ignoring the casing of both strings. 511 | * 512 | * @param {String} string 513 | */ 514 | toEqualCaseInsensitive(string: string): void; 515 | 516 | /** 517 | * Use `.toStartWith` when checking if a `String` starts with a given `String` prefix. 518 | * 519 | * @param {String} prefix 520 | */ 521 | toStartWith(prefix: string): void; 522 | 523 | /** 524 | * Use `.toEndWith` when checking if a `String` ends with a given `String` suffix. 525 | * 526 | * @param {String} suffix 527 | */ 528 | toEndWith(suffix: string): void; 529 | 530 | /** 531 | * Use `.toInclude` when checking if a `String` includes the given `String` substring. 532 | * 533 | * @param {String} substring 534 | */ 535 | toInclude(substring: string): void; 536 | 537 | /** 538 | * Use `.toIncludeRepeated` when checking if a `String` includes the given `String` substring the correct number of times. 539 | * 540 | * @param {String} substring 541 | * @param {Number} times 542 | */ 543 | toIncludeRepeated(substring: string, times: number): void; 544 | 545 | /** 546 | * Use `.toIncludeMultiple` when checking if a `String` includes all of the given substrings. 547 | * 548 | * @param {Array.} substring 549 | */ 550 | toIncludeMultiple(substring: string[]): void; 551 | }; 552 | 553 | interface JestExpectType { 554 | not: 555 | & JestExpectType 556 | & EnzymeMatchersType 557 | & DomTestingLibraryType 558 | & JestJQueryMatchersType 559 | & JestStyledComponentsMatchersType 560 | & JestExtendedMatchersType, 561 | /** 562 | * If you have a mock function, you can use .lastCalledWith to test what 563 | * arguments it was last called with. 564 | */ 565 | lastCalledWith(...args: Array): void, 566 | /** 567 | * toBe just checks that a value is what you expect. It uses === to check 568 | * strict equality. 569 | */ 570 | toBe(value: any): void, 571 | /** 572 | * Use .toBeCalledWith to ensure that a mock function was called with 573 | * specific arguments. 574 | */ 575 | toBeCalledWith(...args: Array): void, 576 | /** 577 | * Using exact equality with floating point numbers is a bad idea. Rounding 578 | * means that intuitive things fail. 579 | */ 580 | toBeCloseTo(num: number, delta: any): void, 581 | /** 582 | * Use .toBeDefined to check that a variable is not undefined. 583 | */ 584 | toBeDefined(): void, 585 | /** 586 | * Use .toBeFalsy when you don't care what a value is, you just want to 587 | * ensure a value is false in a boolean context. 588 | */ 589 | toBeFalsy(): void, 590 | /** 591 | * To compare floating point numbers, you can use toBeGreaterThan. 592 | */ 593 | toBeGreaterThan(number: number): void, 594 | /** 595 | * To compare floating point numbers, you can use toBeGreaterThanOrEqual. 596 | */ 597 | toBeGreaterThanOrEqual(number: number): void, 598 | /** 599 | * To compare floating point numbers, you can use toBeLessThan. 600 | */ 601 | toBeLessThan(number: number): void, 602 | /** 603 | * To compare floating point numbers, you can use toBeLessThanOrEqual. 604 | */ 605 | toBeLessThanOrEqual(number: number): void, 606 | /** 607 | * Use .toBeInstanceOf(Class) to check that an object is an instance of a 608 | * class. 609 | */ 610 | toBeInstanceOf(cls: Class<*>): void, 611 | /** 612 | * .toBeNull() is the same as .toBe(null) but the error messages are a bit 613 | * nicer. 614 | */ 615 | toBeNull(): void, 616 | /** 617 | * Use .toBeTruthy when you don't care what a value is, you just want to 618 | * ensure a value is true in a boolean context. 619 | */ 620 | toBeTruthy(): void, 621 | /** 622 | * Use .toBeUndefined to check that a variable is undefined. 623 | */ 624 | toBeUndefined(): void, 625 | /** 626 | * Use .toContain when you want to check that an item is in a list. For 627 | * testing the items in the list, this uses ===, a strict equality check. 628 | */ 629 | toContain(item: any): void, 630 | /** 631 | * Use .toContainEqual when you want to check that an item is in a list. For 632 | * testing the items in the list, this matcher recursively checks the 633 | * equality of all fields, rather than checking for object identity. 634 | */ 635 | toContainEqual(item: any): void, 636 | /** 637 | * Use .toEqual when you want to check that two objects have the same value. 638 | * This matcher recursively checks the equality of all fields, rather than 639 | * checking for object identity. 640 | */ 641 | toEqual(value: any): void, 642 | /** 643 | * Use .toHaveBeenCalled to ensure that a mock function got called. 644 | */ 645 | toHaveBeenCalled(): void, 646 | toBeCalled(): void; 647 | /** 648 | * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact 649 | * number of times. 650 | */ 651 | toHaveBeenCalledTimes(number: number): void, 652 | toBeCalledTimes(number: number): void; 653 | /** 654 | * 655 | */ 656 | toHaveBeenNthCalledWith(nthCall: number, ...args: Array): void; 657 | nthCalledWith(nthCall: number, ...args: Array): void; 658 | /** 659 | * 660 | */ 661 | toHaveReturned(): void; 662 | toReturn(): void; 663 | /** 664 | * 665 | */ 666 | toHaveReturnedTimes(number: number): void; 667 | toReturnTimes(number: number): void; 668 | /** 669 | * 670 | */ 671 | toHaveReturnedWith(value: any): void; 672 | toReturnWith(value: any): void; 673 | /** 674 | * 675 | */ 676 | toHaveLastReturnedWith(value: any): void; 677 | lastReturnedWith(value: any): void; 678 | /** 679 | * 680 | */ 681 | toHaveNthReturnedWith(nthCall: number, value: any): void; 682 | nthReturnedWith(nthCall: number, value: any): void; 683 | /** 684 | * Use .toHaveBeenCalledWith to ensure that a mock function was called with 685 | * specific arguments. 686 | */ 687 | toHaveBeenCalledWith(...args: Array): void, 688 | toBeCalledWith(...args: Array): void, 689 | /** 690 | * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called 691 | * with specific arguments. 692 | */ 693 | toHaveBeenLastCalledWith(...args: Array): void, 694 | lastCalledWith(...args: Array): void, 695 | /** 696 | * Check that an object has a .length property and it is set to a certain 697 | * numeric value. 698 | */ 699 | toHaveLength(number: number): void, 700 | /** 701 | * 702 | */ 703 | toHaveProperty(propPath: string, value?: any): void, 704 | /** 705 | * Use .toMatch to check that a string matches a regular expression or string. 706 | */ 707 | toMatch(regexpOrString: RegExp | string): void, 708 | /** 709 | * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. 710 | */ 711 | toMatchObject(object: Object | Array): void, 712 | /** 713 | * Use .toStrictEqual to check that a javascript object matches a subset of the properties of an object. 714 | */ 715 | toStrictEqual(value: any): void, 716 | /** 717 | * This ensures that an Object matches the most recent snapshot. 718 | */ 719 | toMatchSnapshot(propertyMatchers?: any, name?: string): void, 720 | /** 721 | * This ensures that an Object matches the most recent snapshot. 722 | */ 723 | toMatchSnapshot(name: string): void, 724 | 725 | toMatchInlineSnapshot(snapshot?: string): void, 726 | toMatchInlineSnapshot(propertyMatchers?: any, snapshot?: string): void, 727 | /** 728 | * Use .toThrow to test that a function throws when it is called. 729 | * If you want to test that a specific error gets thrown, you can provide an 730 | * argument to toThrow. The argument can be a string for the error message, 731 | * a class for the error, or a regex that should match the error. 732 | * 733 | * Alias: .toThrowError 734 | */ 735 | toThrow(message?: string | Error | Class | RegExp): void, 736 | toThrowError(message?: string | Error | Class | RegExp): void, 737 | /** 738 | * Use .toThrowErrorMatchingSnapshot to test that a function throws a error 739 | * matching the most recent snapshot when it is called. 740 | */ 741 | toThrowErrorMatchingSnapshot(): void, 742 | toThrowErrorMatchingInlineSnapshot(snapshot?: string): void, 743 | } 744 | 745 | type JestObjectType = { 746 | /** 747 | * Disables automatic mocking in the module loader. 748 | * 749 | * After this method is called, all `require()`s will return the real 750 | * versions of each module (rather than a mocked version). 751 | */ 752 | disableAutomock(): JestObjectType, 753 | /** 754 | * An un-hoisted version of disableAutomock 755 | */ 756 | autoMockOff(): JestObjectType, 757 | /** 758 | * Enables automatic mocking in the module loader. 759 | */ 760 | enableAutomock(): JestObjectType, 761 | /** 762 | * An un-hoisted version of enableAutomock 763 | */ 764 | autoMockOn(): JestObjectType, 765 | /** 766 | * Clears the mock.calls and mock.instances properties of all mocks. 767 | * Equivalent to calling .mockClear() on every mocked function. 768 | */ 769 | clearAllMocks(): JestObjectType, 770 | /** 771 | * Resets the state of all mocks. Equivalent to calling .mockReset() on every 772 | * mocked function. 773 | */ 774 | resetAllMocks(): JestObjectType, 775 | /** 776 | * Restores all mocks back to their original value. 777 | */ 778 | restoreAllMocks(): JestObjectType, 779 | /** 780 | * Removes any pending timers from the timer system. 781 | */ 782 | clearAllTimers(): void, 783 | /** 784 | * The same as `mock` but not moved to the top of the expectation by 785 | * babel-jest. 786 | */ 787 | doMock(moduleName: string, moduleFactory?: any): JestObjectType, 788 | /** 789 | * The same as `unmock` but not moved to the top of the expectation by 790 | * babel-jest. 791 | */ 792 | dontMock(moduleName: string): JestObjectType, 793 | /** 794 | * Returns a new, unused mock function. Optionally takes a mock 795 | * implementation. 796 | */ 797 | fn, TReturn>( 798 | implementation?: (...args: TArguments) => TReturn 799 | ): JestMockFn, 800 | /** 801 | * Determines if the given function is a mocked function. 802 | */ 803 | isMockFunction(fn: Function): boolean, 804 | /** 805 | * Given the name of a module, use the automatic mocking system to generate a 806 | * mocked version of the module for you. 807 | */ 808 | genMockFromModule(moduleName: string): any, 809 | /** 810 | * Mocks a module with an auto-mocked version when it is being required. 811 | * 812 | * The second argument can be used to specify an explicit module factory that 813 | * is being run instead of using Jest's automocking feature. 814 | * 815 | * The third argument can be used to create virtual mocks -- mocks of modules 816 | * that don't exist anywhere in the system. 817 | */ 818 | mock( 819 | moduleName: string, 820 | moduleFactory?: any, 821 | options?: Object 822 | ): JestObjectType, 823 | /** 824 | * Returns the actual module instead of a mock, bypassing all checks on 825 | * whether the module should receive a mock implementation or not. 826 | */ 827 | requireActual(moduleName: string): any, 828 | /** 829 | * Returns a mock module instead of the actual module, bypassing all checks 830 | * on whether the module should be required normally or not. 831 | */ 832 | requireMock(moduleName: string): any, 833 | /** 834 | * Resets the module registry - the cache of all required modules. This is 835 | * useful to isolate modules where local state might conflict between tests. 836 | */ 837 | resetModules(): JestObjectType, 838 | /** 839 | * Exhausts the micro-task queue (usually interfaced in node via 840 | * process.nextTick). 841 | */ 842 | runAllTicks(): void, 843 | /** 844 | * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), 845 | * setInterval(), and setImmediate()). 846 | */ 847 | runAllTimers(): void, 848 | /** 849 | * Exhausts all tasks queued by setImmediate(). 850 | */ 851 | runAllImmediates(): void, 852 | /** 853 | * Executes only the macro task queue (i.e. all tasks queued by setTimeout() 854 | * or setInterval() and setImmediate()). 855 | */ 856 | advanceTimersByTime(msToRun: number): void, 857 | /** 858 | * Executes only the macro task queue (i.e. all tasks queued by setTimeout() 859 | * or setInterval() and setImmediate()). 860 | * 861 | * Renamed to `advanceTimersByTime`. 862 | */ 863 | runTimersToTime(msToRun: number): void, 864 | /** 865 | * Executes only the macro-tasks that are currently pending (i.e., only the 866 | * tasks that have been queued by setTimeout() or setInterval() up to this 867 | * point) 868 | */ 869 | runOnlyPendingTimers(): void, 870 | /** 871 | * Explicitly supplies the mock object that the module system should return 872 | * for the specified module. Note: It is recommended to use jest.mock() 873 | * instead. 874 | */ 875 | setMock(moduleName: string, moduleExports: any): JestObjectType, 876 | /** 877 | * Indicates that the module system should never return a mocked version of 878 | * the specified module from require() (e.g. that it should always return the 879 | * real module). 880 | */ 881 | unmock(moduleName: string): JestObjectType, 882 | /** 883 | * Instructs Jest to use fake versions of the standard timer functions 884 | * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, 885 | * setImmediate and clearImmediate). 886 | */ 887 | useFakeTimers(): JestObjectType, 888 | /** 889 | * Instructs Jest to use the real versions of the standard timer functions. 890 | */ 891 | useRealTimers(): JestObjectType, 892 | /** 893 | * Creates a mock function similar to jest.fn but also tracks calls to 894 | * object[methodName]. 895 | */ 896 | spyOn(object: Object, methodName: string, accessType?: "get" | "set"): JestMockFn, 897 | /** 898 | * Set the default timeout interval for tests and before/after hooks in milliseconds. 899 | * Note: The default timeout interval is 5 seconds if this method is not called. 900 | */ 901 | setTimeout(timeout: number): JestObjectType 902 | }; 903 | 904 | type JestSpyType = { 905 | calls: JestCallsType 906 | }; 907 | 908 | /** Runs this function after every test inside this context */ 909 | declare function afterEach( 910 | fn: (done: () => void) => ?Promise, 911 | timeout?: number 912 | ): void; 913 | /** Runs this function before every test inside this context */ 914 | declare function beforeEach( 915 | fn: (done: () => void) => ?Promise, 916 | timeout?: number 917 | ): void; 918 | /** Runs this function after all tests have finished inside this context */ 919 | declare function afterAll( 920 | fn: (done: () => void) => ?Promise, 921 | timeout?: number 922 | ): void; 923 | /** Runs this function before any tests have started inside this context */ 924 | declare function beforeAll( 925 | fn: (done: () => void) => ?Promise, 926 | timeout?: number 927 | ): void; 928 | 929 | /** A context for grouping tests together */ 930 | declare var describe: { 931 | /** 932 | * Creates a block that groups together several related tests in one "test suite" 933 | */ 934 | (name: JestTestName, fn: () => void): void, 935 | 936 | /** 937 | * Only run this describe block 938 | */ 939 | only(name: JestTestName, fn: () => void): void, 940 | 941 | /** 942 | * Skip running this describe block 943 | */ 944 | skip(name: JestTestName, fn: () => void): void, 945 | 946 | /** 947 | * each runs this test against array of argument arrays per each run 948 | * 949 | * @param {table} table of Test 950 | */ 951 | each( 952 | ...table: Array | mixed> | [Array, string] 953 | ): ( 954 | name: JestTestName, 955 | fn?: (...args: Array) => ?Promise, 956 | timeout?: number 957 | ) => void, 958 | }; 959 | 960 | /** An individual test unit */ 961 | declare var it: { 962 | /** 963 | * An individual test unit 964 | * 965 | * @param {JestTestName} Name of Test 966 | * @param {Function} Test 967 | * @param {number} Timeout for the test, in milliseconds. 968 | */ 969 | ( 970 | name: JestTestName, 971 | fn?: (done: () => void) => ?Promise, 972 | timeout?: number 973 | ): void, 974 | 975 | /** 976 | * Only run this test 977 | * 978 | * @param {JestTestName} Name of Test 979 | * @param {Function} Test 980 | * @param {number} Timeout for the test, in milliseconds. 981 | */ 982 | only( 983 | name: JestTestName, 984 | fn?: (done: () => void) => ?Promise, 985 | timeout?: number 986 | ): { 987 | each( 988 | ...table: Array | mixed> | [Array, string] 989 | ): ( 990 | name: JestTestName, 991 | fn?: (...args: Array) => ?Promise, 992 | timeout?: number 993 | ) => void, 994 | }, 995 | 996 | /** 997 | * Skip running this test 998 | * 999 | * @param {JestTestName} Name of Test 1000 | * @param {Function} Test 1001 | * @param {number} Timeout for the test, in milliseconds. 1002 | */ 1003 | skip( 1004 | name: JestTestName, 1005 | fn?: (done: () => void) => ?Promise, 1006 | timeout?: number 1007 | ): void, 1008 | 1009 | /** 1010 | * Run the test concurrently 1011 | * 1012 | * @param {JestTestName} Name of Test 1013 | * @param {Function} Test 1014 | * @param {number} Timeout for the test, in milliseconds. 1015 | */ 1016 | concurrent( 1017 | name: JestTestName, 1018 | fn?: (done: () => void) => ?Promise, 1019 | timeout?: number 1020 | ): void, 1021 | 1022 | /** 1023 | * each runs this test against array of argument arrays per each run 1024 | * 1025 | * @param {table} table of Test 1026 | */ 1027 | each( 1028 | ...table: Array | mixed> | [Array, string] 1029 | ): ( 1030 | name: JestTestName, 1031 | fn?: (...args: Array) => ?Promise, 1032 | timeout?: number 1033 | ) => void, 1034 | }; 1035 | 1036 | declare function fit( 1037 | name: JestTestName, 1038 | fn: (done: () => void) => ?Promise, 1039 | timeout?: number 1040 | ): void; 1041 | /** An individual test unit */ 1042 | declare var test: typeof it; 1043 | /** A disabled group of tests */ 1044 | declare var xdescribe: typeof describe; 1045 | /** A focused group of tests */ 1046 | declare var fdescribe: typeof describe; 1047 | /** A disabled individual test */ 1048 | declare var xit: typeof it; 1049 | /** A disabled individual test */ 1050 | declare var xtest: typeof it; 1051 | 1052 | type JestPrettyFormatColors = { 1053 | comment: { close: string, open: string }, 1054 | content: { close: string, open: string }, 1055 | prop: { close: string, open: string }, 1056 | tag: { close: string, open: string }, 1057 | value: { close: string, open: string }, 1058 | }; 1059 | 1060 | type JestPrettyFormatIndent = string => string; 1061 | type JestPrettyFormatRefs = Array; 1062 | type JestPrettyFormatPrint = any => string; 1063 | type JestPrettyFormatStringOrNull = string | null; 1064 | 1065 | type JestPrettyFormatOptions = {| 1066 | callToJSON: boolean, 1067 | edgeSpacing: string, 1068 | escapeRegex: boolean, 1069 | highlight: boolean, 1070 | indent: number, 1071 | maxDepth: number, 1072 | min: boolean, 1073 | plugins: JestPrettyFormatPlugins, 1074 | printFunctionName: boolean, 1075 | spacing: string, 1076 | theme: {| 1077 | comment: string, 1078 | content: string, 1079 | prop: string, 1080 | tag: string, 1081 | value: string, 1082 | |}, 1083 | |}; 1084 | 1085 | type JestPrettyFormatPlugin = { 1086 | print: ( 1087 | val: any, 1088 | serialize: JestPrettyFormatPrint, 1089 | indent: JestPrettyFormatIndent, 1090 | opts: JestPrettyFormatOptions, 1091 | colors: JestPrettyFormatColors, 1092 | ) => string, 1093 | test: any => boolean, 1094 | }; 1095 | 1096 | type JestPrettyFormatPlugins = Array; 1097 | 1098 | /** The expect function is used every time you want to test a value */ 1099 | declare var expect: { 1100 | /** The object that you want to make assertions against */ 1101 | (value: any): 1102 | & JestExpectType 1103 | & JestPromiseType 1104 | & EnzymeMatchersType 1105 | & DomTestingLibraryType 1106 | & JestJQueryMatchersType 1107 | & JestStyledComponentsMatchersType 1108 | & JestExtendedMatchersType, 1109 | 1110 | /** Add additional Jasmine matchers to Jest's roster */ 1111 | extend(matchers: { [name: string]: JestMatcher }): void, 1112 | /** Add a module that formats application-specific data structures. */ 1113 | addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, 1114 | assertions(expectedAssertions: number): void, 1115 | hasAssertions(): void, 1116 | any(value: mixed): JestAsymmetricEqualityType, 1117 | anything(): any, 1118 | arrayContaining(value: Array): Array, 1119 | objectContaining(value: Object): Object, 1120 | /** Matches any received string that contains the exact expected string. */ 1121 | stringContaining(value: string): string, 1122 | stringMatching(value: string | RegExp): string, 1123 | not: { 1124 | arrayContaining: (value: $ReadOnlyArray) => Array, 1125 | objectContaining: (value: {}) => Object, 1126 | stringContaining: (value: string) => string, 1127 | stringMatching: (value: string | RegExp) => string, 1128 | }, 1129 | }; 1130 | 1131 | // TODO handle return type 1132 | // http://jasmine.github.io/2.4/introduction.html#section-Spies 1133 | declare function spyOn(value: mixed, method: string): Object; 1134 | 1135 | /** Holds all functions related to manipulating test runner */ 1136 | declare var jest: JestObjectType; 1137 | 1138 | /** 1139 | * The global Jasmine object, this is generally not exposed as the public API, 1140 | * using features inside here could break in later versions of Jest. 1141 | */ 1142 | declare var jasmine: { 1143 | DEFAULT_TIMEOUT_INTERVAL: number, 1144 | any(value: mixed): JestAsymmetricEqualityType, 1145 | anything(): any, 1146 | arrayContaining(value: Array): Array, 1147 | clock(): JestClockType, 1148 | createSpy(name: string): JestSpyType, 1149 | createSpyObj( 1150 | baseName: string, 1151 | methodNames: Array 1152 | ): { [methodName: string]: JestSpyType }, 1153 | objectContaining(value: Object): Object, 1154 | stringMatching(value: string): string 1155 | }; 1156 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | 3 | const dirname = require('path').dirname; 4 | const resolve = require('resolve-from'); 5 | const isBuiltin = require('is-builtin-module'); 6 | 7 | module.exports = function rewire(babel /*: any */) { 8 | const t = babel.types; 9 | 10 | return { 11 | visitor: { 12 | TryStatement(path /*: any */, state /*: any */) { 13 | path.get('block').traverse({ 14 | CallExpression(p) { 15 | if ( 16 | p.node.callee.name !== 'require' || 17 | p.node.arguments.length !== 1 18 | ) { 19 | return; 20 | } 21 | 22 | const { 23 | builtins = false, 24 | blacklist = [], 25 | whitelist = [], 26 | } = state.opts; 27 | 28 | const name = p.get('arguments')[0].evaluate().value; 29 | 30 | if (typeof name !== 'string') { 31 | return; 32 | } 33 | 34 | if (whitelist.includes(name)) { 35 | return; 36 | } 37 | 38 | const cwd = 39 | state.file && state.file.opts && state.file.opts.filename 40 | ? dirname(state.file.opts.filename) 41 | : process.cwd(); 42 | 43 | try { 44 | if (blacklist.includes(name)) { 45 | throw new Error(`Cannot find module '${name}'`); 46 | } 47 | 48 | if (builtins !== true && isBuiltin(name)) { 49 | throw new Error(`Cannot resolve builtin module '${name}'`); 50 | } else { 51 | resolve(cwd, name); 52 | } 53 | } catch (e) { 54 | p.replaceWith( 55 | t.throwStatement( 56 | t.newExpression(t.identifier('Error'), [ 57 | t.stringLiteral(e.message), 58 | ]) 59 | ) 60 | ); 61 | } 62 | }, 63 | }); 64 | }, 65 | }, 66 | }; 67 | }; 68 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-optional-require", 3 | "version": "0.3.1", 4 | "description": "Babel plugin to transpile object styles to template literal", 5 | "main": "index.js", 6 | "files": [ 7 | "index.js" 8 | ], 9 | "repository": "git@github.com:satya164/babel-plugin-optional-require.git", 10 | "author": "Satyajit Sahoo ", 11 | "license": "MIT", 12 | "keywords": [ 13 | "babel-plugin", 14 | "babel", 15 | "module", 16 | "require", 17 | "import" 18 | ], 19 | "scripts": { 20 | "lint": "eslint .", 21 | "flow": "flow", 22 | "test": "jest", 23 | "release": "release-it" 24 | }, 25 | "publishConfig": { 26 | "registry": "https://registry.npmjs.org/" 27 | }, 28 | "devDependencies": { 29 | "@babel/core": "^7.0.0", 30 | "babel-test": "^0.1.1", 31 | "conventional-changelog-cli": "^2.0.5", 32 | "dedent": "^0.7.0", 33 | "eslint": "^5.4.0", 34 | "eslint-config-satya164": "^2.0.1", 35 | "flow-bin": "^0.79.1", 36 | "jest": "^23.5.0", 37 | "jest-file-snapshot": "^0.3.2", 38 | "prettier": "^1.14.2", 39 | "release-it": "^7.6.1" 40 | }, 41 | "dependencies": { 42 | "is-builtin-module": "^2.0.0", 43 | "resolve-from": "^4.0.0" 44 | }, 45 | "jest": { 46 | "testEnvironment": "node", 47 | "watchPathIgnorePatterns": [ 48 | "__fixtures__\\/[^/]+\\/(output|error)\\.js" 49 | ] 50 | } 51 | } 52 | --------------------------------------------------------------------------------