[
  {
    "path": ".github/workflows/ci.yaml",
    "content": "name: CI\non:\n  - push\n  - pull_request\njobs:\n  test:\n    name: Node.js ${{ matrix.node-version }}\n    runs-on: ubuntu-latest\n    strategy:\n      matrix:\n        node-version:\n          - 16\n    steps:\n      - uses: actions/checkout@v3\n      - uses: actions/setup-node@v3\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: Install dependencies\n        run: yarn\n      - name: Run tests\n        run: yarn run test\n"
  },
  {
    "path": ".gitignore",
    "content": "# dependencies\nnode_modules\n\n# logs\nnpm-debug.log\nyarn-error.log\n\n# coverage\ncoverage\n.nyc_output\n\n# build\ndist/"
  },
  {
    "path": ".npmrc",
    "content": "save-exact = true\nstrict-peer-dependencies=false"
  },
  {
    "path": ".yarnrc",
    "content": "save-prefix \"\"\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2023 Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "errors/invalid-entry.md",
    "content": "# Invalid Entry File\n\n#### Why This Error Occurred\n\nWhen the `micro` command was ran, you passed a path to a file or directory that contains invalid code. This code might either not be syntactically correct or throw an error on execution.\n\n#### Possible Ways to Fix It\n\nThe only way to avoid this error is to ensure that the entry file to your microservice (the one passed to the `micro`) command contains code that doesn't contain any syntax errors and doesn't throw an error when executed.\n\n### Useful Links\n\n- [JSLint](http://www.jslint.com) - Validate the code of your entry file\n"
  },
  {
    "path": "errors/invalid-package-json.md",
    "content": "# Invalid `package.json` File\n\n#### Why This Error Occurred\n\nThe content of the `package.json` file that's located near the entry file of your microservice is not valid. This means that it's not correct JSON syntax.\n\n#### Possible Ways to Fix It\n\nThe only way to avoid this error is to ensure that the file contains a valid JSON object. You can use [JSONLint](https://jsonlint.com) to find any possible errors.\n"
  },
  {
    "path": "errors/invalid-port-socket.md",
    "content": "# Port and socket provided\n\n#### Why This Error Occurred\n\nWhen the `micro` command was ran, you passed both a port and a socket. Node.js can only listen to either a port or a socket, not both.\n\n#### Possible Ways to Fix It\n\nOnly provide one of the arguments. If both are needed you can start 2 instances of micro with different arguments.\n"
  },
  {
    "path": "errors/invalid-server-port.md",
    "content": "# Invalid Server Port\n\n#### Why This Error Occurred\n\nWhen the `micro` command was ran, you supplied the port flag although it is\nnot a valid number.\n\n\n#### Possible Ways to Fix It\n\nThe port must be a valid number between 1 and 65535. Although, remember some are\nreserved to the operating system and others not in userland (only accessible\nwith administrator access).\n"
  },
  {
    "path": "errors/invalid-socket.md",
    "content": "# Invalid socket\n\n#### Why This Error Occurred\n\nWhen the `micro` command was ran, you passed `-s` or `--socket` without a value.\n\n#### Possible Ways to Fix It\n\nRun `micro` with a value:\n\n```\nmicro -s '/tmp/micro.sock'\n```\n"
  },
  {
    "path": "errors/no-export.md",
    "content": "# No Export\n\n#### Why This Error Occurred\n\nWhen `micro` tried to ran your microservice, it noticed that your code didn't export anything that could be run.\n\n#### Possible Ways to Fix It\n\nYou need to ensure that the entry file you passed to the `micro` command contains an export - like this one:\n\n```js\nmodule.exports = (req, res) => {\n  res.end('test');\n};\n```\n\n### Useful Links\n\n- [List of examples](https://github.com/vercel/micro/tree/master/examples)\n- [Usage information](https://github.com/vercel/micro#usage)\n"
  },
  {
    "path": "errors/path-missing.md",
    "content": "# Path Missing\n\n#### Why This Error Occurred\n\nWhen running the `micro` command, you need to pass a path to a file or directory that contains your microservice. If you don't define one, it will detect the entry file to your code using the `main` property inside the `package.json` file in the directory where the command is run.\n\n#### Possible Ways to Fix It\n\n- Enter the path to your microservice in the `main` property inside `package.json`\n- Specify the path of your entry file when running the command: `micro <path>`\n"
  },
  {
    "path": "errors/path-not-existent.md",
    "content": "# Path Not Existent\n\n#### Why This Error Occurred\n\nWhen the `micro` command ran, you passed it a path to a file or directory that does't exist. This is how such a command can look like:\n\n```bash\nmicro <not-existing-path>\n```\n\n#### Possible Ways to Fix It\n\nThe only way to fix this is to pass a path to a file or directory that exists and contains a working microservice.\n"
  },
  {
    "path": "examples/external-api-call/README.md",
    "content": "# External API call example\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/external-api-call\ncd external-api-call\n```\n\nInstall it and run:\n\n```bash\nnpm install\nnpm run start\n```\n\n## The idea behind the example\n\nShows how to get data from an external api using async/await.\n"
  },
  {
    "path": "examples/external-api-call/index.js",
    "content": "const fetch = require('node-fetch');\n\nmodule.exports = async () => {\n\tconst response = await fetch('https://api.example.com');\n\tconst json = await response.json();\n\n\treturn json;\n};\n"
  },
  {
    "path": "examples/external-api-call/package.json",
    "content": "{\n  \"name\": \"external-api-call\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"micro\"\n  },\n  \"dependencies\": {\n    \"micro\": \"latest\",\n    \"node-fetch\": \"latest\"\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "examples/json-body-parsing/README.md",
    "content": "# Parse JSON body example\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/json-body-parsing\ncd json-body-parsing\n```\n\nInstall it and run:\n\n```bash\nnpm install\nnpm run start\n```\n\n## The idea behind the example\n\nShows how to get data posted to your microservice using async/await.\n"
  },
  {
    "path": "examples/json-body-parsing/index.js",
    "content": "const {json} = require('micro');\n\nmodule.exports = async req => {\n\tconst data = await json(req);\n\tconsole.log(data);\n\n\treturn 'Data logged to your console';\n};\n"
  },
  {
    "path": "examples/json-body-parsing/package.json",
    "content": "{\n  \"name\": \"json-body-parsing\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"micro\"\n  },\n  \"dependencies\": {\n    \"micro\": \"latest\"\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "examples/socket.io-chat-app/README.md",
    "content": "# Chat app with socket.io\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/socket.io-chat-app\ncd socket.io-chat-app\n```\n\nInstall it and run:\n\n```bash\nnpm install\nnpm run start\n```\n\n## The idea behind the example\n\nShows how to make use of socket.io with micro, to deploy on now.\n"
  },
  {
    "path": "examples/socket.io-chat-app/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <title>Socket.IO Chat Example</title>\n  <link rel=\"stylesheet\" href=\"style.css\">\n</head>\n<body>\n\t<style>\n\t\t* { margin: 0; padding: 0; box-sizing: border-box; }\n\t\tbody { font: 13px Helvetica, Arial; }\n\t\tform { background: grey; padding: 10px; position: fixed; bottom: 0; width: 100%; }\n\t\tform input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }\n\t\tform button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }\n\t\t#messages { list-style-type: none; margin: 0; padding: 0; }\n\t\t#messages li { padding: 5px 10px; }\n\t\t#messages li:nth-child(odd) { background: #eee; }\n\t</style>\n\n\t<ul id=\"messages\"></ul>\n\n\t<form action=\"\">\n\t\t<input id=\"m\" autocomplete=\"off\" /><button>Send</button>\n\t</form>\n\n\t<script src=\"https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.min.js\"></script>\n\n\t<script>\n\t\tvar socket = io()\n\n\t\tdocument.querySelector('form').addEventListener('submit', (e) => {\n\t\t\te.preventDefault();\n\t\t\tsocket.emit('chat message', document.getElementById('m').value);\n\t\t\tdocument.getElementById('m').value = '';\n\t\t});\n\n\t\tsocket.on('chat message', msg => {\n\t\t\tdocument.getElementById('messages').insertAdjacentHTML('beforeend', `<li>${msg}</li>`);\n\t\t});\n\t</script>\n</body>\n</html>\n"
  },
  {
    "path": "examples/socket.io-chat-app/index.js",
    "content": "const micro = require('micro');\nconst fs = require('fs');\nconst path = require('path');\n\nconst document = path.join(__dirname, 'index.html');\nconst html = fs.readFileSync(document);\n\nconst server = micro(async (req, res) => {\n\tconsole.log('Serving index.html');\n\tres.end(html);\n});\n\nconst io = require('socket.io')(server);\n\n// socket-io handlers are in websocket-server.js\nrequire('./websocket-server.js')(io);\n\nserver.listen(4000, () => console.log('Listening on localhost:4000'));\n"
  },
  {
    "path": "examples/socket.io-chat-app/package.json",
    "content": "{\n  \"name\": \"chatnow\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node .\"\n  },\n  \"author\": \"Lucas Kostka\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"micro\": \"latest\",\n    \"socket.io\": \"1.7.3\"\n  }\n}\n"
  },
  {
    "path": "examples/socket.io-chat-app/websocket-server.js",
    "content": "module.exports = function startServer(io) {\n\tio.on('connection', socket => {\n\t\tconsole.log('a user connected');\n\n\t\tsocket.on('disconnect', () => {\n\t\t\tconsole.log('user disconnected');\n\t\t});\n\n\t\tsocket.on('chat message', msg => {\n\t\t\tconsole.log(`message: ${msg}`);\n\t\t\tio.emit('chat message', msg);\n\t\t});\n\t});\n};\n"
  },
  {
    "path": "examples/urlencoded-body-parsing/README.md",
    "content": "# Parse JSON body example\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/urlencoded-body-parsing\ncd urlencoded-body-parsing\n```\n\nInstall it and run:\n\n```bash\nnpm install\nnpm run start\n```\n\n## The idea behind the example\n\nShows how to get urlencoded (html form post) data posted to your microservice using async/await.\n"
  },
  {
    "path": "examples/urlencoded-body-parsing/index.js",
    "content": "const parse = require('urlencoded-body-parser');\n\nmodule.exports = async req => {\n\tconst data = await parse(req);\n\tconsole.log(data);\n\n\treturn 'Data logged to your console';\n};\n"
  },
  {
    "path": "examples/urlencoded-body-parsing/package.json",
    "content": "{\n  \"name\": \"urlencoded-body-parsing\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"micro\"\n  },\n  \"dependencies\": {\n    \"micro\": \"latest\",\n    \"urlencoded-body-parser\": \"latest\"\n  },\n  \"author\": \"\",\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "examples/with-graphql-request/README.md",
    "content": "# GraphQL Request example\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/with-graphql-request\ncd with-graphql-request\n```\n\nInstall it and run:\n\n```bash\n$ yarn install # (or `$ npm install`)\n$ yarn run start # (or `$ npm run start`)\n```\n\n## The idea behind the example\n\nShows how to get data from a GraphQL endpoint using [GraphQL Request](https://github.com/graphcool/graphql-request).\nThis example relies on [graph.cool](https://www.graph.cool) for its GraphQL backend.\n"
  },
  {
    "path": "examples/with-graphql-request/index.js",
    "content": "const {request} = require('graphql-request');\nconst endpoint = 'https://api.graph.cool/simple/v1/movies';\n\n// Prepare simple query\nconst query = `\n  query Movie($title: String!) {\n    movie: Movie(title: $title) {\n      releaseDate\n      actors {\n        name\n      }\n    }\n  }\n`;\n\nmodule.exports = async () => {\n\t// Perform query\n\tconst data = await request(endpoint, query, {title: 'Inception'});\n\n\t// Return Movie\n\treturn data.movie;\n};\n"
  },
  {
    "path": "examples/with-graphql-request/package.json",
    "content": "{\n  \"name\": \"with-graphql-request\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"micro\"\n  },\n  \"dependencies\": {\n    \"graphql-request\": \"latest\",\n    \"micro\": \"latest\"\n  },\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "examples/with-https/README.md",
    "content": "# Micro app with HTTPS\n\n## How to use\n\nDownload the example [or clone the repo](https://github.com/vercel/micro):\n\n```bash\ncurl https://codeload.github.com/vercel/micro/tar.gz/master | tar -xz --strip=2 micro-master/examples/with-https\ncd socket.io-chat-app\n```\n\nInstall it and run:\n\n```bash\nnpm install\nnpm run start\n```\n\n## The idea behind the example\n\nShows how to make use of HTTPS requests with micro.\n"
  },
  {
    "path": "examples/with-https/index.js",
    "content": "const https = require('https');\nconst {run, send} = require('micro');\n\nconst {key, cert, passphrase} = require('openssl-self-signed-certificate');\n\nconst PORT = process.env.PORT || 3443;\n\nconst options = {key, cert, passphrase};\n\nconst microHttps = fn => https.createServer(options, (req, res) => run(req, res, fn));\n\nconst server = microHttps(async (req, res) => {\n\tsend(res, 200, {encrypted: req.client.encrypted});\n});\n\nserver.listen(PORT);\nconsole.log(`Listening on https://localhost:${PORT}`);\n"
  },
  {
    "path": "examples/with-https/package.json",
    "content": "{\n  \"name\": \"with-https\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"scripts\": {\n    \"start\": \"node .\"\n  },\n  \"dependencies\": {\n    \"micro\": \"latest\",\n    \"openssl-self-signed-certificate\": \"^1.1.6\"\n  }\n}\n"
  },
  {
    "path": "lerna.json",
    "content": "{\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"packages\": [\n    \"packages/*\"\n  ],\n  \"command\": {\n    \"version\": {\n      \"exact\": true\n    },\n    \"publish\": {\n      \"npmClient\": \"npm\",\n      \"allowBranch\": [\n        \"master\",\n        \"canary\"\n      ],\n      \"registry\": \"https://registry.npmjs.org/\"\n    }\n  },\n  \"version\": \"9.4.0\"\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/*\",\n    \"test\"\n  ],\n  \"scripts\": {\n    \"prepublish\": \"lerna run prepublish\",\n    \"publish-canary\": \"lerna version prerelease --preid canary --force-publish && release --pre\",\n    \"publish-stable\": \"lerna version --force-publish\",\n    \"test\": \"cd test && yarn run test\"\n  },\n  \"license\": \"MIT\",\n  \"devDependencies\": {\n    \"lerna\": \"^3.4.0\"\n  }\n}\n"
  },
  {
    "path": "packages/micro/.eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  extends: [\n    require.resolve('@vercel/style-guide/eslint/node'),\n    require.resolve('@vercel/style-guide/eslint/typescript'),\n  ],\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./tsconfig.json'],\n  },\n  ignorePatterns: ['dist/**', 'types/**'],\n};\n"
  },
  {
    "path": "packages/micro/README.md",
    "content": "# Micro — Asynchronous HTTP microservices\n\n## Features\n\n- **Easy**: Designed for usage with `async` and `await`\n- **Fast**: Ultra-high performance (even JSON parsing is opt-in)\n- **Micro**: The whole project is ~260 lines of code\n- **Agile**: Super easy deployment and containerization\n- **Simple**: Oriented for single purpose modules (function)\n- **Standard**: Just HTTP!\n- **Explicit**: No middleware - modules declare all [dependencies](https://github.com/amio/awesome-micro)\n- **Lightweight**: With all dependencies, the package weighs less than a megabyte\n\n**Disclaimer:** Micro was created for use within containers and is not intended for use in serverless environments. For those using Vercel, this means that there is no requirement to use Micro in your projects as the benefits it provides are not applicable to the platform. Utility features provided by Micro, such as `json`, are readily available in the form of [Serverless Function helpers](https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-request-and-response-objects).\n\n## Installation\n\n**Important:** Micro is only meant to be used in production. In development, you should use [micro-dev](https://github.com/vercel/micro-dev), which provides you with a tool belt specifically tailored for developing microservices.\n\nTo prepare your microservice for running in the production environment, firstly install `micro`:\n\n```bash\nnpm install --save micro\n```\n\n## Usage\n\nCreate an `index.js` file and export a function that accepts the standard [http.IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage) and [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse) objects:\n\n```js\nmodule.exports = (req, res) => {\n  res.end('Welcome to Micro');\n};\n```\n\nMicro provides [useful helpers](https://github.com/vercel/micro#body-parsing) but also handles return values – so you can write it even shorter!\n\n```js\nmodule.exports = () => 'Welcome to Micro';\n```\n\nNext, ensure that the `main` property inside `package.json` points to your microservice (which is inside `index.js` in this example case) and add a `start` script:\n\n```json\n{\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"micro\"\n  }\n}\n```\n\nOnce all of that is done, the server can be started like this:\n\n```bash\nnpm start\n```\n\nAnd go to this URL: `http://localhost:3000` - 🎉\n\n### Command line\n\n```\n  micro - Asynchronous HTTP microservices\n\n  USAGE\n\n      $ micro --help\n      $ micro --version\n      $ micro [-l listen_uri [-l ...]] [entry_point.js]\n\n      By default micro will listen on 0.0.0.0:3000 and will look first\n      for the \"main\" property in package.json and subsequently for index.js\n      as the default entry_point.\n\n      Specifying a single --listen argument will overwrite the default, not supplement it.\n\n  OPTIONS\n\n      --help                              shows this help message\n\n      -v, --version                       displays the current version of micro\n\n      -l, --listen listen_uri             specify a URI endpoint on which to listen (see below) -\n                                          more than one may be specified to listen in multiple places\n\n  ENDPOINTS\n\n      Listen endpoints (specified by the --listen or -l options above) instruct micro\n      to listen on one or more interfaces/ports, UNIX domain sockets, or Windows named pipes.\n\n      For TCP (traditional host/port) endpoints:\n\n          $ micro -l tcp://hostname:1234\n\n      For UNIX domain socket endpoints:\n\n          $ micro -l unix:/path/to/socket.sock\n\n      For Windows named pipe endpoints:\n\n          $ micro -l pipe:\\\\.\\pipe\\PipeName\n```\n\n### `async` & `await`\n\n<p><details>\n  <summary><b>Examples</b></summary>\n  <ul><li><a href=\"./examples/external-api-call\">Fetch external api</a></li></ul>\n</details></p>\n\nMicro is built for usage with async/await.\n\n```js\nconst sleep = require('then-sleep');\n\nmodule.exports = async (req, res) => {\n  await sleep(500);\n  return 'Ready!';\n};\n```\n\n### Port Based on Environment Variable\n\nWhen you want to set the port using an environment variable you can use:\n\n```\nmicro -l tcp://0.0.0.0:$PORT\n```\n\nOptionally you can add a default if it suits your use case:\n\n```\nmicro -l tcp://0.0.0.0:${PORT-3000}\n```\n\n`${PORT-3000}` will allow a fallback to port `3000` when `$PORT` is not defined.\n\nNote that this only works in Bash.\n\n### Body parsing\n\n<p id=\"body-parsing-examples\"><details>\n  <summary><b>Examples</b></summary>\n  <ul>\n    <li><a href=\"./examples/json-body-parsing\">Parse JSON</a></li>\n    <li><a href=\"./examples/urlencoded-body-parsing\">Parse urlencoded form (html `form` tag)</a></li>\n  </ul>\n</details></p>\n\nFor parsing the incoming request body we included an async functions `buffer`, `text` and `json`\n\n```js\nconst { buffer, text, json } = require('micro');\n\nmodule.exports = async (req, res) => {\n  const buf = await buffer(req);\n  console.log(buf);\n  // <Buffer 7b 22 70 72 69 63 65 22 3a 20 39 2e 39 39 7d>\n  const txt = await text(req);\n  console.log(txt);\n  // '{\"price\": 9.99}'\n  const js = await json(req);\n  console.log(js.price);\n  // 9.99\n  return '';\n};\n```\n\n### API\n\n##### `buffer(req, { limit = '1mb', encoding = 'utf8' })`\n\n##### `text(req, { limit = '1mb', encoding = 'utf8' })`\n\n##### `json(req, { limit = '1mb', encoding = 'utf8' })`\n\n- Buffers and parses the incoming body and returns it.\n- Exposes an `async` function that can be run with `await`.\n- Can be called multiple times, as it caches the raw request body the first time.\n- `limit` is how much data is aggregated before parsing at max. Otherwise, an `Error` is thrown with `statusCode` set to `413` (see [Error Handling](#error-handling)). It can be a `Number` of bytes or [a string](https://www.npmjs.com/package/bytes) like `'1mb'`.\n- If JSON parsing fails, an `Error` is thrown with `statusCode` set to `400` (see [Error Handling](#error-handling))\n\nFor other types of data check the [examples](#body-parsing-examples)\n\n### Sending a different status code\n\nSo far we have used `return` to send data to the client. `return 'Hello World'` is the equivalent of `send(res, 200, 'Hello World')`.\n\n```js\nconst { send } = require('micro');\n\nmodule.exports = async (req, res) => {\n  const statusCode = 400;\n  const data = { error: 'Custom error message' };\n\n  send(res, statusCode, data);\n};\n```\n\n##### `send(res, statusCode, data = null)`\n\n- Use `require('micro').send`.\n- `statusCode` is a `Number` with the HTTP status code, and must always be supplied.\n- If `data` is supplied it is sent in the response. Different input types are processed appropriately, and `Content-Type` and `Content-Length` are automatically set.\n  - `Stream`: `data` is piped as an `octet-stream`. Note: it is _your_ responsibility to handle the `error` event in this case (usually, simply logging the error and aborting the response is enough).\n  - `Buffer`: `data` is written as an `octet-stream`.\n  - `object`: `data` is serialized as JSON.\n  - `string`: `data` is written as-is.\n- If JSON serialization fails (for example, if a cyclical reference is found), a `400` error is thrown. See [Error Handling](#error-handling).\n\n### Programmatic use\n\nYou can use Micro programmatically by requiring Micro directly:\n\n```js\nconst http = require('http');\nconst sleep = require('then-sleep');\nconst { serve } = require('micro');\n\nconst server = new http.Server(\n  serve(async (req, res) => {\n    await sleep(500);\n    return 'Hello world';\n  }),\n);\n\nserver.listen(3000);\n```\n\n##### serve(fn)\n\n- Use `require('micro').serve`.\n- Returns a function with the `(req, res) => void` signature. That uses the provided `function` as the request handler.\n- The supplied function is run with `await`. So it can be `async`\n\n##### sendError(req, res, error)\n\n- Use `require('micro').sendError`.\n- Used as the default handler for errors thrown.\n- Automatically sets the status code of the response based on `error.statusCode`.\n- Sends the `error.message` as the body.\n- Stacks are printed out with `console.error` and during development (when `NODE_ENV` is set to `'development'`) also sent in responses.\n- Usually, you don't need to invoke this method yourself, as you can use the [built-in error handling](#error-handling) flow with `throw`.\n\n##### createError(code, msg, orig)\n\n- Use `require('micro').createError`.\n- Creates an error object with a `statusCode`.\n- Useful for easily throwing errors with HTTP status codes, which are interpreted by the [built-in error handling](#error-handling).\n- `orig` sets `error.originalError` which identifies the original error (if any).\n\n## Error Handling\n\nMicro allows you to write robust microservices. This is accomplished primarily by bringing sanity back to error handling and avoiding callback soup.\n\nIf an error is thrown and not caught by you, the response will automatically be `500`. **Important:** Error stacks will be printed as `console.error` and during development mode (if the env variable `NODE_ENV` is `'development'`), they will also be included in the responses.\n\nIf the `Error` object that's thrown contains a `statusCode` property, that's used as the HTTP code to be sent. Let's say you want to write a rate limiting module:\n\n```js\nconst rateLimit = require('my-rate-limit');\n\nmodule.exports = async (req, res) => {\n  await rateLimit(req);\n  // ... your code\n};\n```\n\nIf the API endpoint is abused, it can throw an error with `createError` like so:\n\n```js\nif (tooMany) {\n  throw createError(429, 'Rate limit exceeded');\n}\n```\n\nAlternatively you can create the `Error` object yourself\n\n```js\nif (tooMany) {\n  const err = new Error('Rate limit exceeded');\n  err.statusCode = 429;\n  throw err;\n}\n```\n\nThe nice thing about this model is that the `statusCode` is merely a suggestion. The user can override it:\n\n```js\ntry {\n  await rateLimit(req);\n} catch (err) {\n  if (429 == err.statusCode) {\n    // perhaps send 500 instead?\n    send(res, 500);\n  }\n}\n```\n\nIf the error is based on another error that **Micro** caught, like a `JSON.parse` exception, then `originalError` will point to it. If a generic error is caught, the status will be set to `500`.\n\nIn order to set up your own error handling mechanism, you can use composition in your handler:\n\n```js\nconst { send } = require('micro');\n\nconst handleErrors = (fn) => async (req, res) => {\n  try {\n    return await fn(req, res);\n  } catch (err) {\n    console.log(err.stack);\n    send(res, 500, 'My custom error!');\n  }\n};\n\nmodule.exports = handleErrors(async (req, res) => {\n  throw new Error('What happened here?');\n});\n```\n\n## Testing\n\nMicro makes tests compact and a pleasure to read and write.\nWe recommend [Node TAP](https://node-tap.org/) or [AVA](https://github.com/avajs/ava), a highly parallel test framework with built-in support for async tests:\n\n```js\nconst http = require('http');\nconst { send, serve } = require('micro');\nconst test = require('ava');\nconst listen = require('test-listen');\nconst fetch = require('node-fetch');\n\ntest('my endpoint', async (t) => {\n  const service = new http.Server(\n    serve(async (req, res) => {\n      send(res, 200, {\n        test: 'woot',\n      });\n    }),\n  );\n\n  const url = await listen(service);\n  const response = await fetch(url);\n  const body = await response.json();\n\n  t.deepEqual(body.test, 'woot');\n  service.close();\n});\n```\n\nLook at [test-listen](https://github.com/vercel/test-listen) for a\nfunction that returns a URL with an ephemeral port every time it's called.\n\n## Contributing\n\n1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device\n2. Link the package to the global module directory: `npm link`\n3. Within the module you want to test your local development instance of Micro, just link it to the dependencies: `npm link micro`. Instead of the default one from npm, node will now use your clone of Micro!\n\nYou can run the tests using: `npm test`.\n\n## Credits\n\nThanks to Tom Yandell and Richard Hodgson for donating the name \"micro\" on [npm](https://www.npmjs.com)!\n\n## Authors\n\n- Guillermo Rauch ([@rauchg](https://x.com/rauchg)) - [Vercel](https://vercel.com)\n- Leo Lamprecht ([@leo](https://x.com/leo)) - [Vercel](https://vercel.com)\n- Tim Neutkens ([@timneutkens](https://x.com/timneutkens)) - [Vercel](https://vercel.com)\n"
  },
  {
    "path": "packages/micro/package.json",
    "content": "{\n  \"name\": \"micro\",\n  \"version\": \"10.0.1\",\n  \"description\": \"Asynchronous HTTP microservices\",\n  \"license\": \"MIT\",\n  \"main\": \"./dist/src/lib/index.js\",\n  \"types\": \"./types/src/lib\",\n  \"files\": [\n    \"src\",\n    \"dist\",\n    \"types\"\n  ],\n  \"bin\": {\n    \"micro\": \"./dist/src/bin/micro.js\"\n  },\n  \"engines\": {\n    \"node\": \">= 16.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc\",\n    \"prepublishOnly\": \"yarn run build\",\n    \"eslint-check\": \"eslint --max-warnings=0 .\",\n    \"prettier-check\": \"prettier --check .\",\n    \"type-check\": \"tsc --noEmit\"\n  },\n  \"repository\": \"vercel/micro\",\n  \"keywords\": [\n    \"micro\",\n    \"service\",\n    \"microservice\",\n    \"serverless\",\n    \"API\"\n  ],\n  \"dependencies\": {\n    \"arg\": \"4.1.0\",\n    \"content-type\": \"1.0.4\",\n    \"raw-body\": \"2.4.1\"\n  },\n  \"devDependencies\": {\n    \"@types/content-type\": \"1.1.5\",\n    \"@types/node\": \"18.0.3\",\n    \"@vercel/style-guide\": \"3.0.0\",\n    \"eslint\": \"8.19.0\",\n    \"prettier\": \"2.7.1\",\n    \"typescript\": \"4.7.4\"\n  },\n  \"prettier\": \"@vercel/style-guide/prettier\"\n}\n"
  },
  {
    "path": "packages/micro/src/bin/micro.ts",
    "content": "#!/usr/bin/env node\n/* eslint-disable eslint-comments/disable-enable-pair */\n/* eslint-disable no-console */\n\n// Native\nimport Module from 'module';\nimport http from 'http';\nimport path from 'path';\nimport { existsSync } from 'fs';\n// Packages\nimport arg from 'arg';\n// Utilities\nimport { serve } from '../lib';\nimport { handle } from '../lib/handler';\nimport { version } from '../../package.json';\nimport { logError } from '../lib/error';\nimport { parseEndpoint } from '../lib/parse-endpoint';\nimport type { AddressInfo } from 'net';\nimport type { RequestHandler } from '../lib';\n\n// Check if the user defined any options\nconst args = arg({\n  '--listen': parseEndpoint,\n  '-l': '--listen',\n  '--help': Boolean,\n  '--version': Boolean,\n  '-v': '--version',\n});\n\n// When `-h` or `--help` are used, print out\n// the usage information\nif (args['--help']) {\n  console.error(`\n  micro - Asynchronous HTTP microservices\n\n  USAGE\n\n      $ micro --help\n      $ micro --version\n      $ micro [-l listen_uri [-l ...]] [entry_point.js]\n\n      By default micro will listen on 0.0.0.0:3000 and will look first\n      for the \"main\" property in package.json and subsequently for index.js\n      as the default entry_point.\n\n      Specifying a single --listen argument will overwrite the default, not supplement it.\n\n  OPTIONS\n\n      --help                              shows this help message\n\n      -v, --version                       displays the current version of micro\n\n      -l, --listen listen_uri             specify a URI endpoint on which to listen (see below) -\n                                          more than one may be specified to listen in multiple places\n\n  ENDPOINTS\n\n      Listen endpoints (specified by the --listen or -l options above) instruct micro\n      to listen on one or more interfaces/ports, UNIX domain sockets, or Windows named pipes.\n\n      For TCP (traditional host/port) endpoints:\n\n          $ micro -l tcp://hostname:1234\n\n      For UNIX domain socket endpoints:\n\n          $ micro -l unix:/path/to/socket.sock\n\n      For Windows named pipe endpoints:\n\n          $ micro -l pipe:\\\\\\\\.\\\\pipe\\\\PipeName\n`);\n  process.exit(2);\n}\n\n// Print out the package's version when\n// `--version` or `-v` are used\nif (args['--version']) {\n  console.log(version);\n  process.exit();\n}\n\nif (!args['--listen']) {\n  // default endpoint\n  args['--listen'] = [String(3000)];\n}\n\nlet file = args._[0];\n\nif (!file) {\n  try {\n    const req = Module.createRequire(module.filename);\n    const packageJson: unknown = req(\n      path.resolve(process.cwd(), 'package.json'),\n    );\n    if (hasMain(packageJson)) {\n      file = packageJson.main;\n    } else {\n      file = 'index.js';\n    }\n  } catch (err) {\n    if (isNodeError(err) && err.code !== 'MODULE_NOT_FOUND') {\n      logError(\n        `Could not read \\`package.json\\`: ${err.message}`,\n        'invalid-package-json',\n      );\n      process.exit(1);\n    }\n  }\n}\n\nif (!file) {\n  logError('Please supply a file!', 'path-missing');\n  process.exit(1);\n}\n\nif (!file.startsWith('/')) {\n  file = path.resolve(process.cwd(), file);\n}\n\nif (!existsSync(file)) {\n  logError(\n    `The file or directory \"${path.basename(file)}\" doesn't exist!`,\n    'path-not-existent',\n  );\n  process.exit(1);\n}\n\nfunction registerShutdown(fn: () => void) {\n  let run = false;\n\n  const wrapper = () => {\n    if (!run) {\n      run = true;\n      fn();\n    }\n  };\n\n  process.on('SIGINT', wrapper);\n  process.on('SIGTERM', wrapper);\n  process.on('exit', wrapper);\n}\n\nfunction startEndpoint(module: RequestHandler, endpoint: string) {\n  const server = new http.Server(serve(module));\n\n  server.on('error', (err) => {\n    console.error('micro:', err.stack);\n    process.exit(1);\n  });\n\n  server.listen(endpoint, () => {\n    const details = server.address();\n    registerShutdown(() => {\n      console.log('micro: Gracefully shutting down. Please wait...');\n      server.close();\n      process.exit();\n    });\n\n    // `micro` is designed to run only in production, so\n    // this message is perfect for prod\n    if (typeof details === 'string') {\n      console.log(`micro: Accepting connections on ${details}`);\n    } else if (isAddressInfo(details)) {\n      console.log(`micro: Accepting connections on port ${details.port}`);\n    } else {\n      console.log('micro: Accepting connections');\n    }\n  });\n}\n\nasync function start() {\n  if (file && args['--listen']) {\n    const loadedModule = await handle(file);\n\n    for (const endpoint of args['--listen']) {\n      startEndpoint(loadedModule as RequestHandler, endpoint);\n    }\n  }\n}\n\nstart()\n  .then()\n  .catch((error) => {\n    if (error instanceof Error) {\n      logError(error.message, 'STARTUP_FAILURE');\n    }\n    process.exit(1);\n  });\n\nfunction hasMain(packageJson: unknown): packageJson is { main: string } {\n  return (\n    typeof packageJson === 'object' &&\n    packageJson !== null &&\n    'main' in packageJson\n  );\n}\n\nfunction isNodeError(\n  error: unknown,\n): error is { code: string; message: string } {\n  return error instanceof Error && 'code' in error;\n}\n\nfunction isAddressInfo(obj: unknown): obj is AddressInfo {\n  return 'port' in (obj as AddressInfo);\n}\n"
  },
  {
    "path": "packages/micro/src/lib/error.ts",
    "content": "// eslint-disable-next-line eslint-comments/disable-enable-pair\n/* eslint-disable no-console */\nexport function logError(message: string, errorCode: string) {\n  console.error(`micro: ${message}`);\n  console.error(`micro: https://err.sh/micro/${errorCode}`);\n}\n"
  },
  {
    "path": "packages/micro/src/lib/handler.ts",
    "content": "// Utilities\nimport { logError } from './error';\n\nexport const handle = async (file: string) => {\n  let mod: unknown;\n\n  try {\n    mod = await import(file);\n\n    mod = await (mod as { default: unknown }).default; // use ES6 module's default export\n  } catch (err: unknown) {\n    if (isErrorObject(err) && err.stack) {\n      logError(`Error when importing ${file}: ${err.stack}`, 'invalid-entry');\n    }\n    process.exit(1);\n  }\n\n  if (typeof mod !== 'function') {\n    logError(`The file \"${file}\" does not export a function.`, 'no-export');\n    process.exit(1);\n  }\n\n  return mod;\n};\n\nfunction isErrorObject(error: unknown): error is Error {\n  return (error as Error).stack !== undefined;\n}\n"
  },
  {
    "path": "packages/micro/src/lib/index.ts",
    "content": "// Native\nimport { Stream, Readable } from 'stream';\n// Packages\nimport contentType from 'content-type';\nimport getRawBody from 'raw-body';\nimport type { RawBodyError } from 'raw-body';\n//Types\nimport type { IncomingMessage, ServerResponse, RequestListener } from 'http';\n\n// slight modification of is-stream https://github.com/sindresorhus/is-stream/blob/c918e3795ea2451b5265f331a00fb6a8aaa27816/license\nfunction isStream(stream: unknown): stream is Stream {\n  return (\n    stream !== null &&\n    typeof stream === 'object' &&\n    stream instanceof Stream &&\n    typeof stream.pipe === 'function'\n  );\n}\n\nfunction readable(stream: unknown): stream is Readable {\n  return (\n    isStream(stream) && // TODO: maybe this isn't needed because we could use only the checks below\n    stream instanceof Readable &&\n    stream.readable\n  );\n}\n\nexport type RequestHandler = (\n  req: IncomingMessage,\n  res: ServerResponse,\n) => unknown;\n\ntype Serve = (fn: RequestHandler) => RequestListener;\n\nexport const serve: Serve = (fn) => (req, res) => run(req, res, fn);\n\nexport class HttpError extends Error {\n  constructor(message: string) {\n    super(message);\n    Object.setPrototypeOf(this, HttpError.prototype);\n  }\n\n  statusCode?: number;\n  originalError?: Error;\n}\n\nfunction isError(error: unknown): error is Error | HttpError {\n  return error instanceof Error || error instanceof HttpError;\n}\n\nexport const createError = (code: number, message: string, original: Error) => {\n  const err = new HttpError(message);\n\n  err.statusCode = code;\n  err.originalError = original;\n\n  return err;\n};\n\nexport const send = (\n  res: ServerResponse,\n  code: number,\n  obj: unknown = null,\n) => {\n  res.statusCode = code;\n\n  if (obj === null) {\n    res.end();\n    return;\n  }\n\n  if (Buffer.isBuffer(obj)) {\n    if (!res.getHeader('Content-Type')) {\n      res.setHeader('Content-Type', 'application/octet-stream');\n    }\n\n    res.setHeader('Content-Length', obj.length);\n    res.end(obj);\n    return;\n  }\n\n  if (obj instanceof Stream || readable(obj)) {\n    //TODO: Wouldn't (obj instanceof Stream) be the only check here? Do we specifically need a Readable stream or a Stream object that's not of NodeJS Stream?\n    if (!res.getHeader('Content-Type')) {\n      res.setHeader('Content-Type', 'application/octet-stream');\n    }\n\n    obj.pipe(res);\n    return;\n  }\n\n  let str = obj;\n\n  if (typeof obj === 'object' || typeof obj === 'number') {\n    // We stringify before setting the header\n    // in case `JSON.stringify` throws and a\n    // 500 has to be sent instead\n    str = JSON.stringify(obj);\n\n    if (!res.getHeader('Content-Type')) {\n      res.setHeader('Content-Type', 'application/json; charset=utf-8');\n    }\n  }\n\n  if (typeof str === 'string') {\n    res.setHeader('Content-Length', Buffer.byteLength(str));\n  }\n\n  res.end(str);\n};\n\nexport const sendError = (\n  req: IncomingMessage,\n  res: ServerResponse,\n  errorObj: Error | HttpError,\n) => {\n  if ('statusCode' in errorObj && errorObj.statusCode) {\n    send(res, errorObj.statusCode, errorObj.message);\n  } else send(res, 500, 'Internal Server Error');\n\n  if (errorObj instanceof Error) {\n    // eslint-disable-next-line no-console\n    console.error(errorObj.stack);\n  } else {\n    // eslint-disable-next-line no-console\n    console.warn('thrown error must be an instance Error');\n  }\n};\n\nexport const run = (\n  req: IncomingMessage,\n  res: ServerResponse,\n  fn: RequestHandler,\n) =>\n  new Promise((resolve) => {\n    resolve(fn(req, res));\n  })\n    .then((val) => {\n      if (val === null) {\n        send(res, 204, null);\n        return;\n      }\n\n      // Send value if it is not undefined, otherwise assume res.end\n      // will be called later\n      if (val !== undefined) {\n        send(res, res.statusCode || 200, val);\n      }\n    })\n    .catch((err: unknown) => {\n      if (isError(err)) {\n        sendError(req, res, err);\n      }\n    });\n\n// Maps requests to buffered raw bodies so that\n// multiple calls to `json` work as expected\nconst rawBodyMap = new WeakMap<IncomingMessage, Buffer>();\n\nconst parseJSON = (str: string): unknown => {\n  try {\n    return JSON.parse(str);\n  } catch (err: unknown) {\n    throw createError(400, 'Invalid JSON', err as Error);\n  }\n};\n\nexport interface BufferInfo {\n  limit?: string | number | undefined;\n  encoding?: BufferEncoding;\n}\n\nfunction isRawBodyError(error: unknown): error is RawBodyError {\n  return 'type' in (error as RawBodyError);\n}\n\nexport const buffer = (\n  req: IncomingMessage,\n  { limit = '1mb', encoding }: BufferInfo = {},\n) =>\n  Promise.resolve().then(() => {\n    const type = req.headers['content-type'] || 'text/plain';\n    const length = req.headers['content-length'];\n\n    const body = rawBodyMap.get(req);\n\n    if (body) {\n      return body;\n    }\n\n    return getRawBody(req, {\n      limit,\n      length,\n      encoding: encoding ?? contentType.parse(type).parameters.charset,\n    })\n      .then((buf) => {\n        rawBodyMap.set(req, buf);\n        return buf;\n      })\n      .catch((err) => {\n        if (isRawBodyError(err) && err.type === 'entity.too.large') {\n          throw createError(413, `Body exceeded ${limit} limit`, err);\n        } else {\n          throw createError(400, 'Invalid body', err as Error);\n        }\n      });\n  });\n\nexport const text = (\n  req: IncomingMessage,\n  { limit, encoding }: BufferInfo = {},\n) => buffer(req, { limit, encoding }).then((body) => body.toString(encoding));\n\nexport const json = (req: IncomingMessage, opts: BufferInfo = {}) =>\n  text(req, opts).then((body) => parseJSON(body));\n"
  },
  {
    "path": "packages/micro/src/lib/parse-endpoint.ts",
    "content": "export function parseEndpoint(endpoint: string) {\n  const url = new URL(endpoint);\n\n  switch (url.protocol) {\n    case 'pipe:': {\n      // some special handling\n      const cutStr = endpoint.replace(/^pipe:/, '');\n      if (!cutStr.startsWith('\\\\\\\\.\\\\')) {\n        throw new Error(`Invalid Windows named pipe endpoint: ${endpoint}`);\n      }\n      return [cutStr];\n    }\n    case 'unix:':\n      if (!url.pathname) {\n        throw new Error(`Invalid UNIX domain socket endpoint: ${endpoint}`);\n      }\n      return [url.pathname];\n    case 'tcp:':\n      url.port = url.port || '3000';\n      return [parseInt(url.port, 10).toString(), url.hostname];\n    default:\n      throw new Error(\n        `Unknown --listen endpoint scheme (protocol): ${url.protocol}`,\n      );\n  }\n}\n"
  },
  {
    "path": "packages/micro/tsconfig.json",
    "content": "{\n  \"extends\": \"@vercel/style-guide/typescript\",\n  \"compilerOptions\": {\n    \"target\": \"ES2021\",\n    \"module\": \"CommonJS\",\n    \"moduleResolution\": \"Node16\",\n    \"esModuleInterop\": true,\n    \"resolveJsonModule\": true,\n    \"outDir\": \"dist\",\n    \"declaration\": true,\n    \"declarationDir\": \"./types\",\n    \"declarationMap\": true,\n    \"removeComments\": true\n  },\n  \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "packages/micro/types/src/bin/micro.d.ts",
    "content": "#!/usr/bin/env node\nexport {};\n//# sourceMappingURL=micro.d.ts.map"
  },
  {
    "path": "packages/micro/types/src/lib/error.d.ts",
    "content": "export declare function logError(message: string, errorCode: string): void;\n//# sourceMappingURL=error.d.ts.map"
  },
  {
    "path": "packages/micro/types/src/lib/handler.d.ts",
    "content": "export declare const handle: (file: string) => Promise<Function>;\n//# sourceMappingURL=handler.d.ts.map"
  },
  {
    "path": "packages/micro/types/src/lib/index.d.ts",
    "content": "/// <reference types=\"node\" />\n/// <reference types=\"node\" />\nimport type { IncomingMessage, ServerResponse, RequestListener } from 'http';\nexport declare type RequestHandler = (req: IncomingMessage, res: ServerResponse) => unknown;\ndeclare type Serve = (fn: RequestHandler) => RequestListener;\nexport declare const serve: Serve;\nexport declare class HttpError extends Error {\n    constructor(message: string);\n    statusCode?: number;\n    originalError?: Error;\n}\nexport declare const createError: (code: number, message: string, original: Error) => HttpError;\nexport declare const send: (res: ServerResponse, code: number, obj?: unknown) => void;\nexport declare const sendError: (req: IncomingMessage, res: ServerResponse, errorObj: Error | HttpError) => void;\nexport declare const run: (req: IncomingMessage, res: ServerResponse, fn: RequestHandler) => Promise<void>;\nexport interface BufferInfo {\n    limit?: string | number | undefined;\n    encoding?: BufferEncoding;\n}\nexport declare const buffer: (req: IncomingMessage, { limit, encoding }?: BufferInfo) => Promise<Buffer>;\nexport declare const text: (req: IncomingMessage, { limit, encoding }?: BufferInfo) => Promise<string>;\nexport declare const json: (req: IncomingMessage, opts?: BufferInfo) => Promise<unknown>;\nexport {};\n//# sourceMappingURL=index.d.ts.map"
  },
  {
    "path": "packages/micro/types/src/lib/parse-endpoint.d.ts",
    "content": "export declare function parseEndpoint(endpoint: string): string[];\n//# sourceMappingURL=parse-endpoint.d.ts.map"
  },
  {
    "path": "test/.eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  extends: [\n    require.resolve('@vercel/style-guide/eslint/node'),\n    require.resolve('@vercel/style-guide/eslint/typescript'),\n  ],\n  parserOptions: {\n    tsconfigRootDir: __dirname,\n    project: ['./tsconfig.json'],\n  },\n};\n"
  },
  {
    "path": "test/package.json",
    "content": "{\n  \"name\": \"test\",\n  \"version\": \"1.0.0\",\n  \"engines\": {\n    \"node\": \">= 16.0.0\"\n  },\n  \"scripts\": {\n    \"eslint-check\": \"eslint --max-warnings=0 .\",\n    \"prettier-check\": \"prettier --check .\",\n    \"type-check\": \"tsc --noEmit\",\n    \"test\": \"tap --ts suite/\"\n  },\n  \"devDependencies\": {\n    \"@types/node-fetch\": \"2.6.2\",\n    \"@types/sinon\": \"10.0.13\",\n    \"@types/tap\": \"15.0.7\",\n    \"@vercel/style-guide\": \"3.0.0\",\n    \"eslint\": \"8.19.0\",\n    \"node-fetch\": \"2.6.6\",\n    \"prettier\": \"2.7.1\",\n    \"sinon\": \"14.0.0\",\n    \"tap\": \"16.3.0\",\n    \"ts-node\": \"10.9.1\",\n    \"typescript\": \"4.7.4\",\n    \"micro\": \"*\"\n  },\n  \"prettier\": \"@vercel/style-guide/prettier\"\n}\n"
  },
  {
    "path": "test/suite/handler.ts",
    "content": "import { test } from 'tap';\nimport { handle } from 'micro/src/lib/handler';\nimport { stub } from 'sinon';\n\nvoid test('handle a non-async function', async (t) => {\n  const dir = t.testdir({\n    'regular-function-export.js': `module.exports = () => 'Test';`,\n  });\n\n  const result = await handle(`${dir}/regular-function-export.js`);\n  t.type(result, 'function');\n});\n\nvoid test('handle async function', async (t) => {\n  const dir = t.testdir({\n    'promise-export.js': `module.exports = async () => 'Test';`,\n  });\n\n  const result = await handle(`${dir}/promise-export.js`);\n  t.type(result, 'function');\n});\n\nvoid test(`handle ESM's non-async function`, async (t) => {\n  const dir = t.testdir({\n    'esm-function-export.mjs': `export default () => 'Hello ESM';`,\n  });\n\n  const result = await handle(`${dir}/esm-function-export.mjs`);\n  t.type(result, 'function');\n});\n\nvoid test(`handle ESM's async function`, async (t) => {\n  const dir = t.testdir({\n    'esm-async-export.mjs': `export default async () => 'Hello ESM';`,\n  });\n\n  const result = await handle(`${dir}/esm-async-export.mjs`);\n  t.type(result, 'function');\n});\n\nvoid test('process.exit when handling an invalid export', async (t) => {\n  const dir = t.testdir({\n    'regular-object.js': `module.exports = {};`,\n  });\n  const processStub = stub(process, 'exit').callsFake(() => {\n    throw new Error('Fake');\n  });\n\n  await t.rejects(handle(`${dir}/regular-object.js`), { message: 'Fake' });\n  t.equal(processStub.calledOnceWith(1), true);\n\n  processStub.restore();\n});\n\nvoid test('process.exit when handling and inexisting file', async (t) => {\n  const dir = t.testdir();\n  const processStub = stub(process, 'exit').callsFake(() => {\n    throw new Error('Fake');\n  });\n\n  await t.rejects(handle(`${dir}/foo/bar`), { message: 'Fake' });\n  t.equal(processStub.calledOnceWith(1), true);\n\n  processStub.restore();\n});\n"
  },
  {
    "path": "test/suite/index.ts",
    "content": "import http from 'http';\nimport Stream from 'stream';\nimport { Socket } from 'net';\nimport { stub } from 'sinon';\nimport { test } from 'tap';\nimport {\n  serve,\n  run,\n  send,\n  sendError,\n  buffer,\n  json,\n  HttpError,\n} from 'micro/src/lib/index';\nimport fetch from 'node-fetch';\nimport type { AddressInfo } from 'net';\nimport type { RequestHandler, BufferInfo } from 'micro/src/lib/index';\n\nfunction startServer(handler: RequestHandler): Promise<[string, () => void]> {\n  return new Promise((resolve, reject) => {\n    const server = http.createServer(serve(handler));\n\n    server.on('error', reject);\n\n    server.listen(() => {\n      const { port } = server.address() as AddressInfo;\n      resolve([\n        `http://localhost:${port}`,\n        () => {\n          server.close();\n        },\n      ]);\n    });\n  });\n}\n\nfunction sleep(ms: number) {\n  return new Promise((resolve) => {\n    setTimeout(resolve, ms);\n  });\n}\n\nvoid test('send(200, <String>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 200, 'woot');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n  const body = await res.text();\n\n  t.same(body, 'woot');\n  shutdown();\n});\n\nvoid test('send(200, <Object>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 200, {\n      a: 'b',\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const res: unknown = await fetch(url).then((r) => r.json());\n\n  t.same(res, {\n    a: 'b',\n  });\n  shutdown();\n});\n\nvoid test('send(200, <Number>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    // Chosen by fair dice roll. guaranteed to be random.\n    send(res, 200, 4);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res: unknown = await fetch(url).then((r) => r.json());\n\n  t.same(res, 4);\n  shutdown();\n});\n\nvoid test('send(200, <Buffer>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 200, Buffer.from('muscle'));\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'muscle');\n  shutdown();\n});\n\nvoid test('send(200, <Stream>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 200, 'waterfall');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'waterfall');\n  shutdown();\n});\n\nvoid test('send(<Number>)', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 404);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n  t.same(status, 404);\n  shutdown();\n});\n\nvoid test('return <String>', async (t) => {\n  const fn: RequestHandler = () => 'woot';\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'woot');\n  shutdown();\n});\n\nvoid test('return <Promise>', async (t) => {\n  const fn: RequestHandler = async () => {\n    await sleep(100);\n    return 'I Promise';\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'I Promise');\n  shutdown();\n});\n\nvoid test('sync return <String>', async (t) => {\n  const fn: RequestHandler = () => 'argon';\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'argon');\n  shutdown();\n});\n\nvoid test('return empty string', async (t) => {\n  const fn: RequestHandler = () => '';\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, '');\n  shutdown();\n});\n\nvoid test('return <Object>', async (t) => {\n  const fn: RequestHandler = () => ({\n    a: 'b',\n  });\n\n  const [url, shutdown] = await startServer(fn);\n  const res: unknown = await fetch(url).then((r) => r.json());\n\n  t.same(res, {\n    a: 'b',\n  });\n  shutdown();\n});\n\nvoid test('return <Number>', async (t) => {\n  const fn: RequestHandler = () =>\n    // Chosen by fair dice roll. guaranteed to be random.\n    4;\n\n  const [url, shutdown] = await startServer(fn);\n  const res: unknown = await fetch(url).then((r) => r.json());\n\n  t.same(res, 4);\n  shutdown();\n});\n\nvoid test('return <Buffer>', async (t) => {\n  const fn: RequestHandler = () => Buffer.from('Hammer');\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'Hammer');\n  shutdown();\n});\n\nvoid test('return <Stream>', async (t) => {\n  const fn: RequestHandler = () => {\n    const stream = new Stream.Transform();\n    stream.push('River');\n    stream.end();\n    return stream;\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'River');\n  shutdown();\n});\n\nvoid test('return <null>', async (t) => {\n  const fn: RequestHandler = () => null;\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n  const body = await res.text();\n\n  t.equal(res.status, 204);\n  t.equal(body, '');\n  shutdown();\n});\n\nvoid test('return <null> calls res.end once', async (t) => {\n  const fn: RequestHandler = () => null;\n\n  const req = new http.IncomingMessage(new Socket());\n  const res = new http.ServerResponse(req);\n  const fake = stub(res, 'end');\n\n  await run(req, res, fn);\n\n  t.equal(fake.calledOnce, true);\n});\n\nvoid test('throw with code', async (t) => {\n  const fn: RequestHandler = async () => {\n    await sleep(100);\n\n    const err = new HttpError('Error from test (expected)');\n    err.statusCode = 402;\n    throw err;\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n\n  t.same(status, 402);\n  shutdown();\n});\n\nvoid test('throw (500)', async (t) => {\n  const fn: RequestHandler = () => {\n    throw new Error('500 from test (expected)');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n  t.same(status, 500);\n  shutdown();\n});\n\nvoid test('throw (500) sync', async (t) => {\n  const fn: RequestHandler = () => {\n    throw new Error('500 from test (expected)');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n  t.same(status, 500);\n  shutdown();\n});\n\nvoid test('send(200, <Stream>) with error on same tick', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    const stream = new Stream.Transform();\n    stream.push('error-stream');\n\n    stream.emit('error', new Error('500 from test (expected)'));\n    stream.end();\n    send(res, 200, stream);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const { status } = await fetch(url);\n\n  t.same(status, 500);\n  shutdown();\n});\n\nvoid test('custom error', async (t) => {\n  const fn: RequestHandler = async () => {\n    await sleep(50);\n    throw new Error('500 from test (expected)');\n  };\n\n  const handleErrors =\n    (ofn: RequestHandler) =>\n    async (req: http.IncomingMessage, res: http.ServerResponse) => {\n      try {\n        return await ofn(req, res);\n      } catch (err) {\n        send(res, 200, 'My custom error!');\n      }\n    };\n\n  const [url, shutdown] = await startServer(handleErrors(fn));\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'My custom error!');\n  shutdown();\n});\n\nvoid test('custom async error', async (t) => {\n  const fn: RequestHandler = async () => {\n    await sleep(50);\n    throw new Error('500 from test (expected)');\n  };\n\n  const handleErrors =\n    (ofn: RequestHandler) =>\n    async (req: http.IncomingMessage, res: http.ServerResponse) => {\n      try {\n        return await ofn(req, res);\n      } catch (err) {\n        send(res, 200, 'My custom error!');\n      }\n    };\n\n  const [url, shutdown] = await startServer(handleErrors(fn));\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'My custom error!');\n  shutdown();\n});\n\nvoid test('json parse error', async (t) => {\n  const fn: RequestHandler = async (req, res) => {\n    const body = await json(req);\n    send(res, 200, (body as { woot: string }).woot);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url, {\n    method: 'POST',\n    body: '{ \"bad json\" }',\n    headers: {\n      'Content-Type': 'application/json',\n    },\n  });\n  t.same(status, 400);\n  shutdown();\n});\n\nvoid test('json', async (t) => {\n  interface Payload {\n    some: { cool: string };\n  }\n  const fn: RequestHandler = async (req, res) => {\n    const body = await json(req);\n\n    send(res, 200, {\n      response: (body as Payload).some.cool,\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const res = await fetch(url, {\n    method: 'POST',\n    body: JSON.stringify({\n      some: {\n        cool: 'json',\n      },\n    }),\n  });\n  const body: unknown = await res.json();\n\n  t.same((body as { response: unknown }).response, 'json');\n  shutdown();\n});\n\nvoid test('json limit (below)', async (t) => {\n  interface Payload {\n    some: { cool: string };\n  }\n  const fn: RequestHandler = async (req, res) => {\n    const body = await json(req, {\n      limit: 100,\n    });\n\n    send(res, 200, {\n      response: (body as Payload).some.cool,\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const res = await fetch(url, {\n    method: 'POST',\n    body: JSON.stringify({\n      some: {\n        cool: 'json',\n      },\n    }),\n  });\n  const body: unknown = await res.json();\n\n  t.same((body as { response: unknown }).response, 'json');\n  shutdown();\n});\n\nvoid test('json limit (over)', async (t) => {\n  const fn: RequestHandler = async (req, res) => {\n    try {\n      await json(req, {\n        limit: 3,\n      });\n    } catch (err) {\n      t.same((err as HttpError).statusCode, 413);\n    }\n\n    send(res, 200, 'ok');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url, {\n    method: 'POST',\n    body: JSON.stringify({\n      some: {\n        cool: 'json',\n      },\n    }),\n  });\n  t.same(res.status, 200);\n  shutdown();\n});\n\nvoid test('json circular', async (t) => {\n  interface Payload {\n    circular: boolean;\n    obj?: Payload;\n  }\n  const fn: RequestHandler = (req, res) => {\n    const obj: Payload = {\n      circular: true,\n    };\n\n    obj.obj = obj;\n    send(res, 200, obj);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n  t.same(status, 500);\n  shutdown();\n});\n\nvoid test('no async', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    send(res, 200, {\n      a: 'b',\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const obj: unknown = await fetch(url).then((r) => r.json());\n\n  t.same((obj as { a: string }).a, 'b');\n  shutdown();\n});\n\nvoid test('limit included in error', async (t) => {\n  interface Payload {\n    some: { cool: string };\n  }\n  const fn: RequestHandler = async (req, res) => {\n    let body;\n\n    try {\n      body = await json(req, {\n        limit: 3,\n      });\n    } catch (err) {\n      t.ok((err as Error).message.includes('exceeded 3 limit'));\n    }\n\n    send(res, 200, {\n      response: (body as Payload).some.cool,\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url, {\n    method: 'POST',\n    body: JSON.stringify({\n      some: {\n        cool: 'json',\n      },\n    }),\n  });\n\n  t.same(res.status, 500);\n  shutdown();\n});\n\nvoid test('support for status fallback in errors', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    const err = new HttpError('Custom');\n    err.statusCode = 403;\n    sendError(req, res, err);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const { status } = await fetch(url);\n  t.same(status, 403);\n  shutdown();\n});\n\nvoid test('json from rawBodyMap works', async (t) => {\n  interface Payload {\n    some: { cool: string };\n  }\n  const fn: RequestHandler = async (req, res) => {\n    const bodyOne = await json(req);\n    const bodyTwo = await json(req);\n\n    t.same(bodyOne, bodyTwo);\n\n    send(res, 200, {\n      response: (bodyOne as Payload).some.cool,\n    });\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url, {\n    method: 'POST',\n    body: JSON.stringify({\n      some: {\n        cool: 'json',\n      },\n    }),\n  });\n  const body: unknown = await res.json();\n\n  t.same((body as { response: unknown }).response, 'json');\n  shutdown();\n});\n\nvoid test('statusCode defaults to 200', async (t) => {\n  const fn: RequestHandler = () => {\n    return 'woot';\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n  const body = await res.text();\n  t.equal(body, 'woot');\n  t.equal(res.status, 200);\n  shutdown();\n});\n\nvoid test('statusCode on response works', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    res.statusCode = 400;\n    return 'woot';\n  };\n\n  const [url, shutdown] = await startServer(fn);\n\n  const { status } = await fetch(url);\n  t.same(status, 400);\n  shutdown();\n});\n\nvoid test('Content-Type header is preserved on string', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    res.setHeader('Content-Type', 'text/html');\n    return '<blink>woot</blink>';\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n\n  t.equal(res.headers.get('content-type'), 'text/html');\n  shutdown();\n});\n\nvoid test('Content-Type header is preserved on stream', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    res.setHeader('Content-Type', 'text/html');\n    const stream = new Stream.Transform();\n    stream.push('River');\n    stream.end();\n    return stream;\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n\n  t.equal(res.headers.get('content-type'), 'text/html');\n  shutdown();\n});\n\nvoid test('Content-Type header is preserved on buffer', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    res.setHeader('Content-Type', 'text/html');\n    return Buffer.from('hello');\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n\n  t.equal(res.headers.get('content-type'), 'text/html');\n  shutdown();\n});\n\nvoid test('Content-Type header is preserved on object', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    res.setHeader('Content-Type', 'text/html');\n    return {};\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url);\n\n  t.equal(res.headers.get('content-type'), 'text/html');\n  shutdown();\n});\n\nvoid test('res.end is working', async (t) => {\n  const fn: RequestHandler = (req, res) => {\n    setTimeout(() => res.end('woot'), 100);\n  };\n\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url).then((r) => r.text());\n\n  t.same(res, 'woot');\n  shutdown();\n});\n\nvoid test('json should throw 400 on empty body with no headers', async (t) => {\n  const fn: RequestHandler = (req) => json(req);\n\n  const [url, shutdown] = await startServer(fn);\n\n  const res = await fetch(url);\n  const body = await res.text();\n  t.equal(body, 'Invalid JSON');\n  t.equal(res.status, 400);\n  shutdown();\n});\n\nvoid test('buffer should throw 400 on invalid encoding', async (t) => {\n  const bufferInfo = { encoding: 'lol' };\n\n  const fn: RequestHandler = async (req) =>\n    buffer(req, bufferInfo as BufferInfo);\n\n  const [url, shutdown] = await startServer(fn);\n\n  const res = await fetch(url, {\n    method: 'POST',\n    body: '❤️',\n  });\n  const body = await res.text();\n\n  t.equal(body, 'Invalid body');\n  t.equal(res.status, 400);\n  shutdown();\n});\n\nvoid test('buffer works', async (t) => {\n  const fn: RequestHandler = (req) => buffer(req);\n  const [url, shutdown] = await startServer(fn);\n  const res = await fetch(url, { method: 'POST', body: '❤️' });\n  const body = await res.text();\n  t.equal(body, '❤️');\n  shutdown();\n});\n\nvoid test('Content-Type header for JSON is set', async (t) => {\n  const [url, shutdown] = await startServer(() => ({}));\n  const res = await fetch(url);\n\n  t.equal(res.headers.get('content-type'), 'application/json; charset=utf-8');\n  shutdown();\n});\n"
  },
  {
    "path": "test/suite/parse-endpoint.ts",
    "content": "import { test } from 'tap';\nimport { parseEndpoint } from 'micro/src/lib/parse-endpoint';\n\nvoid test('parses TCP URI', (t) => {\n  t.same(parseEndpoint('tcp://my-host-name.foo.bar:12345'), [\n    12345,\n    'my-host-name.foo.bar',\n  ]);\n  t.same(parseEndpoint('tcp://0.0.0.0:8080'), [8080, '0.0.0.0']);\n\n  // with the default\n  t.same(parseEndpoint('tcp://1.2.3.4'), [3000, '1.2.3.4']);\n  t.end();\n});\n\nvoid test('parses UNIX domain socket URI', (t) => {\n  t.same(parseEndpoint('unix:/foo/bar.sock'), ['/foo/bar.sock']);\n  t.same(parseEndpoint('unix:///foo/bar.sock'), ['/foo/bar.sock']);\n  t.end();\n});\n\nvoid test('parses Windows named pipe URI', (t) => {\n  t.same(parseEndpoint('pipe:\\\\\\\\.\\\\pipe\\\\some-name'), [\n    '\\\\\\\\.\\\\pipe\\\\some-name',\n  ]);\n  t.end();\n});\n\nvoid test('throws on invalid scheme (protocol)', (t) => {\n  t.throws(\n    () => parseEndpoint('foobar://blah'),\n    'Unknown --listen endpoint scheme (protocol): foobar:',\n  );\n  t.end();\n});\n\nvoid test('throws on invalid Windows named pipe', (t) => {\n  t.throws(\n    () => parseEndpoint('pipe:lolsickbro'),\n    'Invalid Windows named pipe endpoint: pipe:lolsickbro',\n  );\n  t.throws(\n    () => parseEndpoint('pipe://./pipe/lol'),\n    'Invalid Windows named pipe endpoint: pipe://./pipe/lol',\n  );\n  t.end();\n});\n\nvoid test('throws on invalid UNIX domain socket', (t) => {\n  t.throws(\n    () => parseEndpoint('unix:'),\n    'Invalid UNIX domain socket endpoint: unix:',\n  );\n  t.end();\n});\n"
  },
  {
    "path": "test/tsconfig.json",
    "content": "{\n  \"extends\": \"@vercel/style-guide/typescript\",\n  \"compilerOptions\": {\n    \"target\": \"ES2021\",\n    \"module\": \"CommonJS\",\n    \"moduleResolution\": \"Node16\",\n    \"esModuleInterop\": true,\n    \"noEmit\": true\n  }\n}\n"
  }
]