@frogbotai/plugin-api-keys 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/ApiKeysManager.d.ts +3 -1
- package/dist/client/ApiKeysManager.d.ts.map +1 -1
- package/dist/client/ApiKeysManager.js +51 -14
- package/dist/client/ApiKeysManager.js.map +1 -1
- package/dist/client/ApiKeysManager.spec.js +65 -11
- package/dist/client/ApiKeysManager.spec.js.map +1 -1
- package/dist/client/CostUSD.d.ts +11 -0
- package/dist/client/CostUSD.d.ts.map +1 -0
- package/dist/client/CostUSD.js +19 -0
- package/dist/client/CostUSD.js.map +1 -0
- package/dist/client/CostUSD.spec.d.ts +2 -0
- package/dist/client/CostUSD.spec.d.ts.map +1 -0
- package/dist/client/CostUSD.spec.js +19 -0
- package/dist/client/CostUSD.spec.js.map +1 -0
- package/dist/client/styles.css +89 -0
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -0
- package/dist/client.js.map +1 -1
- package/dist/collection.d.ts +1 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +53 -7
- package/dist/collection.js.map +1 -1
- package/dist/fields.d.ts +3 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +46 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +120 -15
- package/dist/index.js.map +1 -1
- package/dist/policy.d.ts +45 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +76 -0
- package/dist/policy.js.map +1 -0
- package/dist/server/token.d.ts.map +1 -1
- package/dist/server/token.js +1 -1
- package/dist/server/token.js.map +1 -1
- package/package.json +11 -5
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import './styles.css';
|
|
1
2
|
export declare function ApiKeysManager(): import("react/jsx-runtime").JSX.Element;
|
|
2
|
-
export declare function RevokeApiKey({ rowData }: {
|
|
3
|
+
export declare function RevokeApiKey({ rowData, }: {
|
|
3
4
|
rowData: {
|
|
4
5
|
id: string | number;
|
|
6
|
+
name?: string;
|
|
5
7
|
revokedAt?: string | null;
|
|
6
8
|
};
|
|
7
9
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeysManager.d.ts","sourceRoot":"","sources":["../../src/client/ApiKeysManager.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ApiKeysManager.d.ts","sourceRoot":"","sources":["../../src/client/ApiKeysManager.tsx"],"names":[],"mappings":"AAKA,OAAO,cAAc,CAAC;AAItB,wBAAgB,cAAc,4CAsI7B;AAED,wBAAgB,YAAY,CAAC,EAC3B,OAAO,GACR,EAAE;IACD,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;CAC5E,2CA4DA"}
|
|
@@ -1,24 +1,35 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
3
|
-
import { Button, Modal, TextInput, useConfig, useListQuery, useModal } from '@payloadcms/ui';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Button, CopyIcon, Modal, TextInput, Tooltip, useConfig, useListQuery, useModal, useRouteCache } from '@payloadcms/ui';
|
|
4
4
|
import { useState } from 'react';
|
|
5
|
+
import './styles.css';
|
|
5
6
|
const modalSlug = 'create-api-key-modal';
|
|
6
7
|
export function ApiKeysManager() {
|
|
7
8
|
const { config } = useConfig();
|
|
8
|
-
const { collectionSlug
|
|
9
|
+
const { collectionSlug } = useListQuery();
|
|
9
10
|
const { closeModal, openModal } = useModal();
|
|
11
|
+
const { clearRouteCache } = useRouteCache();
|
|
10
12
|
const [name, setName] = useState('');
|
|
11
13
|
const [token, setToken] = useState();
|
|
12
14
|
const [error, setError] = useState();
|
|
13
15
|
const [loading, setLoading] = useState(false);
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
const [copied, setCopied] = useState(false);
|
|
17
|
+
const [hoveredControl, setHoveredControl] = useState();
|
|
18
|
+
function open() {
|
|
16
19
|
setName('');
|
|
17
20
|
setToken(undefined);
|
|
18
21
|
setError(undefined);
|
|
19
|
-
|
|
22
|
+
setCopied(false);
|
|
23
|
+
openModal(modalSlug);
|
|
24
|
+
}
|
|
25
|
+
function close() {
|
|
26
|
+
closeModal(modalSlug);
|
|
27
|
+
if (token)
|
|
28
|
+
clearRouteCache();
|
|
20
29
|
}
|
|
21
30
|
async function createKey() {
|
|
31
|
+
if (loading || !name.trim())
|
|
32
|
+
return;
|
|
22
33
|
setLoading(true);
|
|
23
34
|
setError(undefined);
|
|
24
35
|
const response = await fetch(`${config.routes.api}/${collectionSlug}/mint`, {
|
|
@@ -35,16 +46,40 @@ export function ApiKeysManager() {
|
|
|
35
46
|
setToken(result.token);
|
|
36
47
|
}
|
|
37
48
|
async function copyToken() {
|
|
38
|
-
if (token)
|
|
39
|
-
|
|
49
|
+
if (!token)
|
|
50
|
+
return;
|
|
51
|
+
await navigator.clipboard.writeText(token);
|
|
52
|
+
setCopied(true);
|
|
40
53
|
}
|
|
41
|
-
|
|
54
|
+
function copyHandlers(control) {
|
|
55
|
+
return {
|
|
56
|
+
onClick: copyToken,
|
|
57
|
+
onMouseEnter: () => {
|
|
58
|
+
setHoveredControl(control);
|
|
59
|
+
setCopied(false);
|
|
60
|
+
},
|
|
61
|
+
onMouseLeave: () => {
|
|
62
|
+
setHoveredControl(undefined);
|
|
63
|
+
setCopied(false);
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "secondary", margin: false, onClick: open, type: "button", children: "Create API key" }), _jsx(Modal, { className: "api-keys-modal", closeOnBlur: true, onClose: close, slug: modalSlug, children: _jsxs("div", { className: "api-keys-modal__wrapper", children: [_jsxs("div", { className: "api-keys-modal__content", children: [_jsx("h1", { children: "Create API Key" }), token ? (_jsxs(_Fragment, { children: [_jsx("p", { className: "api-keys-modal__warning", role: "alert", children: "Key generated! Copy it now \u2014 you won't see it again." }), _jsxs("div", { className: "api-keys-modal__token-row", children: [_jsxs("button", { "aria-label": "Click to copy API key", className: "api-keys-clear-button api-keys-modal__token", type: "button", ...copyHandlers('token'), children: [_jsx("code", { children: token }), _jsx(Tooltip, { delay: copied ? 0 : undefined, show: hoveredControl === 'token', children: copied ? 'Copied' : 'Click to copy' })] }), _jsxs("button", { "aria-label": "Copy API key", className: "api-keys-clear-button api-keys-slide-up-1 api-keys-modal__copy", type: "button", ...copyHandlers('icon'), children: [_jsx(CopyIcon, {}), _jsx(Tooltip, { delay: copied ? 0 : undefined, show: hoveredControl === 'icon', children: copied ? 'Copied' : 'Copy' })] })] })] })) : (_jsx(TextInput, { label: "Key name", path: "api-key-name", placeholder: "Key name (e.g. My MacBook CLI)", readOnly: loading, value: name, onChange: (event) => setName(event.target.value), onKeyDown: (event) => {
|
|
68
|
+
if (event.key === 'Enter') {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
void createKey();
|
|
71
|
+
}
|
|
72
|
+
} })), error ? _jsx("p", { role: "alert", children: error }) : null] }), _jsxs("div", { className: "api-keys-modal__controls", children: [_jsx(Button, { buttonStyle: "secondary", onClick: close, type: "button", children: token ? 'Close' : 'Dismiss' }), token ? null : (_jsx(Button, { disabled: loading || !name.trim(), onClick: createKey, type: "button", children: loading ? 'Generating…' : 'Generate' }))] })] }) })] }));
|
|
42
73
|
}
|
|
43
|
-
export function RevokeApiKey({ rowData }) {
|
|
74
|
+
export function RevokeApiKey({ rowData, }) {
|
|
44
75
|
const { config } = useConfig();
|
|
45
|
-
const { collectionSlug
|
|
76
|
+
const { collectionSlug } = useListQuery();
|
|
77
|
+
const { closeModal, openModal } = useModal();
|
|
78
|
+
const { clearRouteCache } = useRouteCache();
|
|
46
79
|
const [loading, setLoading] = useState(false);
|
|
80
|
+
const [revoked, setRevoked] = useState(false);
|
|
47
81
|
const [error, setError] = useState();
|
|
82
|
+
const confirmSlug = `revoke-api-key-modal-${rowData.id}`;
|
|
48
83
|
async function revoke() {
|
|
49
84
|
setLoading(true);
|
|
50
85
|
setError(undefined);
|
|
@@ -55,10 +90,12 @@ export function RevokeApiKey({ rowData }) {
|
|
|
55
90
|
setError(result.error ?? 'Unable to revoke API key');
|
|
56
91
|
return;
|
|
57
92
|
}
|
|
58
|
-
|
|
93
|
+
closeModal(confirmSlug);
|
|
94
|
+
setRevoked(true);
|
|
95
|
+
clearRouteCache();
|
|
59
96
|
}
|
|
60
|
-
if (rowData.revokedAt)
|
|
97
|
+
if (revoked || rowData.revokedAt)
|
|
61
98
|
return _jsx("span", { children: "Revoked" });
|
|
62
|
-
return (_jsxs(_Fragment, { children: [_jsx(Button, { buttonStyle: "secondary",
|
|
99
|
+
return (_jsxs(_Fragment, { children: [_jsx(Button, { margin: false, buttonStyle: "secondary", onClick: () => openModal(confirmSlug), size: "small", type: "button", children: "Revoke" }), _jsx(Modal, { className: "api-keys-modal", closeOnBlur: true, onClose: () => closeModal(confirmSlug), slug: confirmSlug, children: _jsxs("div", { className: "api-keys-modal__wrapper", children: [_jsxs("div", { className: "api-keys-modal__content", children: [_jsx("h1", { children: "Revoke API Key" }), _jsxs("p", { children: ["This will immediately disable ", rowData.name ?? 'this key', ". Any scripts or tools using this key will stop working. This cannot be undone."] }), error ? _jsx("p", { role: "alert", children: error }) : null] }), _jsxs("div", { className: "api-keys-modal__controls", children: [_jsx(Button, { buttonStyle: "secondary", onClick: () => closeModal(confirmSlug), type: "button", children: "Cancel" }), _jsx(Button, { disabled: loading, onClick: revoke, type: "button", children: loading ? 'Revoking…' : 'Revoke key' })] })] }) })] }));
|
|
63
100
|
}
|
|
64
101
|
//# sourceMappingURL=ApiKeysManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeysManager.js","sourceRoot":"","sources":["../../src/client/ApiKeysManager.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ApiKeysManager.js","sourceRoot":"","sources":["../../src/client/ApiKeysManager.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,14 +3,17 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
|
3
3
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
4
|
const closeModal = vi.fn();
|
|
5
5
|
const openModal = vi.fn();
|
|
6
|
-
const
|
|
6
|
+
const clearRouteCache = vi.fn();
|
|
7
7
|
vi.mock('@payloadcms/ui', () => ({
|
|
8
8
|
Button: ({ children, ...props }) => _jsx("button", { ...props, children: children }),
|
|
9
|
-
|
|
9
|
+
CopyIcon: () => _jsx("svg", { "data-testid": "copy-icon" }),
|
|
10
|
+
Modal: ({ children, className }) => _jsx("div", { className: className, role: "dialog", children: children }),
|
|
10
11
|
TextInput: ({ label, ...props }) => _jsx("input", { "aria-label": label, ...props }),
|
|
12
|
+
Tooltip: ({ children, show }) => (show ? _jsx("span", { children: children }) : null),
|
|
11
13
|
useConfig: () => ({ config: { routes: { api: '/api' } } }),
|
|
12
|
-
useListQuery: () => ({ collectionSlug: 'api-keys'
|
|
14
|
+
useListQuery: () => ({ collectionSlug: 'api-keys' }),
|
|
13
15
|
useModal: () => ({ closeModal, openModal }),
|
|
16
|
+
useRouteCache: () => ({ clearRouteCache }),
|
|
14
17
|
}));
|
|
15
18
|
const { ApiKeysManager, RevokeApiKey } = await import('./ApiKeysManager.js');
|
|
16
19
|
describe('API key controls', () => {
|
|
@@ -25,27 +28,78 @@ describe('API key controls', () => {
|
|
|
25
28
|
json: () => Promise.resolve({ token: 'frogbot_secret' }),
|
|
26
29
|
});
|
|
27
30
|
render(_jsx(ApiKeysManager, {}));
|
|
28
|
-
|
|
31
|
+
expect(screen.getByRole('dialog').className).toBe('api-keys-modal');
|
|
32
|
+
fireEvent.click(screen.getByRole('button', { name: 'Create API key' }));
|
|
29
33
|
expect(openModal).toHaveBeenCalledWith('create-api-key-modal');
|
|
30
34
|
fireEvent.change(screen.getByLabelText('Key name'), { target: { value: 'Deploy' } });
|
|
31
|
-
fireEvent.click(screen.
|
|
32
|
-
expect(await screen.findByText(
|
|
33
|
-
expect(screen.
|
|
35
|
+
fireEvent.click(screen.getByRole('button', { name: 'Generate' }));
|
|
36
|
+
expect(await screen.findByText("Key generated! Copy it now — you won't see it again.")).toBeTruthy();
|
|
37
|
+
expect(screen.getByText('frogbot_secret')).toBeTruthy();
|
|
34
38
|
expect(fetch).toHaveBeenCalledWith('/api/api-keys/mint', expect.objectContaining({
|
|
35
39
|
body: JSON.stringify({ name: 'Deploy' }),
|
|
36
40
|
method: 'POST',
|
|
37
41
|
}));
|
|
42
|
+
fireEvent.click(screen.getByRole('button', { name: 'Close' }));
|
|
43
|
+
expect(closeModal).toHaveBeenCalledWith('create-api-key-modal');
|
|
44
|
+
expect(clearRouteCache).toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
it('generates on Enter in the key name input', async () => {
|
|
47
|
+
vi.mocked(fetch).mockResolvedValue({
|
|
48
|
+
ok: true,
|
|
49
|
+
json: () => Promise.resolve({ token: 'frogbot_secret' }),
|
|
50
|
+
});
|
|
51
|
+
render(_jsx(ApiKeysManager, {}));
|
|
52
|
+
fireEvent.change(screen.getByLabelText('Key name'), { target: { value: 'Deploy' } });
|
|
53
|
+
fireEvent.keyDown(screen.getByLabelText('Key name'), { key: 'Enter' });
|
|
54
|
+
expect(await screen.findByText('frogbot_secret')).toBeTruthy();
|
|
55
|
+
});
|
|
56
|
+
it('ignores Enter when the name is empty', () => {
|
|
57
|
+
render(_jsx(ApiKeysManager, {}));
|
|
58
|
+
fireEvent.keyDown(screen.getByLabelText('Key name'), { key: 'Enter' });
|
|
59
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
60
|
+
});
|
|
61
|
+
it('copies the token with feedback', async () => {
|
|
62
|
+
vi.mocked(fetch).mockResolvedValue({
|
|
63
|
+
ok: true,
|
|
64
|
+
json: () => Promise.resolve({ token: 'frogbot_secret' }),
|
|
65
|
+
});
|
|
66
|
+
render(_jsx(ApiKeysManager, {}));
|
|
67
|
+
fireEvent.change(screen.getByLabelText('Key name'), { target: { value: 'Deploy' } });
|
|
68
|
+
fireEvent.click(screen.getByRole('button', { name: 'Generate' }));
|
|
69
|
+
await screen.findByText('frogbot_secret');
|
|
70
|
+
fireEvent.mouseEnter(screen.getByRole('button', { name: 'Copy API key' }));
|
|
71
|
+
fireEvent.click(screen.getByRole('button', { name: 'Copy API key' }));
|
|
72
|
+
await waitFor(() => expect(screen.getByText('Copied')).toBeTruthy());
|
|
73
|
+
expect(navigator.clipboard.writeText).toHaveBeenCalledWith('frogbot_secret');
|
|
74
|
+
expect(screen.getByTestId('copy-icon')).toBeTruthy();
|
|
75
|
+
});
|
|
76
|
+
it('does not clear the route cache when dismissed without a key', () => {
|
|
77
|
+
render(_jsx(ApiKeysManager, {}));
|
|
38
78
|
fireEvent.click(screen.getByRole('button', { name: 'Dismiss' }));
|
|
39
79
|
expect(closeModal).toHaveBeenCalledWith('create-api-key-modal');
|
|
40
|
-
expect(
|
|
80
|
+
expect(clearRouteCache).not.toHaveBeenCalled();
|
|
41
81
|
});
|
|
42
|
-
it('
|
|
82
|
+
it('confirms before revoking an active key', async () => {
|
|
43
83
|
vi.mocked(fetch).mockResolvedValue({ ok: true });
|
|
44
|
-
render(_jsx(RevokeApiKey, { rowData: { id: 'key-1' } }));
|
|
84
|
+
render(_jsx(RevokeApiKey, { rowData: { id: 'key-1', name: 'Deploy' } }));
|
|
45
85
|
fireEvent.click(screen.getByRole('button', { name: 'Revoke' }));
|
|
46
|
-
|
|
86
|
+
expect(openModal).toHaveBeenCalledWith('revoke-api-key-modal-key-1');
|
|
87
|
+
expect(screen.getByText('This will immediately disable Deploy. Any scripts or tools using this key will stop working. This cannot be undone.')).toBeTruthy();
|
|
88
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
89
|
+
fireEvent.click(screen.getByRole('button', { name: 'Revoke key' }));
|
|
90
|
+
await waitFor(() => expect(screen.getByText('Revoked')).toBeTruthy());
|
|
91
|
+
expect(closeModal).toHaveBeenCalledWith('revoke-api-key-modal-key-1');
|
|
92
|
+
expect(clearRouteCache).toHaveBeenCalled();
|
|
47
93
|
expect(fetch).toHaveBeenCalledWith('/api/api-keys/key-1/revoke', { method: 'POST' });
|
|
48
94
|
});
|
|
95
|
+
it('cancels revocation without calling the endpoint', () => {
|
|
96
|
+
render(_jsx(RevokeApiKey, { rowData: { id: 'key-1', name: 'Deploy' } }));
|
|
97
|
+
fireEvent.click(screen.getByRole('button', { name: 'Revoke' }));
|
|
98
|
+
fireEvent.click(screen.getByRole('button', { name: 'Cancel' }));
|
|
99
|
+
expect(closeModal).toHaveBeenCalledWith('revoke-api-key-modal-key-1');
|
|
100
|
+
expect(fetch).not.toHaveBeenCalled();
|
|
101
|
+
expect(screen.getByRole('button', { name: 'Revoke' })).toBeTruthy();
|
|
102
|
+
});
|
|
49
103
|
it('shows revoked keys without an action', () => {
|
|
50
104
|
render(_jsx(RevokeApiKey, { rowData: { id: 'key-1', revokedAt: '2026-07-29' } }));
|
|
51
105
|
expect(screen.getByText('Revoked')).toBeTruthy();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiKeysManager.spec.js","sourceRoot":"","sources":["../../src/client/ApiKeysManager.spec.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAE5E,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9D,MAAM,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAC3B,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;AAC1B,MAAM,
|
|
1
|
+
{"version":3,"file":"ApiKeysManager.spec.js","sourceRoot":"","sources":["../../src/client/ApiKeysManager.spec.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function formatCostUSD(value: unknown): string;
|
|
2
|
+
export declare function CostUSDCell({ cellData }: {
|
|
3
|
+
cellData?: unknown;
|
|
4
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function CostUSDField({ field, path }: {
|
|
6
|
+
field: {
|
|
7
|
+
label?: string;
|
|
8
|
+
};
|
|
9
|
+
path: string;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=CostUSD.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostUSD.d.ts","sourceRoot":"","sources":["../../src/client/CostUSD.tsx"],"names":[],"mappings":"AAIA,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAOpD;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,2CAE/D;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAAE,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,2CASxF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { FieldLabel, useField } from '@payloadcms/ui';
|
|
4
|
+
export function formatCostUSD(value) {
|
|
5
|
+
return new Intl.NumberFormat('en-US', {
|
|
6
|
+
style: 'currency',
|
|
7
|
+
currency: 'USD',
|
|
8
|
+
minimumFractionDigits: 2,
|
|
9
|
+
maximumFractionDigits: 6,
|
|
10
|
+
}).format(typeof value === 'number' ? value : 0);
|
|
11
|
+
}
|
|
12
|
+
export function CostUSDCell({ cellData }) {
|
|
13
|
+
return _jsx("span", { children: formatCostUSD(cellData) });
|
|
14
|
+
}
|
|
15
|
+
export function CostUSDField({ field, path }) {
|
|
16
|
+
const { value } = useField({ path });
|
|
17
|
+
return (_jsxs("div", { className: "field-type number", children: [_jsx(FieldLabel, { label: field.label, path: path }), _jsx("div", { children: formatCostUSD(value) })] }));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=CostUSD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostUSD.js","sourceRoot":"","sources":["../../src/client/CostUSD.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,IAAI,IAAI,CAAC,YAAY,CAAC,OAAO,EAAE;QACpC,KAAK,EAAE,UAAU;QACjB,QAAQ,EAAE,KAAK;QACf,qBAAqB,EAAE,CAAC;QACxB,qBAAqB,EAAE,CAAC;KACzB,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAA0B;IAC9D,OAAO,yBAAO,aAAa,CAAC,QAAQ,CAAC,GAAQ,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAA+C;IACvF,MAAM,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,OAAO,CACL,eAAK,SAAS,EAAC,mBAAmB,aAChC,KAAC,UAAU,IAAC,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,GAAI,EAC9C,wBAAM,aAAa,CAAC,KAAK,CAAC,GAAO,IAC7B,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostUSD.spec.d.ts","sourceRoot":"","sources":["../../src/client/CostUSD.spec.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
vi.mock('@payloadcms/ui', () => ({
|
|
5
|
+
FieldLabel: () => null,
|
|
6
|
+
useField: () => ({ value: 0 }),
|
|
7
|
+
}));
|
|
8
|
+
const { CostUSDCell, formatCostUSD } = await import('./CostUSD.js');
|
|
9
|
+
describe('USD cost formatting', () => {
|
|
10
|
+
it('formats dollars with sub-cent precision', () => {
|
|
11
|
+
expect(formatCostUSD(12.5)).toBe('$12.50');
|
|
12
|
+
expect(formatCostUSD(0.000322618)).toBe('$0.000323');
|
|
13
|
+
});
|
|
14
|
+
it('renders formatted list cells', () => {
|
|
15
|
+
render(_jsx(CostUSDCell, { cellData: 1.2345678 }));
|
|
16
|
+
expect(screen.getByText('$1.234568')).toBeTruthy();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=CostUSD.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CostUSD.spec.js","sourceRoot":"","sources":["../../src/client/CostUSD.spec.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAElD,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/B,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI;IACtB,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;CAC/B,CAAC,CAAC,CAAC;AAEJ,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;AAEpE,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,CAAC,KAAC,WAAW,IAAC,QAAQ,EAAE,SAAS,GAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
.api-keys-modal {
|
|
2
|
+
align-items: center;
|
|
3
|
+
backdrop-filter: blur(8px);
|
|
4
|
+
background: color-mix(in srgb, var(--theme-elevation-0) 80%, transparent);
|
|
5
|
+
display: flex;
|
|
6
|
+
height: 100%;
|
|
7
|
+
justify-content: center;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.api-keys-modal__wrapper {
|
|
11
|
+
background: var(--theme-elevation-50);
|
|
12
|
+
border: 1px solid var(--theme-elevation-150);
|
|
13
|
+
border-radius: var(--style-radius-m);
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: column;
|
|
16
|
+
gap: 24px;
|
|
17
|
+
max-width: 720px;
|
|
18
|
+
padding: 32px;
|
|
19
|
+
position: relative;
|
|
20
|
+
width: min(90vw, 720px);
|
|
21
|
+
z-index: 1;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.api-keys-modal__content {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
gap: 12px;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.api-keys-modal__content > * {
|
|
31
|
+
margin: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.api-keys-modal__warning {
|
|
35
|
+
color: var(--theme-success-500);
|
|
36
|
+
font-weight: 600;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.api-keys-modal__token-row {
|
|
40
|
+
align-items: center;
|
|
41
|
+
background: var(--theme-elevation-0);
|
|
42
|
+
border: 1px solid var(--theme-elevation-150);
|
|
43
|
+
border-radius: var(--style-radius-m);
|
|
44
|
+
display: flex;
|
|
45
|
+
gap: 8px;
|
|
46
|
+
padding: 4px 4px 4px 16px;
|
|
47
|
+
transition: border-color 200ms ease-out;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.api-keys-modal__token-row:hover {
|
|
51
|
+
border-color: var(--theme-elevation-400);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.api-keys-modal__token {
|
|
55
|
+
flex: 1;
|
|
56
|
+
overflow-wrap: anywhere;
|
|
57
|
+
padding: 8px 0;
|
|
58
|
+
position: relative;
|
|
59
|
+
text-align: left;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.api-keys-modal__copy {
|
|
63
|
+
padding: 9px;
|
|
64
|
+
position: relative;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.api-keys-modal__controls {
|
|
68
|
+
display: flex;
|
|
69
|
+
gap: 12px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.api-keys-clear-button {
|
|
73
|
+
background: none;
|
|
74
|
+
border: none;
|
|
75
|
+
box-shadow: none;
|
|
76
|
+
box-sizing: border-box;
|
|
77
|
+
cursor: pointer;
|
|
78
|
+
line-height: 1;
|
|
79
|
+
margin: 0;
|
|
80
|
+
outline: none;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.api-keys-slide-up-1 {
|
|
84
|
+
transition: transform 200ms ease-out;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.api-keys-slide-up-1:hover {
|
|
88
|
+
transform: translateY(-4px);
|
|
89
|
+
}
|
package/dist/client.d.ts
CHANGED
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/client.js
CHANGED
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/collection.d.ts
CHANGED
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAmC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAmC,MAAM,SAAS,CAAC;AAKjF,KAAK,iBAAiB,GAAG;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AAgFF,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,GAAG,gBAAgB,CA2GpF"}
|
package/dist/collection.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createApiKeyToken, getApiKeyPrefix, hashApiKeyToken } from './server/token.js';
|
|
2
|
+
import { createPolicyFields } from './fields.js';
|
|
2
3
|
function mergeFields(...groups) {
|
|
3
4
|
const fields = new Map();
|
|
4
5
|
for (const group of groups) {
|
|
@@ -75,18 +76,62 @@ function createEndpoints({ collectionSlug, tokenPrefix }) {
|
|
|
75
76
|
];
|
|
76
77
|
}
|
|
77
78
|
export function createApiKeysCollection(options) {
|
|
78
|
-
const { authCollection, collectionSlug, collection, existing } = options;
|
|
79
|
+
const { authCollection, collectionSlug, collection, existing, usageCollection } = options;
|
|
79
80
|
const ownerAccess = ({ req }) => {
|
|
80
81
|
const owner = getOwnerID(req);
|
|
81
82
|
return owner === null ? false : { owner: { equals: owner } };
|
|
82
83
|
};
|
|
83
84
|
const fields = [
|
|
84
85
|
{ name: 'name', type: 'text', required: true },
|
|
85
|
-
{ name: 'owner', type: 'relationship', relationTo: authCollection, required: true, index: true },
|
|
86
|
-
{ name: 'prefix', type: 'text', required: true, index: true, admin: { readOnly: true } },
|
|
87
|
-
{ name: 'tokenHash', type: 'text', required: true, unique: true, index: true, access: { read: () => false }, admin: { hidden: true } },
|
|
88
|
-
{ name: 'lastUsedAt', type: 'date', admin: { readOnly: true } },
|
|
89
|
-
|
|
86
|
+
{ name: 'owner', type: 'relationship', relationTo: authCollection, required: true, index: true, access: { update: () => false } },
|
|
87
|
+
{ name: 'prefix', type: 'text', required: true, index: true, access: { update: () => false }, admin: { readOnly: true } },
|
|
88
|
+
{ name: 'tokenHash', type: 'text', required: true, unique: true, index: true, access: { read: () => false, update: () => false }, admin: { hidden: true } },
|
|
89
|
+
{ name: 'lastUsedAt', type: 'date', access: { update: () => false }, admin: { readOnly: true } },
|
|
90
|
+
...createPolicyFields(true),
|
|
91
|
+
{
|
|
92
|
+
name: 'revokedAt',
|
|
93
|
+
type: 'date',
|
|
94
|
+
index: true,
|
|
95
|
+
access: { update: () => false },
|
|
96
|
+
admin: { readOnly: true, condition: (_, siblingData) => Boolean(siblingData.revokedAt) },
|
|
97
|
+
},
|
|
98
|
+
...(usageCollection
|
|
99
|
+
? [
|
|
100
|
+
{
|
|
101
|
+
name: 'totalCostUSD',
|
|
102
|
+
type: 'number',
|
|
103
|
+
label: 'Total Cost (USD)',
|
|
104
|
+
virtual: true,
|
|
105
|
+
admin: {
|
|
106
|
+
readOnly: true,
|
|
107
|
+
components: {
|
|
108
|
+
Cell: '@frogbotai/plugin-api-keys/client#CostUSDCell',
|
|
109
|
+
Field: '@frogbotai/plugin-api-keys/client#CostUSDField',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
hooks: {
|
|
113
|
+
afterRead: [
|
|
114
|
+
async ({ data, req }) => {
|
|
115
|
+
if (data?.id === undefined)
|
|
116
|
+
return 0;
|
|
117
|
+
const result = await req.frogbot.find({
|
|
118
|
+
collection: usageCollection,
|
|
119
|
+
depth: 0,
|
|
120
|
+
overrideAccess: true,
|
|
121
|
+
pagination: false,
|
|
122
|
+
req,
|
|
123
|
+
where: { apiKey: { equals: data.id } },
|
|
124
|
+
});
|
|
125
|
+
return result.docs.reduce((total, doc) => {
|
|
126
|
+
const cost = doc.costUSD;
|
|
127
|
+
return total + (typeof cost === 'number' ? cost : 0);
|
|
128
|
+
}, 0);
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
]
|
|
134
|
+
: []),
|
|
90
135
|
{
|
|
91
136
|
name: 'actions',
|
|
92
137
|
type: 'ui',
|
|
@@ -104,7 +149,7 @@ export function createApiKeysCollection(options) {
|
|
|
104
149
|
create: () => false,
|
|
105
150
|
delete: () => false,
|
|
106
151
|
read: ownerAccess,
|
|
107
|
-
update:
|
|
152
|
+
update: ownerAccess,
|
|
108
153
|
...existing?.access,
|
|
109
154
|
...collection?.access,
|
|
110
155
|
},
|
|
@@ -115,6 +160,7 @@ export function createApiKeysCollection(options) {
|
|
|
115
160
|
defaultColumns: collection?.admin?.defaultColumns ?? existing?.admin?.defaultColumns ?? [
|
|
116
161
|
'name',
|
|
117
162
|
'prefix',
|
|
163
|
+
...(usageCollection ? ['totalCostUSD'] : []),
|
|
118
164
|
'lastUsedAt',
|
|
119
165
|
'revokedAt',
|
|
120
166
|
'actions',
|
package/dist/collection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AA0BrC,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,OAAO,GAAG,KAAK,EAAE,CAqBjE"}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { canField } from '@frogbotai/plugin-roles';
|
|
2
|
+
const manage = canField('budgets:manage');
|
|
3
|
+
function policyField(name, value) {
|
|
4
|
+
return {
|
|
5
|
+
name,
|
|
6
|
+
type: 'group',
|
|
7
|
+
access: { update: manage },
|
|
8
|
+
fields: [
|
|
9
|
+
{
|
|
10
|
+
name: 'mode',
|
|
11
|
+
type: 'select',
|
|
12
|
+
defaultValue: 'inherit',
|
|
13
|
+
required: true,
|
|
14
|
+
options: ['inherit', 'custom', 'unlimited'],
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
...value,
|
|
18
|
+
name: 'value',
|
|
19
|
+
admin: { ...value.admin, condition: (_, siblingData) => siblingData.mode === 'custom' },
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export function createPolicyFields(includeState) {
|
|
25
|
+
return [
|
|
26
|
+
policyField('monthlyBudget', { name: 'value', type: 'number', min: 0 }),
|
|
27
|
+
policyField('rpm', { name: 'value', type: 'number', min: 1 }),
|
|
28
|
+
policyField('tpm', { name: 'value', type: 'number', min: 1 }),
|
|
29
|
+
policyField('models', { name: 'value', type: 'json' }),
|
|
30
|
+
{
|
|
31
|
+
name: 'budgetBehavior',
|
|
32
|
+
type: 'select',
|
|
33
|
+
defaultValue: 'block',
|
|
34
|
+
options: ['block', 'alert-only'],
|
|
35
|
+
access: { update: manage },
|
|
36
|
+
},
|
|
37
|
+
...(includeState
|
|
38
|
+
? [
|
|
39
|
+
{ name: 'spendThisPeriodUSD', type: 'number', defaultValue: 0, access: { update: () => false }, admin: { readOnly: true } },
|
|
40
|
+
{ name: 'budgetPeriodStartedAt', type: 'date', access: { update: () => false }, admin: { readOnly: true } },
|
|
41
|
+
{ name: 'budgetAlertsSent', type: 'json', access: { update: () => false }, admin: { hidden: true } },
|
|
42
|
+
]
|
|
43
|
+
: []),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAGnD,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC,CAAC;AAE1C,SAAS,WAAW,CAAC,IAAY,EAAE,KAAY;IAC7C,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;QAC1B,MAAM,EAAE;YACN;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,QAAQ;gBACd,YAAY,EAAE,SAAS;gBACvB,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC;aAC5C;YACD;gBACE,GAAG,KAAK;gBACR,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE;aACxF;SACF;KACO,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,YAAqB;IACtD,OAAO;QACL,WAAW,CAAC,eAAe,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QACvE,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAC7D,WAAW,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;QAC7D,WAAW,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACtD;YACE,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,QAAQ;YACd,YAAY,EAAE,OAAO;YACrB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC;YAChC,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;SAC3B;QACD,GAAG,CAAC,YAAY;YACd,CAAC,CAAC;gBACE,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,QAAiB,EAAE,YAAY,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;gBACpI,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,MAAe,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;gBACpH,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAe,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;aAC9G;YACH,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CollectionConfig, Plugin } from 'frogbot';
|
|
2
2
|
export type { ApiKeyHeaderOptions, ApiKeyTokenOptions } from './server/token.js';
|
|
3
|
+
export type { EffectivePolicy, PolicyDefaults, PolicyDocument, PolicyMode, PolicyValue } from './policy.js';
|
|
3
4
|
export { createApiKeyToken, extractApiKeyToken, getApiKeyPrefix, hashApiKeyToken, } from './server/token.js';
|
|
4
5
|
export type ApiKeysPluginOptions = {
|
|
5
6
|
authCollection?: string;
|
|
@@ -7,6 +8,12 @@ export type ApiKeysPluginOptions = {
|
|
|
7
8
|
tokenPrefix?: string;
|
|
8
9
|
headerNames?: string[];
|
|
9
10
|
collection?: Partial<CollectionConfig>;
|
|
11
|
+
defaults?: import('./policy.js').PolicyDefaults;
|
|
12
|
+
alerts?: {
|
|
13
|
+
webhookURL: string;
|
|
14
|
+
thresholds?: number[];
|
|
15
|
+
headers?: Record<string, string>;
|
|
16
|
+
};
|
|
10
17
|
};
|
|
11
18
|
export declare function apiKeysPlugin(options?: ApiKeysPluginOptions): Plugin;
|
|
12
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAUxD,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC5G,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,oBAAoB,GAAG;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,aAAa,EAAE,cAAc,CAAC;IAChD,MAAM,CAAC,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClC,CAAC;CACH,CAAC;AAQF,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,MAAM,CAwKxE"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
|
+
import { calculateModelCostUSD } from '@frogbotai/gateway';
|
|
2
|
+
import { BudgetExceededError, ModelNotAllowedError, RateLimitExceededError } from '@frogbotai/gateway/errors';
|
|
1
3
|
import { createApiKeysCollection } from './collection.js';
|
|
4
|
+
import { createPolicyFields } from './fields.js';
|
|
5
|
+
import { SerialQueue, SlidingWindowRateLimiter, resolvePolicy } from './policy.js';
|
|
2
6
|
import { createApiKeyStrategy } from './strategy.js';
|
|
3
7
|
export { createApiKeyToken, extractApiKeyToken, getApiKeyPrefix, hashApiKeyToken, } from './server/token.js';
|
|
4
8
|
export function apiKeysPlugin(options = {}) {
|
|
9
|
+
for (const [name, value] of Object.entries(options.defaults ?? {})) {
|
|
10
|
+
if (name !== 'models' && name !== 'budgetBehavior' && (typeof value !== 'number' || !Number.isFinite(value) || value < 0))
|
|
11
|
+
throw new Error(`[plugin-api-keys] Default '${name}' must be a non-negative finite number.`);
|
|
12
|
+
}
|
|
13
|
+
if ((options.defaults?.rpm !== undefined && options.defaults.rpm < 1) || (options.defaults?.tpm !== undefined && options.defaults.tpm < 1))
|
|
14
|
+
throw new Error('[plugin-api-keys] RPM and TPM defaults must be at least 1.');
|
|
15
|
+
if (options.defaults?.budgetBehavior !== undefined && !['block', 'alert-only'].includes(options.defaults.budgetBehavior))
|
|
16
|
+
throw new Error('[plugin-api-keys] Budget behavior must be block or alert-only.');
|
|
17
|
+
if (options.defaults?.models?.some((model) => !model.includes('/')))
|
|
18
|
+
throw new Error('[plugin-api-keys] Default models must use provider/model IDs.');
|
|
19
|
+
if (options.alerts && !options.alerts.webhookURL)
|
|
20
|
+
throw new Error('[plugin-api-keys] Alert webhookURL is required.');
|
|
21
|
+
if (options.alerts?.thresholds?.some((threshold) => !Number.isFinite(threshold) || threshold <= 0 || threshold > 1))
|
|
22
|
+
throw new Error('[plugin-api-keys] Alert thresholds must be greater than 0 and at most 1.');
|
|
23
|
+
const limiter = new SlidingWindowRateLimiter();
|
|
24
|
+
const queue = new SerialQueue();
|
|
5
25
|
return (config) => {
|
|
6
26
|
const authCollection = options.authCollection ?? 'users';
|
|
7
27
|
const collectionSlug = options.collectionSlug ?? 'api-keys';
|
|
@@ -9,11 +29,23 @@ export function apiKeysPlugin(options = {}) {
|
|
|
9
29
|
if (!auth || auth.auth === undefined || auth.auth === false) {
|
|
10
30
|
throw new Error(`[plugin-api-keys] Auth collection '${authCollection}' must exist and have auth enabled.`);
|
|
11
31
|
}
|
|
32
|
+
const reservedPolicyFields = new Set(['monthlyBudget', 'rpm', 'tpm', 'models', 'budgetBehavior', 'spendThisPeriodUSD', 'budgetPeriodStartedAt', 'budgetAlertsSent']);
|
|
33
|
+
const collision = auth.fields.find((field) => 'name' in field && reservedPolicyFields.has(field.name));
|
|
34
|
+
if (collision && 'name' in collision)
|
|
35
|
+
throw new Error(`[plugin-api-keys] Auth field '${collision.name}' is reserved.`);
|
|
12
36
|
const existing = config.collections.find((collection) => collection.slug === collectionSlug);
|
|
37
|
+
const usageLog = config.ai
|
|
38
|
+
? config.collections.find((item) => item.usageLog === true) ?? {
|
|
39
|
+
slug: 'usage-logs',
|
|
40
|
+
usageLog: true,
|
|
41
|
+
fields: [],
|
|
42
|
+
}
|
|
43
|
+
: undefined;
|
|
13
44
|
const collection = createApiKeysCollection({
|
|
14
45
|
authCollection,
|
|
15
46
|
collectionSlug,
|
|
16
|
-
tokenPrefix: options.tokenPrefix ?? '
|
|
47
|
+
tokenPrefix: options.tokenPrefix ?? 'fb',
|
|
48
|
+
usageCollection: usageLog?.slug,
|
|
17
49
|
collection: options.collection,
|
|
18
50
|
existing,
|
|
19
51
|
});
|
|
@@ -21,15 +53,8 @@ export function apiKeysPlugin(options = {}) {
|
|
|
21
53
|
authCollection,
|
|
22
54
|
collectionSlug,
|
|
23
55
|
headerNames: options.headerNames,
|
|
24
|
-
tokenPrefix: options.tokenPrefix ?? '
|
|
56
|
+
tokenPrefix: options.tokenPrefix ?? 'fb',
|
|
25
57
|
});
|
|
26
|
-
const usageLog = config.ai
|
|
27
|
-
? config.collections.find((item) => item.usageLog === true) ?? {
|
|
28
|
-
slug: 'usage-logs',
|
|
29
|
-
usageLog: true,
|
|
30
|
-
fields: [],
|
|
31
|
-
}
|
|
32
|
-
: undefined;
|
|
33
58
|
const usageField = {
|
|
34
59
|
name: 'apiKey',
|
|
35
60
|
type: 'relationship',
|
|
@@ -44,6 +69,7 @@ export function apiKeysPlugin(options = {}) {
|
|
|
44
69
|
const authConfig = typeof next.auth === 'object' ? next.auth : {};
|
|
45
70
|
next = {
|
|
46
71
|
...next,
|
|
72
|
+
fields: [...next.fields, ...createPolicyFields(true)],
|
|
47
73
|
auth: {
|
|
48
74
|
...authConfig,
|
|
49
75
|
strategies: [...(authConfig.strategies ?? []), strategy],
|
|
@@ -54,8 +80,33 @@ export function apiKeysPlugin(options = {}) {
|
|
|
54
80
|
next = { ...next, fields: [...next.fields, usageField] };
|
|
55
81
|
return next;
|
|
56
82
|
});
|
|
83
|
+
const resetTask = {
|
|
84
|
+
slug: 'frogbot-reset-ai-budgets',
|
|
85
|
+
schedule: [{ cron: '0 0 1 * *', queue: 'frogbot-reset-ai-budgets' }],
|
|
86
|
+
handler: async ({ req }) => {
|
|
87
|
+
for (const collection of [collectionSlug, authCollection]) {
|
|
88
|
+
await req.payload.update({
|
|
89
|
+
collection,
|
|
90
|
+
where: { id: { exists: true } },
|
|
91
|
+
data: { spendThisPeriodUSD: 0, budgetPeriodStartedAt: new Date().toISOString(), budgetAlertsSent: [] },
|
|
92
|
+
overrideAccess: true,
|
|
93
|
+
req,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return { output: {} };
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
const autoRun = config.jobs?.autoRun;
|
|
100
|
+
const jobs = {
|
|
101
|
+
...config.jobs,
|
|
102
|
+
tasks: [...(config.jobs?.tasks ?? []), resetTask],
|
|
103
|
+
autoRun: typeof autoRun === 'function'
|
|
104
|
+
? async (payload) => [...(await autoRun(payload)), { allQueues: true, cron: '* * * * *' }]
|
|
105
|
+
: [...(autoRun ?? []), { allQueues: true, cron: '* * * * *' }],
|
|
106
|
+
};
|
|
57
107
|
return {
|
|
58
108
|
...config,
|
|
109
|
+
jobs: config.ai ? jobs : config.jobs,
|
|
59
110
|
collections: [
|
|
60
111
|
...collections,
|
|
61
112
|
...(existing ? [] : [collection]),
|
|
@@ -71,14 +122,68 @@ export function apiKeysPlugin(options = {}) {
|
|
|
71
122
|
...config.ai.hooks,
|
|
72
123
|
beforeOperation: [
|
|
73
124
|
...(config.ai.hooks?.beforeOperation ?? []),
|
|
74
|
-
(args) => {
|
|
125
|
+
async (args) => {
|
|
75
126
|
const apiKeyId = args.req?.user?.apiKeyId;
|
|
76
|
-
if (
|
|
127
|
+
if (!args.req?.user)
|
|
128
|
+
return;
|
|
129
|
+
if (apiKeyId !== undefined)
|
|
130
|
+
args.context.usageFields = { ...args.context.usageFields, apiKey: apiKeyId };
|
|
131
|
+
if (!args.req.frogbot?.findByID)
|
|
132
|
+
return;
|
|
133
|
+
const key = apiKeyId === undefined ? undefined : await args.req.frogbot.findByID({ collection: collectionSlug, id: apiKeyId, depth: 0, overrideAccess: true, req: args.req });
|
|
134
|
+
const user = args.req.user;
|
|
135
|
+
const policy = resolvePolicy({ key: key, user, defaults: options.defaults });
|
|
136
|
+
const userPolicy = resolvePolicy({ user, defaults: options.defaults });
|
|
137
|
+
const subjects = [
|
|
138
|
+
apiKeyId === undefined ? undefined : { subject: `key:${apiKeyId}`, policy },
|
|
139
|
+
{ subject: `user:${args.req.user.id}`, policy: userPolicy },
|
|
140
|
+
].filter((value) => Boolean(value));
|
|
141
|
+
if (subjects.some(({ policy: current }) => current.budgetBehavior === 'block' && current.monthlyBudgetUSD !== undefined && current.spendThisPeriodUSD >= current.monthlyBudgetUSD))
|
|
142
|
+
throw new BudgetExceededError();
|
|
143
|
+
for (const { subject, policy: current } of subjects) {
|
|
144
|
+
const violation = limiter.admit(subject, current);
|
|
145
|
+
if (violation)
|
|
146
|
+
throw new RateLimitExceededError(violation);
|
|
147
|
+
}
|
|
148
|
+
Object.assign(args.context, { policy, policySubjects: subjects, policyKey: key });
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
beforeUpstream: [
|
|
152
|
+
...(config.ai.hooks?.beforeUpstream ?? []),
|
|
153
|
+
(args) => {
|
|
154
|
+
const models = args.context.policy?.models;
|
|
155
|
+
if (models && !models.includes(args.model))
|
|
156
|
+
throw new ModelNotAllowedError(args.model);
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
afterOperation: [
|
|
160
|
+
...(config.ai.hooks?.afterOperation ?? []),
|
|
161
|
+
async (args) => {
|
|
162
|
+
const context = args.context;
|
|
163
|
+
const req = args.req;
|
|
164
|
+
if (!req?.user || args.error)
|
|
165
|
+
return;
|
|
166
|
+
const tokens = args.usage?.totalTokens ?? 0;
|
|
167
|
+
for (const { subject } of context.policySubjects ?? [])
|
|
168
|
+
limiter.settle(subject, tokens);
|
|
169
|
+
const cost = args.usage ? calculateModelCostUSD(args.model, args.usage) : 0;
|
|
170
|
+
if (cost <= 0)
|
|
77
171
|
return;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
172
|
+
const targets = [
|
|
173
|
+
req.user.apiKeyId === undefined ? undefined : { collection: collectionSlug, id: req.user.apiKeyId },
|
|
174
|
+
{ collection: authCollection, id: req.user.id },
|
|
175
|
+
].filter((target) => Boolean(target));
|
|
176
|
+
await Promise.all(targets.map((target) => queue.run(`${target.collection}:${target.id}`, async () => {
|
|
177
|
+
const doc = await req.frogbot.findByID({ collection: target.collection, id: target.id, depth: 0, overrideAccess: true, req });
|
|
178
|
+
const spend = (typeof doc.spendThisPeriodUSD === 'number' ? doc.spendThisPeriodUSD : 0) + cost;
|
|
179
|
+
const sent = Array.isArray(doc.budgetAlertsSent) ? doc.budgetAlertsSent.filter((value) => typeof value === 'number') : [];
|
|
180
|
+
const policy = resolvePolicy({ key: (target.collection === collectionSlug ? doc : context.policyKey), user: (target.collection === authCollection ? doc : req.user), defaults: options.defaults });
|
|
181
|
+
const thresholds = options.alerts?.thresholds ?? [0.8, 1];
|
|
182
|
+
const crossed = policy.monthlyBudgetUSD === undefined ? [] : thresholds.filter((threshold) => spend / policy.monthlyBudgetUSD >= threshold && !sent.includes(threshold));
|
|
183
|
+
await req.frogbot.update({ collection: target.collection, id: target.id, data: { spendThisPeriodUSD: spend, budgetPeriodStartedAt: doc.budgetPeriodStartedAt ?? new Date().toISOString(), budgetAlertsSent: [...sent, ...crossed] }, overrideAccess: true, req });
|
|
184
|
+
if (options.alerts && crossed.length)
|
|
185
|
+
await fetch(options.alerts.webhookURL, { method: 'POST', headers: { 'content-type': 'application/json', ...options.alerts.headers }, body: JSON.stringify({ subject: target, spendThisPeriodUSD: spend, monthlyBudgetUSD: policy.monthlyBudgetUSD, thresholds: crossed }) });
|
|
186
|
+
})));
|
|
82
187
|
},
|
|
83
188
|
],
|
|
84
189
|
},
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/policy.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type PolicyMode = 'inherit' | 'custom' | 'unlimited';
|
|
2
|
+
export type PolicyValue<T> = {
|
|
3
|
+
mode?: PolicyMode;
|
|
4
|
+
value?: T;
|
|
5
|
+
};
|
|
6
|
+
export type PolicyDocument = {
|
|
7
|
+
monthlyBudget?: PolicyValue<number>;
|
|
8
|
+
rpm?: PolicyValue<number>;
|
|
9
|
+
tpm?: PolicyValue<number>;
|
|
10
|
+
models?: PolicyValue<string[]>;
|
|
11
|
+
spendThisPeriodUSD?: number;
|
|
12
|
+
budgetBehavior?: 'block' | 'alert-only';
|
|
13
|
+
};
|
|
14
|
+
export type PolicyDefaults = {
|
|
15
|
+
monthlyBudgetUSD?: number;
|
|
16
|
+
rpm?: number;
|
|
17
|
+
tpm?: number;
|
|
18
|
+
models?: string[];
|
|
19
|
+
budgetBehavior?: 'block' | 'alert-only';
|
|
20
|
+
};
|
|
21
|
+
export type EffectivePolicy = PolicyDefaults & {
|
|
22
|
+
spendThisPeriodUSD: number;
|
|
23
|
+
};
|
|
24
|
+
export declare class SerialQueue {
|
|
25
|
+
private readonly updates;
|
|
26
|
+
get pending(): number;
|
|
27
|
+
run(subject: string, update: () => Promise<void>): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
export declare function resolvePolicy(args: {
|
|
30
|
+
key?: PolicyDocument;
|
|
31
|
+
user?: PolicyDocument;
|
|
32
|
+
defaults?: PolicyDefaults;
|
|
33
|
+
}): EffectivePolicy;
|
|
34
|
+
export declare class SlidingWindowRateLimiter {
|
|
35
|
+
private readonly now;
|
|
36
|
+
private readonly windows;
|
|
37
|
+
constructor(now?: () => number);
|
|
38
|
+
admit(subject: string, policy: Pick<EffectivePolicy, 'rpm' | 'tpm'>): {
|
|
39
|
+
kind: 'rpm' | 'tpm';
|
|
40
|
+
retryAfterSeconds: number;
|
|
41
|
+
} | undefined;
|
|
42
|
+
settle(subject: string, tokens: number): void;
|
|
43
|
+
private get;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5D,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;IAC3B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,CAAC,CAAC;CACX,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACpC,GAAG,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,GAAG,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,cAAc,GAAG;IAC7C,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAE5D,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAUjE;AAUD,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,cAAc,CAAC;IAAC,IAAI,CAAC,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GAAG,eAAe,CAiB/H;AAID,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAFhC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;gBAE7B,GAAG,GAAE,MAAM,MAAiB;IAEzD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,GAAG,KAAK,CAAC,GAAG;QAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CAAC;QAAC,iBAAiB,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAWpI,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAK7C,OAAO,CAAC,GAAG;CAOZ"}
|
package/dist/policy.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export class SerialQueue {
|
|
2
|
+
updates = new Map();
|
|
3
|
+
get pending() {
|
|
4
|
+
return this.updates.size;
|
|
5
|
+
}
|
|
6
|
+
run(subject, update) {
|
|
7
|
+
const next = (this.updates.get(subject) ?? Promise.resolve()).then(update, update);
|
|
8
|
+
let owner;
|
|
9
|
+
const release = () => {
|
|
10
|
+
if (this.updates.get(subject) === owner)
|
|
11
|
+
this.updates.delete(subject);
|
|
12
|
+
};
|
|
13
|
+
owner = next.then(release, release);
|
|
14
|
+
this.updates.set(subject, owner);
|
|
15
|
+
return next;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function resolveValue(key, user, fallback) {
|
|
19
|
+
for (const policy of [key, user]) {
|
|
20
|
+
if (policy?.mode === 'unlimited')
|
|
21
|
+
return undefined;
|
|
22
|
+
if (policy?.mode === 'custom')
|
|
23
|
+
return policy.value;
|
|
24
|
+
}
|
|
25
|
+
return fallback;
|
|
26
|
+
}
|
|
27
|
+
export function resolvePolicy(args) {
|
|
28
|
+
const { key, user, defaults = {} } = args;
|
|
29
|
+
const budgetSpend = key?.monthlyBudget?.mode === 'custom'
|
|
30
|
+
? key.spendThisPeriodUSD
|
|
31
|
+
: key?.monthlyBudget?.mode === 'unlimited'
|
|
32
|
+
? 0
|
|
33
|
+
: user?.monthlyBudget?.mode === 'custom'
|
|
34
|
+
? user.spendThisPeriodUSD
|
|
35
|
+
: key?.spendThisPeriodUSD ?? user?.spendThisPeriodUSD;
|
|
36
|
+
return {
|
|
37
|
+
monthlyBudgetUSD: resolveValue(key?.monthlyBudget, user?.monthlyBudget, defaults.monthlyBudgetUSD),
|
|
38
|
+
rpm: resolveValue(key?.rpm, user?.rpm, defaults.rpm),
|
|
39
|
+
tpm: resolveValue(key?.tpm, user?.tpm, defaults.tpm),
|
|
40
|
+
models: resolveValue(key?.models, user?.models, defaults.models),
|
|
41
|
+
budgetBehavior: key?.budgetBehavior ?? user?.budgetBehavior ?? defaults.budgetBehavior ?? 'block',
|
|
42
|
+
spendThisPeriodUSD: budgetSpend ?? 0,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export class SlidingWindowRateLimiter {
|
|
46
|
+
now;
|
|
47
|
+
windows = new Map();
|
|
48
|
+
constructor(now = Date.now) {
|
|
49
|
+
this.now = now;
|
|
50
|
+
}
|
|
51
|
+
admit(subject, policy) {
|
|
52
|
+
const now = this.now();
|
|
53
|
+
const entry = this.get(subject, now);
|
|
54
|
+
const retry = (at) => Math.max(1, Math.ceil((at + 60_000 - now) / 1000));
|
|
55
|
+
if (policy.rpm !== undefined && entry.requests.length >= policy.rpm)
|
|
56
|
+
return { kind: 'rpm', retryAfterSeconds: retry(entry.requests[0]) };
|
|
57
|
+
const tokens = entry.tokens.reduce((sum, item) => sum + item.value, 0);
|
|
58
|
+
if (policy.tpm !== undefined && tokens >= policy.tpm)
|
|
59
|
+
return { kind: 'tpm', retryAfterSeconds: retry(entry.tokens[0]?.at ?? now) };
|
|
60
|
+
entry.requests.push(now);
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
settle(subject, tokens) {
|
|
64
|
+
if (tokens <= 0)
|
|
65
|
+
return;
|
|
66
|
+
this.get(subject, this.now()).tokens.push({ at: this.now(), value: tokens });
|
|
67
|
+
}
|
|
68
|
+
get(subject, now) {
|
|
69
|
+
const entry = this.windows.get(subject) ?? { requests: [], tokens: [] };
|
|
70
|
+
entry.requests = entry.requests.filter((at) => at > now - 60_000);
|
|
71
|
+
entry.tokens = entry.tokens.filter(({ at }) => at > now - 60_000);
|
|
72
|
+
this.windows.set(subject, entry);
|
|
73
|
+
return entry;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,EAAE,WAAkB,EAAE,GAAE,kBAAuB,GAAG,MAAM,CAEzF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,EAAE,WAA2B,EAAE,GAAE,mBAAwB,GACxD,MAAM,GAAG,IAAI,CAWf"}
|
package/dist/server/token.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
-
export function createApiKeyToken({ tokenPrefix = '
|
|
2
|
+
export function createApiKeyToken({ tokenPrefix = 'fb' } = {}) {
|
|
3
3
|
return `${tokenPrefix}_${randomBytes(32).toString('base64url')}`;
|
|
4
4
|
}
|
|
5
5
|
export function hashApiKeyToken(token) {
|
package/dist/server/token.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAUtD,MAAM,UAAU,iBAAiB,CAAC,EAAE,WAAW,GAAG,
|
|
1
|
+
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../src/server/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAUtD,MAAM,UAAU,iBAAiB,CAAC,EAAE,WAAW,GAAG,IAAI,KAAyB,EAAE;IAC/E,OAAO,GAAG,WAAW,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,OAAgB,EAChB,EAAE,WAAW,GAAG,CAAC,WAAW,CAAC,KAA0B,EAAE;IAEzD,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,aAAa,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC;QAC9C,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frogbotai/plugin-api-keys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Multiple named API keys for FrogBot.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Colby Gilbert",
|
|
@@ -28,12 +28,16 @@
|
|
|
28
28
|
"files": [
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
|
-
"sideEffects":
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"*.css"
|
|
33
|
+
],
|
|
32
34
|
"peerDependencies": {
|
|
33
35
|
"@payloadcms/ui": "3.85.1",
|
|
34
36
|
"react": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
35
37
|
"react-dom": "^19.0.1 || ^19.1.2 || ^19.2.1",
|
|
36
|
-
"
|
|
38
|
+
"@frogbotai/gateway": "0.12.0",
|
|
39
|
+
"@frogbotai/plugin-roles": "0.12.0",
|
|
40
|
+
"frogbot": "0.12.0"
|
|
37
41
|
},
|
|
38
42
|
"devDependencies": {
|
|
39
43
|
"@payloadcms/ui": "3.85.1",
|
|
@@ -42,13 +46,15 @@
|
|
|
42
46
|
"react": "19.2.6",
|
|
43
47
|
"react-dom": "19.2.6",
|
|
44
48
|
"typescript": "5.6.2",
|
|
45
|
-
"frogbot": "0.
|
|
49
|
+
"frogbot": "0.12.0",
|
|
50
|
+
"@frogbotai/plugin-roles": "0.12.0",
|
|
51
|
+
"@frogbotai/gateway": "0.12.0"
|
|
46
52
|
},
|
|
47
53
|
"publishConfig": {
|
|
48
54
|
"access": "public"
|
|
49
55
|
},
|
|
50
56
|
"scripts": {
|
|
51
|
-
"build": "tsc -p tsconfig.json",
|
|
57
|
+
"build": "tsc -p tsconfig.json && cp src/client/styles.css dist/client/styles.css",
|
|
52
58
|
"clean": "rm -rf dist",
|
|
53
59
|
"typecheck": "tsc --noEmit"
|
|
54
60
|
}
|