@rytass/bpm-core-client 0.1.2 → 0.1.4
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 +113 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ functions directly from any framework (Next.js / Vite / Remix / plain Node).
|
|
|
18
18
|
|
|
19
19
|
## Package Status
|
|
20
20
|
|
|
21
|
-
Current version: `0.
|
|
21
|
+
Current version: `0.1.2`
|
|
22
22
|
|
|
23
23
|
The package intentionally stays framework-agnostic so it can be reused from
|
|
24
24
|
Next.js Server Components, Server Actions, plain React, or non-React
|
|
@@ -42,6 +42,113 @@ your `tsconfig.json` so the package's `exports` field is honored. Classic
|
|
|
42
42
|
shipped with this package, but is on TypeScript's long-term deprecation
|
|
43
43
|
path — new projects should opt in to modern resolution.
|
|
44
44
|
|
|
45
|
+
## Runtime Compatibility
|
|
46
|
+
|
|
47
|
+
> **TL;DR — the transport is isomorphic (always `fetch`), but session is
|
|
48
|
+
> browser-first.** Out of the box every function works in a browser tab.
|
|
49
|
+
> Server Components, Server Actions, Node CLIs, workers, and Edge Functions
|
|
50
|
+
> can also call the same functions, but the caller is responsible for
|
|
51
|
+
> resolving the endpoint to an absolute URL and for forwarding any
|
|
52
|
+
> session cookie.
|
|
53
|
+
|
|
54
|
+
### What is identical across runtimes
|
|
55
|
+
|
|
56
|
+
| Concern | Behavior |
|
|
57
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| Transport | Always `globalThis.fetch`. No `axios`, no `node-fetch`, no `cross-fetch`, no Apollo Link. |
|
|
59
|
+
| Serialization | `Content-Type: application/json`; `POST { query, variables }`. |
|
|
60
|
+
| Error model | Throws `Error` on non-2xx HTTP, on `payload.errors[]`, or on missing `data`. |
|
|
61
|
+
| Type guarantees | Every function returns a typed `Promise<T>` — return shape is identical regardless of where the call runs. |
|
|
62
|
+
|
|
63
|
+
### What differs across runtimes
|
|
64
|
+
|
|
65
|
+
| Concern | Browser | Node SSR / Server Component / CLI |
|
|
66
|
+
| ---------------------- | ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
67
|
+
| Default endpoint | Same-origin `/graphql` resolves to `https://your-host/graphql`. | Same-origin `/graphql` **throws** `TypeError: Failed to parse URL`. Set `NEXT_PUBLIC_API_URL` to an absolute URL. |
|
|
68
|
+
| Session cookie | `credentials: 'include'` automatically sends the HttpOnly cookie issued by `/auth/login`.| `fetch` has no cookie jar; the host must forward the incoming request's `Cookie` header manually. |
|
|
69
|
+
| `loginApi()` storage | Cookie lands in browser jar, persists across navigations. | Returned `Set-Cookie` header is dropped — caller must read and reuse it explicitly. |
|
|
70
|
+
| `window.location` | Used to detect `localhost` for the dev fallback endpoint. | `typeof window === 'undefined'` → endpoint resolver returns `/graphql` (relative), which is invalid in Node unless overridden. |
|
|
71
|
+
|
|
72
|
+
### Server Component / Server Action recipe
|
|
73
|
+
|
|
74
|
+
Next.js App Router server runtime needs two things: an absolute endpoint and
|
|
75
|
+
a way to relay the inbound `Cookie` header. The recommended pattern is to
|
|
76
|
+
set `NEXT_PUBLIC_API_URL` at build time and pass cookies via the underlying
|
|
77
|
+
`fetch` headers using a wrapper such as Next's `cookies()`:
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
// app/inbox/page.tsx — Server Component
|
|
81
|
+
import { cookies } from 'next/headers';
|
|
82
|
+
|
|
83
|
+
async function fetchInbox(): Promise<unknown> {
|
|
84
|
+
const cookieHeader = (await cookies()).toString();
|
|
85
|
+
const response = await fetch(`${process.env.BPM_API_URL}/graphql`, {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: {
|
|
88
|
+
'Content-Type': 'application/json',
|
|
89
|
+
Cookie: cookieHeader,
|
|
90
|
+
},
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
query: 'query Ping { memberCount }',
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
return response.json();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
> For SSR cases that need to call **many** typed functions, the cleanest
|
|
100
|
+
> long-term option is to add a `configureBPMClient({ fetch, endpoint })`
|
|
101
|
+
> hook so the typed wrappers can be reused. That is not yet shipped — if
|
|
102
|
+
> you need it, file an issue. Today, Server Component callers either talk
|
|
103
|
+
> to the host directly (as above) or proxy through a Route Handler that
|
|
104
|
+
> runs inside the consumer's browser session.
|
|
105
|
+
|
|
106
|
+
### Node CLI recipe
|
|
107
|
+
|
|
108
|
+
CLIs that drive BPM from outside a browser need both an absolute endpoint
|
|
109
|
+
and explicit session management. The auth REST client (`loginApi`,
|
|
110
|
+
`logoutApi`, `readApiCurrentMember`) returns typed bodies but does not
|
|
111
|
+
persist cookies in Node — capture them yourself:
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// scripts/dump-running-instances.ts
|
|
115
|
+
import { listApprovalInstancesPage } from '@rytass/bpm-core-client/workflow';
|
|
116
|
+
|
|
117
|
+
process.env.NEXT_PUBLIC_API_URL ??= 'https://bpm.your-host.example/graphql';
|
|
118
|
+
|
|
119
|
+
// 1. Log in and capture the session cookie manually.
|
|
120
|
+
const loginResponse = await fetch(
|
|
121
|
+
'https://bpm.your-host.example/auth/login',
|
|
122
|
+
{
|
|
123
|
+
method: 'POST',
|
|
124
|
+
headers: { 'Content-Type': 'application/json' },
|
|
125
|
+
body: JSON.stringify({ identifier: 'svc-bot', password: '...' }),
|
|
126
|
+
},
|
|
127
|
+
);
|
|
128
|
+
const cookieJar = loginResponse.headers.get('set-cookie') ?? '';
|
|
129
|
+
|
|
130
|
+
// 2. Hand the cookie to subsequent fetches via a small fetch override.
|
|
131
|
+
const originalFetch = globalThis.fetch;
|
|
132
|
+
globalThis.fetch = ((input, init = {}) =>
|
|
133
|
+
originalFetch(input, {
|
|
134
|
+
...init,
|
|
135
|
+
headers: { ...(init.headers ?? {}), Cookie: cookieJar },
|
|
136
|
+
})) as typeof fetch;
|
|
137
|
+
|
|
138
|
+
// 3. Call typed BPM functions as usual.
|
|
139
|
+
const { instances } = await listApprovalInstancesPage({
|
|
140
|
+
view: 'ALL', state: 'RUNNING', page: 1, pageSize: 1000,
|
|
141
|
+
searchText: '', templateId: null,
|
|
142
|
+
});
|
|
143
|
+
console.log(instances.length, 'running instances');
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Edge / Workers
|
|
147
|
+
|
|
148
|
+
Cloudflare Workers, Vercel Edge Functions, and similar V8-isolate runtimes
|
|
149
|
+
ship `fetch` natively and follow the **Node SSR** column above — no
|
|
150
|
+
default endpoint, no cookie jar. Treat them the same as Server Components.
|
|
151
|
+
|
|
45
152
|
## Endpoint Resolution
|
|
46
153
|
|
|
47
154
|
By default the client targets the same origin (no `/api` prefix) — see
|
|
@@ -161,8 +268,11 @@ export function useMembers(memberIds: readonly string[]) {
|
|
|
161
268
|
}
|
|
162
269
|
```
|
|
163
270
|
|
|
164
|
-
For Next.js App Router
|
|
165
|
-
|
|
271
|
+
For Next.js App Router Client Components the typed wrappers work
|
|
272
|
+
out of the box (same-origin endpoint, browser cookie jar). For Server
|
|
273
|
+
Components, Server Actions, Route Handlers, Edge runtimes, or plain Node
|
|
274
|
+
CLIs, see **[Runtime Compatibility](#runtime-compatibility)** — those
|
|
275
|
+
runtimes need an absolute endpoint and manual cookie forwarding.
|
|
166
276
|
|
|
167
277
|
## Local Development
|
|
168
278
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rytass/bpm-core-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Framework-agnostic TypeScript client for the Rytass BPM approval workflow GraphQL surface: fetch-based GraphQL transport, REST auth client, pre-baked typed operations for organization, member, form, template, and workflow.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"bpm",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
}
|
|
74
74
|
},
|
|
75
75
|
"peerDependencies": {
|
|
76
|
-
"@rytass/bpm-core-shared": "^0.1.
|
|
76
|
+
"@rytass/bpm-core-shared": "^0.1.4"
|
|
77
77
|
},
|
|
78
78
|
"dependencies": {
|
|
79
79
|
"tslib": "^2.3.0"
|