@approvio/ts-sdk 0.0.8 → 0.0.9
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/index.cjs +603 -0
- package/dist/index.d.cts +145 -0
- package/dist/index.d.mts +145 -0
- package/dist/index.mjs +571 -0
- package/package.json +21 -7
- package/dist/auth/agent.authenticator.d.ts +0 -12
- package/dist/auth/agent.authenticator.js +0 -96
- package/dist/auth/agent.authenticator.js.map +0 -1
- package/dist/auth/auth.helpers.d.ts +0 -12
- package/dist/auth/auth.helpers.js +0 -122
- package/dist/auth/auth.helpers.js.map +0 -1
- package/dist/auth/auth.helpers.test.d.ts +0 -1
- package/dist/auth/auth.helpers.test.js +0 -44
- package/dist/auth/auth.helpers.test.js.map +0 -1
- package/dist/auth/bearer.authenticator.d.ts +0 -11
- package/dist/auth/bearer.authenticator.js +0 -43
- package/dist/auth/bearer.authenticator.js.map +0 -1
- package/dist/auth/oauth.helper.d.ts +0 -10
- package/dist/auth/oauth.helper.js +0 -83
- package/dist/auth/oauth.helper.js.map +0 -1
- package/dist/auth/user.authenticator.d.ts +0 -11
- package/dist/auth/user.authenticator.js +0 -45
- package/dist/auth/user.authenticator.js.map +0 -1
- package/dist/auth/utils.d.ts +0 -1
- package/dist/auth/utils.js +0 -11
- package/dist/auth/utils.js.map +0 -1
- package/dist/client/agent.client.d.ts +0 -8
- package/dist/client/agent.client.js +0 -16
- package/dist/client/agent.client.js.map +0 -1
- package/dist/client/agent.client.test.d.ts +0 -1
- package/dist/client/agent.client.test.js +0 -82
- package/dist/client/agent.client.test.js.map +0 -1
- package/dist/client/approvio.client.d.ts +0 -44
- package/dist/client/approvio.client.js +0 -68
- package/dist/client/approvio.client.js.map +0 -1
- package/dist/client/base.client.d.ts +0 -29
- package/dist/client/base.client.js +0 -143
- package/dist/client/base.client.js.map +0 -1
- package/dist/client/base.client.test.d.ts +0 -1
- package/dist/client/base.client.test.js +0 -218
- package/dist/client/base.client.test.js.map +0 -1
- package/dist/client/errors.d.ts +0 -6
- package/dist/client/errors.js +0 -16
- package/dist/client/errors.js.map +0 -1
- package/dist/client/user.client.d.ts +0 -56
- package/dist/client/user.client.js +0 -137
- package/dist/client/user.client.js.map +0 -1
- package/dist/client/utils.d.ts +0 -4
- package/dist/client/utils.js +0 -29
- package/dist/client/utils.js.map +0 -1
- package/dist/client/utils.test.d.ts +0 -1
- package/dist/client/utils.test.js +0 -150
- package/dist/client/utils.test.js.map +0 -1
- package/dist/config.d.ts +0 -7
- package/dist/config.js +0 -3
- package/dist/config.js.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -24
- package/dist/index.js.map +0 -1
- package/dist/interfaces.d.ts +0 -6
- package/dist/interfaces.js +0 -3
- package/dist/interfaces.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
import * as jose from "jose";
|
|
2
|
+
import { decodeJwt } from "jose";
|
|
3
|
+
import axios from "axios";
|
|
4
|
+
import * as crypto$1 from "node:crypto";
|
|
5
|
+
import * as TE from "fp-ts/TaskEither";
|
|
6
|
+
import { pipe } from "fp-ts/function";
|
|
7
|
+
//#region src/auth/utils.ts
|
|
8
|
+
function isJwtTokenExpired(token) {
|
|
9
|
+
if (!token) return true;
|
|
10
|
+
const decoded = decodeJwt(token);
|
|
11
|
+
return !decoded.exp || decoded.exp < Date.now() / 1e3;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/client/utils.ts
|
|
15
|
+
/**
|
|
16
|
+
* Checks if the given data matches the APIError structure.
|
|
17
|
+
*/
|
|
18
|
+
function isApprovioError(data) {
|
|
19
|
+
return data !== null && typeof data === "object" && "message" in data && "code" in data && typeof data.message === "string" && typeof data.code === "string";
|
|
20
|
+
}
|
|
21
|
+
function validateURL(url) {
|
|
22
|
+
try {
|
|
23
|
+
const validatedUrl = new URL(url);
|
|
24
|
+
if (validatedUrl.search.length > 0) throw new Error("URL must not contain query parameters");
|
|
25
|
+
if (validatedUrl.hash.length > 0) throw new Error("URL must not contain hash");
|
|
26
|
+
} catch (e) {
|
|
27
|
+
throw new Error("Invalid URL", { cause: e });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function removeTrailingSlash(url) {
|
|
31
|
+
return url.endsWith("/") ? url.slice(0, -1) : url;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
//#region src/auth/user.authenticator.ts
|
|
35
|
+
/**
|
|
36
|
+
* Authenticator for Approvio Users (Human sessions).
|
|
37
|
+
* Handles automatic token renewal using a refresh token when the access token expires.
|
|
38
|
+
*/
|
|
39
|
+
var CliUserAuthenticator = class {
|
|
40
|
+
endpoint;
|
|
41
|
+
constructor(endpoint, accessToken, refreshToken, onTokenRefreshed) {
|
|
42
|
+
this.accessToken = accessToken;
|
|
43
|
+
this.refreshToken = refreshToken;
|
|
44
|
+
this.onTokenRefreshed = onTokenRefreshed;
|
|
45
|
+
validateURL(endpoint);
|
|
46
|
+
this.endpoint = removeTrailingSlash(endpoint);
|
|
47
|
+
}
|
|
48
|
+
customizeAxios(axios) {
|
|
49
|
+
axios.interceptors.request.use(async (axiosConfig) => {
|
|
50
|
+
const accessToken = await this.getAccessToken();
|
|
51
|
+
axiosConfig.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
52
|
+
return axiosConfig;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Returns a valid access token.
|
|
57
|
+
* If the token is expired, it will automatically attempt to renew it using the refresh token.
|
|
58
|
+
*/
|
|
59
|
+
async getAccessToken() {
|
|
60
|
+
if (this.isTokenExpired()) {
|
|
61
|
+
const { accessToken, refreshToken } = await this.renewToken();
|
|
62
|
+
this.accessToken = accessToken;
|
|
63
|
+
this.refreshToken = refreshToken;
|
|
64
|
+
this.onTokenRefreshed?.(this.accessToken, this.refreshToken);
|
|
65
|
+
}
|
|
66
|
+
return this.accessToken;
|
|
67
|
+
}
|
|
68
|
+
isTokenExpired() {
|
|
69
|
+
if (!this.accessToken) return true;
|
|
70
|
+
return isJwtTokenExpired(this.accessToken);
|
|
71
|
+
}
|
|
72
|
+
async renewToken() {
|
|
73
|
+
const request = { refreshToken: this.refreshToken };
|
|
74
|
+
return (await axios.post(`${this.endpoint}/auth/cli/refresh`, request)).data;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
//#endregion
|
|
78
|
+
//#region src/auth/web.authenticator.ts
|
|
79
|
+
/**
|
|
80
|
+
* WebAuthenticator is designed for browser-based environments
|
|
81
|
+
* where authentication is managed automatically via HttpOnly cookies.
|
|
82
|
+
*
|
|
83
|
+
*/
|
|
84
|
+
var WebAuthenticator = class {
|
|
85
|
+
customizeAxios(axios) {
|
|
86
|
+
axios.defaults.withCredentials = true;
|
|
87
|
+
axios.interceptors.response.use((response) => response, async (error) => {
|
|
88
|
+
const originalRequest = error.config;
|
|
89
|
+
if (error.response?.status === 401 && (originalRequest.retry === void 0 || !originalRequest.retry)) {
|
|
90
|
+
originalRequest.retry = true;
|
|
91
|
+
try {
|
|
92
|
+
await axios.post("/auth/web/refresh", {}, { retry: true });
|
|
93
|
+
return axios(originalRequest);
|
|
94
|
+
} catch (refreshError) {
|
|
95
|
+
return Promise.reject(refreshError);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return Promise.reject(error);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/auth/auth.helpers.ts
|
|
104
|
+
/**
|
|
105
|
+
* Helper class for managing Approvio authentication flows.
|
|
106
|
+
* Provides methods for both user-based OIDC login and agent-based challenge-response authentication.
|
|
107
|
+
*/
|
|
108
|
+
var AuthHelper = class {
|
|
109
|
+
endpoint;
|
|
110
|
+
constructor(endpoint) {
|
|
111
|
+
validateURL(endpoint);
|
|
112
|
+
this.endpoint = removeTrailingSlash(endpoint);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Generates the login URL to initiate the OIDC authentication flow for users.
|
|
116
|
+
*/
|
|
117
|
+
getUserLoginUrl() {
|
|
118
|
+
return `${this.endpoint}/auth/web/login`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Initiates the CLI login flow using a local loopback redirect URI.
|
|
122
|
+
* Prompts the backend to return an authorization URL for the IDP.
|
|
123
|
+
*/
|
|
124
|
+
initiateCliLogin(redirectUri) {
|
|
125
|
+
return TE.tryCatch(async () => {
|
|
126
|
+
return (await axios.post(`${this.endpoint}/auth/cli/initiate`, { redirectUri })).data.authorizationUrl;
|
|
127
|
+
}, (error) => this.handleError(error));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Exchanges an authorization code and state for a set of JWT tokens (access and refresh).
|
|
131
|
+
* This is typically the final step of the OIDC login flow.
|
|
132
|
+
*/
|
|
133
|
+
exchangeTokenForUser(code, state) {
|
|
134
|
+
const request = {
|
|
135
|
+
code,
|
|
136
|
+
state
|
|
137
|
+
};
|
|
138
|
+
return TE.tryCatch(async () => {
|
|
139
|
+
return (await axios.post(`${this.endpoint}/auth/cli/token`, request)).data;
|
|
140
|
+
}, (error) => this.handleError(error));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Authenticates an agent using the challenge-response flow.
|
|
144
|
+
* 1. Request a challenge from the server.
|
|
145
|
+
* 2. Decrypt the challenge using the agent's private key.
|
|
146
|
+
* 3. specific claims and sign a JWT assertion.
|
|
147
|
+
* 4. Exchange the assertion for an access token.
|
|
148
|
+
*/
|
|
149
|
+
authenticateAgent(agentName, privateKeyPem) {
|
|
150
|
+
return TE.tryCatch(async () => {
|
|
151
|
+
const challengeRequest = { agentName };
|
|
152
|
+
const { challenge: b64EncodedChallenge } = (await axios.post(`${this.endpoint}/auth/agents/challenge`, challengeRequest)).data;
|
|
153
|
+
const encryptedBuffer = Buffer.from(b64EncodedChallenge, "base64");
|
|
154
|
+
const decryptedContent = crypto$1.privateDecrypt({
|
|
155
|
+
key: privateKeyPem,
|
|
156
|
+
padding: crypto$1.constants.RSA_PKCS1_OAEP_PADDING,
|
|
157
|
+
oaepHash: "sha256"
|
|
158
|
+
}, encryptedBuffer).toString("utf-8");
|
|
159
|
+
const { nonce } = JSON.parse(decryptedContent);
|
|
160
|
+
const privateKey = await jose.importPKCS8(privateKeyPem, "RS256");
|
|
161
|
+
const tokenRequest = {
|
|
162
|
+
grantType: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
163
|
+
clientAssertionType: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
|
|
164
|
+
clientAssertion: await new jose.SignJWT({
|
|
165
|
+
iss: agentName,
|
|
166
|
+
sub: agentName,
|
|
167
|
+
aud: "approvio-api",
|
|
168
|
+
jti: nonce
|
|
169
|
+
}).setProtectedHeader({
|
|
170
|
+
alg: "RS256",
|
|
171
|
+
typ: "JWT"
|
|
172
|
+
}).setIssuedAt().setExpirationTime("5m").sign(privateKey)
|
|
173
|
+
};
|
|
174
|
+
return (await axios.post(`${this.endpoint}/auth/agents/token`, tokenRequest)).data;
|
|
175
|
+
}, (error) => this.handleError(error));
|
|
176
|
+
}
|
|
177
|
+
handleError(error) {
|
|
178
|
+
if (axios.isAxiosError(error)) {
|
|
179
|
+
const status = error.response?.status;
|
|
180
|
+
const data = error.response?.data;
|
|
181
|
+
if (status && isApprovioError(data)) return {
|
|
182
|
+
...data,
|
|
183
|
+
status
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
if (error instanceof Error) return error;
|
|
187
|
+
return new Error(String(error));
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
//#endregion
|
|
191
|
+
//#region src/auth/agent.authenticator.ts
|
|
192
|
+
/**
|
|
193
|
+
* Authenticator for Approvio Agents.
|
|
194
|
+
* Handles automatic token renewal using a refresh token and DPoP proof when the access token expires.
|
|
195
|
+
*/
|
|
196
|
+
var AgentAuthenticator = class {
|
|
197
|
+
endpoint;
|
|
198
|
+
constructor(endpoint, privateKey, accessToken, refreshToken, onTokenRefreshed) {
|
|
199
|
+
this.privateKey = privateKey;
|
|
200
|
+
this.accessToken = accessToken;
|
|
201
|
+
this.refreshToken = refreshToken;
|
|
202
|
+
this.onTokenRefreshed = onTokenRefreshed;
|
|
203
|
+
validateURL(endpoint);
|
|
204
|
+
this.endpoint = removeTrailingSlash(endpoint);
|
|
205
|
+
}
|
|
206
|
+
customizeAxios(axios) {
|
|
207
|
+
axios.interceptors.request.use(async (axiosConfig) => {
|
|
208
|
+
const accessToken = await this.getAccessToken();
|
|
209
|
+
axiosConfig.headers.set("Authorization", `Bearer ${accessToken}`);
|
|
210
|
+
return axiosConfig;
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Returns a valid access token.
|
|
215
|
+
* If the token is expired, it will automatically attempt to renew it using the refresh token.
|
|
216
|
+
*/
|
|
217
|
+
async getAccessToken() {
|
|
218
|
+
if (isJwtTokenExpired(this.accessToken)) {
|
|
219
|
+
const { accessToken, refreshToken } = await this.renewToken();
|
|
220
|
+
this.accessToken = accessToken;
|
|
221
|
+
this.refreshToken = refreshToken;
|
|
222
|
+
this.onTokenRefreshed?.(this.accessToken, this.refreshToken);
|
|
223
|
+
}
|
|
224
|
+
return this.accessToken;
|
|
225
|
+
}
|
|
226
|
+
async renewToken() {
|
|
227
|
+
const request = { refreshToken: this.refreshToken };
|
|
228
|
+
const dpopProof = await this.generateDpopProof("POST", `${this.endpoint}/auth/agents/refresh`);
|
|
229
|
+
return (await axios.post(`${this.endpoint}/auth/agents/refresh`, request, { headers: { DPoP: dpopProof } })).data;
|
|
230
|
+
}
|
|
231
|
+
async generateDpopProof(method, url) {
|
|
232
|
+
const privateKey = await jose.importPKCS8(this.privateKey, "RS256");
|
|
233
|
+
return await new jose.SignJWT({
|
|
234
|
+
htu: url,
|
|
235
|
+
htm: method,
|
|
236
|
+
jti: crypto.randomUUID()
|
|
237
|
+
}).setProtectedHeader({
|
|
238
|
+
alg: "RS256",
|
|
239
|
+
typ: "dpop+jwt"
|
|
240
|
+
}).setIssuedAt().setJti(crypto.randomUUID()).sign(privateKey);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/client/errors.ts
|
|
245
|
+
var LocationNotFoundError = class extends Error {
|
|
246
|
+
constructor() {
|
|
247
|
+
super("Location header was expected but not found");
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
var NetworkError = class extends Error {
|
|
251
|
+
constructor(message) {
|
|
252
|
+
super(message);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
//#endregion
|
|
256
|
+
//#region src/client/base.client.ts
|
|
257
|
+
const networkCodes = [
|
|
258
|
+
"ECONNREFUSED",
|
|
259
|
+
"ETIMEDOUT",
|
|
260
|
+
"ENOTFOUND",
|
|
261
|
+
"ECONNRESET"
|
|
262
|
+
];
|
|
263
|
+
/**
|
|
264
|
+
* Base client for Approvio API.
|
|
265
|
+
*/
|
|
266
|
+
var BaseApprovioClient = class {
|
|
267
|
+
axios;
|
|
268
|
+
constructor(config, authenticator) {
|
|
269
|
+
this.config = config;
|
|
270
|
+
this.authenticator = authenticator;
|
|
271
|
+
validateURL(config.endpoint);
|
|
272
|
+
this.axios = axios.create({ baseURL: removeTrailingSlash(config.endpoint) });
|
|
273
|
+
this.authenticator.customizeAxios(this.axios);
|
|
274
|
+
}
|
|
275
|
+
handleError(error) {
|
|
276
|
+
if (axios.isAxiosError(error)) {
|
|
277
|
+
if (networkCodes.includes(error.code ?? "")) return new NetworkError(`Network error ${error.code}`);
|
|
278
|
+
const status = error.response?.status;
|
|
279
|
+
const data = error.response?.data;
|
|
280
|
+
if (status && isApprovioError(data)) return {
|
|
281
|
+
...data,
|
|
282
|
+
status
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (error instanceof Error) return error;
|
|
286
|
+
return new Error(String(error));
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Performs a GET request.
|
|
290
|
+
*/
|
|
291
|
+
get(url, params) {
|
|
292
|
+
return TE.tryCatch(async () => {
|
|
293
|
+
return (await this.axios.get(url, { params })).data;
|
|
294
|
+
}, (error) => this.handleError(error));
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Performs a POST request.
|
|
298
|
+
*/
|
|
299
|
+
post(url, data) {
|
|
300
|
+
return TE.tryCatch(async () => {
|
|
301
|
+
return (await this.axios.post(url, data)).data;
|
|
302
|
+
}, (error) => this.handleError(error));
|
|
303
|
+
}
|
|
304
|
+
postWithLocation(url, data) {
|
|
305
|
+
return TE.tryCatch(async () => {
|
|
306
|
+
const response = await this.axios.post(url, data);
|
|
307
|
+
const location = response.headers["location"];
|
|
308
|
+
if (!location) throw new LocationNotFoundError();
|
|
309
|
+
return {
|
|
310
|
+
data: response.data,
|
|
311
|
+
location
|
|
312
|
+
};
|
|
313
|
+
}, (error) => this.handleError(error));
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Performs a PUT request.
|
|
317
|
+
*/
|
|
318
|
+
put(url, data) {
|
|
319
|
+
return TE.tryCatch(async () => {
|
|
320
|
+
return (await this.axios.put(url, data)).data;
|
|
321
|
+
}, (error) => this.handleError(error));
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Performs a DELETE request.
|
|
325
|
+
*/
|
|
326
|
+
delete(url, data) {
|
|
327
|
+
return TE.tryCatch(async () => {
|
|
328
|
+
const config = data !== void 0 ? { data } : void 0;
|
|
329
|
+
return (await this.axios.delete(url, config)).data;
|
|
330
|
+
}, (error) => this.handleError(error));
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Get workflow details.
|
|
334
|
+
*/
|
|
335
|
+
getWorkflow(workflowId, params) {
|
|
336
|
+
return this.get(`/workflows/${workflowId}`, params);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* List workflows.
|
|
340
|
+
*/
|
|
341
|
+
listWorkflows(params) {
|
|
342
|
+
const queryParams = {
|
|
343
|
+
page: params?.page,
|
|
344
|
+
limit: params?.limit,
|
|
345
|
+
"include-only-non-terminal-state": params?.includeOnlyNonTerminalState,
|
|
346
|
+
include: params?.include
|
|
347
|
+
};
|
|
348
|
+
return this.get("/workflows", queryParams);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Create a new workflow.
|
|
352
|
+
*/
|
|
353
|
+
createWorkflow(data) {
|
|
354
|
+
return this.post("/workflows", data);
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Vote on a workflow.
|
|
358
|
+
*/
|
|
359
|
+
voteOnWorkflow(workflowId, data) {
|
|
360
|
+
return this.post(`/workflows/${workflowId}/vote`, data);
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Check if the current entity can vote on a workflow.
|
|
364
|
+
*/
|
|
365
|
+
canVoteOnWorkflow(workflowId) {
|
|
366
|
+
return this.get(`/workflows/${workflowId}/canVote`);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* List role templates.
|
|
370
|
+
*/
|
|
371
|
+
listRoleTemplates() {
|
|
372
|
+
return this.get("/roles");
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Get authenticated entity information.
|
|
376
|
+
*/
|
|
377
|
+
getEntityInfo() {
|
|
378
|
+
return this.get("/auth/info");
|
|
379
|
+
}
|
|
380
|
+
};
|
|
381
|
+
//#endregion
|
|
382
|
+
//#region src/client/user.client.ts
|
|
383
|
+
/**
|
|
384
|
+
* Client for Approvio API (Human/User).
|
|
385
|
+
*/
|
|
386
|
+
var ApprovioUserClient = class extends BaseApprovioClient {
|
|
387
|
+
constructor(config, authenticator) {
|
|
388
|
+
super(config, authenticator);
|
|
389
|
+
this.authenticator = authenticator;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Lists users.
|
|
393
|
+
*/
|
|
394
|
+
listUsers(params) {
|
|
395
|
+
return this.get("/users", params);
|
|
396
|
+
}
|
|
397
|
+
registerAgent(data) {
|
|
398
|
+
return this.post("/agents/register", data);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Assign roles to an agent.
|
|
402
|
+
*/
|
|
403
|
+
assignAgentRoles(agentId, data) {
|
|
404
|
+
return this.put(`/agents/${agentId}/roles`, data);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Remove roles from an agent.
|
|
408
|
+
*/
|
|
409
|
+
removeAgentRoles(agentId, data) {
|
|
410
|
+
return this.delete(`/agents/${agentId}/roles`, data);
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Creates a new user.
|
|
414
|
+
*/
|
|
415
|
+
createUser(data) {
|
|
416
|
+
return pipe(this.postWithLocation("/users", data), TE.map(({ location }) => location), TE.chain((location) => {
|
|
417
|
+
const id = location.split("/").pop();
|
|
418
|
+
if (!id) return TE.left(/* @__PURE__ */ new Error("Invalid location"));
|
|
419
|
+
return TE.right(id);
|
|
420
|
+
}));
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Get user details.
|
|
424
|
+
*/
|
|
425
|
+
getUser(userId) {
|
|
426
|
+
return this.get(`/users/${userId}`);
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Assign roles to a user.
|
|
430
|
+
*/
|
|
431
|
+
assignUserRoles(userId, data) {
|
|
432
|
+
return this.put(`/users/${userId}/roles`, data);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Remove roles from a user.
|
|
436
|
+
*/
|
|
437
|
+
removeUserRoles(userId, data) {
|
|
438
|
+
return this.delete(`/users/${userId}/roles`, data);
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Create a new workflow template.
|
|
442
|
+
*/
|
|
443
|
+
createWorkflowTemplate(data) {
|
|
444
|
+
return this.post("/workflow-templates", data);
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* List workflow templates.
|
|
448
|
+
*/
|
|
449
|
+
listWorkflowTemplates(params) {
|
|
450
|
+
return this.get("/workflow-templates", params);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Get workflow template details.
|
|
454
|
+
*/
|
|
455
|
+
getWorkflowTemplate(templateIdentifier) {
|
|
456
|
+
return this.get(`/workflow-templates/${templateIdentifier}`);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Update a workflow template.
|
|
460
|
+
*/
|
|
461
|
+
updateWorkflowTemplate(templateIdentifier, data) {
|
|
462
|
+
return this.put(`/workflow-templates/${templateIdentifier}`, data);
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Deprecate a workflow template.
|
|
466
|
+
*/
|
|
467
|
+
deprecateWorkflowTemplate(templateName, data) {
|
|
468
|
+
return this.post(`/workflow-templates/${templateName}/deprecate`, data);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Create a new group.
|
|
472
|
+
*/
|
|
473
|
+
createGroup(data) {
|
|
474
|
+
return pipe(this.postWithLocation("/groups", data), TE.map(({ location }) => location), TE.chain((location) => {
|
|
475
|
+
const id = location.split("/").pop();
|
|
476
|
+
if (!id) return TE.left(/* @__PURE__ */ new Error("Invalid location"));
|
|
477
|
+
return TE.right(id);
|
|
478
|
+
}));
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* List groups.
|
|
482
|
+
*/
|
|
483
|
+
listGroups(params) {
|
|
484
|
+
return this.get("/groups", params);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Get group details.
|
|
488
|
+
*/
|
|
489
|
+
getGroup(groupIdentifier) {
|
|
490
|
+
return this.get(`/groups/${groupIdentifier}`);
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* List entities in a group.
|
|
494
|
+
*/
|
|
495
|
+
listGroupEntities(groupId, params) {
|
|
496
|
+
return this.get(`/groups/${groupId}/entities`, params);
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Add entities to a group.
|
|
500
|
+
*/
|
|
501
|
+
addGroupEntities(groupId, data) {
|
|
502
|
+
return this.post(`/groups/${groupId}/entities`, data);
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Remove entities from a group.
|
|
506
|
+
*/
|
|
507
|
+
removeGroupEntities(groupId, data) {
|
|
508
|
+
return this.delete(`/groups/${groupId}/entities`, data);
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Create a new space.
|
|
512
|
+
*/
|
|
513
|
+
createSpace(data) {
|
|
514
|
+
return this.post("/spaces", data);
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* List spaces.
|
|
518
|
+
*/
|
|
519
|
+
listSpaces(params) {
|
|
520
|
+
return this.get("/spaces", params);
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Get space details.
|
|
524
|
+
*/
|
|
525
|
+
getSpace(spaceId) {
|
|
526
|
+
return this.get(`/spaces/${spaceId}`);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Delete a space.
|
|
530
|
+
*/
|
|
531
|
+
deleteSpace(spaceId) {
|
|
532
|
+
return this.delete(`/spaces/${spaceId}`);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Add an organization admin.
|
|
536
|
+
*/
|
|
537
|
+
addOrganizationAdminToOrg(organizationName, data) {
|
|
538
|
+
return this.post(`/organization/${organizationName}/admins`, data);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* List organization admins.
|
|
542
|
+
*/
|
|
543
|
+
listOrganizationAdminsForOrg(organizationName, params) {
|
|
544
|
+
return this.get(`/organization/${organizationName}/admins`, params);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Remove an organization admin.
|
|
548
|
+
*/
|
|
549
|
+
removeOrganizationAdminFromOrg(organizationName, data) {
|
|
550
|
+
return this.delete(`/organization/${organizationName}/admins`, data);
|
|
551
|
+
}
|
|
552
|
+
getAgent(agentId) {
|
|
553
|
+
return this.get(`/agents/${agentId}`);
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
//#endregion
|
|
557
|
+
//#region src/client/agent.client.ts
|
|
558
|
+
/**
|
|
559
|
+
* Client for Approvio API (Agent).
|
|
560
|
+
*/
|
|
561
|
+
var ApprovioAgentClient = class extends BaseApprovioClient {
|
|
562
|
+
constructor(config, authenticator) {
|
|
563
|
+
super(config, authenticator);
|
|
564
|
+
this.authenticator = authenticator;
|
|
565
|
+
}
|
|
566
|
+
getAuthenticator() {
|
|
567
|
+
return this.authenticator;
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
//#endregion
|
|
571
|
+
export { AgentAuthenticator, ApprovioAgentClient, ApprovioUserClient, AuthHelper, BaseApprovioClient, CliUserAuthenticator, WebAuthenticator };
|
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@approvio/ts-sdk",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.9",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.mts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
6
15
|
"files": [
|
|
7
16
|
"dist",
|
|
8
17
|
"README.md",
|
|
@@ -14,19 +23,21 @@
|
|
|
14
23
|
},
|
|
15
24
|
"packageManager": "yarn@4.7.0",
|
|
16
25
|
"scripts": {
|
|
17
|
-
"build": "
|
|
26
|
+
"build": "tsdown src/index.ts --format esm,cjs --dts",
|
|
18
27
|
"lint": "eslint --cache --fix .",
|
|
19
28
|
"format": "prettier --config .prettierrc . --write",
|
|
20
29
|
"test": "jest",
|
|
21
30
|
"prepublishOnly": "yarn format && yarn lint && yarn build"
|
|
22
31
|
},
|
|
23
32
|
"dependencies": {
|
|
24
|
-
"@approvio/api": "0.0.
|
|
33
|
+
"@approvio/api": "0.0.31",
|
|
25
34
|
"axios": "1.13.2",
|
|
26
|
-
"fp-ts": "2.16.11",
|
|
27
|
-
"io-ts": "2.2.22",
|
|
28
35
|
"jose": "6.1.3"
|
|
29
36
|
},
|
|
37
|
+
"peerDependencies": {
|
|
38
|
+
"fp-ts": "^2.0.0",
|
|
39
|
+
"io-ts": "^2.0.0"
|
|
40
|
+
},
|
|
30
41
|
"devDependencies": {
|
|
31
42
|
"@types/jest": "29.5.14",
|
|
32
43
|
"@types/node": "22.18.0",
|
|
@@ -37,9 +48,12 @@
|
|
|
37
48
|
"eslint-plugin-jest": "28.14.0",
|
|
38
49
|
"eslint-plugin-node": "11.1.0",
|
|
39
50
|
"eslint-plugin-prettier": "5.5.4",
|
|
51
|
+
"fp-ts": "2.16.11",
|
|
52
|
+
"io-ts": "2.2.20",
|
|
40
53
|
"jest": "29.7.0",
|
|
41
54
|
"prettier": "3.7.4",
|
|
42
55
|
"ts-jest": "29.4.6",
|
|
56
|
+
"tsdown": "^0.21.4",
|
|
43
57
|
"typescript": "5.9.3"
|
|
44
58
|
}
|
|
45
59
|
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { Authenticator } from "../interfaces";
|
|
2
|
-
export declare class AgentAuthenticator implements Authenticator {
|
|
3
|
-
private readonly privateKey;
|
|
4
|
-
private accessToken;
|
|
5
|
-
private refreshToken;
|
|
6
|
-
private readonly onTokenRefreshed?;
|
|
7
|
-
private readonly endpoint;
|
|
8
|
-
constructor(endpoint: string, privateKey: string, accessToken: string, refreshToken: string, onTokenRefreshed?: ((accessToken: string, refreshToken: string) => void) | undefined);
|
|
9
|
-
getAccessToken(): Promise<string>;
|
|
10
|
-
private renewToken;
|
|
11
|
-
private generateDpopProof;
|
|
12
|
-
}
|