diff --git a/apps/api/package.json b/apps/api/package.json index bd67fc7d98..c7abdb774f 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -13,7 +13,7 @@ "devDependencies": { "@cloudflare/vitest-pool-workers": "^0.8.12", "@cloudflare/workers-types": "^4.20240603.0", - "@unkey/api": "workspace:^", + "@unkey/api": "2.0.0", "@unkey/tsconfig": "workspace:^", "@vitest/ui": "^1.6.0", "typescript": "^5.5.3", diff --git a/apps/api/src/integration/sdk/create_and_verify.test.ts b/apps/api/src/integration/sdk/create_and_verify.test.ts deleted file mode 100644 index 6c70d38f57..0000000000 --- a/apps/api/src/integration/sdk/create_and_verify.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; -import { type Flatten, Unkey, or } from "@unkey/api/src/index"; // use unbundled raw esm typescript -import { schema } from "@unkey/db"; -import { newId } from "@unkey/id"; -import { expect, test } from "vitest"; - -test("create with roles and permissions", async (t) => { - const h = await IntegrationHarness.init(t); - type Resources = { - domain: "create" | "delete" | "read"; - dns: { - record: "create" | "read" | "delete"; - }; - }; - type Permissions = Flatten; - - const roleId = newId("test"); - await h.db.primary.insert(schema.roles).values({ - id: roleId, - name: "domain.manager", - workspaceId: h.resources.userWorkspace.id, - }); - - for (const name of ["domain.create", "dns.record.create", "domain.delete"]) { - const permissionId = newId("test"); - await h.db.primary.insert(schema.permissions).values({ - id: permissionId, - name, - slug: name, - workspaceId: h.resources.userWorkspace.id, - }); - - await h.db.primary.insert(schema.rolesPermissions).values({ - roleId, - permissionId, - workspaceId: h.resources.userWorkspace.id, - }); - } - - const { key: rootKey } = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: rootKey, - }); - - const create = await sdk.keys.create({ - apiId: h.resources.userApi.id, - roles: ["domain.manager"], - }); - expect(create.error).toBeUndefined(); - const key = create.result!.key; - - const verify = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key, - authorization: { - permissions: or("domain.create", "dns.record.create"), - }, - }); - - expect(verify.error).toBeUndefined(); - expect(verify.result).toBeDefined(); - - expect(verify.result!.valid).toBe(true); -}, 10_000); diff --git a/apps/api/src/integration/sdk/create_key_then_update_identity.test.ts b/apps/api/src/integration/sdk/create_key_then_update_identity.test.ts deleted file mode 100644 index f425edc632..0000000000 --- a/apps/api/src/integration/sdk/create_key_then_update_identity.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; -import { Unkey } from "@unkey/api/src/index"; // use unbundled raw esm typescript -import { newId } from "@unkey/id"; -import { expect, test } from "vitest"; - -test("create key and then update the identity", async (t) => { - const h = await IntegrationHarness.init(t); - - const root = await h.createRootKey([ - `api.${h.resources.userApi.id}.create_key`, - "identity.*.create_identity", - "identity.*.update_identity", - ]); - const unkey = new Unkey({ baseUrl: h.baseUrl, rootKey: root.key }); - - const userId = newId("test"); - const externalId = newId("test"); - - const key = await unkey.keys.create({ - apiId: h.resources.userApi.id, - prefix: "XXX", - externalId: externalId, - name: "org_test", - }); - - expect(key.error).toBeUndefined(); - - const identity = await unkey.identities.update({ - externalId, - environment: "default", - meta: { - userId, - }, - ratelimits: [ - { - name: "default", - limit: 50, - duration: 1000, - }, - ], - }); - - expect(identity.error).toBeUndefined(); - expect(identity.result!.meta.userId).toEqual(userId); -}, 10_000); diff --git a/apps/api/src/integration/sdk/create_key_with_permissions.ts b/apps/api/src/integration/sdk/create_key_with_permissions.ts deleted file mode 100644 index 0a42c37e36..0000000000 --- a/apps/api/src/integration/sdk/create_key_with_permissions.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; -import { Unkey, and } from "@unkey/api/src/index"; // use unbundled raw esm typescript -import { schema } from "@unkey/db"; -import { newId } from "@unkey/id"; -import { expect, test } from "vitest"; - -test("create with permissions", async (t) => { - const h = await IntegrationHarness.init(t); - - const permissions = ["domain.create", "dns.record.create", "domain.delete"]; - await h.db.primary.insert(schema.permissions).values( - permissions.map((name) => ({ - id: newId("test"), - name, - slug: name, - workspaceId: h.resources.userWorkspace.id, - })), - ); - - const { key: rootKey } = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: rootKey, - }); - - const create = await sdk.keys.create({ - apiId: h.resources.userApi.id, - permissions: ["domain.create", "dns.record.create"], - }); - expect(create.error).toBeUndefined(); - // biome-ignore lint/style/noNonNullAssertion: Safe to leave - const key = create.result!.key; - - const verify = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key, - authorization: { - permissions: and("domain.create", "dns.record.create"), - }, - }); - - expect(verify.error).toBeUndefined(); - expect(verify.result).toBeDefined(); - - expect(verify.result?.valid).toBe(true); -}, 10_000); diff --git a/apps/api/src/integration/sdk/verify.test.ts b/apps/api/src/integration/sdk/verify.test.ts deleted file mode 100644 index 5b613d20a5..0000000000 --- a/apps/api/src/integration/sdk/verify.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { describe } from "node:test"; -import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; -import { type Flatten, Unkey, and, or } from "@unkey/api/src/index"; // use unbundled raw esm typescript -import { expect, test } from "vitest"; - -test("with raw query", async (t) => { - const h = await IntegrationHarness.init(t); - const { key } = await h.createKey(); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: "not-needed-for-this-test", - }); - - const { result, error } = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key, - authorization: { - permissions: { - and: ["p1", "p2"], - }, - }, - }); - expect(error).toBeUndefined(); - expect(result).toBeDefined(); - - expect(result!.valid).toBe(false); - expect(result!.code).toBe("INSUFFICIENT_PERMISSIONS"); -}); - -describe("with typesafe generated permissions", () => { - test("returns valid", async (t) => { - const h = await IntegrationHarness.init(t); - const { key } = await h.createKey({ - roles: [ - { - name: "domain.manager", - permissions: ["domain.create", "dns.record.create", "domain.delete"], - }, - ], - }); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: "not-needed-for-this-test", - }); - - type Resources = { - domain: "create" | "delete" | "read"; - dns: { - record: "create" | "read" | "delete"; - }; - }; - type Permissions = Flatten; - - const { result, error } = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key, - authorization: { - permissions: or("domain.create", "dns.record.create"), - }, - }); - - expect(error).toBeUndefined(); - expect(result).toBeDefined(); - - expect(result!.valid).toBe(true); - }); - - test("with helper functions", async (t) => { - const h = await IntegrationHarness.init(t); - const { key } = await h.createKey(); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: "not-needed-for-this-test", - }); - - type Permission = "p1" | "p2"; - - const { result, error } = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key, - authorization: { - permissions: and("p1", "p2"), - }, - }); - expect(error).toBeUndefined(); - expect(result).toBeDefined(); - - expect(result!.valid).toBe(false); - expect(result!.code).toBe("INSUFFICIENT_PERMISSIONS"); - }); -}); diff --git a/apps/api/src/integration/sdk/verify_with_ratelimit.test.ts b/apps/api/src/integration/sdk/verify_with_ratelimit.test.ts deleted file mode 100644 index 0a93c953a5..0000000000 --- a/apps/api/src/integration/sdk/verify_with_ratelimit.test.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; -import { Unkey } from "@unkey/api/src/index"; // use unbundled raw esm typescript -import { schema } from "@unkey/db"; -import { newId } from "@unkey/id"; -import { expect, test } from "vitest"; - -test("1 per 10 seconds", async (t) => { - const h = await IntegrationHarness.init(t); - - const root = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - - await h.db.primary.insert(schema.roles).values({ - id: newId("test"), - workspaceId: h.resources.userWorkspace.id, - name: "role", - }); - - const sdk = new Unkey({ - baseUrl: h.baseUrl, - rootKey: root.key, - }); - - const { result: key, error: createKeyError } = await sdk.keys.create({ - apiId: h.resources.userApi.id, - ownerId: "ownerId", - roles: ["role"], - ratelimit: { - limit: 1, - duration: 10000, - async: false, - }, - }); - expect(createKeyError).toBeUndefined(); - expect(key).toBeDefined(); - - const { result: firstVerify, error: firstVerifyError } = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key: key!.key, - ratelimit: { - cost: 1, - }, - }); - expect(firstVerifyError).toBeUndefined(); - expect(firstVerify).toBeDefined(); - expect(firstVerify!.code).toBe("VALID"); - - const { result: secondVerify, error: secondVerifyError } = await sdk.keys.verify({ - apiId: h.resources.userApi.id, - key: key!.key, - }); - expect(secondVerifyError).toBeUndefined(); - expect(secondVerify).toBeDefined(); - expect(secondVerify!.code).toBe("RATE_LIMITED"); -}); diff --git a/apps/api/src/integration/verify_permissions.test.ts b/apps/api/src/integration/verify_permissions.test.ts index a262df2751..ad57f967d1 100644 --- a/apps/api/src/integration/verify_permissions.test.ts +++ b/apps/api/src/integration/verify_permissions.test.ts @@ -1,6 +1,5 @@ import { IntegrationHarness } from "@/pkg/testutil/integration-harness"; import type { V1KeysVerifyKeyRequest, V1KeysVerifyKeyResponse } from "@/routes/v1_keys_verifyKey"; -import type { ErrorResponse } from "@unkey/api/src"; import { describe, expect, test } from "vitest"; test("without permissions", async (t) => { @@ -199,7 +198,7 @@ describe( const h = await IntegrationHarness.init(t); const { key } = await h.createKey(); - const res = await h.post({ + const res = await h.post({ url: `${h.baseUrl}/v1/keys.verifyKey`, headers: { "Content-Type": "application/json", diff --git a/apps/api/src/routes/v1_keys_createKey.security.test.ts b/apps/api/src/routes/v1_keys_createKey.security.test.ts index a376b768e4..c28b49511a 100644 --- a/apps/api/src/routes/v1_keys_createKey.security.test.ts +++ b/apps/api/src/routes/v1_keys_createKey.security.test.ts @@ -4,7 +4,6 @@ import { eq, schema } from "@unkey/db"; import { newId } from "@unkey/id"; import { IntegrationHarness } from "src/pkg/testutil/integration-harness"; -import type { ErrorResponse } from "@unkey/api/src"; import { describe, expect, test } from "vitest"; import type { V1KeysCreateKeyRequest, V1KeysCreateKeyResponse } from "./v1_keys_createKey"; @@ -94,7 +93,7 @@ test("cannot encrypt without permissions", async (t) => { const root = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - const res = await h.post({ + const res = await h.post({ url: "/v1/keys.createKey", headers: { "Content-Type": "application/json", @@ -122,7 +121,7 @@ test("cannot create role without permissions", async (t) => { const root = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - const res = await h.post({ + const res = await h.post({ url: "/v1/keys.createKey", headers: { "Content-Type": "application/json", @@ -150,7 +149,7 @@ test("cannot create permission without permissions", async (t) => { const root = await h.createRootKey([`api.${h.resources.userApi.id}.create_key`]); - const res = await h.post({ + const res = await h.post({ url: "/v1/keys.createKey", headers: { "Content-Type": "application/json", diff --git a/apps/api/src/routes/v1_keys_verifyKey.multilimit.test.ts b/apps/api/src/routes/v1_keys_verifyKey.multilimit.test.ts index 50278c2357..3c2e6c5d19 100644 --- a/apps/api/src/routes/v1_keys_verifyKey.multilimit.test.ts +++ b/apps/api/src/routes/v1_keys_verifyKey.multilimit.test.ts @@ -6,7 +6,6 @@ import { newId } from "@unkey/id"; import { KeyV1 } from "@unkey/keys"; import { IntegrationHarness } from "src/pkg/testutil/integration-harness"; -import type { ErrorResponse } from "@unkey/api/src"; import type { V1KeysVerifyKeyRequest, V1KeysVerifyKeyResponse } from "./v1_keys_verifyKey"; describe("without identities", () => { @@ -110,7 +109,7 @@ describe("without identities", () => { createdAtM: Date.now(), }); - const res = await h.post({ + const res = await h.post({ url: "/v1/keys.verifyKey", headers: { "Content-Type": "application/json", diff --git a/apps/api/src/routes/v1_migrations_createKey.happy.test.ts b/apps/api/src/routes/v1_migrations_createKey.happy.test.ts index 1303e17f30..bcaf420fff 100644 --- a/apps/api/src/routes/v1_migrations_createKey.happy.test.ts +++ b/apps/api/src/routes/v1_migrations_createKey.happy.test.ts @@ -5,7 +5,6 @@ import { eq, schema } from "@unkey/db"; import { newId } from "@unkey/id"; import { IntegrationHarness } from "src/pkg/testutil/integration-harness"; -import type { ErrorResponse } from "@unkey/api/src"; import { sha256 } from "@unkey/hash"; import { KeyV1 } from "@unkey/keys"; import type { V1KeysGetKeyResponse } from "./v1_keys_getKey"; @@ -481,7 +480,10 @@ test("an error rolls back and does not create any keys", async (t) => { // add a duplicate req.push(req[0]); - const res = await h.post({ + + const res = await h.post({ url: "/v1/migrations.createKeys", headers: { "Content-Type": "application/json", diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md deleted file mode 100644 index a15f9861de..0000000000 --- a/packages/api/CHANGELOG.md +++ /dev/null @@ -1,299 +0,0 @@ -# @unkey/api - -## 0.38.0 - -### Minor Changes - -- a4636e6: feat: add listPermissions and listRoles - -## 0.37.0 - -### Minor Changes - -- 0b489a9: feat: return permission slugs - -## 0.35.0 - -### Minor Changes - -- f73fc7e: feat: add permissions - -## 0.34.0 - -### Minor Changes - -- 8b69b15: feat: return requestId - -## 0.33.1 - -### Patch Changes - -- 10120e0: don't retry on 4XX - -## 0.33.0 - -### Minor Changes - -- 98bbb16: Add all options to verifyKey - -## 0.32.0 - -### Minor Changes - -- a2f16f0: Add all options to verifyKey - -## 0.31.0 - -### Minor Changes - -- 56ae5f6: feat: add analytics - -## 0.30.0 - -### Minor Changes - -- 0746b33: Add the types for error codes - -## 0.29.0 - -### Minor Changes - -- 3f8d078: Adding ratelimit override API to SDK - -## 0.28.0 - -### Minor Changes - -- 25fd102: feat: tags - -## 0.27.0 - -### Minor Changes - -- 852d1a1: Add ratelimit override API - -## 0.26.2 - -### Patch Changes - -- 82f5b5d: create readme - -## 0.26.1 - -### Patch Changes - -- 2aada7d: fix: 🌐 Correctly handle `undefined` values in API package fetch. - -## 0.26.0 - -### Minor Changes - -- bb6d04e: add skip cache flag - -## 0.25.0 - -### Minor Changes - -- a532369: add identities - -## 0.24.0 - -### Minor Changes - -- bdad4b6: feat: mark keys as recoverable - -## 0.23.0 - -### Minor Changes - -- e3231e3: Add identities - -## 0.22.1 - -### Patch Changes - -- Updated dependencies [6e386ad] - - @unkey/rbac@0.3.1 - -## 0.22.0 - -### Minor Changes - -- 53a1df1: Update licenses in package.json - -### Patch Changes - -- Updated dependencies [53a1df1] - - @unkey/rbac@0.3.0 - -## 0.21.0 - -### Minor Changes - -- 9dab761: Updating licenses - -### Patch Changes - -- Updated dependencies [9dab761] - - @unkey/rbac@0.2.0 - -## 0.20.7 - -### Patch Changes - -- 69c88fa: enqueue keys - -## 0.20.6 - -### Patch Changes - -- 56ad960: allow adding permissions on when creating keys - -## 0.20.5 - -### Patch Changes - -- e4961c7: feat(client.ts): add support for migrations.createKeys endpoint in Unkey class - -## 0.20.4 - -### Patch Changes - -- 3ddb1f1: feat: apis.deleteKeys - -## 0.20.3 - -### Patch Changes - -- fc2b651: update -- Updated dependencies [fc2b651] - - @unkey/rbac@0.1.13 - -## 0.20.2 - -### Patch Changes - -- c14b285: add updatedAt field when retrieving keys - -## 0.20.1 - -### Patch Changes - -- @unkey/rbac@0.1.12 - -## 0.20.0 - -### Minor Changes - -- 94d721d: Allow overriding ratelimit cost - -## 0.19.5 - -### Patch Changes - -- a4001eb: Fix UnkeyContext type - -## 0.19.4 - -### Patch Changes - -- 7043c1c: Add ratelimit - -## 0.19.3 - -### Patch Changes - -- Updated dependencies [04b1785] - - @unkey/rbac@0.1.11 - -## 0.19.2 - -### Patch Changes - -- a2f3d7a: Include status and trace id in logs - -## 0.19.1 - -### Patch Changes - -- d561b57: Release rbac as separate package -- Updated dependencies [d561b57] - - @unkey/rbac@0.1.10 - -## 0.19.0 - -### Minor Changes - -- eddab6b: RBAC introduction - -## 0.18.0 - -### Minor Changes - -- 2af9a51: Add permission checks - -## 0.17.0 - -### Minor Changes - -- 9f5f3d6: Collect SDK telemetry data - -## 0.16.0 - -### Minor Changes - -- 5de3ae76: add enabled flag - -## 0.15.0 - -### Minor Changes - -- a1e82245: add getVerifications method - -## 0.14.0 - -### Minor Changes - -- 2e26a07e: Add refill options - -## 0.13.1 - -### Patch Changes - -- 153bd10: send name and version in header - -## 0.13.0 - -### Minor Changes - -- 0bfbc54: autogenerate types - -## 0.12.1 - -### Patch Changes - -- 2347efd: Fix `@unkey/client` types - -## 0.12.0 - -### Minor Changes - -- 8a6b040: accept apiId when verifying a key - -## 0.11.0 - -### Minor Changes - -- 4cb0267: allow configuration of cache behavior - -## 0.10.2 - -### Patch Changes - -- 7a1ddf3: accept rootKey or token - -## 0.10.0 - -### Minor Changes - -- 631a37c: fix version diff --git a/packages/api/LICENSE.md b/packages/api/LICENSE.md deleted file mode 100644 index d02c4877cd..0000000000 --- a/packages/api/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023-present Unkeyed, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/api/README.md b/packages/api/README.md deleted file mode 100644 index 183117d65e..0000000000 --- a/packages/api/README.md +++ /dev/null @@ -1,125 +0,0 @@ -
-

@unkey/api

-
`@unkey/api` is a TypeScript client for Unkey. If you prefer a typed experience over calling HTTP endpoints directly, this SDK is for you.
-
- - - - -
- - -Currently the latest version on npm is v2.0.0-alpha.x, which was released on the main channel by accident. Due to npm’s policy, we can not take it back down. - -v2 is coming, but it’s not ready yet and lacks some api methods. Please install @unkey/api@0.35 for now. - -## Installation - -```bash -npm install @unkey/api@0.35 -``` - -## Quickstart - -1. Create a new Unkey Root Key in the settings. -2. Use the root key to initialize the client: - -```ts -import { Unkey } from "@unkey/api"; - -const unkey = new Unkey({ rootKey: "" }); -``` - -**Important:** Always keep your root key safe and reset it if you suspect it has been compromised. - -## Usage - -### Verifying a Key - -```ts -import { verifyKey } from "@unkey/api"; - -const { result, error } = await verifyKey("key_123"); - -if (error) { - console.error(error.message); - // Handle potential network or bad request error - // A link to our docs will be in the `error.docs` field - return; -} - -if (!result.valid) { - // Do not grant access - return; -} - -// Process request -console.log(result); -``` - -## Response Format - -All methods return either an `error` or a `result` field, never both and never none. This approach helps with proper error handling. - -### Success Response - -```ts -{ - result: T; // The result depends on what method you called -} -``` - -### Error Response - -```ts -{ - error: { - message: string; - docs: string; // URL to relevant documentation - } -} -``` - -## Configuration Options - -### Base URL - -You can customize the base URL for all requests: - -```ts -const unkey = new Unkey({ - rootKey: "", - baseUrl: "https://my.domain", -}); -``` - -### Retries - -Configure retry behavior for network errors: - -```ts -const unkey = new Unkey({ - rootKey: "", - retry: { - attempts: 3, - backoff: (retryCount) => retryCount * 1000, - }, -}); -``` - -### Disable Telemetry - -To opt out of anonymous telemetry data collection: - -```ts -const unkey = new Unkey({ - rootKey: "", - disableTelemetry: true, -}); -``` - -### Documentation - -[Read the full documentation](https://www.unkey.com/docs/libraries/ts/sdk/overview) diff --git a/packages/api/package.json b/packages/api/package.json deleted file mode 100644 index b2a6b4c8c2..0000000000 --- a/packages/api/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "@unkey/api", - "version": "0.38.0", - "main": "./dist/index.js", - "module": "./dist/index.mjs", - "types": "./dist/index.d.ts", - "license": "MIT", - "private": false, - "publishConfig": { - "access": "public" - }, - "keywords": ["unkey", "client", "api"], - "bugs": { - "url": "https://github.com/unkeyed/unkey/issues" - }, - "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**", "README.md"], - "author": "Andreas Thomas ", - "scripts": { - "generate": "openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts", - "build": "pnpm generate && tsup", - "test": "vitest run" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "@unkey/tsconfig": "workspace:^", - "openapi-typescript": "^6.7.5", - "tsup": "^8.0.2", - "typescript": "^5.5.3", - "vitest": "^1.6.1" - }, - "dependencies": { - "@unkey/rbac": "workspace:^" - } -} diff --git a/packages/api/src/client.test.ts b/packages/api/src/client.test.ts deleted file mode 100644 index 20ef60f88e..0000000000 --- a/packages/api/src/client.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { describe, expect, test } from "vitest"; -import { Unkey } from "./client"; - -describe("client", () => { - test("fetch can encode the params without throwing", async () => { - const unkey = new Unkey({ token: "rawr" }); - expect(() => { - unkey.apis.listKeys({ - apiId: "meow", - cursor: undefined, - }); - }).not.toThrow(); - }); - - test("errors are correctly passed through to the caller", async () => { - const unkey = new Unkey({ rootKey: "wrong key" }); - const res = await unkey.keys.create({ - apiId: "", - }); - - expect(res.error).toBeDefined(); - expect(res.error!.code).toEqual("UNAUTHORIZED"); - expect(res.error!.docs).toEqual( - "https://unkey.dev/docs/api-reference/errors/code/UNAUTHORIZED", - ); - expect(res.error!.message).toEqual("key not found"); - expect(res.error!.requestId).toBeDefined(); - }); -}); diff --git a/packages/api/src/client.ts b/packages/api/src/client.ts deleted file mode 100644 index 9320a67654..0000000000 --- a/packages/api/src/client.ts +++ /dev/null @@ -1,737 +0,0 @@ -import type { PermissionQuery } from "@unkey/rbac"; -import type { ErrorResponse } from "./errors"; -import type { paths } from "./openapi"; - -import { type Telemetry, getTelemetry } from "./telemetry"; - -export type UnkeyOptions = ( - | { - token?: never; - - /** - * The root key from unkey.dev. - * - * You can create/manage your root keys here: - * https://unkey.dev/app/settings/root-keys - */ - rootKey: string; - } - | { - /** - * The workspace key from unkey.dev - * - * @deprecated Use `rootKey` - */ - token: string; - rootKey?: never; - } -) & { - /** - * @default https://api.unkey.dev - */ - baseUrl?: string; - - /** - * - * By default telemetry data is enabled, and sends: - * runtime (Node.js / Edge) - * platform (Node.js / Vercel / AWS) - * SDK version - */ - disableTelemetry?: boolean; - - /** - * Retry on network errors - */ - retry?: { - /** - * How many attempts should be made - * The maximum number of requests will be `attempts + 1` - * `0` means no retries - * - * @default 5 - */ - attempts?: number; - /** - * Return how many milliseconds to wait until the next attempt is made - * - * @default `(retryCount) => Math.round(Math.exp(retryCount) * 10)),` - */ - backoff?: (retryCount: number) => number; - }; - /** - * Customize the `fetch` cache behaviour - */ - cache?: RequestCache; - - /** - * The version of the SDK instantiating this client. - * - * This is used for internal metrics and is not covered by semver, and may change at any time. - * - * You can leave this blank unless you are building a wrapper around this SDK. - */ - wrapperSdkVersion?: string; -}; - -type ApiRequest = { - path: string[]; -} & ( - | { - method: "GET"; - body?: never; - query?: Record; - } - | { - method: "POST"; - body?: unknown; - query?: never; - } -); - -type Result = - | { - result: R; - error?: never; - } - | { - result?: never; - error: { - code: ErrorResponse["error"]["code"]; - message: ErrorResponse["error"]["message"]; - docs: ErrorResponse["error"]["docs"]; - requestId: string; - }; - }; - -export class Unkey { - public readonly baseUrl: string; - private readonly rootKey: string; - private readonly cache?: RequestCache; - private readonly telemetry?: Telemetry | null; - - public readonly retry: { - attempts: number; - backoff: (retryCount: number) => number; - }; - - constructor(opts: UnkeyOptions) { - this.baseUrl = opts.baseUrl ?? "https://api.unkey.dev"; - this.rootKey = opts.rootKey ?? opts.token; - if (!opts.disableTelemetry) { - this.telemetry = getTelemetry(opts); - } - - this.cache = opts.cache; - /** - * Even though typescript should prevent this, some people still pass undefined or empty strings - */ - if (!this.rootKey) { - throw new Error( - "Unkey root key must be set, maybe you passed in `undefined` or an empty string?", - ); - } - - this.retry = { - attempts: opts.retry?.attempts ?? 5, - backoff: opts.retry?.backoff ?? ((n) => Math.round(Math.exp(n) * 10)), - }; - } - - private getHeaders(): Record { - const headers: Record = { - "Content-Type": "application/json", - Authorization: `Bearer ${this.rootKey}`, - }; - if (this.telemetry?.sdkVersions) { - headers["Unkey-Telemetry-SDK"] = this.telemetry.sdkVersions.join(","); - } - if (this.telemetry?.platform) { - headers["Unkey-Telemetry-Platform"] = this.telemetry.platform; - } - if (this.telemetry?.runtime) { - headers["Unkey-Telemetry-Runtime"] = this.telemetry.runtime; - } - return headers; - } - - private async fetch(req: ApiRequest): Promise> { - let res: Response | null = null; - let err: Error | null = null; - for (let i = 0; i <= this.retry.attempts; i++) { - const url = new URL(`${this.baseUrl}/${req.path.join("/")}`); - if (req.query) { - for (const [k, v] of Object.entries(req.query)) { - if (typeof v === "undefined" || v === null) { - continue; - } - url.searchParams.set(k, v.toString()); - } - } - res = await fetch(url, { - method: req.method, - headers: this.getHeaders(), - cache: this.cache, - body: JSON.stringify(req.body), - }).catch((e: Error) => { - err = e; - return null; // set `res` to `null` - }); - // 200-299 -> success - if (res && res.status >= 200 && res.status <= 299) { - return { result: (await res.json()) as TResult }; - } - // 400-499 -> client error, retries are futile - if (res && res.status >= 400 && res.status <= 499) { - return (await res.json()) as ErrorResponse; - } - const backoff = this.retry.backoff(i); - console.debug( - `attempt ${i + 1} of ${ - this.retry.attempts + 1 - } to reach ${url} failed, retrying in ${backoff} ms: status=${ - res?.status - } | ${res?.headers.get("unkey-request-id")}`, - ); - await new Promise((r) => setTimeout(r, backoff)); - } - - if (res) { - return (await res.json()) as ErrorResponse; - } - - return { - error: { - // @ts-ignore - code: "FETCH_ERROR", - // @ts-ignore I don't understand why `err` is `never` - message: err?.message ?? "No response", - docs: "https://developer.mozilla.org/en-US/docs/Web/API/fetch", - requestId: "N/A", - }, - }; - } - - public get keys() { - return { - create: async ( - req: paths["/v1/keys.createKey"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.createKey"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.createKey"], - method: "POST", - body: req, - }); - }, - addPermissions: async ( - req: paths["/v1/keys.addPermissions"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.addPermissions"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.addPermissions"], - method: "POST", - body: req, - }); - }, - setPermissions: async ( - req: paths["/v1/keys.setPermissions"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.setPermissions"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.setPermissions"], - method: "POST", - body: req, - }); - }, - removePermissions: async ( - req: paths["/v1/keys.removePermissions"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.removePermissions"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.removePermissions"], - method: "POST", - body: req, - }); - }, - addRoles: async ( - req: paths["/v1/keys.addRoles"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.addRoles"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.addRoles"], - method: "POST", - body: req, - }); - }, - removeRoles: async ( - req: paths["/v1/keys.removeRoles"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.removeRoles"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.removeRoles"], - method: "POST", - body: req, - }); - }, - setRoles: async ( - req: paths["/v1/keys.setRoles"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.setRoles"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.setRoles"], - method: "POST", - body: req, - }); - }, - update: async ( - req: paths["/v1/keys.updateKey"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.updateKey"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.updateKey"], - method: "POST", - body: req, - }); - }, - verify: async ( - req: Omit< - paths["/v1/keys.verifyKey"]["post"]["requestBody"]["content"]["application/json"], - "authorization" - > & { authorization?: { permissions: PermissionQuery } }, - ): Promise< - Result< - paths["/v1/keys.verifyKey"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.verifyKey"], - method: "POST", - body: req, - }); - }, - delete: async ( - req: paths["/v1/keys.deleteKey"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.deleteKey"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.deleteKey"], - method: "POST", - body: req, - }); - }, - updateRemaining: async ( - req: paths["/v1/keys.updateRemaining"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/keys.updateRemaining"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.updateRemaining"], - method: "POST", - body: req, - }); - }, - get: async ( - req: paths["/v1/keys.getKey"]["get"]["parameters"]["query"], - ): Promise< - Result - > => { - return await this.fetch({ - path: ["v1", "keys.getKey"], - method: "GET", - query: req, - }); - }, - getVerifications: async ( - req: paths["/v1/keys.getVerifications"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/keys.getVerifications"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "keys.getVerifications"], - method: "GET", - query: req, - }); - }, - }; - } - - public get apis() { - return { - create: async ( - req: paths["/v1/apis.createApi"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/apis.createApi"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "apis.createApi"], - method: "POST", - body: req, - }); - }, - delete: async ( - req: paths["/v1/apis.deleteApi"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/apis.deleteApi"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "apis.deleteApi"], - method: "POST", - body: req, - }); - }, - get: async ( - req: paths["/v1/apis.getApi"]["get"]["parameters"]["query"], - ): Promise< - Result - > => { - return await this.fetch({ - path: ["v1", "apis.getApi"], - method: "GET", - query: req, - }); - }, - listKeys: async ( - req: paths["/v1/apis.listKeys"]["get"]["parameters"]["query"], - ): Promise< - Result - > => { - return await this.fetch({ - path: ["v1", "apis.listKeys"], - method: "GET", - query: req, - }); - }, - }; - } - public get permissions() { - return { - createRole: async ( - req: paths["/v1/permissions.createRole"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/permissions.createRole"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.createRole"], - method: "POST", - body: req, - }); - }, - getRole: async ( - req: paths["/v1/permissions.getRole"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/permissions.getRole"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.getRole"], - method: "GET", - query: req, - }); - }, - deleteRole: async ( - req: paths["/v1/permissions.deleteRole"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/permissions.deleteRole"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.deleteRole"], - method: "POST", - body: req, - }); - }, - createPermission: async ( - req: paths["/v1/permissions.createPermission"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/permissions.createPermission"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.createPermission"], - method: "POST", - body: req, - }); - }, - getPermission: async ( - req: paths["/v1/permissions.getPermission"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/permissions.getPermission"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.getPermission"], - method: "GET", - query: req, - }); - }, - listPermissions: async (): Promise< - Result< - paths["/v1/permissions.listPermissions"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.listPermissions"], - method: "GET", - query: undefined, - }); - }, - - listRoles: async (): Promise< - Result< - paths["/v1/permissions.listRoles"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.listRoles"], - method: "GET", - query: undefined, - }); - }, - - deletePermission: async ( - req: paths["/v1/permissions.deletePermission"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/permissions.deletePermission"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "permissions.deletePermission"], - method: "POST", - body: req, - }); - }, - }; - } - public get ratelimits() { - return { - limit: async ( - req: paths["/v1/ratelimits.limit"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/ratelimits.limit"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "ratelimits.limit"], - method: "POST", - body: req, - }); - }, - getOverride: async ( - req: paths["/v1/ratelimits.getOverride"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/ratelimits.getOverride"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "ratelimits.getOverride"], - method: "GET", - query: req, - }); - }, - listOverrides: async ( - req: paths["/v1/ratelimits.listOverrides"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/ratelimits.listOverrides"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "ratelimits.listOverrides"], - method: "GET", - query: req, - }); - }, - - setOverride: async ( - req: paths["/v1/ratelimits.setOverride"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/ratelimits.setOverride"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "ratelimits.setOverride"], - method: "POST", - body: req, - }); - }, - - deleteOverride: async ( - req: paths["/v1/ratelimits.deleteOverride"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/ratelimits.deleteOverride"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "ratelimits.deleteOverride"], - method: "POST", - body: req, - }); - }, - }; - } - public get identities() { - return { - create: async ( - req: paths["/v1/identities.createIdentity"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/identities.createIdentity"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "identities.createIdentity"], - method: "POST", - body: req, - }); - }, - get: async ( - req: paths["/v1/identities.getIdentity"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/identities.getIdentity"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "identities.getIdentity"], - method: "GET", - query: req, - }); - }, - list: async ( - req: paths["/v1/identities.listIdentities"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/identities.listIdentities"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "identities.listIdentities"], - method: "GET", - query: req, - }); - }, - delete: async ( - req: paths["/v1/identities.deleteIdentity"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/identities.deleteIdentity"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "identities.deleteIdentity"], - method: "POST", - body: req, - }); - }, - update: async ( - req: paths["/v1/identities.updateIdentity"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/identities.updateIdentity"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "identities.updateIdentity"], - method: "POST", - body: req, - }); - }, - }; - } - - public get analytics() { - return { - getVerifications: async ( - req: paths["/v1/analytics.getVerifications"]["get"]["parameters"]["query"], - ): Promise< - Result< - paths["/v1/analytics.getVerifications"]["get"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "analytics.getVerifications"], - method: "GET", - query: req, - }); - }, - }; - } - - public get migrations() { - return { - createKeys: async ( - req: paths["/v1/migrations.createKeys"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/migrations.createKeys"]["post"]["responses"]["200"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "migrations.createKeys"], - method: "POST", - body: req, - }); - }, - enqueueKeys: async ( - req: paths["/v1/migrations.enqueueKeys"]["post"]["requestBody"]["content"]["application/json"], - ): Promise< - Result< - paths["/v1/migrations.enqueueKeys"]["post"]["responses"]["202"]["content"]["application/json"] - > - > => { - return await this.fetch({ - path: ["v1", "migrations.enqueueKeys"], - method: "POST", - body: req, - }); - }, - }; - } -} diff --git a/packages/api/src/errors.ts b/packages/api/src/errors.ts deleted file mode 100644 index f04cedbeb8..0000000000 --- a/packages/api/src/errors.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { paths } from "./openapi"; - -// this is what a json body response looks like -export type ErrorResponse = - | paths["/v1/liveness"]["get"]["responses"]["400"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["401"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["403"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["404"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["409"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["429"]["content"]["application/json"] - | paths["/v1/liveness"]["get"]["responses"]["500"]["content"]["application/json"]; diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts deleted file mode 100644 index febfcff6a3..0000000000 --- a/packages/api/src/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./client"; -export * from "./verify"; -export * from "./errors"; -export { and, or, type Flatten } from "@unkey/rbac"; diff --git a/packages/api/src/openapi.d.ts b/packages/api/src/openapi.d.ts deleted file mode 100644 index 85ef3064eb..0000000000 --- a/packages/api/src/openapi.d.ts +++ /dev/null @@ -1,5312 +0,0 @@ -/** - * This file was auto-generated by openapi-typescript. - * Do not make direct changes to the file. - */ - -/** OneOf type helpers */ -type Without = { [P in Exclude]?: never }; -type XOR = T | U extends object ? (Without & U) | (Without & T) : T | U; -type OneOf = T extends [infer Only] - ? Only - : T extends [infer A, infer B, ...infer Rest] - ? OneOf<[XOR, ...Rest]> - : never; - -export interface paths { - "/v1/liveness": { - get: operations["v1.liveness"]; - }; - "/v1/keys.getKey": { - get: operations["getKey"]; - }; - "/v1/keys.whoami": { - post: operations["whoami"]; - }; - "/v1/keys.deleteKey": { - post: operations["deleteKey"]; - }; - "/v1/keys.createKey": { - post: operations["createKey"]; - }; - "/v1/keys.verifyKey": { - post: operations["verifyKey"]; - }; - "/v1/keys.updateKey": { - post: operations["updateKey"]; - }; - "/v1/keys.updateRemaining": { - post: operations["updateRemaining"]; - }; - "/v1/keys.getVerifications": { - get: operations["keys.getVerifications"]; - }; - "/v1/keys.addPermissions": { - post: operations["addPermissions"]; - }; - "/v1/keys.removePermissions": { - post: operations["removePermissions"]; - }; - "/v1/keys.setPermissions": { - post: operations["setPermissions"]; - }; - "/v1/keys.addRoles": { - post: operations["addRoles"]; - }; - "/v1/keys.removeRoles": { - post: operations["removeRoles"]; - }; - "/v1/keys.setRoles": { - post: operations["setRoles"]; - }; - "/v1/apis.getApi": { - get: operations["getApi"]; - }; - "/v1/apis.createApi": { - post: operations["createApi"]; - }; - "/v1/apis.listKeys": { - get: operations["listKeys"]; - }; - "/v1/apis.deleteApi": { - post: operations["deleteApi"]; - }; - "/v1/apis.deleteKeys": { - post: operations["deleteKeys"]; - }; - "/v1/ratelimits.limit": { - post: operations["limit"]; - }; - "/v1/ratelimits.setOverride": { - post: operations["setOverride"]; - }; - "/v1/ratelimits.listOverrides": { - get: operations["listOverrides"]; - }; - "/v1/ratelimits.deleteOverride": { - post: operations["deleteOverride"]; - }; - "/v1/ratelimits.getOverride": { - get: operations["getOverride"]; - }; - "/v1/migrations.createKeys": { - post: operations["v1.migrations.createKeys"]; - }; - "/v1/migrations.enqueueKeys": { - post: operations["v1.migrations.enqueueKeys"]; - }; - "/v1/permissions.createPermission": { - post: operations["createPermission"]; - }; - "/v1/permissions.deletePermission": { - post: operations["deletePermission"]; - }; - "/v1/permissions.getPermission": { - get: operations["getPermission"]; - }; - "/v1/permissions.listPermissions": { - get: operations["listPermissions"]; - }; - "/v1/permissions.createRole": { - post: operations["createRole"]; - }; - "/v1/permissions.deleteRole": { - post: operations["deleteRole"]; - }; - "/v1/permissions.getRole": { - get: operations["getRole"]; - }; - "/v1/permissions.listRoles": { - get: operations["listRoles"]; - }; - "/v1/identities.createIdentity": { - post: operations["createIdentity"]; - }; - "/v1/identities.getIdentity": { - get: operations["getIdentity"]; - }; - "/v1/identities.listIdentities": { - get: operations["listIdentities"]; - }; - "/v1/identities.updateIdentity": { - post: operations["updateIdentity"]; - }; - "/v1/identities.deleteIdentity": { - post: operations["deleteIdentity"]; - }; - "/v1/analytics.getVerifications": { - get: operations["getVerifications"]; - }; - "/v1/keys": { - post: operations["deprecated.createKey"]; - }; - "/v1/keys/verify": { - /** @deprecated */ - post: operations["deprecated.verifyKey"]; - }; - "/v1/apis/{apiId}/keys": { - get: operations["deprecated.listKeys"]; - }; -} - -export type webhooks = Record; - -export interface components { - schemas: { - ErrBadRequest: { - error: { - /** - * @description A machine readable error code. - * @example BAD_REQUEST - * @enum {string} - */ - code: "BAD_REQUEST"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/BAD_REQUEST - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrUnauthorized: { - error: { - /** - * @description A machine readable error code. - * @example UNAUTHORIZED - * @enum {string} - */ - code: "UNAUTHORIZED"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/UNAUTHORIZED - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrForbidden: { - error: { - /** - * @description A machine readable error code. - * @example FORBIDDEN - * @enum {string} - */ - code: "FORBIDDEN"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/FORBIDDEN - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrNotFound: { - error: { - /** - * @description A machine readable error code. - * @example NOT_FOUND - * @enum {string} - */ - code: "NOT_FOUND"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/NOT_FOUND - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrConflict: { - error: { - /** - * @description A machine readable error code. - * @example CONFLICT - * @enum {string} - */ - code: "CONFLICT"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/CONFLICT - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrPreconditionFailed: { - error: { - /** - * @description A machine readable error code. - * @example PRECONDITION_FAILED - * @enum {string} - */ - code: "PRECONDITION_FAILED"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/PRECONDITION_FAILED - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrTooManyRequests: { - error: { - /** - * @description A machine readable error code. - * @example TOO_MANY_REQUESTS - * @enum {string} - */ - code: "TOO_MANY_REQUESTS"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/TOO_MANY_REQUESTS - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - ErrInternalServerError: { - error: { - /** - * @description A machine readable error code. - * @example INTERNAL_SERVER_ERROR - * @enum {string} - */ - code: "INTERNAL_SERVER_ERROR"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/INTERNAL_SERVER_ERROR - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - Key: { - /** - * @description The id of the key - * @example key_1234 - */ - id: string; - /** - * @description The first few characters of the key to visually identify it - * @example sk_5j1 - */ - start: string; - /** - * @description The id of the workspace that owns the key - * @example ws_1234 - */ - workspaceId: string; - /** - * @description The id of the api that this key is for - * @example api_1234 - */ - apiId?: string; - /** - * @description The name of the key, give keys a name to easily identify their purpose - * @example Customer X - */ - name?: string; - /** - * @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. - * @example user_123 - */ - ownerId?: string; - /** - * @description Any additional metadata you want to store with the key - * @example { - * "roles": [ - * "admin", - * "user" - * ], - * "stripeCustomerId": "cus_1234" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description The unix timestamp in milliseconds when the key was created - * @example 0 - */ - createdAt: number; - /** - * @description The unix timestamp in milliseconds when the key was last updated - * @example 0 - */ - updatedAt?: number; - /** - * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. - * @example 0 - */ - expires?: number; - /** - * @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. - * @example 1000 - */ - remaining?: number; - /** - * @description Unkey allows you to refill remaining verifications on a key on a regular interval. - * @example { - * "interval": "monthly", - * "amount": 10, - * "refillDay": 10 - * } - */ - refill?: { - /** - * @description Determines the rate at which verifications will be refilled. When 'daily' is set for 'interval' 'refillDay' will be set to null. - * @example daily - * @enum {string} - */ - interval: "daily" | "monthly"; - /** - * @description Resets `remaining` to this value every interval. - * @example 100 - */ - amount: number; - /** - * @description The day verifications will refill each month, when interval is set to 'monthly'. Value is not zero-indexed making 1 the first day of the month. If left blank it will default to the first day of the month. When 'daily' is set for 'interval' 'refillDay' will be set to null. - * @default 1 - * @example 15 - */ - refillDay?: number | null; - /** - * @description The unix timestamp in miliseconds when the key was last refilled. - * @example 100 - */ - lastRefillAt?: number; - }; - /** - * @description Unkey comes with per-key ratelimiting out of the box. - * @example { - * "async": true, - * "limit": 10, - * "duration": 60 - * } - */ - ratelimit?: { - async: boolean; - /** - * @description Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * @enum {string} - */ - type?: "fast" | "consistent"; - /** @description The total amount of burstable requests. */ - limit: number; - /** @description How many tokens to refill during each refillInterval. */ - refillRate?: number; - /** @description Determines the speed at which tokens are refilled, in milliseconds. */ - refillInterval?: number; - /** @description The duration of the ratelimit window, in milliseconds. */ - duration: number; - }; - /** - * @description All roles this key belongs to - * @example [ - * "admin", - * "finance" - * ] - */ - roles?: string[]; - /** - * @description All permissions this key has - * @example [ - * "domain.dns.create_record", - * "finance.read_receipt" - * ] - */ - permissions?: string[]; - /** - * @description Sets if key is enabled or disabled. Disabled keys are not valid. - * @example true - */ - enabled?: boolean; - /** @description The key in plaintext */ - plaintext?: string; - /** @description The identity of the key */ - identity?: { - /** @description The id of the identity */ - id: string; - /** @description The external id of the identity */ - externalId: string; - /** @description Any additional metadata attached to the identity */ - meta?: { - [key: string]: unknown; - }; - }; - }; - V1KeysVerifyKeyResponse: { - /** - * @description The id of the key - * @example key_1234 - */ - keyId?: string; - /** - * @description Whether the key is valid or not. - * A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. - * @example true - */ - valid: boolean; - /** - * @description The name of the key, give keys a name to easily identifiy their purpose - * @example Customer X - */ - name?: string; - /** - * @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. - * @example user_123 - */ - ownerId?: string; - /** - * @description Any additional metadata you want to store with the key - * @example { - * "roles": [ - * "admin", - * "user" - * ], - * "stripeCustomerId": "cus_1234" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. - * @example 123 - */ - expires?: number; - /** - * @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. - * @example { - * "limit": 10, - * "remaining": 9, - * "reset": 3600000 - * } - */ - ratelimit?: { - /** - * @description Maximum number of requests that can be made inside a window - * @example 10 - */ - limit: number; - /** - * @description Remaining requests after this verification - * @example 9 - */ - remaining: number; - /** - * @description Unix timestamp in milliseconds when the ratelimit will reset - * @example 3600000 - */ - reset: number; - }; - /** - * @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. - * @example 1000 - */ - remaining?: number; - /** - * @description A machine readable code why the key is not valid. - * Possible values are: - * - VALID: the key is valid and you should proceed - * - NOT_FOUND: the key does not exist or has expired - * - FORBIDDEN: the key is not allowed to access the api - * - USAGE_EXCEEDED: the key has exceeded its request limit - * - RATE_LIMITED: the key has been ratelimited - * - UNAUTHORIZED: the key is not authorized - * - DISABLED: the key is disabled - * - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action - * - EXPIRED: The key was only valid for a certain time and has expired. - * - * These are validation codes, the HTTP status will be 200. - * - * @enum {string} - */ - code: - | "VALID" - | "NOT_FOUND" - | "FORBIDDEN" - | "USAGE_EXCEEDED" - | "RATE_LIMITED" - | "UNAUTHORIZED" - | "DISABLED" - | "INSUFFICIENT_PERMISSIONS" - | "EXPIRED"; - /** @description Sets the key to be enabled or disabled. Disabled keys will not verify. */ - enabled?: boolean; - /** - * @description A list of all the permissions this key is connected to. - * @example [ - * "dns.record.update", - * "dns.record.delete" - * ] - */ - permissions?: string[]; - /** - * @description A list of all the roles this key is connected to. - * @example [ - * "admin" - * ] - */ - roles?: string[]; - /** - * @description The environment of the key, this is what what you set when you crated the key - * @example test - */ - environment?: string; - /** @description The associated identity of this key. */ - identity?: { - id: string; - externalId: string; - meta: { - [key: string]: unknown; - }; - }; - /** @description A unique id for this request, please provide it to Unkey support to help us debug your issue. */ - requestId: string; - }; - /** @description A query for which permissions you require */ - PermissionQuery: OneOf< - [ - string, - { - and: components["schemas"]["PermissionQuery"][]; - }, - { - or: components["schemas"]["PermissionQuery"][]; - }, - null, - ] - >; - V1KeysVerifyKeyRequest: { - /** - * @description The id of the api where the key belongs to. This is optional for now but will be required soon. - * The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. - * @example api_1234 - */ - apiId?: string; - /** - * @description The key to verify - * @example sk_1234 - */ - key: string; - /** - * @description Tags do not influence the outcome of a verification. - * They can be added to filter or aggregate historical verification data for your analytics needs. - * To unkey, a tag is simply a string, we don't enforce any schema but leave that up to you. - * The only exception is that each tag must be between 1 and 128 characters long. - * A typical setup would be to add key-value pairs of resources or locations, that you need later when querying. - * - * @example [ - * "path=/v1/users/123", - * "region=us-east-1" - * ] - */ - tags?: string[]; - /** @description Perform RBAC checks */ - authorization?: { - permissions?: components["schemas"]["PermissionQuery"]; - }; - /** @description Customize the behaviour of deducting remaining uses. When some of your endpoints are more expensive than others, you can set a custom `cost` for each. */ - remaining?: { - /** - * @description How many tokens should be deducted from the current `remaining` value. Set it to 0, to make it free. - * @default 1 - */ - cost?: number; - }; - /** - * @deprecated - * @description Use 'ratelimits' with `[{ name: "default", cost: 2}]` - */ - ratelimit?: { - /** - * @description Override how many tokens are deducted during the ratelimit operation. - * @default 1 - */ - cost?: number; - }; - /** - * @description You can check against multiple ratelimits when verifying a key. Let's say you are building an app that uses AI under the hood and you want to limit your customers to 500 requests per hour, but also ensure they use up less than 20k tokens per day. - * - * @example [ - * { - * "name": "requests", - * "limit": 500, - * "duration": 3600000 - * }, - * { - * "name": "tokens", - * "limit": 20000, - * "duration": 86400000 - * } - * ] - */ - ratelimits?: { - /** - * @description The name of the ratelimit. - * @example tokens - */ - name: string; - /** - * @description Optionally override how expensive this operation is and how many tokens are deducted from the current limit. - * @default 1 - */ - cost?: number; - /** @description Optionally override the limit. */ - limit?: number; - /** @description Optionally override the ratelimit window duration. */ - duration?: number; - }[]; - }; - ErrDeleteProtected: { - error: { - /** - * @description A machine readable error code. - * @example DELETE_PROTECTED - * @enum {string} - */ - code: "DELETE_PROTECTED"; - /** - * @description A link to our documentation with more details about this error code - * @example https://unkey.dev/docs/api-reference/errors/code/DELETE_PROTECTED - */ - docs: string; - /** @description A human readable explanation of what went wrong */ - message: string; - /** - * @description Please always include the requestId in your error report - * @example req_1234 - */ - requestId: string; - }; - }; - }; - responses: never; - parameters: {}; - requestBodies: never; - headers: never; - pathItems: never; -} - -export type $defs = Record; - -export type external = Record; - -export interface operations { - "v1.liveness": { - responses: { - /** @description The configured services and their status */ - 200: { - content: { - "application/json": { - /** @description The status of the server */ - status: string; - services: { - /** - * @description The name of the connected metrics service - * @example AxiomMetrics - */ - metrics: string; - /** - * @description The name of the connected logger service - * @example AxiomLogger or ConsoleLogger - */ - logger: string; - /** @description The name of the connected ratelimit service */ - ratelimit: string; - /** @description The name of the connected usagelimit service */ - usagelimit: string; - }; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getKey: { - parameters: { - query: { - keyId: string; - decrypt?: boolean | null; - }; - }; - responses: { - /** @description The configuration for a single key */ - 200: { - content: { - "application/json": components["schemas"]["Key"]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - whoami: { - requestBody: { - content: { - "application/json": { - /** - * @description The actual key to fetch - * @example sk_123 - */ - key: string; - }; - }; - }; - responses: { - /** @description The configuration for a single key */ - 200: { - content: { - "application/json": { - /** - * @description The ID of the key - * @example key_123 - */ - id: string; - /** - * @description The name of the key - * @example API Key 1 - */ - name?: string; - /** - * @description The remaining number of requests for the key - * @example 1000 - */ - remaining?: number; - /** @description The identity object associated with the key */ - identity?: { - /** - * @description The identity ID associated with the key - * @example id_123 - */ - id: string; - /** - * @description The external identity ID associated with the key - * @example ext123 - */ - externalId: string; - }; - /** - * @description Metadata associated with the key - * @example { - * "role": "admin", - * "plan": "premium" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description The timestamp in milliseconds when the key was created - * @example 1620000000000 - */ - createdAt: number; - /** - * @description Whether the key is enabled - * @example true - */ - enabled: boolean; - /** - * @description The environment the key is associated with - * @example production - */ - environment?: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteKey: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the key to revoke - * @example key_1234 - */ - keyId: string; - /** - * @description By default Unkey soft deletes keys, so they may be recovered later. If you want to permanently delete it, set permanent=true. This might be necessary if you run into CONFLICT errors during key migration. - * @default false - */ - permanent?: boolean; - }; - }; - }; - responses: { - /** @description The key was successfully revoked, it may take up to 30s for this to take effect in all regions */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - createKey: { - requestBody: { - content: { - "application/json": { - /** - * @description Choose an `API` where this key should be created. - * @example api_123 - */ - apiId: string; - /** - * @description To make it easier for your users to understand which product an api key belongs to, you can add prefix them. - * - * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. - * - * The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx - */ - prefix?: string; - /** - * @description The name for your Key. This is not customer facing. - * @example my key - */ - name?: string; - /** - * @description The byte length 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. The default is 16 bytes, or 2^^128 possible combinations. - * @default 16 - */ - byteLength?: number; - /** - * @deprecated - * @description Deprecated, use `externalId` - * @example team_123 - */ - ownerId?: string; - /** - * @description Your user's Id. This will provide a link between Unkey and your customer record. - * When validating a key, we will return this back to you, so you can clearly identify your user from their api key. - * @example team_123 - */ - externalId?: string; - /** - * @description This is a place for dynamic meta data, anything that feels useful for you should go here - * @example { - * "billingTier": "PRO", - * "trialEnds": "2023-06-16T17:16:37.161Z" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description A list of roles that this key should have. If the role does not exist, an error is thrown - * @example [ - * "admin", - * "finance" - * ] - */ - roles?: string[]; - /** - * @description A list of permissions that this key should have. If the permission does not exist, an error is thrown - * @example [ - * "domains.create_record", - * "say_hello" - * ] - */ - permissions?: string[]; - /** - * @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. - * @example 1623869797161 - */ - expires?: number; - /** - * @description You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. - * @example 1000 - */ - remaining?: number; - /** - * @description Unkey enables you to refill verifications for each key at regular intervals. - * @example { - * "interval": "monthly", - * "amount": 100, - * "refillDay": 15 - * } - */ - refill?: { - /** - * @description Unkey will automatically refill verifications at the set interval. - * @enum {string} - */ - interval: "daily" | "monthly"; - /** @description The number of verifications to refill for each occurrence is determined individually for each key. */ - amount: number; - /** - * @description The day of the month, when we will refill the remaining verifications. To refill on the 15th of each month, set 'refillDay': 15. - * If the day does not exist, for example you specified the 30th and it's february, we will refill them on the last day of the month instead. - */ - refillDay?: number; - }; - /** - * @description Unkey comes with per-key fixed-window ratelimiting out of the box. - * @example { - * "type": "fast", - * "limit": 10, - * "duration": 60000 - * } - */ - ratelimit?: { - /** - * @description Async will return a response immediately, lowering latency at the cost of accuracy. Will be required soon. - * @default true - */ - async?: boolean; - /** - * @deprecated - * @description Deprecated, use `async`. Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * @default fast - * @enum {string} - */ - type?: "fast" | "consistent"; - /** @description The total amount of requests in a given interval. */ - limit: number; - /** - * @description The window duration in milliseconds. Will be required soon. - * @example 60000 - */ - duration?: number; - /** - * @deprecated - * @description How many tokens to refill during each refillInterval. - */ - refillRate?: number; - /** - * @deprecated - * @description The refill timeframe, in milliseconds. - */ - refillInterval?: number; - }; - /** - * @description Sets if key is enabled or disabled. Disabled keys are not valid. - * @default true - * @example false - */ - enabled?: boolean; - /** - * @description You may want to show keys again later. While we do not recommend this, we leave this option open for you. - * - * 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. - * - * [https://www.unkey.com/docs/security/recovering-keys](https://www.unkey.com/docs/security/recovering-keys) for more information. - * @default false - */ - recoverable?: boolean; - /** - * @description Environments allow you to divide your keyspace. - * - * Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to - * give the developer a way to develop their own application without the risk of modifying real world - * resources. - * - * When you set an environment, we will return it back to you when validating the key, so you can - * handle it correctly. - */ - environment?: string; - }; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. - * @example key_123 - */ - keyId: string; - /** - * @description The newly created api key, do not store this on your own system but pass it along to your user. - * @example prefix_xxxxxxxxx - */ - key: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - verifyKey: { - requestBody: { - content: { - "application/json": components["schemas"]["V1KeysVerifyKeyRequest"]; - }; - }; - responses: { - /** @description The verification result */ - 200: { - content: { - "application/json": components["schemas"]["V1KeysVerifyKeyResponse"]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - updateKey: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the key you want to modify - * @example key_123 - */ - keyId: string; - /** - * @description The name of the key - * @example Customer X - */ - name?: string | null; - /** - * @deprecated - * @description Deprecated, use `externalId` - * The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. - * @example user_123 - */ - ownerId?: string | null; - /** - * @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this back to you, so you know who is accessing your API. - * Under the hood this upserts and connects an `ìdentity` for you. - * To disconnect the key from an identity, set `externalId: null`. - * @example user_123 - */ - externalId?: string | null; - /** - * @description Any additional metadata you want to store with the key - * @example { - * "roles": [ - * "admin", - * "user" - * ], - * "stripeCustomerId": "cus_1234" - * } - */ - meta?: { - [key: string]: unknown; - } | null; - /** - * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. - * @example 0 - */ - expires?: number | null; - /** - * @description Unkey comes with per-key ratelimiting out of the box. Set `null` to disable. - * @example { - * "type": "fast", - * "limit": 10, - * "refillRate": 1, - * "refillInterval": 60 - * } - */ - ratelimit?: { - /** - * @deprecated - * @description Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * Deprecated, use 'async' instead - * @enum {string} - */ - type?: "fast" | "consistent"; - /** - * @description Asnyc ratelimiting doesn't add latency, while sync ratelimiting is slightly more accurate. - * @default false - */ - async?: boolean; - /** @description The total amount of requests allowed in a single window. */ - limit: number; - /** - * @deprecated - * @description How many tokens to refill during each refillInterval. - * Deprecated, use 'limit' instead. - */ - refillRate?: number; - /** - * @deprecated - * @description Determines the speed at which tokens are refilled, in milliseconds. - * Deprecated, use 'duration' - */ - refillInterval?: number; - /** - * @description The duration of each ratelimit window, in milliseconds. - * This field will become required in a future version. - */ - duration?: number; - } | null; - /** - * @description The number of requests that can be made with this key before it becomes invalid. Set `null` to disable. - * @example 1000 - */ - remaining?: number | null; - /** - * @description Unkey enables you to refill verifications for each key at regular intervals. - * @example { - * "interval": "daily", - * "amount": 100 - * } - */ - refill?: { - /** - * @description Unkey will automatically refill verifications at the set interval. If null is used the refill functionality will be removed from the key. - * @enum {string} - */ - interval: "daily" | "monthly"; - /** @description The amount of verifications to refill for each occurrence is determined individually for each key. */ - amount: number; - /** @description The day verifications will refill each month, when interval is set to 'monthly' */ - refillDay?: number; - } | null; - /** - * @description Set if key is enabled or disabled. If disabled, the key cannot be used to verify. - * @example true - */ - enabled?: boolean; - /** - * @description The roles you want to set for this key. This overwrites all existing roles. - * Setting roles requires the `rbac.*.add_role_to_key` permission. - * @example [ - * { - * "id": "perm_123" - * }, - * { - * "name": "dns.record.create" - * }, - * { - * "name": "dns.record.delete", - * "create": true - * } - * ] - */ - roles?: { - /** @description The id of the role. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating roles requires your root key to have the `rbac.*.create_role` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - /** - * @description The permissions you want to set for this key. This overwrites all existing permissions. - * Setting permissions requires the `rbac.*.add_permission_to_key` permission. - * @example [ - * { - * "id": "perm_123" - * }, - * { - * "name": "dns.record.create" - * }, - * { - * "name": "dns.record.delete", - * "create": true - * } - * ] - */ - permissions?: { - /** @description The id of the permission. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the permission via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating permissions requires your root key to have the `rbac.*.create_permission` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - }; - }; - }; - responses: { - /** @description The key was successfully updated, it may take up to 30s for this to take effect in all regions */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - updateRemaining: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the key you want to modify - * @example key_123 - */ - keyId: string; - /** - * @description The operation you want to perform on the remaining count - * @enum {string} - */ - op: "increment" | "decrement" | "set"; - /** - * @description The value you want to set, add or subtract the remaining count by - * @example 1 - */ - value: number | null; - }; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The number of remaining requests for this key after updating it. `null` means unlimited. - * @example 100 - */ - remaining: number | null; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - "keys.getVerifications": { - parameters: { - query?: { - keyId?: string; - ownerId?: string; - start?: number | null; - end?: number | null; - granularity?: "day"; - }; - }; - responses: { - /** @description Usage numbers over time */ - 200: { - content: { - "application/json": { - verifications: { - /** - * @description The timestamp of the usage data - * @example 1620000000000 - */ - time: number; - /** - * @description The number of successful requests - * @example 100 - */ - success: number; - /** - * @description The number of requests that were rate limited - * @example 10 - */ - rateLimited: number; - /** - * @description The number of requests that exceeded the usage limit - * @example 0 - */ - usageExceeded: number; - }[]; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - addPermissions: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** @description The permissions you want to add to this key */ - permissions: { - /** @description The id of the permission. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the permission via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating permissions requires your root key to have the `rbac.*.create_permission` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - }; - }; - }; - responses: { - /** @description All currently connected permissions */ - 200: { - content: { - "application/json": { - /** - * @description The id of the permission. This is used internally - * @example perm_123 - */ - id: string; - /** - * @description The name of the permission - * @example dns.record.create - */ - name: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - removePermissions: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** - * @description The permissions you want to remove from this key. - * @example [ - * { - * "id": "perm_123" - * }, - * { - * "name": "dns.record.create" - * } - * ] - */ - permissions: { - /** @description The id of the permission. Provide either `id` or `slug`. If both are provided `id` is used. */ - id?: string; - /** - * @deprecated - * @description This field is deprecated and will be removed in a future release. please use `slug` instead. - */ - name?: string; - /** @description Identify the permission via its slug. Provide either `id` or `slug`. If both are provided `id` is used. */ - slug?: string; - }[]; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - setPermissions: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** - * @description The permissions you want to set for this key. This overwrites all existing permissions. - * Setting permissions requires the `rbac.*.add_permission_to_key` permission. - * @example [ - * { - * "id": "perm_123" - * }, - * { - * "name": "dns.record.create" - * }, - * { - * "name": "dns.record.delete", - * "create": true - * } - * ] - */ - permissions: { - /** @description The id of the permission. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** - * @deprecated - * @description This field is deprecated and will be removed in a future release. please use `slug` instead. - */ - name?: string; - /** @description Identify the permission via its slug. Provide either `id` or `slug`. If both are provided `id` is used. */ - slug?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating permissions requires your root key to have the `rbac.*.create_permission` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - }; - }; - }; - responses: { - /** @description All currently connected permissions */ - 200: { - content: { - "application/json": { - /** - * @description The id of the permission. This is used internally - * @example perm_123 - */ - id: string; - /** - * @description The name of the permission - * @example dns.record.create - */ - name: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - addRoles: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** - * @description The roles you want to set for this key. This overwrites all existing roles. - * Setting roles requires the `rbac.*.add_role_to_key` permission. - * @example [ - * { - * "id": "role_123" - * }, - * { - * "name": "dns.record.create" - * }, - * { - * "name": "dns.record.delete", - * "create": true - * } - * ] - */ - roles: { - /** @description The id of the role. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating roles requires your root key to have the `rbac.*.create_role` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - }; - }; - }; - responses: { - /** @description All currently connected roles */ - 200: { - content: { - "application/json": { - /** - * @description The id of the role. This is used internally - * @example role_123 - */ - id: string; - /** - * @description The name of the role - * @example dns.record.create - */ - name: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - removeRoles: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** - * @description The roles you want to remove from this key. - * @example [ - * { - * "id": "role_123" - * }, - * { - * "name": "dns.record.create" - * } - * ] - */ - roles: { - /** @description The id of the role. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - }[]; - }; - }; - }; - responses: { - /** @description Success */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - setRoles: { - requestBody: { - content: { - "application/json": { - /** @description The id of the key. */ - keyId: string; - /** - * @description The roles you want to set for this key. This overwrites all existing roles. - * Setting roles requires the `rbac.*.add_role_to_key` permission. - * @example [ - * { - * "id": "role_123" - * }, - * { - * "name": "dns.record.create" - * }, - * { - * "name": "dns.record.delete", - * "create": true - * } - * ] - */ - roles: { - /** @description The id of the role. Provide either `id` or `name`. If both are provided `id` is used. */ - id?: string; - /** @description Identify the role via its name. Provide either `id` or `name`. If both are provided `id` is used. */ - name?: string; - /** - * @description Set to true to automatically create the permissions they do not exist yet. Only works when specifying `name`. - * Autocreating roles requires your root key to have the `rbac.*.create_role` permission, otherwise the request will get rejected - */ - create?: boolean; - }[]; - }; - }; - }; - responses: { - /** @description All currently connected roles */ - 200: { - content: { - "application/json": { - /** - * @description The id of the role. This is used internally - * @example role_123 - */ - id: string; - /** - * @description The name of the role - * @example dns.record.create - */ - name: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getApi: { - parameters: { - query: { - apiId: string; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The id of the key - * @example key_1234 - */ - id: string; - /** - * @description The id of the workspace that owns the api - * @example ws_1234 - */ - workspaceId: string; - /** - * @description The name of the api. This is internal and your users will not see this. - * @example Unkey - Production - */ - name?: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - createApi: { - requestBody: { - content: { - "application/json": { - /** - * @description The name for your API. This is not customer facing. - * @example my-api - */ - name: string; - }; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The id of the api - * @example api_134 - */ - apiId: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - listKeys: { - parameters: { - query: { - apiId: string; - limit?: number; - cursor?: string; - ownerId?: string; - externalId?: string; - decrypt?: boolean | null; - revalidateKeysCache?: boolean | null; - }; - }; - responses: { - /** @description List of keys for the api */ - 200: { - content: { - "application/json": { - keys: components["schemas"]["Key"][]; - /** - * @description The cursor to use for the next page of results, if no cursor is returned, there are no more results - * @example eyJrZXkiOiJrZXlfMTIzNCJ9 - */ - cursor?: string; - /** @description The total number of keys for this api. This is an approximation and may lag behind up to 5 minutes. */ - total: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteApi: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the api to delete - * @example api_1234 - */ - apiId: string; - }; - }; - }; - responses: { - /** @description The api was successfully deleted, it may take up to 30s for this to take effect in all regions */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The api is protected from deletions */ - 429: { - content: { - "application/json": components["schemas"]["ErrDeleteProtected"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteKeys: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the api, that the keys belong to. - * @example api_1234 - */ - apiId: string; - /** - * @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. - * @default false - */ - permanent?: boolean; - }; - }; - }; - responses: { - /** @description The keys have been deleted */ - 200: { - content: { - "application/json": { - /** @description The number of keys that were deleted */ - deletedKeys: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - limit: { - requestBody: { - content: { - "application/json": { - /** - * @description Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes. - * @default default - * @example email.outbound - */ - namespace?: string; - /** - * @description Identifier of your user, this can be their userId, an email, an ip or anything else. - * @example user_123 - */ - identifier: string; - /** - * @description How many requests may pass in a given window. - * @example 10 - */ - limit: number; - /** - * @description The window duration in milliseconds - * @example 60000 - */ - duration: number; - /** - * @description Expensive requests may use up more tokens. You can specify a cost to the request here and we'll deduct this many tokens in the current window. - * If there are not enough tokens left, the request is denied. - * - * Set it to 0 to receive the current limit without changing anything. - * @default 1 - * @example 2 - */ - cost?: number; - /** - * @description Async will return a response immediately, lowering latency at the cost of accuracy. - * @default false - */ - async?: boolean; - /** @description Attach any metadata to this request */ - meta?: { - [key: string]: unknown; - }; - /** - * @description Resources that are about to be accessed by the user - * @example [ - * { - * "type": "project", - * "id": "p_123", - * "name": "dub" - * } - * ] - */ - resources?: { - /** - * @description The type of resource - * @example organization - */ - type: string; - /** - * @description The unique identifier for the resource - * @example org_123 - */ - id: string; - /** - * @description A human readable name for this resource - * @example unkey - */ - name?: string; - /** @description Attach any metadata to this resources */ - meta?: { - [key: string]: unknown; - }; - }[]; - }; - }; - }; - responses: { - 200: { - content: { - "application/json": { - /** - * @description Returns true if the request should be processed, false if it was rejected. - * @example true - */ - success: boolean; - /** - * @description How many requests are allowed within a window. - * @example 10 - */ - limit: number; - /** - * @description How many requests can still be made in the current window. - * @example 9 - */ - remaining: number; - /** - * @description A unix millisecond timestamp when the limits reset. - * @example 1709804263654 - */ - reset: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - setOverride: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the namespace. Either namespaceId or namespaceName must be provided - * @example rlns_1234 - */ - namespaceId?: string; - /** - * @description Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes. Wildcards can also be used, more info can be found at https://www.unkey.com/docs/ratelimiting/overrides#wildcard-rules - * @example email.outbound - */ - namespaceName?: string; - /** - * @description Identifier of your user, this can be their userId, an email, an ip or anything else. Wildcards ( * ) can be used to match multiple identifiers, More info can be found at https://www.unkey.com/docs/ratelimiting/overrides#wildcard-rules - * @example user_123 - */ - identifier: string; - /** - * @description How many requests may pass in a given window. - * @example 10 - */ - limit: number; - /** - * @description The window duration in milliseconds - * @example 60000 - */ - duration: number; - /** - * @description Async will return a response immediately, lowering latency at the cost of accuracy. - * @default false - */ - async?: boolean; - }; - }; - }; - responses: { - /** @description Sucessfully created a ratelimit override */ - 200: { - content: { - "application/json": { - /** - * @description The id of the override. This is used internally - * @example over_123 - */ - overrideId: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - listOverrides: { - parameters: { - query?: { - namespaceId?: string; - namespaceName?: string; - limit?: number; - cursor?: string; - }; - }; - responses: { - /** @description List of overrides for the given namespace. */ - 200: { - content: { - "application/json": { - overrides: { - id: string; - identifier: string; - limit: number; - duration: number; - async?: boolean | null; - }[]; - /** - * @description The cursor to use for the next page of results, if no cursor is returned, there are no more results - * @example eyJrZXkiOiJrZXlfMTIzNCJ9 - */ - cursor?: string; - /** @description The total number of overrides for the namespace */ - total: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteOverride: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the namespace. Either namespaceId or namespaceName must be provided - * @example rlns_1234 - */ - namespaceId?: string; - /** - * @description The name of the namespace. Namespaces group different limits together for better analytics. You might have a namespace for your public API and one for internal tRPC routes. - * @example email.outbound - */ - namespaceName?: string; - /** - * @description Identifier of your user, this can be their userId, an email, an ip or anything else. Wildcards ( * ) can be used to match multiple identifiers, More info can be found at https://www.unkey.com/docs/ratelimiting/overrides#wildcard-rules - * @example user_123 - */ - identifier: string; - }; - }; - }; - responses: { - /** @description Successfully deleted a ratelimit override */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getOverride: { - parameters: { - query: { - namespaceId?: string; - namespaceName?: string; - identifier: string; - }; - }; - responses: { - /** @description Details of the override for the given identifier */ - 200: { - content: { - "application/json": { - id: string; - identifier: string; - limit: number; - duration: number; - async?: boolean | null; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - "v1.migrations.createKeys": { - requestBody: { - content: { - "application/json": { - /** - * @description Choose an `API` where this key should be created. - * @example api_123 - */ - apiId: string; - /** - * @description To make it easier for your users to understand which product an api key belongs to, you can add prefix them. - * - * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. - * - * The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx - */ - prefix?: string; - /** - * @description The name for your Key. This is not customer facing. - * @example my key - */ - name?: string; - /** @description The raw key in plaintext. If provided, unkey encrypts this value and stores it securely. Provide either `hash` or `plaintext` */ - plaintext?: string; - /** @description Provide either `hash` or `plaintext` */ - hash?: { - /** @description The hashed and encoded key */ - value: string; - /** - * @description The algorithm for hashing and encoding, currently only sha256 and base64 are supported - * @enum {string} - */ - variant: "sha256_base64"; - }; - /** - * @description The first 4 characters of the key. If a prefix is used, it should be the prefix plus 4 characters. - * @example unkey_32kq - */ - start?: string; - /** - * @deprecated - * @description Deprecated, use `externalId` - * @example team_123 - */ - ownerId?: string; - /** - * @description Your user’s Id. This will provide a link between Unkey and your customer record. - * When validating a key, we will return this back to you, so you can clearly identify your user from their api key. - * @example user_123 - */ - externalId?: string; - /** - * @description This is a place for dynamic meta data, anything that feels useful for you should go here - * @example { - * "billingTier": "PRO", - * "trialEnds": "2023-06-16T17:16:37.161Z" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description A list of roles that this key should have. If the role does not exist, an error is thrown - * @example [ - * "admin", - * "finance" - * ] - */ - roles?: string[]; - /** - * @description A list of permissions that this key should have. If the permission does not exist, an error is thrown - * @example [ - * "domains.create_record", - * "say_hello" - * ] - */ - permissions?: string[]; - /** - * @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. - * @example 1623869797161 - */ - expires?: number; - /** - * @description You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. - * @example 1000 - */ - remaining?: number; - /** - * @description Unkey enables you to refill verifications for each key at regular intervals. - * @example { - * "interval": "daily", - * "amount": 100 - * } - */ - refill?: { - /** - * @description Unkey will automatically refill verifications at the set interval. - * @enum {string} - */ - interval: "daily" | "monthly"; - /** @description The number of verifications to refill for each occurrence is determined individually for each key. */ - amount: number; - /** @description The day verifications will refill each month, when interval is set to 'monthly' */ - refillDay?: number; - }; - /** - * @description Unkey comes with per-key ratelimiting out of the box. - * @example { - * "type": "fast", - * "limit": 10, - * "refillRate": 1, - * "refillInterval": 60 - * } - */ - ratelimit?: { - /** - * @description Async will return a response immediately, lowering latency at the cost of accuracy. - * @default false - */ - async?: boolean; - /** - * @deprecated - * @description Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * @default fast - * @enum {string} - */ - type?: "fast" | "consistent"; - /** @description The total amount of burstable requests. */ - limit: number; - /** - * @deprecated - * @description How many tokens to refill during each refillInterval. - */ - refillRate: number; - /** - * @deprecated - * @description Determines the speed at which tokens are refilled, in milliseconds. - */ - refillInterval: number; - }; - /** - * @description Sets if key is enabled or disabled. Disabled keys are not valid. - * @default true - * @example false - */ - enabled?: boolean; - /** - * @description Environments allow you to divide your keyspace. - * - * Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to - * give the developer a way to develop their own application without the risk of modifying real world - * resources. - * - * When you set an environment, we will return it back to you when validating the key, so you can - * handle it correctly. - */ - environment?: string; - }[]; - }; - }; - responses: { - /** @description The key ids of all created keys */ - 200: { - content: { - "application/json": { - /** - * @description The ids of the keys. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. - * @example [ - * "key_123", - * "key_456" - * ] - */ - keyIds: string[]; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - "v1.migrations.enqueueKeys": { - requestBody: { - content: { - "application/json": { - /** @description Contact support@unkey.dev to receive your migration id. */ - migrationId: string; - /** @description The id of the api, you want to migrate keys to */ - apiId: string; - keys: { - /** - * @description To make it easier for your users to understand which product an api key belongs to, you can add prefix them. - * - * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. - * - * The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx - */ - prefix?: string; - /** - * @description The name for your Key. This is not customer facing. - * @example my key - */ - name?: string; - /** @description The raw key in plaintext. If provided, unkey encrypts this value and stores it securely. Provide either `hash` or `plaintext` */ - plaintext?: string; - /** @description Provide either `hash` or `plaintext` */ - hash?: { - /** @description The hashed and encoded key */ - value: string; - /** - * @description The algorithm for hashing and encoding, currently only sha256 and base64 are supported - * @enum {string} - */ - variant: "sha256_base64"; - }; - /** - * @description The first 4 characters of the key. If a prefix is used, it should be the prefix plus 4 characters. - * @example unkey_32kq - */ - start?: string; - /** - * @description Your user’s Id. This will provide a link between Unkey and your customer record. - * When validating a key, we will return this back to you, so you can clearly identify your user from their api key. - * @example team_123 - */ - ownerId?: string; - /** - * @description This is a place for dynamic meta data, anything that feels useful for you should go here - * @example { - * "billingTier": "PRO", - * "trialEnds": "2023-06-16T17:16:37.161Z" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description A list of roles that this key should have. If the role does not exist, an error is thrown - * @example [ - * "admin", - * "finance" - * ] - */ - roles?: string[]; - /** - * @description A list of permissions that this key should have. If the permission does not exist, an error is thrown - * @example [ - * "domains.create_record", - * "say_hello" - * ] - */ - permissions?: string[]; - /** - * @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. - * @example 1623869797161 - */ - expires?: number; - /** - * @description You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. - * @example 1000 - */ - remaining?: number; - /** - * @description Unkey enables you to refill verifications for each key at regular intervals. - * @example { - * "interval": "daily", - * "amount": 100 - * } - */ - refill?: { - /** - * @description Unkey will automatically refill verifications at the set interval. - * @enum {string} - */ - interval: "daily" | "monthly"; - /** @description The number of verifications to refill for each occurrence is determined individually for each key. */ - amount: number; - /** @description The day verifications will refill each month, when interval is set to 'monthly' */ - refillDay?: number; - }; - /** - * @description Unkey comes with per-key fixed-window ratelimiting out of the box. - * @example { - * "type": "fast", - * "limit": 10, - * "duration": 60000 - * } - */ - ratelimit?: { - /** - * @description Async will return a response immediately, lowering latency at the cost of accuracy. - * @default true - */ - async?: boolean; - /** - * @deprecated - * @description Deprecated, use `async`. Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * @default fast - * @enum {string} - */ - type?: "fast" | "consistent"; - /** @description The total amount of requests in a given interval. */ - limit: number; - /** - * @description The window duration in milliseconds - * @example 60000 - */ - duration: number; - /** - * @deprecated - * @description How many tokens to refill during each refillInterval. - */ - refillRate?: number; - /** - * @deprecated - * @description The refill timeframe, in milliseconds. - */ - refillInterval?: number; - }; - /** - * @description Sets if key is enabled or disabled. Disabled keys are not valid. - * @default true - * @example false - */ - enabled?: boolean; - /** - * @description Environments allow you to divide your keyspace. - * - * Some applications like Stripe, Clerk, WorkOS and others have a concept of "live" and "test" keys to - * give the developer a way to develop their own application without the risk of modifying real world - * resources. - * - * When you set an environment, we will return it back to you when validating the key, so you can - * handle it correctly. - */ - environment?: string; - }[]; - }; - }; - }; - responses: { - /** @description The key ids of all created keys */ - 202: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - createPermission: { - requestBody: { - content: { - "application/json": { - /** - * @description The unique name of your permission. - * @example Can write records - */ - name: string; - /** - * @description The unique slug of your permission. If not provided, the name is used. - * @example record.write - */ - slug?: string; - /** - * @description Explain what this permission does. This is just for your team, your users will not see this. - * @example record.write can create new dns records for our domains. - */ - description?: string | ""; - }; - }; - }; - responses: { - /** @description Sucessfully created a permission */ - 200: { - content: { - "application/json": { - /** - * @description The id of the permission. This is used internally - * @example perm_123 - */ - permissionId: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deletePermission: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the permission you want to delete. - * @example perm_123 - */ - permissionId: string; - }; - }; - }; - responses: { - /** @description Sucessfully deleted a permission */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getPermission: { - parameters: { - query: { - permissionId: string; - }; - }; - responses: { - /** @description The Role */ - 200: { - content: { - "application/json": { - /** - * @description The id of the permission - * @example perm_123 - */ - id: string; - /** - * @description The name of the permission. - * @example domain.record.manager - */ - name: string; - /** - * @description The slug of the permission - * @example domain-record-manager - */ - slug: string; - /** - * @description The description of what this permission does. This is just for your team, your users will not see this. - * @example Can manage dns records - */ - description?: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - listPermissions: { - responses: { - /** @description The permissions in your workspace */ - 200: { - content: { - "application/json": { - /** - * @description The id of the permission - * @example perm_123 - */ - id: string; - /** - * @description The name of the permission. - * @example domain.record.manager - */ - name: string; - /** - * @description The slug of the permission - * @example domain-record-manager - */ - slug: string; - /** - * @description The description of what this permission does. This is just for your team, your users will not see this. - * @example Can manage dns records - */ - description?: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - createRole: { - requestBody: { - content: { - "application/json": { - /** - * @description The unique name of your role. - * @example dns.records.manager - */ - name: string; - /** - * @description Explain what this role does. This is just for your team, your users will not see this. - * @example dns.records.manager can read and write dns records for our domains. - */ - description?: string | ""; - }; - }; - }; - responses: { - /** @description Sucessfully created a role */ - 200: { - content: { - "application/json": { - /** - * @description The id of the role. This is used internally - * @example role_123 - */ - roleId: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteRole: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the role you want to delete. - * @example role_123 - */ - roleId: string; - }; - }; - }; - responses: { - /** @description Sucessfully deleted a role */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getRole: { - parameters: { - query: { - roleId: string; - }; - }; - responses: { - /** @description The Role */ - 200: { - content: { - "application/json": { - /** - * @description The id of the role - * @example role_1234 - */ - id: string; - /** - * @description The name of the role. - * @example domain.record.manager - */ - name: string; - /** - * @description The description of what this role does. This is just for your team, your users will not see this. - * @example Can manage dns records - */ - description?: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - listRoles: { - responses: { - /** @description The Roles in your workspace */ - 200: { - content: { - "application/json": { - /** - * @description The id of the role - * @example role_1234 - */ - id: string; - /** - * @description The name of the role. - * @example domain.record.manager - */ - name: string; - /** - * @description The description of what this role does. This is just for your team, your users will not see this. - * @example Can manage dns records - */ - description?: string; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - createIdentity: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of this identity in your system. - * - * This usually comes from your authentication provider and could be a userId, organisationId or even an email. - * It does not matter what you use, as long as it uniquely identifies something in your application. - * - * `externalId`s are unique across your workspace and therefore a `CONFLICT` error is returned when you try to create duplicates. - * - * @example user_123 - */ - externalId: string; - /** - * @description Attach metadata to this identity that you need to have access to when verifying a key. - * - * This will be returned as part of the `verifyKey` response. - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description Attach ratelimits to this identity. - * - * When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits. - */ - ratelimits?: { - /** - * @description The name of this limit. You will need to use this again when verifying a key. - * @example tokens - */ - name: string; - /** - * @description How many requests may pass within a given window before requests are rejected. - * @example 10 - */ - limit: number; - /** - * @description The duration for each ratelimit window in milliseconds. - * @example 1000 - */ - duration: number; - }[]; - }; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The id of the identity. Used internally, you do not need to store this. - * @example id_123 - */ - identityId: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getIdentity: { - parameters: { - query?: { - identityId?: string; - externalId?: string; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** @description The id of this identity. Used to interact with unkey's API */ - id: string; - /** @description The id in your system */ - externalId: string; - /** @description The meta object defined for this identity. */ - meta: { - [key: string]: unknown; - }; - /** @description When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits. */ - ratelimits: { - /** - * @description The name of this limit. You will need to use this again when verifying a key. - * @example tokens - */ - name: string; - /** - * @description How many requests may pass within a given window before requests are rejected. - * @example 10 - */ - limit: number; - /** - * @description The duration for each ratelimit window in milliseconds. - * @example 1000 - */ - duration: number; - }[]; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - listIdentities: { - parameters: { - query?: { - environment?: string; - limit?: number; - cursor?: string; - }; - }; - responses: { - /** @description A list of identities. */ - 200: { - content: { - "application/json": { - /** @description A list of identities. */ - identities: { - /** @description The id of this identity. Used to interact with unkey's API */ - id: string; - /** @description The id in your system */ - externalId: string; - /** @description When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits. */ - ratelimits: { - /** - * @description The name of this limit. You will need to use this again when verifying a key. - * @example tokens - */ - name: string; - /** - * @description How many requests may pass within a given window before requests are rejected. - * @example 10 - */ - limit: number; - /** - * @description The duration for each ratelimit window in milliseconds. - * @example 1000 - */ - duration: number; - }[]; - }[]; - /** - * @description The cursor to use for the next page of results, if no cursor is returned, there are no more results - * @example eyJrZXkiOiJrZXlfMTIzNCJ9 - */ - cursor?: string; - /** @description The total number of identities for this environment */ - total: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - updateIdentity: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the identity to update, use either `identityId` or `externalId`, if both are provided, `identityId` takes precedence. - * @example id_1234 - */ - identityId?: string; - /** - * @description The externalId of the identity to update, use either `identityId` or `externalId`, if both are provided, `identityId` takes precedence. - * @example user_1234 - */ - externalId?: string; - /** - * @description This is not yet used but here for future compatibility. - * @default default - */ - environment?: string; - /** - * @description Attach metadata to this identity that you need to have access to when verifying a key. - * - * Set to `{}` to clear. - * - * This will be returned as part of the `verifyKey` response. - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description Attach ratelimits to this identity. - * - * This overwrites all existing ratelimits on this identity. - * Setting an empty array will delete all existing ratelimits. - * - * When verifying keys, you can specify which limits you want to use and all keys attached to this identity, will share the limits. - */ - ratelimits?: { - /** - * @description The name of this limit. You will need to use this again when verifying a key. - * @example tokens - */ - name: string; - /** - * @description How many requests may pass within a given window before requests are rejected. - * @example 10 - */ - limit: number; - /** - * @description The duration for each ratelimit window in milliseconds. - * @example 1000 - */ - duration: number; - }[]; - }; - }; - }; - responses: { - /** @description The identity after the update. */ - 200: { - content: { - "application/json": { - /** - * @description The id of the identity. - * @example id_1234 - */ - id: string; - /** - * @description The externalId of the identity. - * @example user_1234 - */ - externalId: string; - /** - * @description The metadata attached to this identity. - * @example { - * "stripeSubscriptionId": "sub_1234" - * } - */ - meta: { - [key: string]: unknown; - }; - ratelimits: { - /** - * @description The name of this limit. - * @example tokens - */ - name: string; - /** - * @description How many requests may pass within a given window before requests are rejected. - * @example 10 - */ - limit: number; - /** - * @description The duration for each ratelimit window in milliseconds. - * @example 1000 - */ - duration: number; - }[]; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - deleteIdentity: { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the identity to delete - * @example id_1234 - */ - identityId: string; - }; - }; - }; - responses: { - /** @description The identity was successfully deleted, it may take up to 30s for this to take effect in all regions */ - 200: { - content: { - "application/json": Record; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - getVerifications: { - parameters: { - query: { - apiId: string; - externalId?: string; - keyId?: string | string[]; - tag?: string | string[]; - start?: number | null; - end?: number | null; - groupBy?: - | ("key" | "identity" | "tags" | "tag" | "month" | "day" | "hour") - | ("key" | "identity" | "tags" | "tag" | "month" | "day" | "hour")[]; - limit?: number; - orderBy?: - | "time" - | "valid" - | "notFound" - | "forbidden" - | "usageExceeded" - | "rateLimited" - | "unauthorized" - | "disabled" - | "insufficientPermissions" - | "expired" - | "total"; - order?: "asc" | "desc"; - }; - }; - responses: { - /** @description Retrieve all required data to build end-user facing dashboards and drive your usage-based billing. */ - 200: { - content: { - "application/json": { - /** @description Unix timestamp in milliseconds of the start of the current time slice. */ - time?: number; - valid?: number; - notFound?: number; - forbidden?: number; - usageExceeded?: number; - rateLimited?: number; - unauthorized?: number; - disabled?: number; - insufficientPermissions?: number; - expired?: number; - /** @description Total number of verifications in the current time slice, regardless of outcome. */ - total: number; - /** @description Only available when grouping by tag. */ - tag?: string; - /** @description Filter by one or multiple tags. If multiple tags are provided */ - tags?: string[]; - /** - * @description Only available when specifying groupBy=key in the query. - * In this case there would be one datapoint per time and groupBy target. - */ - keyId?: string; - /** - * @description Only available when specifying groupBy=identity in the query. - * In this case there would be one datapoint per time and groupBy target. - */ - identity?: { - id: string; - externalId: string; - }; - }[]; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - "deprecated.createKey": { - requestBody: { - content: { - "application/json": { - /** - * @description Choose an `API` where this key should be created. - * @example api_123 - */ - apiId: string; - /** - * @description To make it easier for your users to understand which product an api key belongs to, you can add prefix them. - * - * For example Stripe famously prefixes their customer ids with cus_ or their api keys with sk_live_. - * - * The underscore is automatically added if you are defining a prefix, for example: "prefix": "abc" will result in a key like abc_xxxxxxxxx - */ - prefix?: string; - /** - * @description The name for your Key. This is not customer facing. - * @example my key - */ - name?: string; - /** - * @description The byte length 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. The default is 16 bytes, or 2^^128 possible combinations. - * @default 16 - */ - byteLength?: number; - /** - * @description Your user’s Id. This will provide a link between Unkey and your customer record. - * When validating a key, we will return this back to you, so you can clearly identify your user from their api key. - * @example team_123 - */ - ownerId?: string; - /** - * @description This is a place for dynamic meta data, anything that feels useful for you should go here - * @example { - * "billingTier": "PRO", - * "trialEnds": "2023-06-16T17:16:37.161Z" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description You can auto expire keys by providing a unix timestamp in milliseconds. Once Keys expire they will automatically be disabled and are no longer valid unless you enable them again. - * @example 1623869797161 - */ - expires?: number; - /** - * @description You can limit the number of requests a key can make. Once a key reaches 0 remaining requests, it will automatically be disabled and is no longer valid unless you update it. - * @example 1000 - */ - remaining?: number; - /** - * @description Unkey comes with per-key ratelimiting out of the box. - * @example { - * "type": "fast", - * "limit": 10, - * "refillRate": 1, - * "refillInterval": 60 - * } - */ - ratelimit?: { - /** - * @description Fast ratelimiting doesn't add latency, while consistent ratelimiting is more accurate. - * @default fast - * @enum {string} - */ - type?: "fast" | "consistent"; - /** @description The total amount of burstable requests. */ - limit: number; - /** @description How many tokens to refill during each refillInterval. */ - refillRate: number; - /** @description Determines the speed at which tokens are refilled, in milliseconds. */ - refillInterval: number; - }; - }; - }; - }; - responses: { - /** @description The configuration for an api */ - 200: { - content: { - "application/json": { - /** - * @description The id of the key. This is not a secret and can be stored as a reference if you wish. You need the keyId to update or delete a key later. - * @example key_123 - */ - keyId: string; - /** - * @description The newly created api key, do not store this on your own system but pass it along to your user. - * @example prefix_xxxxxxxxx - */ - key: string; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - /** @deprecated */ - "deprecated.verifyKey": { - requestBody: { - content: { - "application/json": { - /** - * @description The id of the api where the key belongs to. This is optional for now but will be required soon. - * The key will be verified against the api's configuration. If the key does not belong to the api, the verification will fail. - * @example api_1234 - */ - apiId?: string; - /** - * @description The key to verify - * @example sk_1234 - */ - key: string; - }; - }; - }; - responses: { - /** @description The verification result */ - 200: { - content: { - "application/json": { - /** - * @description The id of the key - * @example key_1234 - */ - keyId?: string; - /** - * @description Whether the key is valid or not. - * A key could be invalid for a number of reasons, for example if it has expired, has no more verifications left or if it has been deleted. - * @example true - */ - valid: boolean; - /** - * @description The name of the key, give keys a name to easily identify their purpose - * @example Customer X - */ - name?: string; - /** - * @description The id of the tenant associated with this key. Use whatever reference you have in your system to identify the tenant. When verifying the key, we will send this field back to you, so you know who is accessing your API. - * @example user_123 - */ - ownerId?: string; - /** - * @description Any additional metadata you want to store with the key - * @example { - * "roles": [ - * "admin", - * "user" - * ], - * "stripeCustomerId": "cus_1234" - * } - */ - meta?: { - [key: string]: unknown; - }; - /** - * @description The unix timestamp in milliseconds when the key was created - * @example 0 - */ - createdAt?: number; - /** - * @description The unix timestamp in milliseconds when the key will expire. If this field is null or undefined, the key is not expiring. - * @example 123 - */ - expires?: number; - /** - * @description The ratelimit configuration for this key. If this field is null or undefined, the key has no ratelimit. - * @example { - * "limit": 10, - * "remaining": 9, - * "reset": 3600000 - * } - */ - ratelimit?: { - /** - * @description Maximum number of requests that can be made inside a window - * @example 10 - */ - limit: number; - /** - * @description Remaining requests after this verification - * @example 9 - */ - remaining: number; - /** - * @description Unix timestamp in milliseconds when the ratelimit will reset - * @example 3600000 - */ - reset: number; - }; - /** - * @description The number of requests that can be made with this key before it becomes invalid. If this field is null or undefined, the key has no request limit. - * @example 1000 - */ - remaining?: number; - /** - * @description If the key is invalid this field will be set to the reason why it is invalid. - * Possible values are: - * - NOT_FOUND: the key does not exist or has expired - * - FORBIDDEN: the key is not allowed to access the api - * - USAGE_EXCEEDED: the key has exceeded its request limit - * - RATE_LIMITED: the key has been ratelimited, - * - INSUFFICIENT_PERMISSIONS: you do not have the required permissions to perform this action - * - * @example NOT_FOUND - * @enum {string} - */ - code?: - | "NOT_FOUND" - | "FORBIDDEN" - | "USAGE_EXCEEDED" - | "RATE_LIMITED" - | "UNAUTHORIZED" - | "DISABLED" - | "INSUFFICIENT_PERMISSIONS" - | "EXPIRED"; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; - "deprecated.listKeys": { - parameters: { - query?: { - limit?: number; - offset?: number | null; - ownerId?: string; - }; - path: { - apiId: string; - }; - }; - responses: { - /** @description Keys belonging to the api */ - 200: { - content: { - "application/json": { - keys: components["schemas"]["Key"][]; - /** @description The total number of keys for this api */ - total: number; - }; - }; - }; - /** @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). */ - 400: { - content: { - "application/json": components["schemas"]["ErrBadRequest"]; - }; - }; - /** @description Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. */ - 401: { - content: { - "application/json": components["schemas"]["ErrUnauthorized"]; - }; - }; - /** @description The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401 Unauthorized, the client's identity is known to the server. */ - 403: { - content: { - "application/json": components["schemas"]["ErrForbidden"]; - }; - }; - /** @description The server cannot find the requested resource. In the browser, this means the URL is not recognized. In an API, this can also mean that the endpoint is valid but the resource itself does not exist. Servers may also send this response instead of 403 Forbidden to hide the existence of a resource from an unauthorized client. This response code is probably the most well known due to its frequent occurrence on the web. */ - 404: { - content: { - "application/json": components["schemas"]["ErrNotFound"]; - }; - }; - /** @description This response is sent when a request conflicts with the current state of the server. */ - 409: { - content: { - "application/json": components["schemas"]["ErrConflict"]; - }; - }; - /** @description The requested operation cannot be completed because certain conditions were not met. This typically occurs when a required resource state or version check fails. */ - 412: { - content: { - "application/json": components["schemas"]["ErrPreconditionFailed"]; - }; - }; - /** @description The user has sent too many requests in a given amount of time ("rate limiting") */ - 429: { - content: { - "application/json": components["schemas"]["ErrTooManyRequests"]; - }; - }; - /** @description The server has encountered a situation it does not know how to handle. */ - 500: { - content: { - "application/json": components["schemas"]["ErrInternalServerError"]; - }; - }; - }; - }; -} diff --git a/packages/api/src/telemetry.ts b/packages/api/src/telemetry.ts deleted file mode 100644 index cdeb8f2dca..0000000000 --- a/packages/api/src/telemetry.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { version } from "../package.json"; -import type { UnkeyOptions } from "./client"; - -export type Telemetry = { - /** - * Unkey-Telemetry-Sdk - * @example @unkey/api@v1.1.1 - */ - sdkVersions: string[]; - /** - * Unkey-Telemetry-Platform - * @example cloudflare - */ - platform?: string; - /** - * Unkey-Telemetry-Runtime - * @example node@v18 - */ - runtime?: string; -}; - -export function getTelemetry(opts: UnkeyOptions): Telemetry | null { - let platform: string | undefined; - let runtime: string | undefined; - const sdkVersions = [`@unkey/api@${version}`]; - - try { - if (typeof process !== "undefined") { - if (process.env.UNKEY_DISABLE_TELEMETRY) { - return null; - } - platform = process.env.VERCEL ? "vercel" : process.env.AWS_REGION ? "aws" : undefined; - - // @ts-ignore - if (typeof EdgeRuntime !== "undefined") { - runtime = "edge-light"; - } else { - runtime = `node@${process.version}`; - } - } - - if (opts.wrapperSdkVersion) { - sdkVersions.push(opts.wrapperSdkVersion); - } - } catch (_error) {} - - return { platform, runtime, sdkVersions }; -} diff --git a/packages/api/src/verify.ts b/packages/api/src/verify.ts deleted file mode 100644 index 11ea8aa627..0000000000 --- a/packages/api/src/verify.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { PermissionQuery } from "@unkey/rbac"; -import { Unkey } from "./client"; -import type { paths } from "./openapi"; - -/** - * Verify a key - * - * @example - * ```ts - * const { result, error } = await verifyKey("key_123") - * if (error){ - * // handle potential network or bad request error - * // a link to our docs will be in the `error.docs` field - * console.error(error.message) - * return - * } - * if (!result.valid) { - * // do not grant access - * return - * } - * - * // process request - * console.log(result) - * ``` - */ -export function verifyKey( - req: - | string - | (Omit< - paths["/v1/keys.verifyKey"]["post"]["requestBody"]["content"]["application/json"], - "authorization" - > & { authorization?: { permissions: PermissionQuery } }), -) { - // yes this is empty to make typescript happy but we don't need a token for verifying keys - // it's not the cleanest but it works for now :) - const unkey = new Unkey({ rootKey: "public" }); - return unkey.keys.verify(typeof req === "string" ? { key: req } : req); -} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json deleted file mode 100644 index 49fb1f9ddb..0000000000 --- a/packages/api/tsconfig.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "extends": "@unkey/tsconfig/base.json", - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ - "ESNext", - "DOM" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - // "module": "CommonJS", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "resolveJsonModule": true /* Enable importing .json files. */, - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */, - "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, - "strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */, - "strictBindCallApply": true /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */, - "strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */, - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/packages/api/tsup.config.js b/packages/api/tsup.config.js deleted file mode 100644 index cf7c3fea9c..0000000000 --- a/packages/api/tsup.config.js +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["cjs", "esm"], - splitting: false, - sourcemap: true, - clean: true, - bundle: true, - dts: true, -}); diff --git a/packages/hono/CHANGELOG.md b/packages/hono/CHANGELOG.md deleted file mode 100644 index b6d2aef706..0000000000 --- a/packages/hono/CHANGELOG.md +++ /dev/null @@ -1,355 +0,0 @@ -# @unkey/hono - -## 1.5.2 - -### Patch Changes - -- Updated dependencies [a4636e6] - - @unkey/api@0.38.0 - -## 1.5.1 - -### Patch Changes - -- Updated dependencies [0b489a9] - - @unkey/api@0.37.0 - -## 1.5.0 - -### Minor Changes - -- c528107: feat: allow setting tags to pass through on verification - -## 1.4.16 - -### Patch Changes - -- Updated dependencies [f73fc7e] - - @unkey/api@0.35.0 - -## 1.4.15 - -### Patch Changes - -- Updated dependencies [10120e0] - - @unkey/api@0.33.1 - -## 1.4.14 - -### Patch Changes - -- Updated dependencies [98bbb16] - - @unkey/api@0.33.0 - -## 1.4.13 - -### Patch Changes - -- Updated dependencies [a2f16f0] - - @unkey/api@0.32.0 - -## 1.4.12 - -### Patch Changes - -- Updated dependencies [56ae5f6] - - @unkey/api@0.31.0 - -## 1.4.11 - -### Patch Changes - -- Updated dependencies [0746b33] - - @unkey/api@0.30.0 - -## 1.4.10 - -### Patch Changes - -- Updated dependencies [3f8d078] - - @unkey/api@0.29.0 - -## 1.4.9 - -### Patch Changes - -- Updated dependencies [25fd102] - - @unkey/api@0.28.0 - -## 1.4.8 - -### Patch Changes - -- Updated dependencies [852d1a1] - - @unkey/api@0.27.0 - -## 1.4.7 - -### Patch Changes - -- Updated dependencies [82f5b5d] - - @unkey/api@0.26.2 - -## 1.4.6 - -### Patch Changes - -- Updated dependencies [2aada7d] - - @unkey/api@0.26.1 - -## 1.4.5 - -### Patch Changes - -- Updated dependencies [bb6d04e] - - @unkey/api@0.26.0 - -## 1.4.4 - -### Patch Changes - -- Updated dependencies [a532369] - - @unkey/api@0.25.0 - -## 1.4.3 - -### Patch Changes - -- Updated dependencies [bdad4b6] - - @unkey/api@0.24.0 - -## 1.4.2 - -### Patch Changes - -- Updated dependencies [e3231e3] - - @unkey/api@0.23.0 - -## 1.4.1 - -### Patch Changes - -- @unkey/api@0.22.1 - -## 1.4.0 - -### Minor Changes - -- 53a1df1: Update licenses in package.json - -### Patch Changes - -- Updated dependencies [53a1df1] - - @unkey/api@0.22.0 - -## 1.3.0 - -### Minor Changes - -- 9dab761: Updating licenses - -### Patch Changes - -- Updated dependencies [9dab761] - - @unkey/api@0.21.0 - -## 1.2.0 - -### Minor Changes - -- 362aaaa: Update hono deps - -## 1.1.14 - -### Patch Changes - -- Updated dependencies [69c88fa] - - @unkey/api@0.20.7 - -## 1.1.13 - -### Patch Changes - -- Updated dependencies [56ad960] - - @unkey/api@0.20.6 - -## 1.1.12 - -### Patch Changes - -- Updated dependencies [e4961c7] - - @unkey/api@0.20.5 - -## 1.1.11 - -### Patch Changes - -- Updated dependencies [3ddb1f1] - - @unkey/api@0.20.4 - -## 1.1.10 - -### Patch Changes - -- Updated dependencies [fc2b651] - - @unkey/api@0.20.3 - -## 1.1.9 - -### Patch Changes - -- Updated dependencies [c14b285] - - @unkey/api@0.20.2 - -## 1.1.8 - -### Patch Changes - -- @unkey/api@0.20.1 - -## 1.1.7 - -### Patch Changes - -- Updated dependencies [94d721d] - - @unkey/api@0.20.0 - -## 1.1.6 - -### Patch Changes - -- a4001eb: Fix UnkeyContext type -- Updated dependencies [a4001eb] - - @unkey/api@0.19.5 - -## 1.1.5 - -### Patch Changes - -- Updated dependencies [7043c1c] - - @unkey/api@0.19.4 - -## 1.1.4 - -### Patch Changes - -- @unkey/api@0.19.3 - -## 1.1.3 - -### Patch Changes - -- Updated dependencies [a2f3d7a] - - @unkey/api@0.19.2 - -## 1.1.2 - -### Patch Changes - -- d561b57: Release rbac as separate package -- Updated dependencies [d561b57] - - @unkey/api@0.19.1 - -## 1.1.1 - -### Patch Changes - -- Updated dependencies [eddab6b] - - @unkey/api@0.19.0 - -## 1.1.0 - -### Minor Changes - -- 3d81139: Add environment to context - -## 1.0.0 - -### Major Changes - -- 7d94063: Require apiId for verifying keys - -## 0.11.1 - -### Patch Changes - -- Updated dependencies [2af9a51] - - @unkey/api@0.18.0 - -## 0.11.0 - -### Minor Changes - -- 9f5f3d6: Collect SDK telemetry data - -### Patch Changes - -- Updated dependencies [9f5f3d6] - - @unkey/api@0.17.0 - -## 0.10.8 - -### Patch Changes - -- Updated dependencies [5de3ae76] - - @unkey/api@0.16.0 - -## 0.10.7 - -### Patch Changes - -- Updated dependencies [a1e82245] - - @unkey/api@0.15.0 - -## 0.10.6 - -### Patch Changes - -- Updated dependencies [2e26a07e] - - @unkey/api@0.14.0 - -## 0.10.5 - -### Patch Changes - -- Updated dependencies [153bd10] - - @unkey/api@0.13.1 - -## 0.10.4 - -### Patch Changes - -- Updated dependencies [0bfbc54] - - @unkey/api@0.13.0 - -## 0.10.3 - -### Patch Changes - -- Updated dependencies [2347efd] - - @unkey/api@0.12.1 - -## 0.10.2 - -### Patch Changes - -- Updated dependencies [8a6b040] - - @unkey/api@0.12.0 - -## 0.10.1 - -### Patch Changes - -- Updated dependencies [4cb0267] - - @unkey/api@0.11.0 - -## 0.10.0 - -### Minor Changes - -- 631a37c: fix version - -### Patch Changes - -- Updated dependencies [631a37c] - - @unkey/api@0.10.0 diff --git a/packages/hono/LICENSE.md b/packages/hono/LICENSE.md deleted file mode 100644 index d02c4877cd..0000000000 --- a/packages/hono/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023-present Unkeyed, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/hono/README.md b/packages/hono/README.md deleted file mode 100644 index a14fe830c2..0000000000 --- a/packages/hono/README.md +++ /dev/null @@ -1,34 +0,0 @@ - -
-

@unkey/hono

-
Hono.js middleware for authenticating API keys
-
- - -
- - - -Check out the docs at [unkey.dev/docs](https://unkey.com/docs/libraries/ts/hono). - - -Here's just an example: - -```ts -import { Hono } from "hono" -import { UnkeyContext, unkey } from "@unkey/hono"; - -const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - -app.use("*", unkey()); - - -app.get("/somewhere", (c) => { - // access the unkey response here to get metadata of the key etc - const ... = c.get("unkey") - - return c.text("yo") -}) -`` diff --git a/packages/hono/package.json b/packages/hono/package.json deleted file mode 100644 index c2ebf5f2ec..0000000000 --- a/packages/hono/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "@unkey/hono", - "version": "1.5.2", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "license": "MIT", - "private": false, - "publishConfig": { - "access": "public" - }, - "keywords": ["unkey", "client", "api", "hono"], - "bugs": { - "url": "https://github.com/unkeyed/unkey/issues" - }, - "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**"], - "author": "Andreas Thomas ", - "scripts": { - "build": "tsup", - "test": "vitest run" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "hono": "^4.6.3", - "msw": "^2.8.7", - "tsup": "^8.0.2", - "typescript": "^5.5.3", - "zod": "^3.23.5" - }, - "dependencies": { - "@unkey/api": "workspace:^" - }, - "peerDependencies": { - "hono": "^4.6.3" - } -} diff --git a/packages/hono/src/index.test.ts b/packages/hono/src/index.test.ts deleted file mode 100644 index 9acc66f3ce..0000000000 --- a/packages/hono/src/index.test.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { Hono } from "hono"; -import { http, HttpResponse } from "msw"; -import { setupServer } from "msw/node"; -import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest"; -import { z } from "zod"; -import { type UnkeyContext, unkey } from "./index"; - -const key = "test_key"; -const apiId = "api_test"; - -const server = setupServer( - // @ts-expect-error - http.post("https://api.unkey.dev/v1/keys.verifyKey", async ({ request }) => { - const req = z - .object({ - apiId: z.string(), - key: z.string(), - }) - .parse(await request.json()); - - if (req.apiId !== apiId) { - return HttpResponse.json({ - valid: false, - code: "FORBDIDDEN", - }); - } - if (req.key !== key) { - return HttpResponse.json({ - valid: false, - code: "NOT_FOUND", - }); - } - - return HttpResponse.json({ - valid: true, - environment: "test", - }); - }), -); - -beforeAll(() => { - server.listen(); -}); -afterEach(() => { - server.resetHandlers(); -}); -afterAll(() => { - server.close(); -}); - -describe("No custom Config", () => { - describe("happy path", () => { - const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - - app.use( - "*", - unkey({ - apiId, - }), - ); - - app.get("/", (c) => c.json(c.get("unkey"))); - - test("Should be hello message", async () => { - const res = await app.request("http://localhost/", { - headers: { - Authorization: `Bearer ${key}`, - }, - }); - expect(res.status, `expected 200, received: ${JSON.stringify(res, null, 2)}`).toBe(200); - expect(await res.json()).toMatchObject({ valid: true }); - }); - }); - - describe("No Authorization header", () => { - const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - - app.use( - "*", - unkey({ - apiId, - }), - ); - - app.get("/", (c) => c.json(c.get("unkey"))); - - test("should be unauthorized", async () => { - const res = await app.request("http://localhost/"); - expect(res.status).toBe(401); - expect(await res.json()).toMatchObject({ - error: "unauthorized", - }); - }); - }); -}); - -describe("with key environment", () => { - const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - - app.use( - "/*", - unkey({ - apiId, - }), - ); - - let returnedEnvironment: string | undefined = undefined; - - app.get("/", (c) => { - returnedEnvironment = c.get("unkey").environment; - return c.text("hello"); - }); - - test("environment should be returned in context", async () => { - const res = await app.request("http://localhost/", { - headers: { - Authorization: `Bearer ${key}`, - }, - }); - expect(res.status, `expected 200, received: ${JSON.stringify(res, null, 2)}`).toBe(200); - expect(returnedEnvironment).toBe("test"); - }); -}); - -describe("With custom key getter", () => { - describe("No Authorization header", () => { - const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - - app.use( - "/*", - unkey({ - apiId, - getKey: (c) => { - return c.text("oh well"); - }, - }), - ); - - app.get("/", (c) => c.json(c.get("unkey"))); - - test("should be called with response", async () => { - const res = await app.request("http://localhost/"); - expect(res.status, `expected 200, received: ${JSON.stringify(res, null, 2)}`).toBe(200); - expect(await res.text()).toEqual("oh well"); - }); - }); -}); - -describe("With custom invald handler", () => { - describe("No Authorization header", () => { - const app = new Hono<{ Variables: { unkey: UnkeyContext } }>(); - - let calledWith: UnkeyContext | null = null; - app.use( - "/*", - unkey({ - apiId, - handleInvalidKey: (c, result) => { - calledWith = result; - return c.text("oh well"); - }, - }), - ); - - app.get("/", (c) => c.json(c.get("unkey"))); - - test("should be called with response", async () => { - const res = await app.request("http://localhost/", { - headers: { - Authorization: "Bearer notakey", - }, - }); - expect(res.status, `expected 200, received: ${JSON.stringify(res, null, 2)}`).toBe(200); - expect(await res.text()).toEqual("oh well"); - expect(calledWith).toMatchObject({ - valid: false, - code: "NOT_FOUND", - }); - }); - }); -}); diff --git a/packages/hono/src/index.ts b/packages/hono/src/index.ts deleted file mode 100644 index 9c0a96aa05..0000000000 --- a/packages/hono/src/index.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { type ErrorResponse, Unkey } from "@unkey/api"; -import type { Context, MiddlewareHandler } from "hono"; -import { HTTPException } from "hono/http-exception"; -import { version } from "../package.json"; - -type VerifyResponse = Awaited["keys"]["verify"]>>; -export type UnkeyContext = VerifyResponse["result"]; - -export type UnkeyConfig = { - /** - * The apiId to verify against. Only keys belonging to this api will be valid. - */ - apiId: string; - - /** - * Arbitrary tags you may add during the verification to filter later. - */ - tags?: string[]; - - /** - * - * By default telemetry data is enabled, and sends: - * runtime (Node.js / Edge) - * platform (Node.js / Vercel / AWS) - * SDK version - */ - disableTelemetry?: boolean; - - /** - * How to get the key from the request - * Usually the key is provided in an `Authorization` header, but you can do what you want. - * - * Return the key as string, or undefined if it doesn't exist. - * - * You can also override the response given to the caller by returning a `Response` - * - * @default `c.req.header("Authorization")?.replace("Bearer ", "")` - */ - getKey?: (c: Context) => string | undefined | Response; - - /** - * Automatically return a custom response when a key is invalid - */ - handleInvalidKey?: (c: Context, result: UnkeyContext) => Response | Promise; - - /** - * What to do if things go wrong - */ - onError?: (c: Context, err: ErrorResponse["error"]) => Response | Promise; -}; - -export function unkey(config: UnkeyConfig): MiddlewareHandler { - return async (c, next) => { - const key = config.getKey - ? config.getKey(c) - : (c.req.header("Authorization")?.replace("Bearer ", "") ?? null); - if (!key) { - return c.json({ error: "unauthorized" }, { status: 401 }); - } - if (typeof key !== "string") { - return key; - } - - const unkeyInstance = new Unkey({ - rootKey: "public", - disableTelemetry: config.disableTelemetry, - wrapperSdkVersion: `@unkey/hono@${version}`, - }); - - const res = await unkeyInstance.keys.verify({ - key, - apiId: config.apiId, - tags: config.tags, - }); - if (res.error) { - if (config.onError) { - return config.onError(c, res.error); - } - throw new HTTPException(500, { - message: `unkey error: [CODE: ${res.error.code}] - [REQUEST_ID: ${res.error.requestId}] - ${res.error.message} - read more at ${res.error.docs}`, - }); - } - - if (!res.result.valid && config.handleInvalidKey) { - return config.handleInvalidKey(c, res.result); - } - - c.set("unkey", res.result); - await next(); - }; -} diff --git a/packages/hono/tsconfig.json b/packages/hono/tsconfig.json deleted file mode 100644 index da9b626fec..0000000000 --- a/packages/hono/tsconfig.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ - "ESNext", - "DOM" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - // "module": "CommonJS", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "resolveJsonModule": true /* Enable importing .json files. */, - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/packages/hono/tsup.config.js b/packages/hono/tsup.config.js deleted file mode 100644 index cf7c3fea9c..0000000000 --- a/packages/hono/tsup.config.js +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["cjs", "esm"], - splitting: false, - sourcemap: true, - clean: true, - bundle: true, - dts: true, -}); diff --git a/packages/hono/vitest.config.ts b/packages/hono/vitest.config.ts deleted file mode 100644 index 07da01c8f9..0000000000 --- a/packages/hono/vitest.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { defineConfig } from "vitest/config"; - -export default defineConfig({ - test: { - reporters: ["html", "verbose"], - outputFile: "./.vitest/html", - }, - resolve: { - mainFields: ["module"], - }, -}); diff --git a/packages/nextjs/CHANGELOG.md b/packages/nextjs/CHANGELOG.md deleted file mode 100644 index 8853dcbd77..0000000000 --- a/packages/nextjs/CHANGELOG.md +++ /dev/null @@ -1,379 +0,0 @@ -# @unkey/nextjs - -## 0.18.11 - -### Patch Changes - -- Updated dependencies [a4636e6] - - @unkey/api@0.38.0 - -## 0.18.10 - -### Patch Changes - -- Updated dependencies [0b489a9] - - @unkey/api@0.37.0 - -## 0.18.9 - -### Patch Changes - -- Updated dependencies [f73fc7e] - - @unkey/api@0.35.0 - -## 0.18.8 - -### Patch Changes - -- Updated dependencies [10120e0] - - @unkey/api@0.33.1 - -## 0.18.7 - -### Patch Changes - -- Updated dependencies [98bbb16] - - @unkey/api@0.33.0 - -## 0.18.6 - -### Patch Changes - -- Updated dependencies [a2f16f0] - - @unkey/api@0.32.0 - -## 0.18.5 - -### Patch Changes - -- Updated dependencies [56ae5f6] - - @unkey/api@0.31.0 - -## 0.18.4 - -### Patch Changes - -- Updated dependencies [0746b33] - - @unkey/api@0.30.0 - -## 0.18.3 - -### Patch Changes - -- Updated dependencies [3f8d078] - - @unkey/api@0.29.0 - -## 0.18.2 - -### Patch Changes - -- Updated dependencies [25fd102] - - @unkey/api@0.28.0 - -## 0.18.1 - -### Patch Changes - -- Updated dependencies [852d1a1] - - @unkey/api@0.27.0 - -## 0.18.0 - -### Minor Changes - -- 77ca701: upgrade types to match nextjs 15 - -## 0.17.7 - -### Patch Changes - -- Updated dependencies [82f5b5d] - - @unkey/api@0.26.2 - -## 0.17.6 - -### Patch Changes - -- Updated dependencies [2aada7d] - - @unkey/api@0.26.1 - -## 0.17.5 - -### Patch Changes - -- Updated dependencies [bb6d04e] - - @unkey/api@0.26.0 - -## 0.17.4 - -### Patch Changes - -- Updated dependencies [a532369] - - @unkey/api@0.25.0 - -## 0.17.3 - -### Patch Changes - -- Updated dependencies [bdad4b6] - - @unkey/api@0.24.0 - -## 0.17.2 - -### Patch Changes - -- Updated dependencies [e3231e3] - - @unkey/api@0.23.0 - -## 0.17.1 - -### Patch Changes - -- @unkey/api@0.22.1 - -## 0.17.0 - -### Minor Changes - -- 53a1df1: Update licenses in package.json - -### Patch Changes - -- Updated dependencies [53a1df1] - - @unkey/api@0.22.0 - -## 0.16.0 - -### Minor Changes - -- 9dab761: Updating licenses - -### Patch Changes - -- Updated dependencies [9dab761] - - @unkey/api@0.21.0 - -## 0.15.16 - -### Patch Changes - -- Updated dependencies [69c88fa] - - @unkey/api@0.20.7 - -## 0.15.15 - -### Patch Changes - -- Updated dependencies [56ad960] - - @unkey/api@0.20.6 - -## 0.15.14 - -### Patch Changes - -- Updated dependencies [e4961c7] - - @unkey/api@0.20.5 - -## 0.15.13 - -### Patch Changes - -- Updated dependencies [3ddb1f1] - - @unkey/api@0.20.4 - -## 0.15.12 - -### Patch Changes - -- Updated dependencies [fc2b651] - - @unkey/api@0.20.3 - -## 0.15.11 - -### Patch Changes - -- Updated dependencies [c14b285] - - @unkey/api@0.20.2 - -## 0.15.10 - -### Patch Changes - -- @unkey/api@0.20.1 - -## 0.15.9 - -### Patch Changes - -- Updated dependencies [94d721d] - - @unkey/api@0.20.0 - -## 0.15.8 - -### Patch Changes - -- a4001eb: Fix UnkeyContext type -- Updated dependencies [a4001eb] - - @unkey/api@0.19.5 - -## 0.15.7 - -### Patch Changes - -- Updated dependencies [7043c1c] - - @unkey/api@0.19.4 - -## 0.15.6 - -### Patch Changes - -- @unkey/api@0.19.3 - -## 0.15.5 - -### Patch Changes - -- Updated dependencies [a2f3d7a] - - @unkey/api@0.19.2 - -## 0.15.4 - -### Patch Changes - -- d561b57: Release rbac as separate package -- Updated dependencies [d561b57] - - @unkey/api@0.19.1 - -## 0.15.3 - -### Patch Changes - -- Updated dependencies [eddab6b] - - @unkey/api@0.19.0 - -## 0.15.2 - -### Patch Changes - -- Updated dependencies [2af9a51] - - @unkey/api@0.18.0 - -## 0.15.1 - -### Patch Changes - -- 9433394: Fix NextContext type - -## 0.15.0 - -### Minor Changes - -- 9f5f3d6: Collect SDK telemetry data - -### Patch Changes - -- Updated dependencies [9f5f3d6] - - @unkey/api@0.17.0 - -## 0.14.0 - -### Minor Changes - -- 6cd23ae9: Alter SDK types for compatibility with route handlers - -## 0.13.8 - -### Patch Changes - -- Updated dependencies [5de3ae76] - - @unkey/api@0.16.0 - -## 0.13.7 - -### Patch Changes - -- Updated dependencies [a1e82245] - - @unkey/api@0.15.0 - -## 0.13.6 - -### Patch Changes - -- Updated dependencies [2e26a07e] - - @unkey/api@0.14.0 - -## 0.13.5 - -### Patch Changes - -- Updated dependencies [153bd10] - - @unkey/api@0.13.1 - -## 0.13.4 - -### Patch Changes - -- Updated dependencies [0bfbc54] - - @unkey/api@0.13.0 - -## 0.13.3 - -### Patch Changes - -- Updated dependencies [2347efd] - - @unkey/api@0.12.1 - -## 0.13.2 - -### Patch Changes - -- 5987377: default to loading authorization header - -## 0.13.1 - -### Patch Changes - -- c5f3cdb: Remove nextjs peer dependency -- c5f3cdb: Do not bundle next - -## 0.13.0 - -### Minor Changes - -- 8a6b040: accept apiId when verifying a key - -### Patch Changes - -- Updated dependencies [8a6b040] - - @unkey/api@0.12.0 - -## 0.12.0 - -### Minor Changes - -- fce7720: remove unstable prefix - -## 0.11.1 - -### Patch Changes - -- Updated dependencies [4cb0267] - - @unkey/api@0.11.0 - -## 0.11.0 - -### Minor Changes - -- 0ea67b8: Add error and invalid callback - -## 0.10.0 - -### Minor Changes - -- 631a37c: fix version - -### Patch Changes - -- 7575101: upgrade dev dependencies -- Updated dependencies [631a37c] - - @unkey/api@0.10.0 diff --git a/packages/nextjs/LICENSE.md b/packages/nextjs/LICENSE.md deleted file mode 100644 index d02c4877cd..0000000000 --- a/packages/nextjs/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023-present Unkeyed, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/packages/nextjs/README.md b/packages/nextjs/README.md deleted file mode 100644 index e89e818ef6..0000000000 --- a/packages/nextjs/README.md +++ /dev/null @@ -1,93 +0,0 @@ -
-

@unkey/nextjs

-
`@unkey/nextjs` the official SDK for Next.js. Just use it in your route handlers a direct and type-safe method to verify API keys.
-
- - -
- -## Installation - -```bash -npm install @unkey/nextjs -``` - -## Quickstart - -Protecting API routes is as simple as wrapping them with the ```withUnkey``` handler: - -```ts -import { NextRequestWithUnkeyContext, withUnkey } from '@unkey/nextjs'; - -export const POST = withUnkey(async (req) => { - - // Process the request here - // You have access to the verification response using `req.unkey` - console.log(req.unkey); - - return new Response('Your API key is valid!'); -}); -``` - -That’s it! Since this is just handling key verification, there’s no need to specify a root key as an environment variable. - -If you want to customize how withUnkey processes incoming requests, you can do so as follows: - -## ```getKey``` -By default, withUnkey will look for a bearer token located in the ```authorization``` header. If you want to customize this, you can do so by passing a getter in the configuration object: - -```ts -export const GET = withUnkey(async (req) => { - // ... -}, { - getKey: (req) => new URL(req.url).searchParams.get("key"), -}); -``` - -## ```onError``` - -You can specify custom error handling. By default errors will be logged to the console, and ```withUnkey``` will return a NextResponse with status 500. - -```ts -export const GET = withUnkey(async (req) => { - // ... -}, { - onError: async (req, res) => { - await analytics.trackEvent(`Error ${res.code}: ${res.message}`) - return new NextResponse("Unkey error", { status: 500 }) - } -}); -``` - -## ```handleInvalidKey``` - -Specify what to do if Unkey reports that your key is invalid. - -```ts -export const GET = withUnkey(async (req) => { - // ... -}, { - handleInvalidKey: (req, res) => { - return new Response("Unauthorized", { status: 401 }) - } -}); -``` - - -## Disable telemetry - -By default, Unkey collects anonymous telemetry data to help us understand how our SDKs are used. - -If you wish to disable this, you can do so by passing a boolean flag to the constructor: - -```ts -export const GET = withUnkey(async (req) => { - // ... -}, { disableTelemetry: true }); -``` - -### Documentation - -[Read the full documentation](https://www.unkey.com/docs/libraries/ts/nextjs) \ No newline at end of file diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json deleted file mode 100644 index e6725133fa..0000000000 --- a/packages/nextjs/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "@unkey/nextjs", - "version": "0.18.11", - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "license": "MIT", - "private": false, - "publishConfig": { - "access": "public" - }, - "keywords": ["unkey", "client", "api"], - "bugs": { - "url": "https://github.com/unkeyed/unkey/issues" - }, - "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**", "README.md"], - "author": "Andreas Thomas ", - "scripts": { - "build": "tsup" - }, - "devDependencies": { - "@types/node": "^20.14.9", - "next": "14.2.15", - "tsup": "^8.0.2", - "typescript": "^5.5.3" - }, - "dependencies": { - "@unkey/api": "workspace:^" - } -} diff --git a/packages/nextjs/src/index.ts b/packages/nextjs/src/index.ts deleted file mode 100644 index 27602d0aee..0000000000 --- a/packages/nextjs/src/index.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { type ErrorResponse, Unkey } from "@unkey/api"; -import { type NextRequest, NextResponse } from "next/server"; - -import { version } from "../package.json"; - -export type WithUnkeyConfig = { - /** - * The apiId to verify against. - * - * This will be required soon. - */ - apiId?: string; - - /** - * - * By default telemetry data is enabled, and sends: - * runtime (Node.js / Edge) - * platform (Node.js / Vercel / AWS) - * SDK version - */ - disableTelemetry?: boolean; - - /** - * How to get the key from the request - * Usually the key is provided in an `Authorization` header, but you can do what you want. - * - * Return the key as string, or null if it doesn't exist. - * - * You can also override the response given to the caller by returning a `NextResponse` - * - * @default `req.headers.get("authorization")?.replace("Bearer ", "") ?? null` - */ - getKey?: (req: NextRequest) => string | null | Response | NextResponse; - - /** - * Automatically return a custom response when a key is invalid - */ - handleInvalidKey?: ( - req: NextRequest, - result: UnkeyContext, - ) => Response | NextResponse | Promise | Promise; - - /** - * What to do if things go wrong - */ - onError?: ( - req: NextRequest, - err: ErrorResponse["error"], - ) => Response | NextResponse | Promise | Promise; -}; - -type VerifyResponse = Awaited["keys"]["verify"]>>; -export type UnkeyContext = VerifyResponse["result"]; - -export type NextContext = { params: Promise> }; - -export type NextRequestWithUnkeyContext = NextRequest & { unkey: UnkeyContext }; - -export function withUnkey( - handler: ( - req: NextRequestWithUnkeyContext, - context: TContext, - ) => Response | NextResponse | Promise, - config?: WithUnkeyConfig, -) { - return async (req: NextRequest, context: TContext) => { - /** - * Get key from request and return a response early if not found - */ - const key = config?.getKey - ? config.getKey(req) - : (req.headers.get("authorization")?.replace("Bearer ", "") ?? null); - if (key === null) { - return NextResponse.json({ error: "unauthorized" }, { status: 401 }); - } - if (typeof key !== "string") { - return key; - } - - const unkey = new Unkey({ - rootKey: "public", - wrapperSdkVersion: `@unkey/nextjs@${version}`, - disableTelemetry: config?.disableTelemetry, - }); - - const res = await unkey.keys.verify(config?.apiId ? { key, apiId: config.apiId } : { key }); - - if (res.error) { - if (config?.onError) { - return config.onError(req, res.error); - } - console.error( - `unkey error: [CODE: ${res.error.code}] - [TRACE: ${res.error.requestId}] - ${res.error.message} - read more at ${res.error.docs}`, - ); - return new NextResponse("Internal Server Error", { status: 500 }); - } - - if (!res.result.valid) { - if (config?.handleInvalidKey) { - return config.handleInvalidKey(req, res.result); - } - - return new NextResponse("Unauthorized", { status: 500 }); - } - - // @ts-ignore - req.unkey = res.result; - - return handler(req as NextRequestWithUnkeyContext, context); - }; -} diff --git a/packages/nextjs/tsconfig.json b/packages/nextjs/tsconfig.json deleted file mode 100644 index da9b626fec..0000000000 --- a/packages/nextjs/tsconfig.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - /* Language and Environment */ - "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, - "lib": [ - "ESNext", - "DOM" - ] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ - /* Modules */ - // "module": "CommonJS", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - "moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */, - // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ - // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ - // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ - // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - "resolveJsonModule": true /* Enable importing .json files. */, - // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ - /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ - /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ - // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ - /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, - /* Type Checking */ - "strict": true /* Enable all strict type-checking options. */, - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ - // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ - // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ - /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } -} diff --git a/packages/nextjs/tsup.config.js b/packages/nextjs/tsup.config.js deleted file mode 100644 index 4c25bc2236..0000000000 --- a/packages/nextjs/tsup.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import { defineConfig } from "tsup"; - -export default defineConfig({ - entry: ["src/index.ts"], - format: ["cjs", "esm"], - external: ["next"], - splitting: false, - sourcemap: true, - clean: true, - bundle: true, - dts: true, -}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b1214d710d..47aa03eb33 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,8 +119,8 @@ importers: specifier: ^4.20240603.0 version: 4.20240603.0 '@unkey/api': - specifier: workspace:^ - version: link:../../packages/api + specifier: 2.0.0 + version: 2.0.0 '@unkey/tsconfig': specifier: workspace:^ version: link:../../internal/tsconfig @@ -437,7 +437,7 @@ importers: devDependencies: mintlify: specifier: ^4.2.31 - version: 4.2.31(@types/node@22.14.0)(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3) + version: 4.2.31(@types/node@22.14.0)(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3) apps/engineering: dependencies: @@ -621,10 +621,10 @@ importers: devDependencies: checkly: specifier: latest - version: 6.1.1(@types/node@24.1.0)(typescript@5.5.3) + version: 6.1.1(@types/node@20.14.9)(typescript@5.5.3) ts-node: specifier: 10.9.1 - version: 10.9.1(@types/node@24.1.0)(typescript@5.5.3) + version: 10.9.1(@types/node@20.14.9)(typescript@5.5.3) typescript: specifier: 5.5.3 version: 5.5.3 @@ -870,7 +870,7 @@ importers: version: 2.1.1(eslint@9.31.0) resend: specifier: ^4.4.0 - version: 4.4.0(react-dom@19.1.0)(react@18.3.1) + version: 4.4.0(react-dom@18.3.1)(react@18.3.1) devDependencies: '@types/node': specifier: ^20.14.9 @@ -1039,31 +1039,6 @@ importers: specifier: ^5.5.3 version: 5.7.3 - packages/api: - dependencies: - '@unkey/rbac': - specifier: workspace:^ - version: link:../rbac - devDependencies: - '@types/node': - specifier: ^20.14.9 - version: 20.14.9 - '@unkey/tsconfig': - specifier: workspace:^ - version: link:../../internal/tsconfig - openapi-typescript: - specifier: ^6.7.5 - version: 6.7.5 - tsup: - specifier: ^8.0.2 - version: 8.0.2(typescript@5.7.3) - typescript: - specifier: ^5.5.3 - version: 5.7.3 - vitest: - specifier: ^1.6.1 - version: 1.6.1(@types/node@20.14.9)(@vitest/ui@3.2.4) - packages/cache: dependencies: '@opentelemetry/api': @@ -1111,50 +1086,6 @@ importers: specifier: ^5.5.3 version: 5.7.3 - packages/hono: - dependencies: - '@unkey/api': - specifier: workspace:^ - version: link:../api - devDependencies: - '@types/node': - specifier: ^20.14.9 - version: 20.14.9 - hono: - specifier: ^4.6.3 - version: 4.6.3 - msw: - specifier: ^2.8.7 - version: 2.8.7(@types/node@20.14.9)(typescript@5.7.3) - tsup: - specifier: ^8.0.2 - version: 8.0.2(typescript@5.7.3) - typescript: - specifier: ^5.5.3 - version: 5.7.3 - zod: - specifier: 3.23.8 - version: 3.23.8 - - packages/nextjs: - dependencies: - '@unkey/api': - specifier: workspace:^ - version: link:../api - devDependencies: - '@types/node': - specifier: ^20.14.9 - version: 20.14.9 - next: - specifier: 14.2.15 - version: 14.2.15(react-dom@18.3.1)(react@18.3.1) - tsup: - specifier: ^8.0.2 - version: 8.0.2(typescript@5.7.3) - typescript: - specifier: ^5.5.3 - version: 5.7.3 - packages/rbac: dependencies: '@unkey/error': @@ -1760,25 +1691,6 @@ packages: dev: true optional: true - /@bundled-es-modules/cookie@2.0.1: - resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} - dependencies: - cookie: 0.7.2 - dev: true - - /@bundled-es-modules/statuses@1.0.1: - resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} - dependencies: - statuses: 2.0.2 - dev: true - - /@bundled-es-modules/tough-cookie@0.1.6: - resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} - dependencies: - '@types/tough-cookie': 4.0.5 - tough-cookie: 4.1.4 - dev: true - /@changesets/apply-release-plan@7.0.12: resolution: {integrity: sha512-EaET7As5CeuhTzvXTQCRZeBUcisoYPDDcXvgTE/2jmmypKp0RC7LxKj/yzqeh/1qFTZI7oDGFcL1PHRuQuketQ==} dependencies: @@ -4350,7 +4262,7 @@ packages: dev: false optional: true - /@inquirer/checkbox@4.2.0(@types/node@22.14.0): + /@inquirer/checkbox@4.2.0(@types/node@20.14.9): resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==} engines: {node: '>=18'} peerDependencies: @@ -4359,15 +4271,15 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@22.14.0) + '@inquirer/core': 10.1.15(@types/node@20.14.9) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.14.0) - '@types/node': 22.14.0 + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/checkbox@4.2.0(@types/node@24.1.0): + /@inquirer/checkbox@4.2.0(@types/node@22.14.0): resolution: {integrity: sha512-fdSw07FLJEU5vbpOPzXo5c6xmMGDzbZE2+niuDHX5N6mc6V0Ebso/q3xiHra4D73+PMsC8MJmcaZKuAAoaQsSA==} engines: {node: '>=18'} peerDependencies: @@ -4376,16 +4288,16 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) + '@inquirer/core': 10.1.15(@types/node@22.14.0) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/type': 3.0.8(@types/node@22.14.0) + '@types/node': 22.14.0 ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/confirm@5.1.13(@types/node@20.14.9): - resolution: {integrity: sha512-EkCtvp67ICIVVzjsquUiVSd+V5HRGOGQfsqA4E4vMWhYnB7InUL0pa0TIWt1i+OfP16Gkds8CdIu6yGZwOM1Yw==} + /@inquirer/confirm@5.1.14(@types/node@20.14.9): + resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4393,8 +4305,8 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.14(@types/node@20.14.9) - '@inquirer/type': 3.0.7(@types/node@20.14.9) + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) '@types/node': 20.14.9 dev: true @@ -4412,22 +4324,8 @@ packages: '@types/node': 22.14.0 dev: true - /@inquirer/confirm@5.1.14(@types/node@24.1.0): - resolution: {integrity: sha512-5yR4IBfe0kXe59r1YCTG8WXkUbl7Z35HK87Sw+WUyGD8wNUx7JvY7laahzeytyE1oLn74bQnL7hstctQxisQ8Q==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - dev: true - - /@inquirer/core@10.1.14(@types/node@20.14.9): - resolution: {integrity: sha512-Ma+ZpOJPewtIYl6HZHZckeX1STvDnHTCB2GVINNUlSEn2Am6LddWwfPkIGY0IUFVjUUrr/93XlBwTK6mfLjf0A==} + /@inquirer/core@10.1.15(@types/node@20.14.9): + resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4436,7 +4334,7 @@ packages: optional: true dependencies: '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.7(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) '@types/node': 20.14.9 ansi-escapes: 4.3.2 cli-width: 4.1.0 @@ -4466,8 +4364,8 @@ packages: yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/core@10.1.15(@types/node@24.1.0): - resolution: {integrity: sha512-8xrp836RZvKkpNbVvgWUlxjT4CraKk2q+I3Ksy+seI2zkcE+y6wNs1BVhgcv8VyImFecUhdQrYLdW32pAjwBdA==} + /@inquirer/editor@4.2.15(@types/node@20.14.9): + resolution: {integrity: sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4475,15 +4373,10 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - ansi-escapes: 4.3.2 - cli-width: 4.1.0 - mute-stream: 2.0.0 - signal-exit: 4.1.0 - wrap-ansi: 6.2.0 - yoctocolors-cjs: 2.1.2 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 + external-editor: 3.1.0 dev: true /@inquirer/editor@4.2.15(@types/node@22.14.0): @@ -4501,8 +4394,8 @@ packages: external-editor: 3.1.0 dev: true - /@inquirer/editor@4.2.15(@types/node@24.1.0): - resolution: {integrity: sha512-wst31XT8DnGOSS4nNJDIklGKnf+8shuauVrWzgKegWUe28zfCftcWZ2vktGdzJgcylWSS2SrDnYUb6alZcwnCQ==} + /@inquirer/expand@4.0.17(@types/node@20.14.9): + resolution: {integrity: sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4510,10 +4403,10 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - external-editor: 3.1.0 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 + yoctocolors-cjs: 2.1.2 dev: true /@inquirer/expand@4.0.17(@types/node@22.14.0): @@ -4531,8 +4424,13 @@ packages: yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/expand@4.0.17(@types/node@24.1.0): - resolution: {integrity: sha512-PSqy9VmJx/VbE3CT453yOfNa+PykpKg/0SYP7odez1/NWBGuDXgPhp4AeGYYKjhLn5lUUavVS/JbeYMPdH50Mw==} + /@inquirer/figures@1.0.13: + resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} + engines: {node: '>=18'} + dev: true + + /@inquirer/input@4.2.1(@types/node@20.14.9): + resolution: {integrity: sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4540,15 +4438,9 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - yoctocolors-cjs: 2.1.2 - dev: true - - /@inquirer/figures@1.0.13: - resolution: {integrity: sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==} - engines: {node: '>=18'} + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 dev: true /@inquirer/input@4.2.1(@types/node@22.14.0): @@ -4565,8 +4457,8 @@ packages: '@types/node': 22.14.0 dev: true - /@inquirer/input@4.2.1(@types/node@24.1.0): - resolution: {integrity: sha512-tVC+O1rBl0lJpoUZv4xY+WGWY8V5b0zxU1XDsMsIHYregdh7bN5X5QnIONNBAl0K765FYlAfNHS2Bhn7SSOVow==} + /@inquirer/number@3.0.17(@types/node@20.14.9): + resolution: {integrity: sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4574,9 +4466,9 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 dev: true /@inquirer/number@3.0.17(@types/node@22.14.0): @@ -4593,8 +4485,8 @@ packages: '@types/node': 22.14.0 dev: true - /@inquirer/number@3.0.17(@types/node@24.1.0): - resolution: {integrity: sha512-GcvGHkyIgfZgVnnimURdOueMk0CztycfC8NZTiIY9arIAkeOgt6zG57G+7vC59Jns3UX27LMkPKnKWAOF5xEYg==} + /@inquirer/password@4.0.17(@types/node@20.14.9): + resolution: {integrity: sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4602,9 +4494,10 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 + ansi-escapes: 4.3.2 dev: true /@inquirer/password@4.0.17(@types/node@22.14.0): @@ -4622,8 +4515,8 @@ packages: ansi-escapes: 4.3.2 dev: true - /@inquirer/password@4.0.17(@types/node@24.1.0): - resolution: {integrity: sha512-DJolTnNeZ00E1+1TW+8614F7rOJJCM4y4BAGQ3Gq6kQIG+OJ4zr3GLjIjVVJCbKsk2jmkmv6v2kQuN/vriHdZA==} + /@inquirer/prompts@7.7.1(@types/node@20.14.9): + resolution: {integrity: sha512-XDxPrEWeWUBy8scAXzXuFY45r/q49R0g72bUzgQXZ1DY/xEFX+ESDMkTQolcb5jRBzaNJX2W8XQl6krMNDTjaA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4631,10 +4524,17 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - ansi-escapes: 4.3.2 + '@inquirer/checkbox': 4.2.0(@types/node@20.14.9) + '@inquirer/confirm': 5.1.14(@types/node@20.14.9) + '@inquirer/editor': 4.2.15(@types/node@20.14.9) + '@inquirer/expand': 4.0.17(@types/node@20.14.9) + '@inquirer/input': 4.2.1(@types/node@20.14.9) + '@inquirer/number': 3.0.17(@types/node@20.14.9) + '@inquirer/password': 4.0.17(@types/node@20.14.9) + '@inquirer/rawlist': 4.1.5(@types/node@20.14.9) + '@inquirer/search': 3.0.17(@types/node@20.14.9) + '@inquirer/select': 4.3.1(@types/node@20.14.9) + '@types/node': 20.14.9 dev: true /@inquirer/prompts@7.7.1(@types/node@22.14.0): @@ -4659,8 +4559,8 @@ packages: '@types/node': 22.14.0 dev: true - /@inquirer/prompts@7.7.1(@types/node@24.1.0): - resolution: {integrity: sha512-XDxPrEWeWUBy8scAXzXuFY45r/q49R0g72bUzgQXZ1DY/xEFX+ESDMkTQolcb5jRBzaNJX2W8XQl6krMNDTjaA==} + /@inquirer/rawlist@4.1.5(@types/node@20.14.9): + resolution: {integrity: sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4668,17 +4568,10 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/checkbox': 4.2.0(@types/node@24.1.0) - '@inquirer/confirm': 5.1.14(@types/node@24.1.0) - '@inquirer/editor': 4.2.15(@types/node@24.1.0) - '@inquirer/expand': 4.0.17(@types/node@24.1.0) - '@inquirer/input': 4.2.1(@types/node@24.1.0) - '@inquirer/number': 3.0.17(@types/node@24.1.0) - '@inquirer/password': 4.0.17(@types/node@24.1.0) - '@inquirer/rawlist': 4.1.5(@types/node@24.1.0) - '@inquirer/search': 3.0.17(@types/node@24.1.0) - '@inquirer/select': 4.3.1(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 + yoctocolors-cjs: 2.1.2 dev: true /@inquirer/rawlist@4.1.5(@types/node@22.14.0): @@ -4696,8 +4589,8 @@ packages: yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/rawlist@4.1.5(@types/node@24.1.0): - resolution: {integrity: sha512-R5qMyGJqtDdi4Ht521iAkNqyB6p2UPuZUbMifakg1sWtu24gc2Z8CJuw8rP081OckNDMgtDCuLe42Q2Kr3BolA==} + /@inquirer/search@3.0.17(@types/node@20.14.9): + resolution: {integrity: sha512-CuBU4BAGFqRYors4TNCYzy9X3DpKtgIW4Boi0WNkm4Ei1hvY9acxKdBdyqzqBCEe4YxSdaQQsasJlFlUJNgojw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4705,9 +4598,10 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/core': 10.1.15(@types/node@20.14.9) + '@inquirer/figures': 1.0.13 + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 yoctocolors-cjs: 2.1.2 dev: true @@ -4727,8 +4621,8 @@ packages: yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/search@3.0.17(@types/node@24.1.0): - resolution: {integrity: sha512-CuBU4BAGFqRYors4TNCYzy9X3DpKtgIW4Boi0WNkm4Ei1hvY9acxKdBdyqzqBCEe4YxSdaQQsasJlFlUJNgojw==} + /@inquirer/select@4.3.1(@types/node@20.14.9): + resolution: {integrity: sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4736,10 +4630,11 @@ packages: '@types/node': optional: true dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) + '@inquirer/core': 10.1.15(@types/node@20.14.9) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 + '@inquirer/type': 3.0.8(@types/node@20.14.9) + '@types/node': 20.14.9 + ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 dev: true @@ -4760,25 +4655,8 @@ packages: yoctocolors-cjs: 2.1.2 dev: true - /@inquirer/select@4.3.1(@types/node@24.1.0): - resolution: {integrity: sha512-Gfl/5sqOF5vS/LIrSndFgOh7jgoe0UXEizDqahFRkq5aJBLegZ6WjuMh/hVEJwlFQjyLq1z9fRtvUMkb7jM1LA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - dependencies: - '@inquirer/core': 10.1.15(@types/node@24.1.0) - '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@24.1.0) - '@types/node': 24.1.0 - ansi-escapes: 4.3.2 - yoctocolors-cjs: 2.1.2 - dev: true - - /@inquirer/type@3.0.7(@types/node@20.14.9): - resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} + /@inquirer/type@3.0.8(@types/node@20.14.9): + resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -4801,18 +4679,6 @@ packages: '@types/node': 22.14.0 dev: true - /@inquirer/type@3.0.8(@types/node@24.1.0): - resolution: {integrity: sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - dependencies: - '@types/node': 24.1.0 - dev: true - /@isaacs/balanced-match@4.0.1: resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -5096,14 +4962,14 @@ packages: - acorn - supports-color - /@mdx-js/react@3.1.0(@types/react@19.1.8)(react@18.3.1): + /@mdx-js/react@3.1.0(@types/react@18.3.11)(react@18.3.1): resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} peerDependencies: '@types/react': '>=16' react: '>=16' dependencies: '@types/mdx': 2.0.13 - '@types/react': 19.1.8 + '@types/react': 18.3.11 react: 18.3.1 dev: true @@ -5120,21 +4986,21 @@ packages: - ws dev: false - /@mintlify/cli@4.0.635(@types/node@22.14.0)(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3): + /@mintlify/cli@4.0.635(@types/node@22.14.0)(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-jvTcEz3Zt31AQG9K+VBzJujssYKL6ED5NHeajsoysH2aJzLM8Xp7h+JPseVZmeDUU7jp+yCF/fNeGmmlUQXyqQ==} engines: {node: '>=18.0.0'} hasBin: true dependencies: - '@mintlify/common': 1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1) - '@mintlify/link-rot': 3.0.583(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) + '@mintlify/common': 1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/link-rot': 3.0.583(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) '@mintlify/models': 0.0.210 - '@mintlify/prebuild': 1.0.576(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) - '@mintlify/previewing': 4.0.620(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3) + '@mintlify/prebuild': 1.0.576(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) + '@mintlify/previewing': 4.0.620(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3) '@mintlify/validation': 0.1.421 chalk: 5.4.1 detect-port: 1.6.1 fs-extra: 11.3.0 - ink: 5.2.1(@types/react@19.1.8)(react@18.3.1) + ink: 5.2.1(@types/react@18.3.11)(react@18.3.1) inquirer: 12.8.2(@types/node@22.14.0) js-yaml: 4.1.0 react: 18.3.1 @@ -5154,11 +5020,11 @@ packages: - utf-8-validate dev: true - /@mintlify/common@1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1): + /@mintlify/common@1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-yYwEfKJOjH+X8B13b5cjbpy3X1bSjEhxSFAVFhGFNbM5eT8f0S/Yu3i+jcJXbkl+5zifa4b4Mh4Vk7oUhXRxuQ==} dependencies: '@asyncapi/parser': 3.4.0 - '@mintlify/mdx': 2.0.3(@types/react@19.1.8)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/mdx': 2.0.3(@types/react@18.3.11)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1) '@mintlify/models': 0.0.210 '@mintlify/openapi-parser': 0.0.7 '@mintlify/validation': 0.1.421 @@ -5202,13 +5068,13 @@ packages: - supports-color dev: true - /@mintlify/link-rot@3.0.583(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): + /@mintlify/link-rot@3.0.583(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-rZ47hB/lUdQhYnbH4QrBl5Sph2JTJr78LhXlKTcY226fQUD3yaRNCmk23lIkoGm7sc2gQEIuPW+guPL8KJx8XA==} engines: {node: '>=18.0.0'} dependencies: - '@mintlify/common': 1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1) - '@mintlify/prebuild': 1.0.576(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) - '@mintlify/previewing': 4.0.620(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3) + '@mintlify/common': 1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/prebuild': 1.0.576(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) + '@mintlify/previewing': 4.0.620(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3) '@mintlify/validation': 0.1.421 fs-extra: 11.3.0 unist-util-visit: 4.1.2 @@ -5226,7 +5092,7 @@ packages: - utf-8-validate dev: true - /@mintlify/mdx@2.0.3(@types/react@19.1.8)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1): + /@mintlify/mdx@2.0.3(@types/react@18.3.11)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-UGlwavma8QooWAlhtXpTAG5MAUZTTUKI8Qu25Wqfp1HMOPrYGvo5YQPmlqqogbMsqDMcFPLP/ZYnaZsGUYBspQ==} peerDependencies: react: ^18.3.1 @@ -5235,7 +5101,7 @@ packages: '@shikijs/transformers': 3.8.1 hast-util-to-string: 3.0.1 mdast-util-mdx-jsx: 3.2.0 - next-mdx-remote-client: 1.1.1(@types/react@19.1.8)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1)(unified@11.0.5) + next-mdx-remote-client: 1.1.1(@types/react@18.3.11)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1)(unified@11.0.5) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) rehype-katex: 7.0.1 @@ -5273,12 +5139,12 @@ packages: yaml: 2.8.0 dev: true - /@mintlify/prebuild@1.0.576(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): + /@mintlify/prebuild@1.0.576(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-qEK9BXkAUWvUn0EXa2mstrJDDQO5qxeJYPMD+gfbcHaIJ6suJ6eZSC0VMDpouUra+YxZGHM+HKI0BfeHOKCftA==} dependencies: - '@mintlify/common': 1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/common': 1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1) '@mintlify/openapi-parser': 0.0.7 - '@mintlify/scraping': 4.0.314(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) + '@mintlify/scraping': 4.0.314(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) '@mintlify/validation': 0.1.421 chalk: 5.4.1 favicons: 7.2.0 @@ -5301,12 +5167,12 @@ packages: - utf-8-validate dev: true - /@mintlify/previewing@4.0.620(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3): + /@mintlify/previewing@4.0.620(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-s51OZTAsRe4GDSoHf19CKBPZgSS5heqC9n+ENsAej22sd1tN8oGHl2Fw2rgSt7VgxdcINu/yXsEt9sgS2LPz7g==} engines: {node: '>=18.0.0'} dependencies: - '@mintlify/common': 1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1) - '@mintlify/prebuild': 1.0.576(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) + '@mintlify/common': 1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/prebuild': 1.0.576(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3) '@mintlify/validation': 0.1.421 better-opn: 3.0.2 chalk: 5.4.1 @@ -5315,7 +5181,7 @@ packages: fs-extra: 11.3.0 got: 13.0.0 gray-matter: 4.0.3 - ink: 5.2.1(@types/react@19.1.8)(react@18.3.1) + ink: 5.2.1(@types/react@18.3.11)(react@18.3.1) ink-spinner: 5.0.0(ink@5.2.1)(react@18.3.1) is-online: 10.0.0 js-yaml: 4.1.0 @@ -5339,12 +5205,12 @@ packages: - utf-8-validate dev: true - /@mintlify/scraping@4.0.314(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): + /@mintlify/scraping@4.0.314(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-vPNUJpYSXllf5A+hiSBze3urMkNzKn8CeQ58cu7CzIco05h8hH0hnZYG8JaBCReXk3kfosSiDB4veY9EBEsB0w==} engines: {node: '>=18.0.0'} hasBin: true dependencies: - '@mintlify/common': 1.0.458(@types/react@19.1.8)(react-dom@18.3.1)(react@18.3.1) + '@mintlify/common': 1.0.458(@types/react@18.3.11)(react-dom@18.3.1)(react@18.3.1) '@mintlify/openapi-parser': 0.0.7 fs-extra: 11.3.0 hast-util-to-mdast: 10.1.2 @@ -5387,18 +5253,6 @@ packages: - debug dev: true - /@mswjs/interceptors@0.38.7: - resolution: {integrity: sha512-Jkb27iSn7JPdkqlTqKfhncFfnEZsIJVYxsFbUSWEkxdIPdsyngrhoDBk0/BGD2FQcRH99vlRrkHpNTyKqI+0/w==} - engines: {node: '>=18'} - dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 - dev: true - /@neon-rs/load@0.0.4: resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} dev: true @@ -5409,6 +5263,7 @@ packages: /@next/env@14.2.15: resolution: {integrity: sha512-S1qaj25Wru2dUpcIZMjxeMVSwkt8BK4dmWHHiBuRstcIyOsMapqT4A4jSB6onvqeygkSSmOkyny9VVx8JIGamQ==} + dev: false /@next/env@14.2.25: resolution: {integrity: sha512-JnzQ2cExDeG7FxJwqAksZ3aqVJrHjFwZQAEJ9gQZSoEhIow7SNoKZzju/AwQ+PLIR4NY8V0rhcVozx/2izDO0w==} @@ -5433,6 +5288,7 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true + dev: false optional: true /@next/swc-darwin-arm64@14.2.25: @@ -5468,6 +5324,7 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true + dev: false optional: true /@next/swc-darwin-x64@14.2.25: @@ -5503,6 +5360,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: false optional: true /@next/swc-linux-arm64-gnu@14.2.25: @@ -5538,6 +5396,7 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true + dev: false optional: true /@next/swc-linux-arm64-musl@14.2.25: @@ -5573,6 +5432,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: false optional: true /@next/swc-linux-x64-gnu@14.2.25: @@ -5608,6 +5468,7 @@ packages: cpu: [x64] os: [linux] requiresBuild: true + dev: false optional: true /@next/swc-linux-x64-musl@14.2.25: @@ -5643,6 +5504,7 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true + dev: false optional: true /@next/swc-win32-arm64-msvc@14.2.25: @@ -5678,6 +5540,7 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true + dev: false optional: true /@next/swc-win32-ia32-msvc@14.2.25: @@ -5713,6 +5576,7 @@ packages: cpu: [x64] os: [win32] requiresBuild: true + dev: false optional: true /@next/swc-win32-x64-msvc@14.2.25: @@ -5803,11 +5667,11 @@ packages: '@oclif/core': 4.5.2 dev: true - /@oclif/plugin-not-found@3.2.60(@types/node@24.1.0): + /@oclif/plugin-not-found@3.2.60(@types/node@20.14.9): resolution: {integrity: sha512-TK+o2gdFK/IEOR/A9lk2Ob7qm7Z+fEaaHlNls4AfKcEgxfSGaDwGu6cF9lxtMq87pVJ47uiAjjZaBtGYmS01Wg==} engines: {node: '>=18.0.0'} dependencies: - '@inquirer/prompts': 7.7.1(@types/node@24.1.0) + '@inquirer/prompts': 7.7.1(@types/node@20.14.9) '@oclif/core': 4.5.2 ansis: 3.17.0 fast-levenshtein: 3.0.0 @@ -6031,21 +5895,6 @@ packages: zod: 3.23.8 dev: false - /@open-draft/deferred-promise@2.2.0: - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - dev: true - - /@open-draft/logger@0.3.0: - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - dev: true - - /@open-draft/until@2.1.0: - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - dev: true - /@openapi-contrib/openapi-schema-to-json-schema@3.2.0: resolution: {integrity: sha512-Gj6C0JwCr8arj0sYuslWXUBSP/KnUlEGnPW4qxlXvAl543oaNQgMgIgkQUA6vs5BCCvwTEiL8m/wdWzfl4UvSw==} dependencies: @@ -9171,7 +9020,7 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@react-email/render@1.0.6(react-dom@19.1.0)(react@18.3.1): + /@react-email/render@1.0.6(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-zNueW5Wn/4jNC1c5LFgXzbUdv5Lhms+FWjOvWAhal7gx5YVf0q6dPJ0dnR70+ifo59gcMLwCZEaTS9EEuUhKvQ==} engines: {node: '>=18.0.0'} peerDependencies: @@ -9181,7 +9030,7 @@ packages: html-to-text: 9.0.5 prettier: 3.5.3 react: 18.3.1 - react-dom: 19.1.0(react@18.3.1) + react-dom: 18.3.1(react@18.3.1) react-promise-suspense: 0.3.4 dev: false @@ -10094,6 +9943,7 @@ packages: /@swc/counter@0.1.3: resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + dev: false /@swc/helpers@0.5.2: resolution: {integrity: sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw==} @@ -10106,6 +9956,7 @@ packages: dependencies: '@swc/counter': 0.1.3 tslib: 2.8.1 + dev: false /@swc/types@0.1.23: resolution: {integrity: sha512-u1iIVZV9Q0jxY+yM2vw/hZGDNudsN85bBpTqzAQ9rzkxW9D+e3aEM4Han+ow518gSewkXgjmEK0BD79ZcNVgPw==} @@ -10339,7 +10190,7 @@ packages: /@types/accepts@1.3.7: resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} dependencies: - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/archiver@6.0.3: @@ -10356,7 +10207,7 @@ packages: resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} dependencies: '@types/connect': 3.4.38 - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/chai@5.2.2: @@ -10368,7 +10219,7 @@ packages: /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/content-disposition@0.5.9: @@ -10378,7 +10229,7 @@ packages: /@types/conventional-commits-parser@5.0.1: resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} dependencies: - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: true optional: true @@ -10390,17 +10241,13 @@ packages: resolution: {integrity: sha512-7z/eR6O859gyWIAjuvBWFzNURmf2oPBmJlfVWkwehU5nzIyjwBsTh7WMmEEV4JFnHuQ3ex4oyTvfKzcyJVDBNA==} dev: false - /@types/cookie@0.6.0: - resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - dev: true - /@types/cookies@0.9.1: resolution: {integrity: sha512-E/DPgzifH4sM1UMadJMWd6mO2jOd4g1Ejwzx8/uRCDpJis1IrlyQEcGAYEomtAqRYmD5ORbNXMeI9U0RiVGZbg==} dependencies: '@types/connect': 3.4.38 '@types/express': 4.17.23 '@types/keygrip': 1.0.6 - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/cors@2.8.19: @@ -10485,7 +10332,7 @@ packages: /@types/es-aggregate-error@1.0.6: resolution: {integrity: sha512-qJ7LIFp06h1QE1aVxbVd+zJP2wdaugYXYfd6JxsyRMrYHaxb6itXPogW2tz+ylUJ1n1b+JF1PHyYCfYHm0dvUg==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true /@types/eslint-scope@3.7.7: @@ -10513,7 +10360,7 @@ packages: /@types/express-serve-static-core@4.19.6: resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} dependencies: - '@types/node': 22.14.0 + '@types/node': 20.14.9 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -10572,7 +10419,7 @@ packages: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/mdast@4.0.4: @@ -10638,12 +10485,6 @@ packages: undici-types: 6.19.8 dev: true - /@types/node@24.1.0: - resolution: {integrity: sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==} - dependencies: - undici-types: 7.8.0 - dev: true - /@types/prismjs@1.26.5: resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==} dev: false @@ -10670,36 +10511,30 @@ packages: '@types/prop-types': 15.7.15 csstype: 3.1.3 - /@types/react@19.1.8: - resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==} - dependencies: - csstype: 3.1.3 - dev: true - /@types/readable-stream@4.0.21: resolution: {integrity: sha512-19eKVv9tugr03IgfXlA9UVUVRbW6IuqRO5B92Dl4a6pT7K8uaGrNS0GkxiZD0BOk6PLuXl5FhWl//eX/pzYdTQ==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true /@types/readdir-glob@1.1.5: resolution: {integrity: sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true /@types/send@0.17.5: resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} dependencies: '@types/mime': 1.3.5 - '@types/node': 22.14.0 + '@types/node': 20.14.9 dev: false /@types/serve-static@1.15.8: resolution: {integrity: sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==} dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.14.0 + '@types/node': 20.14.9 '@types/send': 0.17.5 dev: false @@ -10710,13 +10545,13 @@ packages: /@types/ssh2-streams@0.1.12: resolution: {integrity: sha512-Sy8tpEmCce4Tq0oSOYdfqaBpA3hDM8SoxoFh5vzFsu2oL+znzGz8oVWW7xb4K920yYMUY+PIG31qZnFMfPWNCg==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true /@types/ssh2@0.5.52: resolution: {integrity: sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 '@types/ssh2-streams': 0.1.12 dev: true @@ -10726,14 +10561,6 @@ packages: '@types/node': 18.19.120 dev: true - /@types/statuses@2.0.6: - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} - dev: true - - /@types/tough-cookie@4.0.5: - resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - dev: true - /@types/unist@2.0.11: resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -10760,14 +10587,14 @@ packages: /@types/ws@8.18.1: resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true /@types/yauzl@2.10.3: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 24.1.0 + '@types/node': 20.14.9 dev: true optional: true @@ -10842,6 +10669,18 @@ packages: /@ungap/structured-clone@1.3.0: resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + /@unkey/api@2.0.0: + resolution: {integrity: sha512-hCC4D+RrkqrPg1EJ2PbCSiWnlnIveeGF5S3+EvOTP1J33CIzFYlDxO212oHffi317m1GSTojlF7qW4pgjhpLsQ==} + hasBin: true + peerDependencies: + '@modelcontextprotocol/sdk': '>=1.5.0 <1.10.0' + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + dependencies: + zod: 3.23.8 + dev: true + /@unkey/api@2.0.0-alpha.7(zod@3.23.8): resolution: {integrity: sha512-iiA+PVXn5T3dlZT8woKrnr0kB15XLtmkFWHV2+ox+980W/7vQLP1gdgcU/lrX/qA09Z+0w0wN+n0C88RLd4nvw==} hasBin: true @@ -12043,6 +11882,7 @@ packages: engines: {node: '>=10.16.0'} dependencies: streamsearch: 1.1.0 + dev: false /byline@5.0.0: resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} @@ -12218,7 +12058,7 @@ packages: engines: {node: '>= 16'} dev: true - /checkly@6.1.1(@types/node@24.1.0)(typescript@5.5.3): + /checkly@6.1.1(@types/node@20.14.9)(typescript@5.5.3): resolution: {integrity: sha512-NElnSoIQSPtn35LaC/cO9hJzn6x7bi8Xv5aUTOh6Q1aW7SP5HVew/A/RVmWCTJTEb/iI28iPWvzJ4BRdpUsxQw==} engines: {node: ^18.19.0 || >=20.5.0} hasBin: true @@ -12230,7 +12070,7 @@ packages: dependencies: '@oclif/core': 4.5.2 '@oclif/plugin-help': 6.2.31 - '@oclif/plugin-not-found': 3.2.60(@types/node@24.1.0) + '@oclif/plugin-not-found': 3.2.60(@types/node@20.14.9) '@oclif/plugin-plugins': 5.4.45 '@oclif/plugin-warn-if-update-available': 3.1.45 '@types/archiver': 6.0.3 @@ -12432,6 +12272,7 @@ packages: /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + dev: false /clipanion@3.2.1(typanion@3.14.0): resolution: {integrity: sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==} @@ -13618,7 +13459,7 @@ packages: engines: {node: '>=10.2.0'} dependencies: '@types/cors': 2.8.19 - '@types/node': 24.1.0 + '@types/node': 20.14.9 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -15747,10 +15588,6 @@ packages: space-separated-tokens: 2.0.2 dev: true - /headers-polyfill@4.0.3: - resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} - dev: true - /help-me@5.0.0: resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} dev: true @@ -15770,6 +15607,7 @@ packages: /hono@4.6.3: resolution: {integrity: sha512-0LeEuBNFeSHGqZ9sNVVgZjB1V5fmhkBSB0hZrpqStSMLOWgfLy0dHOvrjbJh0H2khsjet6rbHfWTHY0kpYThKQ==} engines: {node: '>=16.9.0'} + dev: false /hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} @@ -15990,11 +15828,11 @@ packages: react: '>=18.0.0' dependencies: cli-spinners: 2.9.2 - ink: 5.2.1(@types/react@19.1.8)(react@18.3.1) + ink: 5.2.1(@types/react@18.3.11)(react@18.3.1) react: 18.3.1 dev: true - /ink@5.2.1(@types/react@19.1.8)(react@18.3.1): + /ink@5.2.1(@types/react@18.3.11)(react@18.3.1): resolution: {integrity: sha512-BqcUyWrG9zq5HIwW6JcfFHsIYebJkWWb4fczNah1goUO0vv5vneIlfwuS85twyJ5hYR/y18FlAYUxrO9ChIWVg==} engines: {node: '>=18'} peerDependencies: @@ -16008,7 +15846,7 @@ packages: optional: true dependencies: '@alcalzone/ansi-tokenize': 0.1.3 - '@types/react': 19.1.8 + '@types/react': 18.3.11 ansi-escapes: 7.0.0 ansi-styles: 6.2.1 auto-bind: 5.0.1 @@ -16329,10 +16167,6 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - /is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} - dev: true - /is-number-object@1.1.1: resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} @@ -17856,12 +17690,12 @@ packages: minipass: 7.1.2 dev: true - /mintlify@4.2.31(@types/node@22.14.0)(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3): + /mintlify@4.2.31(@types/node@22.14.0)(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3): resolution: {integrity: sha512-DFDlm0KRUGcnaO2kAw3QpAIVXQ4qUy63OSOzwleKLN+sqJJJIc8cd5rfd98v5ORmPtf0YJJQGNX6SvsvIxOHCQ==} engines: {node: '>=18.0.0'} hasBin: true dependencies: - '@mintlify/cli': 4.0.635(@types/node@22.14.0)(@types/react@19.1.8)(react-dom@18.3.1)(typescript@5.7.3) + '@mintlify/cli': 4.0.635(@types/node@22.14.0)(@types/react@18.3.11)(react-dom@18.3.1)(typescript@5.7.3) transitivePeerDependencies: - '@types/node' - '@types/react' @@ -17974,40 +17808,6 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - /msw@2.8.7(@types/node@20.14.9)(typescript@5.7.3): - resolution: {integrity: sha512-0TGfV4oQiKpa3pDsQBDf0xvFP+sRrqEOnh2n1JWpHVKHJHLv6ZmY1HCZpCi7uDiJTeIHJMBpmBiRmBJN+ETPSQ==} - engines: {node: '>=18'} - hasBin: true - requiresBuild: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@bundled-es-modules/cookie': 2.0.1 - '@bundled-es-modules/statuses': 1.0.1 - '@bundled-es-modules/tough-cookie': 0.1.6 - '@inquirer/confirm': 5.1.13(@types/node@20.14.9) - '@mswjs/interceptors': 0.38.7 - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/until': 2.1.0 - '@types/cookie': 0.6.0 - '@types/statuses': 2.0.6 - graphql: 16.11.0 - headers-polyfill: 4.0.3 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - strict-event-emitter: 0.5.1 - type-fest: 4.41.0 - typescript: 5.7.3 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - dev: true - /mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true @@ -18092,7 +17892,7 @@ packages: engines: {node: '>= 0.4.0'} dev: true - /next-mdx-remote-client@1.1.1(@types/react@19.1.8)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1)(unified@11.0.5): + /next-mdx-remote-client@1.1.1(@types/react@18.3.11)(acorn@8.15.0)(react-dom@18.3.1)(react@18.3.1)(unified@11.0.5): resolution: {integrity: sha512-cJnJGaRiHc1gn4aCzDmY9zmcCjEw+zMCpCYIy45Kjs8HzeQpdGcaO5GrgIcX/DFkuCVrrzc69wi2gGnExXbv/A==} engines: {node: '>=18.18.0'} peerDependencies: @@ -18101,7 +17901,7 @@ packages: dependencies: '@babel/code-frame': 7.27.1 '@mdx-js/mdx': 3.1.0(acorn@8.15.0) - '@mdx-js/react': 3.1.0(@types/react@19.1.8)(react@18.3.1) + '@mdx-js/react': 3.1.0(@types/react@18.3.11)(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) remark-mdx-remove-esm: 1.2.0(unified@11.0.5) @@ -18214,6 +18014,7 @@ packages: transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + dev: false /next@14.2.25(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-N5M7xMc4wSb4IkPvEV5X2BRRXUmhVHNyaXwEM86+voXthSZz8ZiRyQW4p9mwAoAPIm6OzuVZtn7idgEJeAJN3Q==} @@ -18653,18 +18454,6 @@ packages: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} dev: true - /openapi-typescript@6.7.5: - resolution: {integrity: sha512-ZD6dgSZi0u1QCP55g8/2yS5hNJfIpgqsSGHLxxdOjvY7eIrXzj271FJEQw33VwsZ6RCtO/NOuhxa7GBWmEudyA==} - hasBin: true - dependencies: - ansi-colors: 4.1.3 - fast-glob: 3.3.3 - js-yaml: 4.1.0 - supports-color: 9.4.0 - undici: 5.29.0 - yargs-parser: 21.1.1 - dev: true - /openapi3-ts@4.5.0: resolution: {integrity: sha512-jaL+HgTq2Gj5jRcfdutgRGLosCy/hT8sQf6VOy+P+g36cZOjI1iukdPnijC+4CmeRzg/jEllJUboEic2FhxhtQ==} dependencies: @@ -18706,10 +18495,6 @@ packages: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} dev: true - /outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - dev: true - /own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -19230,6 +19015,7 @@ packages: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 + dev: false /postcss@8.4.35: resolution: {integrity: sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==} @@ -19429,7 +19215,7 @@ packages: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 24.1.0 + '@types/node': 20.14.9 long: 5.3.2 dev: true @@ -19460,12 +19246,6 @@ packages: /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - /psl@1.15.0: - resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} - dependencies: - punycode: 2.3.1 - dev: true - /public-ip@5.0.0: resolution: {integrity: sha512-xaH3pZMni/R2BG7ZXXaWS9Wc9wFlhyDVJF47IJ+3ali0TGv+2PsckKxbmo+rnx3ZxiV2wblVhtdS3bohAP6GGw==} engines: {node: ^14.13.1 || >=16.0.0} @@ -19551,6 +19331,7 @@ packages: /querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: false /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -19625,15 +19406,6 @@ packages: react: 18.3.1 scheduler: 0.23.2 - /react-dom@19.1.0(react@18.3.1): - resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} - peerDependencies: - react: ^19.1.0 - dependencies: - react: 18.3.1 - scheduler: 0.26.0 - dev: false - /react-element-to-jsx-string@15.0.0(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} peerDependencies: @@ -20275,12 +20047,13 @@ packages: /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: false - /resend@4.4.0(react-dom@19.1.0)(react@18.3.1): + /resend@4.4.0(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-SmVI3JCpgPNt4/m3Uy403LjoSeeleUE2X+KwPYQZcw+jiBCFsqL6vdf1r/XuQ7yOjvxYmlI8GD/oIWonFF9t9w==} engines: {node: '>=18'} dependencies: - '@react-email/render': 1.0.6(react-dom@19.1.0)(react@18.3.1) + '@react-email/render': 1.0.6(react-dom@18.3.1)(react@18.3.1) transitivePeerDependencies: - react - react-dom @@ -20568,10 +20341,6 @@ packages: dependencies: loose-envify: 1.4.0 - /scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} - dev: false - /schema-utils@4.3.2: resolution: {integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==} engines: {node: '>= 10.13.0'} @@ -21232,11 +21001,6 @@ packages: engines: {node: '>= 0.8'} dev: true - /statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - dev: true - /std-env@3.9.0: resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} dev: true @@ -21256,6 +21020,7 @@ packages: /streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + dev: false /streamx@2.22.1: resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} @@ -21266,10 +21031,6 @@ packages: bare-events: 2.6.0 dev: true - /strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - dev: true - /string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -21450,6 +21211,7 @@ packages: dependencies: client-only: 0.0.1 react: 18.3.1 + dev: false /sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} @@ -21499,11 +21261,6 @@ packages: dependencies: has-flag: 4.0.0 - /supports-color@9.4.0: - resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==} - engines: {node: '>=12'} - dev: true - /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -21921,16 +21678,6 @@ packages: engines: {node: '>=6'} dev: true - /tough-cookie@4.1.4: - resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} - engines: {node: '>=6'} - dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - dev: true - /tough-cookie@5.1.2: resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} engines: {node: '>=16'} @@ -22020,7 +21767,7 @@ packages: code-block-writer: 13.0.3 dev: false - /ts-node@10.9.1(@types/node@24.1.0)(typescript@5.5.3): + /ts-node@10.9.1(@types/node@20.14.9)(typescript@5.5.3): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -22039,7 +21786,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 24.1.0 + '@types/node': 20.14.9 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -22393,10 +22140,6 @@ packages: /undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - /undici-types@7.8.0: - resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - dev: true - /undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} @@ -22546,11 +22289,6 @@ packages: engines: {node: '>= 4.0.0'} dev: true - /universalify@0.2.0: - resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} - engines: {node: '>= 4.0.0'} - dev: true - /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} @@ -22586,6 +22324,7 @@ packages: dependencies: querystringify: 2.2.0 requires-port: 1.0.0 + dev: false /urlpattern-polyfill@10.0.0: resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==}