UNPKG

@lumina-study/courses-sdk

Version:

Type-safe TypeScript SDK for the Courses Platform API, auto-generated from OpenAPI specification

529 lines (518 loc) 16.1 kB
'use strict'; var createClient = require('openapi-fetch'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var createClient__default = /*#__PURE__*/_interopDefault(createClient); // src/client/factory.ts // src/errors/index.ts var ApiError = class extends Error { constructor(message, statusCode) { super(message); this.name = "ApiError"; this.statusCode = statusCode; this.isNetworkError = false; } }; var ValidationError = class extends ApiError { constructor(message, fields) { super(message, 400); this.name = "ValidationError"; this.fields = fields; } }; var AuthenticationError = class extends ApiError { constructor(message = "Authentication required") { super(message, 401); this.name = "AuthenticationError"; } }; var AuthorizationError = class extends ApiError { constructor(message = "Insufficient permissions") { super(message, 403); this.name = "AuthorizationError"; } }; var NotFoundError = class extends ApiError { constructor(resourceType, resourceId) { super(`${resourceType} with ID ${resourceId} not found`, 404); this.name = "NotFoundError"; this.resourceType = resourceType; this.resourceId = resourceId; } }; var ServerError = class extends ApiError { constructor(message, statusCode = 500) { super(message, statusCode); this.name = "ServerError"; } }; var NetworkError = class extends Error { constructor(message = "Network connection failed") { super(message); this.isNetworkError = true; this.name = "NetworkError"; } }; // src/client/error-handler.ts function handleApiError(error, response, resourceType, resourceId) { if (error instanceof TypeError && error.message.includes("Failed to fetch")) { throw new NetworkError("Unable to connect to server. Please check your network connection."); } const status = response?.status ?? 500; switch (status) { case 400: if (typeof error === "object" && error !== null && "message" in error) { const errorObj = error; if (Array.isArray(errorObj.message)) { const fields = {}; errorObj.message.forEach((msg) => { const match = msg.match(/^(\w+)\.(.+)$/); if (match && match[1] && match[2]) { const field = match[1]; const message = match[2]; if (!fields[field]) fields[field] = []; fields[field].push(message); } else { if (!fields.general) fields.general = []; fields.general.push(msg); } }); throw new ValidationError("Validation failed", fields); } } throw new ValidationError("Invalid request", {}); case 401: throw new AuthenticationError(); case 403: throw new AuthorizationError(); case 404: if (resourceType && resourceId) { throw new NotFoundError(resourceType, resourceId); } throw new ApiError("Resource not found", 404); case 500: case 502: case 503: case 504: throw new ServerError("Server error occurred", status); default: if (status >= 500) { throw new ServerError(`Server error occurred (${status})`, status); } throw new ApiError(`Request failed with status ${status}`, status); } } // src/namespaces/courses.ts function createCoursesNamespace(client) { return { /** * Get all courses (public endpoint) * @returns Array of all published courses */ async findAll() { const { data, error, response } = await client.GET("/api/courses"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Get all published courses * @returns Array of published courses */ async findAllPublished() { const { data, error, response } = await client.GET("/api/courses/published"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Get a single course by ID * @param id - Course ID * @returns Course details * @throws NotFoundError if course doesn't exist */ async findOne(id) { const { data, error, response } = await client.GET("/api/courses/{id}", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Search for courses (authenticated endpoint) * @returns Array of matching courses */ async search() { const { data, error, response } = await client.GET("/api/courses/search"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Publish a new course from local draft (authenticated endpoint) * @param dto - Course data to publish * @returns Published course details * @throws ValidationError if course data is invalid * @throws AuthenticationError if not authenticated */ async publishCourse(dto) { const { data, error, response } = await client.POST("/api/courses/publish", { body: dto }); if (error || !data) { handleApiError(error, response); } return data; }, /** * Get courses owned by authenticated user * @returns Array of user's courses (published and unpublished) * @throws AuthenticationError if not authenticated */ async getMyCourses() { const { data, error, response } = await client.GET("/api/courses/my-courses"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Update an existing course * @param id - Course ID * @param dto - Updated course data * @returns Updated course details * @throws NotFoundError if course doesn't exist * @throws AuthorizationError if user doesn't own the course */ async update(id, dto) { const { data, error, response } = await client.PATCH("/api/courses/{id}", { params: { path: { id } }, body: dto }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Delete a course * @param id - Course ID * @throws NotFoundError if course doesn't exist * @throws AuthorizationError if user doesn't own the course */ async remove(id) { const { error, response } = await client.DELETE("/api/courses/{id}", { params: { path: { id } } }); if (error) { handleApiError(error, response, "Course", id); } }, /** * Publish a course (change state to published) * @param id - Course ID * @returns Updated course details */ async publish(id) { const { data, error, response } = await client.PATCH("/api/courses/{id}/publish", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Unpublish a course (change state to unpublished) * @param id - Course ID * @returns Updated course details */ async unpublish(id) { const { data, error, response } = await client.PATCH("/api/courses/{id}/unpublish", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Get version history for a course * @param id - Course ID * @param params - Optional pagination parameters * @returns Paginated version history */ async getVersionHistory(id, params) { const { data, error, response } = await client.GET("/api/courses/{id}/versions", { params: { path: { id }, query: params } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Get the latest version of a course * @param id - Course ID * @returns Latest course version */ async getLatestVersion(id) { const { data, error, response } = await client.GET("/api/courses/{id}/versions/latest", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "CourseVersion", id); } return data; }, /** * Get a specific version of a course * @param id - Course ID * @param versionNumber - Version number * @returns Course version details */ async getVersion(id, versionNumber) { const { data, error, response } = await client.GET("/api/courses/{id}/versions/{versionNumber}", { params: { path: { id, versionNumber } } }); if (error || !data) { handleApiError(error, response, "CourseVersion", `${id}/v${versionNumber}`); } return data; }, /** * Compare two versions of a course * @param id - Course ID * @param v1 - First version number * @param v2 - Second version number * @returns Comparison data for both versions */ async compareVersions(id, v1, v2) { const { data, error, response } = await client.GET("/api/courses/{id}/versions/compare", { params: { path: { id }, query: { v1, v2 } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; } }; } // src/namespaces/enrollments.ts function createEnrollmentsNamespace(client) { return { /** * Enroll in a course (idempotent - returns existing enrollment if already enrolled) * @param courseId - Course ID to enroll in * @returns Enrollment details * @throws AuthenticationError if not authenticated * @throws NotFoundError if course doesn't exist */ async enroll(courseId) { const { data, error, response } = await client.POST("/api/enrollments", { body: { courseId } }); if (error || !data) { handleApiError(error, response); } return data; }, /** * Get all enrollments for authenticated user * @returns Array of active enrollments * @throws AuthenticationError if not authenticated */ async getUserEnrollments() { const { data, error, response } = await client.GET("/api/enrollments"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Check if user is enrolled in a specific course * @param courseId - Course ID to check * @returns Enrollment details or null if not enrolled * @throws AuthenticationError if not authenticated */ async getEnrollment(courseId) { const { data, error, response } = await client.GET("/api/enrollments/{courseId}", { params: { path: { courseId } } }); if (response?.status === 404) { return null; } if (error || !data) { handleApiError(error, response); } return data; }, /** * Withdraw from a course * @param courseId - Course ID to withdraw from * @returns Updated enrollment with withdrawn status * @throws AuthenticationError if not authenticated * @throws NotFoundError if not enrolled in course */ async withdraw(courseId) { const { data, error, response } = await client.DELETE("/api/enrollments/{courseId}", { params: { path: { courseId } } }); if (error || !data) { handleApiError(error, response); } return data; }, /** * Check if user is enrolled in a course (boolean helper) * @param courseId - Course ID to check * @returns true if enrolled and active, false otherwise */ async isEnrolled(courseId) { try { const enrollment = await this.getEnrollment(courseId); return enrollment !== null && enrollment.status === "active"; } catch { return false; } } }; } // src/namespaces/admin.ts function createAdminNamespace(client) { return { courses: { /** * Get all courses (admin endpoint) * @returns Array of all courses * @throws AuthenticationError if not authenticated * @throws AuthorizationError if user is not admin */ async findAll() { const { data, error, response } = await client.GET("/api/admin/courses"); if (error || !data) { handleApiError(error, response); } return data; }, /** * Get a single course by ID (admin endpoint) * @param id - Course ID * @returns Course details * @throws AuthorizationError if user is not admin */ async findOne(id) { const { data, error, response } = await client.GET("/api/admin/courses/{id}", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Update a course (admin endpoint) * @param id - Course ID * @param dto - Updated course data * @returns Updated course details * @throws AuthorizationError if user is not admin */ async update(id, dto) { const { data, error, response } = await client.PATCH("/api/admin/courses/{id}", { params: { path: { id } }, body: dto }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Delete a course (admin endpoint) * @param id - Course ID * @throws AuthorizationError if user is not admin */ async remove(id) { const { error, response } = await client.DELETE("/api/admin/courses/{id}", { params: { path: { id } } }); if (error) { handleApiError(error, response, "Course", id); } }, /** * Publish a course (admin endpoint) * @param id - Course ID * @returns Updated course details * @throws AuthorizationError if user is not admin */ async publish(id) { const { data, error, response } = await client.PATCH("/api/admin/courses/{id}/publish", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; }, /** * Unpublish a course (admin endpoint) * @param id - Course ID * @returns Updated course details * @throws AuthorizationError if user is not admin */ async unpublish(id) { const { data, error, response } = await client.PATCH("/api/admin/courses/{id}/unpublish", { params: { path: { id } } }); if (error || !data) { handleApiError(error, response, "Course", id); } return data; } } }; } // src/client/factory.ts function createCoursesSDK(config) { const client = createClient__default.default({ baseUrl: config.baseUrl, fetch: config.fetch }); if (config.getToken) { client.use({ async onRequest({ request }) { const token = await Promise.resolve(config.getToken?.()); if (token) { request.headers.set("Authorization", `Bearer ${token}`); } return request; } }); } return { courses: createCoursesNamespace(client), enrollments: createEnrollmentsNamespace(client), admin: createAdminNamespace(client) }; } exports.ApiError = ApiError; exports.AuthenticationError = AuthenticationError; exports.AuthorizationError = AuthorizationError; exports.NetworkError = NetworkError; exports.NotFoundError = NotFoundError; exports.ServerError = ServerError; exports.ValidationError = ValidationError; exports.createCoursesSDK = createCoursesSDK; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map