diff --git a/apps/dashboard/CHANGELOG.md b/apps/dashboard/CHANGELOG.md index 1eb8fec7b..ab40f851a 100644 --- a/apps/dashboard/CHANGELOG.md +++ b/apps/dashboard/CHANGELOG.md @@ -1,5 +1,11 @@ # @unkey/web +## 0.1.40 + +### Patch Changes + +- @unkey/ratelimit@0.5.1 + ## 0.1.39 ### Patch Changes diff --git a/apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx b/apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx index f94ecb0bd..72bfda765 100644 --- a/apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx +++ b/apps/dashboard/app/(app)/apis/[apiId]/keys/[keyAuthId]/[keyId]/page.tsx @@ -111,6 +111,9 @@ export default async function APIKeyDetailPage(props: { .then((res) => res.val?.at(0)?.time ?? 0), ]); + // Sort all verifications by time first + const sortedVerifications = verifications.val!.sort((a, b) => a.time - b.time); + const successOverTime: { x: string; y: number }[] = []; const ratelimitedOverTime: { x: string; y: number }[] = []; const usageExceededOverTime: { x: string; y: number }[] = []; @@ -119,30 +122,47 @@ export default async function APIKeyDetailPage(props: { const expiredOverTime: { x: string; y: number }[] = []; const forbiddenOverTime: { x: string; y: number }[] = []; - for (const d of verifications.val!.sort((a, b) => a.time - b.time)) { + // Get all unique timestamps + const uniqueDates = [...new Set(sortedVerifications.map((d) => d.time))].sort((a, b) => a - b); + + // Ensure each array has entries for all timestamps with zero counts + for (const timestamp of uniqueDates) { + const x = new Date(timestamp).toISOString(); + successOverTime.push({ x, y: 0 }); + ratelimitedOverTime.push({ x, y: 0 }); + usageExceededOverTime.push({ x, y: 0 }); + disabledOverTime.push({ x, y: 0 }); + insufficientPermissionsOverTime.push({ x, y: 0 }); + expiredOverTime.push({ x, y: 0 }); + forbiddenOverTime.push({ x, y: 0 }); + } + + for (const d of sortedVerifications) { const x = new Date(d.time).toISOString(); + const index = uniqueDates.indexOf(d.time); + switch (d.outcome) { case "": case "VALID": - successOverTime.push({ x, y: d.count }); + successOverTime[index] = { x, y: d.count }; break; case "RATE_LIMITED": - ratelimitedOverTime.push({ x, y: d.count }); + ratelimitedOverTime[index] = { x, y: d.count }; break; case "USAGE_EXCEEDED": - usageExceededOverTime.push({ x, y: d.count }); + usageExceededOverTime[index] = { x, y: d.count }; break; case "DISABLED": - disabledOverTime.push({ x, y: d.count }); + disabledOverTime[index] = { x, y: d.count }; break; case "INSUFFICIENT_PERMISSIONS": - insufficientPermissionsOverTime.push({ x, y: d.count }); + insufficientPermissionsOverTime[index] = { x, y: d.count }; break; case "EXPIRED": - expiredOverTime.push({ x, y: d.count }); + expiredOverTime[index] = { x, y: d.count }; break; case "FORBIDDEN": - forbiddenOverTime.push({ x, y: d.count }); + forbiddenOverTime[index] = { x, y: d.count }; break; } } @@ -209,6 +229,7 @@ export default async function APIKeyDetailPage(props: { stats.forbidden += v.count; } }); + const roleTee = key.workspace.roles.map((role) => { const nested: NestedPermissions = {}; for (const permission of key.workspace.permissions) { @@ -328,7 +349,7 @@ export default async function APIKeyDetailPage(props: { - + ) => { const { resolvedTheme } = useTheme(); - const colors: { light: Record; dark: Record } = { + const colors: { + light: Record; + dark: Record; + } = { light: { primary: "#1c1917", warn: "#FFCD07", @@ -133,9 +136,9 @@ export const LineChart: React.FC<{ tooltip={{ formatter: (datum) => ({ name: datum.category, - value: `${Intl.NumberFormat(undefined, { notation: "compact" }).format( - Number(datum.y), - )} ms`, + value: `${Intl.NumberFormat(undefined, { + notation: "compact", + }).format(Number(datum.y))} ms`, }), }} /> @@ -202,6 +205,53 @@ export const StackedColumnChart: React.FC<{ colors: Array; }> = ({ data, timeGranularity, colors }) => { const { axisColor } = useColors(colors); + + const formatDate = (date: string) => { + const d = new Date(date); + if (Number.isNaN(d.getTime())) { + return date; + } + + switch (timeGranularity) { + case "minute": + return d.toLocaleString(undefined, { + hour: "numeric", + minute: "2-digit", + hour12: true, + month: "short", + day: "numeric", + }); + case "hour": + return d.toLocaleString(undefined, { + hour: "numeric", + hour12: true, + month: "short", + day: "numeric", + year: "numeric", + }); + case "day": + return d.toLocaleString(undefined, { + weekday: "short", + month: "short", + day: "numeric", + year: "numeric", + }); + case "month": + return d.toLocaleString(undefined, { + month: "long", + year: "numeric", + }); + default: + return d.toLocaleString(undefined, { + month: "short", + day: "numeric", + year: "numeric", + hour: "numeric", + minute: "2-digit", + }); + } + }; + return ( ({ name: datum.category, - value: Intl.NumberFormat(undefined, { notation: "compact" }).format(Number(datum.y)), + value: Intl.NumberFormat(undefined, { + notation: "compact", + maximumFractionDigits: 1, + compactDisplay: "short", + }).format(Number(datum.y)), }), }} /> diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 8796f2eca..f1dec61d7 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@unkey/dashboard", - "version": "0.1.39", + "version": "0.1.40", "private": true, "scripts": { "dev": "next dev", diff --git a/packages/api/CHANGELOG.md b/packages/api/CHANGELOG.md index e0824693f..4cec01e33 100644 --- a/packages/api/CHANGELOG.md +++ b/packages/api/CHANGELOG.md @@ -1,5 +1,11 @@ # @unkey/api +## 0.30.0 + +### Minor Changes + +- 0746b33: Add the types for error codes + ## 0.29.0 ### Minor Changes diff --git a/packages/api/package.json b/packages/api/package.json index af6aa472c..1bb94cd86 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@unkey/api", - "version": "0.29.0", + "version": "0.30.0", "main": "./dist/index.js", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", @@ -9,12 +9,19 @@ "publishConfig": { "access": "public" }, - "keywords": ["unkey", "client", "api"], + "keywords": [ + "unkey", + "client", + "api" + ], "bugs": { "url": "https://github.com/unkeyed/unkey/issues" }, "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**", "README.md"], + "files": [ + "./dist/**", + "README.md" + ], "author": "Andreas Thomas ", "scripts": { "generate": "openapi-typescript https://api.unkey.dev/openapi.json -o ./src/openapi.d.ts", diff --git a/packages/api/src/errors.ts b/packages/api/src/errors.ts index 866ff1642..f04cedbeb 100644 --- a/packages/api/src/errors.ts +++ b/packages/api/src/errors.ts @@ -2,4 +2,10 @@ import type { paths } from "./openapi"; // this is what a json body response looks like export type ErrorResponse = - paths["/v1/liveness"]["get"]["responses"]["500"]["content"]["application/json"]; + | 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/hono/CHANGELOG.md b/packages/hono/CHANGELOG.md index 6f3b3d77d..00da89b88 100644 --- a/packages/hono/CHANGELOG.md +++ b/packages/hono/CHANGELOG.md @@ -1,5 +1,12 @@ # @unkey/hono +## 1.4.11 + +### Patch Changes + +- Updated dependencies [0746b33] + - @unkey/api@0.30.0 + ## 1.4.10 ### Patch Changes diff --git a/packages/hono/package.json b/packages/hono/package.json index 82c7598c6..fcabc2fa0 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@unkey/hono", - "version": "1.4.10", + "version": "1.4.11", "main": "./dist/index.js", "types": "./dist/index.d.ts", "license": "MIT", @@ -8,12 +8,19 @@ "publishConfig": { "access": "public" }, - "keywords": ["unkey", "client", "api", "hono"], + "keywords": [ + "unkey", + "client", + "api", + "hono" + ], "bugs": { "url": "https://github.com/unkeyed/unkey/issues" }, "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**"], + "files": [ + "./dist/**" + ], "author": "Andreas Thomas ", "scripts": { "build": "tsup", diff --git a/packages/nextjs/CHANGELOG.md b/packages/nextjs/CHANGELOG.md index 2c942a3bb..490cd960a 100644 --- a/packages/nextjs/CHANGELOG.md +++ b/packages/nextjs/CHANGELOG.md @@ -1,5 +1,12 @@ # @unkey/nextjs +## 0.18.4 + +### Patch Changes + +- Updated dependencies [0746b33] + - @unkey/api@0.30.0 + ## 0.18.3 ### Patch Changes diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index a8ada0e7a..11bdf331b 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@unkey/nextjs", - "version": "0.18.3", + "version": "0.18.4", "main": "./dist/index.js", "types": "./dist/index.d.ts", "license": "MIT", @@ -8,12 +8,19 @@ "publishConfig": { "access": "public" }, - "keywords": ["unkey", "client", "api"], + "keywords": [ + "unkey", + "client", + "api" + ], "bugs": { "url": "https://github.com/unkeyed/unkey/issues" }, "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**", "README.md"], + "files": [ + "./dist/**", + "README.md" + ], "author": "Andreas Thomas ", "scripts": { "build": "tsup" diff --git a/packages/ratelimit/CHANGELOG.md b/packages/ratelimit/CHANGELOG.md index b51453d18..e481e8bd8 100644 --- a/packages/ratelimit/CHANGELOG.md +++ b/packages/ratelimit/CHANGELOG.md @@ -1,5 +1,12 @@ # @unkey/ratelimit +## 0.5.1 + +### Patch Changes + +- Updated dependencies [0746b33] + - @unkey/api@0.30.0 + ## 0.5.0 ### Minor Changes diff --git a/packages/ratelimit/package.json b/packages/ratelimit/package.json index 8e1639e4b..fb5c5e100 100644 --- a/packages/ratelimit/package.json +++ b/packages/ratelimit/package.json @@ -1,6 +1,6 @@ { "name": "@unkey/ratelimit", - "version": "0.5.0", + "version": "0.5.1", "main": "./dist/index.js", "module": "./dist/index.mjs", "types": "./dist/index.d.ts", @@ -9,12 +9,20 @@ "publishConfig": { "access": "public" }, - "keywords": ["unkey", "ratelimit", "global", "serverless"], + "keywords": [ + "unkey", + "ratelimit", + "global", + "serverless" + ], "bugs": { "url": "https://github.com/unkeyed/unkey/issues" }, "homepage": "https://github.com/unkeyed/unkey#readme", - "files": ["./dist/**", "README.md"], + "files": [ + "./dist/**", + "README.md" + ], "author": "Andreas Thomas ", "scripts": { "build": "tsup"