@openstax/ts-utils 1.40.2 → 1.41.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/dist/cjs/services/accountsGateway/index.d.ts +3 -0
- package/dist/cjs/services/accountsGateway/index.js +1 -0
- package/dist/cjs/services/documentStore/dynamoEncoding.js +2 -2
- package/dist/cjs/services/documentStore/unversioned/file-system.d.ts +0 -1
- package/dist/cjs/services/documentStore/unversioned/file-system.js +0 -19
- package/dist/cjs/services/documentStore/versioned/file-system.d.ts +0 -1
- package/dist/cjs/services/documentStore/versioned/file-system.js +1 -12
- package/dist/cjs/services/lrsGateway/batching.d.ts +46 -0
- package/dist/cjs/services/lrsGateway/batching.js +106 -0
- package/dist/cjs/services/lrsGateway/file-system.js +52 -2
- package/dist/cjs/services/lrsGateway/index.d.ts +13 -0
- package/dist/cjs/services/lrsGateway/index.js +151 -55
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/esm/services/accountsGateway/index.d.ts +3 -0
- package/dist/esm/services/accountsGateway/index.js +1 -0
- package/dist/esm/services/documentStore/dynamoEncoding.js +2 -2
- package/dist/esm/services/documentStore/unversioned/file-system.d.ts +0 -1
- package/dist/esm/services/documentStore/unversioned/file-system.js +0 -19
- package/dist/esm/services/documentStore/versioned/file-system.d.ts +0 -1
- package/dist/esm/services/documentStore/versioned/file-system.js +1 -12
- package/dist/esm/services/lrsGateway/batching.d.ts +46 -0
- package/dist/esm/services/lrsGateway/batching.js +102 -0
- package/dist/esm/services/lrsGateway/file-system.js +52 -2
- package/dist/esm/services/lrsGateway/index.d.ts +13 -0
- package/dist/esm/services/lrsGateway/index.js +151 -22
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/cjs/services/documentStore/fileSystemAssert.d.ts +0 -1
- package/dist/cjs/services/documentStore/fileSystemAssert.js +0 -14
- package/dist/esm/services/documentStore/fileSystemAssert.d.ts +0 -1
- package/dist/esm/services/documentStore/fileSystemAssert.js +0 -10
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.lrsGateway = void 0;
|
|
37
|
-
const queryString = __importStar(require("query-string"));
|
|
38
4
|
const __1 = require("../..");
|
|
39
5
|
const assertions_1 = require("../../assertions");
|
|
40
6
|
const config_1 = require("../../config");
|
|
@@ -44,6 +10,7 @@ const guards_1 = require("../../guards");
|
|
|
44
10
|
const helpers_1 = require("../../misc/helpers");
|
|
45
11
|
const routing_1 = require("../../routing");
|
|
46
12
|
const addStatementDefaultFields_1 = require("./addStatementDefaultFields");
|
|
13
|
+
const batching_1 = require("./batching");
|
|
47
14
|
const lrsGateway = (initializer) => (configProvider) => {
|
|
48
15
|
const config = configProvider[(0, guards_1.ifDefined)(initializer.configSpace, 'lrs')];
|
|
49
16
|
const lrsHost = (0, __1.once)(() => (0, config_1.resolveConfigValue)(config.lrsHost));
|
|
@@ -55,20 +22,51 @@ const lrsGateway = (initializer) => (configProvider) => {
|
|
|
55
22
|
wait: 1000,
|
|
56
23
|
status: [502]
|
|
57
24
|
});
|
|
25
|
+
// Initialize request batcher if batching is enabled
|
|
26
|
+
const enableBatching = initializer.enableBatching !== false;
|
|
27
|
+
const batcher = new batching_1.RequestBatcher(fetcher, {
|
|
28
|
+
batchEndpoint: '/api/batch',
|
|
29
|
+
getAuthHeader: lrsAuthorization,
|
|
30
|
+
getHost: lrsHost,
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Makes a fetch request, optionally through the request batcher.
|
|
34
|
+
* Automatically batches concurrent requests when batching is enabled.
|
|
35
|
+
*/
|
|
36
|
+
const makeFetch = async (options) => {
|
|
37
|
+
return enableBatching ? batcher.queueRequest(options) : batcher.singleRequest(options);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Formats an agent parameter into a full XapiAgent object.
|
|
41
|
+
* Accepts either a UUID string or a full XapiAgent object.
|
|
42
|
+
*/
|
|
43
|
+
const formatAgent = (agent) => {
|
|
44
|
+
if (typeof agent === 'string') {
|
|
45
|
+
return {
|
|
46
|
+
objectType: 'Agent',
|
|
47
|
+
account: {
|
|
48
|
+
homePage: 'https://openstax.org',
|
|
49
|
+
name: agent,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return agent;
|
|
54
|
+
};
|
|
58
55
|
// Note: This method actually uses POST
|
|
59
56
|
const putXapiStatements = async (statements, user) => {
|
|
60
57
|
const userObj = user
|
|
61
58
|
? { uuid: user }
|
|
62
59
|
: (0, assertions_1.assertDefined)(await authProvider.getUser(), new errors_1.UnauthorizedError);
|
|
63
60
|
const statementsWithDefaults = statements.map(statement => (0, addStatementDefaultFields_1.addStatementDefaultFields)(statement, userObj));
|
|
64
|
-
const response = await
|
|
65
|
-
|
|
61
|
+
const response = await makeFetch({
|
|
62
|
+
path: '/data/xAPI/statements',
|
|
63
|
+
method: routing_1.METHOD.POST,
|
|
66
64
|
headers: {
|
|
67
65
|
Authorization: await lrsAuthorization(),
|
|
68
66
|
'Content-Type': 'application/json',
|
|
69
67
|
'X-Experience-API-Version': '1.0.0',
|
|
70
68
|
},
|
|
71
|
-
|
|
69
|
+
body: JSON.stringify(statementsWithDefaults),
|
|
72
70
|
});
|
|
73
71
|
if (![200, 201].includes(response.status)) {
|
|
74
72
|
throw new Error(`Unexpected LRS POST statements response code ${response.status} with body:
|
|
@@ -88,29 +86,51 @@ ${await response.text()}`);
|
|
|
88
86
|
}
|
|
89
87
|
return response.json();
|
|
90
88
|
};
|
|
91
|
-
const getMoreXapiStatements = async (more) =>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
89
|
+
const getMoreXapiStatements = async (more) => {
|
|
90
|
+
// 'more' is a full path with query string, so we don't use makeFetch batching here
|
|
91
|
+
const host = await lrsHost();
|
|
92
|
+
return fetcher(host.replace(/\/+$/, '') + more, {
|
|
93
|
+
headers: {
|
|
94
|
+
Authorization: await lrsAuthorization(),
|
|
95
|
+
'X-Experience-API-Version': '1.0.0',
|
|
96
|
+
},
|
|
97
|
+
}).then(formatGetXapiStatementsResponse);
|
|
98
|
+
};
|
|
99
|
+
const fetchXapiStatements = async ({ user, anyUser, ...options }) => {
|
|
100
|
+
const queryParams = {};
|
|
101
|
+
// Add filter params
|
|
102
|
+
if (options.verb)
|
|
103
|
+
queryParams.verb = options.verb;
|
|
104
|
+
if (options.activity)
|
|
105
|
+
queryParams.activity = options.activity;
|
|
106
|
+
if (options.registration)
|
|
107
|
+
queryParams.registration = options.registration;
|
|
108
|
+
if (options.related_activities !== undefined)
|
|
109
|
+
queryParams.related_activities = String(options.related_activities);
|
|
110
|
+
if (options.since)
|
|
111
|
+
queryParams.since = options.since;
|
|
112
|
+
if (options.until)
|
|
113
|
+
queryParams.until = options.until;
|
|
114
|
+
// Add agent unless anyUser is true
|
|
115
|
+
if (anyUser !== true) {
|
|
116
|
+
queryParams.agent = JSON.stringify({
|
|
101
117
|
account: {
|
|
102
118
|
homePage: 'https://openstax.org',
|
|
103
119
|
name: user || (0, assertions_1.assertDefined)(await authProvider.getUser(), new errors_1.UnauthorizedError()).uuid,
|
|
104
120
|
},
|
|
105
121
|
objectType: 'Agent',
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return makeFetch({
|
|
125
|
+
path: '/data/xAPI/statements',
|
|
126
|
+
method: routing_1.METHOD.GET,
|
|
127
|
+
queryParams,
|
|
128
|
+
headers: {
|
|
129
|
+
Authorization: await lrsAuthorization(),
|
|
130
|
+
'X-Experience-API-Version': '1.0.0',
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
};
|
|
114
134
|
const getXapiStatements = async (params) => {
|
|
115
135
|
const { ensureSync, ...fetchParams } = params;
|
|
116
136
|
if (ensureSync) {
|
|
@@ -139,11 +159,87 @@ ${await response.text()}`);
|
|
|
139
159
|
};
|
|
140
160
|
return loadRemaining(await getXapiStatements(params));
|
|
141
161
|
};
|
|
162
|
+
/**
|
|
163
|
+
* Get a single state document from the xAPI State API.
|
|
164
|
+
*
|
|
165
|
+
* @param activityId - The activity ID
|
|
166
|
+
* @param agent - The agent (UUID string or full XapiAgent object)
|
|
167
|
+
* @param stateId - The state document identifier
|
|
168
|
+
* @param registration - Optional registration UUID
|
|
169
|
+
* @returns The state document as a JSON object, or null if not found
|
|
170
|
+
*/
|
|
171
|
+
const getState = async (activityId, agent, stateId, registration) => {
|
|
172
|
+
const agentObj = formatAgent(agent);
|
|
173
|
+
const queryParams = {
|
|
174
|
+
activityId,
|
|
175
|
+
agent: JSON.stringify(agentObj),
|
|
176
|
+
stateId,
|
|
177
|
+
};
|
|
178
|
+
if (registration) {
|
|
179
|
+
queryParams.registration = registration;
|
|
180
|
+
}
|
|
181
|
+
const response = await makeFetch({
|
|
182
|
+
path: '/data/xAPI/activities/state',
|
|
183
|
+
method: routing_1.METHOD.GET,
|
|
184
|
+
queryParams,
|
|
185
|
+
headers: {
|
|
186
|
+
Authorization: await lrsAuthorization(),
|
|
187
|
+
'X-Experience-API-Version': '1.0.0',
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
if (response.status === 404) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if (response.status !== 200) {
|
|
194
|
+
throw new Error(`Unexpected LRS GET state response code ${response.status} with body:
|
|
195
|
+
|
|
196
|
+
${await response.text()}`);
|
|
197
|
+
}
|
|
198
|
+
return response.json();
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Create or update a state document in the xAPI State API.
|
|
202
|
+
*
|
|
203
|
+
* @param activityId - The activity ID
|
|
204
|
+
* @param agent - The agent (UUID string or full XapiAgent object)
|
|
205
|
+
* @param stateId - The state document identifier
|
|
206
|
+
* @param body - The state document content (JSON object)
|
|
207
|
+
* @param registration - Optional registration UUID
|
|
208
|
+
*/
|
|
209
|
+
const setState = async (activityId, agent, stateId, body, registration) => {
|
|
210
|
+
const agentObj = formatAgent(agent);
|
|
211
|
+
const queryParams = {
|
|
212
|
+
activityId,
|
|
213
|
+
agent: JSON.stringify(agentObj),
|
|
214
|
+
stateId,
|
|
215
|
+
};
|
|
216
|
+
if (registration) {
|
|
217
|
+
queryParams.registration = registration;
|
|
218
|
+
}
|
|
219
|
+
const response = await makeFetch({
|
|
220
|
+
path: '/data/xAPI/activities/state',
|
|
221
|
+
method: routing_1.METHOD.PUT,
|
|
222
|
+
queryParams,
|
|
223
|
+
headers: {
|
|
224
|
+
Authorization: await lrsAuthorization(),
|
|
225
|
+
'Content-Type': 'application/json',
|
|
226
|
+
'X-Experience-API-Version': '1.0.0',
|
|
227
|
+
},
|
|
228
|
+
body: JSON.stringify(body),
|
|
229
|
+
});
|
|
230
|
+
if (response.status !== 204) {
|
|
231
|
+
throw new Error(`Unexpected LRS PUT state response code ${response.status} with body:
|
|
232
|
+
|
|
233
|
+
${await response.text()}`);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
142
236
|
return {
|
|
143
237
|
putXapiStatements,
|
|
144
238
|
getXapiStatements,
|
|
145
239
|
getMoreXapiStatements,
|
|
146
240
|
getAllXapiStatements,
|
|
241
|
+
getState,
|
|
242
|
+
setState,
|
|
147
243
|
};
|
|
148
244
|
};
|
|
149
245
|
};
|