@rytass/bpm-core-client 0.1.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/CHANGELOG.md +40 -0
- package/LICENSE +21 -0
- package/README.md +191 -0
- package/package.json +82 -0
- package/src/index.d.ts +3 -0
- package/src/index.js +7 -0
- package/src/index.js.map +1 -0
- package/src/lib/api-auth-client.d.ts +73 -0
- package/src/lib/api-auth-client.js +121 -0
- package/src/lib/api-auth-client.js.map +1 -0
- package/src/lib/form/form-api.d.ts +48 -0
- package/src/lib/form/form-api.js +228 -0
- package/src/lib/form/form-api.js.map +1 -0
- package/src/lib/form/form-rendering.d.ts +52 -0
- package/src/lib/form/form-rendering.js +341 -0
- package/src/lib/form/form-rendering.js.map +1 -0
- package/src/lib/form/index.d.ts +2 -0
- package/src/lib/form/index.js +6 -0
- package/src/lib/form/index.js.map +1 -0
- package/src/lib/graphql-client.d.ts +45 -0
- package/src/lib/graphql-client.js +92 -0
- package/src/lib/graphql-client.js.map +1 -0
- package/src/lib/member-api.d.ts +49 -0
- package/src/lib/member-api.js +72 -0
- package/src/lib/member-api.js.map +1 -0
- package/src/lib/organization/index.d.ts +1 -0
- package/src/lib/organization/index.js +5 -0
- package/src/lib/organization/index.js.map +1 -0
- package/src/lib/organization/organization-api.d.ts +168 -0
- package/src/lib/organization/organization-api.js +394 -0
- package/src/lib/organization/organization-api.js.map +1 -0
- package/src/lib/template/index.d.ts +1 -0
- package/src/lib/template/index.js +5 -0
- package/src/lib/template/index.js.map +1 -0
- package/src/lib/template/template-api.d.ts +150 -0
- package/src/lib/template/template-api.js +407 -0
- package/src/lib/template/template-api.js.map +1 -0
- package/src/lib/workflow/index.d.ts +1 -0
- package/src/lib/workflow/index.js +5 -0
- package/src/lib/workflow/index.js.map +1 -0
- package/src/lib/workflow/workflow-api.d.ts +376 -0
- package/src/lib/workflow/workflow-api.js +867 -0
- package/src/lib/workflow/workflow-api.js.map +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@rytass/bpm-core-client` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
Releases are managed by [`nx release`](https://nx.dev/recipes/nx-release) with
|
|
9
|
+
Conventional Commits — see `nx.json` for the release config.
|
|
10
|
+
|
|
11
|
+
## 0.1.0 — Unreleased
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Initial published surface extracted from `apps/client` of the BPMCore
|
|
16
|
+
monorepo:
|
|
17
|
+
- Root: `requestGraphQl`, endpoint resolvers, REST auth client (`loginApi`,
|
|
18
|
+
`logoutApi`, `readApiCurrentMember`, `listApiTestMembers`), member
|
|
19
|
+
directory queries (`resolveMembers`, `searchMembers`,
|
|
20
|
+
`listMemberDirectoryPage`).
|
|
21
|
+
- `/organization`: org unit / position / membership / manager resolution
|
|
22
|
+
queries and mutations.
|
|
23
|
+
- `/form`: form definition CRUD, version management, schema rendering
|
|
24
|
+
helpers.
|
|
25
|
+
- `/template`: approval template CRUD, category management, version
|
|
26
|
+
publish / rollback.
|
|
27
|
+
- `/workflow`: instance / task / notification / attachment / signature
|
|
28
|
+
operations.
|
|
29
|
+
- Endpoint defaults: `http://localhost:17603/graphql` on local hostnames,
|
|
30
|
+
same-origin `/graphql` on deployed hostnames, plus root-level
|
|
31
|
+
`/auth/*` (no `/api` prefix). Overridable through `NEXT_PUBLIC_API_URL`
|
|
32
|
+
and `NEXT_PUBLIC_API_AUTH_URL`.
|
|
33
|
+
|
|
34
|
+
### Notes
|
|
35
|
+
|
|
36
|
+
- `@rytass/bpm-core-shared` is a `peerDependency` (`^0.1.0`).
|
|
37
|
+
- The package ships without `"type"` at source level so Next.js webpack
|
|
38
|
+
resolving the path alias to TypeScript source does not flag CJS / ESM
|
|
39
|
+
conflicts; the publish pipeline injects `"type": "commonjs"` into the
|
|
40
|
+
tarball's `package.json`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rytass
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @rytass/bpm-core-client
|
|
2
|
+
|
|
3
|
+
Framework-agnostic TypeScript client for the BPM approval workflow GraphQL
|
|
4
|
+
surface published by
|
|
5
|
+
[`@rytass/bpm-core-nestjs-module`](https://www.npmjs.com/package/@rytass/bpm-core-nestjs-module).
|
|
6
|
+
|
|
7
|
+
This package contains:
|
|
8
|
+
|
|
9
|
+
- A tiny `fetch`-based GraphQL transport (`requestGraphQl`).
|
|
10
|
+
- Endpoint resolution helpers (`readGraphQlEndpoint`, `readApiBaseUrl`).
|
|
11
|
+
- The BPM host auth REST client (`loginApi`, `logoutApi`, `readApiCurrentMember`, `listApiTestMembers`).
|
|
12
|
+
- Pre-baked typed GraphQL operations for organization, member directory, form
|
|
13
|
+
definition, approval template, workflow instance, task, notification,
|
|
14
|
+
attachment, signature, and delegation flows.
|
|
15
|
+
|
|
16
|
+
It does **not** ship React components, hooks, or UI. Hosts can call the
|
|
17
|
+
functions directly from any framework (Next.js / Vite / Remix / plain Node).
|
|
18
|
+
|
|
19
|
+
## Package Status
|
|
20
|
+
|
|
21
|
+
Current version: `0.0.1`
|
|
22
|
+
|
|
23
|
+
The package intentionally stays framework-agnostic so it can be reused from
|
|
24
|
+
Next.js Server Components, Server Actions, plain React, or non-React
|
|
25
|
+
runtimes. There is no Apollo Client setup.
|
|
26
|
+
|
|
27
|
+
## Install
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pnpm add @rytass/bpm-core-client @rytass/bpm-core-shared
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`@rytass/bpm-core-shared` is a `peerDependency` and must be installed
|
|
34
|
+
alongside.
|
|
35
|
+
|
|
36
|
+
The browser bundle uses the standard Fetch API; Node 20+ also has `fetch`
|
|
37
|
+
built in. No `graphql` runtime package is required.
|
|
38
|
+
|
|
39
|
+
**TypeScript moduleResolution**: prefer `node16`, `nodenext`, or `bundler` in
|
|
40
|
+
your `tsconfig.json` so the package's `exports` field is honored. Classic
|
|
41
|
+
`moduleResolution: "node"` also works through the `typesVersions` fallback
|
|
42
|
+
shipped with this package, but is on TypeScript's long-term deprecation
|
|
43
|
+
path — new projects should opt in to modern resolution.
|
|
44
|
+
|
|
45
|
+
## Endpoint Resolution
|
|
46
|
+
|
|
47
|
+
By default the client targets the same origin (no `/api` prefix) — see
|
|
48
|
+
[`docs/10-bpm-embedding-auth.md`](../../docs/10-bpm-embedding-auth.md) for the
|
|
49
|
+
host contract. Endpoint resolution rules:
|
|
50
|
+
|
|
51
|
+
| Source | Behavior |
|
|
52
|
+
| ----------------------------------------------- | -------------------------------------------------------------------------- |
|
|
53
|
+
| `process.env.NEXT_PUBLIC_API_URL` | If set, used as the GraphQL endpoint URL. |
|
|
54
|
+
| `process.env.NEXT_PUBLIC_API_AUTH_URL` | If set, used as the base URL for the REST `/auth/*` endpoints. |
|
|
55
|
+
| Browser hostname `localhost` or `127.0.0.1` | GraphQL defaults to `http://localhost:17603/graphql`. |
|
|
56
|
+
| Deployed hostname (anything else, or SSR) | GraphQL defaults to same-origin `/graphql`; auth uses same-origin root. |
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import {
|
|
60
|
+
loginApi,
|
|
61
|
+
readApiCurrentMember,
|
|
62
|
+
readApiBaseUrl,
|
|
63
|
+
readGraphQlEndpoint,
|
|
64
|
+
requestGraphQl,
|
|
65
|
+
} from '@rytass/bpm-core-client';
|
|
66
|
+
|
|
67
|
+
console.log(readGraphQlEndpoint());
|
|
68
|
+
console.log(readApiBaseUrl());
|
|
69
|
+
|
|
70
|
+
const member = await loginApi({ identifier: 'member-001', password: 'demo' });
|
|
71
|
+
const currentMember = await readApiCurrentMember();
|
|
72
|
+
|
|
73
|
+
interface PingQueryData {
|
|
74
|
+
readonly memberCount: number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const data = await requestGraphQl<PingQueryData>(`
|
|
78
|
+
query Ping {
|
|
79
|
+
memberCount
|
|
80
|
+
}
|
|
81
|
+
`);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`requestGraphQl` always sends `credentials: 'include'`, so the HTTP-only
|
|
85
|
+
session cookie issued by the BPM host's `/auth/login` flows back automatically
|
|
86
|
+
on subsequent calls.
|
|
87
|
+
|
|
88
|
+
## Subpath Overview
|
|
89
|
+
|
|
90
|
+
| Import path | Contents |
|
|
91
|
+
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| `@rytass/bpm-core-client` | GraphQL transport, endpoint resolution, REST auth client, member directory queries. |
|
|
93
|
+
| `@rytass/bpm-core-client/organization` | Org unit CRUD, position CRUD, membership CRUD, manager resolution. |
|
|
94
|
+
| `@rytass/bpm-core-client/form` | Form definition CRUD, form version management, schema parsing helpers (`form-rendering`). |
|
|
95
|
+
| `@rytass/bpm-core-client/template` | Approval template CRUD, category management, version publish/revert. |
|
|
96
|
+
| `@rytass/bpm-core-client/workflow` | Instance submit / decide / cancel, task queries, notification queries, attachment & signature reads. |
|
|
97
|
+
|
|
98
|
+
Every subpath uses the same `requestGraphQl` transport from the root. Hosts
|
|
99
|
+
can mix and match — for example a read-only dashboard might only import
|
|
100
|
+
`workflow` queries, never reaching for `/organization` mutations.
|
|
101
|
+
|
|
102
|
+
## Auth REST Endpoints
|
|
103
|
+
|
|
104
|
+
The BPM wrapper-host exposes the following endpoints under the host root (no
|
|
105
|
+
`/api` prefix; do not enable Nest `setGlobalPrefix` on a BPM host):
|
|
106
|
+
|
|
107
|
+
| Method | Path | Function |
|
|
108
|
+
| ------ | --------------------- | ----------------------------------------- |
|
|
109
|
+
| GET | `/auth/test-members` | `listApiTestMembers()` |
|
|
110
|
+
| POST | `/auth/login` | `loginApi({ identifier, password })` |
|
|
111
|
+
| GET | `/auth/me` | `readApiCurrentMember()` (returns `null` on `401`) |
|
|
112
|
+
| POST | `/auth/logout` | `logoutApi()` |
|
|
113
|
+
|
|
114
|
+
If your production host names its auth endpoints differently, set
|
|
115
|
+
`NEXT_PUBLIC_API_AUTH_URL` so the client points at the right base URL, and
|
|
116
|
+
implement those paths server-side.
|
|
117
|
+
|
|
118
|
+
## GraphQL Operations
|
|
119
|
+
|
|
120
|
+
Each subpath exports typed wrapper functions over `requestGraphQl`. Records
|
|
121
|
+
returned from these functions match the BPM GraphQL schema field-by-field.
|
|
122
|
+
Examples:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { resolveMembers, searchMembers } from '@rytass/bpm-core-client';
|
|
126
|
+
import {
|
|
127
|
+
listApprovalInstances,
|
|
128
|
+
decideTask,
|
|
129
|
+
submitApprovalInstance,
|
|
130
|
+
} from '@rytass/bpm-core-client/workflow';
|
|
131
|
+
import { listApprovalTemplates } from '@rytass/bpm-core-client/template';
|
|
132
|
+
import { listFormDefinitions } from '@rytass/bpm-core-client/form';
|
|
133
|
+
import { listOrgUnits, listPositions } from '@rytass/bpm-core-client/organization';
|
|
134
|
+
|
|
135
|
+
const members = await resolveMembers(['member-001', 'member-002']);
|
|
136
|
+
const templates = await listApprovalTemplates({ status: 'PUBLISHED' });
|
|
137
|
+
const inbox = await listApprovalInstances({ assigneeMemberId: members[0]?.memberId ?? null });
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The available operations track the BPM resolvers; consult the GraphQL schema
|
|
141
|
+
file generated by the host's `GraphQLModule` (`autoSchemaFile`) for the
|
|
142
|
+
authoritative list.
|
|
143
|
+
|
|
144
|
+
## React / Next.js Integration
|
|
145
|
+
|
|
146
|
+
The client is intentionally hookless. Hosts compose their own hook layer on
|
|
147
|
+
top — for example with React Query or SWR:
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
'use client';
|
|
151
|
+
|
|
152
|
+
import { useQuery } from '@tanstack/react-query';
|
|
153
|
+
import { resolveMembers } from '@rytass/bpm-core-client';
|
|
154
|
+
|
|
155
|
+
export function useMembers(memberIds: readonly string[]) {
|
|
156
|
+
return useQuery({
|
|
157
|
+
queryKey: ['members', memberIds],
|
|
158
|
+
queryFn: () => resolveMembers(memberIds),
|
|
159
|
+
enabled: memberIds.length > 0,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
For Next.js App Router, call the same functions from Server Components or
|
|
165
|
+
Server Actions — they only need standard `fetch`.
|
|
166
|
+
|
|
167
|
+
## Local Development
|
|
168
|
+
|
|
169
|
+
From this monorepo the client is automatically available through the
|
|
170
|
+
`@rytass/bpm-core-client` TypeScript path alias; no `pnpm link` step is
|
|
171
|
+
required.
|
|
172
|
+
|
|
173
|
+
External consumers should run against a host built with
|
|
174
|
+
`@rytass/bpm-core-nestjs-module` (sample host: `apps/api` in this repo). The
|
|
175
|
+
sample host exposes:
|
|
176
|
+
|
|
177
|
+
- `http://localhost:17603/graphql`
|
|
178
|
+
- `http://localhost:17603/auth/*`
|
|
179
|
+
- `http://localhost:17603/attachments/:id/download`
|
|
180
|
+
|
|
181
|
+
## Verification
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
pnpm nx typecheck bpm-core-client
|
|
185
|
+
pnpm nx test bpm-core-client
|
|
186
|
+
pnpm nx build bpm-core-client
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## License
|
|
190
|
+
|
|
191
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rytass/bpm-core-client",
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
"keywords": [
|
|
6
|
+
"bpm",
|
|
7
|
+
"approval",
|
|
8
|
+
"workflow",
|
|
9
|
+
"graphql",
|
|
10
|
+
"client",
|
|
11
|
+
"fetch",
|
|
12
|
+
"nextjs",
|
|
13
|
+
"react",
|
|
14
|
+
"rytass"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/Rytass/BPMCore#readme",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/Rytass/BPMCore.git",
|
|
20
|
+
"directory": "libs/bpm-core-client"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/Rytass/BPMCore/issues"
|
|
24
|
+
},
|
|
25
|
+
"author": "Rytass <hello@rytass.com>",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"private": false,
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20.0.0"
|
|
33
|
+
},
|
|
34
|
+
"main": "./src/index.js",
|
|
35
|
+
"types": "./src/index.d.ts",
|
|
36
|
+
"typesVersions": {
|
|
37
|
+
"*": {
|
|
38
|
+
"form": [
|
|
39
|
+
"./src/lib/form/index.d.ts"
|
|
40
|
+
],
|
|
41
|
+
"organization": [
|
|
42
|
+
"./src/lib/organization/index.d.ts"
|
|
43
|
+
],
|
|
44
|
+
"template": [
|
|
45
|
+
"./src/lib/template/index.d.ts"
|
|
46
|
+
],
|
|
47
|
+
"workflow": [
|
|
48
|
+
"./src/lib/workflow/index.d.ts"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"exports": {
|
|
53
|
+
".": {
|
|
54
|
+
"types": "./src/index.d.ts",
|
|
55
|
+
"default": "./src/index.js"
|
|
56
|
+
},
|
|
57
|
+
"./package.json": "./package.json",
|
|
58
|
+
"./organization": {
|
|
59
|
+
"types": "./src/lib/organization/index.d.ts",
|
|
60
|
+
"default": "./src/lib/organization/index.js"
|
|
61
|
+
},
|
|
62
|
+
"./form": {
|
|
63
|
+
"types": "./src/lib/form/index.d.ts",
|
|
64
|
+
"default": "./src/lib/form/index.js"
|
|
65
|
+
},
|
|
66
|
+
"./template": {
|
|
67
|
+
"types": "./src/lib/template/index.d.ts",
|
|
68
|
+
"default": "./src/lib/template/index.js"
|
|
69
|
+
},
|
|
70
|
+
"./workflow": {
|
|
71
|
+
"types": "./src/lib/workflow/index.d.ts",
|
|
72
|
+
"default": "./src/lib/workflow/index.js"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@rytass/bpm-core-shared": "^0.1.0"
|
|
77
|
+
},
|
|
78
|
+
"dependencies": {
|
|
79
|
+
"tslib": "^2.3.0"
|
|
80
|
+
},
|
|
81
|
+
"type": "commonjs"
|
|
82
|
+
}
|
package/src/index.d.ts
ADDED
package/src/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./lib/api-auth-client"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./lib/graphql-client"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./lib/member-api"), exports);
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/bpm-core-client/src/index.ts"],"names":[],"mappings":";;;AAAA,gEAAsC;AACtC,+DAAqC;AACrC,2DAAiC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authenticated BPM member returned by {@link loginApi} and
|
|
3
|
+
* {@link readApiCurrentMember}.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the shape that BPM-compatible wrapper hosts emit from their
|
|
6
|
+
* `POST /auth/login` and `GET /auth/me` endpoints. Roles and permissions
|
|
7
|
+
* are used by BPM's `BPMAdminGuard` / `BPMDesignerGuard`.
|
|
8
|
+
*/
|
|
9
|
+
export interface ApiMember {
|
|
10
|
+
readonly email: string;
|
|
11
|
+
readonly expiresAt: string;
|
|
12
|
+
readonly memberId: string;
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly permissions: readonly string[];
|
|
15
|
+
readonly roles: readonly string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Reduced member shape returned by {@link listApiTestMembers}. Excludes
|
|
19
|
+
* `permissions` and `expiresAt` because the test-members endpoint is meant
|
|
20
|
+
* for picker UIs in dev / demo, not for session establishment.
|
|
21
|
+
*/
|
|
22
|
+
export interface ApiPublicMember {
|
|
23
|
+
readonly email: string;
|
|
24
|
+
readonly memberId: string;
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly roles: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Lists seeded test members exposed by the host's `/auth/test-members`
|
|
30
|
+
* endpoint. Hosts targeting production typically disable this endpoint or
|
|
31
|
+
* gate it behind a feature flag.
|
|
32
|
+
*/
|
|
33
|
+
export declare function listApiTestMembers(): Promise<readonly ApiPublicMember[]>;
|
|
34
|
+
/**
|
|
35
|
+
* Performs a login against the host's `POST /auth/login` endpoint. On
|
|
36
|
+
* success the host issues an HTTP-only session cookie that subsequent
|
|
37
|
+
* {@link requestGraphQl} calls automatically carry, because
|
|
38
|
+
* {@link requestApi} uses `credentials: 'include'`.
|
|
39
|
+
*
|
|
40
|
+
* Throws on HTTP errors with a message extracted from the response body
|
|
41
|
+
* when available.
|
|
42
|
+
*
|
|
43
|
+
* @param input.identifier - Member id, email, or any other identifier the
|
|
44
|
+
* host understands.
|
|
45
|
+
* @param input.password - Cleartext credential — TLS is the consumer's
|
|
46
|
+
* responsibility.
|
|
47
|
+
*/
|
|
48
|
+
export declare function loginApi(input: {
|
|
49
|
+
readonly identifier: string;
|
|
50
|
+
readonly password: string;
|
|
51
|
+
}): Promise<ApiMember>;
|
|
52
|
+
/**
|
|
53
|
+
* Calls `POST /auth/logout` on the host. The host clears the session
|
|
54
|
+
* cookie. Safe to call when not logged in (host should return 200).
|
|
55
|
+
*/
|
|
56
|
+
export declare function logoutApi(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Reads the currently authenticated member from `GET /auth/me`.
|
|
59
|
+
*
|
|
60
|
+
* Returns `null` when the host replies `401`, which is the conventional
|
|
61
|
+
* way to signal "no active session". Any other HTTP failure throws.
|
|
62
|
+
*/
|
|
63
|
+
export declare function readApiCurrentMember(): Promise<ApiMember | null>;
|
|
64
|
+
/**
|
|
65
|
+
* Resolves the base URL used by the REST `/auth/*` calls.
|
|
66
|
+
*
|
|
67
|
+
* Resolution order:
|
|
68
|
+
* 1. `process.env.NEXT_PUBLIC_API_AUTH_URL` if non-empty.
|
|
69
|
+
* 2. Derived from {@link readGraphQlEndpoint}'s origin — the host is
|
|
70
|
+
* assumed to expose both `/graphql` and `/auth/*` at the same origin.
|
|
71
|
+
*/
|
|
72
|
+
export declare function readApiBaseUrl(): string;
|
|
73
|
+
export declare function resolveApiBaseUrlFromGraphQlEndpoint(graphQlEndpoint: string): string;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listApiTestMembers = listApiTestMembers;
|
|
4
|
+
exports.loginApi = loginApi;
|
|
5
|
+
exports.logoutApi = logoutApi;
|
|
6
|
+
exports.readApiCurrentMember = readApiCurrentMember;
|
|
7
|
+
exports.readApiBaseUrl = readApiBaseUrl;
|
|
8
|
+
exports.resolveApiBaseUrlFromGraphQlEndpoint = resolveApiBaseUrlFromGraphQlEndpoint;
|
|
9
|
+
const graphql_client_1 = require("./graphql-client");
|
|
10
|
+
/**
|
|
11
|
+
* Lists seeded test members exposed by the host's `/auth/test-members`
|
|
12
|
+
* endpoint. Hosts targeting production typically disable this endpoint or
|
|
13
|
+
* gate it behind a feature flag.
|
|
14
|
+
*/
|
|
15
|
+
async function listApiTestMembers() {
|
|
16
|
+
return requestApi('/auth/test-members');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Performs a login against the host's `POST /auth/login` endpoint. On
|
|
20
|
+
* success the host issues an HTTP-only session cookie that subsequent
|
|
21
|
+
* {@link requestGraphQl} calls automatically carry, because
|
|
22
|
+
* {@link requestApi} uses `credentials: 'include'`.
|
|
23
|
+
*
|
|
24
|
+
* Throws on HTTP errors with a message extracted from the response body
|
|
25
|
+
* when available.
|
|
26
|
+
*
|
|
27
|
+
* @param input.identifier - Member id, email, or any other identifier the
|
|
28
|
+
* host understands.
|
|
29
|
+
* @param input.password - Cleartext credential — TLS is the consumer's
|
|
30
|
+
* responsibility.
|
|
31
|
+
*/
|
|
32
|
+
async function loginApi(input) {
|
|
33
|
+
return requestApi('/auth/login', {
|
|
34
|
+
body: JSON.stringify(input),
|
|
35
|
+
headers: { 'Content-Type': 'application/json' },
|
|
36
|
+
method: 'POST',
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Calls `POST /auth/logout` on the host. The host clears the session
|
|
41
|
+
* cookie. Safe to call when not logged in (host should return 200).
|
|
42
|
+
*/
|
|
43
|
+
async function logoutApi() {
|
|
44
|
+
await requestApi('/auth/logout', {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reads the currently authenticated member from `GET /auth/me`.
|
|
50
|
+
*
|
|
51
|
+
* Returns `null` when the host replies `401`, which is the conventional
|
|
52
|
+
* way to signal "no active session". Any other HTTP failure throws.
|
|
53
|
+
*/
|
|
54
|
+
async function readApiCurrentMember() {
|
|
55
|
+
try {
|
|
56
|
+
return await requestApi('/auth/me');
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
if (error instanceof ApiRequestError && error.status === 401) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolves the base URL used by the REST `/auth/*` calls.
|
|
67
|
+
*
|
|
68
|
+
* Resolution order:
|
|
69
|
+
* 1. `process.env.NEXT_PUBLIC_API_AUTH_URL` if non-empty.
|
|
70
|
+
* 2. Derived from {@link readGraphQlEndpoint}'s origin — the host is
|
|
71
|
+
* assumed to expose both `/graphql` and `/auth/*` at the same origin.
|
|
72
|
+
*/
|
|
73
|
+
function readApiBaseUrl() {
|
|
74
|
+
const explicitApiBaseUrl = process.env.NEXT_PUBLIC_API_AUTH_URL?.trim();
|
|
75
|
+
if (explicitApiBaseUrl) {
|
|
76
|
+
return explicitApiBaseUrl.replace(/\/$/, '');
|
|
77
|
+
}
|
|
78
|
+
const graphQlEndpoint = (0, graphql_client_1.readGraphQlEndpoint)();
|
|
79
|
+
return resolveApiBaseUrlFromGraphQlEndpoint(graphQlEndpoint);
|
|
80
|
+
}
|
|
81
|
+
function resolveApiBaseUrlFromGraphQlEndpoint(graphQlEndpoint) {
|
|
82
|
+
if (!isAbsoluteUrl(graphQlEndpoint)) {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
const endpoint = new URL(graphQlEndpoint);
|
|
86
|
+
endpoint.pathname = '/';
|
|
87
|
+
endpoint.search = '';
|
|
88
|
+
endpoint.hash = '';
|
|
89
|
+
return endpoint.toString().replace(/\/$/, '');
|
|
90
|
+
}
|
|
91
|
+
async function requestApi(path, init) {
|
|
92
|
+
const response = await fetch(`${readApiBaseUrl()}${path}`, {
|
|
93
|
+
credentials: 'include',
|
|
94
|
+
...init,
|
|
95
|
+
});
|
|
96
|
+
if (!response.ok) {
|
|
97
|
+
throw new ApiRequestError(response.status, await readError(response));
|
|
98
|
+
}
|
|
99
|
+
return (await response.json());
|
|
100
|
+
}
|
|
101
|
+
async function readError(response) {
|
|
102
|
+
try {
|
|
103
|
+
const payload = (await response.json());
|
|
104
|
+
return typeof payload.message === 'string'
|
|
105
|
+
? payload.message
|
|
106
|
+
: `BPM API request failed with HTTP ${response.status}`;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return `BPM API request failed with HTTP ${response.status}`;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
class ApiRequestError extends Error {
|
|
113
|
+
constructor(status, message) {
|
|
114
|
+
super(message);
|
|
115
|
+
this.status = status;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function isAbsoluteUrl(value) {
|
|
119
|
+
return value.startsWith('http://') || value.startsWith('https://');
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=api-auth-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-auth-client.js","sourceRoot":"","sources":["../../../../../libs/bpm-core-client/src/lib/api-auth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { FormDefinitionSchema, FormFieldDefinition, FormUiSchema } from '@rytass/bpm-core-shared/form';
|
|
2
|
+
export interface FormDefinitionRecord {
|
|
3
|
+
readonly currentVersionId: string | null;
|
|
4
|
+
readonly currentVersionCreatedAt: string | null;
|
|
5
|
+
readonly currentVersionNumber: number | null;
|
|
6
|
+
readonly currentVersionPublishedAt: string | null;
|
|
7
|
+
readonly description: string | null;
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly updatedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export type FormDefinitionListStatus = 'DRAFT' | 'PUBLISHED';
|
|
13
|
+
export interface FormDefinitionVersionRecord {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly publishedAt: string | null;
|
|
16
|
+
readonly schema: FormDefinitionSchema;
|
|
17
|
+
readonly schemaJson: string;
|
|
18
|
+
readonly status: 'ARCHIVED' | 'DRAFT' | 'PUBLISHED';
|
|
19
|
+
readonly uiSchema: FormUiSchema;
|
|
20
|
+
readonly uiSchemaJson: string;
|
|
21
|
+
readonly updatedAt: string;
|
|
22
|
+
readonly version: number;
|
|
23
|
+
}
|
|
24
|
+
export interface FormBuilderRecord {
|
|
25
|
+
readonly definition: FormDefinitionRecord;
|
|
26
|
+
readonly versions: readonly FormDefinitionVersionRecord[];
|
|
27
|
+
}
|
|
28
|
+
export interface FormSchemaLintResult {
|
|
29
|
+
readonly errors: readonly string[];
|
|
30
|
+
readonly valid: boolean;
|
|
31
|
+
}
|
|
32
|
+
export declare function listFormDefinitions(): Promise<readonly FormDefinitionRecord[]>;
|
|
33
|
+
export declare function listFormDefinitionsPage({ page, pageSize, status, }: {
|
|
34
|
+
readonly page: number;
|
|
35
|
+
readonly pageSize: number;
|
|
36
|
+
readonly status?: FormDefinitionListStatus | null;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
readonly forms: readonly FormDefinitionRecord[];
|
|
39
|
+
readonly totalCount: number;
|
|
40
|
+
}>;
|
|
41
|
+
export declare function createFormDefinition(name: string): Promise<string>;
|
|
42
|
+
export declare function updateFormDefinition(id: string, name: string): Promise<FormDefinitionRecord>;
|
|
43
|
+
export declare function readFormBuilder(formDefinitionId: string): Promise<FormBuilderRecord>;
|
|
44
|
+
export declare function updateFormDefinitionDraft(versionId: string, schema: FormDefinitionSchema, uiSchema: FormUiSchema): Promise<FormDefinitionVersionRecord>;
|
|
45
|
+
export declare function publishFormDefinitionVersion(versionId: string): Promise<FormDefinitionVersionRecord>;
|
|
46
|
+
export declare function forkFormDefinition(formDefinitionId: string): Promise<FormDefinitionVersionRecord>;
|
|
47
|
+
export declare function lintFormSchema(schema: FormDefinitionSchema, uiSchema: FormUiSchema): Promise<FormSchemaLintResult>;
|
|
48
|
+
export declare function createFieldDefinition(type: FormFieldDefinition['type'], index: number): FormFieldDefinition;
|