npm package: @lumina-study/courses-sdk
Description: Type-safe TypeScript SDK for the Courses Platform API, auto-generated from OpenAPI specification
Author: Lumina Study
Latest version: 0.1.0-alpha.1

# @lumina-study/courses-sdk

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

## Installation

```bash
npm install @lumina-study/courses-sdk openapi-fetch
# or
pnpm add @lumina-study/courses-sdk openapi-fetch
```

## Quick Start

```typescript
import { createCoursesSDK } from '@lumina-study/courses-sdk';

// Initialize the SDK
const sdk = createCoursesSDK({
  baseUrl: 'https://api.example.com',
  getToken: () => localStorage.getItem('token'), // Optional: for authenticated endpoints
});

// Use the SDK
const courses = await sdk.courses.findAll();
console.log(courses);
```

## Features

- 🔒 **Type-safe** - Full TypeScript type inference for all API methods
- 🚀 **Lightweight** - Only 6kb runtime with openapi-fetch
- 📝 **Auto-generated** - Types and methods generated from OpenAPI specification
- 🎯 **Namespaced** - Intuitive API organization (courses, enrollments, admin)
- ⚡ **Modern** - Supports both CommonJS and ESM
- 🧪 **Testable** - Dependency injection for easy mocking

## Usage Examples

### List Courses

```typescript
// Get all published courses (public endpoint)
const courses = await sdk.courses.findAllPublished();
```

### Publish a Course

```typescript
// Publish a new course (requires authentication)
const course = await sdk.courses.publishCourse({
  data: {
    name: 'Introduction to TypeScript',
    institution: 'Tech University',
  },
  categories: ['Programming'],
  tags: ['typescript', 'beginner'],
});
```

### Enroll in a Course

```typescript
// Enroll in a course (requires authentication)
const enrollment = await sdk.enrollments.enroll(courseId);

// Check if enrolled
const isEnrolled = await sdk.enrollments.isEnrolled(courseId);
```

### Error Handling

```typescript
import {
  ValidationError,
  AuthenticationError,
  NotFoundError,
} from '@lumina-study/courses-sdk';

try {
  const course = await sdk.courses.findOne('invalid-id');
} catch (error) {
  if (error instanceof NotFoundError) {
    console.error('Course not found:', error.resourceId);
  } else if (error instanceof AuthenticationError) {
    // Redirect to login
  } else if (error instanceof ValidationError) {
    // Display field errors
    console.error(error.fields);
  }
}
```

## API Reference

### Courses Namespace

- `findAll()` - Get all courses
- `findAllPublished()` - Get published courses
- `findOne(id)` - Get course by ID
- `publishCourse(dto)` - Publish new course
- `getMyCourses()` - Get authenticated user's courses
- `update(id, dto)` - Update course
- `remove(id)` - Delete course
- `publish(id)` - Publish course
- `unpublish(id)` - Unpublish course
- `getVersionHistory(id, params?)` - Get course version history
- `getLatestVersion(id)` - Get latest version
- `getVersion(id, versionNumber)` - Get specific version
- `compareVersions(id, v1, v2)` - Compare two versions

### Enrollments Namespace

- `enroll(courseId)` - Enroll in course
- `getUserEnrollments()` - Get user's enrollments
- `getEnrollment(courseId)` - Check enrollment status
- `withdraw(courseId)` - Withdraw from course
- `isEnrolled(courseId)` - Check if enrolled (boolean)

### Admin Namespace

- `admin.courses.findAll()` - Get all courses (admin)
- `admin.courses.findOne(id)` - Get course (admin)
- `admin.courses.update(id, dto)` - Update course (admin)
- `admin.courses.remove(id)` - Delete course (admin)
- `admin.courses.publish(id)` - Publish course (admin)
- `admin.courses.unpublish(id)` - Unpublish course (admin)

## Development

```bash
# Install dependencies
pnpm install

# Generate types from OpenAPI spec
pnpm run generate

# Build the SDK
pnpm run build

# Run tests
pnpm test

# Type check
pnpm run typecheck
```

## CI/CD and Publishing

This package uses GitHub Actions for automated testing, building, and publishing to npm.

### Continuous Integration

Every push and pull request triggers the CI workflow:
- ✅ Tests across Node.js 18, 20, and 22
- ✅ Type checking with TypeScript
- ✅ Linting with ESLint
- ✅ Build verification

### Publishing to npm

The package is automatically published to npm when you create a version tag.

**Manual Release (Recommended):**

```bash
# Patch release (0.1.0 -> 0.1.1)
pnpm run release:patch

# Minor release (0.1.0 -> 0.2.0)
pnpm run release:minor

# Major release (0.1.0 -> 1.0.0)
pnpm run release:major
```

These commands will:
1. Bump the version in package.json
2. Create a git tag
3. Push changes and tag to GitHub
4. Trigger the release workflow
5. Publish to npm automatically

**Automated Release via GitHub Actions:**

Go to Actions → "Auto Release" → Run workflow:
- Select version bump type (patch/minor/major)
- Optionally specify prerelease identifier (alpha/beta/rc)

**Requirements:**
- Set `NPM_TOKEN` secret in GitHub repository settings
  - Get token from https://www.npmjs.com/settings/[username]/tokens
  - Add as repository secret: Settings → Secrets → Actions → New secret
  - Name: `NPM_TOKEN`
  - Value: Your npm token

### Version Management

This package follows [Semantic Versioning](https://semver.org/):
- **MAJOR** (1.0.0): Breaking API changes
- **MINOR** (0.1.0): New features, backward compatible
- **PATCH** (0.0.1): Bug fixes, backward compatible

See [CHANGELOG.md](./CHANGELOG.md) for release history.

## Repository Structure

```
courses-service-sdk/
├── .github/
│   └── workflows/
│       ├── ci.yml              # CI: test, lint, build
│       ├── release.yml         # Release: publish to npm
│       ├── auto-release.yml    # Manual version bump workflow
│       └── update-types.yml    # Auto-update OpenAPI types
├── src/
│   ├── client/                 # SDK client factory
│   ├── errors/                 # Error classes
│   ├── namespaces/             # API namespaces
│   ├── types/                  # Type exports
│   └── generated/              # Auto-generated from OpenAPI
├── package.json
├── tsconfig.json
└── README.md
```

## Contributing

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## License

MIT