Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
},
"files": {
"ignoreUnknown": false,
"ignore": ["*/node_modules/*", "*/dist/*", "packages/types/*"]
"ignore": [
"*/node_modules/*",
"*/dist/*",
"packages/types/*",
"packages/api/src/types/*"
]
},
"organizeImports": {
"enabled": true
Expand Down
84 changes: 84 additions & 0 deletions packages/api/src/client/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ import type {
getAssetTimeseriesWithGranularityParameters,
getAssetTimeseriesWithGranularityResponse,
TimeseriesMetadata,
createWatchlistResponse,
createWatchlistParameters,
getWatchlistParameters,
listWatchlistsResponse,
getWatchlistResponse,
updateWatchlistResponse,
updateWatchlistParameters,
deleteWatchlistParameters,
deleteWatchlistResponse,
modifyWatchlistAssetsParameters,
modifyWatchlistAssetsResponse,
getTeamAllowanceResponse,
getPermissionsResponse,
} from "../types";
import { LogLevel, type Logger, makeConsoleLogger, createFilteredLogger, noOpLogger } from "../logging";
import type { PaginatedResult, RequestOptions, ClientEventMap, ClientEventType, ClientEventHandler } from "./types";
Expand Down Expand Up @@ -317,6 +330,72 @@ export interface ResearchInterface {
getResearchReportTags(options?: RequestOptions): Promise<getResearchReportTagsResponse>;
}

/**
* Interface for the User Management API methods
*/
export interface UserManagementInterface {
/**
* Get a team's current credit allowance
* @param options Optional request configuration
* @returns A promise resolving to the team's credit allowance information
*/
getTeamAllowance(options?: RequestOptions): Promise<getTeamAllowanceResponse>;

/**
* Get all permissions with active status for the current user
* @param options Optional request configuration
* @returns A promise resolving to the user's permissions
*/
getPermissions(options?: RequestOptions): Promise<getPermissionsResponse>;

/**
* Get all watchlists for the authenticated user
* @param options Optional request configuration
* @returns A promise resolving to the user's watchlists
*/
listWatchlists(options?: RequestOptions): Promise<listWatchlistsResponse>;

/**
* Create a new watchlist for the authenticated user
* @param params Parameters for creating a watchlist
* @param options Optional request configuration
* @returns A promise resolving to the created watchlist
*/
createWatchlist(params: createWatchlistParameters, options?: RequestOptions): Promise<createWatchlistResponse>;

/**
* Get a specific watchlist by ID for the authenticated user
* @param params Parameters including the watchlist ID
* @param options Optional request configuration
* @returns A promise resolving to the requested watchlist
*/
getWatchlist(params: getWatchlistParameters, options?: RequestOptions): Promise<getWatchlistResponse>;

/**
* Update a specific watchlist by ID for the authenticated user
* @param params Parameters for updating the watchlist
* @param options Optional request configuration
* @returns A promise resolving to the updated watchlist
*/
updateWatchlist(params: updateWatchlistParameters, options?: RequestOptions): Promise<updateWatchlistResponse>;

/**
* Delete a specific watchlist by ID for the authenticated user
* @param params Parameters including the watchlist ID
* @param options Optional request configuration
* @returns A promise resolving to the API response
*/
deleteWatchlist(params: deleteWatchlistParameters, options?: RequestOptions): Promise<deleteWatchlistResponse>;

/**
* Modify the assets in a specific watchlist by ID for the authenticated user
* @param params Parameters for modifying the watchlist assets
* @param options Optional request configuration
* @returns A promise resolving to the modified watchlist
*/
modifyWatchlistAssets(params: modifyWatchlistAssetsParameters, options?: RequestOptions): Promise<modifyWatchlistAssetsResponse>;
}

/**
* Interface for the Diligence API methods
*/
Expand Down Expand Up @@ -431,6 +510,11 @@ export abstract class MessariClientBase {
*/
public abstract readonly diligence: DiligenceAPIInterface;

/**
* Interface for User Management-related API methods
*/
public abstract readonly userManagement: UserManagementInterface;

/**
* Interface for Recaps-related API methods
*/
Expand Down
98 changes: 97 additions & 1 deletion packages/api/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ import {
getAssetsV2ROI,
getAssetTimeseries,
getAssetTimeseriesWithGranularity,
modifyWatchlistAssets,
deleteWatchlist,
listWatchlists,
getPermissions,
createWatchlist,
getTeamAllowance,
getWatchlist,
updateWatchlist,
} from "../types";
import type {
createChatCompletionParameters,
Expand Down Expand Up @@ -105,6 +113,19 @@ import type {
getAssetTimeseriesWithGranularityParameters,
getAssetTimeseriesWithGranularityResponse,
TimeseriesMetadata,
modifyWatchlistAssetsResponse,
modifyWatchlistAssetsParameters,
deleteWatchlistResponse,
deleteWatchlistParameters,
listWatchlistsResponse,
createWatchlistParameters,
createWatchlistResponse,
getPermissionsResponse,
getWatchlistParameters,
getTeamAllowanceResponse,
getWatchlistResponse,
updateWatchlistParameters,
updateWatchlistResponse,
} from "../types";
import type { Agent } from "node:http";
import { pick } from "../utils";
Expand Down Expand Up @@ -132,6 +153,7 @@ import type {
RecapsAPIInterface,
ResearchInterface,
TokenUnlocksInterface,
UserManagementInterface,
} from "./base";
import { MessariClientBase } from "./base";

Expand Down Expand Up @@ -278,7 +300,16 @@ export class MessariClient extends MessariClientBase {
throw error;
}

const responseData = await response.json();
// Check if the response is JSON or text based on Content-Type header
const contentType = response.headers.get("Content-Type");
let responseData: { data: T };

if (contentType?.toLowerCase().includes("application/json")) {
responseData = await response.json();
} else {
responseData = { data: await response.text() } as { data: T };
}

this.logger(LogLevel.DEBUG, "request success", { responseData });

// Emit response event
Expand Down Expand Up @@ -965,6 +996,71 @@ export class MessariClient extends MessariClientBase {
},
};

/**
* User Management API service
* Provides methods for managing user-specific data like watchlists, credits, and permissions
*/
public readonly userManagement: UserManagementInterface = {
getTeamAllowance: (options?: RequestOptions) =>
this.request<getTeamAllowanceResponse>({
method: getTeamAllowance.method,
path: getTeamAllowance.path(),
options,
}),

getPermissions: (options?: RequestOptions) =>
this.request<getPermissionsResponse>({
method: getPermissions.method,
path: getPermissions.path(),
options,
}),

listWatchlists: (options?: RequestOptions) =>
this.request<listWatchlistsResponse>({
method: listWatchlists.method,
path: listWatchlists.path(),
options,
}),

createWatchlist: (params: createWatchlistParameters, options?: RequestOptions) =>
this.request<createWatchlistResponse>({
method: createWatchlist.method,
path: createWatchlist.path(),
body: pick(params, createWatchlist.bodyParams),
options,
}),

getWatchlist: (params: getWatchlistParameters, options?: RequestOptions) =>
this.request<getWatchlistResponse>({
method: getWatchlist.method,
path: getWatchlist.path(params),
options,
}),

updateWatchlist: (params: updateWatchlistParameters, options?: RequestOptions) =>
this.request<updateWatchlistResponse>({
method: updateWatchlist.method,
path: updateWatchlist.path({ id: params.id }),
body: pick(params, updateWatchlist.bodyParams),
options,
}),

deleteWatchlist: (params: deleteWatchlistParameters, options?: RequestOptions) =>
this.request<deleteWatchlistResponse>({
method: deleteWatchlist.method,
path: deleteWatchlist.path(params),
options,
}),

modifyWatchlistAssets: (params: modifyWatchlistAssetsParameters, options?: RequestOptions) =>
this.request<modifyWatchlistAssetsResponse>({
method: modifyWatchlistAssets.method,
path: modifyWatchlistAssets.path({ id: params.id }),
body: pick(params, modifyWatchlistAssets.bodyParams),
options,
}),
};

// Recaps is commented out as we don't want to expose it yet
// public readonly recaps: RecapsAPIInterface = {
// getProjectRecap: async (params: getProjectRecapParameters) => {
Expand Down
Loading