{"version":3,"file":"index.mjs","sources":["../src/internal.ts","../src/util.ts","../src/parse.ts","../src/tokenize.ts","../src/index.ts"],"sourcesContent":["/** @internal */\nexport const cacheControlSymbol = Symbol('cache-parser');\n","export function isDuration(val: unknown): boolean {\n  return (\n    (typeof val === 'string' || typeof val === 'number') &&\n    // biome-ignore lint/suspicious/noAssignInExpressions: to reduce one line\n    (val = Number(val)) >= 0 &&\n    (val as number) < Number.POSITIVE_INFINITY\n  );\n}\n\nexport function isTruthy(val: unknown): boolean {\n  return (\n    val === true ||\n    typeof val === 'number' ||\n    (typeof val === 'string' && val !== 'false')\n  );\n}\n\nexport function parseRawHeaders(headerStr: string): Record<string, string | true> {\n  const headers: Record<string, string | true> = {};\n  const tokens = headerStr.toLowerCase().replace(/\\s+/g, '').split(',');\n\n  for (const token of tokens) {\n    const split = token.split('=', 2) as [string, string];\n    headers[split[0]] = split[1] ?? true;\n  }\n\n  return headers;\n}\n","import type { CacheControl } from './index';\nimport { cacheControlSymbol } from './internal';\nimport { isDuration, isTruthy, parseRawHeaders } from './util';\n\nconst number = Number;\n\n/**\n * Parses the Cache-Control header.\n *\n * You can check if a object was returned by this function with {@link isCacheControl} .\n *\n * @param {string} Header The header to parse\n * @returns {CacheControl} The parsed cache control header\n */\nexport function parse(headerStr?: string): CacheControl {\n  const header: CacheControl = Object.defineProperty({}, cacheControlSymbol, {\n    enumerable: false,\n    value: 1\n  });\n\n  if (!headerStr || typeof headerStr !== 'string') {\n    return header;\n  }\n\n  const headers = parseRawHeaders(headerStr);\n\n  const maxAge = headers['max-age'];\n  const maxStale = headers['max-stale'];\n  const minFresh = headers['min-fresh'];\n  const sMaxAge = headers['s-maxage'];\n  const staleIfError = headers['stale-if-error'];\n  const staleWhileRevalidate = headers['stale-while-revalidate'];\n\n  if (isTruthy(headers.immutable)) {\n    header.immutable = true;\n  }\n\n  if (isDuration(maxAge)) {\n    header.maxAge = number(maxAge);\n  }\n\n  if (isDuration(maxStale)) {\n    header.maxStale = number(maxStale);\n  }\n\n  if (isDuration(minFresh)) {\n    header.minFresh = number(minFresh);\n  }\n\n  if (isTruthy(headers['must-revalidate'])) {\n    header.mustRevalidate = true;\n  }\n\n  if (isTruthy(headers['must-understand'])) {\n    header.mustUnderstand = true;\n  }\n\n  if (isTruthy(headers['no-cache'])) {\n    header.noCache = true;\n  }\n\n  if (isTruthy(headers['no-store'])) {\n    header.noStore = true;\n  }\n\n  if (isTruthy(headers['no-transform'])) {\n    header.noTransform = true;\n  }\n\n  if (isTruthy(headers['only-if-cached'])) {\n    header.onlyIfCached = true;\n  }\n\n  if (isTruthy(headers.private)) {\n    header.private = true;\n  }\n\n  if (isTruthy(headers['proxy-revalidate'])) {\n    header.proxyRevalidate = true;\n  }\n\n  if (isTruthy(headers.public)) {\n    header.public = true;\n  }\n\n  if (isDuration(sMaxAge)) {\n    header.sMaxAge = number(sMaxAge);\n  }\n\n  if (isDuration(staleIfError)) {\n    header.staleIfError = number(staleIfError);\n  }\n\n  if (isDuration(staleWhileRevalidate)) {\n    header.staleWhileRevalidate = number(staleWhileRevalidate);\n  }\n\n  return header;\n}\n","/* eslint-disable @typescript-eslint/restrict-template-expressions */\nimport type { CacheControl } from './index';\nimport { isDuration, isTruthy } from './util';\n\n/**\n * Return an array of tokens from the header object.\n *\n * #### The output is sorted by alphabetical order\n *\n * The cache control object does not need to be a CacheControl object from the\n * {@link CacheControl}.This means that the parameter do not have to pass in the\n * {@link isCacheControl} function.\n *\n * You can build a string with `.join(', ')` method.\n *\n * @example\n *\n * ```js\n * const tokens = tokenize({ maxAge: 3600, noCache: true }); // ['max-age=3600',\n * 'no-cache']\n *\n * const header = tokens.join(', '); // 'max-age=3600, no-cache'\n * ```\n *\n * @param header The cache control object\n * @returns An array of directives an their respective values.\n */\nexport function tokenize(header?: CacheControl): string[] {\n  if (!header || typeof header !== 'object') {\n    return [];\n  }\n\n  const tokens: string[] = [];\n\n  if (isTruthy(header.immutable)) {\n    tokens.push('immutable');\n  }\n\n  if (isDuration(header.maxAge)) {\n    tokens.push(`max-age=${header.maxAge}`);\n  }\n\n  if (isDuration(header.maxStale)) {\n    tokens.push(`max-stale=${header.maxStale}`);\n  }\n\n  if (isDuration(header.minFresh)) {\n    tokens.push(`min-fresh=${header.minFresh}`);\n  }\n\n  if (isTruthy(header.mustRevalidate)) {\n    tokens.push('must-revalidate');\n  }\n\n  if (isTruthy(header.mustUnderstand)) {\n    tokens.push('must-understand');\n  }\n\n  if (isTruthy(header.noCache)) {\n    tokens.push('no-cache');\n  }\n\n  if (isTruthy(header.noStore)) {\n    tokens.push('no-store');\n  }\n\n  if (isTruthy(header.noTransform)) {\n    tokens.push('no-transform');\n  }\n\n  if (isTruthy(header.onlyIfCached)) {\n    tokens.push('only-if-cached');\n  }\n\n  if (isTruthy(header.private)) {\n    tokens.push('private');\n  }\n\n  if (isTruthy(header.proxyRevalidate)) {\n    tokens.push('proxy-revalidate');\n  }\n\n  if (isTruthy(header.public)) {\n    tokens.push('public');\n  }\n\n  if (isDuration(header.sMaxAge)) {\n    tokens.push(`s-maxage=${header.sMaxAge}`);\n  }\n\n  if (isDuration(header.staleIfError)) {\n    tokens.push(`stale-if-error=${header.staleIfError}`);\n  }\n\n  if (isDuration(header.staleWhileRevalidate)) {\n    tokens.push(`stale-while-revalidate=${header.staleWhileRevalidate}`);\n  }\n\n  return tokens;\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access */\nimport { cacheControlSymbol } from './internal';\n\nexport * from './parse';\nexport * from './tokenize';\n\n/**\n * Detects if the given parameter is a {@link CacheControl} object.\n *\n * @param {any} obj The object to test\n * @returns {boolean} True if the parameter was created by the {@link parse} function\n */\nexport function isCacheControl(obj?: unknown): obj is CacheControl {\n  return !!obj && !!(obj as Record<symbol, boolean>)[cacheControlSymbol];\n}\n\n/**\n * The Cache-Control HTTP header field holds directives (instructions) — in both requests\n * and responses — that control caching in browsers and shared caches (e.g. Proxies,\n * CDNs).\n *\n * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control\n */\nexport declare type CacheControl = {\n  /**\n   * The immutable response directive indicates that the response will not be updated\n   * while it's fresh.\n   *\n   * ```txt\n   * Cache-Control: public, max-age=604800, immutable\n   * ```\n   *\n   * A modern best practice for static resources is to include version/hashes in their\n   * URLs, while never modifying the resources — but instead, when necessary, updating the\n   * resources with newer versions that have new version-numbers/hashes, so that their\n   * URLs are different. That’s called the cache-busting pattern.\n   *\n   * ```html\n   * <script src=https://example.com/react.0.0.0.js></script>\n   * ```\n   *\n   * When a user reloads the browser, the browser will send conditional requests for\n   * validating to the origin server. But it's not necessary to revalidate those kinds of\n   * static resources even when a user reloads the browser, because they're never\n   * modified. immutable tells a cache that the response is immutable while it's fresh,\n   * and avoids those kinds of unnecessary conditional requests to the server.\n   *\n   * When you use a cache-busting pattern for resources and apply them to a long max-age,\n   * you can also add immutable to avoid revalidation.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#immutable\n   */\n  immutable?: true;\n  /**\n   * The max-age=N response directive indicates that the response remains fresh until N\n   * seconds after the response is generated.\n   *\n   * ```txt\n   * Cache-Control: max-age=604800\n   * ```\n   *\n   * Indicates that caches can store this response and reuse it for subsequent requests\n   * while it's fresh.\n   *\n   * Note that max-age is not the elapsed time since the response was received, but\n   * instead the elapsed time since the response was generated on the origin server. So if\n   * the other cache(s) on the path the response takes store it for 100 seconds (indicated\n   * using the Age response header field), the browser cache would deduct 100 seconds from\n   * its freshness lifetime.\n   *\n   * ```txt\n   * Cache-Control: max-age=604800\n   * Age: 100\n   * ```\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-age\n   */\n  maxAge?: number;\n  /**\n   * The max-stale=N request directive indicates that the client allows a stored response\n   * that is stale within N seconds.\n   *\n   * ```txt\n   * Cache-Control: max-stale=3600\n   * ```\n   *\n   * In the case above, if the response with Cache-Control: max-age=604800 was stored on\n   * caches 3 hours ago, the cache couldn't reuse that response.\n   *\n   * Clients can use this header when the origin server is down or too slow and can accept\n   * cached responses from caches even if they are a bit old.\n   *\n   * Note that the major browsers do not support requests with max-stale.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#max-stale\n   */\n  maxStale?: number;\n  /**\n   * The min-fresh=N request directive indicates that the client allows a stored response\n   * that is fresh for at least N seconds.\n   *\n   * ```txt\n   * Cache-Control: min-fresh=600\n   * ```\n   *\n   * In the case above, if the response with Cache-Control: max-age=3600 was stored in\n   * caches 51 minutes ago, the cache couldn't reuse that response.\n   *\n   * Clients can use this header when the user requires the response to not only be fresh,\n   * but also requires that it won't be updated for a period of time.\n   *\n   * Note that the major browsers do not support requests with min-fresh.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#min-fresh\n   */\n  minFresh?: number;\n  /**\n   * The must-revalidate response directive indicates that the response can be stored in\n   * caches and can be reused while fresh. Once it becomes stale, it must be validated\n   * with the origin server before reuse.\n   *\n   * Typically, must-revalidate is used with max-age.\n   *\n   * ```txt\n   * Cache-Control: max-age=604800, must-revalidate\n   * ```\n   *\n   * HTTP allows caches to reuse stale responses when they are disconnected from the\n   * origin server. must-revalidate is a way to prevent that, so that the cache either\n   * revalidates the stored response with the origin server, or if that's not possible it\n   * generates a 504 (Gateway Timeout) response.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#must-revalidate\n   */\n  mustRevalidate?: true;\n\n  mustUnderstand?: true;\n  /**\n   * The no-cache response directive indicates that the response can be stored in caches,\n   * but must be validated with the origin server before each reuse — even when the cache\n   * is disconnected from the origin server.\n   *\n   * ```txt\n   * Cache-Control: no-cache\n   * ```\n   *\n   * If you want caches to always check for content updates while reusing stored content\n   * when it hasn't changed, no-cache is the directive to use. It does this by requiring\n   * caches to revalidate each request with the origin server.\n   *\n   * Note that no-cache does not mean \"don't cache\". no-cache allows caches to store a\n   * response, but requires them to revalidate it before reuse. If the sense of \"don't\n   * cache\" that you want is actually \"don't store\", then no-store is the directive to\n   * use.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-cache\n   */\n  noCache?: true;\n  /**\n   * The no-store response directive indicates that any caches of any kind (private or\n   * shared) should not store this response.\n   *\n   * ```txt\n   * Cache-Control: no-store\n   * ```\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-store\n   */\n  noStore?: true;\n  /**\n   * Some intermediaries transform content for various reasons. For example, some convert\n   * images to reduce transfer size. In some cases, this is undesirable for the content\n   * provider.\n   *\n   * No-transform indicates that any intermediary (regardless of whether it implements a\n   * cache) shouldn't transform the response contents.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#no-transform\n   */\n  noTransform?: true;\n  /**\n   * The client indicates that cache should obtain an already-cached response. If a cache\n   * has stored a response, it’s reused.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#only-if-cached\n   */\n  onlyIfCached?: true;\n  /**\n   * The private response directive indicates that the response can be stored only in a\n   * private cache (e.g. local caches in browsers).\n   *\n   * ```txt\n   * Cache-Control: private\n   * ```\n   *\n   * You should add the private directive for user-personalized content — in particular,\n   * responses received after login, and sessions managed via cookies.\n   *\n   * If you forget to add private to a response with personalized content, then that\n   * response can be stored in a shared cache and end up being used by multiple users,\n   * which can cause personal information to leak.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#private\n   */\n  private?: true;\n  /**\n   * The proxy-revalidate response directive is the equivalent of must-revalidate, but\n   * specifically for shared caches only.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#proxy-revalidate\n   */\n  proxyRevalidate?: true;\n  /**\n   * Responses for requests with Authorization header fields must not be stored in a\n   * shared cache. But the public directive will cause such responses to be stored in a\n   * shared cache.\n   *\n   * ```txt\n   * Cache-Control: public\n   * ```\n   *\n   * In general, when pages are under Basic Auth or Digest Auth, the browser sends\n   * requests with the Authorization header. That means the response is access-controlled\n   * for restricted users (who have accounts), and it's fundamentally not\n   * shared-cacheable, even if it has max-age.\n   *\n   * You can use the public directive to unlock that restriction.\n   *\n   * ```txt\n   * Cache-Control: public, max-age=604800\n   * ```\n   *\n   * Note that, s-maxage or must-revalidate also unlock that restriction.\n   *\n   * If a request doesn’t have an Authorization header, or you are already using s-maxage\n   * or must-revalidate in the response, then you don't need to use public.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#public\n   */\n  public?: true;\n  /**\n   * The s-maxage response directive also indicates how long the response is fresh for\n   * (similar to max-age) — but it is specific to shared caches, and they will ignore\n   * max-age when it is present.\n   *\n   * ```txt\n   * Cache-Control: s-maxage=604800\n   * ```\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#s-maxage\n   */\n  sMaxAge?: number;\n  /**\n   * The stale-if-error response directive indicates that the cache can reuse a stale\n   * response when an origin server responds with an error (500, 502, 503, or 504).\n   *\n   * ```txt\n   * Cache-Control: max-age=604800, stale-if-error=86400\n   * ```\n   *\n   * In the example above, the response is fresh for 7 days (604800s). After 7 days it\n   * becomes stale, but it can be used for an extra 1 day (86400s) if the server responds\n   * with an error.\n   *\n   * After a period of time, the stored response became stale normally. That means the\n   * client will receive an error response as-is if the origin server sends it.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-if-error\n   */\n  staleIfError?: number;\n  /**\n   * The stale-while-revalidate response directive indicates that the cache could reuse a\n   * stale response while it revalidates it to a cache.\n   *\n   * ```txt\n   * Cache-Control: max-age=604800, stale-while-revalidate=86400\n   * ```\n   *\n   * In the example above, the response is fresh for 7 days (604800s). After 7 days, it\n   * becomes stale but the cache is allowed to reuse it for any requests that are made in\n   * the following day (86400s) — provided that they revalidate the response in the\n   * background.\n   *\n   * Revalidation will make the cache be fresh again, so it appears to clients that it was\n   * always fresh during that period — effectively hiding the latency penalty of\n   * revalidation from them.\n   *\n   * If no request happened during that period, the cache became stale and the next\n   * request will revalidate normally.\n   *\n   * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#stale-while-revalidate\n   */\n  staleWhileRevalidate?: number;\n};\n"],"names":["cacheControlSymbol","Symbol","isDuration","val","Number","POSITIVE_INFINITY","isTruthy","number","parse","headerStr","header","Object","defineProperty","enumerable","value","headers","_step","_iterator","_createForOfIteratorHelperLoose","toLowerCase","replace","split","done","_split$","parseRawHeaders","maxAge","maxStale","minFresh","sMaxAge","staleIfError","staleWhileRevalidate","immutable","mustRevalidate","mustUnderstand","noCache","noStore","noTransform","onlyIfCached","proxyRevalidate","tokenize","tokens","push","isCacheControl","obj"],"mappings":"IACaA,EAAqBC,OAAO,+HCDzBC,EAAWC,GACzB,OACkB,iBAARA,GAAmC,iBAARA,KAElCA,EAAMC,OAAOD,KAAS,GACtBA,EAAiBC,OAAOC,iBAE7B,CAEM,SAAUC,EAASH,GACvB,OACU,IAARA,GACe,iBAARA,GACS,iBAARA,GAA4B,UAARA,CAEhC,CCXA,IAAMI,EAASH,OAUC,SAAAI,EAAMC,GACpB,IAAMC,EAAuBC,OAAOC,eAAe,GAAIZ,EAAoB,CACzEa,YAAY,EACZC,MAAO,IAGT,IAAKL,GAAkC,iBAAdA,EACvB,OAAOC,EAGT,IAAMK,EDPQ,SAAgBN,GAI9B,IAHA,IAG0BO,EAHpBD,EAAyC,CAAE,EAGjDE,2pBAAAC,CAFeT,EAAUU,cAAcC,QAAQ,OAAQ,IAAIC,MAAM,QAEvCL,EAAAC,KAAAK,MAAE,CAAA,IAAAC,EACpBF,EADQL,EAAAF,MACMO,MAAM,IAAK,GAC/BN,EAAQM,EAAM,WAAGE,EAAGF,EAAM,KAAEE,CAC9B,CAEA,OAAOR,CACT,CCHkBS,CAAgBf,GAE1BgB,EAASV,EAAQ,WACjBW,EAAWX,EAAQ,aACnBY,EAAWZ,EAAQ,aACnBa,EAAUb,EAAQ,YAClBc,EAAed,EAAQ,kBACvBe,EAAuBf,EAAQ,0BAkErC,OAhEIT,EAASS,EAAQgB,aACnBrB,EAAOqB,WAAY,GAGjB7B,EAAWuB,KACbf,EAAOe,OAASlB,EAAOkB,IAGrBvB,EAAWwB,KACbhB,EAAOgB,SAAWnB,EAAOmB,IAGvBxB,EAAWyB,KACbjB,EAAOiB,SAAWpB,EAAOoB,IAGvBrB,EAASS,EAAQ,sBACnBL,EAAOsB,gBAAiB,GAGtB1B,EAASS,EAAQ,sBACnBL,EAAOuB,gBAAiB,GAGtB3B,EAASS,EAAQ,eACnBL,EAAOwB,SAAU,GAGf5B,EAASS,EAAQ,eACnBL,EAAOyB,SAAU,GAGf7B,EAASS,EAAQ,mBACnBL,EAAO0B,aAAc,GAGnB9B,EAASS,EAAQ,qBACnBL,EAAO2B,cAAe,GAGpB/B,EAASS,aACXL,EAAM,SAAW,GAGfJ,EAASS,EAAQ,uBACnBL,EAAO4B,iBAAkB,GAGvBhC,EAASS,EAAO,UAClBL,EAAa,QAAG,GAGdR,EAAW0B,KACblB,EAAOkB,QAAUrB,EAAOqB,IAGtB1B,EAAW2B,KACbnB,EAAOmB,aAAetB,EAAOsB,IAG3B3B,EAAW4B,KACbpB,EAAOoB,qBAAuBvB,EAAOuB,IAGhCpB,CACT,CCvEgB,SAAA6B,EAAS7B,GACvB,IAAKA,GAA4B,iBAAXA,EACpB,MAAO,GAGT,IAAM8B,EAAmB,GAkEzB,OAhEIlC,EAASI,EAAOqB,YAClBS,EAAOC,KAAK,aAGVvC,EAAWQ,EAAOe,SACpBe,EAAOC,KAAgB/B,WAAAA,EAAOe,QAG5BvB,EAAWQ,EAAOgB,WACpBc,EAAOC,kBAAkB/B,EAAOgB,UAG9BxB,EAAWQ,EAAOiB,WACpBa,EAAOC,KAAI,aAAc/B,EAAOiB,UAG9BrB,EAASI,EAAOsB,iBAClBQ,EAAOC,KAAK,mBAGVnC,EAASI,EAAOuB,iBAClBO,EAAOC,KAAK,mBAGVnC,EAASI,EAAOwB,UAClBM,EAAOC,KAAK,YAGVnC,EAASI,EAAOyB,UAClBK,EAAOC,KAAK,YAGVnC,EAASI,EAAO0B,cAClBI,EAAOC,KAAK,gBAGVnC,EAASI,EAAO2B,eAClBG,EAAOC,KAAK,kBAGVnC,EAASI,EAAM,UACjB8B,EAAOC,KAAK,WAGVnC,EAASI,EAAO4B,kBAClBE,EAAOC,KAAK,oBAGVnC,EAASI,EAAM,SACjB8B,EAAOC,KAAK,UAGVvC,EAAWQ,EAAOkB,UACpBY,EAAOC,KAAiB/B,YAAAA,EAAOkB,SAG7B1B,EAAWQ,EAAOmB,eACpBW,EAAOC,uBAAuB/B,EAAOmB,cAGnC3B,EAAWQ,EAAOoB,uBACpBU,EAAOC,KAA+B/B,0BAAAA,EAAOoB,sBAGxCU,CACT,CCvFM,SAAUE,EAAeC,GAC7B,QAASA,KAAUA,EAAgC3C,EACrD"}