{"_id":"@adam-lynch/sirv","_rev":"1-0d2f0dbd97356347db3dc212ffd7e2ed","name":"@adam-lynch/sirv","dist-tags":{"latest":"1.0.8-0"},"versions":{"1.0.8-0":{"name":"@adam-lynch/sirv","version":"1.0.8-0","description":"The optimized & lightweight middleware for serving requests to static assets","repository":{"type":"git","url":"git+https://github.com/lukeed/sirv.git"},"module":"build.mjs","types":"sirv.d.ts","main":"build.js","license":"MIT","author":{"name":"Luke Edwards","email":"luke@lukeed.com","url":"https://lukeed.com"},"engines":{"node":">= 10"},"dependencies":{"@polka/url":"^1.0.0-next.9","mime":"^2.3.1","totalist":"^1.0.0"},"bugs":{"url":"https://github.com/lukeed/sirv/issues"},"homepage":"https://github.com/lukeed/sirv#readme","_id":"@adam-lynch/sirv@1.0.8-0","_nodeVersion":"12.16.1","_npmVersion":"6.13.4","dist":{"integrity":"sha512-HaZa/FC1+GiblPKGmdn1fENPksfir1jOost8Fu8wwcxn5+tNQPeIdh6UwnjR+PGk6u9pZyMpdxYCFP07AGQOHQ==","shasum":"5f5d8ed6b6256c33fad15f3f42fe031ca127580e","tarball":"https://registry.npmjs.org/@adam-lynch/sirv/-/sirv-1.0.8-0.tgz","fileCount":5,"unpackedSize":20311,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfwK+6CRA9TVsSAnZWagAAjXcQAJvMoK7E6xBCx1rzwaD/\nSFzA6bzsMDHFLTrwH2A8X4ji2z77tGlY3b/imHc2P9M5lbRj95z2bvFWNVnl\nl5XRrQbxE3eRqwkovAYMhmwCTFRZVmQOJmKHFO9Ru/vGYQUNb1OIiNJeJKhT\nelys6zSc1a38sjlJpMCXledbisoDfKb5WLJFmnuDoPezh3S73ieNGbrGJmhv\nyUrDx1e2Kc1Ef5vvLaICfS+08Gui4c2GTCOQURsExHniFtdAwhRa3NAw6vRi\nOFXynkNiBfKj/JmFeU24QB8rxi52jSxk39K52fL8nDE5wk2ZFHNC62ILlyhj\n/vXQfyIXWFzWIJC+p8jifTMANsk/+YCmDdK/nej3wkvK0HMxvRqkMsnv+Aby\nrpzKQEcNKw6fzN/G7aa0+Bswt8ZN40uZ0HPv4AEDjmRbBxOGN8056FyjvQ2X\nS6i0g8kM3TFj0zmqnyChzmEC+a5X4ELTMGuil4qLbHKY7GRRtXKBKEl21x6w\nTuwwfjq8YhpOfELEJWRs1vXInxqkXmXCbAb7sEkNO1KUTd6b3TmXXyLyIATc\nGR19jQ3S0VwNPGp0yt/TYf9C9o5aVyle51g4WwBnhl7B3XekaCzLyUZAJiHV\nYTG/uCdTuW8yCSuyMA1mQtV7ln7NLCghLiSfBIpLDGkkp7K/552YTRqUNi9/\nZXsQ\r\n=lmDn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDOlnXK4pAuJrUHoy5NVeh6pU2qc8kC2ff+Y/7cBCrD9AIhAPvRgzgo7Zu/WA7eKM1VvF22wB0EHG9/ZdRAXoECZdIy"}]},"_npmUser":{"name":"adam-lynch","email":"contact@adamlynch.ie"},"directories":{},"maintainers":[{"name":"adam-lynch","email":"contact@adamlynch.ie"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/sirv_1.0.8-0_1606463418067_0.8926364474874824"},"_hasShrinkwrap":false}},"time":{"created":"2020-11-27T07:50:18.066Z","1.0.8-0":"2020-11-27T07:50:18.199Z","modified":"2022-04-04T11:24:55.028Z"},"maintainers":[{"name":"adam-lynch","email":"contact@adamlynch.ie"}],"description":"The optimized & lightweight middleware for serving requests to static assets","homepage":"https://github.com/lukeed/sirv#readme","repository":{"type":"git","url":"git+https://github.com/lukeed/sirv.git"},"author":{"name":"Luke Edwards","email":"luke@lukeed.com","url":"https://lukeed.com"},"bugs":{"url":"https://github.com/lukeed/sirv/issues"},"license":"MIT","readme":"# sirv ![CI](https://github.com/lukeed/sirv/workflows/CI/badge.svg)\n\n> The optimized and lightweight middleware for serving requests to static assets\n\nYou may use `sirv` as a *very* fast and lightweight alternative to [`serve-static`](https://www.npmjs.com/package/serve-static).\n\nThe massive performance advantage over `serve-static` is explained by **not** relying on the file system for existence checks on every request. These are expensive interactions and must be avoided whenever possible! Instead, when not in \"dev\" mode, `sirv` performs all its file-system operations upfront and then relies on its cache for future operations.\n\nThis middleware will work out of the box for [Polka](https://github.com/lukeed/polka), Express, and other Express-like frameworks. It will also work with the native `http`, `https` and `http2` modules. It requires _very_ little effort to modify/wrap it for servers that don't accept the `(req, res, next)` signature.\n\n:bulb: For a feature-complete CLI application, check out the sibling [`sirv-cli`](https://github.com/lukeed/sirv/tree/master/packages/sirv-cli) package as an alternative to [`zeit/serve`](https://github.com/zeit/serve)~!\n\n## Install\n\n```\n$ npm install --save sirv\n```\n\n\n## Usage\n\n```js\nconst sirv = require('sirv');\nconst polka = require('polka');\nconst compress = require('compression')();\n\n// Init `sirv` handler\nconst assets = sirv('public', {\n  maxAge: 31536000, // 1Y\n  immutable: true\n});\n\npolka()\n  .use(compress, assets)\n  .use('/api', require('./api'))\n  .listen(3000, err => {\n    if (err) throw err;\n    console.log('> Ready on localhost:3000~!');\n  });\n```\n\n\n## API\n\n### sirv(dir, opts={})\n\nReturns: `Function`\n\nThe returned function is a middleware in the standard Express-like signature: `(req, res, next)`, where `req` is the [`http.IncomingMessage`](https://nodejs.org/api/http.html#http_class_http_incomingmessage), `res` is the [`http.ServerResponse`](https://nodejs.org/dist/latest-v9.x/docs/api/http.html#http_class_http_serverresponse), and `next` (in this case) is the function to call if no file was found for the given path.\n\nWhen defined, a `next()` callback is always called _instead of_ the [`opts.onNoMatch`](#optsonnomatch) callback. However, unlike `onNoMatch`, your `next()` is given no arguments.\n\n#### dir\nType: `String`<br>\nDefault: `.`\n\nThe directory from which to read and serve assets. It is resolved to an absolute path &mdash; you must provide an absolute path yourself if `process.cwd()` is not the correct assumption.\n\n#### opts.dev\nType: `Boolean`<br>\nDefault: `false`\n\nEnable \"dev\" mode, which disables/skips caching. Instead, `sirv` will traverse the file system ***on every request***.\n\nAdditionally, `dev` mode will ignore `maxAge` and `immutable` as these options generate a production-oriented `Cache-Control` header value.\n\n> **Important:** Do not use `dev` mode in production!\n\n#### opts.etag\nType: `Boolean`<br>\nDefault: `false`\n\nGenerate and attach an `ETag` header to responses.\n\n> **Note:** If an incoming request's [`If-None-Match` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) matches the `ETag` value, a `304` response is given.\n\n#### opts.dotfiles\nType: `Boolean`<br>\nDefault: `false`\n\nAllow requests to dotfiles (files or directories beginning with a `.`).\n\n> **Note:** Requests to [`/.well-known/*`](https://tools.ietf.org/html/rfc8615) are always allowed.\n\n#### opts.extensions\nType: `Array<String>`<br>\nDefault: `['html', 'htm']`\n\nThe file extension fallbacks to check for if a pathame is not initially found. For example, if a `/login` request cannot find a `login` filename, it will then look for `login.html` and `login.htm` before giving up~!\n\n> **Important:** Actually, `sirv` will **also** look for `login/index.html` and `login/index.htm` before giving up.\n\n#### opts.gzip\nType: `Boolean`<br>\nDefault: `false`\n\nDetermine if `sirv` look for **precompiled** `*.gz` files.<br>\nMust be enabled _and_ the incoming request's [`Accept Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) must include \"gzip\" in order for `sirv` to search for the gzip'd alternative.\n\n> **Note:** The `.gz` assumption also applies to the `opts.extensions` list.\n\n```js\n// NOTE: PSEUDO CODE\n// Showing lookup logic\n\n// Request: [Accept-Encoding: gzip] \"/foobar.jpg\"\nlookup([\n  '/foobar.jpg.gz', '/foobar.jpg',\n  '/foobar.jpg.html.gz', '/foobar.jpg/index.html.gz',\n  '/foobar.jpg.htm.gz', '/foobar.jpg/index.htm.gz',\n  '/foobar.jpg.html', '/foobar.jpg/index.html',\n  '/foobar.jpg.htm', '/foobar.jpg/index.htm',\n]);\n\n// Request: [Accept-Encoding: gzip] \"/\"\nlookup([\n  '/index.html.gz',\n  '/index.htm.gz',\n  '/index.html',\n  '/index.htm',\n]);\n```\n\n\n#### opts.brotli\nType: `Boolean`<br>\nDefault: `false`\n\nDetermine if `sirv` look for **precompiled** `*.br` files.<br>\nMust be enabled _and_ the incoming request's [`Accept Encoding`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding) must include either \"br\" or \"brotli\" in order for `sirv` to search for the brotli-compressed alternative.\n\n> **Note:** The `.br` assumption also applies to the `opts.extensions` list.\n\nWhen both `opts.broli` and `opts.gzip` are enabled &mdash; and all conditions are equal &mdash; then the brotli variant always takes priority.\n\n```js\n// NOTE: PSEUDO CODE\n// Showing lookup logic\n\n// Request: [Accept-Encoding: br] \"/foobar.jpg\"\nlookup([\n  '/foobar.jpg.br', '/foobar.jpg',\n  '/foobar.jpg.html.br', '/foobar.jpg/index.html.br',\n  '/foobar.jpg.htm.br', '/foobar.jpg/index.htm.br',\n  '/foobar.jpg.html', '/foobar.jpg/index.html',\n  '/foobar.jpg.htm', '/foobar.jpg/index.htm',\n]);\n\n// Request: [Accept-Encoding: br,gz] \"/\"\nlookup([\n  '/index.html.br'\n  '/index.htm.br'\n  '/index.html.gz'\n  '/index.htm.gz'\n  '/index.html'\n  '/index.htm'\n]);\n```\n\n#### opts.maxAge\nType: `Number`<br>\nDefault: `undefined`\n\nEnables the `Cache-Control` header on responses and sets the `max-age` value (in seconds).<br>\nFor example, `maxAge: 31536000` is equivalent to one year.\n\n#### opts.immutable\nType: `Boolean`<br>\nDefault: `false`\n\nAppends the [`immutable` directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Revalidation_and_reloading) on your `Cache-Control` header, used for uniquely-named assets that will not change!\n\n> **Important:** Will only work if `opts.maxAge` has a value defined!\n\n#### opts.single\nType: `Boolean` or `String`<br>\nDefault: `false`\n\nTreat the directory as a single-page application.\n\nWhen `true`, the directory's index page (default `index.html`) will be sent if the request asset does not exist.<br>\nYou may pass a `string` value to use a file _instead of_ `index.html` as your fallback.\n\nFor example, if \"/about\" is requested but no variants of that file exist, then the response for \"/\" is sent instead:\n\n```js\n// Note: This is psuedo code to illustrate what's happening\n\n// Request: \"/about\"\nlet file = find(['/about', '/about.html', '/about.htm', '/about/index.html', '/about.htm']);\nif (file) {\n  send(file);\n} else if (opts.single === true) {\n  file = find(['/', '/index.html', '/index.htm']);\n  send(file);\n} else if (typeof opts.single === 'string') {\n  file = find([opts.single]);\n  send(file);\n} else {\n  // next() or 404\n}\n```\n\n#### opts.ignores\nType: `false` or `Array<String | RegExp>`\n\nSpecify paths/patterns that should ignore the fallback behavior that `opts.single` provides.\n\nBy default, any asset-like path (URLs that end with an extension) will be ignored. This means that, for example, if `/foobar.jpg` is not found, a `404` response is sent instead of the `index.html` fallback.\n\nAdditionally, any `/.well-known/*` pathname ignores the fallback – as do all other dotfile requests when `opts.dotfiles` is enabled.\n\nAny string value(s) will be passed through `new RegExp(value, 'i')` directly.\n\nFinally, you may set `ignores: false` to disable ***all*** ignores, including the defaults. Put differently, this will fallback ***all*** unknown pathnames to your `index.html` (or custom `opts.single` value).\n\n> **Important:** Only has an effect if `opts.single` is enabled.\n\n#### opts.onNoMatch\nType: `Function`\n\nA custom function to run if a file cannot be found for a given request. <br>By default, `sirv` will send a basic `(404) Not found` response.\n\nThe function receives the current `req <IncomingMessage>, res <ServerResponse>` pair for as its two arguments.\n\n> **Note:** This won't run if a `next` callback has been provided to the middleware; see [`sirv`](#sirvdir-opts) description.\n\n#### opts.setHeaders\nType: `Function`\n\nA custom function to append or change any headers on the outgoing response. There is no default.\n\nIts signature is `(res, pathname, stats)`, where `res` is the `ServerResponse`, `pathname` is incoming request path (stripped of queries), and `stats` is the file's result from [`fs.statSync`](https://nodejs.org/api/fs.html#fs_fs_statsync_path).\n\n\n## License\n\nMIT © [Luke Edwards](https://lukeed.com)\n","readmeFilename":"readme.md"}