code:
"use strict";

const promisify = require("util.promisify");
const gensync = require("../");

const TEST_ERROR = new Error("TEST_ERROR");

const DID_ERROR = new Error("DID_ERROR");

const doSuccess = gensync({
  sync: () => 42,
  async: () => Promise.resolve(42),
});

const doError = gensync({
  sync: () => {
    throw DID_ERROR;
  },
  async: () => Promise.reject(DID_ERROR),
});

function throwTestError() {
  throw TEST_ERROR;
}

async function expectResult(
  fn,
  arg,
  { error, value, expectSync = false, syncErrback = expectSync }
) {
  if (!expectSync) {
    expect(() => fn.sync(arg)).toThrow(TEST_ERROR);
  } else if (error) {
    expect(() => fn.sync(arg)).toThrow(error);
  } else {
    expect(fn.sync(arg)).toBe(value);
  }

  if (error) {
    await expect(fn.async(arg)).rejects.toBe(error);
  } else {
    await expect(fn.async(arg)).resolves.toBe(value);
  }

  await new Promise((resolve, reject) => {
    let sync = true;
    fn.errback(arg, (err, val) => {
      try {
        expect(err).toBe(error);
        expect(val).toBe(value);
        expect(sync).toBe(syncErrback);

        resolve();
      } catch (e) {
        reject(e);
      }
    });
    sync = false;
  });
}

describe("gensync({})", () => {
  describe("option validation", () => {
    test("disallow async and errback handler together", () => {
      try {
        gensync({
          sync: throwTestError,
          async: throwTestError,
          errback: throwTestError,
        });

        throwTestError();
      } catch (err) {
        expect(err.message).toMatch(
          /Expected one of either opts.async or opts.errback, but got _both_\./
        );
        expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
      }
    });

    test("disallow missing sync handler", () => {
      try {
        gensync({
          async: throwTestError,
        });

        throwTestError();
      } catch (err) {
        expect(err.message).toMatch(/Expected opts.sync to be a function./);
        expect(err.code).toBe("GENSYNC_OPTIONS_ERROR");
      }
    });

    test("errback callback required", () => {
      const fn = gensync({
        sync: throwTestError,
        async: throwTestError,
      });

      try {
        fn.errback();

        throwTestError();
      } catch (err) {
        expect(err.message).toMatch(/function called without callback/);
        expect(err.code).toBe("GENSYNC_ERRBACK_NO_CALLBACK");
      }
    });
  });

  describe("generator function metadata", () => {
    test("automatic naming", () => {
      expect(
        gensync({
          sync: function readFileSync() {},
          async: () => {},
        }).name
      ).toBe("readFile");
      expect(
        gensync({
          sync: function readFile() {},
          async: () => {},
        }).name
      ).toBe("readFile");
      expect(
        gensync({
          sync: function readFileAsync() {},
          async: () => {},
        }).name
      ).toBe("readFileAsync");

      expect(
        gensync({
          sync: () => {},
          async: function readFileSync() {},
        }).name
      ).toBe("readFileSync");
      expect(
        gensync({
          sync: () => {},
          async: function readFile() {},
        }).name
      ).toBe("readFile");
      expect(
        gensync({
          sync: () => {},
          async: function readFileAsync() {},
        }).name
      ).toBe("readFile");

      expect(
        gensync({
          sync: () => {},
          errback: function readFileSync() {},
        }).name
      ).toBe("readFileSync");
      expect(
        gensync({
          sync: () => {},
          errback: function readFile() {},
        }).name
      ).toBe("readFile");
      expect(
        gensync({
          sync: () => {},
          errback: function readFileAsync() {},
        }).name
      ).toBe("readFileAsync");
    });

    test("explicit naming", () => {
      expect(
        gensync({
          name: "readFile",
          sync: () => {},
          async: () => {},
        }).name
      ).toBe("readFile");
    });

    test("default arity", () => {
      expect(
        gensync({
          sync: function(a, b, c, d, e, f, g) {
            throwTestError();
          },
          async: throwTestError,
        }).length
      ).toBe(7);
    });

    test("explicit arity", () => {
      expect(
        gensync({
          arity: 3,
          sync: throwTestError,
          async: throwTestError,
        }).length
      ).toBe(3);
    });
  });

  describe("'sync' handler", async () => {
    test("success", async () => {
      const fn = gensync({
        sync: (...args) => JSON.stringify(args),
      });

      await expectResult(fn, 42, { value: "[42]", expectSync: true });
    });

    test("failure", async () => {
      const fn = gensync({
        sync: (...args) => {
          throw JSON.stringify(args);
        },
      });

      await expectResult(fn, 42, { error: "[42]", expectSync: true });
    });
  });

  describe("'async' handler", async () => {
    test("success", async () => {
      const fn = gensync({
        sync: throwTestError,
        async: (...args) => Promise.resolve(JSON.stringify(args)),
      });

      await expectResult(fn, 42, { value: "[42]" });
    });

    test("failure", async () => {
      const fn = gensync({
        sync: throwTestError,
        async: (...args) => Promise.reject(JSON.stringify(args)),
      });

      await expectResult(fn, 42, { error: "[42]" });
    });
  });

  describe("'errback' sync handler", async () => {
    test("success", async () => {
      const fn = gensync({
        sync: throwTestError,
        errback: (...args) => args.pop()(null, JSON.stringify(args)),
      });

      await expectResult(fn, 42, { value: "[42]", syncErrback: true });
    });

    test("failure", async () => {
      const fn = gensync({
        sync: throwTestError,
        errback: (...args) => args.pop()(JSON.stringify(args)),
      });

      await expectResult(fn, 42, { error: "[42]", syncErrback: true });
    });
  });

  describe("'errback' async handler", async () => {
    test("success", async () => {
      const fn = gensync({
        sync: throwTestError,
        errback: (...args) =>
          process.nextTick(() => args.pop()(null, JSON.stringify(args))),
      });

      await expectResult(fn, 42, { value: "[42]" });
    });

    test("failure", async () => {
      const fn = gensync({
        sync: throwTestError,
        errback: (...args) =>
          process.nextTick(() => args.pop()(JSON.stringify(args))),
      });

      await expectResult(fn, 42, { error: "[42]" });
    });
  });
});

describe("gensync(function* () {})", () => {
  test("sync throw before body", async () => {
    const fn = gensync(function*(arg = throwTestError()) {});

    await expectResult(fn, undefined, {
      error: TEST_ERROR,
      syncErrback: true,
    });
  });

  test("sync throw inside body", async () => {
    const fn = gensync(function*() {
      throwTestError();
    });

    await expectResult(fn, undefined, {
      error: TEST_ERROR,
      syncErrback: true,
    });
  });

  test("async throw inside body", async () => {
    const fn = gensync(function*() {
      const val = yield* doSuccess();
      throwTestError();
    });

    await expectResult(fn, undefined, {
      error: TEST_ERROR,
    });
  });

  test("error inside body", async () => {
    const fn = gensync(function*() {
      yield* doError();
    });

    await expectResult(fn, undefined, {
      error: DID_ERROR,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("successful return value", async () => {
    const fn = gensync(function*() {
      const value = yield* doSuccess();

      expect(value).toBe(42);

      return 84;
    });

    await expectResult(fn, undefined, {
      value: 84,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("successful final value", async () => {
    const fn = gensync(function*() {
      return 42;
    });

    await expectResult(fn, undefined, {
      value: 42,
      expectSync: true,
    });
  });

  test("yield unexpected object", async () => {
    const fn = gensync(function*() {
      yield {};
    });

    try {
      await fn.async();

      throwTestError();
    } catch (err) {
      expect(err.message).toMatch(
        /Got unexpected yielded value in gensync generator/
      );
      expect(err.code).toBe("GENSYNC_EXPECTED_START");
    }
  });

  test("yield suspend yield", async () => {
    const fn = gensync(function*() {
      yield Symbol.for("gensync:v1:start");

      // Should be "yield*" for no error.
      yield {};
    });

    try {
      await fn.async();

      throwTestError();
    } catch (err) {
      expect(err.message).toMatch(/Expected GENSYNC_SUSPEND, got {}/);
      expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
    }
  });

  test("yield suspend return", async () => {
    const fn = gensync(function*() {
      yield Symbol.for("gensync:v1:start");

      // Should be "yield*" for no error.
      return {};
    });

    try {
      await fn.async();

      throwTestError();
    } catch (err) {
      expect(err.message).toMatch(/Unexpected generator completion/);
      expect(err.code).toBe("GENSYNC_EXPECTED_SUSPEND");
    }
  });
});

describe("gensync.all()", () => {
  test("success", async () => {
    const fn = gensync(function*() {
      const result = yield* gensync.all([doSuccess(), doSuccess()]);

      expect(result).toEqual([42, 42]);
    });

    await expectResult(fn, undefined, {
      value: undefined,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("error first", async () => {
    const fn = gensync(function*() {
      yield* gensync.all([doError(), doSuccess()]);
    });

    await expectResult(fn, undefined, {
      error: DID_ERROR,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("error last", async () => {
    const fn = gensync(function*() {
      yield* gensync.all([doSuccess(), doError()]);
    });

    await expectResult(fn, undefined, {
      error: DID_ERROR,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("empty list", async () => {
    const fn = gensync(function*() {
      yield* gensync.all([]);
    });

    await expectResult(fn, undefined, {
      value: undefined,
      expectSync: true,
      syncErrback: false,
    });
  });
});

describe("gensync.race()", () => {
  test("success", async () => {
    const fn = gensync(function*() {
      const result = yield* gensync.race([doSuccess(), doError()]);

      expect(result).toEqual(42);
    });

    await expectResult(fn, undefined, {
      value: undefined,
      expectSync: true,
      syncErrback: false,
    });
  });

  test("error", async () => {
    const fn = gensync(function*() {
      yield* gensync.race([doError(), doSuccess()]);
    });

    await expectResult(fn, undefined, {
      error: DID_ERROR,
      expectSync: true,
      syncErrback: false,
    });
  });
});


code:
# get-caller-file

[![Build Status](https://travis-ci.org/stefanpenner/get-caller-file.svg?branch=master)](https://travis-ci.org/stefanpenner/get-caller-file)
[![Build status](https://ci.appveyor.com/api/projects/status/ol2q94g1932cy14a/branch/master?svg=true)](https://ci.appveyor.com/project/embercli/get-caller-file/branch/master)

This is a utility, which allows a function to figure out from which file it was invoked. It does so by inspecting v8's stack trace at the time it is invoked.

Inspired by http://stackoverflow.com/questions/13227489

*note: this relies on Node/V8 specific APIs, as such other runtimes may not work*

## Installation

```bash
yarn add get-caller-file
```

## Usage

Given:

```js
// ./foo.js
const getCallerFile = require('get-caller-file');

module.exports = function() {
  return getCallerFile(); // figures out who called it
};
```

```js
// index.js
const foo = require('./foo');

foo() // => /full/path/to/this/file/index.js
```

## Options:

* `getCallerFile(position = 2)`: where position is stack frame whos fileName we want.

license: mit


code:
declare const _default: (position?: number) => any;
export = _default;


code:
"use strict";
// Call this function in a another function to find out the file from
// which that function was called from. (Inspects the v8 stack trace)
//
// Inspired by http://stackoverflow.com/questions/13227489
module.exports = function getCallerFile(position) {
    if (position === void 0) { position = 2; }
    if (position >= Error.stackTraceLimit) {
        throw new TypeError('getCallerFile(position) requires position be less then Error.stackTraceLimit but position was: `' + position + '` and Error.stackTraceLimit was: `' + Error.stackTraceLimit + '`');
    }
    var oldPrepareStackTrace = Error.prepareStackTrace;
    Error.prepareStackTrace = function (_, stack) { return stack; };
    var stack = new Error().stack;
    Error.prepareStackTrace = oldPrepareStackTrace;
    if (stack !== null && typeof stack === 'object') {
        // stack[0] holds this file
        // stack[1] holds where this function was called
        // stack[2] holds the file we're interested in
        return stack[position] ? stack[position].getFileName() : undefined;
    }
};
//# sourceMappingURL=index.js.map


get-caller-file

test: tests

prepare: tsc

test: mocha test

test:debug: mocha test

type: git

author: Stefan Penner

license: ISC


code:
export type WidthType = 'fullwidth' | 'halfwidth' | 'wide' | 'narrow' | 'neutral' | 'ambiguous';

export type Options = {
	/**
	Whether to treat an `'ambiguous'` character as wide.

	@default true

	@example
	```
	import {eastAsianWidth} from 'get-east-asian-width';

	const codePoint = '⛣'.codePointAt(0);

	console.log(eastAsianWidth(codePoint));
	//=> 1

	console.log(eastAsianWidth(codePoint, {ambiguousAsWide: true}));
	//=> 2
	```

	> Ambiguous characters behave like wide or narrow characters depending on the context (language tag, script identification, associated font, source of data, or explicit markup; all can provide the context). __If the context cannot be established reliably, they should be treated as narrow characters by default.__
	> - http://www.unicode.org/reports/tr11/
	*/
	readonly ambiguousAsWide?: boolean;
};

/**
Returns the width as a number for the given code point.

@param codePoint - A Unicode code point.

@example
```
import {eastAsianWidth} from 'get-east-asian-width';

const codePoint = '字'.codePointAt(0);

console.log(eastAsianWidth(codePoint));
//=> 2
```
*/
export function eastAsianWidth(codePoint: number, options?: Options): 1 | 2;

/**
Returns the type of “East Asian Width” for the given code point.

@param codePoint - A Unicode code point.

@example
```
import {eastAsianWidthType} from 'get-east-asian-width';

const codePoint = '字'.codePointAt(0);

console.log(eastAsianWidthType(codePoint));
//=> 'wide'
```
*/
export function eastAsianWidthType(codePoint: number): WidthType;


code:
import {getCategory, isAmbiguous, isFullWidth, isWide} from './lookup.js';

function validate(codePoint) {
	if (!Number.isSafeInteger(codePoint)) {
		throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
	}
}

export function eastAsianWidthType(codePoint) {
	validate(codePoint);

	return getCategory(codePoint);
}

export function eastAsianWidth(codePoint, {ambiguousAsWide = false} = {}) {
	validate(codePoint);

	if (
		isFullWidth(codePoint)
		|| isWide(codePoint)
		|| (ambiguousAsWide && isAmbiguous(codePoint))
	) {
		return 2;
	}

	return 1;
}

// For Prettier. This doesn't count "ambiguous" characters or check for valid input.
// https://github.com/sindresorhus/get-east-asian-width/pull/6
export const _isNarrowWidth = codePoint => !(isFullWidth(codePoint) || isWide(codePoint));


get-east-asian-width

description: Determine the East Asian Width of a Unicode character

license: MIT

repository: sindresorhus/get-east-asian-width

type: module

test: xo && ava && tsc index.d.ts

build: node scripts/build.js

prepublish: npm run build

keywords: unicode east-asian-width eastasianwidth character string width text layout alignment fullwidth halfwidth ambiguous narrow wide neutral typography japanese chinese korean codepoint text-processing i18n l10n


code:
# get-east-asian-width

> Determine the [East Asian Width](https://unicode.org/reports/tr11/) of a Unicode character

> East Asian Width categorizes Unicode characters based on their occupied space in East Asian typography, which helps in text layout and alignment, particularly in languages like Japanese, Chinese, and Korean.

Unlike other similar packages, this package uses the latest Unicode data (which changes each year).

## Install

```sh
npm install get-east-asian-width
```

## Usage

```js
import {eastAsianWidth, eastAsianWidthType} from 'get-east-asian-width';

const codePoint = '字'.codePointAt(0);

console.log(eastAsianWidth(codePoint));
//=> 2

console.log(eastAsianWidthType(codePoint));
//=> 'wide'
```

## `eastAsianWidth(codePoint: number, options?: object): 1 | 2`

Returns the width as a number for the given code point.

### options

Type: `object`

#### ambiguousAsWide

Type: `boolean`\
Default: `false`

Whether to treat an `'ambiguous'` character as wide.

```js
import {eastAsianWidth} from 'get-east-asian-width';

const codePoint = '⛣'.codePointAt(0);

console.log(eastAsianWidth(codePoint));
//=> 1

console.log(eastAsianWidth(codePoint, {ambiguousAsWide: true}));
//=> 2
```

> Ambiguous characters behave like wide or narrow characters depending on the context (language tag, script identification, associated font, source of data, or explicit markup; all can provide the context). **If the context cannot be established reliably, they should be treated as narrow characters by default.**
> - http://www.unicode.org/reports/tr11/

## `eastAsianWidthType(codePoint: number): 'fullwidth' | 'halfwidth' | 'wide' | 'narrow' | 'neutral' | 'ambiguous'`

Returns the type of “East Asian Width” for the given code point.

## Related

- [string-width](https://github.com/sindresorhus/string-width) - Get the visual width of a string


code:
{
	"root": true,

	"extends": "@ljharb",

	"env": {
		"es6": true,
		"es2017": true,
		"es2020": true,
		"es2021": true,
		"es2022": true,
	},

	"rules": {
		"array-bracket-newline": 0,
		"complexity": 0,
		"eqeqeq": [2, "allow-null"],
		"func-name-matching": 0,
		"id-length": 0,
		"max-lines": 0,
		"max-lines-per-function": [2, 90],
		"max-params": [2, 4],
		"max-statements": 0,
		"max-statements-per-line": [2, { "max": 2 }],
		"multiline-comment-style": 0,
		"no-magic-numbers": 0,
		"sort-keys": 0,
	},

	"overrides": [
		{
			"files": "test/**",
			"rules": {
				"new-cap": 0,
			},
		},
	],
}


code:
# These are supported funding model platforms

github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/get-intrinsic
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']


reporter: text-summary text html json

exclude: coverage test


code:
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v1.2.4](https://github.com/ljharb/get-intrinsic/compare/v1.2.3...v1.2.4) - 2024-02-05

### Commits

- [Refactor] use all 7 <+ ES6 Errors from `es-errors` [`bcac811`](https://github.com/ljharb/get-intrinsic/commit/bcac811abdc1c982e12abf848a410d6aae148d14)

## [v1.2.3](https://github.com/ljharb/get-intrinsic/compare/v1.2.2...v1.2.3) - 2024-02-03

### Commits

- [Refactor] use `es-errors`, so things that only need those do not need `get-intrinsic` [`f11db9c`](https://github.com/ljharb/get-intrinsic/commit/f11db9c4fb97d87bbd53d3c73ac6b3db3613ad3b)
- [Dev Deps] update `aud`, `es-abstract`, `mock-property`, `npmignore` [`b7ac7d1`](https://github.com/ljharb/get-intrinsic/commit/b7ac7d1616fefb03877b1aed0c8f8d61aad32b6c)
- [meta] simplify `exports` [`faa0cc6`](https://github.com/ljharb/get-intrinsic/commit/faa0cc618e2830ffb51a8202490b0c215d965cbc)
- [meta] add missing `engines.node` [`774dd0b`](https://github.com/ljharb/get-intrinsic/commit/774dd0b3e8f741c3f05a6322d124d6087f146af1)
- [Dev Deps] update `tape` [`5828e8e`](https://github.com/ljharb/get-intrinsic/commit/5828e8e4a04e69312e87a36c0ea39428a7a4c3d8)
- [Robustness] use null objects for lookups [`eb9a11f`](https://github.com/ljharb/get-intrinsic/commit/eb9a11fa9eb3e13b193fcc05a7fb814341b1a7b7)
- [meta] add `sideEffects` flag [`89bcc7a`](https://github.com/ljharb/get-intrinsic/commit/89bcc7a42e19bf07b7c21e3094d5ab177109e6d2)

## [v1.2.2](https://github.com/ljharb/get-intrinsic/compare/v1.2.1...v1.2.2) - 2023-10-20

### Commits

- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `call-bind`, `es-abstract`, `mock-property`, `object-inspect`, `tape` [`f51bcf2`](https://github.com/ljharb/get-intrinsic/commit/f51bcf26412d58d17ce17c91c9afd0ad271f0762)
- [Refactor] use `hasown` instead of `has` [`18d14b7`](https://github.com/ljharb/get-intrinsic/commit/18d14b799bea6b5765e1cec91890830cbcdb0587)
- [Deps] update `function-bind` [`6e109c8`](https://github.com/ljharb/get-intrinsic/commit/6e109c81e03804cc5e7824fb64353cdc3d8ee2c7)

## [v1.2.1](https://github.com/ljharb/get-intrinsic/compare/v1.2.0...v1.2.1) - 2023-05-13

### Commits

- [Fix] avoid a crash in envs without `__proto__` [`7bad8d0`](https://github.com/ljharb/get-intrinsic/commit/7bad8d061bf8721733b58b73a2565af2b6756b64)
- [Dev Deps] update `es-abstract` [`c60e6b7`](https://github.com/ljharb/get-intrinsic/commit/c60e6b7b4cf9660c7f27ed970970fd55fac48dc5)

## [v1.2.0](https://github.com/ljharb/get-intrinsic/compare/v1.1.3...v1.2.0) - 2023-01-19

### Commits

- [actions] update checkout action [`ca6b12f`](https://github.com/ljharb/get-intrinsic/commit/ca6b12f31eaacea4ea3b055e744cd61623385ffb)
- [Dev Deps] update `@ljharb/eslint-config`, `es-abstract`, `object-inspect`, `tape` [`41a3727`](https://github.com/ljharb/get-intrinsic/commit/41a3727d0026fa04273ae216a5f8e12eefd72da8)
- [Fix] ensure `Error.prototype` is undeniable [`c511e97`](https://github.com/ljharb/get-intrinsic/commit/c511e97ae99c764c4524b540dee7a70757af8da3)
- [Dev Deps] update `aud`, `es-abstract`, `tape` [`1bef8a8`](https://github.com/ljharb/get-intrinsic/commit/1bef8a8fd439ebb80863199b6189199e0851ac67)
- [Dev Deps] update `aud`, `es-abstract` [`0d41f16`](https://github.com/ljharb/get-intrinsic/commit/0d41f16bcd500bc28b7bfc98043ebf61ea081c26)
- [New] add `BigInt64Array` and `BigUint64Array` [`a6cca25`](https://github.com/ljharb/get-intrinsic/commit/a6cca25f29635889b7e9bd669baf9e04be90e48c)
- [Tests] use `gopd` [`ecf7722`](https://github.com/ljharb/get-intrinsic/commit/ecf7722240d15cfd16edda06acf63359c10fb9bd)

## [v1.1.3](https://github.com/ljharb/get-intrinsic/compare/v1.1.2...v1.1.3) - 2022-09-12

### Commits

- [Dev Deps] update `es-abstract`, `es-value-fixtures`, `tape` [`07ff291`](https://github.com/ljharb/get-intrinsic/commit/07ff291816406ebe5a12d7f16965bde0942dd688)
- [Fix] properly check for % signs [`50ac176`](https://github.com/ljharb/get-intrinsic/commit/50ac1760fe99c227e64eabde76e9c0e44cd881b5)

## [v1.1.2](https://github.com/ljharb/get-intrinsic/compare/v1.1.1...v1.1.2) - 2022-06-08

### Fixed

- [Fix] properly validate against extra % signs [`#16`](https://github.com/ljharb/get-intrinsic/issues/16)

### Commits

- [actions] reuse common workflows [`0972547`](https://github.com/ljharb/get-intrinsic/commit/0972547efd0abc863fe4c445a6ca7eb4f8c6901d)
- [meta] use `npmignore` to autogenerate an npmignore file [`5ba0b51`](https://github.com/ljharb/get-intrinsic/commit/5ba0b51d8d8d4f1c31d426d74abc0770fd106bad)
- [actions] use `node/install` instead of `node/run`; use `codecov` action [`c364492`](https://github.com/ljharb/get-intrinsic/commit/c364492af4af51333e6f81c0bf21fd3d602c3661)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `es-abstract`, `object-inspect`, `tape` [`dc04dad`](https://github.com/ljharb/get-intrinsic/commit/dc04dad86f6e5608775a2640cb0db5927ae29ed9)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `es-abstract`, `object-inspect`, `safe-publish-latest`, `tape` [`1c14059`](https://github.com/ljharb/get-intrinsic/commit/1c1405984e86dd2dc9366c15d8a0294a96a146a5)
- [Tests] use `mock-property` [`b396ef0`](https://github.com/ljharb/get-intrinsic/commit/b396ef05bb73b1d699811abd64b0d9b97997fdda)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `object-inspect`, `tape` [`c2c758d`](https://github.com/ljharb/get-intrinsic/commit/c2c758d3b90af4fef0a76910d8d3c292ec8d1d3e)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `es-abstract`, `es-value-fixtures`, `object-inspect`, `tape` [`29e3c09`](https://github.com/ljharb/get-intrinsic/commit/29e3c091c2bf3e17099969847e8729d0e46896de)
- [actions] update codecov uploader [`8cbc141`](https://github.com/ljharb/get-intrinsic/commit/8cbc1418940d7a8941f3a7985cbc4ac095c5e13d)
- [Dev Deps] update `@ljharb/eslint-config`, `es-abstract`, `es-value-fixtures`, `object-inspect`, `tape` [`10b6f5c`](https://github.com/ljharb/get-intrinsic/commit/10b6f5c02593fb3680c581d696ac124e30652932)
- [readme] add github actions/codecov badges [`4e25400`](https://github.com/ljharb/get-intrinsic/commit/4e25400d9f51ae9eb059cbe22d9144e70ea214e8)
- [Tests] use `for-each` instead of `foreach` [`c05b957`](https://github.com/ljharb/get-intrinsic/commit/c05b957ad9a7bc7721af7cc9e9be1edbfe057496)
- [Dev Deps] update `es-abstract` [`29b05ae`](https://github.com/ljharb/get-intrinsic/commit/29b05aec3e7330e9ad0b8e0f685a9112c20cdd97)
- [meta] use `prepublishOnly` script for npm 7+ [`95c285d`](https://github.com/ljharb/get-intrinsic/commit/95c285da810516057d3bbfa871176031af38f05d)
- [Deps] update `has-symbols` [`593cb4f`](https://github.com/ljharb/get-intrinsic/commit/593cb4fb38e7922e40e42c183f45274b636424cd)
- [readme] fix repo URLs [`1c8305b`](https://github.com/ljharb/get-intrinsic/commit/1c8305b5365827c9b6fc785434aac0e1328ff2f5)
- [Deps] update `has-symbols` [`c7138b6`](https://github.com/ljharb/get-intrinsic/commit/c7138b6c6d73132d859471fb8c13304e1e7c8b20)
- [Dev Deps] remove unused `has-bigints` [`bd63aff`](https://github.com/ljharb/get-intrinsic/commit/bd63aff6ad8f3a986c557fcda2914187bdaab359)

## [v1.1.1](https://github.com/ljharb/get-intrinsic/compare/v1.1.0...v1.1.1) - 2021-02-03

### Fixed

- [meta] export `./package.json` [`#9`](https://github.com/ljharb/get-intrinsic/issues/9)

### Commits

- [readme] flesh out the readme; use `evalmd` [`d12f12c`](https://github.com/ljharb/get-intrinsic/commit/d12f12c15345a0a0772cc65a7c64369529abd614)
- [eslint] set up proper globals config [`5a8c098`](https://github.com/ljharb/get-intrinsic/commit/5a8c0984e3319d1ac0e64b102f8ec18b64e79f36)
- [Dev Deps] update `eslint` [`7b9a5c0`](https://github.com/ljharb/get-intrinsic/commit/7b9a5c0d31a90ca1a1234181c74988fb046701cd)

## [v1.1.0](https://github.com/ljharb/get-intrinsic/compare/v1.0.2...v1.1.0) - 2021-01-25

### Fixed

- [Refactor] delay `Function` eval until syntax-derived values are requested [`#3`](https://github.com/ljharb/get-intrinsic/issues/3)

### Commits

- [Tests] migrate tests to Github Actions [`2ab762b`](https://github.com/ljharb/get-intrinsic/commit/2ab762b48164aea8af37a40ba105bbc8246ab8c4)
- [meta] do not publish github action workflow files [`5e7108e`](https://github.com/ljharb/get-intrinsic/commit/5e7108e4768b244d48d9567ba4f8a6cab9c65b8e)
- [Tests] add some coverage [`01ac7a8`](https://github.com/ljharb/get-intrinsic/commit/01ac7a87ac29738567e8524cd8c9e026b1fa8cb3)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `call-bind`, `es-abstract`, `tape`; add `call-bind` [`911b672`](https://github.com/ljharb/get-intrinsic/commit/911b672fbffae433a96924c6ce013585e425f4b7)
- [Refactor] rearrange evalled constructors a bit [`7e7e4bf`](https://github.com/ljharb/get-intrinsic/commit/7e7e4bf583f3799c8ac1c6c5e10d2cb553957347)
- [meta] add Automatic Rebase and Require Allow Edits workflows [`0199968`](https://github.com/ljharb/get-intrinsic/commit/01999687a263ffce0a3cb011dfbcb761754aedbc)

## [v1.0.2](https://github.com/ljharb/get-intrinsic/compare/v1.0.1...v1.0.2) - 2020-12-17

### Commits

- [Fix] Throw for non‑existent intrinsics [`68f873b`](https://github.com/ljharb/get-intrinsic/commit/68f873b013c732a05ad6f5fc54f697e55515461b)
- [Fix] Throw for non‑existent segments in the intrinsic path [`8325dee`](https://github.com/ljharb/get-intrinsic/commit/8325deee43128f3654d3399aa9591741ebe17b21)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `has-bigints`, `object-inspect` [`0c227a7`](https://github.com/ljharb/get-intrinsic/commit/0c227a7d8b629166f25715fd242553892e458525)
- [meta] do not lint coverage output [`70d2419`](https://github.com/ljharb/get-intrinsic/commit/70d24199b620043cd9110fc5f426d214ebe21dc9)

## [v1.0.1](https://github.com/ljharb/get-intrinsic/compare/v1.0.0...v1.0.1) - 2020-10-30

### Commits

- [Tests] gather coverage data on every job [`d1d280d`](https://github.com/ljharb/get-intrinsic/commit/d1d280dec714e3f0519cc877dbcb193057d9cac6)
- [Fix] add missing dependencies [`5031771`](https://github.com/ljharb/get-intrinsic/commit/5031771bb1095b38be88ce7c41d5de88718e432e)
- [Tests] use `es-value-fixtures` [`af48765`](https://github.com/ljharb/get-intrinsic/commit/af48765a23c5323fb0b6b38dbf00eb5099c7bebc)

## v1.0.0 - 2020-10-29

### Commits

- Implementation [`bbce57c`](https://github.com/ljharb/get-intrinsic/commit/bbce57c6f33d05b2d8d3efa273ceeb3ee01127bb)
- Tests [`17b4f0d`](https://github.com/ljharb/get-intrinsic/commit/17b4f0d56dea6b4059b56fc30ef3ee4d9500ebc2)
- Initial commit [`3153294`](https://github.com/ljharb/get-intrinsic/commit/31532948de363b0a27dd9fd4649e7b7028ec4b44)
- npm init [`fb326c4`](https://github.com/ljharb/get-intrinsic/commit/fb326c4d2817c8419ec31de1295f06bb268a7902)
- [meta] add Automatic Rebase and Require Allow Edits workflows [`48862fb`](https://github.com/ljharb/get-intrinsic/commit/48862fb2508c8f6a57968e6d08b7c883afc9d550)
- [meta] add `auto-changelog` [`5f28ad0`](https://github.com/ljharb/get-intrinsic/commit/5f28ad019e060a353d8028f9f2591a9cc93074a1)
- [meta] add "funding"; create `FUNDING.yml` [`c2bbdde`](https://github.com/ljharb/get-intrinsic/commit/c2bbddeba73a875be61484ee4680b129a6d4e0a1)
- [Tests] add `npm run lint` [`0a84b98`](https://github.com/ljharb/get-intrinsic/commit/0a84b98b22b7cf7a748666f705b0003a493c35fd)
- Only apps should have lockfiles [`9586c75`](https://github.com/ljharb/get-intrinsic/commit/9586c75866c1ee678e4d5d4dbbdef6997e511b05)


code:
# get-intrinsic <sup>[![Version Badge][npm-version-svg]][package-url]</sup>

[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]

[![npm badge][npm-badge-png]][package-url]

Get and robustly cache all JS language-level intrinsics at first require time.

See the syntax described [in the JS spec](https://tc39.es/ecma262/#sec-well-known-intrinsic-objects) for reference.

## Example

```js
var GetIntrinsic = require('get-intrinsic');
var assert = require('assert');

// static methods
assert.equal(GetIntrinsic('%Math.pow%'), Math.pow);
assert.equal(Math.pow(2, 3), 8);
assert.equal(GetIntrinsic('%Math.pow%')(2, 3), 8);
delete Math.pow;
assert.equal(GetIntrinsic('%Math.pow%')(2, 3), 8);

// instance methods
var arr = [1];
assert.equal(GetIntrinsic('%Array.prototype.push%'), Array.prototype.push);
assert.deepEqual(arr, [1]);

arr.push(2);
assert.deepEqual(arr, [1, 2]);

GetIntrinsic('%Array.prototype.push%').call(arr, 3);
assert.deepEqual(arr, [1, 2, 3]);

delete Array.prototype.push;
GetIntrinsic('%Array.prototype.push%').call(arr, 4);
assert.deepEqual(arr, [1, 2, 3, 4]);

// missing features
delete JSON.parse; // to simulate a real intrinsic that is missing in the environment
assert.throws(() => GetIntrinsic('%JSON.parse%'));
assert.equal(undefined, GetIntrinsic('%JSON.parse%', true));
```

## Tests
Simply clone the repo, `npm install`, and run `npm test`

## Security

Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.

[package-url]: https://npmjs.org/package/get-intrinsic
[npm-version-svg]: https://versionbadg.es/ljharb/get-intrinsic.svg
[deps-svg]: https://david-dm.org/ljharb/get-intrinsic.svg
[deps-url]: https://david-dm.org/ljharb/get-intrinsic
[dev-deps-svg]: https://david-dm.org/ljharb/get-intrinsic/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/get-intrinsic#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/get-intrinsic.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/get-intrinsic.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/get-intrinsic.svg
[downloads-url]: https://npm-stat.com/charts.html?package=get-intrinsic
[codecov-image]: https://codecov.io/gh/ljharb/get-intrinsic/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/get-intrinsic/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/get-intrinsic
[actions-url]: https://github.com/ljharb/get-intrinsic/actions


code:
'use strict';

var undefined;

var $Error = require('es-errors');
var $EvalError = require('es-errors/eval');
var $RangeError = require('es-errors/range');
var $ReferenceError = require('es-errors/ref');
var $SyntaxError = require('es-errors/syntax');
var $TypeError = require('es-errors/type');
var $URIError = require('es-errors/uri');

var $Function = Function;

// eslint-disable-next-line consistent-return
var getEvalledConstructor = function (expressionSyntax) {
	try {
		return $Function('"use strict"; return (' + expressionSyntax + ').constructor;')();
	} catch (e) {}
};

var $gOPD = Object.getOwnPropertyDescriptor;
if ($gOPD) {
	try {
		$gOPD({}, '');
	} catch (e) {
		$gOPD = null; // this is IE 8, which has a broken gOPD
	}
}

var throwTypeError = function () {
	throw new $TypeError();
};
var ThrowTypeError = $gOPD
	? (function () {
		try {
			// eslint-disable-next-line no-unused-expressions, no-caller, no-restricted-properties
			arguments.callee; // IE 8 does not throw here
			return throwTypeError;
		} catch (calleeThrows) {
			try {
				// IE 8 throws on Object.getOwnPropertyDescriptor(arguments, '')
				return $gOPD(arguments, 'callee').get;
			} catch (gOPDthrows) {
				return throwTypeError;
			}
		}
	}())
	: throwTypeError;

var hasSymbols = require('has-symbols')();
var hasProto = require('has-proto')();

var getProto = Object.getPrototypeOf || (
	hasProto
		? function (x) { return x.__proto__; } // eslint-disable-line no-proto
		: null
);

var needsEval = {};

var TypedArray = typeof Uint8Array === 'undefined' || !getProto ? undefined : getProto(Uint8Array);

var INTRINSICS = {
	__proto__: null,
	'%AggregateError%': typeof AggregateError === 'undefined' ? undefined : AggregateError,
	'%Array%': Array,
	'%ArrayBuffer%': typeof ArrayBuffer === 'undefined' ? undefined : ArrayBuffer,
	'%ArrayIteratorPrototype%': hasSymbols && getProto ? getProto([][Symbol.iterator]()) : undefined,
	'%AsyncFromSyncIteratorPrototype%': undefined,
	'%AsyncFunction%': needsEval,
	'%AsyncGenerator%': needsEval,
	'%AsyncGeneratorFunction%': needsEval,
	'%AsyncIteratorPrototype%': needsEval,
	'%Atomics%': typeof Atomics === 'undefined' ? undefined : Atomics,
	'%BigInt%': typeof BigInt === 'undefined' ? undefined : BigInt,
	'%BigInt64Array%': typeof BigInt64Array === 'undefined' ? undefined : BigInt64Array,
	'%BigUint64Array%': typeof BigUint64Array === 'undefined' ? undefined : BigUint64Array,
	'%Boolean%': Boolean,
	'%DataView%': typeof DataView === 'undefined' ? undefined : DataView,
	'%Date%': Date,
	'%decodeURI%': decodeURI,
	'%decodeURIComponent%': decodeURIComponent,
	'%encodeURI%': encodeURI,
	'%encodeURIComponent%': encodeURIComponent,
	'%Error%': $Error,
	'%eval%': eval, // eslint-disable-line no-eval
	'%EvalError%': $EvalError,
	'%Float32Array%': typeof Float32Array === 'undefined' ? undefined : Float32Array,
	'%Float64Array%': typeof Float64Array === 'undefined' ? undefined : Float64Array,
	'%FinalizationRegistry%': typeof FinalizationRegistry === 'undefined' ? undefined : FinalizationRegistry,
	'%Function%': $Function,
	'%GeneratorFunction%': needsEval,
	'%Int8Array%': typeof Int8Array === 'undefined' ? undefined : Int8Array,
	'%Int16Array%': typeof Int16Array === 'undefined' ? undefined : Int16Array,
	'%Int32Array%': typeof Int32Array === 'undefined' ? undefined : Int32Array,
	'%isFinite%': isFinite,
	'%isNaN%': isNaN,
	'%IteratorPrototype%': hasSymbols && getProto ? getProto(getProto([][Symbol.iterator]())) : undefined,
	'%JSON%': typeof JSON === 'object' ? JSON : undefined,
	'%Map%': typeof Map === 'undefined' ? undefined : Map,
	'%MapIteratorPrototype%': typeof Map === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Map()[Symbol.iterator]()),
	'%Math%': Math,
	'%Number%': Number,
	'%Object%': Object,
	'%parseFloat%': parseFloat,
	'%parseInt%': parseInt,
	'%Promise%': typeof Promise === 'undefined' ? undefined : Promise,
	'%Proxy%': typeof Proxy === 'undefined' ? undefined : Proxy,
	'%RangeError%': $RangeError,
	'%ReferenceError%': $ReferenceError,
	'%Reflect%': typeof Reflect === 'undefined' ? undefined : Reflect,
	'%RegExp%': RegExp,
	'%Set%': typeof Set === 'undefined' ? undefined : Set,
	'%SetIteratorPrototype%': typeof Set === 'undefined' || !hasSymbols || !getProto ? undefined : getProto(new Set()[Symbol.iterator]()),
	'%SharedArrayBuffer%': typeof SharedArrayBuffer === 'undefined' ? undefined : SharedArrayBuffer,
	'%String%': String,
	'%StringIteratorPrototype%': hasSymbols && getProto ? getProto(''[Symbol.iterator]()) : undefined,
	'%Symbol%': hasSymbols ? Symbol : undefined,
	'%SyntaxError%': $SyntaxError,
	'%ThrowTypeError%': ThrowTypeError,
	'%TypedArray%': TypedArray,
	'%TypeError%': $TypeError,
	'%Uint8Array%': typeof Uint8Array === 'undefined' ? undefined : Uint8Array,
	'%Uint8ClampedArray%': typeof Uint8ClampedArray === 'undefined' ? undefined : Uint8ClampedArray,
	'%Uint16Array%': typeof Uint16Array === 'undefined' ? undefined : Uint16Array,
	'%Uint32Array%': typeof Uint32Array === 'undefined' ? undefined : Uint32Array,
	'%URIError%': $URIError,
	'%WeakMap%': typeof WeakMap === 'undefined' ? undefined : WeakMap,
	'%WeakRef%': typeof WeakRef === 'undefined' ? undefined : WeakRef,
	'%WeakSet%': typeof WeakSet === 'undefined' ? undefined : WeakSet
};

if (getProto) {
	try {
		null.error; // eslint-disable-line no-unused-expressions
	} catch (e) {
		// https://github.com/tc39/proposal-shadowrealm/pull/384#issuecomment-1364264229
		var errorProto = getProto(getProto(e));
		INTRINSICS['%Error.prototype%'] = errorProto;
	}
}

var doEval = function doEval(name) {
	var value;
	if (name === '%AsyncFunction%') {
		value = getEvalledConstructor('async function () {}');
	} else if (name === '%GeneratorFunction%') {
		value = getEvalledConstructor('function* () {}');
	} else if (name === '%AsyncGeneratorFunction%') {
		value = getEvalledConstructor('async function* () {}');
	} else if (name === '%AsyncGenerator%') {
		var fn = doEval('%AsyncGeneratorFunction%');
		if (fn) {
			value = fn.prototype;
		}
	} else if (name === '%AsyncIteratorPrototype%') {
		var gen = doEval('%AsyncGenerator%');
		if (gen && getProto) {
			value = getProto(gen.prototype);
		}
	}

	INTRINSICS[name] = value;

	return value;
};

var LEGACY_ALIASES = {
	__proto__: null,
	'%ArrayBufferPrototype%': ['ArrayBuffer', 'prototype'],
	'%ArrayPrototype%': ['Array', 'prototype'],
	'%ArrayProto_entries%': ['Array', 'prototype', 'entries'],
	'%ArrayProto_forEach%': ['Array', 'prototype', 'forEach'],
	'%ArrayProto_keys%': ['Array', 'prototype', 'keys'],
	'%ArrayProto_values%': ['Array', 'prototype', 'values'],
	'%AsyncFunctionPrototype%': ['AsyncFunction', 'prototype'],
	'%AsyncGenerator%': ['AsyncGeneratorFunction', 'prototype'],
	'%AsyncGeneratorPrototype%': ['AsyncGeneratorFunction', 'prototype', 'prototype'],
	'%BooleanPrototype%': ['Boolean', 'prototype'],
	'%DataViewPrototype%': ['DataView', 'prototype'],
	'%DatePrototype%': ['Date', 'prototype'],
	'%ErrorPrototype%': ['Error', 'prototype'],
	'%EvalErrorPrototype%': ['EvalError', 'prototype'],
	'%Float32ArrayPrototype%': ['Float32Array', 'prototype'],
	'%Float64ArrayPrototype%': ['Float64Array', 'prototype'],
	'%FunctionPrototype%': ['Function', 'prototype'],
	'%Generator%': ['GeneratorFunction', 'prototype'],
	'%GeneratorPrototype%': ['GeneratorFunction', 'prototype', 'prototype'],
	'%Int8ArrayPrototype%': ['Int8Array', 'prototype'],
	'%Int16ArrayPrototype%': ['Int16Array', 'prototype'],
	'%Int32ArrayPrototype%': ['Int32Array', 'prototype'],
	'%JSONParse%': ['JSON', 'parse'],
	'%JSONStringify%': ['JSON', 'stringify'],
	'%MapPrototype%': ['Map', 'prototype'],
	'%NumberPrototype%': ['Number', 'prototype'],
	'%ObjectPrototype%': ['Object', 'prototype'],
	'%ObjProto_toString%': ['Object', 'prototype', 'toString'],
	'%ObjProto_valueOf%': ['Object', 'prototype', 'valueOf'],
	'%PromisePrototype%': ['Promise', 'prototype'],
	'%PromiseProto_then%': ['Promise', 'prototype', 'then'],
	'%Promise_all%': ['Promise', 'all'],
	'%Promise_reject%': ['Promise', 'reject'],
	'%Promise_resolve%': ['Promise', 'resolve'],
	'%RangeErrorPrototype%': ['RangeError', 'prototype'],
	'%ReferenceErrorPrototype%': ['ReferenceError', 'prototype'],
	'%RegExpPrototype%': ['RegExp', 'prototype'],
	'%SetPrototype%': ['Set', 'prototype'],
	'%SharedArrayBufferPrototype%': ['SharedArrayBuffer', 'prototype'],
	'%StringPrototype%': ['String', 'prototype'],
	'%SymbolPrototype%': ['Symbol', 'prototype'],
	'%SyntaxErrorPrototype%': ['SyntaxError', 'prototype'],
	'%TypedArrayPrototype%': ['TypedArray', 'prototype'],
	'%TypeErrorPrototype%': ['TypeError', 'prototype'],
	'%Uint8ArrayPrototype%': ['Uint8Array', 'prototype'],
	'%Uint8ClampedArrayPrototype%': ['Uint8ClampedArray', 'prototype'],
	'%Uint16ArrayPrototype%': ['Uint16Array', 'prototype'],
	'%Uint32ArrayPrototype%': ['Uint32Array', 'prototype'],
	'%URIErrorPrototype%': ['URIError', 'prototype'],
	'%WeakMapPrototype%': ['WeakMap', 'prototype'],
	'%WeakSetPrototype%': ['WeakSet', 'prototype']
};

var bind = require('function-bind');
var hasOwn = require('hasown');
var $concat = bind.call(Function.call, Array.prototype.concat);
var $spliceApply = bind.call(Function.apply, Array.prototype.splice);
var $replace = bind.call(Function.call, String.prototype.replace);
var $strSlice = bind.call(Function.call, String.prototype.slice);
var $exec = bind.call(Function.call, RegExp.prototype.exec);

/* adapted from https://github.com/lodash/lodash/blob/4.17.15/dist/lodash.js#L6735-L6744 */
var rePropName = /[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g;
var reEscapeChar = /\\(\\)?/g; /** Used to match backslashes in property paths. */
var stringToPath = function stringToPath(string) {
	var first = $strSlice(string, 0, 1);
	var last = $strSlice(string, -1);
	if (first === '%' && last !== '%') {
		throw new $SyntaxError('invalid intrinsic syntax, expected closing `%`');
	} else if (last === '%' && first !== '%') {
		throw new $SyntaxError('invalid intrinsic syntax, expected opening `%`');
	}
	var result = [];
	$replace(string, rePropName, function (match, number, quote, subString) {
		result[result.length] = quote ? $replace(subString, reEscapeChar, '$1') : number || match;
	});
	return result;
};
/* end adaptation */

var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
	var intrinsicName = name;
	var alias;
	if (hasOwn(LEGACY_ALIASES, intrinsicName)) {
		alias = LEGACY_ALIASES[intrinsicName];
		intrinsicName = '%' + alias[0] + '%';
	}

	if (hasOwn(INTRINSICS, intrinsicName)) {
		var value = INTRINSICS[intrinsicName];
		if (value === needsEval) {
			value = doEval(intrinsicName);
		}
		if (typeof value === 'undefined' && !allowMissing) {
			throw new $TypeError('intrinsic ' + name + ' exists, but is not available. Please file an issue!');
		}

		return {
			alias: alias,
			name: intrinsicName,
			value: value
		};
	}

	throw new $SyntaxError('intrinsic ' + name + ' does not exist!');
};

module.exports = function GetIntrinsic(name, allowMissing) {
	if (typeof name !== 'string' || name.length === 0) {
		throw new $TypeError('intrinsic name must be a non-empty string');
	}
	if (arguments.length > 1 && typeof allowMissing !== 'boolean') {
		throw new $TypeError('"allowMissing" argument must be a boolean');
	}

	if ($exec(/^%?[^%]*%?$/, name) === null) {
		throw new $SyntaxError('`%` may not be present anywhere but at the beginning and end of the intrinsic name');
	}
	var parts = stringToPath(name);
	var intrinsicBaseName = parts.length > 0 ? parts[0] : '';

	var intrinsic = getBaseIntrinsic('%' + intrinsicBaseName + '%', allowMissing);
	var intrinsicRealName = intrinsic.name;
	var value = intrinsic.value;
	var skipFurtherCaching = false;

	var alias = intrinsic.alias;
	if (alias) {
		intrinsicBaseName = alias[0];
		$spliceApply(parts, $concat([0, 1], alias));
	}

	for (var i = 1, isOwn = true; i < parts.length; i += 1) {
		var part = parts[i];
		var first = $strSlice(part, 0, 1);
		var last = $strSlice(part, -1);
		if (
			(
				(first === '"' || first === "'" || first === '`')
				|| (last === '"' || last === "'" || last === '`')
			)
			&& first !== last
		) {
			throw new $SyntaxError('property names with quotes must have matching quotes');
		}
		if (part === 'constructor' || !isOwn) {
			skipFurtherCaching = true;
		}

		intrinsicBaseName += '.' + part;
		intrinsicRealName = '%' + intrinsicBaseName + '%';

		if (hasOwn(INTRINSICS, intrinsicRealName)) {
			value = INTRINSICS[intrinsicRealName];
		} else if (value != null) {
			if (!(part in value)) {
				if (!allowMissing) {
					throw new $TypeError('base intrinsic for ' + name + ' exists, but the property is not available.');
				}
				return void undefined;
			}
			if ($gOPD && (i + 1) >= parts.length) {
				var desc = $gOPD(value, part);
				isOwn = !!desc;

				// By convention, when a data property is converted to an accessor
				// property to emulate a data property that does not suffer from
				// the override mistake, that accessor's getter is marked with
				// an `originalValue` property. Here, when we detect this, we
				// uphold the illusion by pretending to see that original data
				// property, i.e., returning the value rather than the getter
				// itself.
				if (isOwn && 'get' in desc && !('originalValue' in desc.get)) {
					value = desc.get;
				} else {
					value = value[part];
				}
			} else {
				isOwn = hasOwn(value, part);
				value = value[part];
			}

			if (isOwn && !skipFurtherCaching) {
				INTRINSICS[intrinsicRealName] = value;
			}
		}
	}
	return value;
};


get-intrinsic

description: Get and robustly cache all JS language-level intrinsics at first require time

prepublish: not-in-publish || npm run prepublishOnly

prepublishOnly: safe-publish-latest

prelint: evalmd README.md

lint: eslint --ext=.js,.mjs .

pretest: npm run lint

tests-only: nyc tape 'test/**/*.js'

test: npm run tests-only

posttest: aud --production

version: auto-changelog && git add CHANGELOG.md

postversion: auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f "v$(node -e "console.log(require('./package.json').version)")"

keywords: javascript ecmascript es js intrinsic getintrinsic es-abstract

author: Jordan Harband <ljharb@gmail.com>

output: CHANGELOG.md

template: keepachangelog


code:
'use strict';

var GetIntrinsic = require('../');

var test = require('tape');
var forEach = require('for-each');
var debug = require('object-inspect');
var generatorFns = require('make-generator-function')();
var asyncFns = require('make-async-function').list();
var asyncGenFns = require('make-async-generator-function')();
var mockProperty = require('mock-property');

var callBound = require('call-bind/callBound');
var v = require('es-value-fixtures');
var $gOPD = require('gopd');
var DefinePropertyOrThrow = require('es-abstract/2021/DefinePropertyOrThrow');

var $isProto = callBound('%Object.prototype.isPrototypeOf%');

test('export', function (t) {
	t.equal(typeof GetIntrinsic, 'function', 'it is a function');
	t.equal(GetIntrinsic.length, 2, 'function has length of 2');

	t.end();
});

test('throws', function (t) {
	t['throws'](
		function () { GetIntrinsic('not an intrinsic'); },
		SyntaxError,
		'nonexistent intrinsic throws a syntax error'
	);

	t['throws'](
		function () { GetIntrinsic(''); },
		TypeError,
		'empty string intrinsic throws a type error'
	);

	t['throws'](
		function () { GetIntrinsic('.'); },
		SyntaxError,
		'"just a dot" intrinsic throws a syntax error'
	);

	t['throws'](
		function () { GetIntrinsic('%String'); },
		SyntaxError,
		'Leading % without trailing % throws a syntax error'
	);

	t['throws'](
		function () { GetIntrinsic('String%'); },
		SyntaxError,
		'Trailing % without leading % throws a syntax error'
	);

	t['throws'](
		function () { GetIntrinsic("String['prototype]"); },
		SyntaxError,
		'Dynamic property access is disallowed for intrinsics (unterminated string)'
	);

	t['throws'](
		function () { GetIntrinsic('%Proxy.prototype.undefined%'); },
		TypeError,
		"Throws when middle part doesn't exist (%Proxy.prototype.undefined%)"
	);

	t['throws'](
		function () { GetIntrinsic('%Array.prototype%garbage%'); },
		SyntaxError,
		'Throws with extra percent signs'
	);

	t['throws'](
		function () { GetIntrinsic('%Array.prototype%push%'); },
		SyntaxError,
		'Throws with extra percent signs, even on an existing intrinsic'
	);

	forEach(v.nonStrings, function (nonString) {
		t['throws'](
			function () { GetIntrinsic(nonString); },
			TypeError,
			debug(nonString) + ' is not a String'
		);
	});

	forEach(v.nonBooleans, function (nonBoolean) {
		t['throws'](
			function () { GetIntrinsic('%', nonBoolean); },
			TypeError,
			debug(nonBoolean) + ' is not a Boolean'
		);
	});

	forEach([
		'toString',
		'propertyIsEnumerable',
		'hasOwnProperty'
	], function (objectProtoMember) {
		t['throws'](
			function () { GetIntrinsic(objectProtoMember); },
			SyntaxError,
			debug(objectProtoMember) + ' is not an intrinsic'
		);
	});

	t.end();
});

test('base intrinsics', function (t) {
	t.equal(GetIntrinsic('%Object%'), Object, '%Object% yields Object');
	t.equal(GetIntrinsic('Object'), Object, 'Object yields Object');
	t.equal(GetIntrinsic('%Array%'), Array, '%Array% yields Array');
	t.equal(GetIntrinsic('Array'), Array, 'Array yields Array');

	t.end();
});

test('dotted paths', function (t) {
	t.equal(GetIntrinsic('%Object.prototype.toString%'), Object.prototype.toString, '%Object.prototype.toString% yields Object.prototype.toString');
	t.equal(GetIntrinsic('Object.prototype.toString'), Object.prototype.toString, 'Object.prototype.toString yields Object.prototype.toString');
	t.equal(GetIntrinsic('%Array.prototype.push%'), Array.prototype.push, '%Array.prototype.push% yields Array.prototype.push');
	t.equal(GetIntrinsic('Array.prototype.push'), Array.prototype.push, 'Array.prototype.push yields Array.prototype.push');

	test('underscore paths are aliases for dotted paths', { skip: !Object.isFrozen || Object.isFrozen(Object.prototype) }, function (st) {
		var original = GetIntrinsic('%ObjProto_toString%');

		forEach([
			'%Object.prototype.toString%',
			'Object.prototype.toString',
			'%ObjectPrototype.toString%',
			'ObjectPrototype.toString',
			'%ObjProto_toString%',
			'ObjProto_toString'
		], function (name) {
			DefinePropertyOrThrow(Object.prototype, 'toString', {
				'[[Value]]': function toString() {
					return original.apply(this, arguments);
				}
			});
			st.equal(GetIntrinsic(name), original, name + ' yields original Object.prototype.toString');
		});

		DefinePropertyOrThrow(Object.prototype, 'toString', { '[[Value]]': original });
		st.end();
	});

	test('dotted paths cache', { skip: !Object.isFrozen || Object.isFrozen(Object.prototype) }, function (st) {
		var original = GetIntrinsic('%Object.prototype.propertyIsEnumerable%');

		forEach([
			'%Object.prototype.propertyIsEnumerable%',
			'Object.prototype.propertyIsEnumerable',
			'%ObjectPrototype.propertyIsEnumerable%',
			'ObjectPrototype.propertyIsEnumerable'
		], function (name) {
			var restore = mockProperty(Object.prototype, 'propertyIsEnumerable', {
				value: function propertyIsEnumerable() {
					return original.apply(this, arguments);
				}
			});
			st.equal(GetIntrinsic(name), original, name + ' yields cached Object.prototype.propertyIsEnumerable');

			restore();
		});

		st.end();
	});

	test('dotted path reports correct error', function (st) {
		st['throws'](function () {
			GetIntrinsic('%NonExistentIntrinsic.prototype.property%');
		}, /%NonExistentIntrinsic%/, 'The base intrinsic of %NonExistentIntrinsic.prototype.property% is %NonExistentIntrinsic%');

		st['throws'](function () {
			GetIntrinsic('%NonExistentIntrinsicPrototype.property%');
		}, /%NonExistentIntrinsicPrototype%/, 'The base intrinsic of %NonExistentIntrinsicPrototype.property% is %NonExistentIntrinsicPrototype%');

		st.end();
	});

	t.end();
});

test('accessors', { skip: !$gOPD || typeof Map !== 'function' }, function (t) {
	var actual = $gOPD(Map.prototype, 'size');
	t.ok(actual, 'Map.prototype.size has a descriptor');
	t.equal(typeof actual.get, 'function', 'Map.prototype.size has a getter function');
	t.equal(GetIntrinsic('%Map.prototype.size%'), actual.get, '%Map.prototype.size% yields the getter for it');
	t.equal(GetIntrinsic('Map.prototype.size'), actual.get, 'Map.prototype.size yields the getter for it');

	t.end();
});

test('generator functions', { skip: !generatorFns.length }, function (t) {
	var $GeneratorFunction = GetIntrinsic('%GeneratorFunction%');
	var $GeneratorFunctionPrototype = GetIntrinsic('%Generator%');
	var $GeneratorPrototype = GetIntrinsic('%GeneratorPrototype%');

	forEach(generatorFns, function (genFn) {
		var fnName = genFn.name;
		fnName = fnName ? "'" + fnName + "'" : 'genFn';

		t.ok(genFn instanceof $GeneratorFunction, fnName + ' instanceof %GeneratorFunction%');
		t.ok($isProto($GeneratorFunctionPrototype, genFn), '%Generator% is prototype of ' + fnName);
		t.ok($isProto($GeneratorPrototype, genFn.prototype), '%GeneratorPrototype% is prototype of ' + fnName + '.prototype');
	});

	t.end();
});

test('async functions', { skip: !asyncFns.length }, function (t) {
	var $AsyncFunction = GetIntrinsic('%AsyncFunction%');
	var $AsyncFunctionPrototype = GetIntrinsic('%AsyncFunctionPrototype%');

	forEach(asyncFns, function (asyncFn) {
		var fnName = asyncFn.name;
		fnName = fnName ? "'" + fnName + "'" : 'asyncFn';

		t.ok(asyncFn instanceof $AsyncFunction, fnName + ' instanceof %AsyncFunction%');
		t.ok($isProto($AsyncFunctionPrototype, asyncFn), '%AsyncFunctionPrototype% is prototype of ' + fnName);
	});

	t.end();
});

test('async generator functions', { skip: asyncGenFns.length === 0 }, function (t) {
	var $AsyncGeneratorFunction = GetIntrinsic('%AsyncGeneratorFunction%');
	var $AsyncGeneratorFunctionPrototype = GetIntrinsic('%AsyncGenerator%');
	var $AsyncGeneratorPrototype = GetIntrinsic('%AsyncGeneratorPrototype%');

	forEach(asyncGenFns, function (asyncGenFn) {
		var fnName = asyncGenFn.name;
		fnName = fnName ? "'" + fnName + "'" : 'asyncGenFn';

		t.ok(asyncGenFn instanceof $AsyncGeneratorFunction, fnName + ' instanceof %AsyncGeneratorFunction%');
		t.ok($isProto($AsyncGeneratorFunctionPrototype, asyncGenFn), '%AsyncGenerator% is prototype of ' + fnName);
		t.ok($isProto($AsyncGeneratorPrototype, asyncGenFn.prototype), '%AsyncGeneratorPrototype% is prototype of ' + fnName + '.prototype');
	});

	t.end();
});

test('%ThrowTypeError%', function (t) {
	var $ThrowTypeError = GetIntrinsic('%ThrowTypeError%');

	t.equal(typeof $ThrowTypeError, 'function', 'is a function');
	t['throws'](
		$ThrowTypeError,
		TypeError,
		'%ThrowTypeError% throws a TypeError'
	);

	t.end();
});

test('allowMissing', { skip: asyncGenFns.length > 0 }, function (t) {
	t['throws'](
		function () { GetIntrinsic('%AsyncGeneratorPrototype%'); },
		TypeError,
		'throws when missing'
	);

	t.equal(
		GetIntrinsic('%AsyncGeneratorPrototype%', true),
		undefined,
		'does not throw when allowMissing'
	);

	t.end();
});


code:
1.0.0 / 2015-09-29
==================

 * chore: use eslint and es6
 * test: add test with co
 * travis: test on node(1,2,3,4)
 * feat: support promise
 * fork from supershabam/ready


code:
get-ready
=====

[![NPM version][npm-image]][npm-url]
[![build status][travis-image]][travis-url]
[![Test coverage][codecov-image]][codecov-url]
[![David deps][david-image]][david-url]
[![npm download][download-image]][download-url]

[npm-image]: https://img.shields.io/npm/v/get-ready.svg?style=flat-square
[npm-url]: https://npmjs.org/package/get-ready
[travis-image]: https://img.shields.io/travis/node-modules/ready.svg?style=flat-square
[travis-url]: https://travis-ci.org/node-modules/ready
[codecov-image]: https://codecov.io/github/node-modules/ready/coverage.svg?branch=master
[codecov-url]: https://codecov.io/github/node-modules/ready?branch=master
[david-image]: https://img.shields.io/david/node-modules/ready.svg?style=flat-square
[david-url]: https://david-dm.org/node-modules/ready
[download-image]: https://img.shields.io/npm/dm/get-ready.svg?style=flat-square
[download-url]: https://npmjs.org/package/get-ready

**Fork from [supershabam/ready](https://github.com/supershabam/ready)**

NodeJS mixin to add one-time ready event

## Purpose
Events are great. You should use events, but not for signaling ready! Ready implies state, and once you are ready, you stay ready.

This is a module for everyone who has bound an event handler.on('ready', function() {}) that doesn't execute because you added the handler after the 'ready' event already fired.

## Warning
If you use this mixin, you must have 'ready', '_ready', and '_readyCallbacks' available on your class. Ready will stomp on these variables if you're trying to use them in your class.

## Example
```javascript
var ready = require('ready');

// example class that uses Ready
function MyClass() {
  this.someProperty = 'some value';
}
ready.mixin(MyClass.prototype);

// Normal class prototype functions
MyClass.prototype.doSomeWork = function() {};

// Create a new class that uses ready mixin
var myClass = new MyClass();

// Add callback for when myClass is ready
myClass.ready(function() {
  console.log('I am now ready');
});

myClass.doSomeWork();

// We are now ready, fire callbacks!
myClass.ready(true);

// Adding a new callback once we're already ready gets executed immediately
myClass.ready(function() {
  console.log('I came late to the party, but I will still execute.');
});

// Ok, you can set the ready state to false now as well... for whatever reason
myClass.ready(false);
myClass.ready(function() {
  console.log('I will not fire until you set ready to true again.');
});
```

## License

[MIT](LICENSE)


code:
'use strict';

function ready(flagOrFunction) {
  this._ready = !!this._ready;
  this._readyCallbacks = this._readyCallbacks || [];

  if (arguments.length === 0) {
    // return a promise
    // support `this.ready().then(onready);` and `yield this.ready()`;
    return new Promise(function (resolve) {
      if (this._ready) {
        return resolve();
      }
      this._readyCallbacks.push(resolve);
    }.bind(this));
  } else if (typeof flagOrFunction === 'function') {
    this._readyCallbacks.push(flagOrFunction);
  } else {
    this._ready = !!flagOrFunction;
  }

  if (this._ready) {
    this._readyCallbacks.splice(0, Infinity).forEach(function(callback) {
      process.nextTick(callback);
    });
  }
}

function mixin(object) {
  object.ready = ready;
}

module.exports = mixin;
module.exports.mixin = mixin;


get-ready

description: mixin to add one-time ready event callback handler

lint: eslint index.js test

test: mocha -r thunk-mocha test/*.test.js

test-cov: istanbul cover node_modules/.bin/_mocha -- -r thunk-mocha test/*.test.js

keywords: ready once event


code:
'use strict';
const {PassThrough} = require('stream');

module.exports = options => {
	options = Object.assign({}, options);

	const {array} = options;
	let {encoding} = options;
	const buffer = encoding === 'buffer';
	let objectMode = false;

	if (array) {
		objectMode = !(encoding || buffer);
	} else {
		encoding = encoding || 'utf8';
	}

	if (buffer) {
		encoding = null;
	}

	let len = 0;
	const ret = [];
	const stream = new PassThrough({objectMode});

	if (encoding) {
		stream.setEncoding(encoding);
	}

	stream.on('data', chunk => {
		ret.push(chunk);

		if (objectMode) {
			len = ret.length;
		} else {
			len += chunk.length;
		}
	});

	stream.getBufferedValue = () => {
		if (array) {
			return ret;
		}

		return buffer ? Buffer.concat(ret, len) : ret.join('');
	};

	stream.getBufferedLength = () => len;

	return stream;
};


code:
'use strict';
const pump = require('pump');
const bufferStream = require('./buffer-stream');

class MaxBufferError extends Error {
	constructor() {
		super('maxBuffer exceeded');
		this.name = 'MaxBufferError';
	}
}

function getStream(inputStream, options) {
	if (!inputStream) {
		return Promise.reject(new Error('Expected a stream'));
	}

	options = Object.assign({maxBuffer: Infinity}, options);

	const {maxBuffer} = options;

	let stream;
	return new Promise((resolve, reject) => {
		const rejectPromise = error => {
			if (error) { // A null check
				error.bufferedData = stream.getBufferedValue();
			}
			reject(error);
		};

		stream = pump(inputStream, bufferStream(options), error => {
			if (error) {
				rejectPromise(error);
				return;
			}

			resolve();
		});

		stream.on('data', () => {
			if (stream.getBufferedLength() > maxBuffer) {
				rejectPromise(new MaxBufferError());
			}
		});
	}).then(() => stream.getBufferedValue());
}

module.exports = getStream;
module.exports.buffer = (stream, options) => getStream(stream, Object.assign({}, options, {encoding: 'buffer'}));
module.exports.array = (stream, options) => getStream(stream, Object.assign({}, options, {array: true}));
module.exports.MaxBufferError = MaxBufferError;


get-stream

description: Get a stream as a string, buffer, or array

repository: sindresorhus/get-stream

test: xo && ava

keywords: get stream promise concat string text buffer read data consume readable readablestream array object


code:
# get-stream [![Build Status](https://travis-ci.org/sindresorhus/get-stream.svg?branch=master)](https://travis-ci.org/sindresorhus/get-stream)

> Get a stream as a string, buffer, or array

## Install

```
$ npm install get-stream
```

## Usage

```js
const fs = require('fs');
const getStream = require('get-stream');

(async () => {
	const stream = fs.createReadStream('unicorn.txt');

	console.log(await getStream(stream));
	/*
	              ,,))))))));,
	           __)))))))))))))),
	\|/       -\(((((''''((((((((.
	-*-==//////((''  .     `)))))),
	/|\      ))| o    ;-.    '(((((                                  ,(,
	         ( `|    /  )    ;))))'                               ,_))^;(~
	            |   |   |   ,))((((_     _____------~~~-.        %,;(;(>';'~
	            o_);   ;    )))(((` ~---~  `::           \      %%~~)(v;(`('~
	                  ;    ''''````         `:       `:::|\,__,%%    );`'; ~
	                 |   _                )     /      `:|`----'     `-'
	           ______/\/~    |                 /        /
	         /~;;.____/;;'  /          ___--,-(   `;;;/
	        / //  _;______;'------~~~~~    /;;/\    /
	       //  | |                        / ;   \;;,\
	      (<_  | ;                      /',/-----'  _>
	       \_| ||_                     //~;~~~~~~~~~
	           `\_|                   (,~~
	                                   \~\
	                                    ~~
	*/
})();
```

## API

The methods returns a promise that resolves when the `end` event fires on the stream, indicating that there is no more data to be read. The stream is switched to flowing mode.

### getStream(stream, [options])

Get the `stream` as a string.

#### options

Type: `Object`

##### encoding

Type: `string`<br>
Default: `utf8`

[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream.

##### maxBuffer

Type: `number`<br>
Default: `Infinity`

Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `getStream.MaxBufferError` error.

### getStream.buffer(stream, [options])

Get the `stream` as a buffer.

It honors the `maxBuffer` option as above, but it refers to byte length rather than string length.

### getStream.array(stream, [options])

Get the `stream` as an array of values.

It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen:

- When `encoding` is unset, it assumes an [object mode stream](https://nodesource.com/blog/understanding-object-streams/) and collects values emitted from `stream` unmodified. In this case `maxBuffer` refers to the number of items in the array (not the sum of their sizes).

- When `encoding` is set to `buffer`, it collects an array of buffers. `maxBuffer` refers to the summed byte lengths of every buffer in the array.

- When `encoding` is set to anything else, it collects an array of strings. `maxBuffer` refers to the summed character lengths of every string in the array.

## Errors

If the input stream emits an `error` event, the promise will be rejected with the error. The buffered data will be attached to the `bufferedData` property of the error.

```js
(async () => {
	try {
		await getStream(streamThatErrorsAtTheEnd('unicorn'));
	} catch (error) {
		console.log(error.bufferedData);
		//=> 'unicorn'
	}
})()
```

## FAQ

### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)?

This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, buffer, or array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package.

## Related

- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer

## License

MIT © [Sindre Sorhus](https://sindresorhus.com)


code:
# glob-parent

[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][ci-image]][ci-url] [![Coveralls Status][coveralls-image]][coveralls-url]

Extract the non-magic parent path from a glob string.

## Usage

```js
var globParent = require('glob-parent');

globParent('path/to/*.js'); // 'path/to'
globParent('/root/path/to/*.js'); // '/root/path/to'
globParent('/*.js'); // '/'
globParent('*.js'); // '.'
globParent('**/*.js'); // '.'
globParent('path/{to,from}'); // 'path'
globParent('path/!(to|from)'); // 'path'
globParent('path/?(to|from)'); // 'path'
globParent('path/+(to|from)'); // 'path'
globParent('path/*(to|from)'); // 'path'
globParent('path/@(to|from)'); // 'path'
globParent('path/**/*'); // 'path'

// if provided a non-glob path, returns the nearest dir
globParent('path/foo/bar.js'); // 'path/foo'
globParent('path/foo/'); // 'path/foo'
globParent('path/foo'); // 'path' (see issue #3 for details)
```

## API

### `globParent(maybeGlobString, [options])`

Takes a string and returns the part of the path before the glob begins. Be aware of Escaping rules and Limitations below.

#### options

```js
{
  // Disables the automatic conversion of slashes for Windows
  flipBackslashes: true;
}
```

## Escaping

The following characters have special significance in glob patterns and must be escaped if you want them to be treated as regular path characters:

- `?` (question mark) unless used as a path segment alone
- `*` (asterisk)
- `|` (pipe)
- `(` (opening parenthesis)
- `)` (closing parenthesis)
- `{` (opening curly brace)
- `}` (closing curly brace)
- `[` (opening bracket)
- `]` (closing bracket)

**Example**

```js
globParent('foo/[bar]/'); // 'foo'
globParent('foo/\\[bar]/'); // 'foo/[bar]'
```

## Limitations

### Braces & Brackets

This library attempts a quick and imperfect method of determining which path
parts have glob magic without fully parsing/lexing the pattern. There are some
advanced use cases that can trip it up, such as nested braces where the outer
pair is escaped and the inner one contains a path separator. If you find
yourself in the unlikely circumstance of being affected by this or need to
ensure higher-fidelity glob handling in your library, it is recommended that you
pre-process your input with [expand-braces] and/or [expand-brackets].

### Windows

Backslashes are not valid path separators for globs. If a path with backslashes
is provided anyway, for simple cases, glob-parent will replace the path
separator for you and return the non-glob parent path (now with
forward-slashes, which are still valid as Windows path separators).

This cannot be used in conjunction with escape characters.

```js
// BAD
globParent('C:\\Program Files \\(x86\\)\\*.ext'); // 'C:/Program Files /(x86/)'

// GOOD
globParent('C:/Program Files\\(x86\\)/*.ext'); // 'C:/Program Files (x86)'
```

If you are using escape characters for a pattern without path parts (i.e.
relative to `cwd`), prefix with `./` to avoid confusing glob-parent.

```js
// BAD
globParent('foo \\[bar]'); // 'foo '
globParent('foo \\[bar]*'); // 'foo '

// GOOD
globParent('./foo \\[bar]'); // 'foo [bar]'
globParent('./foo \\[bar]*'); // '.'
```

## License

ISC

[downloads-image]: https://img.shields.io/npm/dm/glob-parent.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/glob-parent
[npm-image]: https://img.shields.io/npm/v/glob-parent.svg?style=flat-square

[ci-url]: https://github.com/gulpjs/glob-parent/actions?query=workflow:dev
[ci-image]: https://img.shields.io/github/workflow/status/gulpjs/glob-parent/dev?style=flat-square

[coveralls-url]: https://coveralls.io/r/gulpjs/glob-parent
[coveralls-image]: https://img.shields.io/coveralls/gulpjs/glob-parent/master.svg?style=flat-square

[expand-braces]: https://github.com/jonschlinkert/expand-braces
[expand-brackets]: https://github.com/jonschlinkert/expand-brackets


code:
'use strict';

var isGlob = require('is-glob');
var pathPosixDirname = require('path').posix.dirname;
var isWin32 = require('os').platform() === 'win32';

var slash = '/';
var backslash = /\\/g;
var escaped = /\\([!*?|[\](){}])/g;

/**
 * @param {string} str
 * @param {Object} opts
 * @param {boolean} [opts.flipBackslashes=true]
 */
module.exports = function globParent(str, opts) {
  var options = Object.assign({ flipBackslashes: true }, opts);

  // flip windows path separators
  if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) {
    str = str.replace(backslash, slash);
  }

  // special case for strings ending in enclosure containing path separator
  if (isEnclosure(str)) {
    str += slash;
  }

  // preserves full path in case of trailing path separator
  str += 'a';

  // remove path parts that are globby
  do {
    str = pathPosixDirname(str);
  } while (isGlobby(str));

  // remove escape chars and return result
  return str.replace(escaped, '$1');
};

function isEnclosure(str) {
  var lastChar = str.slice(-1);

  var enclosureStart;
  switch (lastChar) {
    case '}':
      enclosureStart = '{';
      break;
    case ']':
      enclosureStart = '[';
      break;
    default:
      return false;
  }

  var foundIndex = str.indexOf(enclosureStart);
  if (foundIndex < 0) {
    return false;
  }

  return str.slice(foundIndex + 1, -1).includes(slash);
}

function isGlobby(str) {
  if (/\([^()]+$/.test(str)) {
    return true;
  }
  if (str[0] === '{' || str[0] === '[') {
    return true;
  }
  if (/[^\\][{[]/.test(str)) {
    return true;
  }
  return isGlob(str);
}


glob-parent

description: Extract the non-magic parent path from a glob string.

author: Gulp Team <team@gulpjs.com> (https://gulpjs.com/)

repository: gulpjs/glob-parent

lint: eslint .

test: nyc mocha --async-only

reporter: lcov text-summary

keywords: glob parent strip path dirname directory base wildcard


code:
language: node_js
node_js:
  - 0.8
  - "0.10"


code:
# Glob To Regular Expression

[![Build Status](https://travis-ci.org/fitzgen/glob-to-regexp.png?branch=master)](https://travis-ci.org/fitzgen/glob-to-regexp)

Turn a \*-wildcard style glob (`"*.min.js"`) into a regular expression
(`/^.*\.min\.js$/`)!

To match bash-like globs, eg. `?` for any single-character match, `[a-z]` for
character ranges, and `{*.html, *.js}` for multiple alternatives, call with
`{ extended: true }`.

To obey [globstars `**`](https://github.com/isaacs/node-glob#glob-primer) rules set option `{globstar: true}`.
NOTE: This changes the behavior of `*` when `globstar` is `true` as shown below:
When `{globstar: true}`: `/foo/**` will match any string that starts with `/foo/`
like `/foo/index.htm`, `/foo/bar/baz.txt`, etc.  Also, `/foo/**/*.txt` will match
any string that starts with `/foo/` and ends with `.txt` like `/foo/bar.txt`,
`/foo/bar/baz.txt`, etc.
Whereas `/foo/*` (single `*`, not a globstar) will match strings that start with
`/foo/` like `/foo/index.htm`, `/foo/baz.txt` but will not match strings that
contain a `/` to the right like `/foo/bar/baz.txt`, `/foo/bar/baz/qux.dat`, etc.

Set flags on the resulting `RegExp` object by adding the `flags` property to the option object, eg `{ flags: "i" }` for ignoring case.

## Install

    npm install glob-to-regexp

## Usage
```js
var globToRegExp = require('glob-to-regexp');
var re = globToRegExp("p*uck");
re.test("pot luck"); // true
re.test("pluck"); // true
re.test("puck"); // true

re = globToRegExp("*.min.js");
re.test("http://example.com/jquery.min.js"); // true
re.test("http://example.com/jquery.min.js.map"); // false

re = globToRegExp("*/www/*.js");
re.test("http://example.com/www/app.js"); // true
re.test("http://example.com/www/lib/factory-proxy-model-observer.js"); // true

// Extended globs
re = globToRegExp("*/www/{*.js,*.html}", { extended: true });
re.test("http://example.com/www/app.js"); // true
re.test("http://example.com/www/index.html"); // true
```

## License

Copyright (c) 2013, Nick Fitzgerald

All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this
  list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this
  list of conditions and the following disclaimer in the documentation and/or
  other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


code:
module.exports = function (glob, opts) {
  if (typeof glob !== 'string') {
    throw new TypeError('Expected a string');
  }

  var str = String(glob);

  // The regexp we are building, as a string.
  var reStr = "";

  // Whether we are matching so called "extended" globs (like bash) and should
  // support single character matching, matching ranges of characters, group
  // matching, etc.
  var extended = opts ? !!opts.extended : false;

  // When globstar is _false_ (default), '/foo/*' is translated a regexp like
  // '^\/foo\/.*$' which will match any string beginning with '/foo/'
  // When globstar is _true_, '/foo/*' is translated to regexp like
  // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
  // which does not have a '/' to the right of it.
  // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
  // these will not '/foo/bar/baz', '/foo/bar/baz.txt'
  // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
  // globstar is _false_
  var globstar = opts ? !!opts.globstar : false;

  // If we are doing extended matching, this boolean is true when we are inside
  // a group (eg {*.html,*.js}), and false otherwise.
  var inGroup = false;

  // RegExp flags (eg "i" ) to pass in to RegExp constructor.
  var flags = opts && typeof( opts.flags ) === "string" ? opts.flags : "";

  var c;
  for (var i = 0, len = str.length; i < len; i++) {
    c = str[i];

    switch (c) {
    case "/":
    case "$":
    case "^":
    case "+":
    case ".":
    case "(":
    case ")":
    case "=":
    case "!":
    case "|":
      reStr += "\\" + c;
      break;

    case "?":
      if (extended) {
        reStr += ".";
	    break;
      }

    case "[":
    case "]":
      if (extended) {
        reStr += c;
	    break;
      }

    case "{":
      if (extended) {
        inGroup = true;
	    reStr += "(";
	    break;
      }

    case "}":
      if (extended) {
        inGroup = false;
	    reStr += ")";
	    break;
      }

    case ",":
      if (inGroup) {
        reStr += "|";
	    break;
      }
      reStr += "\\" + c;
      break;

    case "*":
      // Move over all consecutive "*"'s.
      // Also store the previous and next characters
      var prevChar = str[i - 1];
      var starCount = 1;
      while(str[i + 1] === "*") {
        starCount++;
        i++;
      }
      var nextChar = str[i + 1];

      if (!globstar) {
        // globstar is disabled, so treat any number of "*" as one
        reStr += ".*";
      } else {
        // globstar is enabled, so determine if this is a globstar segment
        var isGlobstar = starCount > 1                      // multiple "*"'s
          && (prevChar === "/" || prevChar === undefined)   // from the start of the segment
          && (nextChar === "/" || nextChar === undefined)   // to the end of the segment

        if (isGlobstar) {
          // it's a globstar, so match zero or more path segments
          reStr += "((?:[^/]*(?:\/|$))*)";
          i++; // move over the "/"
        } else {
          // it's not a globstar, so only match one path segment
          reStr += "([^/]*)";
        }
      }
      break;

    default:
      reStr += c;
    }
  }

  // When regexp 'g' flag is specified don't
  // constrain the regular expression with ^ & $
  if (!flags || !~flags.indexOf('g')) {
    reStr = "^" + reStr + "$";
  }

  return new RegExp(reStr, flags);
};


glob-to-regexp

description: Convert globs to regular expressions

test: node test.js

keywords:
regexp
glob
regexps
regular expressions
regular expression
wildcard

author: Nick Fitzgerald <fitzgen@gmail.com>


code:
var globToRegexp = require("./index.js");
var assert = require("assert");

function assertMatch(glob, str, opts) {
  //console.log(glob, globToRegexp(glob, opts));
  assert.ok(globToRegexp(glob, opts).test(str));
}

function assertNotMatch(glob, str, opts) {
  //console.log(glob, globToRegexp(glob, opts));
  assert.equal(false, globToRegexp(glob, opts).test(str));
}

function test(globstar) {
  // Match everything
  assertMatch("*", "foo");
  assertMatch("*", "foo", { flags: 'g' });

  // Match the end
  assertMatch("f*", "foo");
  assertMatch("f*", "foo", { flags: 'g' });

  // Match the start
  assertMatch("*o", "foo");
  assertMatch("*o", "foo", { flags: 'g' });

  // Match the middle
  assertMatch("f*uck", "firetruck");
  assertMatch("f*uck", "firetruck", { flags: 'g' });

  // Don't match without Regexp 'g'
  assertNotMatch("uc", "firetruck");
  // Match anywhere with RegExp 'g'
  assertMatch("uc", "firetruck", { flags: 'g' });

  // Match zero characters
  assertMatch("f*uck", "fuck");
  assertMatch("f*uck", "fuck", { flags: 'g' });

  // More complex matches
  assertMatch("*.min.js", "http://example.com/jquery.min.js", {globstar: false});
  assertMatch("*.min.*", "http://example.com/jquery.min.js", {globstar: false});
  assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js", {globstar: false});

  // More complex matches with RegExp 'g' flag (complex regression)
  assertMatch("*.min.*", "http://example.com/jquery.min.js", { flags: 'g' });
  assertMatch("*.min.js", "http://example.com/jquery.min.js", { flags: 'g' });
  assertMatch("*/js/*.js", "http://example.com/js/jquery.min.js", { flags: 'g' });

  // Test string  "\\\\/$^+?.()=!|{},[].*"  represents  <glob>\\/$^+?.()=!|{},[].*</glob>
  // The equivalent regex is:  /^\\\/\$\^\+\?\.\(\)\=\!\|\{\}\,\[\]\..*$/
  // Both glob and regex match:  \/$^+?.()=!|{},[].*
  var testStr = "\\\\/$^+?.()=!|{},[].*";
  var targetStr = "\\/$^+?.()=!|{},[].*";
  assertMatch(testStr, targetStr);
  assertMatch(testStr, targetStr, { flags: 'g' });

  // Equivalent matches without/with using RegExp 'g'
  assertNotMatch(".min.", "http://example.com/jquery.min.js");
  assertMatch("*.min.*", "http://example.com/jquery.min.js");
  assertMatch(".min.", "http://example.com/jquery.min.js", { flags: 'g' });

  assertNotMatch("http:", "http://example.com/jquery.min.js");
  assertMatch("http:*", "http://example.com/jquery.min.js");
  assertMatch("http:", "http://example.com/jquery.min.js", { flags: 'g' });

  assertNotMatch("min.js", "http://example.com/jquery.min.js");
  assertMatch("*.min.js", "http://example.com/jquery.min.js");
  assertMatch("min.js", "http://example.com/jquery.min.js", { flags: 'g' });

  // Match anywhere (globally) using RegExp 'g'
  assertMatch("min", "http://example.com/jquery.min.js", { flags: 'g' });
  assertMatch("/js/", "http://example.com/js/jquery.min.js", { flags: 'g' });

  assertNotMatch("/js*jq*.js", "http://example.com/js/jquery.min.js");
  assertMatch("/js*jq*.js", "http://example.com/js/jquery.min.js", { flags: 'g' });

  // Extended mode

  // ?: Match one character, no more and no less
  assertMatch("f?o", "foo", { extended: true });
  assertNotMatch("f?o", "fooo", { extended: true });
  assertNotMatch("f?oo", "foo", { extended: true });

  // ?: Match one character with RegExp 'g'
  assertMatch("f?o", "foo", { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("f?o", "fooo", { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("f?o?", "fooo", { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("?fo", "fooo", { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("f?oo", "foo", { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("foo?", "foo", { extended: true,  globstar: globstar, flags: 'g' });

  // []: Match a character range
  assertMatch("fo[oz]", "foo", { extended: true });
  assertMatch("fo[oz]", "foz", { extended: true });
  assertNotMatch("fo[oz]", "fog", { extended: true });

  // []: Match a character range and RegExp 'g' (regresion)
  assertMatch("fo[oz]", "foo", { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("fo[oz]", "foz", { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("fo[oz]", "fog", { extended: true,  globstar: globstar, flags: 'g' });

  // {}: Match a choice of different substrings
  assertMatch("foo{bar,baaz}", "foobaaz", { extended: true });
  assertMatch("foo{bar,baaz}", "foobar", { extended: true });
  assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true });
  assertMatch("foo{bar,b*z}", "foobuzz", { extended: true });

  // {}: Match a choice of different substrings and RegExp 'g' (regression)
  assertMatch("foo{bar,baaz}", "foobaaz", { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("foo{bar,baaz}", "foobar", { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("foo{bar,baaz}", "foobuzz", { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("foo{bar,b*z}", "foobuzz", { extended: true,  globstar: globstar, flags: 'g' });

  // More complex extended matches
  assertMatch("http://?o[oz].b*z.com/{*.js,*.html}",
              "http://foo.baaz.com/jquery.min.js",
              { extended: true });
  assertMatch("http://?o[oz].b*z.com/{*.js,*.html}",
              "http://moz.buzz.com/index.html",
              { extended: true });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://moz.buzz.com/index.htm",
                 { extended: true });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://moz.bar.com/index.html",
                 { extended: true });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://flozz.buzz.com/index.html",
                 { extended: true });

  // More complex extended matches and RegExp 'g' (regresion)
  assertMatch("http://?o[oz].b*z.com/{*.js,*.html}",
              "http://foo.baaz.com/jquery.min.js",
              { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("http://?o[oz].b*z.com/{*.js,*.html}",
              "http://moz.buzz.com/index.html",
              { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://moz.buzz.com/index.htm",
                 { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://moz.bar.com/index.html",
                 { extended: true,  globstar: globstar, flags: 'g' });
  assertNotMatch("http://?o[oz].b*z.com/{*.js,*.html}",
                 "http://flozz.buzz.com/index.html",
                 { extended: true,  globstar: globstar, flags: 'g' });

  // globstar
  assertMatch("http://foo.com/**/{*.js,*.html}",
              "http://foo.com/bar/jquery.min.js",
              { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("http://foo.com/**/{*.js,*.html}",
              "http://foo.com/bar/baz/jquery.min.js",
              { extended: true,  globstar: globstar, flags: 'g' });
  assertMatch("http://foo.com/**",
              "http://foo.com/bar/baz/jquery.min.js",
              { extended: true,  globstar: globstar, flags: 'g' });

  // Remaining special chars should still match themselves
  // Test string  "\\\\/$^+.()=!|,.*"  represents  <glob>\\/$^+.()=!|,.*</glob>
  // The equivalent regex is:  /^\\\/\$\^\+\.\(\)\=\!\|\,\..*$/
  // Both glob and regex match:  \/$^+.()=!|,.*
  var testExtStr = "\\\\/$^+.()=!|,.*";
  var targetExtStr = "\\/$^+.()=!|,.*";
  assertMatch(testExtStr, targetExtStr, { extended: true });
  assertMatch(testExtStr, targetExtStr, { extended: true,  globstar: globstar, flags: 'g' });
}

// regression
// globstar false
test(false)
// globstar true
test(true);

// globstar specific tests
assertMatch("/foo/*", "/foo/bar.txt", {globstar: true });
assertMatch("/foo/**", "/foo/baz.txt", {globstar: true });
assertMatch("/foo/**", "/foo/bar/baz.txt", {globstar: true });
assertMatch("/foo/*/*.txt", "/foo/bar/baz.txt", {globstar: true });
assertMatch("/foo/**/*.txt", "/foo/bar/baz.txt", {globstar: true });
assertMatch("/foo/**/*.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertMatch("/foo/**/bar.txt", "/foo/bar.txt", {globstar: true });
assertMatch("/foo/**/**/bar.txt", "/foo/bar.txt", {globstar: true });
assertMatch("/foo/**/*/baz.txt", "/foo/bar/baz.txt", {globstar: true });
assertMatch("/foo/**/*.txt", "/foo/bar.txt", {globstar: true });
assertMatch("/foo/**/**/*.txt", "/foo/bar.txt", {globstar: true });
assertMatch("/foo/**/*/*.txt", "/foo/bar/baz.txt", {globstar: true });
assertMatch("**/*.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertMatch("**/foo.txt", "foo.txt", {globstar: true });
assertMatch("**/*.txt", "foo.txt", {globstar: true });

assertNotMatch("/foo/*", "/foo/bar/baz.txt", {globstar: true });
assertNotMatch("/foo/*.txt", "/foo/bar/baz.txt", {globstar: true });
assertNotMatch("/foo/*/*.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertNotMatch("/foo/*/bar.txt", "/foo/bar.txt", {globstar: true });
assertNotMatch("/foo/*/*/baz.txt", "/foo/bar/baz.txt", {globstar: true });
assertNotMatch("/foo/**.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertNotMatch("/foo/bar**/*.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertNotMatch("/foo/bar**", "/foo/bar/baz.txt", {globstar: true });
assertNotMatch("**/.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertNotMatch("*/*.txt", "/foo/bar/baz/qux.txt", {globstar: true });
assertNotMatch("*/*.txt", "foo.txt", {globstar: true });

assertNotMatch("http://foo.com/*",
               "http://foo.com/bar/baz/jquery.min.js",
               { extended: true,  globstar: true });
assertNotMatch("http://foo.com/*",
               "http://foo.com/bar/baz/jquery.min.js",
               { globstar: true });

assertMatch("http://foo.com/*",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: false });
assertMatch("http://foo.com/**",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: true });

assertMatch("http://foo.com/*/*/jquery.min.js",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: true });
assertMatch("http://foo.com/**/jquery.min.js",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: true });
assertMatch("http://foo.com/*/*/jquery.min.js",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: false });
assertMatch("http://foo.com/*/jquery.min.js",
            "http://foo.com/bar/baz/jquery.min.js",
            { globstar: false });
assertNotMatch("http://foo.com/*/jquery.min.js",
               "http://foo.com/bar/baz/jquery.min.js",
               { globstar: true });

console.log("Ok!");