Skip to content

Commit 748d8d8

Browse files
authored
Add User management methods to the SDK and examples (#21)
* Add user-service swagger and types * Add userService example and fixes * Regen * Lint * fmt * Return watchlist on creation * clean
1 parent 4a8e8c0 commit 748d8d8

File tree

10 files changed

+1818
-591
lines changed

10 files changed

+1818
-591
lines changed

biome.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@
77
},
88
"files": {
99
"ignoreUnknown": false,
10-
"ignore": ["*/node_modules/*", "*/dist/*", "packages/types/*"]
10+
"ignore": [
11+
"*/node_modules/*",
12+
"*/dist/*",
13+
"packages/types/*",
14+
"packages/api/src/types/*"
15+
]
1116
},
1217
"organizeImports": {
1318
"enabled": true

packages/api/src/client/base.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ import type {
6363
getAssetTimeseriesWithGranularityParameters,
6464
getAssetTimeseriesWithGranularityResponse,
6565
TimeseriesMetadata,
66+
createWatchlistResponse,
67+
createWatchlistParameters,
68+
getWatchlistParameters,
69+
listWatchlistsResponse,
70+
getWatchlistResponse,
71+
updateWatchlistResponse,
72+
updateWatchlistParameters,
73+
deleteWatchlistParameters,
74+
deleteWatchlistResponse,
75+
modifyWatchlistAssetsParameters,
76+
modifyWatchlistAssetsResponse,
77+
getTeamAllowanceResponse,
78+
getPermissionsResponse,
6679
} from "../types";
6780
import { LogLevel, type Logger, makeConsoleLogger, createFilteredLogger, noOpLogger } from "../logging";
6881
import type { PaginatedResult, RequestOptions, ClientEventMap, ClientEventType, ClientEventHandler } from "./types";
@@ -271,6 +284,72 @@ export interface ResearchInterface {
271284
getResearchReportTags(options?: RequestOptions): Promise<getResearchReportTagsResponse>;
272285
}
273286

287+
/**
288+
* Interface for the User Management API methods
289+
*/
290+
export interface UserManagementInterface {
291+
/**
292+
* Get a team's current credit allowance
293+
* @param options Optional request configuration
294+
* @returns A promise resolving to the team's credit allowance information
295+
*/
296+
getTeamAllowance(options?: RequestOptions): Promise<getTeamAllowanceResponse>;
297+
298+
/**
299+
* Get all permissions with active status for the current user
300+
* @param options Optional request configuration
301+
* @returns A promise resolving to the user's permissions
302+
*/
303+
getPermissions(options?: RequestOptions): Promise<getPermissionsResponse>;
304+
305+
/**
306+
* Get all watchlists for the authenticated user
307+
* @param options Optional request configuration
308+
* @returns A promise resolving to the user's watchlists
309+
*/
310+
listWatchlists(options?: RequestOptions): Promise<listWatchlistsResponse>;
311+
312+
/**
313+
* Create a new watchlist for the authenticated user
314+
* @param params Parameters for creating a watchlist
315+
* @param options Optional request configuration
316+
* @returns A promise resolving to the created watchlist
317+
*/
318+
createWatchlist(params: createWatchlistParameters, options?: RequestOptions): Promise<createWatchlistResponse>;
319+
320+
/**
321+
* Get a specific watchlist by ID for the authenticated user
322+
* @param params Parameters including the watchlist ID
323+
* @param options Optional request configuration
324+
* @returns A promise resolving to the requested watchlist
325+
*/
326+
getWatchlist(params: getWatchlistParameters, options?: RequestOptions): Promise<getWatchlistResponse>;
327+
328+
/**
329+
* Update a specific watchlist by ID for the authenticated user
330+
* @param params Parameters for updating the watchlist
331+
* @param options Optional request configuration
332+
* @returns A promise resolving to the updated watchlist
333+
*/
334+
updateWatchlist(params: updateWatchlistParameters, options?: RequestOptions): Promise<updateWatchlistResponse>;
335+
336+
/**
337+
* Delete a specific watchlist by ID for the authenticated user
338+
* @param params Parameters including the watchlist ID
339+
* @param options Optional request configuration
340+
* @returns A promise resolving to the API response
341+
*/
342+
deleteWatchlist(params: deleteWatchlistParameters, options?: RequestOptions): Promise<deleteWatchlistResponse>;
343+
344+
/**
345+
* Modify the assets in a specific watchlist by ID for the authenticated user
346+
* @param params Parameters for modifying the watchlist assets
347+
* @param options Optional request configuration
348+
* @returns A promise resolving to the modified watchlist
349+
*/
350+
modifyWatchlistAssets(params: modifyWatchlistAssetsParameters, options?: RequestOptions): Promise<modifyWatchlistAssetsResponse>;
351+
}
352+
274353
/**
275354
* Interface for the Diligence API methods
276355
*/
@@ -380,6 +459,11 @@ export abstract class MessariClientBase {
380459
*/
381460
public abstract readonly diligence: DiligenceAPIInterface;
382461

462+
/**
463+
* Interface for User Management-related API methods
464+
*/
465+
public abstract readonly userManagement: UserManagementInterface;
466+
383467
/**
384468
* Interface for Recaps-related API methods
385469
*/

packages/api/src/client/client.ts

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ import {
3030
getAssetsV2ROI,
3131
getAssetTimeseries,
3232
getAssetTimeseriesWithGranularity,
33+
modifyWatchlistAssets,
34+
deleteWatchlist,
35+
listWatchlists,
36+
getPermissions,
37+
createWatchlist,
38+
getTeamAllowance,
39+
getWatchlist,
40+
updateWatchlist,
3341
} from "../types";
3442
import type {
3543
createChatCompletionParameters,
@@ -92,6 +100,19 @@ import type {
92100
getAssetTimeseriesWithGranularityParameters,
93101
getAssetTimeseriesWithGranularityResponse,
94102
TimeseriesMetadata,
103+
modifyWatchlistAssetsResponse,
104+
modifyWatchlistAssetsParameters,
105+
deleteWatchlistResponse,
106+
deleteWatchlistParameters,
107+
listWatchlistsResponse,
108+
createWatchlistParameters,
109+
createWatchlistResponse,
110+
getPermissionsResponse,
111+
getWatchlistParameters,
112+
getTeamAllowanceResponse,
113+
getWatchlistResponse,
114+
updateWatchlistParameters,
115+
updateWatchlistResponse,
95116
} from "../types";
96117
import type { Agent } from "node:http";
97118
import { pick } from "../utils";
@@ -118,6 +139,7 @@ import type {
118139
RecapsAPIInterface,
119140
ResearchInterface,
120141
TokenUnlocksInterface,
142+
UserManagementInterface,
121143
} from "./base";
122144
import { MessariClientBase } from "./base";
123145

@@ -264,7 +286,16 @@ export class MessariClient extends MessariClientBase {
264286
throw error;
265287
}
266288

267-
const responseData = await response.json();
289+
// Check if the response is JSON or text based on Content-Type header
290+
const contentType = response.headers.get("Content-Type");
291+
let responseData: { data: T };
292+
293+
if (contentType?.toLowerCase().includes("application/json")) {
294+
responseData = await response.json();
295+
} else {
296+
responseData = { data: await response.text() } as { data: T };
297+
}
298+
268299
this.logger(LogLevel.DEBUG, "request success", { responseData });
269300

270301
// Emit response event
@@ -913,6 +944,71 @@ export class MessariClient extends MessariClientBase {
913944
},
914945
};
915946

947+
/**
948+
* User Management API service
949+
* Provides methods for managing user-specific data like watchlists, credits, and permissions
950+
*/
951+
public readonly userManagement: UserManagementInterface = {
952+
getTeamAllowance: (options?: RequestOptions) =>
953+
this.request<getTeamAllowanceResponse>({
954+
method: getTeamAllowance.method,
955+
path: getTeamAllowance.path(),
956+
options,
957+
}),
958+
959+
getPermissions: (options?: RequestOptions) =>
960+
this.request<getPermissionsResponse>({
961+
method: getPermissions.method,
962+
path: getPermissions.path(),
963+
options,
964+
}),
965+
966+
listWatchlists: (options?: RequestOptions) =>
967+
this.request<listWatchlistsResponse>({
968+
method: listWatchlists.method,
969+
path: listWatchlists.path(),
970+
options,
971+
}),
972+
973+
createWatchlist: (params: createWatchlistParameters, options?: RequestOptions) =>
974+
this.request<createWatchlistResponse>({
975+
method: createWatchlist.method,
976+
path: createWatchlist.path(),
977+
body: pick(params, createWatchlist.bodyParams),
978+
options,
979+
}),
980+
981+
getWatchlist: (params: getWatchlistParameters, options?: RequestOptions) =>
982+
this.request<getWatchlistResponse>({
983+
method: getWatchlist.method,
984+
path: getWatchlist.path(params),
985+
options,
986+
}),
987+
988+
updateWatchlist: (params: updateWatchlistParameters, options?: RequestOptions) =>
989+
this.request<updateWatchlistResponse>({
990+
method: updateWatchlist.method,
991+
path: updateWatchlist.path({ id: params.id }),
992+
body: pick(params, updateWatchlist.bodyParams),
993+
options,
994+
}),
995+
996+
deleteWatchlist: (params: deleteWatchlistParameters, options?: RequestOptions) =>
997+
this.request<deleteWatchlistResponse>({
998+
method: deleteWatchlist.method,
999+
path: deleteWatchlist.path(params),
1000+
options,
1001+
}),
1002+
1003+
modifyWatchlistAssets: (params: modifyWatchlistAssetsParameters, options?: RequestOptions) =>
1004+
this.request<modifyWatchlistAssetsResponse>({
1005+
method: modifyWatchlistAssets.method,
1006+
path: modifyWatchlistAssets.path({ id: params.id }),
1007+
body: pick(params, modifyWatchlistAssets.bodyParams),
1008+
options,
1009+
}),
1010+
};
1011+
9161012
// Recaps is commented out as we don't want to expose it yet
9171013
// public readonly recaps: RecapsAPIInterface = {
9181014
// getProjectRecap: async (params: getProjectRecapParameters) => {

0 commit comments

Comments
 (0)