@eduware/oneroster 1.2.5 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/FUNCTIONS.md +232 -0
  2. package/README.md +490 -342
  3. package/dist/commonjs/clients/classlink.d.ts +2 -3
  4. package/dist/commonjs/clients/classlink.d.ts.map +1 -1
  5. package/dist/commonjs/clients/classlink.js.map +1 -1
  6. package/dist/commonjs/clients/types.d.ts +5 -3
  7. package/dist/commonjs/clients/types.d.ts.map +1 -1
  8. package/dist/commonjs/enums/index.d.ts +2 -0
  9. package/dist/commonjs/enums/index.d.ts.map +1 -0
  10. package/dist/commonjs/enums/index.js +18 -0
  11. package/dist/commonjs/enums/index.js.map +1 -0
  12. package/dist/commonjs/models/index.d.ts +2 -0
  13. package/dist/commonjs/models/index.d.ts.map +1 -0
  14. package/dist/commonjs/models/index.js +18 -0
  15. package/dist/commonjs/models/index.js.map +1 -0
  16. package/dist/commonjs/types/index.d.ts +1 -0
  17. package/dist/commonjs/types/index.d.ts.map +1 -1
  18. package/dist/commonjs/types/index.js +16 -0
  19. package/dist/commonjs/types/index.js.map +1 -1
  20. package/dist/esm/clients/classlink.d.ts +2 -3
  21. package/dist/esm/clients/classlink.d.ts.map +1 -1
  22. package/dist/esm/clients/classlink.js.map +1 -1
  23. package/dist/esm/clients/types.d.ts +5 -3
  24. package/dist/esm/clients/types.d.ts.map +1 -1
  25. package/dist/esm/enums/index.d.ts +2 -0
  26. package/dist/esm/enums/index.d.ts.map +1 -0
  27. package/dist/esm/enums/index.js +2 -0
  28. package/dist/esm/enums/index.js.map +1 -0
  29. package/dist/esm/models/index.d.ts +2 -0
  30. package/dist/esm/models/index.d.ts.map +1 -0
  31. package/dist/esm/models/index.js +2 -0
  32. package/dist/esm/models/index.js.map +1 -0
  33. package/dist/esm/types/index.d.ts +1 -0
  34. package/dist/esm/types/index.d.ts.map +1 -1
  35. package/dist/esm/types/index.js +2 -0
  36. package/dist/esm/types/index.js.map +1 -1
  37. package/package.json +37 -79
  38. package/src/clients/classlink.ts +2 -3
  39. package/src/clients/types.ts +5 -3
  40. package/src/enums/index.ts +1 -0
  41. package/src/models/index.ts +1 -0
  42. package/src/types/index.ts +3 -0
  43. package/vitest.config.ts +2 -2
  44. package/test/summary-reporter.ts +0 -114
package/README.md CHANGED
@@ -22,13 +22,13 @@ Type-safe TypeScript SDK for the OneRoster API with LMS-specific client profiles
22
22
 
23
23
  ## Features
24
24
 
25
- - **OneRoster v1.1 & v1.2 support** - Complete implementation of both 1EdTech OneRoster specifications
26
- - **LMS-specific profiles** - Pre-built profiles for ClassLink with type-safe method restrictions
27
- - **Custom profiles** - Create your own profiles using TypeScript's `Pick<>` types
28
- - **OAuth 2.0 & OAuth 1.0a authentication** - OAuth 2.0 for v1.2 (default), OAuth 1.0a for v1.1
29
- - **Automatic pagination** - Async iterables for seamless data fetching
30
- - **TypeScript-first** - Full type safety with comprehensive type definitions
31
- - **Tree-shakeable** - Standalone functions for optimal bundle sizes
25
+ - OneRoster v1.1 and v1.2 support
26
+ - LMS-specific client profiles (read-only vs full CRUD)
27
+ - Custom profiles: create your own profiles with TypeScript `Pick<>`
28
+ - OAuth 2.0 (v1.2) and OAuth 1.0a (v1.1)
29
+ - Automatic pagination with async iterables
30
+ - TypeScript-first with comprehensive types
31
+ - Tree-shakeable standalone functions for small bundles
32
32
 
33
33
  ## Installation
34
34
 
@@ -46,9 +46,15 @@ yarn add @eduware/oneroster zod
46
46
  bun add @eduware/oneroster
47
47
  ```
48
48
 
49
- > **Note:** Yarn does not install peer dependencies automatically. You will need to install `zod` manually.
49
+ > Note: Yarn does not install peer dependencies automatically. Install `zod` manually.
50
50
 
51
- ## Quick Start
51
+ ## Changelog
52
+
53
+ See [CHANGELOG.md](./CHANGELOG.md) for release notes and breaking changes.
54
+
55
+ ## Quick Start (recommended)
56
+
57
+ The main entry point is the full client:
52
58
 
53
59
  ```typescript
54
60
  import { OneRoster } from '@eduware/oneroster';
@@ -62,21 +68,19 @@ const client = new OneRoster({
62
68
  },
63
69
  });
64
70
 
65
- // Fetch all users with automatic pagination
66
- const result = await client.usersManagement.getAllUsers({});
71
+ const user = await client.usersManagement.getUser({
72
+ sourcedId: 'user-id',
73
+ });
67
74
 
68
- for await (const page of result) {
69
- console.log(page.result.users);
75
+ const schools = await client.schoolsManagement.getAllSchools({});
76
+ for await (const page of schools) {
77
+ console.log(page.result.orgs);
70
78
  }
71
79
  ```
72
80
 
73
- ## LMS Profiles
74
-
75
- The SDK provides LMS-specific client profiles that restrict available methods to match what each provider supports. This gives you compile-time safety and prevents calling unsupported endpoints.
76
-
77
- ### ClassLink Client
81
+ ## ClassLink Example (read-only profile)
78
82
 
79
- ClassLink provides read-only rostering data. The `ClassLink` client is typed to only expose supported methods:
83
+ Show LMS integrations explicitly by using the ClassLink client, which only exposes read endpoints:
80
84
 
81
85
  ```typescript
82
86
  import { ClassLink } from '@eduware/oneroster/clients';
@@ -89,248 +93,208 @@ const client = new ClassLink({
89
93
  },
90
94
  });
91
95
 
92
- // Read operations work
96
+ // Read operations are available
93
97
  const users = await client.usersManagement.getAllUsers({});
94
- const schools = await client.schoolsManagement.getAllSchools({});
95
98
 
96
- // Write operations are not available (TypeScript error)
97
- // client.usersManagement.createUser({}); // Error: Property 'createUser' does not exist
99
+ // Write operations are not available (TypeScript error)
100
+ // await client.usersManagement.createUser({ ... });
98
101
  ```
99
102
 
100
- ### Full Client
103
+ ## Custom Profile Example (your LMS)
101
104
 
102
- For full OneRoster access with all methods available:
105
+ Define a profile that matches your LMS contract by picking only the methods you need:
103
106
 
104
107
  ```typescript
105
108
  import { OneRoster } from '@eduware/oneroster';
109
+ import type { OneRosterClient } from '@eduware/oneroster/clients';
110
+ import type { UsersManagement, ClassesManagement } from '@eduware/oneroster';
106
111
 
107
- const client = new OneRoster({
108
- serverURL: 'https://your-oneroster-server.com',
112
+ interface CustomProfile {
113
+ usersManagement: Pick<UsersManagement, 'getAllUsers' | 'getUser'>;
114
+ classesManagement: Pick<ClassesManagement, 'getAllClasses' | 'getClass'>;
115
+ }
116
+
117
+ const client: OneRosterClient<CustomProfile> = new OneRoster({
118
+ serverURL: 'https://your-roster-server.com',
109
119
  security: {
110
120
  clientID: process.env.ONEROSTER_CLIENT_ID!,
111
121
  clientSecret: process.env.ONEROSTER_CLIENT_SECRET!,
112
- tokenURL: 'https://your-oneroster-server.com/oauth/token',
122
+ tokenURL: 'https://your-roster-server.com/oauth/token',
113
123
  },
114
124
  });
115
125
 
116
- // All operations available
117
126
  const users = await client.usersManagement.getAllUsers({});
118
- await client.usersManagement.createUser({
119
- user: {
120
- /* ... */
121
- },
122
- });
123
127
  ```
124
128
 
125
- ### Custom Profiles
129
+ This SDK works with any OneRoster-compliant LMS and includes profiles for common integrations.
126
130
 
127
- Create your own profiles by defining an interface that uses `Pick<>` to select specific methods:
131
+ ## Recommended Import Path
132
+
133
+ Most users only need the main client:
128
134
 
129
135
  ```typescript
130
136
  import { OneRoster } from '@eduware/oneroster';
131
- import type { UsersManagement, ClassesManagement } from '@eduware/oneroster/sdk';
132
- import type { OneRosterClient } from '@eduware/oneroster/clients';
137
+ ```
133
138
 
134
- // Define a custom profile with only the methods you need
135
- interface IMyCustomProfile {
136
- usersManagement: Pick<UsersManagement, 'getAllUsers' | 'getUser'>;
137
- classesManagement: Pick<ClassesManagement, 'getAllClasses' | 'getClass'>;
138
- }
139
+ Operation types use `@eduware/oneroster/types`:
139
140
 
140
- // Create a typed client
141
- type MyCustomClient = OneRosterClient<IMyCustomProfile>;
141
+ ```typescript
142
+ import type { GetAllUsersUser, GetAllSchoolsOrg } from '@eduware/oneroster/types';
143
+ ```
142
144
 
143
- const client: MyCustomClient = new OneRoster({
144
- serverURL: 'https://your-server.com',
145
- security: {
146
- /* ... */
147
- },
148
- });
145
+ Model types live at `@eduware/oneroster/models`:
149
146
 
150
- // Only picked methods are available
151
- const users = await client.usersManagement.getAllUsers({});
152
- // client.usersManagement.createUser({}); // TypeScript error!
153
- ```
154
-
155
- ## Management Modules & LMS Support
156
-
157
- The SDK provides management modules for all OneRoster resources. Each module supports CRUD (Create, Read, Update, Delete) operations as defined by the OneRoster specification. However, **not all LMS providers support all operations** - some providers offer read-only access to rostering data.
158
-
159
- > **⚠️ Important:** The availability of operations depends on your LMS provider's implementation. The table below shows which operations are supported by each LMS. Operations marked with ❌ will result in API errors if called against providers that don't support them.
160
-
161
- ### Management Modules Overview
162
-
163
- | Module | Description | Primary Resources |
164
- | ------------------------------------ | ------------------------------------------ | --------------------------------------- |
165
- | `usersManagement` | User accounts (students, teachers, admins) | Users |
166
- | `studentsManagement` | Student-specific operations | Users (role: student) |
167
- | `teachersManagement` | Teacher-specific operations | Users (role: teacher) |
168
- | `classesManagement` | Class/section management | Classes |
169
- | `coursesManagement` | Course catalog management | Courses |
170
- | `enrollmentsManagement` | Class enrollment records | Enrollments |
171
- | `schoolsManagement` | School/organization management | Orgs (type: school) |
172
- | `organizationsManagement` | All organization types | Orgs |
173
- | `academicSessionsManagement` | School years, semesters, terms | Academic Sessions |
174
- | `termsManagement` | Term-specific operations | Academic Sessions (type: term) |
175
- | `gradingPeriodsManagement` | Grading period management | Academic Sessions (type: gradingPeriod) |
176
- | `demographicsManagement` | Student demographic data | Demographics |
177
- | `lineItemsManagement` | Gradebook assignments | Line Items |
178
- | `resultsManagement` | Student grades/scores | Results |
179
- | `categoriesManagement` | Grade categories | Categories |
180
- | `scoreScalesManagement` | Grading scales | Score Scales |
181
- | `resourcesManagement` | Learning resources | Resources |
182
- | `courseComponentsManagement` | Course modules/units | Course Components |
183
- | `courseComponentResourcesManagement` | Resources linked to components | Component Resources |
184
- | `assessmentLineItemsManagement` | Assessment definitions | Assessment Line Items |
185
- | `assessmentResultsManagement` | Assessment scores | Assessment Results |
147
+ ```typescript
148
+ import type { User } from '@eduware/oneroster/models';
149
+ ```
186
150
 
187
- ### CRUD Operations by Module
151
+ Enums live at `@eduware/oneroster/enums`:
188
152
 
189
- | Module | Create | Read | Update | Delete |
190
- | ------------------------------------ | :----: | :--: | :----: | :----: |
191
- | `usersManagement` | ✅ | ✅ | ✅ | ✅ |
192
- | `studentsManagement` | — | ✅ | — | — |
193
- | `teachersManagement` | — | ✅ | — | — |
194
- | `classesManagement` | ✅ | ✅ | ✅ | ✅ |
195
- | `coursesManagement` | ✅ | ✅ | ✅ | ✅ |
196
- | `enrollmentsManagement` | ✅ | ✅ | ✅ | ✅ |
197
- | `schoolsManagement` | ✅ | ✅ | ✅ | ✅ |
198
- | `organizationsManagement` | ✅ | ✅ | ✅ | ✅ |
199
- | `academicSessionsManagement` | ✅ | ✅ | ✅ | ✅ |
200
- | `termsManagement` | — | ✅ | — | — |
201
- | `gradingPeriodsManagement` | ✅ | ✅ | ✅ | ✅ |
202
- | `demographicsManagement` | ✅ | ✅ | ✅ | ✅ |
203
- | `lineItemsManagement` | ✅ | ✅ | ✅ | ✅ |
204
- | `resultsManagement` | ✅ | ✅ | ✅ | ✅ |
205
- | `categoriesManagement` | ✅ | ✅ | ✅ | ✅ |
206
- | `scoreScalesManagement` | ✅ | ✅ | ✅ | ✅ |
207
- | `resourcesManagement` | ✅ | ✅ | ✅ | ✅ |
208
- | `courseComponentsManagement` | ✅ | ✅ | ✅ | ✅ |
209
- | `courseComponentResourcesManagement` | ✅ | ✅ | ✅ | ✅ |
210
- | `assessmentLineItemsManagement` | ✅ | ✅ | ✅ | ✅ |
211
- | `assessmentResultsManagement` | ✅ | ✅ | ✅ | ✅ |
153
+ ```typescript
154
+ import { UserRole } from '@eduware/oneroster/enums';
155
+ ```
212
156
 
213
- _Note: indicates the module uses parent module operations (e.g., students/teachers use usersManagement for CUD)_
157
+ Advanced import paths (standalone functions) are documented later in this README.
214
158
 
215
- ### LMS Provider Support
159
+ ## Client Structure
216
160
 
217
- Different LMS providers implement different subsets of the OneRoster specification. Use this table to understand what's available for your provider:
161
+ The SDK is organized by management modules, grouped by domain:
218
162
 
219
- | Module | OneRoster (Full) | ClassLink |
220
- | ------------------------------------ | :--------------: | :-------: |
221
- | **Core Rostering** | | |
222
- | `usersManagement` | ✅ CRUD | ✅ Read |
223
- | `studentsManagement` | ✅ Read | ✅ Read |
224
- | `teachersManagement` | ✅ Read | ✅ Read |
225
- | `classesManagement` | ✅ CRUD | ✅ Read |
226
- | `coursesManagement` | ✅ CRUD | ✅ Read |
227
- | `enrollmentsManagement` | ✅ CRUD | ✅ Read |
228
- | `schoolsManagement` | ✅ CRUD | ✅ Read |
229
- | `organizationsManagement` | ✅ CRUD | ✅ Read |
230
- | **Academic Calendar** | | |
231
- | `academicSessionsManagement` | ✅ CRUD | ✅ Read |
232
- | `termsManagement` | ✅ Read | ✅ Read |
233
- | `gradingPeriodsManagement` | ✅ CRUD | ✅ Read |
234
- | **Demographics** | | |
235
- | `demographicsManagement` | ✅ CRUD | ❌ |
236
- | **Gradebook** | | |
237
- | `lineItemsManagement` | ✅ CRUD | ❌ |
238
- | `resultsManagement` | ✅ CRUD | ❌ |
239
- | `categoriesManagement` | ✅ CRUD | ❌ |
240
- | `scoreScalesManagement` | ✅ CRUD | ❌ |
241
- | **Resources** | | |
242
- | `resourcesManagement` | ✅ CRUD | ❌ |
243
- | `courseComponentsManagement` | ✅ CRUD | ❌ |
244
- | `courseComponentResourcesManagement` | ✅ CRUD | ❌ |
245
- | **Assessments** | | |
246
- | `assessmentLineItemsManagement` | ✅ CRUD | ❌ |
247
- | `assessmentResultsManagement` | ✅ CRUD | ❌ |
163
+ ### Rostering
164
+
165
+ - `usersManagement`
166
+ - `studentsManagement`
167
+ - `teachersManagement`
168
+ - `classesManagement`
169
+ - `coursesManagement`
170
+ - `enrollmentsManagement`
171
+ - `schoolsManagement`
172
+ - `organizationsManagement`
173
+
174
+ ### Academic Calendar
175
+
176
+ - `academicSessionsManagement`
177
+ - `termsManagement`
178
+ - `gradingPeriodsManagement`
248
179
 
249
- **Legend:**
180
+ ### Gradebook
250
181
 
251
- - ✅ CRUD = Create, Read, Update, Delete all supported
252
- - ✅ Read = Read-only access (GET operations)
253
- - ❌ = Not supported by this provider
182
+ - `lineItemsManagement`
183
+ - `resultsManagement`
184
+ - `categoriesManagement`
185
+ - `scoreScalesManagement`
254
186
 
255
- > **Note:** This table reflects the typical capabilities of each provider. Actual availability may vary based on your specific contract, configuration, or API version. Always consult your provider's documentation for the most accurate information.
187
+ ### Resources
256
188
 
257
- ### Nested Queries
189
+ - `resourcesManagement`
190
+ - `courseComponentsManagement`
191
+ - `courseComponentResourcesManagement`
258
192
 
259
- Many modules support nested queries to fetch related data efficiently:
193
+ ### Assessments
194
+
195
+ - `assessmentLineItemsManagement`
196
+ - `assessmentResultsManagement`
197
+
198
+ ### Demographics
199
+
200
+ - `demographicsManagement`
201
+
202
+ ## Common Operations
260
203
 
261
204
  ```typescript
262
- // Get all students in a specific class
263
- const students = await client.classesManagement.getStudentsForClass({
264
- classSourcedId: 'class-123',
265
- });
205
+ // List with pagination
206
+ const users = await client.usersManagement.getAllUsers({ limit: 100 });
207
+ for await (const page of users) {
208
+ console.log(page.result.users);
209
+ }
266
210
 
267
- // Get all classes for a specific school
268
- const classes = await client.schoolsManagement.getClassesForSchool({
269
- schoolSourcedId: 'school-456',
211
+ // Get by sourcedId
212
+ const student = await client.studentsManagement.getStudent({ sourcedId: 'student-id' });
213
+
214
+ // Create
215
+ await client.coursesManagement.createCourse({
216
+ course: {
217
+ title: 'Algebra I',
218
+ org: { sourcedId: 'school-id' },
219
+ },
270
220
  });
271
221
 
272
- // Get all enrollments for a class
273
- const enrollments = await client.classesManagement.getEnrollmentsForClass({
274
- classSourcedId: 'class-123',
222
+ // Update
223
+ await client.classesManagement.updateClass({
224
+ sourcedId: 'class-id',
225
+ class: { title: 'Math 101 - Period 2' },
275
226
  });
227
+
228
+ // Delete
229
+ await client.organizationsManagement.deleteOrg({ sourcedId: 'org-id' });
276
230
  ```
277
231
 
278
- Common nested query patterns:
232
+ ## Filtering and Sorting
279
233
 
280
- - `schools/{id}/classes`, `schools/{id}/students`, `schools/{id}/teachers`
281
- - `classes/{id}/students`, `classes/{id}/teachers`, `classes/{id}/enrollments`
282
- - `users/{id}/classes`, `students/{id}/classes`, `teachers/{id}/classes`
283
- - `terms/{id}/classes`, `courses/{id}/classes`
234
+ ```typescript
235
+ import { OrderBy } from '@eduware/oneroster/enums';
284
236
 
285
- ## OneRoster Versions
237
+ const activeUsers = await client.usersManagement.getAllUsers({
238
+ filter: "status='active'",
239
+ sort: 'familyName',
240
+ orderBy: OrderBy.Asc,
241
+ });
286
242
 
287
- The SDK supports both OneRoster v1.1 and v1.2 specifications. The default is v1.2.
243
+ const teachers = await client.usersManagement.getAllUsers({
244
+ filter: "role='teacher' AND status='active'",
245
+ });
288
246
 
289
- ### Version 1.2 (Default)
247
+ const searchByEmail = await client.usersManagement.getAllUsers({
248
+ search: 'teacher@district.edu',
249
+ fields: 'sourcedId,username,email',
250
+ });
251
+ ```
290
252
 
291
- OneRoster v1.2 uses OAuth 2.0 authentication and the `/ims/oneroster/rostering/v1p2/` path format:
253
+ ## Pagination and Total Count
254
+
255
+ List operations return an async iterator. If the provider sets `X-Total-Count`, it is exposed as `totalCount`.
292
256
 
293
257
  ```typescript
294
- import { OneRoster } from '@eduware/oneroster';
258
+ const pages = await client.usersManagement.getAllUsers({ limit: 200, offset: 0 });
295
259
 
296
- const client = new OneRoster({
297
- serverURL: 'https://your-server.com',
298
- // oneRosterVersion defaults to '1.2'
299
- security: {
300
- clientID: process.env.ONEROSTER_CLIENT_ID!,
301
- clientSecret: process.env.ONEROSTER_CLIENT_SECRET!,
302
- tokenURL: 'https://your-server.com/oauth/token',
303
- },
304
- });
260
+ for await (const page of pages) {
261
+ console.log('page count', page.result.users.length);
262
+ console.log('total count', page.totalCount);
263
+ }
305
264
  ```
306
265
 
307
- ### Version 1.1
266
+ ## Nested Query Patterns
308
267
 
309
- OneRoster v1.1 uses OAuth 1.0a authentication and the `/ims/oneroster/v1p1/` path format:
268
+ Use the module methods that reflect OneRoster relationships:
310
269
 
311
270
  ```typescript
312
- import { OneRoster } from '@eduware/oneroster';
271
+ // School -> class -> enrollments
272
+ const classes = await client.schoolsManagement.getClassesForSchool({ sourcedId: 'school-id' });
273
+ const enrollments = await client.schoolsManagement.getEnrollmentsForClassInSchool({
274
+ schoolSourcedId: 'school-id',
275
+ classSourcedId: 'class-id',
276
+ });
313
277
 
314
- const client = new OneRoster({
315
- serverURL: 'https://your-server.com',
316
- oneRosterVersion: '1.1',
317
- security: {
318
- authType: 'oauth1',
319
- clientID: process.env.ONEROSTER_CLIENT_ID!,
320
- clientSecret: process.env.ONEROSTER_CLIENT_SECRET!,
321
- },
278
+ // Teacher -> classes
279
+ const teaching = await client.teachersManagement.getClassesForTeacher({
280
+ sourcedId: 'teacher-id',
281
+ });
282
+
283
+ // Class -> line items -> results
284
+ const lineItems = await client.classesManagement.getLineItemsForClass({ sourcedId: 'class-id' });
285
+ const results = await client.classesManagement.getResultsForLineItemForClass({
286
+ classSourcedId: 'class-id',
287
+ lineItemSourcedId: 'line-item-id',
322
288
  });
323
289
  ```
324
290
 
325
- > **Note:** OAuth 1.0a is only supported in OneRoster v1.1. Per the 1EdTech specification, v1.2 requires OAuth 2.0.
291
+ ## OneRoster Versions
326
292
 
327
- ## Authentication
293
+ The SDK supports both OneRoster v1.1 and v1.2. Default is v1.2.
328
294
 
329
- ### OAuth 2.0 (Default for v1.2)
295
+ ### v1.2 (OAuth 2.0)
330
296
 
331
297
  ```typescript
332
- import { OneRoster } from '@eduware/oneroster';
333
-
334
298
  const client = new OneRoster({
335
299
  serverURL: 'https://your-server.com',
336
300
  security: {
@@ -341,17 +305,9 @@ const client = new OneRoster({
341
305
  });
342
306
  ```
343
307
 
344
- You can also use environment variables:
345
-
346
- - `ONEROSTER_CLIENT_ID`
347
- - `ONEROSTER_CLIENT_SECRET`
348
- - `ONEROSTER_TOKEN_URL`
349
-
350
- ### OAuth 1.0a (v1.1 only)
308
+ ### v1.1 (OAuth 1.0a)
351
309
 
352
310
  ```typescript
353
- import { OneRoster } from '@eduware/oneroster';
354
-
355
311
  const client = new OneRoster({
356
312
  serverURL: 'https://your-server.com',
357
313
  oneRosterVersion: '1.1',
@@ -363,170 +319,388 @@ const client = new OneRoster({
363
319
  });
364
320
  ```
365
321
 
366
- ### Bearer Token
367
-
368
- If you already have a token:
322
+ ### Bearer Token (provider-specific)
369
323
 
370
324
  ```typescript
371
- import { OneRoster } from '@eduware/oneroster';
372
-
373
325
  const client = new OneRoster({
374
326
  serverURL: 'https://your-server.com',
375
327
  security: {
376
328
  authType: 'bearer',
377
- bearerToken: 'your-access-token',
329
+ bearerToken: process.env.ONEROSTER_BEARER_TOKEN!,
378
330
  },
379
331
  });
380
332
  ```
381
333
 
382
- ## Pagination
383
-
384
- All list endpoints support automatic pagination using async iterables:
334
+ ## Error Handling
385
335
 
386
336
  ```typescript
387
- const result = await client.usersManagement.getAllUsers({
388
- limit: 100, // Items per page (default: 100)
389
- offset: 0, // Starting offset
337
+ import { OneRoster, OneRosterError, NotFoundResponseError } from '@eduware/oneroster';
338
+
339
+ const client = new OneRoster({
340
+ /* ... */
390
341
  });
391
342
 
392
- // Iterate through all pages automatically
393
- for await (const page of result) {
394
- for (const user of page.result.users ?? []) {
395
- console.log(user.givenName, user.familyName);
343
+ try {
344
+ await client.usersManagement.getUser({ sourcedId: 'missing-id' });
345
+ } catch (error) {
346
+ if (error instanceof NotFoundResponseError) {
347
+ console.log('User not found');
348
+ } else if (error instanceof OneRosterError) {
349
+ console.log('HTTP Error:', error.statusCode, error.message);
396
350
  }
397
351
  }
398
352
  ```
399
353
 
400
- ### Total Count
354
+ ## Standalone Functions (tree-shaking)
401
355
 
402
- The OneRoster API returns the total number of records in the `X-Total-Count` HTTP header. This value is automatically extracted and exposed on each page result:
356
+ Use standalone functions for minimal bundles or serverless environments:
403
357
 
404
358
  ```typescript
405
- const result = await client.usersManagement.getAllUsers({});
359
+ import { OneRosterCore } from '@eduware/oneroster/core.js';
360
+ import { usersManagementGetAllUsers } from '@eduware/oneroster/funcs/usersManagementGetAllUsers.js';
406
361
 
407
- // Or during iteration
408
- for await (const page of result) {
409
- console.log(`Page has ${page.result.users?.length ?? 0} users`);
410
- console.log(`Total: ${page.totalCount}`);
362
+ const core = new OneRosterCore({
363
+ security: {
364
+ clientID: process.env.ONEROSTER_CLIENT_ID!,
365
+ clientSecret: process.env.ONEROSTER_CLIENT_SECRET!,
366
+ },
367
+ });
368
+
369
+ const result = await usersManagementGetAllUsers(core, {});
370
+ if (result.ok) {
371
+ for await (const page of result.value) {
372
+ console.log(page.result.users);
373
+ }
411
374
  }
412
375
  ```
413
376
 
414
- > **Note:** The `totalCount` property is `undefined` if the server does not return the `X-Total-Count` header.
377
+ See [FUNCTIONS.md](./FUNCTIONS.md) for the full list.
415
378
 
416
- ## Filtering & Sorting
379
+ ## Function Index (by Module)
417
380
 
418
- ```typescript
419
- // Filter by status
420
- const activeUsers = await client.usersManagement.getAllUsers({
421
- filter: "status='active'",
422
- });
381
+ Each function maps to `@eduware/oneroster/funcs/<name>.js`.
423
382
 
424
- // Multiple filters
425
- const filteredUsers = await client.usersManagement.getAllUsers({
426
- filter: "status='active' AND role='student'",
427
- });
383
+ ### academicSessionsManagement
428
384
 
429
- // Sorting
430
- const sortedUsers = await client.usersManagement.getAllUsers({
431
- sort: 'familyName',
432
- orderBy: 'asc',
433
- });
385
+ ```text
386
+ academicSessionsManagementDeleteAcademicSession
387
+ academicSessionsManagementGetAcademicSession
388
+ academicSessionsManagementGetAllAcademicSessions
389
+ academicSessionsManagementPostAcademicSession
390
+ academicSessionsManagementPutAcademicSession
391
+ ```
434
392
 
435
- // Select specific fields
436
- const partialUsers = await client.usersManagement.getAllUsers({
437
- fields: 'sourcedId,givenName,familyName,email',
438
- });
393
+ ### assessmentLineItemsManagement
394
+
395
+ ```text
396
+ assessmentLineItemsManagementCreateAssessmentLineItem
397
+ assessmentLineItemsManagementDeleteAssessmentLineItem
398
+ assessmentLineItemsManagementGetAllAssessmentLineItems
399
+ assessmentLineItemsManagementGetAssessmentLineItem
400
+ assessmentLineItemsManagementUpdateAssessmentLineItem
439
401
  ```
440
402
 
441
- ## Error Handling
403
+ ### assessmentResultsManagement
442
404
 
443
- Error classes are exported directly from the main package for convenience:
405
+ ```text
406
+ assessmentResultsManagementCreateAssessmentResult
407
+ assessmentResultsManagementDeleteAssessmentResult
408
+ assessmentResultsManagementGetAllAssessmentResults
409
+ assessmentResultsManagementGetAssessmentResult
410
+ assessmentResultsManagementUpdateAssessmentResult
411
+ ```
444
412
 
445
- ```typescript
446
- import {
447
- OneRoster,
448
- OneRosterError,
449
- NotFoundResponseError,
450
- UnauthorizedRequestResponseError,
451
- } from '@eduware/oneroster';
413
+ ### categoriesManagement
452
414
 
453
- const client = new OneRoster({
454
- /* ... */
455
- });
415
+ ```text
416
+ categoriesManagementCreateCategory
417
+ categoriesManagementDeleteCategory
418
+ categoriesManagementGetAllCategories
419
+ categoriesManagementGetCategory
420
+ categoriesManagementUpdateCategory
421
+ ```
456
422
 
457
- try {
458
- const user = await client.usersManagement.getUser({
459
- sourcedId: 'non-existent-id',
460
- });
461
- } catch (error) {
462
- if (error instanceof NotFoundResponseError) {
463
- console.log('User not found');
464
- } else if (error instanceof UnauthorizedRequestResponseError) {
465
- console.log('Authentication failed');
466
- } else if (error instanceof OneRosterError) {
467
- // Base class for all HTTP errors
468
- console.log('HTTP Error:', error.statusCode, error.message);
469
- }
470
- }
423
+ ### classesManagement
424
+
425
+ ```text
426
+ classesManagementAddStudentToClass
427
+ classesManagementAddTeacherToClass
428
+ classesManagementCreateClass
429
+ classesManagementDeleteClass
430
+ classesManagementGetAllClasses
431
+ classesManagementGetCategoriesForClass
432
+ classesManagementGetClass
433
+ classesManagementGetClassesForStudent
434
+ classesManagementGetClassesForTeacher
435
+ classesManagementGetClassesForTerm
436
+ classesManagementGetClassesForUser
437
+ classesManagementGetLineItemsForClass
438
+ classesManagementGetResultsForClass
439
+ classesManagementGetResultsForLineItemForClass
440
+ classesManagementGetResultsForStudentForClass
441
+ classesManagementGetScoreScalesForClass
442
+ classesManagementGetStudentsForClass
443
+ classesManagementGetTeachersForClass
444
+ classesManagementPostResultsForAcademicSessionForClass
445
+ classesManagementUpdateClass
471
446
  ```
472
447
 
473
- You can also import all errors as a namespace:
448
+ ### coursesManagement
449
+
450
+ ```text
451
+ coursesManagementCreateComponentResource
452
+ coursesManagementCreateCourse
453
+ coursesManagementCreateCourseComponent
454
+ coursesManagementDeleteComponentResource
455
+ coursesManagementDeleteCourse
456
+ coursesManagementDeleteCourseComponent
457
+ coursesManagementGetAllComponentResources
458
+ coursesManagementGetAllCourseComponents
459
+ coursesManagementGetAllCourses
460
+ coursesManagementGetClassesForCourse
461
+ coursesManagementGetComponentResource
462
+ coursesManagementGetCourse
463
+ coursesManagementGetCourseComponent
464
+ coursesManagementPutComponentResource
465
+ coursesManagementPutCourse
466
+ coursesManagementPutCourseComponent
467
+ ```
474
468
 
475
- ```typescript
476
- import { OneRoster, errors } from '@eduware/oneroster';
477
- // Or from the dedicated subpath
478
- import * as errors from '@eduware/oneroster/models/errors';
469
+ ### demographicsManagement
479
470
 
480
- if (error instanceof errors.NotFoundResponseError) {
481
- // ...
482
- }
471
+ ```text
472
+ demographicsManagementDeleteDemographics
473
+ demographicsManagementGetAllDemographics
474
+ demographicsManagementGetDemographics
475
+ demographicsManagementPostDemographics
476
+ demographicsManagementPutDemographics
483
477
  ```
484
478
 
485
- ### Error Classes
479
+ ### enrollmentsManagement
486
480
 
487
- | Error | Status Code | Description |
488
- | ---------------------------------- | ----------- | -------------------------- |
489
- | `BadRequestResponseError` | 400 | Invalid request parameters |
490
- | `UnauthorizedRequestResponseError` | 401 | Authentication failed |
491
- | `ForbiddenResponseError` | 403 | Access denied |
492
- | `NotFoundResponseError` | 404 | Resource not found |
493
- | `UnprocessableEntityResponseError` | 422 | Validation error |
494
- | `TooManyRequestsResponseError` | 429 | Rate limit exceeded |
495
- | `InternalServerErrorResponse` | 500 | Server error |
481
+ ```text
482
+ enrollmentsManagementCreateEnrollment
483
+ enrollmentsManagementDeleteEnrollment
484
+ enrollmentsManagementGetAllEnrollments
485
+ enrollmentsManagementGetEnrollment
486
+ enrollmentsManagementUpdateEnrollment
487
+ ```
496
488
 
497
- ## Standalone Functions
489
+ ### gradingPeriodsManagement
498
490
 
499
- For optimal bundle sizes in browser and serverless environments, use standalone functions:
491
+ ```text
492
+ gradingPeriodsManagementCreateGradingPeriod
493
+ gradingPeriodsManagementDeleteGradingPeriod
494
+ gradingPeriodsManagementGetAllGradingPeriods
495
+ gradingPeriodsManagementGetGradingPeriod
496
+ gradingPeriodsManagementUpdateGradingPeriod
497
+ ```
500
498
 
501
- ```typescript
502
- import { OneRosterCore } from '@eduware/oneroster/core.js';
503
- import { usersManagementGetAllUsers } from '@eduware/oneroster/funcs/usersManagementGetAllUsers.js';
499
+ ### lineItemsManagement
504
500
 
505
- const client = new OneRosterCore({
506
- security: {
507
- clientID: process.env.ONEROSTER_CLIENT_ID!,
508
- clientSecret: process.env.ONEROSTER_CLIENT_SECRET!,
509
- },
510
- });
501
+ ```text
502
+ lineItemsManagementCreateLineItem
503
+ lineItemsManagementCreateResultForLineItem
504
+ lineItemsManagementDeleteLineItem
505
+ lineItemsManagementGetAllLineItems
506
+ lineItemsManagementGetLineItem
507
+ lineItemsManagementUpdateLineItem
508
+ ```
511
509
 
512
- const result = await usersManagementGetAllUsers(client, {});
510
+ ### organizationsManagement
513
511
 
514
- if (result.ok) {
515
- for await (const page of result.value) {
516
- console.log(page.result.users);
517
- }
518
- } else {
519
- console.error('Error:', result.error);
520
- }
512
+ ```text
513
+ organizationsManagementCreateOrg
514
+ organizationsManagementDeleteOrg
515
+ organizationsManagementGetAllOrgs
516
+ organizationsManagementGetOrg
517
+ organizationsManagementUpdateOrg
518
+ ```
519
+
520
+ ### resourcesManagement
521
+
522
+ ```text
523
+ resourcesManagementCreateResource
524
+ resourcesManagementDeleteResource
525
+ resourcesManagementExportResourceToCommonCartridge
526
+ resourcesManagementGetAllResources
527
+ resourcesManagementGetResource
528
+ resourcesManagementGetResourcesForClass
529
+ resourcesManagementGetResourcesForCourse
530
+ resourcesManagementGetResourcesForUser
531
+ resourcesManagementUpdateResource
532
+ ```
533
+
534
+ ### resultsManagement
535
+
536
+ ```text
537
+ resultsManagementCreateResult
538
+ resultsManagementDeleteResult
539
+ resultsManagementGetAllResults
540
+ resultsManagementGetResult
541
+ resultsManagementUpdateResult
542
+ ```
543
+
544
+ ### schoolsManagement
545
+
546
+ ```text
547
+ schoolsManagementCreateLineItemsForSchool
548
+ schoolsManagementCreateSchool
549
+ schoolsManagementDeleteSchool
550
+ schoolsManagementGetAllSchools
551
+ schoolsManagementGetClassesForSchool
552
+ schoolsManagementGetCoursesForSchool
553
+ schoolsManagementGetEnrollmentsForClassInSchool
554
+ schoolsManagementGetEnrollmentsForSchool
555
+ schoolsManagementGetLineItemsForSchool
556
+ schoolsManagementGetSchool
557
+ schoolsManagementGetStudentsForClassInSchool
558
+ schoolsManagementGetStudentsForSchool
559
+ schoolsManagementGetTeachersForClassInSchool
560
+ schoolsManagementGetTeachersForSchool
561
+ schoolsManagementGetTermsForSchool
562
+ schoolsManagementUpdateSchool
563
+ ```
564
+
565
+ ### scoreScalesManagement
566
+
567
+ ```text
568
+ scoreScalesManagementCreateScoreScale
569
+ scoreScalesManagementDeleteScoreScale
570
+ scoreScalesManagementGetAllScoreScales
571
+ scoreScalesManagementGetScoreScale
572
+ scoreScalesManagementGetScoreScalesForSchool
573
+ scoreScalesManagementUpdateScoreScale
574
+ ```
575
+
576
+ ### studentsManagement
577
+
578
+ ```text
579
+ studentsManagementGetAllStudents
580
+ studentsManagementGetStudent
581
+ ```
582
+
583
+ ### teachersManagement
584
+
585
+ ```text
586
+ teachersManagementGetAllTeachers
587
+ teachersManagementGetTeacher
588
+ ```
589
+
590
+ ### termsManagement
591
+
592
+ ```text
593
+ termsManagementCreateGradingPeriodForTerm
594
+ termsManagementGetAllTerms
595
+ termsManagementGetGradingPeriodsForTerm
596
+ termsManagementGetTerm
597
+ ```
598
+
599
+ ### usersManagement
600
+
601
+ ```text
602
+ usersManagementCreateUser
603
+ usersManagementDeleteUser
604
+ usersManagementGetAllUsers
605
+ usersManagementGetUser
606
+ usersManagementGetUserWithDemographics
607
+ usersManagementUpdateUser
521
608
  ```
522
609
 
523
- See [FUNCTIONS.md](./FUNCTIONS.md) for the complete list of standalone functions.
610
+ ## LMS Provider Support
611
+
612
+ Support varies by LMS provider and contract. The profile you choose reflects LMS capabilities, not library limitations.
613
+
614
+ ### LMS Profiles
615
+
616
+ | Provider | Profile | Notes |
617
+ | --------- | ----------- | -------------------------- |
618
+ | OneRoster | full | All endpoints available |
619
+ | ClassLink | classlink | Read-only rostering access |
620
+ | (future) | coming soon | Add new LMS profiles here |
621
+
622
+ ### CRUD Operations by Module
623
+
624
+ | Module | Create | Read | Update | Delete |
625
+ | ------------------------------------ | :----: | :--: | :----: | :----: |
626
+ | `usersManagement` | ✅ | ✅ | ✅ | ✅ |
627
+ | `studentsManagement` | — | ✅ | — | — |
628
+ | `teachersManagement` | — | ✅ | — | — |
629
+ | `classesManagement` | ✅ | ✅ | ✅ | ✅ |
630
+ | `coursesManagement` | ✅ | ✅ | ✅ | ✅ |
631
+ | `enrollmentsManagement` | ✅ | ✅ | ✅ | ✅ |
632
+ | `schoolsManagement` | ✅ | ✅ | ✅ | ✅ |
633
+ | `organizationsManagement` | ✅ | ✅ | ✅ | ✅ |
634
+ | `academicSessionsManagement` | ✅ | ✅ | ✅ | ✅ |
635
+ | `termsManagement` | — | ✅ | — | — |
636
+ | `gradingPeriodsManagement` | ✅ | ✅ | ✅ | ✅ |
637
+ | `demographicsManagement` | ✅ | ✅ | ✅ | ✅ |
638
+ | `lineItemsManagement` | ✅ | ✅ | ✅ | ✅ |
639
+ | `resultsManagement` | ✅ | ✅ | ✅ | ✅ |
640
+ | `categoriesManagement` | ✅ | ✅ | ✅ | ✅ |
641
+ | `scoreScalesManagement` | ✅ | ✅ | ✅ | ✅ |
642
+ | `resourcesManagement` | ✅ | ✅ | ✅ | ✅ |
643
+ | `courseComponentsManagement` | ✅ | ✅ | ✅ | ✅ |
644
+ | `courseComponentResourcesManagement` | ✅ | ✅ | ✅ | ✅ |
645
+ | `assessmentLineItemsManagement` | ✅ | ✅ | ✅ | ✅ |
646
+ | `assessmentResultsManagement` | ✅ | ✅ | ✅ | ✅ |
647
+
648
+ _Note: — indicates the module uses parent module operations (students/teachers map to usersManagement for create/update/delete)._
649
+
650
+ ### Example Provider Matrix (LMS-Specific)
651
+
652
+ | Module | OneRoster (Full) | ClassLink |
653
+ | ------------------------------------ | :--------------: | :-------: |
654
+ | `usersManagement` | ✅ CRUD | ✅ Read |
655
+ | `studentsManagement` | ✅ Read | ✅ Read |
656
+ | `teachersManagement` | ✅ Read | ✅ Read |
657
+ | `classesManagement` | ✅ CRUD | ✅ Read |
658
+ | `coursesManagement` | ✅ CRUD | ✅ Read |
659
+ | `enrollmentsManagement` | ✅ CRUD | ✅ Read |
660
+ | `schoolsManagement` | ✅ CRUD | ✅ Read |
661
+ | `organizationsManagement` | ✅ CRUD | ✅ Read |
662
+ | `academicSessionsManagement` | ✅ CRUD | ✅ Read |
663
+ | `termsManagement` | ✅ Read | ✅ Read |
664
+ | `gradingPeriodsManagement` | ✅ CRUD | ✅ Read |
665
+ | `demographicsManagement` | ✅ CRUD | ❌ |
666
+ | `lineItemsManagement` | ✅ CRUD | ❌ |
667
+ | `resultsManagement` | ✅ CRUD | ❌ |
668
+ | `categoriesManagement` | ✅ CRUD | ❌ |
669
+ | `scoreScalesManagement` | ✅ CRUD | ❌ |
670
+ | `resourcesManagement` | ✅ CRUD | ❌ |
671
+ | `courseComponentsManagement` | ✅ CRUD | ❌ |
672
+ | `courseComponentResourcesManagement` | ✅ CRUD | ❌ |
673
+ | `assessmentLineItemsManagement` | ✅ CRUD | ❌ |
674
+ | `assessmentResultsManagement` | ✅ CRUD | ❌ |
675
+
676
+ > This matrix reflects typical provider behavior. Actual availability may vary by contract or configuration.
677
+
678
+ ## Advanced Import Paths
679
+
680
+ Use these only when you need them.
681
+
682
+ ### Runtime entrypoints
683
+
684
+ ```text
685
+ @eduware/oneroster # Full client + common exports (recommended)
686
+ @eduware/oneroster/clients # LMS profiles (ClassLink, custom profiles)
687
+ @eduware/oneroster/core.js # Lightweight core client for funcs
688
+ @eduware/oneroster/funcs/* # Standalone functions
689
+ ```
690
+
691
+ ### Type-first entrypoints (prefer `import type` when you only need types)
692
+
693
+ ```text
694
+ @eduware/oneroster/models # Data models (component schemas)
695
+ @eduware/oneroster/enums # Shared enums (runtime + types)
696
+ @eduware/oneroster/types # Operation request/response types (runtime alias)
697
+ ```
524
698
 
525
699
  ## MCP Server
526
700
 
527
- This SDK includes an MCP (Model Context Protocol) server for AI applications. The MCP server exposes OneRoster API operations as tools that can be used by AI assistants.
701
+ This SDK includes an MCP (Model Context Protocol) server for AI applications.
528
702
 
529
- ### Basic Configuration (OAuth 2.0)
703
+ ### OAuth 2.0 Configuration
530
704
 
531
705
  ```json
532
706
  {
@@ -556,8 +730,6 @@ This SDK includes an MCP (Model Context Protocol) server for AI applications. Th
556
730
 
557
731
  ### ClassLink Configuration (Bearer Token)
558
732
 
559
- For ClassLink's proxy mode with pre-authenticated bearer tokens:
560
-
561
733
  ```json
562
734
  {
563
735
  "mcpServers": {
@@ -584,9 +756,7 @@ For ClassLink's proxy mode with pre-authenticated bearer tokens:
584
756
  }
585
757
  ```
586
758
 
587
- ### OAuth 1.0a Configuration (OneRoster v1.1)
588
-
589
- For OneRoster v1.1 servers using OAuth 1.0a:
759
+ ### OAuth 1.0a Configuration (v1.1)
590
760
 
591
761
  ```json
592
762
  {
@@ -616,7 +786,7 @@ For OneRoster v1.1 servers using OAuth 1.0a:
616
786
  }
617
787
  ```
618
788
 
619
- ### Command Line Arguments
789
+ ### MCP Arguments
620
790
 
621
791
  | Argument | Description | Default | Required |
622
792
  | --------------------- | ------------------------------------------------------------- | --------- | ----------------- |
@@ -634,31 +804,9 @@ For OneRoster v1.1 servers using OAuth 1.0a:
634
804
  | `--log-level` | Log level: `debug`, `info`, `warn`, `error` | `info` | No |
635
805
  | `--env` | Environment variables (format: `KEY=value`, repeatable) | — | No |
636
806
 
637
- ### Client Profiles
638
-
639
- The `--client-profile` flag restricts which tools are available:
640
-
641
- - **`full`** (default): All OneRoster tools including create, update, and delete operations
642
- - **`classlink`**: Read-only tools matching ClassLink's supported endpoints
643
-
644
- Using the appropriate profile prevents AI assistants from attempting unsupported operations.
645
-
646
- ## Runtime Support
647
-
648
- - **Browsers:** Chrome, Safari, Edge, Firefox (evergreen)
649
- - **Node.js:** v18+ (LTS)
650
- - **Bun:** v1+
651
- - **Deno:** v1.39+
652
-
653
- See [RUNTIMES.md](./RUNTIMES.md) for detailed runtime information.
654
-
655
807
  ## API Reference
656
808
 
657
- For the complete list of available methods, see [FUNCTIONS.md](./FUNCTIONS.md).
658
-
659
- ## Contributing
660
-
661
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for contribution guidelines.
809
+ See [FUNCTIONS.md](./FUNCTIONS.md) for the full method list.
662
810
 
663
811
  ## License
664
812