Publish @classroomio/mcp package
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import type {
|
||||
TCourseImportDraftCreate,
|
||||
TCourseImportDraftPublish,
|
||||
TCourseImportDraftUpdate
|
||||
} from '@cio/utils/validation/course-import';
|
||||
|
||||
import type { McpServerConfig } from './config.js';
|
||||
|
||||
type ApiSuccess<T> = {
|
||||
success: true;
|
||||
data: T;
|
||||
};
|
||||
|
||||
type ApiFailure = {
|
||||
success?: false;
|
||||
error?: string;
|
||||
message?: string;
|
||||
code?: string;
|
||||
field?: string;
|
||||
};
|
||||
|
||||
export class ClassroomIoApiError extends Error {
|
||||
constructor(
|
||||
message: string,
|
||||
public status: number,
|
||||
public code?: string,
|
||||
public field?: string
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'ClassroomIoApiError';
|
||||
}
|
||||
}
|
||||
|
||||
export class ClassroomIoApiClient {
|
||||
constructor(private readonly config: McpServerConfig) {}
|
||||
|
||||
async createCourseDraft(payload: TCourseImportDraftCreate) {
|
||||
return this.request('/organization/course-import/drafts', {
|
||||
method: 'POST',
|
||||
body: payload
|
||||
});
|
||||
}
|
||||
|
||||
async getCourseDraft(draftId: string) {
|
||||
return this.request(`/organization/course-import/drafts/${draftId}`, {
|
||||
method: 'GET'
|
||||
});
|
||||
}
|
||||
|
||||
async updateCourseDraft(draftId: string, payload: TCourseImportDraftUpdate) {
|
||||
return this.request(`/organization/course-import/drafts/${draftId}`, {
|
||||
method: 'PUT',
|
||||
body: payload
|
||||
});
|
||||
}
|
||||
|
||||
async publishCourseDraft(draftId: string, payload: TCourseImportDraftPublish) {
|
||||
return this.request(`/organization/course-import/drafts/${draftId}/publish`, {
|
||||
method: 'POST',
|
||||
body: payload
|
||||
});
|
||||
}
|
||||
|
||||
private async request<TResponse>(
|
||||
path: string,
|
||||
options: {
|
||||
method: 'GET' | 'POST' | 'PUT';
|
||||
body?: unknown;
|
||||
}
|
||||
): Promise<TResponse> {
|
||||
const response = await fetch(new URL(path, this.config.CLASSROOMIO_API_URL), {
|
||||
method: options.method,
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.config.CLASSROOMIO_API_KEY}`,
|
||||
'content-type': 'application/json',
|
||||
'user-agent': this.config.CLASSROOMIO_USER_AGENT
|
||||
},
|
||||
body: options.body ? JSON.stringify(options.body) : undefined
|
||||
});
|
||||
|
||||
const json = (await response.json().catch(() => null)) as ApiSuccess<TResponse> | ApiFailure | null;
|
||||
|
||||
if (!response.ok) {
|
||||
const errorPayload = json as ApiFailure | null;
|
||||
throw new ClassroomIoApiError(
|
||||
errorPayload?.error ?? errorPayload?.message ?? `ClassroomIO request failed with status ${response.status}`,
|
||||
response.status,
|
||||
errorPayload?.code,
|
||||
errorPayload?.field
|
||||
);
|
||||
}
|
||||
|
||||
if (!json || typeof json !== 'object' || !('success' in json) || !json.success) {
|
||||
throw new ClassroomIoApiError('ClassroomIO returned an invalid response payload', response.status);
|
||||
}
|
||||
|
||||
return json.data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user