@unkey/api 0.10.3 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -50,6 +50,10 @@ type UnkeyOptions = ({
50
50
  */
51
51
  backoff?: (retryCount: number) => number;
52
52
  };
53
+ /**
54
+ * Customize the `fetch` cache behaviour
55
+ */
56
+ cache?: RequestCache;
53
57
  };
54
58
  type Result<R> = {
55
59
  result: R;
@@ -61,6 +65,7 @@ type Result<R> = {
61
65
  declare class Unkey {
62
66
  readonly baseUrl: string;
63
67
  private readonly rootKey;
68
+ private readonly cache?;
64
69
  readonly retry: {
65
70
  attempts: number;
66
71
  backoff: (retryCount: number) => number;
@@ -211,7 +216,16 @@ declare class Unkey {
211
216
  keyId: string;
212
217
  }>>;
213
218
  verify: (req: {
219
+ /**
220
+ * The key to verify
221
+ */
214
222
  key: string;
223
+ /**
224
+ * The api id to verify against
225
+ *
226
+ * This will be required soon.
227
+ */
228
+ apiId?: string;
215
229
  }) => Promise<Result<{
216
230
  /**
217
231
  * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting
@@ -400,7 +414,10 @@ declare class Unkey {
400
414
  * console.log(result)
401
415
  * ```
402
416
  */
403
- declare function verifyKey(key: string): Promise<{
417
+ declare function verifyKey(req: string | {
418
+ key: string;
419
+ apiId: string;
420
+ }): Promise<{
404
421
  result?: undefined;
405
422
  error: UnkeyError;
406
423
  } | {
package/dist/index.d.ts CHANGED
@@ -50,6 +50,10 @@ type UnkeyOptions = ({
50
50
  */
51
51
  backoff?: (retryCount: number) => number;
52
52
  };
53
+ /**
54
+ * Customize the `fetch` cache behaviour
55
+ */
56
+ cache?: RequestCache;
53
57
  };
54
58
  type Result<R> = {
55
59
  result: R;
@@ -61,6 +65,7 @@ type Result<R> = {
61
65
  declare class Unkey {
62
66
  readonly baseUrl: string;
63
67
  private readonly rootKey;
68
+ private readonly cache?;
64
69
  readonly retry: {
65
70
  attempts: number;
66
71
  backoff: (retryCount: number) => number;
@@ -211,7 +216,16 @@ declare class Unkey {
211
216
  keyId: string;
212
217
  }>>;
213
218
  verify: (req: {
219
+ /**
220
+ * The key to verify
221
+ */
214
222
  key: string;
223
+ /**
224
+ * The api id to verify against
225
+ *
226
+ * This will be required soon.
227
+ */
228
+ apiId?: string;
215
229
  }) => Promise<Result<{
216
230
  /**
217
231
  * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting
@@ -400,7 +414,10 @@ declare class Unkey {
400
414
  * console.log(result)
401
415
  * ```
402
416
  */
403
- declare function verifyKey(key: string): Promise<{
417
+ declare function verifyKey(req: string | {
418
+ key: string;
419
+ apiId: string;
420
+ }): Promise<{
404
421
  result?: undefined;
405
422
  error: UnkeyError;
406
423
  } | {
package/dist/index.js CHANGED
@@ -29,10 +29,12 @@ module.exports = __toCommonJS(src_exports);
29
29
  var Unkey = class {
30
30
  baseUrl;
31
31
  rootKey;
32
+ cache;
32
33
  retry;
33
34
  constructor(opts) {
34
35
  this.baseUrl = opts.baseUrl ?? "https://api.unkey.dev";
35
36
  this.rootKey = opts.rootKey ?? opts.token;
37
+ this.cache = opts.cache;
36
38
  if (!this.rootKey) {
37
39
  throw new Error(
38
40
  "Unkey root key must be set, maybe you passed in `undefined` or an empty string?"
@@ -59,8 +61,8 @@ var Unkey = class {
59
61
  "Content-Type": "application/json",
60
62
  Authorization: `Bearer ${this.rootKey}`
61
63
  },
62
- body: JSON.stringify(req.body),
63
- cache: req.cache
64
+ cache: this.cache,
65
+ body: JSON.stringify(req.body)
64
66
  }).catch((e) => {
65
67
  err = e;
66
68
  return null;
@@ -99,31 +101,27 @@ var Unkey = class {
99
101
  return await this.fetch({
100
102
  path: ["v1", "keys"],
101
103
  method: "POST",
102
- body: req,
103
- cache: "no-cache"
104
+ body: req
104
105
  });
105
106
  },
106
107
  update: async (req) => {
107
108
  return await this.fetch({
108
109
  path: ["v1", "keys", req.keyId],
109
110
  method: "PUT",
110
- body: req,
111
- cache: "no-cache"
111
+ body: req
112
112
  });
113
113
  },
114
114
  verify: async (req) => {
115
115
  return await this.fetch({
116
116
  path: ["v1", "keys", "verify"],
117
117
  method: "POST",
118
- body: req,
119
- cache: "no-cache"
118
+ body: req
120
119
  });
121
120
  },
122
121
  revoke: async (req) => {
123
122
  return await this.fetch({
124
123
  path: ["v1", "keys", req.keyId],
125
- method: "DELETE",
126
- cache: "no-cache"
124
+ method: "DELETE"
127
125
  });
128
126
  }
129
127
  };
@@ -134,23 +132,20 @@ var Unkey = class {
134
132
  return await this.fetch({
135
133
  path: ["v1", "apis.createApi"],
136
134
  method: "POST",
137
- body: req,
138
- cache: "no-cache"
135
+ body: req
139
136
  });
140
137
  },
141
138
  remove: async (req) => {
142
139
  return await this.fetch({
143
140
  path: ["v1", "apis.removeApi"],
144
141
  method: "POST",
145
- body: req,
146
- cache: "no-cache"
142
+ body: req
147
143
  });
148
144
  },
149
145
  get: async (req) => {
150
146
  return await this.fetch({
151
147
  path: ["v1", "apis", req.apiId],
152
- method: "GET",
153
- cache: "no-cache"
148
+ method: "GET"
154
149
  });
155
150
  },
156
151
  listKeys: async (req) => {
@@ -167,8 +162,7 @@ var Unkey = class {
167
162
  return await this.fetch({
168
163
  path: ["v1", "apis", req.apiId, "keys"],
169
164
  method: "GET",
170
- query,
171
- cache: "no-cache"
165
+ query
172
166
  });
173
167
  }
174
168
  };
@@ -182,16 +176,14 @@ var Unkey = class {
182
176
  return await this.fetch({
183
177
  path: ["v1", "internal", "rootkeys"],
184
178
  method: "POST",
185
- body: req,
186
- cache: "no-cache"
179
+ body: req
187
180
  });
188
181
  },
189
182
  deleteRootKey: async (req) => {
190
183
  return await this.fetch({
191
184
  path: ["v1", "internal.removeRootKey"],
192
185
  method: "POST",
193
- body: req,
194
- cache: "no-cache"
186
+ body: req
195
187
  });
196
188
  }
197
189
  };
@@ -199,9 +191,9 @@ var Unkey = class {
199
191
  };
200
192
 
201
193
  // src/verify.ts
202
- function verifyKey(key) {
194
+ function verifyKey(req) {
203
195
  const unkey = new Unkey({ token: "public" });
204
- return unkey.keys.verify({ key });
196
+ return unkey.keys.verify(typeof req === "string" ? { key: req } : req);
205
197
  }
206
198
  // Annotate the CommonJS export names for ESM import in node:
207
199
  0 && (module.exports = {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\n","import { UnkeyError } from \"./errors\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n // some change\n};\n\ntype ApiRequest = {\n path: string[];\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n query?: Record<string, string>;\n cache?: RequestCache;\n};\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: UnkeyError;\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v);\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n },\n body: JSON.stringify(req.body),\n cache: req.cache,\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: await res.json() };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: await res.json() };\n }\n\n return {\n error: {\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n /**\n * Choose an API where this key should be created.\n */\n apiId: string;\n /**\n * To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n *\n * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n *\n * The underscore is automtically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n */\n prefix?: string;\n\n /**\n * The bytelength used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle.\n *\n * The default is 16 bytes, or 2128 possible combinations\n */\n byteLength?: number;\n /**\n * Your user’s Id. This will provide a link between Unkey and your customer record.\n *\n * When validating a key, we will return this back to you, so you can clearly identify your user from their api key.\n */\n ownerId?: string;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n /**\n * Unkey comes with per-key ratelimiting out of the box.\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n };\n\n /**\n * Unkey allows you to set/update usage limits on individual keys\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n update: async (req: {\n /**\n * The id of the key to update.\n */\n keyId: string;\n /**\n * Update the name\n */\n name?: string | null;\n\n /**\n * Update the owner id\n */\n ownerId?: string | null;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown | null;\n /**\n * Update the expiration time, Unix timstamp in milliseconds\n *\n *\n */\n expires?: number | null;\n\n /**\n * Update the ratelimit\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n } | null;\n\n /**\n * Update the remaining verifications.\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number | null;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"PUT\",\n body: req,\n cache: \"no-cache\",\n });\n },\n verify: async (req: { key: string }): Promise<\n Result<{\n /**\n * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting\n */\n valid: boolean;\n\n /**\n * If you have set an ownerId on this key it is returned here. You can use this to clearly authenticate a user in your system.\n */\n ownerId?: string;\n\n /**\n * This is the meta data you have set when creating the key.\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n\n /**\n * Unix timestamp in milliseconds when this key expires\n * Only available when the key automatically expires\n */\n expires?: number;\n\n /**\n * How many verifications are remaining after the current request.\n */\n remaining?: number;\n\n /**\n * Ratelimit data if the key is ratelimited.\n */\n ratelimit?: {\n /**\n * The maximum number of requests for bursting.\n */\n limit: number;\n\n /**\n * How many requests are remaining until `reset`\n */\n remaining: number;\n\n /**\n * Unix timestamp in millisecond when the ratelimit is refilled.\n */\n reset: number;\n };\n\n /**\n * Machine readable code that explains why a key is invalid or could not be verified\n */\n code?: \"NOT_FOUND\" | \"FORBIDDEN\" | \"RATELIMITED\" | \"KEY_USAGE_EXCEEDED\";\n }>\n > => {\n return await this.fetch<{\n valid: boolean;\n ownerId?: string;\n meta?: unknown;\n }>({\n path: [\"v1\", \"keys\", \"verify\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n revoke: async (req: { keyId: string }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"DELETE\",\n cache: \"no-cache\",\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (req: {\n /**\n * A name for you to identify your API.\n */\n name: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n remove: async (req: {\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.removeApi\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n get: async (req: {\n /**\n * The api id\n */\n apiId: string;\n }): Promise<Result<{ id: string; name: string; workspaceId: string }>> => {\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId],\n method: \"GET\",\n cache: \"no-cache\",\n });\n },\n\n listKeys: async (req: {\n /**\n * The api id\n */\n apiId: string;\n\n /**\n * Limit the number of returned keys, the maximum is 100.\n *\n * @default 100\n */\n limit?: number;\n\n /**\n * Specify an offset for pagination.\n * @example:\n * An offset of 4 will skip the first 4 keys and return keys starting at the 5th position.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * If provided, this will only return keys where the ownerId matches.\n */\n ownerId?: string;\n }): Promise<\n Result<{\n keys: {\n id: string;\n apiId: string;\n ownerId?: string;\n workspaceId: string;\n start: string;\n createdAt: number;\n name?: string;\n expires?: number;\n remaining?: number;\n meta?: unknown;\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n limit: number;\n refillRate: number;\n refillInterval: number;\n };\n }[];\n total: number;\n }>\n > => {\n const query: Record<string, string> = {};\n if (typeof req.limit !== \"undefined\") {\n query.limit = req.limit.toString();\n }\n if (typeof req.offset !== \"undefined\") {\n query.offset = req.offset.toString();\n }\n if (typeof req.ownerId !== \"undefined\") {\n query.ownerId = req.ownerId;\n }\n\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId, \"keys\"],\n method: \"GET\",\n query,\n cache: \"no-cache\",\n });\n },\n };\n }\n /**\n * Must be authenticated via app token\n */\n public get _internal() {\n return {\n createRootKey: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n // Used to create root keys from the frontend, please ignore\n forWorkspaceId: string;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"internal\", \"rootkeys\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n deleteRootKey: async (req: {\n /**\n * Used to create root keys from the frontend, please ignore\n */\n keyId: string;\n }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"internal.removeRootKey\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(key: string) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ token: \"public\" });\n return unkey.keys.verify({ key });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\n","import { UnkeyError } from \"./errors\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n // some change\n};\n\ntype ApiRequest = {\n path: string[];\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n query?: Record<string, string>;\n};\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: UnkeyError;\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v);\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n },\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: await res.json() };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: await res.json() };\n }\n\n return {\n error: {\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n /**\n * Choose an API where this key should be created.\n */\n apiId: string;\n /**\n * To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n *\n * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n *\n * The underscore is automtically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n */\n prefix?: string;\n\n /**\n * The bytelength used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle.\n *\n * The default is 16 bytes, or 2128 possible combinations\n */\n byteLength?: number;\n /**\n * Your user’s Id. This will provide a link between Unkey and your customer record.\n *\n * When validating a key, we will return this back to you, so you can clearly identify your user from their api key.\n */\n ownerId?: string;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n /**\n * Unkey comes with per-key ratelimiting out of the box.\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n };\n\n /**\n * Unkey allows you to set/update usage limits on individual keys\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (req: {\n /**\n * The id of the key to update.\n */\n keyId: string;\n /**\n * Update the name\n */\n name?: string | null;\n\n /**\n * Update the owner id\n */\n ownerId?: string | null;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown | null;\n /**\n * Update the expiration time, Unix timstamp in milliseconds\n *\n *\n */\n expires?: number | null;\n\n /**\n * Update the ratelimit\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n } | null;\n\n /**\n * Update the remaining verifications.\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number | null;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"PUT\",\n body: req,\n });\n },\n verify: async (req: {\n /**\n * The key to verify\n */\n key: string;\n\n /**\n * The api id to verify against\n *\n * This will be required soon.\n */\n apiId?: string;\n }): Promise<\n Result<{\n /**\n * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting\n */\n valid: boolean;\n\n /**\n * If you have set an ownerId on this key it is returned here. You can use this to clearly authenticate a user in your system.\n */\n ownerId?: string;\n\n /**\n * This is the meta data you have set when creating the key.\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n\n /**\n * Unix timestamp in milliseconds when this key expires\n * Only available when the key automatically expires\n */\n expires?: number;\n\n /**\n * How many verifications are remaining after the current request.\n */\n remaining?: number;\n\n /**\n * Ratelimit data if the key is ratelimited.\n */\n ratelimit?: {\n /**\n * The maximum number of requests for bursting.\n */\n limit: number;\n\n /**\n * How many requests are remaining until `reset`\n */\n remaining: number;\n\n /**\n * Unix timestamp in millisecond when the ratelimit is refilled.\n */\n reset: number;\n };\n\n /**\n * Machine readable code that explains why a key is invalid or could not be verified\n */\n code?: \"NOT_FOUND\" | \"FORBIDDEN\" | \"RATELIMITED\" | \"KEY_USAGE_EXCEEDED\";\n }>\n > => {\n return await this.fetch<{\n valid: boolean;\n ownerId?: string;\n meta?: unknown;\n }>({\n path: [\"v1\", \"keys\", \"verify\"],\n method: \"POST\",\n body: req,\n });\n },\n revoke: async (req: { keyId: string }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"DELETE\",\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (req: {\n /**\n * A name for you to identify your API.\n */\n name: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n remove: async (req: {\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.removeApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (req: {\n /**\n * The api id\n */\n apiId: string;\n }): Promise<Result<{ id: string; name: string; workspaceId: string }>> => {\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId],\n method: \"GET\",\n });\n },\n\n listKeys: async (req: {\n /**\n * The api id\n */\n apiId: string;\n\n /**\n * Limit the number of returned keys, the maximum is 100.\n *\n * @default 100\n */\n limit?: number;\n\n /**\n * Specify an offset for pagination.\n * @example:\n * An offset of 4 will skip the first 4 keys and return keys starting at the 5th position.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * If provided, this will only return keys where the ownerId matches.\n */\n ownerId?: string;\n }): Promise<\n Result<{\n keys: {\n id: string;\n apiId: string;\n ownerId?: string;\n workspaceId: string;\n start: string;\n createdAt: number;\n name?: string;\n expires?: number;\n remaining?: number;\n meta?: unknown;\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n limit: number;\n refillRate: number;\n refillInterval: number;\n };\n }[];\n total: number;\n }>\n > => {\n const query: Record<string, string> = {};\n if (typeof req.limit !== \"undefined\") {\n query.limit = req.limit.toString();\n }\n if (typeof req.offset !== \"undefined\") {\n query.offset = req.offset.toString();\n }\n if (typeof req.ownerId !== \"undefined\") {\n query.ownerId = req.ownerId;\n }\n\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId, \"keys\"],\n method: \"GET\",\n query,\n });\n },\n };\n }\n /**\n * Must be authenticated via app token\n */\n public get _internal() {\n return {\n createRootKey: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n // Used to create root keys from the frontend, please ignore\n forWorkspaceId: string;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"internal\", \"rootkeys\"],\n method: \"POST\",\n body: req,\n });\n },\n deleteRootKey: async (req: {\n /**\n * Used to create root keys from the frontend, please ignore\n */\n keyId: string;\n }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"internal.removeRootKey\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ token: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs CHANGED
@@ -2,10 +2,12 @@
2
2
  var Unkey = class {
3
3
  baseUrl;
4
4
  rootKey;
5
+ cache;
5
6
  retry;
6
7
  constructor(opts) {
7
8
  this.baseUrl = opts.baseUrl ?? "https://api.unkey.dev";
8
9
  this.rootKey = opts.rootKey ?? opts.token;
10
+ this.cache = opts.cache;
9
11
  if (!this.rootKey) {
10
12
  throw new Error(
11
13
  "Unkey root key must be set, maybe you passed in `undefined` or an empty string?"
@@ -32,8 +34,8 @@ var Unkey = class {
32
34
  "Content-Type": "application/json",
33
35
  Authorization: `Bearer ${this.rootKey}`
34
36
  },
35
- body: JSON.stringify(req.body),
36
- cache: req.cache
37
+ cache: this.cache,
38
+ body: JSON.stringify(req.body)
37
39
  }).catch((e) => {
38
40
  err = e;
39
41
  return null;
@@ -72,31 +74,27 @@ var Unkey = class {
72
74
  return await this.fetch({
73
75
  path: ["v1", "keys"],
74
76
  method: "POST",
75
- body: req,
76
- cache: "no-cache"
77
+ body: req
77
78
  });
78
79
  },
79
80
  update: async (req) => {
80
81
  return await this.fetch({
81
82
  path: ["v1", "keys", req.keyId],
82
83
  method: "PUT",
83
- body: req,
84
- cache: "no-cache"
84
+ body: req
85
85
  });
86
86
  },
87
87
  verify: async (req) => {
88
88
  return await this.fetch({
89
89
  path: ["v1", "keys", "verify"],
90
90
  method: "POST",
91
- body: req,
92
- cache: "no-cache"
91
+ body: req
93
92
  });
94
93
  },
95
94
  revoke: async (req) => {
96
95
  return await this.fetch({
97
96
  path: ["v1", "keys", req.keyId],
98
- method: "DELETE",
99
- cache: "no-cache"
97
+ method: "DELETE"
100
98
  });
101
99
  }
102
100
  };
@@ -107,23 +105,20 @@ var Unkey = class {
107
105
  return await this.fetch({
108
106
  path: ["v1", "apis.createApi"],
109
107
  method: "POST",
110
- body: req,
111
- cache: "no-cache"
108
+ body: req
112
109
  });
113
110
  },
114
111
  remove: async (req) => {
115
112
  return await this.fetch({
116
113
  path: ["v1", "apis.removeApi"],
117
114
  method: "POST",
118
- body: req,
119
- cache: "no-cache"
115
+ body: req
120
116
  });
121
117
  },
122
118
  get: async (req) => {
123
119
  return await this.fetch({
124
120
  path: ["v1", "apis", req.apiId],
125
- method: "GET",
126
- cache: "no-cache"
121
+ method: "GET"
127
122
  });
128
123
  },
129
124
  listKeys: async (req) => {
@@ -140,8 +135,7 @@ var Unkey = class {
140
135
  return await this.fetch({
141
136
  path: ["v1", "apis", req.apiId, "keys"],
142
137
  method: "GET",
143
- query,
144
- cache: "no-cache"
138
+ query
145
139
  });
146
140
  }
147
141
  };
@@ -155,16 +149,14 @@ var Unkey = class {
155
149
  return await this.fetch({
156
150
  path: ["v1", "internal", "rootkeys"],
157
151
  method: "POST",
158
- body: req,
159
- cache: "no-cache"
152
+ body: req
160
153
  });
161
154
  },
162
155
  deleteRootKey: async (req) => {
163
156
  return await this.fetch({
164
157
  path: ["v1", "internal.removeRootKey"],
165
158
  method: "POST",
166
- body: req,
167
- cache: "no-cache"
159
+ body: req
168
160
  });
169
161
  }
170
162
  };
@@ -172,9 +164,9 @@ var Unkey = class {
172
164
  };
173
165
 
174
166
  // src/verify.ts
175
- function verifyKey(key) {
167
+ function verifyKey(req) {
176
168
  const unkey = new Unkey({ token: "public" });
177
- return unkey.keys.verify({ key });
169
+ return unkey.keys.verify(typeof req === "string" ? { key: req } : req);
178
170
  }
179
171
  export {
180
172
  Unkey,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/verify.ts"],"sourcesContent":["import { UnkeyError } from \"./errors\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n // some change\n};\n\ntype ApiRequest = {\n path: string[];\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n query?: Record<string, string>;\n cache?: RequestCache;\n};\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: UnkeyError;\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v);\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n },\n body: JSON.stringify(req.body),\n cache: req.cache,\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: await res.json() };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: await res.json() };\n }\n\n return {\n error: {\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n /**\n * Choose an API where this key should be created.\n */\n apiId: string;\n /**\n * To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n *\n * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n *\n * The underscore is automtically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n */\n prefix?: string;\n\n /**\n * The bytelength used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle.\n *\n * The default is 16 bytes, or 2128 possible combinations\n */\n byteLength?: number;\n /**\n * Your user’s Id. This will provide a link between Unkey and your customer record.\n *\n * When validating a key, we will return this back to you, so you can clearly identify your user from their api key.\n */\n ownerId?: string;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n /**\n * Unkey comes with per-key ratelimiting out of the box.\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n };\n\n /**\n * Unkey allows you to set/update usage limits on individual keys\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n update: async (req: {\n /**\n * The id of the key to update.\n */\n keyId: string;\n /**\n * Update the name\n */\n name?: string | null;\n\n /**\n * Update the owner id\n */\n ownerId?: string | null;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown | null;\n /**\n * Update the expiration time, Unix timstamp in milliseconds\n *\n *\n */\n expires?: number | null;\n\n /**\n * Update the ratelimit\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n } | null;\n\n /**\n * Update the remaining verifications.\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number | null;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"PUT\",\n body: req,\n cache: \"no-cache\",\n });\n },\n verify: async (req: { key: string }): Promise<\n Result<{\n /**\n * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting\n */\n valid: boolean;\n\n /**\n * If you have set an ownerId on this key it is returned here. You can use this to clearly authenticate a user in your system.\n */\n ownerId?: string;\n\n /**\n * This is the meta data you have set when creating the key.\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n\n /**\n * Unix timestamp in milliseconds when this key expires\n * Only available when the key automatically expires\n */\n expires?: number;\n\n /**\n * How many verifications are remaining after the current request.\n */\n remaining?: number;\n\n /**\n * Ratelimit data if the key is ratelimited.\n */\n ratelimit?: {\n /**\n * The maximum number of requests for bursting.\n */\n limit: number;\n\n /**\n * How many requests are remaining until `reset`\n */\n remaining: number;\n\n /**\n * Unix timestamp in millisecond when the ratelimit is refilled.\n */\n reset: number;\n };\n\n /**\n * Machine readable code that explains why a key is invalid or could not be verified\n */\n code?: \"NOT_FOUND\" | \"FORBIDDEN\" | \"RATELIMITED\" | \"KEY_USAGE_EXCEEDED\";\n }>\n > => {\n return await this.fetch<{\n valid: boolean;\n ownerId?: string;\n meta?: unknown;\n }>({\n path: [\"v1\", \"keys\", \"verify\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n revoke: async (req: { keyId: string }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"DELETE\",\n cache: \"no-cache\",\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (req: {\n /**\n * A name for you to identify your API.\n */\n name: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n remove: async (req: {\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.removeApi\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n get: async (req: {\n /**\n * The api id\n */\n apiId: string;\n }): Promise<Result<{ id: string; name: string; workspaceId: string }>> => {\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId],\n method: \"GET\",\n cache: \"no-cache\",\n });\n },\n\n listKeys: async (req: {\n /**\n * The api id\n */\n apiId: string;\n\n /**\n * Limit the number of returned keys, the maximum is 100.\n *\n * @default 100\n */\n limit?: number;\n\n /**\n * Specify an offset for pagination.\n * @example:\n * An offset of 4 will skip the first 4 keys and return keys starting at the 5th position.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * If provided, this will only return keys where the ownerId matches.\n */\n ownerId?: string;\n }): Promise<\n Result<{\n keys: {\n id: string;\n apiId: string;\n ownerId?: string;\n workspaceId: string;\n start: string;\n createdAt: number;\n name?: string;\n expires?: number;\n remaining?: number;\n meta?: unknown;\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n limit: number;\n refillRate: number;\n refillInterval: number;\n };\n }[];\n total: number;\n }>\n > => {\n const query: Record<string, string> = {};\n if (typeof req.limit !== \"undefined\") {\n query.limit = req.limit.toString();\n }\n if (typeof req.offset !== \"undefined\") {\n query.offset = req.offset.toString();\n }\n if (typeof req.ownerId !== \"undefined\") {\n query.ownerId = req.ownerId;\n }\n\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId, \"keys\"],\n method: \"GET\",\n query,\n cache: \"no-cache\",\n });\n },\n };\n }\n /**\n * Must be authenticated via app token\n */\n public get _internal() {\n return {\n createRootKey: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n // Used to create root keys from the frontend, please ignore\n forWorkspaceId: string;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"internal\", \"rootkeys\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n deleteRootKey: async (req: {\n /**\n * Used to create root keys from the frontend, please ignore\n */\n keyId: string;\n }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"internal.removeRootKey\"],\n method: \"POST\",\n body: req,\n cache: \"no-cache\",\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(key: string) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ token: \"public\" });\n return unkey.keys.verify({ key });\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/verify.ts"],"sourcesContent":["import { UnkeyError } from \"./errors\";\n\nexport type UnkeyOptions = (\n | {\n token?: never;\n\n /**\n * The root key from unkey.dev.\n *\n * You can create/manage your root keys here:\n * https://unkey.dev/app/settings/root-keys\n */\n rootKey: string;\n }\n | {\n /**\n * The workspace key from unkey.dev\n *\n * @deprecated Use `rootKey`\n */\n token: string;\n rootKey?: never;\n }\n) & {\n /**\n * @default https://api.unkey.dev\n */\n baseUrl?: string;\n\n /**\n * Retry on network errors\n */\n retry?: {\n /**\n * How many attempts should be made\n * The maximum number of requests will be `attempts + 1`\n * `0` means no retries\n *\n * @default 5\n */\n attempts?: number;\n /**\n * Return how many milliseconds to wait until the next attempt is made\n *\n * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),`\n */\n backoff?: (retryCount: number) => number;\n };\n /**\n * Customize the `fetch` cache behaviour\n */\n cache?: RequestCache;\n // some change\n};\n\ntype ApiRequest = {\n path: string[];\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n body?: unknown;\n query?: Record<string, string>;\n};\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: UnkeyError;\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n\n public readonly retry: {\n attempts: number;\n backoff: (retryCount: number) => number;\n };\n\n constructor(opts: UnkeyOptions) {\n this.baseUrl = opts.baseUrl ?? \"https://api.unkey.dev\";\n this.rootKey = opts.rootKey ?? opts.token;\n\n this.cache = opts.cache;\n /**\n * Even though typescript should prevent this, some people still pass undefined or empty strings\n */\n if (!this.rootKey) {\n throw new Error(\n \"Unkey root key must be set, maybe you passed in `undefined` or an empty string?\",\n );\n }\n\n this.retry = {\n attempts: opts.retry?.attempts ?? 5,\n backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)),\n };\n }\n\n private async fetch<TResult>(req: ApiRequest): Promise<Result<TResult>> {\n let res: Response | null = null;\n let err: Error | null = null;\n for (let i = 0; i <= this.retry.attempts; i++) {\n const url = new URL(`${this.baseUrl}/${req.path.join(\"/\")}`);\n if (req.query) {\n for (const [k, v] of Object.entries(req.query)) {\n url.searchParams.set(k, v);\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n },\n cache: this.cache,\n body: JSON.stringify(req.body),\n }).catch((e: Error) => {\n err = e;\n return null; // set `res` to `null`\n });\n if (res?.ok) {\n return { result: await res.json() };\n }\n const backoff = this.retry.backoff(i);\n console.debug(\n \"attempt %d of %d to reach %s failed, retrying in %d ms: %s\",\n i + 1,\n this.retry.attempts + 1,\n url,\n backoff,\n // @ts-ignore I don't understand why `err` is `never`\n err?.message,\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: await res.json() };\n }\n\n return {\n error: {\n code: \"FETCH_ERROR\",\n // @ts-ignore I don't understand why `err` is `never`\n message: err?.message ?? \"No response\",\n docs: \"https://developer.mozilla.org/en-US/docs/Web/API/fetch\",\n requestId: \"N/A\",\n },\n };\n }\n\n public get keys() {\n return {\n create: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n /**\n * Choose an API where this key should be created.\n */\n apiId: string;\n /**\n * To make it easier for your users to understand which product an api key belongs to, you can add prefix them.\n *\n * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_.\n *\n * The underscore is automtically added if you are defining a prefix, for example: \"prefix\": \"abc\" will result in a key like abc_xxxxxxxxx\n */\n prefix?: string;\n\n /**\n * The bytelength used to generate your key determines its entropy as well as its length. Higher is better, but keys become longer and more annoying to handle.\n *\n * The default is 16 bytes, or 2128 possible combinations\n */\n byteLength?: number;\n /**\n * Your user’s Id. This will provide a link between Unkey and your customer record.\n *\n * When validating a key, we will return this back to you, so you can clearly identify your user from their api key.\n */\n ownerId?: string;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n /**\n * Unkey comes with per-key ratelimiting out of the box.\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n };\n\n /**\n * Unkey allows you to set/update usage limits on individual keys\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (req: {\n /**\n * The id of the key to update.\n */\n keyId: string;\n /**\n * Update the name\n */\n name?: string | null;\n\n /**\n * Update the owner id\n */\n ownerId?: string | null;\n /**\n * This is a place for dynamic meta data, anything that feels useful for you should go here\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown | null;\n /**\n * Update the expiration time, Unix timstamp in milliseconds\n *\n *\n */\n expires?: number | null;\n\n /**\n * Update the ratelimit\n *\n * @see https://unkey.dev/docs/features/ratelimiting\n */\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n /**\n * The total amount of burstable requests.\n */\n limit: number;\n\n /**\n * How many tokens to refill during each refillInterval\n */\n refillRate: number;\n\n /**\n * Determines the speed at which tokens are refilled.\n * In milliseconds.\n */\n refillInterval: number;\n } | null;\n\n /**\n * Update the remaining verifications.\n *\n * @see https://unkey.dev/docs/features/remaining\n */\n remaining?: number | null;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"PUT\",\n body: req,\n });\n },\n verify: async (req: {\n /**\n * The key to verify\n */\n key: string;\n\n /**\n * The api id to verify against\n *\n * This will be required soon.\n */\n apiId?: string;\n }): Promise<\n Result<{\n /**\n * Whether or not this key is valid and has passed the ratelimit. If false you should not grant access to whatever the user is requesting\n */\n valid: boolean;\n\n /**\n * If you have set an ownerId on this key it is returned here. You can use this to clearly authenticate a user in your system.\n */\n ownerId?: string;\n\n /**\n * This is the meta data you have set when creating the key.\n *\n * Example:\n *\n * ```json\n * {\n * \"billingTier\":\"PRO\",\n * \"trialEnds\": \"2023-06-16T17:16:37.161Z\"\n * }\n * ```\n */\n meta?: unknown;\n\n /**\n * Unix timestamp in milliseconds when this key expires\n * Only available when the key automatically expires\n */\n expires?: number;\n\n /**\n * How many verifications are remaining after the current request.\n */\n remaining?: number;\n\n /**\n * Ratelimit data if the key is ratelimited.\n */\n ratelimit?: {\n /**\n * The maximum number of requests for bursting.\n */\n limit: number;\n\n /**\n * How many requests are remaining until `reset`\n */\n remaining: number;\n\n /**\n * Unix timestamp in millisecond when the ratelimit is refilled.\n */\n reset: number;\n };\n\n /**\n * Machine readable code that explains why a key is invalid or could not be verified\n */\n code?: \"NOT_FOUND\" | \"FORBIDDEN\" | \"RATELIMITED\" | \"KEY_USAGE_EXCEEDED\";\n }>\n > => {\n return await this.fetch<{\n valid: boolean;\n ownerId?: string;\n meta?: unknown;\n }>({\n path: [\"v1\", \"keys\", \"verify\"],\n method: \"POST\",\n body: req,\n });\n },\n revoke: async (req: { keyId: string }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"keys\", req.keyId],\n method: \"DELETE\",\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (req: {\n /**\n * A name for you to identify your API.\n */\n name: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n remove: async (req: {\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }): Promise<\n Result<{\n /**\n * The global unique identifier of your api.\n * You'll need this for other api requests.\n */\n apiId: string;\n }>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.removeApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (req: {\n /**\n * The api id\n */\n apiId: string;\n }): Promise<Result<{ id: string; name: string; workspaceId: string }>> => {\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId],\n method: \"GET\",\n });\n },\n\n listKeys: async (req: {\n /**\n * The api id\n */\n apiId: string;\n\n /**\n * Limit the number of returned keys, the maximum is 100.\n *\n * @default 100\n */\n limit?: number;\n\n /**\n * Specify an offset for pagination.\n * @example:\n * An offset of 4 will skip the first 4 keys and return keys starting at the 5th position.\n *\n * @default 0\n */\n offset?: number;\n\n /**\n * If provided, this will only return keys where the ownerId matches.\n */\n ownerId?: string;\n }): Promise<\n Result<{\n keys: {\n id: string;\n apiId: string;\n ownerId?: string;\n workspaceId: string;\n start: string;\n createdAt: number;\n name?: string;\n expires?: number;\n remaining?: number;\n meta?: unknown;\n ratelimit?: {\n type: \"fast\" | \"consistent\";\n limit: number;\n refillRate: number;\n refillInterval: number;\n };\n }[];\n total: number;\n }>\n > => {\n const query: Record<string, string> = {};\n if (typeof req.limit !== \"undefined\") {\n query.limit = req.limit.toString();\n }\n if (typeof req.offset !== \"undefined\") {\n query.offset = req.offset.toString();\n }\n if (typeof req.ownerId !== \"undefined\") {\n query.ownerId = req.ownerId;\n }\n\n return await this.fetch({\n path: [\"v1\", \"apis\", req.apiId, \"keys\"],\n method: \"GET\",\n query,\n });\n },\n };\n }\n /**\n * Must be authenticated via app token\n */\n public get _internal() {\n return {\n createRootKey: async (req: {\n /**\n * Provide a name to this key if you want for later reference\n */\n name?: string;\n\n /**\n * You can auto expire keys by providing a unix timestamp in milliseconds.\n *\n * Once keys expire they will automatically be deleted and are no longer valid.\n */\n expires?: number;\n\n // Used to create root keys from the frontend, please ignore\n forWorkspaceId: string;\n }): Promise<Result<{ key: string; keyId: string }>> => {\n return await this.fetch<{ key: string; keyId: string }>({\n path: [\"v1\", \"internal\", \"rootkeys\"],\n method: \"POST\",\n body: req,\n });\n },\n deleteRootKey: async (req: {\n /**\n * Used to create root keys from the frontend, please ignore\n */\n keyId: string;\n }): Promise<Result<void>> => {\n return await this.fetch<void>({\n path: [\"v1\", \"internal.removeRootKey\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n}\n","import { Unkey } from \"./client\";\n\n/**\n * Verify a key\n *\n * @example\n * ```ts\n * const { result, error } = await verifyKey(\"key_123\")\n * if (error){\n * // handle potential network or bad request error\n * // a link to our docs will be in the `error.docs` field\n * console.error(error.message)\n * return\n * }\n * if (!result.valid) {\n * // do not grant access\n * return\n * }\n *\n * // process request\n * console.log(result)\n * ```\n */\nexport function verifyKey(req: string | { key: string; apiId: string }) {\n // yes this is empty to make typescript happy but we don't need a token for verifying keys\n // it's not the cleanest but it works for now :)\n const unkey = new Unkey({ token: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":";AAwEO,IAAM,QAAN,MAAY;AAAA,EACD;AAAA,EACC;AAAA,EACA;AAAA,EAED;AAAA,EAKhB,YAAY,MAAoB;AAC9B,SAAK,UAAU,KAAK,WAAW;AAC/B,SAAK,UAAU,KAAK,WAAW,KAAK;AAEpC,SAAK,QAAQ,KAAK;AAIlB,QAAI,CAAC,KAAK,SAAS;AACjB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQ;AAAA,MACX,UAAU,KAAK,OAAO,YAAY;AAAA,MAClC,SAAS,KAAK,OAAO,YAAY,CAAC,MAAM,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,EAAE;AAAA,IACrE;AAAA,EACF;AAAA,EAEA,MAAc,MAAe,KAA2C;AACtE,QAAI,MAAuB;AAC3B,QAAI,MAAoB;AACxB,aAAS,IAAI,GAAG,KAAK,KAAK,MAAM,UAAU,KAAK;AAC7C,YAAM,MAAM,IAAI,IAAI,GAAG,KAAK,OAAO,IAAI,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAC3D,UAAI,IAAI,OAAO;AACb,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,KAAK,GAAG;AAC9C,cAAI,aAAa,IAAI,GAAG,CAAC;AAAA,QAC3B;AAAA,MACF;AACA,YAAM,MAAM,MAAM,KAAK;AAAA,QACrB,QAAQ,IAAI;AAAA,QACZ,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,OAAO;AAAA,QACvC;AAAA,QACA,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK,UAAU,IAAI,IAAI;AAAA,MAC/B,CAAC,EAAE,MAAM,CAAC,MAAa;AACrB,cAAM;AACN,eAAO;AAAA,MACT,CAAC;AACD,UAAI,KAAK,IAAI;AACX,eAAO,EAAE,QAAQ,MAAM,IAAI,KAAK,EAAE;AAAA,MACpC;AACA,YAAM,UAAU,KAAK,MAAM,QAAQ,CAAC;AACpC,cAAQ;AAAA,QACN;AAAA,QACA,IAAI;AAAA,QACJ,KAAK,MAAM,WAAW;AAAA,QACtB;AAAA,QACA;AAAA;AAAA,QAEA,KAAK;AAAA,MACP;AACA,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAAA,IACjD;AAEA,QAAI,KAAK;AACP,aAAO,EAAE,OAAO,MAAM,IAAI,KAAK,EAAE;AAAA,IACnC;AAEA,WAAO;AAAA,MACL,OAAO;AAAA,QACL,MAAM;AAAA;AAAA,QAEN,SAAS,KAAK,WAAW;AAAA,QACzB,MAAM;AAAA,QACN,WAAW;AAAA,MACb;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAW,OAAO;AAChB,WAAO;AAAA,MACL,QAAQ,OAAO,QAgFwC;AACrD,eAAO,MAAM,KAAK,MAAsC;AAAA,UACtD,MAAM,CAAC,MAAM,MAAM;AAAA,UACnB,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,QAAQ,OAAO,QAgEwC;AACrD,eAAO,MAAM,KAAK,MAAsC;AAAA,UACtD,MAAM,CAAC,MAAM,QAAQ,IAAI,KAAK;AAAA,UAC9B,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,QAAQ,OAAO,QA0EV;AACH,eAAO,MAAM,KAAK,MAIf;AAAA,UACD,MAAM,CAAC,MAAM,QAAQ,QAAQ;AAAA,UAC7B,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,QAAQ,OAAO,QAAkD;AAC/D,eAAO,MAAM,KAAK,MAAY;AAAA,UAC5B,MAAM,CAAC,MAAM,QAAQ,IAAI,KAAK;AAAA,UAC9B,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA,EAEA,IAAW,OAAO;AAChB,WAAO;AAAA,MACL,QAAQ,OAAO,QAaV;AACH,eAAO,MAAM,KAAK,MAAM;AAAA,UACtB,MAAM,CAAC,MAAM,gBAAgB;AAAA,UAC7B,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,QAAQ,OAAO,QAcV;AACH,eAAO,MAAM,KAAK,MAAM;AAAA,UACtB,MAAM,CAAC,MAAM,gBAAgB;AAAA,UAC7B,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,KAAK,OAAO,QAK8D;AACxE,eAAO,MAAM,KAAK,MAAM;AAAA,UACtB,MAAM,CAAC,MAAM,QAAQ,IAAI,KAAK;AAAA,UAC9B,QAAQ;AAAA,QACV,CAAC;AAAA,MACH;AAAA,MAEA,UAAU,OAAO,QAgDZ;AACH,cAAM,QAAgC,CAAC;AACvC,YAAI,OAAO,IAAI,UAAU,aAAa;AACpC,gBAAM,QAAQ,IAAI,MAAM,SAAS;AAAA,QACnC;AACA,YAAI,OAAO,IAAI,WAAW,aAAa;AACrC,gBAAM,SAAS,IAAI,OAAO,SAAS;AAAA,QACrC;AACA,YAAI,OAAO,IAAI,YAAY,aAAa;AACtC,gBAAM,UAAU,IAAI;AAAA,QACtB;AAEA,eAAO,MAAM,KAAK,MAAM;AAAA,UACtB,MAAM,CAAC,MAAM,QAAQ,IAAI,OAAO,MAAM;AAAA,UACtC,QAAQ;AAAA,UACR;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAIA,IAAW,YAAY;AACrB,WAAO;AAAA,MACL,eAAe,OAAO,QAeiC;AACrD,eAAO,MAAM,KAAK,MAAsC;AAAA,UACtD,MAAM,CAAC,MAAM,YAAY,UAAU;AAAA,UACnC,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,MACA,eAAe,OAAO,QAKO;AAC3B,eAAO,MAAM,KAAK,MAAY;AAAA,UAC5B,MAAM,CAAC,MAAM,wBAAwB;AAAA,UACrC,QAAQ;AAAA,UACR,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACtiBO,SAAS,UAAU,KAA8C;AAGtE,QAAM,QAAQ,IAAI,MAAM,EAAE,OAAO,SAAS,CAAC;AAC3C,SAAO,MAAM,KAAK,OAAO,OAAO,QAAQ,WAAW,EAAE,KAAK,IAAI,IAAI,GAAG;AACvE;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unkey/api",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "license": "MIT",
@@ -22,9 +22,9 @@
22
22
  ],
23
23
  "author": "Andreas Thomas <andreas@chronark.com>",
24
24
  "devDependencies": {
25
- "@types/node": "^20.5.7",
25
+ "@types/node": "^20.8.7",
26
26
  "tsup": "^7.2.0",
27
- "tsx": "^3.12.8",
27
+ "tsx": "^3.14.0",
28
28
  "typescript": "^5.2.2"
29
29
  },
30
30
  "scripts": {