@aindy/ui-kit 1.0.5 → 2.0.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/README.md +129 -0
- package/dist/api/_routes.d.ts +18 -4
- package/dist/api/auth.d.ts +33 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1751 -1667
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @aindy/ui-kit
|
|
2
|
+
|
|
3
|
+
Shared UI components, React contexts, and API core for **AINDY platform** frontends.
|
|
4
|
+
|
|
5
|
+
`@aindy/ui-kit` is the client-side counterpart to the [`aindy-runtime`](https://pypi.org/project/aindy-runtime/)
|
|
6
|
+
backend: it centralizes the authenticated HTTP layer, the canonical backend route table,
|
|
7
|
+
auth/session contexts, and a small set of shared components and UI primitives so every
|
|
8
|
+
frontend built on the runtime talks to it the same way. It is published to npm and consumed
|
|
9
|
+
as a compiled bundle (`dist/` is built at publish time, not committed).
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @aindy/ui-kit
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Peer dependencies** (provided by the host app):
|
|
18
|
+
|
|
19
|
+
- `react` ^19
|
|
20
|
+
- `react-dom` ^19
|
|
21
|
+
- `react-router-dom` ^6
|
|
22
|
+
|
|
23
|
+
## What it exports
|
|
24
|
+
|
|
25
|
+
### API core (`./api/_core.js`)
|
|
26
|
+
|
|
27
|
+
The authenticated request layer against the runtime. `buildApiUrl` prepends `API_BASE` to a
|
|
28
|
+
`ROUTES` value; the `request` family attaches the stored token and returns the parsed body.
|
|
29
|
+
|
|
30
|
+
| Export | Purpose |
|
|
31
|
+
|---|---|
|
|
32
|
+
| `request`, `authRequest`, `adminRequest`, `taggedRequest`, `requestAbsolute` | HTTP calls (auth-scoped / admin-scoped / cache-tagged / absolute-URL variants) |
|
|
33
|
+
| `buildApiUrl` | Resolve a `ROUTES` value against `API_BASE` |
|
|
34
|
+
| `getStoredToken`, `setStoredToken`, `clearStoredToken` | JWT storage |
|
|
35
|
+
| `unwrapEnvelope` | Unwrap the runtime's `{ data: … }` response envelope |
|
|
36
|
+
| `ApiError` | Typed error carrying status + body |
|
|
37
|
+
| `API_BASE` | Build-time API base (`VITE_API_BASE_URL`, default `""` — relative to origin) |
|
|
38
|
+
|
|
39
|
+
### Routes (`./api/_routes.js`)
|
|
40
|
+
|
|
41
|
+
- `ROUTES` — the canonical backend route table. **Every runtime/platform route carries the
|
|
42
|
+
full `/platform` prefix** (e.g. `ROUTES.OPERATOR.FLOW_STRATEGIES` → `/platform/flows/strategies`).
|
|
43
|
+
A value that drops the prefix segment 404s.
|
|
44
|
+
- `FEATURE_FLAGS` — NavLink gates for routes that are conditionally served; flip a flag to
|
|
45
|
+
`true` when its backing runtime route lands.
|
|
46
|
+
|
|
47
|
+
> **Runtime routes vs app routes.** `ROUTES` should carry **runtime/platform** paths only —
|
|
48
|
+
> these are shared by every consumer, and the runtime's authoritative list lives in
|
|
49
|
+
> [`aindy-runtime` `docs/runtime/UI_CONTRACT.md`](https://github.com/Masterplanner25/aindy-runtime/blob/main/docs/runtime/UI_CONTRACT.md).
|
|
50
|
+
> **App-domain** paths (e.g. `/compute/*` analytics, `/seo/*`) are **not** runtime routes and
|
|
51
|
+
> must not be baked into this shared kit; a consuming app owns those in its own route map that
|
|
52
|
+
> spreads and extends `ROUTES` (mirroring the backend's runtime/app split).
|
|
53
|
+
|
|
54
|
+
### Auth (`./api/auth.js`)
|
|
55
|
+
|
|
56
|
+
`bootIdentity`, `loginUser`, `registerUser`.
|
|
57
|
+
|
|
58
|
+
> **Invariant:** all three must `.then(unwrapEnvelope)` — `bootIdentity` populates
|
|
59
|
+
> `system.runtime.boot_mode` (read by the post-login redirect); returning the raw envelope
|
|
60
|
+
> silently breaks it.
|
|
61
|
+
|
|
62
|
+
### Contexts
|
|
63
|
+
|
|
64
|
+
- `AuthProvider` / `useAuth` — session + identity.
|
|
65
|
+
- `SystemProvider` / `useSystem` — runtime system state (incl. `boot_mode`).
|
|
66
|
+
|
|
67
|
+
### Components
|
|
68
|
+
|
|
69
|
+
`AppShell`, `ProtectedRoute`, `VersionMismatchBanner`, `Toast`, `LoadingPanel`,
|
|
70
|
+
`DomainError`, `AdminAccessRequired` (+ `useAdminApiGuard`), `EmptyState`.
|
|
71
|
+
|
|
72
|
+
### UI primitives
|
|
73
|
+
|
|
74
|
+
`Button` (+ `buttonVariants`), the `Card` family (`Card`, `CardHeader`, `CardTitle`,
|
|
75
|
+
`CardDescription`, `CardContent`, `CardFooter`), the `Tooltip` family (`Tooltip`,
|
|
76
|
+
`TooltipTrigger`, `TooltipContent`, `TooltipProvider`).
|
|
77
|
+
|
|
78
|
+
### Utilities
|
|
79
|
+
|
|
80
|
+
`cn` (class merge), `APPROVAL_EVENT`, `useApiCall`, `useToast`, `safeArray`, `safeMap`.
|
|
81
|
+
|
|
82
|
+
## Usage
|
|
83
|
+
|
|
84
|
+
```jsx
|
|
85
|
+
import {
|
|
86
|
+
AuthProvider, SystemProvider, ProtectedRoute, AppShell,
|
|
87
|
+
ROUTES, request, unwrapEnvelope,
|
|
88
|
+
} from "@aindy/ui-kit";
|
|
89
|
+
|
|
90
|
+
function App() {
|
|
91
|
+
return (
|
|
92
|
+
<AuthProvider>
|
|
93
|
+
<SystemProvider>
|
|
94
|
+
<AppShell>{/* routes */}</AppShell>
|
|
95
|
+
</SystemProvider>
|
|
96
|
+
</AuthProvider>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// A backend call through the canonical route table:
|
|
101
|
+
const strategies = await request(ROUTES.OPERATOR.FLOW_STRATEGIES).then(unwrapEnvelope);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
npm run build # vite build → dist/ (index.js, index.cjs, index.d.ts)
|
|
108
|
+
npm run lint # eslint src
|
|
109
|
+
npm test # vitest
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Versioning & the runtime
|
|
113
|
+
|
|
114
|
+
`@aindy/ui-kit` and `aindy-runtime` are **independently versioned**. This package *consumes*
|
|
115
|
+
the runtime's HTTP contract; the runtime does not depend on it. A ui-kit release does **not**
|
|
116
|
+
require a runtime release (and vice versa) — a runtime bump is only relevant when a ui-kit
|
|
117
|
+
change depends on a *new* runtime route or behavior. Keep `ROUTES` in sync with the runtime's
|
|
118
|
+
`docs/runtime/UI_CONTRACT.md`; a route that drifts from a served backend path is the
|
|
119
|
+
`UIKIT-ROUTE-DRIFT-1` failure mode.
|
|
120
|
+
|
|
121
|
+
## Publishing
|
|
122
|
+
|
|
123
|
+
`dist/` is gitignored and built fresh at publish:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm version patch # e.g. 1.0.5 → 1.0.6
|
|
127
|
+
npm run build
|
|
128
|
+
npm publish
|
|
129
|
+
```
|
package/dist/api/_routes.d.ts
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
+
export const FEATURE_FLAGS: Readonly<{
|
|
2
|
+
OPERATOR_FLOW_STRATEGIES: true;
|
|
3
|
+
OPERATOR_AUTOMATION_LOGS: false;
|
|
4
|
+
OPERATOR_SCHEDULER_STATUS: false;
|
|
5
|
+
RIPPLETRACE_VIEWER: false;
|
|
6
|
+
}>;
|
|
1
7
|
export const ROUTES: Readonly<{
|
|
2
8
|
AUTH: Readonly<{
|
|
3
9
|
LOGIN: "/auth/login";
|
|
4
10
|
REGISTER: "/auth/register";
|
|
11
|
+
LOGOUT: "/auth/logout";
|
|
12
|
+
VERIFY_EMAIL: "/auth/verify-email";
|
|
13
|
+
PASSWORD_CHANGE: "/auth/password/change";
|
|
14
|
+
PASSWORD_FORGOT: "/auth/password/forgot";
|
|
15
|
+
PASSWORD_RESET: "/auth/password/reset";
|
|
5
16
|
}>;
|
|
6
17
|
TASKS: Readonly<{
|
|
7
18
|
LIST: "/tasks/list";
|
|
@@ -23,6 +34,8 @@ export const ROUTES: Readonly<{
|
|
|
23
34
|
RUN: (runId: any) => string;
|
|
24
35
|
APPROVE: (runId: any) => string;
|
|
25
36
|
REJECT: (runId: any) => string;
|
|
37
|
+
RECOVER: (runId: any) => string;
|
|
38
|
+
REPLAY: (runId: any) => string;
|
|
26
39
|
STEPS: (runId: any) => string;
|
|
27
40
|
EVENTS: (runId: any) => string;
|
|
28
41
|
TOOLS: "/apps/agent/tools";
|
|
@@ -142,14 +155,15 @@ export const ROUTES: Readonly<{
|
|
|
142
155
|
FLOW_RUN_RESUME: (runId: any) => string;
|
|
143
156
|
FLOW_REGISTRY: "/platform/flows/registry";
|
|
144
157
|
FLOW_STRATEGIES: "/platform/flows/strategies";
|
|
145
|
-
|
|
146
|
-
AUTOMATION_LOG: (logId: any) => string;
|
|
147
|
-
AUTOMATION_REPLAY: (logId: any) => string;
|
|
148
|
-
SCHEDULER_STATUS: "/platform/observability/scheduler/status";
|
|
158
|
+
RIPPLETRACE_STATUS: "/platform/observability/rippletrace/status";
|
|
149
159
|
OBSERVABILITY_REQUESTS: "/platform/observability/requests";
|
|
150
160
|
OBSERVABILITY_DASHBOARD: "/platform/observability/dashboard";
|
|
151
161
|
CLIENT_ERROR: "/client/error";
|
|
152
162
|
CLIENT_VITALS: "/client/vitals";
|
|
163
|
+
AUTOMATION_LOGS: "/automation/logs";
|
|
164
|
+
AUTOMATION_LOG: (logId: any) => string;
|
|
165
|
+
AUTOMATION_REPLAY: (logId: any) => string;
|
|
166
|
+
SCHEDULER_STATUS: "/platform/observability/scheduler/status";
|
|
153
167
|
}>;
|
|
154
168
|
PLATFORM: Readonly<{
|
|
155
169
|
DASHBOARD_OVERVIEW: "/dashboard/overview";
|
package/dist/api/auth.d.ts
CHANGED
|
@@ -1,3 +1,36 @@
|
|
|
1
1
|
export function loginUser(credentials: any): Promise<any>;
|
|
2
|
+
/**
|
|
3
|
+
* Begin registration. Against runtime >= 2.0.0 this resolves to
|
|
4
|
+
* `{ status: "verification_sent" }` and **carries no access token** — the response is
|
|
5
|
+
* deliberately identical whether or not the address was already registered, which is what
|
|
6
|
+
* closes the account-enumeration oracle. The token is issued by `verifyEmail` once the
|
|
7
|
+
* emailed link is followed.
|
|
8
|
+
*/
|
|
2
9
|
export function registerUser(credentials: any): Promise<any>;
|
|
10
|
+
/** Consume an emailed verification token and receive the access token. */
|
|
11
|
+
export function verifyEmail(token: any): Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* Rotate the signed-in user's password.
|
|
14
|
+
*
|
|
15
|
+
* Returns a freshly-versioned access token. **It must be stored** — the change invalidates
|
|
16
|
+
* every session including this one, so keeping the old token 401s on the next request.
|
|
17
|
+
*/
|
|
18
|
+
export function changePassword(currentPassword: any, newPassword: any, token?: string): Promise<any>;
|
|
19
|
+
/**
|
|
20
|
+
* Begin password recovery.
|
|
21
|
+
*
|
|
22
|
+
* Resolves identically whether or not the address is registered — do not branch on the
|
|
23
|
+
* result to tell the user whether an account exists, that is the oracle this avoids. A 503
|
|
24
|
+
* means the deployment has no email channel configured, which is about the deployment and
|
|
25
|
+
* not about any account.
|
|
26
|
+
*/
|
|
27
|
+
export function forgotPassword(email: any): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* Complete password recovery with an emailed token.
|
|
30
|
+
*
|
|
31
|
+
* Returns no access token — unlike `changePassword`, the caller has not proven they hold a
|
|
32
|
+
* session, so they sign in afresh.
|
|
33
|
+
*/
|
|
34
|
+
export function resetPassword(token: any, newPassword: any): Promise<any>;
|
|
35
|
+
export function logoutUser(token?: string): Promise<any>;
|
|
3
36
|
export function bootIdentity(token?: string): Promise<any>;
|
package/dist/api/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { ROUTES } from './_routes.js';
|
|
2
2
|
export { ApiError, adminRequest, authRequest, authRequestExternal, buildApiUrl, clearStoredToken, getStoredToken, request, requestAbsolute, setStoredToken, taggedRequest, unwrapEnvelope, API_BASE } from './_core.js';
|
|
3
|
-
export { bootIdentity, loginUser, registerUser } from './auth.js';
|
|
3
|
+
export { bootIdentity, changePassword, forgotPassword, loginUser, registerUser, resetPassword, verifyEmail } from './auth.js';
|