@fluxomni/api-client 0.11.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 +253 -0
- package/dist/auth.d.ts +36 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +71 -0
- package/dist/auth.js.map +1 -0
- package/dist/client.d.ts +89 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +254 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +59 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +135 -0
- package/dist/errors.js.map +1 -0
- package/dist/generated/graphql.d.ts +6777 -0
- package/dist/generated/graphql.d.ts.map +1 -0
- package/dist/generated/graphql.js +13702 -0
- package/dist/generated/graphql.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/scalars.d.ts +5 -0
- package/dist/scalars.d.ts.map +1 -0
- package/dist/scalars.js +2 -0
- package/dist/scalars.js.map +1 -0
- package/package.json +61 -0
- package/src/auth.ts +127 -0
- package/src/client.ts +412 -0
- package/src/errors.ts +183 -0
- package/src/generated/graphql.ts +20296 -0
- package/src/index.ts +72 -0
- package/src/scalars.ts +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
# @fluxomni/api-client
|
|
2
|
+
|
|
3
|
+
Thin TypeScript transport for the Fluxomni GraphQL API. The public automation
|
|
4
|
+
surface is intentionally small: authenticate with the session API, send direct
|
|
5
|
+
GraphQL documents, and opt into generated documents/types when compile-time
|
|
6
|
+
operation typing is useful.
|
|
7
|
+
|
|
8
|
+
The current package surface is a public API preview. The stable contract is the
|
|
9
|
+
GraphQL schema, the transport client, and the generated documents/types.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @fluxomni/api-client
|
|
15
|
+
# or
|
|
16
|
+
npm install @fluxomni/api-client
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Minimal Automation Client
|
|
20
|
+
|
|
21
|
+
Use `executeRaw()` for scripts and examples. It sends the GraphQL text exactly
|
|
22
|
+
as written and returns the `data` payload.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { GraphQLClient } from '@fluxomni/api-client';
|
|
26
|
+
|
|
27
|
+
const { client } = await GraphQLClient.login({
|
|
28
|
+
baseUrl: 'http://localhost:8001',
|
|
29
|
+
username: process.env.FLUXOMNI_USERNAME!,
|
|
30
|
+
password: process.env.FLUXOMNI_PASSWORD!,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const data = await client.executeRaw<{
|
|
34
|
+
routes: { allRoutes: Array<{ id: string; label?: string | null }> };
|
|
35
|
+
}>(`
|
|
36
|
+
query Routes {
|
|
37
|
+
routes {
|
|
38
|
+
allRoutes {
|
|
39
|
+
id
|
|
40
|
+
label
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`);
|
|
45
|
+
|
|
46
|
+
console.log(data.routes.allRoutes);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Session Login
|
|
50
|
+
|
|
51
|
+
The first public automation path is user session login through
|
|
52
|
+
`/api/auth/login`. `GraphQLClient.login()` posts the username and password,
|
|
53
|
+
then builds a GraphQL client that reuses the returned `fluxomni_session`
|
|
54
|
+
cookie for `/api` requests and `/api/subscriptions` WebSocket connection
|
|
55
|
+
params when the runtime exposes `Set-Cookie`.
|
|
56
|
+
|
|
57
|
+
Browser and same-origin callers can omit endpoints:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
const { client } = await GraphQLClient.login({
|
|
61
|
+
username,
|
|
62
|
+
password,
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Server-side callers usually pass a server base URL:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
const { client, cookieHeader } = await GraphQLClient.login({
|
|
70
|
+
baseUrl: 'http://localhost:8001',
|
|
71
|
+
username,
|
|
72
|
+
password,
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Session lifetime is controlled by the server's `sessionTtlSeconds` setting.
|
|
77
|
+
`0` or `null` disables expiry; otherwise the in-memory session expires after
|
|
78
|
+
that many seconds from login. Scripts should treat HTTP 401 or GraphQL
|
|
79
|
+
`extensions.code: "UNAUTHORIZED"` as a signal to log in again.
|
|
80
|
+
|
|
81
|
+
For same-origin browser code, keep browser wiring in the webapp boundary.
|
|
82
|
+
`@fluxomni/api-client` stays transport-only; the webapp should construct
|
|
83
|
+
same-origin clients through its local `createWebappGraphQLClient()` helper.
|
|
84
|
+
|
|
85
|
+
## Typed Generated Operations
|
|
86
|
+
|
|
87
|
+
Generated GraphQL documents and result types are exported from the package.
|
|
88
|
+
Use them when compile-time operation typing matters.
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
import { GraphQLClient, ServerInfoDocument } from '@fluxomni/api-client';
|
|
92
|
+
|
|
93
|
+
const { client } = await GraphQLClient.login({
|
|
94
|
+
username: process.env.FLUXOMNI_USERNAME!,
|
|
95
|
+
password: process.env.FLUXOMNI_PASSWORD!,
|
|
96
|
+
});
|
|
97
|
+
const data = await client.query({ query: ServerInfoDocument });
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Subscriptions
|
|
101
|
+
|
|
102
|
+
The client owns Apollo and `graphql-ws` setup so callers do not need to wire the
|
|
103
|
+
transport manually.
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import { GraphQLClient, StateDocument } from '@fluxomni/api-client';
|
|
107
|
+
|
|
108
|
+
const client = new GraphQLClient(
|
|
109
|
+
{
|
|
110
|
+
httpEndpoint: 'http://localhost:8001/api',
|
|
111
|
+
wsEndpoint: 'ws://localhost:8001/api/subscriptions',
|
|
112
|
+
credentials: 'same-origin',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
onConnect: () => console.log('connected'),
|
|
116
|
+
onDisconnect: () => console.log('disconnected'),
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const subscription = client.subscribe({
|
|
121
|
+
query: StateDocument,
|
|
122
|
+
}).subscribe({
|
|
123
|
+
next: (result) => console.log(result.data),
|
|
124
|
+
error: (error) => console.error(error),
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
subscription.unsubscribe();
|
|
128
|
+
client.stop();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Server-side subscription callers can pass a session cookie through login:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
const { client } = await GraphQLClient.login({
|
|
135
|
+
baseUrl: 'http://localhost:8001',
|
|
136
|
+
username: process.env.FLUXOMNI_USERNAME!,
|
|
137
|
+
password: process.env.FLUXOMNI_PASSWORD!,
|
|
138
|
+
wsEndpoint: 'ws://localhost:8001/api/subscriptions',
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The login helper forwards the session cookie through `connection_init.cookie`
|
|
143
|
+
for server-side `graphql-ws` callers. Browser callers normally rely on the
|
|
144
|
+
browser's same-origin cookie handling instead.
|
|
145
|
+
|
|
146
|
+
## Examples
|
|
147
|
+
|
|
148
|
+
Executable examples live under `api/examples/typescript`.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
FLUXOMNI_BASE_URL=http://127.0.0.1:8001 \
|
|
152
|
+
FLUXOMNI_USERNAME=admin \
|
|
153
|
+
FLUXOMNI_PASSWORD=... \
|
|
154
|
+
pnpm --filter @fluxomni/api-examples run session:raw-subscription
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Idempotent route convergence example:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
FLUXOMNI_BASE_URL=http://127.0.0.1:8001 \
|
|
161
|
+
FLUXOMNI_USERNAME=admin \
|
|
162
|
+
FLUXOMNI_PASSWORD=... \
|
|
163
|
+
pnpm --filter @fluxomni/api-examples run ensure-route
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Route controls example:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
FLUXOMNI_BASE_URL=http://127.0.0.1:8001 \
|
|
170
|
+
FLUXOMNI_USERNAME=admin \
|
|
171
|
+
FLUXOMNI_PASSWORD=... \
|
|
172
|
+
FLUXOMNI_ROUTE_ID=... \
|
|
173
|
+
FLUXOMNI_SOURCE_ID=... \
|
|
174
|
+
FLUXOMNI_OUTPUT_ID=... \
|
|
175
|
+
pnpm --filter @fluxomni/api-examples run manage-route-controls
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Playlist, artifact tags, settings export/import, and Fleet read/command example:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
FLUXOMNI_BASE_URL=http://127.0.0.1:8001 \
|
|
182
|
+
FLUXOMNI_USERNAME=admin \
|
|
183
|
+
FLUXOMNI_PASSWORD=... \
|
|
184
|
+
pnpm --filter @fluxomni/api-examples run manage-playlist-artifacts-settings-fleet
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
The examples compile through the API client package:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
pnpm --filter @fluxomni/api-client run examples:check
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
The examples print the public error category from `classifyGraphQLError()` next
|
|
194
|
+
to each server `extensions.code`, so scripts can use the same taxonomy as the
|
|
195
|
+
README error-handling snippet.
|
|
196
|
+
|
|
197
|
+
## Error Handling
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import {
|
|
201
|
+
ClientError,
|
|
202
|
+
GraphQLError,
|
|
203
|
+
NetworkError,
|
|
204
|
+
classifyGraphQLError,
|
|
205
|
+
} from '@fluxomni/api-client';
|
|
206
|
+
|
|
207
|
+
try {
|
|
208
|
+
await client.executeRaw('query Routes { routes { allRoutes { id } } }');
|
|
209
|
+
} catch (error) {
|
|
210
|
+
if (error instanceof GraphQLError) {
|
|
211
|
+
for (const serverError of error.errors) {
|
|
212
|
+
switch (classifyGraphQLError(serverError)) {
|
|
213
|
+
case 'unauthenticated':
|
|
214
|
+
throw new Error('Session expired; log in again.');
|
|
215
|
+
case 'forbidden':
|
|
216
|
+
throw new Error('The current role cannot run this operation.');
|
|
217
|
+
case 'not_found':
|
|
218
|
+
console.warn('Target was already absent:', serverError.code);
|
|
219
|
+
break;
|
|
220
|
+
case 'conflict':
|
|
221
|
+
case 'operation_rejected':
|
|
222
|
+
throw new Error(`State changed before the operation: ${serverError.code}`);
|
|
223
|
+
case 'runtime_unavailable':
|
|
224
|
+
throw new Error(`Runtime state is unavailable: ${serverError.code}`);
|
|
225
|
+
default:
|
|
226
|
+
throw error;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
} else if (error instanceof NetworkError) {
|
|
230
|
+
console.error('Network error:', error.message);
|
|
231
|
+
} else if (error instanceof ClientError) {
|
|
232
|
+
console.error('Client error:', error.message);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Mutation result payloads are not exceptions. Treat statuses such as `UPDATED`,
|
|
238
|
+
`UNCHANGED`, and `NOT_FOUND` as normal convergence outcomes when the schema
|
|
239
|
+
returns them.
|
|
240
|
+
|
|
241
|
+
## Development
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
pnpm install --frozen-lockfile
|
|
245
|
+
pnpm --filter @fluxomni/api-client run graphql:codegen
|
|
246
|
+
pnpm --filter @fluxomni/api-client run build
|
|
247
|
+
pnpm --filter @fluxomni/api-client run lint
|
|
248
|
+
pnpm --filter @fluxomni/api-client run test
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## License
|
|
252
|
+
|
|
253
|
+
PolyForm Noncommercial License 1.0.0
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare const SESSION_COOKIE_NAME = "fluxomni_session";
|
|
2
|
+
export type AuthRole = 'admin' | 'operator' | 'viewer';
|
|
3
|
+
export type AuthUser = {
|
|
4
|
+
id: string;
|
|
5
|
+
username: string;
|
|
6
|
+
displayName: string | null;
|
|
7
|
+
role: AuthRole;
|
|
8
|
+
};
|
|
9
|
+
export type AuthStatus = {
|
|
10
|
+
authRequired: boolean;
|
|
11
|
+
authenticated: boolean;
|
|
12
|
+
role: AuthRole | null;
|
|
13
|
+
currentUser: AuthUser | null;
|
|
14
|
+
canAccessSettings: boolean;
|
|
15
|
+
canAccessFleet: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type LoginOptions = {
|
|
18
|
+
username: string;
|
|
19
|
+
password: string;
|
|
20
|
+
/** Base server URL, for example `http://localhost:8001`. Defaults to same-origin `/api/auth/login`. */
|
|
21
|
+
baseUrl?: string;
|
|
22
|
+
/** Full auth endpoint override. Takes precedence over `baseUrl`. */
|
|
23
|
+
authEndpoint?: string;
|
|
24
|
+
/** Custom fetch implementation. */
|
|
25
|
+
fetch?: typeof fetch;
|
|
26
|
+
/** Browser credential mode for the login request. Defaults to `same-origin`. */
|
|
27
|
+
credentials?: RequestCredentials;
|
|
28
|
+
};
|
|
29
|
+
export type LoginResult = {
|
|
30
|
+
status: AuthStatus;
|
|
31
|
+
/** `Cookie` header value for server-side callers when the runtime exposes Set-Cookie. */
|
|
32
|
+
cookieHeader?: string;
|
|
33
|
+
};
|
|
34
|
+
export declare function login(options: LoginOptions): Promise<LoginResult>;
|
|
35
|
+
export declare function createSessionFetch(cookieHeader: string, fetchFn?: typeof fetch): typeof fetch;
|
|
36
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AAEtD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,IAAI,EAAE,QAAQ,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,uGAAuG;IACvG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,gFAAgF;IAChF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,yFAAyF;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CA0BvE;AAED,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,OAAO,KAAwB,GACvC,OAAO,KAAK,CAYd"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const SESSION_COOKIE_NAME = 'fluxomni_session';
|
|
2
|
+
export async function login(options) {
|
|
3
|
+
const fetchFn = options.fetch ?? globalThis.fetch;
|
|
4
|
+
if (!fetchFn) {
|
|
5
|
+
throw new Error('A fetch implementation is required for login()');
|
|
6
|
+
}
|
|
7
|
+
const response = await fetchFn(resolveAuthEndpoint(options), {
|
|
8
|
+
method: 'POST',
|
|
9
|
+
credentials: options.credentials ?? 'same-origin',
|
|
10
|
+
headers: {
|
|
11
|
+
'content-type': 'application/json',
|
|
12
|
+
},
|
|
13
|
+
body: JSON.stringify({
|
|
14
|
+
username: options.username,
|
|
15
|
+
password: options.password,
|
|
16
|
+
}),
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(await readAuthError(response));
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
status: (await response.json()),
|
|
23
|
+
cookieHeader: sessionCookieHeaderFromResponse(response),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function createSessionFetch(cookieHeader, fetchFn = globalThis.fetch) {
|
|
27
|
+
return (input, init = {}) => {
|
|
28
|
+
const headers = new Headers(init.headers);
|
|
29
|
+
if (!headers.has('cookie')) {
|
|
30
|
+
headers.set('cookie', cookieHeader);
|
|
31
|
+
}
|
|
32
|
+
return fetchFn(input, {
|
|
33
|
+
...init,
|
|
34
|
+
headers,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function resolveAuthEndpoint(options) {
|
|
39
|
+
if (options.authEndpoint) {
|
|
40
|
+
return options.authEndpoint;
|
|
41
|
+
}
|
|
42
|
+
if (options.baseUrl) {
|
|
43
|
+
return new URL('/api/auth/login', options.baseUrl).toString();
|
|
44
|
+
}
|
|
45
|
+
return '/api/auth/login';
|
|
46
|
+
}
|
|
47
|
+
function sessionCookieHeaderFromResponse(response) {
|
|
48
|
+
const setCookie = response.headers.get('set-cookie');
|
|
49
|
+
if (!setCookie) {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
return sessionCookieHeaderFromSetCookie(setCookie);
|
|
53
|
+
}
|
|
54
|
+
function sessionCookieHeaderFromSetCookie(setCookie) {
|
|
55
|
+
const cookiePair = setCookie
|
|
56
|
+
.split(',')
|
|
57
|
+
.map((part) => part.trim())
|
|
58
|
+
.find((part) => part.startsWith(`${SESSION_COOKIE_NAME}=`))
|
|
59
|
+
?.split(';')[0];
|
|
60
|
+
return cookiePair && cookiePair.includes('=') ? cookiePair : undefined;
|
|
61
|
+
}
|
|
62
|
+
async function readAuthError(response) {
|
|
63
|
+
try {
|
|
64
|
+
const body = (await response.json());
|
|
65
|
+
return body.message || `Authentication failed (${response.status})`;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return `Authentication failed (${response.status})`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { Observable } from '@apollo/client/core/index.js';
|
|
2
|
+
import { ApolloClient, type DocumentNode, type FetchResult, type MutationOptions, type NormalizedCacheObject, type OperationVariables, type QueryOptions, type SubscriptionOptions } from '@apollo/client/core/index.js';
|
|
3
|
+
import { type AuthStatus, type LoginOptions } from './auth.js';
|
|
4
|
+
export interface GraphQLClientConfig {
|
|
5
|
+
/** HTTP endpoint for queries and mutations */
|
|
6
|
+
httpEndpoint: string;
|
|
7
|
+
/** WebSocket endpoint for subscriptions (optional) */
|
|
8
|
+
wsEndpoint?: string;
|
|
9
|
+
/** Optional Authorization header for trusted/internal callers; user auth normally uses session cookies. */
|
|
10
|
+
authHeader?: string;
|
|
11
|
+
/** Cookie header for server-side session-auth callers, for example `fluxomni_session=...`. */
|
|
12
|
+
cookieHeader?: string;
|
|
13
|
+
/** Browser credential mode for GraphQL HTTP requests. */
|
|
14
|
+
credentials?: RequestCredentials;
|
|
15
|
+
/** Custom fetch function for HTTP requests */
|
|
16
|
+
fetch?: typeof fetch;
|
|
17
|
+
}
|
|
18
|
+
export interface ConnectionCallbacks {
|
|
19
|
+
onConnect?: () => void;
|
|
20
|
+
onDisconnect?: () => void;
|
|
21
|
+
onError?: (error: unknown) => void;
|
|
22
|
+
}
|
|
23
|
+
export type GraphQLClientLoginOptions = LoginOptions & {
|
|
24
|
+
/** HTTP endpoint for queries and mutations. Defaults to `${baseUrl}/api` or `/api` for same-origin callers. */
|
|
25
|
+
httpEndpoint?: string;
|
|
26
|
+
/** WebSocket endpoint for subscriptions. Defaults to `ws(s)://<baseUrl>/api/subscriptions` or `/api/subscriptions` for same-origin callers. */
|
|
27
|
+
wsEndpoint?: string;
|
|
28
|
+
};
|
|
29
|
+
export type GraphQLClientLoginResult = {
|
|
30
|
+
client: GraphQLClient;
|
|
31
|
+
status: AuthStatus;
|
|
32
|
+
/** `Cookie` header value for server-side callers when the runtime exposes Set-Cookie. */
|
|
33
|
+
cookieHeader?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Low-level GraphQL client wrapping Apollo Client.
|
|
37
|
+
*
|
|
38
|
+
* Provides typed query, mutation, and subscription execution with consistent error handling.
|
|
39
|
+
*/
|
|
40
|
+
export declare class GraphQLClient {
|
|
41
|
+
private readonly config;
|
|
42
|
+
private apolloClient;
|
|
43
|
+
private wsClient?;
|
|
44
|
+
constructor(config: GraphQLClientConfig, callbacks?: ConnectionCallbacks);
|
|
45
|
+
/**
|
|
46
|
+
* Log in with the session endpoint and return a session-aware client.
|
|
47
|
+
*/
|
|
48
|
+
static login(options: GraphQLClientLoginOptions, callbacks?: ConnectionCallbacks): Promise<GraphQLClientLoginResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Create a client from environment variables.
|
|
51
|
+
*/
|
|
52
|
+
static fromEnv(env?: Record<string, string | undefined>, callbacks?: ConnectionCallbacks): GraphQLClient;
|
|
53
|
+
/**
|
|
54
|
+
* Get the underlying Apollo Client instance.
|
|
55
|
+
*/
|
|
56
|
+
get apollo(): ApolloClient<NormalizedCacheObject>;
|
|
57
|
+
/**
|
|
58
|
+
* Execute a GraphQL query.
|
|
59
|
+
*/
|
|
60
|
+
query<TData, TVariables extends OperationVariables = OperationVariables>(options: QueryOptions<TVariables, TData>): Promise<TData>;
|
|
61
|
+
/**
|
|
62
|
+
* Execute a GraphQL mutation.
|
|
63
|
+
*/
|
|
64
|
+
mutate<TData, TVariables extends OperationVariables = OperationVariables>(options: MutationOptions<TData, TVariables>): Promise<TData>;
|
|
65
|
+
/**
|
|
66
|
+
* Create a subscription observable.
|
|
67
|
+
*/
|
|
68
|
+
subscribe<TData, TVariables extends OperationVariables = OperationVariables>(options: SubscriptionOptions<TVariables, TData>): Observable<FetchResult<TData>>;
|
|
69
|
+
/**
|
|
70
|
+
* Execute a raw GraphQL operation with untyped variables.
|
|
71
|
+
*
|
|
72
|
+
* This is the recommended automation surface when generated operation
|
|
73
|
+
* documents are more structure than needed.
|
|
74
|
+
*/
|
|
75
|
+
executeRaw<TData = unknown>(query: DocumentNode | string, variables?: Record<string, unknown>): Promise<TData>;
|
|
76
|
+
/**
|
|
77
|
+
* Stop the client and clean up resources.
|
|
78
|
+
*/
|
|
79
|
+
stop(): void;
|
|
80
|
+
/**
|
|
81
|
+
* Clear the Apollo cache.
|
|
82
|
+
*/
|
|
83
|
+
clearCache(): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Reset the Apollo store (clear cache and refetch active queries).
|
|
86
|
+
*/
|
|
87
|
+
resetStore(): Promise<void>;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|