@unkey/api 0.23.0 → 0.24.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
@@ -116,7 +116,7 @@ interface paths {
116
116
  post: operations["updateIdentity"];
117
117
  };
118
118
  "/v1/identities.deleteIdentity": {
119
- post: operations["deleteeIdentity"];
119
+ post: operations["deleteIdentity"];
120
120
  };
121
121
  "/v1/keys": {
122
122
  post: operations["deprecated.createKey"];
@@ -340,11 +340,6 @@ interface components {
340
340
  * @example 0
341
341
  */
342
342
  updatedAt?: number;
343
- /**
344
- * @description The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.
345
- * @example 0
346
- */
347
- deletedAt?: number;
348
343
  /**
349
344
  * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
350
345
  * @example 0
@@ -427,6 +422,17 @@ interface components {
427
422
  enabled?: boolean;
428
423
  /** @description The key in plaintext */
429
424
  plaintext?: string;
425
+ /** @description The identity of the key */
426
+ identity?: {
427
+ /** @description The id of the identity */
428
+ id: string;
429
+ /** @description The external id of the identity */
430
+ externalId: string;
431
+ /** @description Any additional metadata attached to the identity */
432
+ meta?: {
433
+ [key: string]: unknown;
434
+ };
435
+ };
430
436
  };
431
437
  V1KeysVerifyKeyResponse: {
432
438
  /**
@@ -604,6 +610,28 @@ interface components {
604
610
  duration?: number;
605
611
  }[];
606
612
  };
613
+ ErrDeleteProtected: {
614
+ error: {
615
+ /**
616
+ * @description A machine readable error code.
617
+ * @example DELETE_PROTECTED
618
+ * @enum {string}
619
+ */
620
+ code: "DELETE_PROTECTED";
621
+ /**
622
+ * @description A link to our documentation with more details about this error code
623
+ * @example https://unkey.dev/docs/api-reference/errors/code/DELETE_PROTECTED
624
+ */
625
+ docs: string;
626
+ /** @description A human readable explanation of what went wrong */
627
+ message: string;
628
+ /**
629
+ * @description Please always include the requestId in your error report
630
+ * @example req_1234
631
+ */
632
+ requestId: string;
633
+ };
634
+ };
607
635
  };
608
636
  responses: never;
609
637
  parameters: {
@@ -945,6 +973,15 @@ interface operations {
945
973
  * @example false
946
974
  */
947
975
  enabled?: boolean;
976
+ /**
977
+ * @description You may want to show keys again later. While we do not recommend this, we leave this option open for you.
978
+ *
979
+ * In addition to storing the key's hash, recoverable keys are stored in an encrypted vault, allowing you to retrieve and display the plaintext later.
980
+ *
981
+ * https://www.unkey.com/docs/security/recovering-keys for more information.
982
+ * @default false
983
+ */
984
+ recoverable?: boolean;
948
985
  /**
949
986
  * @description Environments allow you to divide your keyspace.
950
987
  *
@@ -2134,6 +2171,7 @@ interface operations {
2134
2171
  limit?: number;
2135
2172
  cursor?: string;
2136
2173
  ownerId?: string;
2174
+ externalId?: string;
2137
2175
  decrypt?: boolean | null;
2138
2176
  };
2139
2177
  };
@@ -2246,10 +2284,10 @@ interface operations {
2246
2284
  "application/json": components["schemas"]["ErrConflict"];
2247
2285
  };
2248
2286
  };
2249
- /** @description The user has sent too many requests in a given amount of time ("rate limiting") */
2287
+ /** @description The api is protected from deletions */
2250
2288
  429: {
2251
2289
  content: {
2252
- "application/json": components["schemas"]["ErrTooManyRequests"];
2290
+ "application/json": components["schemas"]["ErrDeleteProtected"];
2253
2291
  };
2254
2292
  };
2255
2293
  /** @description The server has encountered a situation it does not know how to handle. */
@@ -2270,7 +2308,7 @@ interface operations {
2270
2308
  */
2271
2309
  apiId: string;
2272
2310
  /**
2273
- * @description If true, the keys will be permanently deleted. If false, the keys will be soft-deleted and can be restored later.
2311
+ * @description Delete the keys permanently, if false the keys will be marked as deleted but not removed from the database. In either case, the keys will no longer be valid when verifying them.
2274
2312
  * @default false
2275
2313
  */
2276
2314
  permanent?: boolean;
@@ -3797,17 +3835,43 @@ interface operations {
3797
3835
  200: {
3798
3836
  content: {
3799
3837
  "application/json": {
3800
- /**
3801
- * @description The id of the permission. This is used internally
3802
- * @example perm_123
3803
- */
3804
- id: string;
3805
- /**
3806
- * @description The name of the permission
3807
- * @example dns.record.create
3808
- */
3809
- name: string;
3810
- }[];
3838
+ /**
3839
+ * @description The id of the identity.
3840
+ * @example id_1234
3841
+ */
3842
+ id: string;
3843
+ /**
3844
+ * @description The externalId of the identity.
3845
+ * @example user_1234
3846
+ */
3847
+ externalId: string;
3848
+ /**
3849
+ * @description The metadata attached to this identity.
3850
+ * @example {
3851
+ * "stripeSubscriptionId": "sub_1234"
3852
+ * }
3853
+ */
3854
+ meta: {
3855
+ [key: string]: unknown;
3856
+ };
3857
+ ratelimits: {
3858
+ /**
3859
+ * @description The name of this limit.
3860
+ * @example tokens
3861
+ */
3862
+ name: string;
3863
+ /**
3864
+ * @description How many requests may pass within a given window before requests are rejected.
3865
+ * @example 10
3866
+ */
3867
+ limit: number;
3868
+ /**
3869
+ * @description The duration for each ratelimit window in milliseconds.
3870
+ * @example 1000
3871
+ */
3872
+ duration: number;
3873
+ }[];
3874
+ };
3811
3875
  };
3812
3876
  };
3813
3877
  /** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
@@ -3854,7 +3918,7 @@ interface operations {
3854
3918
  };
3855
3919
  };
3856
3920
  };
3857
- deleteeIdentity: {
3921
+ deleteIdentity: {
3858
3922
  requestBody: {
3859
3923
  content: {
3860
3924
  "application/json": {
@@ -4121,11 +4185,6 @@ interface operations {
4121
4185
  * @example 0
4122
4186
  */
4123
4187
  createdAt?: number;
4124
- /**
4125
- * @description The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.
4126
- * @example 0
4127
- */
4128
- deletedAt?: number;
4129
4188
  /**
4130
4189
  * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
4131
4190
  * @example 123
package/dist/index.d.ts CHANGED
@@ -116,7 +116,7 @@ interface paths {
116
116
  post: operations["updateIdentity"];
117
117
  };
118
118
  "/v1/identities.deleteIdentity": {
119
- post: operations["deleteeIdentity"];
119
+ post: operations["deleteIdentity"];
120
120
  };
121
121
  "/v1/keys": {
122
122
  post: operations["deprecated.createKey"];
@@ -340,11 +340,6 @@ interface components {
340
340
  * @example 0
341
341
  */
342
342
  updatedAt?: number;
343
- /**
344
- * @description The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.
345
- * @example 0
346
- */
347
- deletedAt?: number;
348
343
  /**
349
344
  * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
350
345
  * @example 0
@@ -427,6 +422,17 @@ interface components {
427
422
  enabled?: boolean;
428
423
  /** @description The key in plaintext */
429
424
  plaintext?: string;
425
+ /** @description The identity of the key */
426
+ identity?: {
427
+ /** @description The id of the identity */
428
+ id: string;
429
+ /** @description The external id of the identity */
430
+ externalId: string;
431
+ /** @description Any additional metadata attached to the identity */
432
+ meta?: {
433
+ [key: string]: unknown;
434
+ };
435
+ };
430
436
  };
431
437
  V1KeysVerifyKeyResponse: {
432
438
  /**
@@ -604,6 +610,28 @@ interface components {
604
610
  duration?: number;
605
611
  }[];
606
612
  };
613
+ ErrDeleteProtected: {
614
+ error: {
615
+ /**
616
+ * @description A machine readable error code.
617
+ * @example DELETE_PROTECTED
618
+ * @enum {string}
619
+ */
620
+ code: "DELETE_PROTECTED";
621
+ /**
622
+ * @description A link to our documentation with more details about this error code
623
+ * @example https://unkey.dev/docs/api-reference/errors/code/DELETE_PROTECTED
624
+ */
625
+ docs: string;
626
+ /** @description A human readable explanation of what went wrong */
627
+ message: string;
628
+ /**
629
+ * @description Please always include the requestId in your error report
630
+ * @example req_1234
631
+ */
632
+ requestId: string;
633
+ };
634
+ };
607
635
  };
608
636
  responses: never;
609
637
  parameters: {
@@ -945,6 +973,15 @@ interface operations {
945
973
  * @example false
946
974
  */
947
975
  enabled?: boolean;
976
+ /**
977
+ * @description You may want to show keys again later. While we do not recommend this, we leave this option open for you.
978
+ *
979
+ * In addition to storing the key's hash, recoverable keys are stored in an encrypted vault, allowing you to retrieve and display the plaintext later.
980
+ *
981
+ * https://www.unkey.com/docs/security/recovering-keys for more information.
982
+ * @default false
983
+ */
984
+ recoverable?: boolean;
948
985
  /**
949
986
  * @description Environments allow you to divide your keyspace.
950
987
  *
@@ -2134,6 +2171,7 @@ interface operations {
2134
2171
  limit?: number;
2135
2172
  cursor?: string;
2136
2173
  ownerId?: string;
2174
+ externalId?: string;
2137
2175
  decrypt?: boolean | null;
2138
2176
  };
2139
2177
  };
@@ -2246,10 +2284,10 @@ interface operations {
2246
2284
  "application/json": components["schemas"]["ErrConflict"];
2247
2285
  };
2248
2286
  };
2249
- /** @description The user has sent too many requests in a given amount of time ("rate limiting") */
2287
+ /** @description The api is protected from deletions */
2250
2288
  429: {
2251
2289
  content: {
2252
- "application/json": components["schemas"]["ErrTooManyRequests"];
2290
+ "application/json": components["schemas"]["ErrDeleteProtected"];
2253
2291
  };
2254
2292
  };
2255
2293
  /** @description The server has encountered a situation it does not know how to handle. */
@@ -2270,7 +2308,7 @@ interface operations {
2270
2308
  */
2271
2309
  apiId: string;
2272
2310
  /**
2273
- * @description If true, the keys will be permanently deleted. If false, the keys will be soft-deleted and can be restored later.
2311
+ * @description Delete the keys permanently, if false the keys will be marked as deleted but not removed from the database. In either case, the keys will no longer be valid when verifying them.
2274
2312
  * @default false
2275
2313
  */
2276
2314
  permanent?: boolean;
@@ -3797,17 +3835,43 @@ interface operations {
3797
3835
  200: {
3798
3836
  content: {
3799
3837
  "application/json": {
3800
- /**
3801
- * @description The id of the permission. This is used internally
3802
- * @example perm_123
3803
- */
3804
- id: string;
3805
- /**
3806
- * @description The name of the permission
3807
- * @example dns.record.create
3808
- */
3809
- name: string;
3810
- }[];
3838
+ /**
3839
+ * @description The id of the identity.
3840
+ * @example id_1234
3841
+ */
3842
+ id: string;
3843
+ /**
3844
+ * @description The externalId of the identity.
3845
+ * @example user_1234
3846
+ */
3847
+ externalId: string;
3848
+ /**
3849
+ * @description The metadata attached to this identity.
3850
+ * @example {
3851
+ * "stripeSubscriptionId": "sub_1234"
3852
+ * }
3853
+ */
3854
+ meta: {
3855
+ [key: string]: unknown;
3856
+ };
3857
+ ratelimits: {
3858
+ /**
3859
+ * @description The name of this limit.
3860
+ * @example tokens
3861
+ */
3862
+ name: string;
3863
+ /**
3864
+ * @description How many requests may pass within a given window before requests are rejected.
3865
+ * @example 10
3866
+ */
3867
+ limit: number;
3868
+ /**
3869
+ * @description The duration for each ratelimit window in milliseconds.
3870
+ * @example 1000
3871
+ */
3872
+ duration: number;
3873
+ }[];
3874
+ };
3811
3875
  };
3812
3876
  };
3813
3877
  /** @description The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing). */
@@ -3854,7 +3918,7 @@ interface operations {
3854
3918
  };
3855
3919
  };
3856
3920
  };
3857
- deleteeIdentity: {
3921
+ deleteIdentity: {
3858
3922
  requestBody: {
3859
3923
  content: {
3860
3924
  "application/json": {
@@ -4121,11 +4185,6 @@ interface operations {
4121
4185
  * @example 0
4122
4186
  */
4123
4187
  createdAt?: number;
4124
- /**
4125
- * @description The unix timestamp in milliseconds when the key was deleted. We don't delete the key outright, you can restore it later.
4126
- * @example 0
4127
- */
4128
- deletedAt?: number;
4129
4188
  /**
4130
4189
  * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring.
4131
4190
  * @example 123
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ __export(src_exports, {
28
28
  module.exports = __toCommonJS(src_exports);
29
29
 
30
30
  // package.json
31
- var version = "0.23.0";
31
+ var version = "0.24.0";
32
32
 
33
33
  // src/telemetry.ts
34
34
  function getTelemetry(opts) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\nexport { and, or, type Flatten } from \"@unkey/rbac\";\n","{\n \"name\": \"@unkey/api\",\n \"version\": \"0.23.0\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.9\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.5\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.5.3\"\n },\n \"dependencies\": {\n \"@unkey/rbac\": \"workspace:^\"\n }\n}\n","import { version } from \"../package.json\";\nimport type { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import type { PermissionQuery } from \"@unkey/rbac\";\nimport type { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\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 *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\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\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\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 if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\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 getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\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 if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\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()) as TResult };\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 | %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 ?? `status=${res?.status}`,\n res?.headers.get(\"unkey-request-id\"),\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\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 (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async <TPermission extends string = string>(\n req: Omit<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n \"authorization\"\n > & { authorization?: { permissions: PermissionQuery<TPermission> } },\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n public get ratelimits() {\n return {\n limit: async (\n req: paths[\"/v1/ratelimits.limit\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/ratelimits.limit\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"ratelimits.limit\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n public get migrations() {\n return {\n createKeys: async (\n req: paths[\"/v1/migrations.createKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.createKeys\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.createKeys\"],\n method: \"POST\",\n body: req,\n });\n },\n enqueueKeys: async (\n req: paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"responses\"][\"202\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.enqueueKeys\"],\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({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\nexport { and, or, type Flatten } from \"@unkey/rbac\";\n","{\n \"name\": \"@unkey/api\",\n \"version\": \"0.24.0\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\"unkey\", \"client\", \"api\"],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\"./dist/**\"],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.9\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.5\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.5.3\"\n },\n \"dependencies\": {\n \"@unkey/rbac\": \"workspace:^\"\n }\n}\n","import { version } from \"../package.json\";\nimport type { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import type { PermissionQuery } from \"@unkey/rbac\";\nimport type { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\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 *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\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\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\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 if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\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 getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\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 if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\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()) as TResult };\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 | %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 ?? `status=${res?.status}`,\n res?.headers.get(\"unkey-request-id\"),\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\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 (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async <TPermission extends string = string>(\n req: Omit<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n \"authorization\"\n > & { authorization?: { permissions: PermissionQuery<TPermission> } },\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n public get ratelimits() {\n return {\n limit: async (\n req: paths[\"/v1/ratelimits.limit\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/ratelimits.limit\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"ratelimits.limit\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n public get migrations() {\n return {\n createKeys: async (\n req: paths[\"/v1/migrations.createKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.createKeys\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.createKeys\"],\n method: \"POST\",\n body: req,\n });\n },\n enqueueKeys: async (\n req: paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"responses\"][\"202\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.enqueueKeys\"],\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({ rootKey: \"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
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.23.0";
2
+ var version = "0.24.0";
3
3
 
4
4
  // src/telemetry.ts
5
5
  function getTelemetry(opts) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@unkey/api\",\n \"version\": \"0.23.0\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\n \"unkey\",\n \"client\",\n \"api\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\n \"./dist/**\"\n ],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.9\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.5\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.5.3\"\n },\n \"dependencies\": {\n \"@unkey/rbac\": \"workspace:^\"\n }\n}\n","import { version } from \"../package.json\";\nimport type { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import type { PermissionQuery } from \"@unkey/rbac\";\nimport type { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\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 *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\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\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\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 if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\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 getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\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 if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\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()) as TResult };\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 | %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 ?? `status=${res?.status}`,\n res?.headers.get(\"unkey-request-id\"),\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\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 (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async <TPermission extends string = string>(\n req: Omit<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n \"authorization\"\n > & { authorization?: { permissions: PermissionQuery<TPermission> } },\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n public get ratelimits() {\n return {\n limit: async (\n req: paths[\"/v1/ratelimits.limit\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/ratelimits.limit\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"ratelimits.limit\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n public get migrations() {\n return {\n createKeys: async (\n req: paths[\"/v1/migrations.createKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.createKeys\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.createKeys\"],\n method: \"POST\",\n body: req,\n });\n },\n enqueueKeys: async (\n req: paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"responses\"][\"202\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.enqueueKeys\"],\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({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n","export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\nexport { and, or, type Flatten } from \"@unkey/rbac\";\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../package.json","../src/telemetry.ts","../src/client.ts","../src/verify.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@unkey/api\",\n \"version\": \"0.24.0\",\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.ts\",\n \"license\": \"MIT\",\n \"private\": false,\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"keywords\": [\"unkey\", \"client\", \"api\"],\n \"bugs\": {\n \"url\": \"https://github.com/unkeyed/unkey/issues\"\n },\n \"homepage\": \"https://github.com/unkeyed/unkey#readme\",\n \"files\": [\"./dist/**\"],\n \"author\": \"Andreas Thomas <andreas@chronark.com>\",\n \"scripts\": {\n \"generate\": \"openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts\",\n \"build\": \"pnpm generate && tsup\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.14.9\",\n \"@unkey/tsconfig\": \"workspace:^\",\n \"openapi-typescript\": \"^6.7.5\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.5.3\"\n },\n \"dependencies\": {\n \"@unkey/rbac\": \"workspace:^\"\n }\n}\n","import { version } from \"../package.json\";\nimport type { UnkeyOptions } from \"./client\";\n\nexport type Telemetry = {\n /**\n * Unkey-Telemetry-Sdk\n * @example @unkey/api@v1.1.1\n */\n sdkVersions: string[];\n /**\n * Unkey-Telemetry-Platform\n * @example cloudflare\n */\n platform?: string;\n /**\n * Unkey-Telemetry-Runtime\n * @example node@v18\n */\n runtime?: string;\n};\n\nexport function getTelemetry(opts: UnkeyOptions): Telemetry | null {\n let platform: string | undefined;\n let runtime: string | undefined;\n const sdkVersions = [`@unkey/api@${version}`];\n\n try {\n if (typeof process !== \"undefined\") {\n if (process.env.UNKEY_DISABLE_TELEMETRY) {\n return null;\n }\n platform = process.env.VERCEL ? \"vercel\" : process.env.AWS_REGION ? \"aws\" : undefined;\n\n // @ts-ignore\n if (typeof EdgeRuntime !== \"undefined\") {\n runtime = \"edge-light\";\n } else {\n runtime = `node@${process.version}`;\n }\n }\n\n if (opts.wrapperSdkVersion) {\n sdkVersions.push(opts.wrapperSdkVersion);\n }\n } catch (_error) {}\n\n return { platform, runtime, sdkVersions };\n}\n","import type { PermissionQuery } from \"@unkey/rbac\";\nimport type { ErrorResponse } from \"./errors\";\nimport type { paths } from \"./openapi\";\n\nimport { type Telemetry, getTelemetry } from \"./telemetry\";\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 *\n * By default telemetry data is enabled, and sends:\n * runtime (Node.js / Edge)\n * platform (Node.js / Vercel / AWS)\n * SDK version\n */\n disableTelemetry?: boolean;\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\n /**\n * The version of the SDK instantiating this client.\n *\n * This is used for internal metrics and is not covered by semver, and may change at any time.\n *\n * You can leave this blank unless you are building a wrapper around this SDK.\n */\n wrapperSdkVersion?: string;\n};\n\ntype ApiRequest = {\n path: string[];\n} & (\n | {\n method: \"GET\";\n body?: never;\n query?: Record<string, string | number | boolean | null>;\n }\n | {\n method: \"POST\";\n body?: unknown;\n query?: never;\n }\n);\n\ntype Result<R> =\n | {\n result: R;\n error?: never;\n }\n | {\n result?: never;\n error: ErrorResponse[\"error\"];\n };\n\nexport class Unkey {\n public readonly baseUrl: string;\n private readonly rootKey: string;\n private readonly cache?: RequestCache;\n private readonly telemetry?: Telemetry | null;\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 if (!opts.disableTelemetry) {\n this.telemetry = getTelemetry(opts);\n }\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 getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${this.rootKey}`,\n };\n if (this.telemetry?.sdkVersions) {\n headers[\"Unkey-Telemetry-SDK\"] = this.telemetry.sdkVersions.join(\",\");\n }\n if (this.telemetry?.platform) {\n headers[\"Unkey-Telemetry-Platform\"] = this.telemetry.platform;\n }\n if (this.telemetry?.runtime) {\n headers[\"Unkey-Telemetry-Runtime\"] = this.telemetry.runtime;\n }\n return headers;\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 if (v === null) {\n continue;\n }\n url.searchParams.set(k, v.toString());\n }\n }\n res = await fetch(url, {\n method: req.method,\n headers: this.getHeaders(),\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()) as TResult };\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 | %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 ?? `status=${res?.status}`,\n res?.headers.get(\"unkey-request-id\"),\n );\n await new Promise((r) => setTimeout(r, backoff));\n }\n\n if (res) {\n return { error: (await res.json()) as ErrorResponse[\"error\"] };\n }\n\n return {\n error: {\n // @ts-ignore\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 (\n req: paths[\"/v1/keys.createKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.createKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.createKey\"],\n method: \"POST\",\n body: req,\n });\n },\n update: async (\n req: paths[\"/v1/keys.updateKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateKey\"],\n method: \"POST\",\n body: req,\n });\n },\n verify: async <TPermission extends string = string>(\n req: Omit<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n \"authorization\"\n > & { authorization?: { permissions: PermissionQuery<TPermission> } },\n ): Promise<\n Result<\n paths[\"/v1/keys.verifyKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.verifyKey\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/keys.deleteKey\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.deleteKey\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.deleteKey\"],\n method: \"POST\",\n body: req,\n });\n },\n updateRemaining: async (\n req: paths[\"/v1/keys.updateRemaining\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.updateRemaining\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.updateRemaining\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/keys.getKey\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/keys.getKey\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getKey\"],\n method: \"GET\",\n query: req,\n });\n },\n getVerifications: async (\n req: paths[\"/v1/keys.getVerifications\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<\n paths[\"/v1/keys.getVerifications\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"keys.getVerifications\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n\n public get apis() {\n return {\n create: async (\n req: paths[\"/v1/apis.createApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.createApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.createApi\"],\n method: \"POST\",\n body: req,\n });\n },\n delete: async (\n req: paths[\"/v1/apis.deleteApi\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/apis.deleteApi\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.deleteApi\"],\n method: \"POST\",\n body: req,\n });\n },\n get: async (\n req: paths[\"/v1/apis.getApi\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.getApi\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.getApi\"],\n method: \"GET\",\n query: req,\n });\n },\n listKeys: async (\n req: paths[\"/v1/apis.listKeys\"][\"get\"][\"parameters\"][\"query\"],\n ): Promise<\n Result<paths[\"/v1/apis.listKeys\"][\"get\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]>\n > => {\n return await this.fetch({\n path: [\"v1\", \"apis.listKeys\"],\n method: \"GET\",\n query: req,\n });\n },\n };\n }\n public get ratelimits() {\n return {\n limit: async (\n req: paths[\"/v1/ratelimits.limit\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/ratelimits.limit\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"ratelimits.limit\"],\n method: \"POST\",\n body: req,\n });\n },\n };\n }\n public get migrations() {\n return {\n createKeys: async (\n req: paths[\"/v1/migrations.createKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.createKeys\"][\"post\"][\"responses\"][\"200\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.createKeys\"],\n method: \"POST\",\n body: req,\n });\n },\n enqueueKeys: async (\n req: paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"requestBody\"][\"content\"][\"application/json\"],\n ): Promise<\n Result<\n paths[\"/v1/migrations.enqueueKeys\"][\"post\"][\"responses\"][\"202\"][\"content\"][\"application/json\"]\n >\n > => {\n return await this.fetch({\n path: [\"v1\", \"migrations.enqueueKeys\"],\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({ rootKey: \"public\" });\n return unkey.keys.verify(typeof req === \"string\" ? { key: req } : req);\n}\n","export * from \"./client\";\nexport * from \"./verify\";\nexport * from \"./errors\";\nexport { and, or, type Flatten } from \"@unkey/rbac\";\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unkey/api",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",