Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
16 changes: 16 additions & 0 deletions .github/workflows/regenerate_sdk.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,22 @@ jobs:
- name: Lint and fix with ruff
run: uv run --locked ruff check --fix .

# -----------------------------------------------------------------------
# 7b. Regenerate the javascript SDK from the same schemas
# -----------------------------------------------------------------------
- name: Set up Node 20
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "20"
cache: npm
cache-dependency-path: javascript/package-lock.json

- name: Regenerate javascript SDK
run: |
CMS_SCHEMA_FILE="platform/docs/cms-openapi.yaml" \
LMS_SCHEMA_FILE="platform/docs/lms-openapi.yaml" \
./regen_sdk_js.sh

# -----------------------------------------------------------------------
# 8. Open a PR if anything changed
#
Expand Down
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ dmypy.json

# Sparse checkout of openedx-platform made by regenerate_sdk.yml
/platform/

# JavaScript
javascript/node_modules/
javascript/dist/
javascript/coverage/
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# openedx-platform-sdk

Client libraries for the OpenedX Authoring and Enrollment APIs, auto-generated
from the platform's OpenAPI schema.

| Directory | Package | Generator |
| --- | --- | --- |
| root (`openedx_platform_sdk/`) | `openedx-platform-sdk` (PyPI) | openapi-python-client |
| [`javascript/`](./javascript) | `@openedx/openedx-platform-sdk` (npm) | @hey-api/openapi-ts |

Both are generated from the same filtered schema, so they cover the same
operations. See [`javascript/README.md`](./javascript/README.md) for the JS SDK.

---

A Python client library for the [OpenedX Authoring API](https://docs.openedx.org), auto-generated from the platform's OpenAPI schema using [openapi-python-client](https://github.com/openapi-generators/openapi-python-client).

Covers the standardized v1/v3/v4 Studio APIs and LMS Enrollment v2 APIs tagged `openedx-platform-sdk` in the platform.
Expand Down
10 changes: 10 additions & 0 deletions javascript/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": { "ecmaVersion": 2022, "sourceType": "module" },
"plugins": ["@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
"env": { "node": true, "es2022": true },
"ignorePatterns": ["dist", "coverage", "node_modules", "src/generated"],
"overrides": [{ "files": ["src/__tests__/**/*.ts"], "env": { "jest": true } }]
}
89 changes: 89 additions & 0 deletions javascript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# openedx-platform-sdk (JavaScript)

A TypeScript client library for the OpenedX Authoring and Enrollment APIs,
auto-generated from the platform's OpenAPI schema using
[@hey-api/openapi-ts](https://github.com/hey-api/openapi-ts).

Generated from the same filtered schema as the Python SDK, so both cover the
operations tagged `openedx-platform-sdk` in the platform.

## Install

```bash
npm install @openedx/openedx-platform-sdk
```

## Usage

```ts
import { OAuth2ClientCredentials, v4HomeCoursesRetrieve } from '@openedx/openedx-platform-sdk';

const auth = new OAuth2ClientCredentials({
lmsUrl: 'http://local.openedx.io:8000',
studioUrl: 'http://studio.local.openedx.io:8001/api/contentstore',
clientId: 'your-client-id',
clientSecret: 'your-client-secret',
});

const client = await auth.getStudioClient();
const { data } = await v4HomeCoursesRetrieve({ client });

const lmsClient = await auth.getLmsClient();
```

Tokens are fetched with the OAuth2 `client_credentials` grant, sent with the
`JWT` prefix that OpenedX expects, and refreshed automatically before expiry.

### Use inside an MFE

MFEs already hold an authenticated session, so skip `OAuth2ClientCredentials`
and build a client around the existing axios instance:

```ts
import { createClient } from '@openedx/openedx-platform-sdk';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';

const client = createClient({ axios: getAuthenticatedHttpClient(), baseURL: studioUrl });
```

## Regenerating

`src/generated/` is produced by the generator and committed, matching how the
Python package is handled. `src/auth.ts` and `src/index.ts` are hand-written and
are never touched by the generator.

### Prerequisites

Node 20 or newer, plus [uv](https://docs.astral.sh/uv/) for the schema filter.

```bash
cd javascript && npm install
```

### Steps

From the repo root, using the same schema sources as `regen_sdk.sh`:

```bash
# From running Studio + LMS instances
STUDIO_URL=http://studio.local.openedx.io:8001 \
LMS_URL=http://local.openedx.io:8000 \
./regen_sdk_js.sh

# From a local platform checkout
PLATFORM_DIR=/path/to/openedx-platform ./regen_sdk_js.sh

# From schema files (used by CI)
CMS_SCHEMA_FILE=platform/docs/cms-openapi.yaml \
LMS_SCHEMA_FILE=platform/docs/lms-openapi.yaml \
./regen_sdk_js.sh
```

The weekly `regenerate_sdk.yml` workflow regenerates both SDKs and opens a PR.

## Development

```bash
npm run validate # lint, typecheck and test
npm run build # dual CJS/ESM build with type declarations
```
12 changes: 12 additions & 0 deletions javascript/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.test.ts'],
transform: {
'^.+\\.ts$': [
'ts-jest',
{ tsconfig: { module: 'CommonJS', target: 'ES2020', esModuleInterop: true } },
],
},
collectCoverageFrom: ['src/**/*.ts', '!src/generated/**', '!src/index.ts'],
};
12 changes: 12 additions & 0 deletions javascript/openapi-ts.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from '@hey-api/openapi-ts';

// Mirrors ../config.yml. Input is the filtered schema produced by
// ../filter_schema.py, so python and js cover the same tagged operations.
export default defineConfig({
input: '../filtered_schema.yml',
output: {
path: 'src/generated',
postProcess: ['prettier'],
},
plugins: ['@hey-api/client-axios'],
});
Loading