{
  "version": 3,
  "sources": ["../../../../src/workers/ratelimit/ratelimit.worker.ts"],
  "sourcesContent": ["// Emulated Ratelimit Binding\n//\n// Thin client: keeps option validation local (so error messages surface\n// synchronously in the caller's isolate), forwards each `.limit()` call to\n// the `RateLimiterObject` Durable Object, which owns the bucket/epoch state.\n\n// ENV configuration\ninterface RatelimitConfig {\n\tlimit: number;\n\tperiod: number;\n\tfetcher: Fetcher;\n}\n\n// options for Ratelimit\n//   (should be kept in sync with https://bitbucket.cfdata.org/projects/EW/repos/edgeworker/browse/src/edgeworker/internal-api/ratelimit.capnp)\nconst RatelimitOptionKeys = [\"key\", \"limit\", \"period\"];\nconst RatelimitPeriodValues = [10, 60];\n\n// result from Ratelimit call\n//   (should be kept in sync with https://bitbucket.cfdata.org/projects/EW/repos/edgeworker/browse/src/edgeworker/internal-api/ratelimit.capnp)\ninterface RatelimitResult {\n\tsuccess: boolean;\n}\n\nfunction validate(test: boolean, message: string): asserts test {\n\tif (!test) {\n\t\tthrow new Error(message);\n\t}\n}\n\nclass Ratelimit {\n\tfetcher: Fetcher;\n\tlimitVal: number;\n\tperiod: number;\n\n\tconstructor(config: RatelimitConfig) {\n\t\tthis.fetcher = config.fetcher;\n\t\tthis.limitVal = config.limit;\n\t\tthis.period = config.period;\n\t}\n\n\t// method that counts and checks against the limit, delegating the actual\n\t// bucket/epoch bookkeeping to the `RateLimiterObject` Durable Object\n\tasync limit(options: unknown): Promise<RatelimitResult> {\n\t\t// validate options input\n\t\tvalidate(\n\t\t\ttypeof options === \"object\" && options !== null,\n\t\t\t\"invalid rate limit options\"\n\t\t);\n\t\tconst invalidProps = Object.keys(options ?? {}).filter(\n\t\t\t(key) => !RatelimitOptionKeys.includes(key)\n\t\t);\n\t\tvalidate(\n\t\t\tinvalidProps.length == 0,\n\t\t\t`bad rate limit options: [${invalidProps.join(\",\")}]`\n\t\t);\n\t\tconst {\n\t\t\tkey = \"\",\n\t\t\tlimit = this.limitVal,\n\t\t\tperiod = this.period,\n\t\t} = options as Record<string, unknown>;\n\t\tvalidate(typeof key === \"string\", `invalid key: ${key}`);\n\t\tvalidate(typeof limit === \"number\", `limit must be a number: ${limit}`);\n\t\tvalidate(typeof period === \"number\", `period must be a number: ${period}`);\n\t\tvalidate(\n\t\t\tRatelimitPeriodValues.includes(period),\n\t\t\t`unsupported period: ${period}`\n\t\t);\n\n\t\tconst res = await this.fetcher.fetch(\"http://ratelimit/limit\", {\n\t\t\tmethod: \"POST\",\n\t\t\tbody: JSON.stringify({ key, limit, period }),\n\t\t});\n\t\treturn await res.json<RatelimitResult>();\n\t}\n}\n\n// create a new Ratelimit\nexport default function (env: RatelimitConfig) {\n\treturn new Ratelimit(env);\n}\n"],
  "mappings": ";AAeA,IAAM,sBAAsB,CAAC,OAAO,SAAS,QAAQ,GAC/C,wBAAwB,CAAC,IAAI,EAAE;AAQrC,SAAS,SAAS,MAAe,SAA+B;AAC/D,MAAI,CAAC;AACJ,UAAM,IAAI,MAAM,OAAO;AAEzB;AAEA,IAAM,YAAN,MAAgB;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,QAAyB;AACpC,SAAK,UAAU,OAAO,SACtB,KAAK,WAAW,OAAO,OACvB,KAAK,SAAS,OAAO;AAAA,EACtB;AAAA;AAAA;AAAA,EAIA,MAAM,MAAM,SAA4C;AAEvD;AAAA,MACC,OAAO,WAAY,YAAY,YAAY;AAAA,MAC3C;AAAA,IACD;AACA,QAAM,eAAe,OAAO,KAAK,WAAW,CAAC,CAAC,EAAE;AAAA,MAC/C,CAACA,SAAQ,CAAC,oBAAoB,SAASA,IAAG;AAAA,IAC3C;AACA;AAAA,MACC,aAAa,UAAU;AAAA,MACvB,4BAA4B,aAAa,KAAK,GAAG,CAAC;AAAA,IACnD;AACA,QAAM;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,IACf,IAAI;AACJ,oBAAS,OAAO,OAAQ,UAAU,gBAAgB,GAAG,EAAE,GACvD,SAAS,OAAO,SAAU,UAAU,2BAA2B,KAAK,EAAE,GACtE,SAAS,OAAO,UAAW,UAAU,4BAA4B,MAAM,EAAE,GACzE;AAAA,MACC,sBAAsB,SAAS,MAAM;AAAA,MACrC,uBAAuB,MAAM;AAAA,IAC9B,GAMO,OAJK,MAAM,KAAK,QAAQ,MAAM,0BAA0B;AAAA,MAC9D,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,EAAE,KAAK,OAAO,OAAO,CAAC;AAAA,IAC5C,CAAC,GACgB,KAAsB;AAAA,EACxC;AACD;AAGe,SAAR,yBAAkB,KAAsB;AAC9C,SAAO,IAAI,UAAU,GAAG;AACzB;",
  "names": ["key"]
}
