@package-uploader/core 1.0.0 → 1.0.2
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.
- package/README.md +303 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
# @package-uploader/core
|
|
2
|
+
|
|
3
|
+
Upload Rise course packages to LMS platforms with optional auto-patching via @patch-adams/core.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Course upload**: Upload SCORM, cmi5, xAPI packages to LMS
|
|
8
|
+
- **Version management**: Upload new versions to existing documents
|
|
9
|
+
- **Auto-patching**: Optionally patch courses before upload (requires @patch-adams/core)
|
|
10
|
+
- **Folder/document browsing**: List folders, documents, and shared links
|
|
11
|
+
- **Async upload support**: Handle large files with async processing
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @package-uploader/core
|
|
17
|
+
|
|
18
|
+
# Optional: Enable auto-patching
|
|
19
|
+
npm install @patch-adams/core
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
### CLI Usage
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Initialize config file
|
|
28
|
+
npx package-upload init
|
|
29
|
+
|
|
30
|
+
# Upload a course to a folder
|
|
31
|
+
npx package-upload upload course.zip --folder 12345
|
|
32
|
+
|
|
33
|
+
# Upload a new version to existing document
|
|
34
|
+
npx package-upload update course.zip --document-id 67890
|
|
35
|
+
|
|
36
|
+
# Check async upload status
|
|
37
|
+
npx package-upload status <jobId>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Programmatic Usage
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { PackageUploaderClient } from '@package-uploader/core';
|
|
44
|
+
|
|
45
|
+
const client = new PackageUploaderClient({
|
|
46
|
+
baseUrl: 'https://your-lms.example.com',
|
|
47
|
+
apiKey: 'your-api-key',
|
|
48
|
+
|
|
49
|
+
// Optional: Enable auto-patching
|
|
50
|
+
patchAdams: {
|
|
51
|
+
enabled: true,
|
|
52
|
+
remoteDomain: 'https://cdn.example.com/rise-overrides',
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Upload a new course
|
|
57
|
+
const result = await client.uploadCourse(fileBuffer, 'course.zip', {
|
|
58
|
+
folderId: '12345',
|
|
59
|
+
title: 'My Course',
|
|
60
|
+
description: 'Course description',
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
console.log('Document ID:', result.documentId);
|
|
64
|
+
|
|
65
|
+
// Upload a new version
|
|
66
|
+
const versionResult = await client.uploadVersion(fileBuffer, 'course.zip', {
|
|
67
|
+
documentId: '67890',
|
|
68
|
+
note: 'Updated content',
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
### Config File
|
|
75
|
+
|
|
76
|
+
Create `uploader.config.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"baseUrl": "https://your-lms.example.com",
|
|
81
|
+
"apiKey": "your-api-key",
|
|
82
|
+
"timeout": 30000,
|
|
83
|
+
"patchAdams": {
|
|
84
|
+
"enabled": true,
|
|
85
|
+
"remoteDomain": "https://cdn.example.com/rise-overrides"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Environment Variables
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
UPLOADER_BASE_URL=https://your-lms.example.com
|
|
94
|
+
UPLOADER_API_KEY=your-api-key
|
|
95
|
+
UPLOADER_TIMEOUT=30000
|
|
96
|
+
PATCH_ADAMS_DOMAIN=https://cdn.example.com/rise-overrides
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## API Reference
|
|
100
|
+
|
|
101
|
+
### `PackageUploaderClient`
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
class PackageUploaderClient {
|
|
105
|
+
constructor(config: UploaderConfig)
|
|
106
|
+
|
|
107
|
+
// Upload Methods
|
|
108
|
+
uploadCourse(buffer: Buffer, filename: string, options: UploadOptions): Promise<CourseUploadResult>
|
|
109
|
+
uploadVersion(buffer: Buffer, filename: string, options: VersionUploadOptions): Promise<CourseUploadResult>
|
|
110
|
+
getUploadStatus(jobId: string): Promise<JobStatus>
|
|
111
|
+
waitForUpload(jobId: string, options?: WaitOptions): Promise<CourseUploadResult>
|
|
112
|
+
|
|
113
|
+
// Folder Methods
|
|
114
|
+
listFolders(options?: FolderListOptions): Promise<Folder[]>
|
|
115
|
+
getFolder(folderId: string | number): Promise<Folder>
|
|
116
|
+
listSubfolders(folderId: string | number, options?: FolderListOptions): Promise<Folder[]>
|
|
117
|
+
|
|
118
|
+
// Document Methods
|
|
119
|
+
listDocuments(options?: DocumentListOptions): Promise<Document[]>
|
|
120
|
+
listFolderDocuments(folderId: string | number, options?: DocumentListOptions): Promise<Document[]>
|
|
121
|
+
getDocument(documentId: string | number): Promise<Document>
|
|
122
|
+
getDocumentVersions(documentId: string | number): Promise<DocumentVersion[]>
|
|
123
|
+
|
|
124
|
+
// Shared Link Methods
|
|
125
|
+
listSharedLinks(documentId: string | number): Promise<SharedLink[]>
|
|
126
|
+
createSharedLink(documentId: string | number, options: CreateSharedLinkOptions): Promise<SharedLink>
|
|
127
|
+
getOrCreateLaunchLink(documentId: string | number): Promise<string>
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Types
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
interface UploaderConfig {
|
|
135
|
+
baseUrl: string;
|
|
136
|
+
apiKey: string;
|
|
137
|
+
timeout?: number; // default: 30000
|
|
138
|
+
patchAdams?: {
|
|
139
|
+
enabled: boolean;
|
|
140
|
+
remoteDomain: string;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface UploadOptions {
|
|
145
|
+
folderId: string;
|
|
146
|
+
externalId?: string; // For upsert behavior
|
|
147
|
+
title?: string;
|
|
148
|
+
description?: string;
|
|
149
|
+
author?: string;
|
|
150
|
+
language?: string;
|
|
151
|
+
note?: string;
|
|
152
|
+
async?: boolean; // Use async upload
|
|
153
|
+
skipPatch?: boolean; // Skip auto-patching
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
interface VersionUploadOptions {
|
|
157
|
+
documentId: string;
|
|
158
|
+
note?: string;
|
|
159
|
+
description?: string;
|
|
160
|
+
author?: string;
|
|
161
|
+
async?: boolean;
|
|
162
|
+
skipPatch?: boolean;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
interface CourseUploadResult {
|
|
166
|
+
success: boolean;
|
|
167
|
+
documentId: number | null;
|
|
168
|
+
versionId: number | null;
|
|
169
|
+
documentName: string;
|
|
170
|
+
folderId: number;
|
|
171
|
+
updated: boolean;
|
|
172
|
+
warnings: string[];
|
|
173
|
+
errors: string[];
|
|
174
|
+
jobId?: string; // For async uploads
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## CLI Commands
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
# Upload a course
|
|
182
|
+
package-upload upload <file> [options]
|
|
183
|
+
|
|
184
|
+
Options:
|
|
185
|
+
-f, --folder <id> Target folder ID (required)
|
|
186
|
+
-e, --external-id <id> External ID for upsert
|
|
187
|
+
-t, --title <title> Document title
|
|
188
|
+
-d, --description <desc> Document description
|
|
189
|
+
-a, --author <author> Document author
|
|
190
|
+
-n, --note <note> Version note
|
|
191
|
+
--async Upload asynchronously
|
|
192
|
+
--skip-patch Skip auto-patching
|
|
193
|
+
--wait Wait for async upload
|
|
194
|
+
|
|
195
|
+
# Upload new version
|
|
196
|
+
package-upload update <file> [options]
|
|
197
|
+
|
|
198
|
+
Options:
|
|
199
|
+
-i, --document-id <id> Target document ID (required)
|
|
200
|
+
-n, --note <note> Version note
|
|
201
|
+
--async Upload asynchronously
|
|
202
|
+
--skip-patch Skip auto-patching
|
|
203
|
+
--wait Wait for async upload
|
|
204
|
+
|
|
205
|
+
# Check upload status
|
|
206
|
+
package-upload status <jobId>
|
|
207
|
+
|
|
208
|
+
# Initialize config
|
|
209
|
+
package-upload init
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Auto-Patching with @patch-adams/core
|
|
213
|
+
|
|
214
|
+
When `patchAdams.enabled` is true and `@patch-adams/core` is installed, courses are automatically patched before upload:
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const client = new PackageUploaderClient({
|
|
218
|
+
baseUrl: 'https://your-lms.example.com',
|
|
219
|
+
apiKey: 'your-api-key',
|
|
220
|
+
patchAdams: {
|
|
221
|
+
enabled: true,
|
|
222
|
+
remoteDomain: 'https://cdn.example.com/rise-overrides',
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// This course will be patched before upload
|
|
227
|
+
await client.uploadCourse(buffer, 'course.zip', {
|
|
228
|
+
folderId: '12345',
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
// Skip patching for this upload
|
|
232
|
+
await client.uploadCourse(buffer, 'course.zip', {
|
|
233
|
+
folderId: '12345',
|
|
234
|
+
skipPatch: true,
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Examples
|
|
239
|
+
|
|
240
|
+
### List All Folders
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
const folders = await client.listFolders();
|
|
244
|
+
folders.forEach(f => console.log(f.id, f.name));
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Browse Documents in Folder
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
const docs = await client.listFolderDocuments('12345', {
|
|
251
|
+
filterText: 'training',
|
|
252
|
+
includeSharedLinks: true,
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Get Launch URL for Course
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
const launchUrl = await client.getOrCreateLaunchLink('67890');
|
|
260
|
+
console.log('Launch at:', launchUrl);
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Async Upload with Polling
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
const result = await client.uploadCourse(buffer, 'large-course.zip', {
|
|
267
|
+
folderId: '12345',
|
|
268
|
+
async: true,
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
if (result.jobId) {
|
|
272
|
+
const finalResult = await client.waitForUpload(result.jobId, {
|
|
273
|
+
pollInterval: 2000,
|
|
274
|
+
maxWait: 300000,
|
|
275
|
+
});
|
|
276
|
+
console.log('Upload complete:', finalResult.documentId);
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Server Integration
|
|
281
|
+
|
|
282
|
+
For Express/Node.js server integration, see `@package-uploader/ui` which includes a ready-to-deploy server.
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
import express from 'express';
|
|
286
|
+
import { PackageUploaderClient } from '@package-uploader/core';
|
|
287
|
+
|
|
288
|
+
const app = express();
|
|
289
|
+
const client = new PackageUploaderClient({ /* config */ });
|
|
290
|
+
|
|
291
|
+
app.post('/api/upload', async (req, res) => {
|
|
292
|
+
const result = await client.uploadCourse(
|
|
293
|
+
req.file.buffer,
|
|
294
|
+
req.file.originalname,
|
|
295
|
+
{ folderId: req.body.folderId }
|
|
296
|
+
);
|
|
297
|
+
res.json(result);
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## License
|
|
302
|
+
|
|
303
|
+
MIT
|