@timeback/masterytrack 0.1.1-beta.20260219190739

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 (41) hide show
  1. package/README.md +225 -0
  2. package/dist/client.d.ts +32 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/constants.d.ts +19 -0
  5. package/dist/constants.d.ts.map +1 -0
  6. package/dist/errors.d.ts +1 -0
  7. package/dist/errors.d.ts.map +1 -0
  8. package/dist/errors.js +1504 -0
  9. package/dist/factory.d.ts +23 -0
  10. package/dist/factory.d.ts.map +1 -0
  11. package/dist/index.d.ts +449 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +16943 -0
  14. package/dist/lib/index.d.ts +4 -0
  15. package/dist/lib/index.d.ts.map +1 -0
  16. package/dist/lib/resolve.d.ts +25 -0
  17. package/dist/lib/resolve.d.ts.map +1 -0
  18. package/dist/lib/token-provider.d.ts +34 -0
  19. package/dist/lib/token-provider.d.ts.map +1 -0
  20. package/dist/lib/transport.d.ts +28 -0
  21. package/dist/lib/transport.d.ts.map +1 -0
  22. package/dist/public-types.d.ts +210 -0
  23. package/dist/public-types.d.ts.map +1 -0
  24. package/dist/public-types.js +0 -0
  25. package/dist/resources/assignments.d.ts +30 -0
  26. package/dist/resources/assignments.d.ts.map +1 -0
  27. package/dist/resources/authorizer.d.ts +22 -0
  28. package/dist/resources/authorizer.d.ts.map +1 -0
  29. package/dist/resources/index.d.ts +4 -0
  30. package/dist/resources/index.d.ts.map +1 -0
  31. package/dist/resources/inventory.d.ts +23 -0
  32. package/dist/resources/inventory.d.ts.map +1 -0
  33. package/dist/types/client.d.ts +61 -0
  34. package/dist/types/client.d.ts.map +1 -0
  35. package/dist/types/index.d.ts +2 -0
  36. package/dist/types/index.d.ts.map +1 -0
  37. package/dist/types.d.ts +2 -0
  38. package/dist/types.d.ts.map +1 -0
  39. package/dist/utils.d.ts +11 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/package.json +42 -0
package/dist/errors.js ADDED
@@ -0,0 +1,1504 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, {
5
+ get: all[name],
6
+ enumerable: true,
7
+ configurable: true,
8
+ set: (newValue) => all[name] = () => newValue
9
+ });
10
+ };
11
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
12
+
13
+ // node:util
14
+ var exports_util = {};
15
+ __export(exports_util, {
16
+ types: () => types,
17
+ promisify: () => promisify,
18
+ log: () => log,
19
+ isUndefined: () => isUndefined,
20
+ isSymbol: () => isSymbol,
21
+ isString: () => isString,
22
+ isRegExp: () => isRegExp,
23
+ isPrimitive: () => isPrimitive,
24
+ isObject: () => isObject,
25
+ isNumber: () => isNumber,
26
+ isNullOrUndefined: () => isNullOrUndefined,
27
+ isNull: () => isNull,
28
+ isFunction: () => isFunction,
29
+ isError: () => isError,
30
+ isDate: () => isDate,
31
+ isBuffer: () => isBuffer,
32
+ isBoolean: () => isBoolean,
33
+ isArray: () => isArray,
34
+ inspect: () => inspect,
35
+ inherits: () => inherits,
36
+ format: () => format,
37
+ deprecate: () => deprecate,
38
+ default: () => util_default,
39
+ debuglog: () => debuglog,
40
+ callbackifyOnRejected: () => callbackifyOnRejected,
41
+ callbackify: () => callbackify,
42
+ _extend: () => _extend,
43
+ TextEncoder: () => TextEncoder,
44
+ TextDecoder: () => TextDecoder
45
+ });
46
+ function format(f, ...args) {
47
+ if (!isString(f)) {
48
+ var objects = [f];
49
+ for (var i = 0;i < args.length; i++)
50
+ objects.push(inspect(args[i]));
51
+ return objects.join(" ");
52
+ }
53
+ var i = 0, len = args.length, str = String(f).replace(formatRegExp, function(x2) {
54
+ if (x2 === "%%")
55
+ return "%";
56
+ if (i >= len)
57
+ return x2;
58
+ switch (x2) {
59
+ case "%s":
60
+ return String(args[i++]);
61
+ case "%d":
62
+ return Number(args[i++]);
63
+ case "%j":
64
+ try {
65
+ return JSON.stringify(args[i++]);
66
+ } catch (_) {
67
+ return "[Circular]";
68
+ }
69
+ default:
70
+ return x2;
71
+ }
72
+ });
73
+ for (var x = args[i];i < len; x = args[++i])
74
+ if (isNull(x) || !isObject(x))
75
+ str += " " + x;
76
+ else
77
+ str += " " + inspect(x);
78
+ return str;
79
+ }
80
+ function deprecate(fn, msg) {
81
+ if (typeof process > "u" || process?.noDeprecation === true)
82
+ return fn;
83
+ var warned = false;
84
+ function deprecated(...args) {
85
+ if (!warned) {
86
+ if (process.throwDeprecation)
87
+ throw Error(msg);
88
+ else if (process.traceDeprecation)
89
+ console.trace(msg);
90
+ else
91
+ console.error(msg);
92
+ warned = true;
93
+ }
94
+ return fn.apply(this, ...args);
95
+ }
96
+ return deprecated;
97
+ }
98
+ function stylizeWithColor(str, styleType) {
99
+ var style = inspect.styles[styleType];
100
+ if (style)
101
+ return "\x1B[" + inspect.colors[style][0] + "m" + str + "\x1B[" + inspect.colors[style][1] + "m";
102
+ else
103
+ return str;
104
+ }
105
+ function stylizeNoColor(str, styleType) {
106
+ return str;
107
+ }
108
+ function arrayToHash(array) {
109
+ var hash = {};
110
+ return array.forEach(function(val, idx) {
111
+ hash[val] = true;
112
+ }), hash;
113
+ }
114
+ function formatValue(ctx, value, recurseTimes) {
115
+ if (ctx.customInspect && value && isFunction(value.inspect) && value.inspect !== inspect && !(value.constructor && value.constructor.prototype === value)) {
116
+ var ret = value.inspect(recurseTimes, ctx);
117
+ if (!isString(ret))
118
+ ret = formatValue(ctx, ret, recurseTimes);
119
+ return ret;
120
+ }
121
+ var primitive = formatPrimitive(ctx, value);
122
+ if (primitive)
123
+ return primitive;
124
+ var keys = Object.keys(value), visibleKeys = arrayToHash(keys);
125
+ if (ctx.showHidden)
126
+ keys = Object.getOwnPropertyNames(value);
127
+ if (isError(value) && (keys.indexOf("message") >= 0 || keys.indexOf("description") >= 0))
128
+ return formatError(value);
129
+ if (keys.length === 0) {
130
+ if (isFunction(value)) {
131
+ var name = value.name ? ": " + value.name : "";
132
+ return ctx.stylize("[Function" + name + "]", "special");
133
+ }
134
+ if (isRegExp(value))
135
+ return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
136
+ if (isDate(value))
137
+ return ctx.stylize(Date.prototype.toString.call(value), "date");
138
+ if (isError(value))
139
+ return formatError(value);
140
+ }
141
+ var base = "", array = false, braces = ["{", "}"];
142
+ if (isArray(value))
143
+ array = true, braces = ["[", "]"];
144
+ if (isFunction(value)) {
145
+ var n = value.name ? ": " + value.name : "";
146
+ base = " [Function" + n + "]";
147
+ }
148
+ if (isRegExp(value))
149
+ base = " " + RegExp.prototype.toString.call(value);
150
+ if (isDate(value))
151
+ base = " " + Date.prototype.toUTCString.call(value);
152
+ if (isError(value))
153
+ base = " " + formatError(value);
154
+ if (keys.length === 0 && (!array || value.length == 0))
155
+ return braces[0] + base + braces[1];
156
+ if (recurseTimes < 0)
157
+ if (isRegExp(value))
158
+ return ctx.stylize(RegExp.prototype.toString.call(value), "regexp");
159
+ else
160
+ return ctx.stylize("[Object]", "special");
161
+ ctx.seen.push(value);
162
+ var output;
163
+ if (array)
164
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
165
+ else
166
+ output = keys.map(function(key) {
167
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
168
+ });
169
+ return ctx.seen.pop(), reduceToSingleString(output, base, braces);
170
+ }
171
+ function formatPrimitive(ctx, value) {
172
+ if (isUndefined(value))
173
+ return ctx.stylize("undefined", "undefined");
174
+ if (isString(value)) {
175
+ var simple = "'" + JSON.stringify(value).replace(/^"|"$/g, "").replace(/'/g, "\\'").replace(/\\"/g, '"') + "'";
176
+ return ctx.stylize(simple, "string");
177
+ }
178
+ if (isNumber(value))
179
+ return ctx.stylize("" + value, "number");
180
+ if (isBoolean(value))
181
+ return ctx.stylize("" + value, "boolean");
182
+ if (isNull(value))
183
+ return ctx.stylize("null", "null");
184
+ }
185
+ function formatError(value) {
186
+ return "[" + Error.prototype.toString.call(value) + "]";
187
+ }
188
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
189
+ var output = [];
190
+ for (var i = 0, l = value.length;i < l; ++i)
191
+ if (hasOwnProperty(value, String(i)))
192
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true));
193
+ else
194
+ output.push("");
195
+ return keys.forEach(function(key) {
196
+ if (!key.match(/^\d+$/))
197
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true));
198
+ }), output;
199
+ }
200
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
201
+ var name, str, desc;
202
+ if (desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }, desc.get)
203
+ if (desc.set)
204
+ str = ctx.stylize("[Getter/Setter]", "special");
205
+ else
206
+ str = ctx.stylize("[Getter]", "special");
207
+ else if (desc.set)
208
+ str = ctx.stylize("[Setter]", "special");
209
+ if (!hasOwnProperty(visibleKeys, key))
210
+ name = "[" + key + "]";
211
+ if (!str)
212
+ if (ctx.seen.indexOf(desc.value) < 0) {
213
+ if (isNull(recurseTimes))
214
+ str = formatValue(ctx, desc.value, null);
215
+ else
216
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
217
+ if (str.indexOf(`
218
+ `) > -1)
219
+ if (array)
220
+ str = str.split(`
221
+ `).map(function(line) {
222
+ return " " + line;
223
+ }).join(`
224
+ `).slice(2);
225
+ else
226
+ str = `
227
+ ` + str.split(`
228
+ `).map(function(line) {
229
+ return " " + line;
230
+ }).join(`
231
+ `);
232
+ } else
233
+ str = ctx.stylize("[Circular]", "special");
234
+ if (isUndefined(name)) {
235
+ if (array && key.match(/^\d+$/))
236
+ return str;
237
+ if (name = JSON.stringify("" + key), name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/))
238
+ name = name.slice(1, -1), name = ctx.stylize(name, "name");
239
+ else
240
+ name = name.replace(/'/g, "\\'").replace(/\\"/g, '"').replace(/(^"|"$)/g, "'"), name = ctx.stylize(name, "string");
241
+ }
242
+ return name + ": " + str;
243
+ }
244
+ function reduceToSingleString(output, base, braces) {
245
+ var numLinesEst = 0, length = output.reduce(function(prev, cur) {
246
+ if (numLinesEst++, cur.indexOf(`
247
+ `) >= 0)
248
+ numLinesEst++;
249
+ return prev + cur.replace(/\u001b\[\d\d?m/g, "").length + 1;
250
+ }, 0);
251
+ if (length > 60)
252
+ return braces[0] + (base === "" ? "" : base + `
253
+ `) + " " + output.join(`,
254
+ `) + " " + braces[1];
255
+ return braces[0] + base + " " + output.join(", ") + " " + braces[1];
256
+ }
257
+ function isArray(ar) {
258
+ return Array.isArray(ar);
259
+ }
260
+ function isBoolean(arg) {
261
+ return typeof arg === "boolean";
262
+ }
263
+ function isNull(arg) {
264
+ return arg === null;
265
+ }
266
+ function isNullOrUndefined(arg) {
267
+ return arg == null;
268
+ }
269
+ function isNumber(arg) {
270
+ return typeof arg === "number";
271
+ }
272
+ function isString(arg) {
273
+ return typeof arg === "string";
274
+ }
275
+ function isSymbol(arg) {
276
+ return typeof arg === "symbol";
277
+ }
278
+ function isUndefined(arg) {
279
+ return arg === undefined;
280
+ }
281
+ function isRegExp(re) {
282
+ return isObject(re) && objectToString(re) === "[object RegExp]";
283
+ }
284
+ function isObject(arg) {
285
+ return typeof arg === "object" && arg !== null;
286
+ }
287
+ function isDate(d) {
288
+ return isObject(d) && objectToString(d) === "[object Date]";
289
+ }
290
+ function isError(e) {
291
+ return isObject(e) && (objectToString(e) === "[object Error]" || e instanceof Error);
292
+ }
293
+ function isFunction(arg) {
294
+ return typeof arg === "function";
295
+ }
296
+ function isPrimitive(arg) {
297
+ return arg === null || typeof arg === "boolean" || typeof arg === "number" || typeof arg === "string" || typeof arg === "symbol" || typeof arg > "u";
298
+ }
299
+ function isBuffer(arg) {
300
+ return arg instanceof Buffer;
301
+ }
302
+ function objectToString(o) {
303
+ return Object.prototype.toString.call(o);
304
+ }
305
+ function pad(n) {
306
+ return n < 10 ? "0" + n.toString(10) : n.toString(10);
307
+ }
308
+ function timestamp() {
309
+ var d = new Date, time = [pad(d.getHours()), pad(d.getMinutes()), pad(d.getSeconds())].join(":");
310
+ return [d.getDate(), months[d.getMonth()], time].join(" ");
311
+ }
312
+ function log(...args) {
313
+ console.log("%s - %s", timestamp(), format.apply(null, args));
314
+ }
315
+ function inherits(ctor, superCtor) {
316
+ if (superCtor)
317
+ ctor.super_ = superCtor, ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } });
318
+ }
319
+ function _extend(origin, add) {
320
+ if (!add || !isObject(add))
321
+ return origin;
322
+ var keys = Object.keys(add), i = keys.length;
323
+ while (i--)
324
+ origin[keys[i]] = add[keys[i]];
325
+ return origin;
326
+ }
327
+ function hasOwnProperty(obj, prop) {
328
+ return Object.prototype.hasOwnProperty.call(obj, prop);
329
+ }
330
+ function callbackifyOnRejected(reason, cb) {
331
+ if (!reason) {
332
+ var newReason = Error("Promise was rejected with a falsy value");
333
+ newReason.reason = reason, reason = newReason;
334
+ }
335
+ return cb(reason);
336
+ }
337
+ function callbackify(original) {
338
+ if (typeof original !== "function")
339
+ throw TypeError('The "original" argument must be of type Function');
340
+ function callbackified(...args) {
341
+ var maybeCb = args.pop();
342
+ if (typeof maybeCb !== "function")
343
+ throw TypeError("The last argument must be of type Function");
344
+ var self = this, cb = function(...args2) {
345
+ return maybeCb.apply(self, ...args2);
346
+ };
347
+ original.apply(this, args).then(function(ret) {
348
+ process.nextTick(cb.bind(null, null, ret));
349
+ }, function(rej) {
350
+ process.nextTick(callbackifyOnRejected.bind(null, rej, cb));
351
+ });
352
+ }
353
+ return Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original)), Object.defineProperties(callbackified, Object.getOwnPropertyDescriptors(original)), callbackified;
354
+ }
355
+ var formatRegExp, debuglog, inspect, types = () => {}, months, promisify, TextEncoder, TextDecoder, util_default;
356
+ var init_util = __esm(() => {
357
+ formatRegExp = /%[sdj%]/g;
358
+ debuglog = ((debugs = {}, debugEnvRegex = {}, debugEnv) => ((debugEnv = typeof process < "u" && false) && (debugEnv = debugEnv.replace(/[|\\{}()[\]^$+?.]/g, "\\$&").replace(/\*/g, ".*").replace(/,/g, "$|^").toUpperCase()), debugEnvRegex = new RegExp("^" + debugEnv + "$", "i"), (set) => {
359
+ if (set = set.toUpperCase(), !debugs[set])
360
+ if (debugEnvRegex.test(set))
361
+ debugs[set] = function(...args) {
362
+ console.error("%s: %s", set, pid, format.apply(null, ...args));
363
+ };
364
+ else
365
+ debugs[set] = function() {};
366
+ return debugs[set];
367
+ }))();
368
+ inspect = ((i) => (i.colors = { bold: [1, 22], italic: [3, 23], underline: [4, 24], inverse: [7, 27], white: [37, 39], grey: [90, 39], black: [30, 39], blue: [34, 39], cyan: [36, 39], green: [32, 39], magenta: [35, 39], red: [31, 39], yellow: [33, 39] }, i.styles = { special: "cyan", number: "yellow", boolean: "yellow", undefined: "grey", null: "bold", string: "green", date: "magenta", regexp: "red" }, i.custom = Symbol.for("nodejs.util.inspect.custom"), i))(function(obj, opts, ...rest) {
369
+ var ctx = { seen: [], stylize: stylizeNoColor };
370
+ if (rest.length >= 1)
371
+ ctx.depth = rest[0];
372
+ if (rest.length >= 2)
373
+ ctx.colors = rest[1];
374
+ if (isBoolean(opts))
375
+ ctx.showHidden = opts;
376
+ else if (opts)
377
+ _extend(ctx, opts);
378
+ if (isUndefined(ctx.showHidden))
379
+ ctx.showHidden = false;
380
+ if (isUndefined(ctx.depth))
381
+ ctx.depth = 2;
382
+ if (isUndefined(ctx.colors))
383
+ ctx.colors = false;
384
+ if (ctx.colors)
385
+ ctx.stylize = stylizeWithColor;
386
+ return formatValue(ctx, obj, ctx.depth);
387
+ });
388
+ months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
389
+ promisify = ((x) => (x.custom = Symbol.for("nodejs.util.promisify.custom"), x))(function(original) {
390
+ if (typeof original !== "function")
391
+ throw TypeError('The "original" argument must be of type Function');
392
+ if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
393
+ var fn = original[kCustomPromisifiedSymbol];
394
+ if (typeof fn !== "function")
395
+ throw TypeError('The "nodejs.util.promisify.custom" argument must be of type Function');
396
+ return Object.defineProperty(fn, kCustomPromisifiedSymbol, { value: fn, enumerable: false, writable: false, configurable: true }), fn;
397
+ }
398
+ function fn(...args) {
399
+ var promiseResolve, promiseReject, promise = new Promise(function(resolve, reject) {
400
+ promiseResolve = resolve, promiseReject = reject;
401
+ });
402
+ args.push(function(err, value) {
403
+ if (err)
404
+ promiseReject(err);
405
+ else
406
+ promiseResolve(value);
407
+ });
408
+ try {
409
+ original.apply(this, args);
410
+ } catch (err) {
411
+ promiseReject(err);
412
+ }
413
+ return promise;
414
+ }
415
+ if (Object.setPrototypeOf(fn, Object.getPrototypeOf(original)), kCustomPromisifiedSymbol)
416
+ Object.defineProperty(fn, kCustomPromisifiedSymbol, { value: fn, enumerable: false, writable: false, configurable: true });
417
+ return Object.defineProperties(fn, Object.getOwnPropertyDescriptors(original));
418
+ });
419
+ ({ TextEncoder, TextDecoder } = globalThis);
420
+ util_default = { TextEncoder, TextDecoder, promisify, log, inherits, _extend, callbackifyOnRejected, callbackify };
421
+ });
422
+
423
+ // ../../internal/constants/src/endpoints.ts
424
+ var DEFAULT_PLATFORM = "BEYOND_AI";
425
+ var BEYONDAI_TOKEN_URLS = {
426
+ staging: "https://staging-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com/oauth2/token",
427
+ production: "https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com/oauth2/token"
428
+ };
429
+ var BEYONDAI_API_URLS = {
430
+ staging: "https://api.staging.alpha-1edtech.ai",
431
+ production: "https://api.alpha-1edtech.ai"
432
+ };
433
+ var BEYONDAI_CALIPER_URLS = {
434
+ staging: "https://caliper.staging.alpha-1edtech.ai",
435
+ production: "https://caliper.alpha-1edtech.ai"
436
+ };
437
+ var BEYONDAI_QTI_URLS = {
438
+ staging: "https://qti.alpha-1edtech.ai/api",
439
+ production: "https://qti.alpha-1edtech.ai/api"
440
+ };
441
+ var LEARNWITHAI_TOKEN_URLS = {
442
+ staging: "https://platform.dev.timeback.com/auth/1.0/token",
443
+ production: "https://platform.timeback.com/auth/1.0/token"
444
+ };
445
+ var LEARNWITHAI_API_URLS = {
446
+ staging: "https://platform.dev.timeback.com",
447
+ production: "https://platform.timeback.com"
448
+ };
449
+ var LEARNWITHAI_CALIPER_URLS = {
450
+ staging: "https://platform.dev.timeback.com",
451
+ production: "https://platform.timeback.com"
452
+ };
453
+ var LEARNWITHAI_QTI_URLS = {
454
+ staging: "https://platform.dev.timeback.com",
455
+ production: "https://platform.timeback.com"
456
+ };
457
+ var PLATFORM_ENDPOINTS = {
458
+ BEYOND_AI: {
459
+ token: BEYONDAI_TOKEN_URLS,
460
+ api: BEYONDAI_API_URLS,
461
+ caliper: BEYONDAI_CALIPER_URLS,
462
+ qti: BEYONDAI_QTI_URLS
463
+ },
464
+ LEARNWITH_AI: {
465
+ token: LEARNWITHAI_TOKEN_URLS,
466
+ api: LEARNWITHAI_API_URLS,
467
+ caliper: LEARNWITHAI_CALIPER_URLS,
468
+ qti: LEARNWITHAI_QTI_URLS
469
+ }
470
+ };
471
+ // ../../internal/constants/src/typescript.ts
472
+ var TypeScriptPackages = {
473
+ tsc: "tsc",
474
+ nativePreview: "@typescript/native-preview"
475
+ };
476
+ var TYPESCRIPT_RUNNER = {
477
+ package: TypeScriptPackages.nativePreview,
478
+ bin: "tsgo"
479
+ };
480
+ // ../../internal/logger/src/debug.ts
481
+ var patterns = null;
482
+ var debugAll = false;
483
+ var debugEnvSet = false;
484
+ function patternToRegex(pattern) {
485
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
486
+ const regexStr = escaped.replace(/\*/g, ".*");
487
+ return new RegExp(`^${regexStr}$`);
488
+ }
489
+ function parseDebugEnv() {
490
+ if (patterns !== null)
491
+ return;
492
+ patterns = [];
493
+ if (typeof process === "undefined" || !process.env?.DEBUG) {
494
+ debugEnvSet = false;
495
+ return;
496
+ }
497
+ debugEnvSet = true;
498
+ const debugValue = process.env.DEBUG.trim();
499
+ if (debugValue === "1" || debugValue === "true" || debugValue === "*") {
500
+ debugAll = true;
501
+ return;
502
+ }
503
+ const parts = debugValue.split(",").map((p) => p.trim()).filter(Boolean);
504
+ for (const part of parts) {
505
+ if (part.startsWith("-")) {
506
+ patterns.push({
507
+ regex: patternToRegex(part.slice(1)),
508
+ exclude: true
509
+ });
510
+ } else {
511
+ patterns.push({
512
+ regex: patternToRegex(part),
513
+ exclude: false
514
+ });
515
+ }
516
+ }
517
+ const hasInclude = patterns.some((p) => !p.exclude);
518
+ if (!hasInclude && patterns.length > 0) {
519
+ debugAll = true;
520
+ }
521
+ }
522
+ function shouldShowDebug(scope) {
523
+ parseDebugEnv();
524
+ if (!debugEnvSet) {
525
+ return true;
526
+ }
527
+ if (debugAll) {
528
+ if (scope) {
529
+ for (const pattern of patterns) {
530
+ if (pattern.exclude && pattern.regex.test(scope)) {
531
+ return false;
532
+ }
533
+ }
534
+ }
535
+ return true;
536
+ }
537
+ if (!scope) {
538
+ return false;
539
+ }
540
+ for (const pattern of patterns) {
541
+ if (pattern.exclude && pattern.regex.test(scope)) {
542
+ return false;
543
+ }
544
+ }
545
+ for (const pattern of patterns) {
546
+ if (!pattern.exclude && pattern.regex.test(scope)) {
547
+ return true;
548
+ }
549
+ }
550
+ return false;
551
+ }
552
+
553
+ // ../../internal/logger/src/env.ts
554
+ function isBrowser() {
555
+ return typeof globalThis !== "undefined" && "window" in globalThis;
556
+ }
557
+ function detectEnvironment() {
558
+ if (isBrowser()) {
559
+ return "browser";
560
+ }
561
+ if (typeof process !== "undefined" && process.env) {
562
+ if (process.env["NODE_ENV"] === "test" || process.env["BUN_ENV"] === "test") {
563
+ return "test";
564
+ }
565
+ if (false) {}
566
+ if (process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.CIRCLECI || process.env.JENKINS_URL || process.env.BUILDKITE) {
567
+ return "ci";
568
+ }
569
+ }
570
+ return "terminal";
571
+ }
572
+
573
+ // ../../internal/logger/src/formatters/terminal.ts
574
+ var nodeInspect;
575
+ if (!isBrowser()) {
576
+ try {
577
+ const util = await Promise.resolve().then(() => (init_util(), exports_util));
578
+ nodeInspect = util.inspect;
579
+ } catch {}
580
+ }
581
+ var colors = {
582
+ reset: "\x1B[0m",
583
+ bold: "\x1B[1m",
584
+ dim: "\x1B[2m",
585
+ red: "\x1B[31m",
586
+ yellow: "\x1B[33m",
587
+ blue: "\x1B[34m",
588
+ cyan: "\x1B[36m"
589
+ };
590
+ function getLevelColor(level) {
591
+ switch (level) {
592
+ case "debug":
593
+ return colors.blue;
594
+ case "info":
595
+ return colors.cyan;
596
+ case "warn":
597
+ return colors.yellow;
598
+ case "error":
599
+ return colors.red;
600
+ }
601
+ }
602
+ function getConsoleMethod(level) {
603
+ switch (level) {
604
+ case "debug":
605
+ return console.debug;
606
+ case "info":
607
+ return console.info;
608
+ case "warn":
609
+ return console.warn;
610
+ case "error":
611
+ return console.error;
612
+ }
613
+ }
614
+ function formatContext(context) {
615
+ if (nodeInspect) {
616
+ return nodeInspect(context, {
617
+ depth: null,
618
+ colors: true,
619
+ breakLength: 80,
620
+ compact: false
621
+ });
622
+ }
623
+ return JSON.stringify(context, null, 2);
624
+ }
625
+ var terminalFormatter = (entry) => {
626
+ const levelColor = getLevelColor(entry.level);
627
+ const consoleMethod = getConsoleMethod(entry.level);
628
+ const levelUpper = entry.level.toUpperCase().padEnd(5);
629
+ const isoString = entry.timestamp.toISOString().replace(/\.\d{3}Z$/, "");
630
+ const timestamp2 = `${colors.dim}[${isoString}]${colors.reset}`;
631
+ const level = `${levelColor}${levelUpper}${colors.reset}`;
632
+ const scope = entry.scope ? `${colors.bold}[${entry.scope}]${colors.reset} ` : "";
633
+ const prefix = `${timestamp2} ${level} ${scope}${entry.message}`;
634
+ if (entry.context && Object.keys(entry.context).length > 0) {
635
+ consoleMethod(prefix, formatContext(entry.context));
636
+ } else {
637
+ consoleMethod(prefix);
638
+ }
639
+ };
640
+ // ../../internal/logger/src/formatters/ci.ts
641
+ var LEVEL_PREFIX = {
642
+ debug: "[DEBUG]",
643
+ info: "[INFO]",
644
+ warn: "[WARN]",
645
+ error: "[ERROR]"
646
+ };
647
+ function formatContext2(context) {
648
+ return Object.entries(context).map(([key, value]) => `${key}=${formatValue2(value)}`).join(" ");
649
+ }
650
+ function formatValue2(value) {
651
+ if (typeof value === "string")
652
+ return value;
653
+ if (typeof value === "number")
654
+ return String(value);
655
+ if (typeof value === "boolean")
656
+ return String(value);
657
+ if (value === null)
658
+ return "null";
659
+ if (value === undefined)
660
+ return "undefined";
661
+ return JSON.stringify(value);
662
+ }
663
+ var ciFormatter = (entry) => {
664
+ const parts = [];
665
+ parts.push(entry.timestamp.toISOString());
666
+ parts.push(LEVEL_PREFIX[entry.level]);
667
+ if (entry.scope) {
668
+ parts.push(`[${entry.scope}]`);
669
+ }
670
+ parts.push(entry.message);
671
+ if (entry.context && Object.keys(entry.context).length > 0) {
672
+ parts.push(formatContext2(entry.context));
673
+ }
674
+ console.log(parts.join(" "));
675
+ };
676
+ // ../../internal/logger/src/formatters/production.ts
677
+ var productionFormatter = (entry) => {
678
+ const output = {
679
+ timestamp: entry.timestamp.toISOString(),
680
+ level: entry.level,
681
+ ...entry.scope && { scope: entry.scope },
682
+ msg: entry.message
683
+ };
684
+ if (entry.context && Object.keys(entry.context).length > 0) {
685
+ Object.assign(output, entry.context);
686
+ }
687
+ console.log(JSON.stringify(output));
688
+ };
689
+ // ../../internal/logger/src/formatters/browser.ts
690
+ var LEVEL_STYLES = {
691
+ debug: "color: gray",
692
+ info: "color: #0ea5e9",
693
+ warn: "color: #f59e0b",
694
+ error: "color: #ef4444; font-weight: bold"
695
+ };
696
+ var LEVEL_METHODS = {
697
+ debug: "log",
698
+ info: "info",
699
+ warn: "warn",
700
+ error: "error"
701
+ };
702
+ var browserFormatter = (entry) => {
703
+ const method = LEVEL_METHODS[entry.level];
704
+ const style = LEVEL_STYLES[entry.level];
705
+ const prefix = entry.scope ? `[${entry.scope}]` : "";
706
+ const label = `%c${prefix} ${entry.message}`;
707
+ if (entry.context && Object.keys(entry.context).length > 0) {
708
+ console[method](label, style, entry.context);
709
+ } else {
710
+ console[method](label, style);
711
+ }
712
+ };
713
+ // ../../internal/logger/src/logger.ts
714
+ var LOG_LEVELS = ["debug", "info", "warn", "error"];
715
+ function getFormatter(env) {
716
+ switch (env) {
717
+ case "terminal":
718
+ return terminalFormatter;
719
+ case "ci":
720
+ return ciFormatter;
721
+ case "production":
722
+ return productionFormatter;
723
+ case "browser":
724
+ return browserFormatter;
725
+ case "test":
726
+ return () => {};
727
+ }
728
+ }
729
+ function getDefaultMinLevel() {
730
+ if (typeof process !== "undefined" && process.env?.DEBUG) {
731
+ return "debug";
732
+ }
733
+ return "info";
734
+ }
735
+ function shouldLog(level, minLevel) {
736
+ return LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(minLevel);
737
+ }
738
+
739
+ class Logger {
740
+ scope;
741
+ minLevel;
742
+ environment;
743
+ formatter;
744
+ defaultContext;
745
+ constructor(options = {}) {
746
+ this.scope = options.scope;
747
+ this.minLevel = options.minLevel ?? getDefaultMinLevel();
748
+ this.defaultContext = options.defaultContext ?? {};
749
+ this.environment = options.environment ?? detectEnvironment();
750
+ this.formatter = getFormatter(this.environment);
751
+ }
752
+ child(scope) {
753
+ const childScope = this.scope ? `${this.scope}:${scope}` : scope;
754
+ return new Logger({
755
+ scope: childScope,
756
+ minLevel: this.minLevel,
757
+ environment: this.environment,
758
+ defaultContext: { ...this.defaultContext }
759
+ });
760
+ }
761
+ withContext(context) {
762
+ return new Logger({
763
+ scope: this.scope,
764
+ minLevel: this.minLevel,
765
+ environment: this.environment,
766
+ defaultContext: { ...this.defaultContext, ...context }
767
+ });
768
+ }
769
+ debug(message, context) {
770
+ this.log("debug", message, context);
771
+ }
772
+ info(message, context) {
773
+ this.log("info", message, context);
774
+ }
775
+ warn(message, context) {
776
+ this.log("warn", message, context);
777
+ }
778
+ error(message, context) {
779
+ this.log("error", message, context);
780
+ }
781
+ log(level, message, context) {
782
+ if (level === "debug" && !shouldShowDebug(this.scope)) {
783
+ return;
784
+ }
785
+ if (!shouldLog(level, this.minLevel)) {
786
+ return;
787
+ }
788
+ const entry = {
789
+ level,
790
+ message,
791
+ scope: this.scope,
792
+ context: context || Object.keys(this.defaultContext).length > 0 ? { ...this.defaultContext, ...context } : undefined,
793
+ timestamp: new Date
794
+ };
795
+ this.formatter(entry);
796
+ }
797
+ }
798
+ function createLogger(options = {}) {
799
+ return new Logger(options);
800
+ }
801
+ // ../../internal/client-infra/src/auth/token-manager.ts
802
+ function isDebug() {
803
+ try {
804
+ const debug = typeof process === "undefined" ? undefined : process.env["DEBUG"];
805
+ return debug === "1" || debug === "true";
806
+ } catch {
807
+ return false;
808
+ }
809
+ }
810
+ var log2 = createLogger({ scope: "auth", minLevel: isDebug() ? "debug" : "warn" });
811
+
812
+ class TokenManager {
813
+ config;
814
+ accessToken = null;
815
+ tokenExpiry = 0;
816
+ pendingRequest = null;
817
+ fetchFn;
818
+ constructor(config) {
819
+ this.config = config;
820
+ this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
821
+ }
822
+ async getToken() {
823
+ if (this.accessToken && Date.now() < this.tokenExpiry) {
824
+ log2.debug("Using cached token");
825
+ return this.accessToken;
826
+ }
827
+ if (this.pendingRequest) {
828
+ log2.debug("Waiting for in-flight token request");
829
+ return this.pendingRequest;
830
+ }
831
+ this.pendingRequest = this.fetchToken();
832
+ try {
833
+ return await this.pendingRequest;
834
+ } finally {
835
+ this.pendingRequest = null;
836
+ }
837
+ }
838
+ async fetchToken() {
839
+ log2.debug("Fetching new access token...");
840
+ const { clientId, clientSecret } = this.config.credentials;
841
+ const credentials = btoa(`${clientId}:${clientSecret}`);
842
+ const start = performance.now();
843
+ const response = await this.fetchFn(this.config.tokenUrl, {
844
+ method: "POST",
845
+ headers: {
846
+ Authorization: `Basic ${credentials}`,
847
+ "Content-Type": "application/x-www-form-urlencoded"
848
+ },
849
+ body: "grant_type=client_credentials"
850
+ });
851
+ const duration = Math.round(performance.now() - start);
852
+ if (!response.ok) {
853
+ log2.error(`Token request failed: ${response.status} ${response.statusText}`);
854
+ throw new Error(`Failed to obtain access token: ${response.status} ${response.statusText}`);
855
+ }
856
+ const data = await response.json();
857
+ this.accessToken = data.access_token;
858
+ this.tokenExpiry = Date.now() + (data.expires_in - 60) * 1000;
859
+ log2.debug(`Token acquired (${duration}ms, expires in ${data.expires_in}s)`);
860
+ return this.accessToken;
861
+ }
862
+ invalidate() {
863
+ log2.debug("Token invalidated");
864
+ this.accessToken = null;
865
+ this.tokenExpiry = 0;
866
+ }
867
+ }
868
+ // ../../internal/client-infra/src/config/paths.ts
869
+ var BEYONDAI_PATHS = {
870
+ caliper: {
871
+ send: "/caliper/event",
872
+ validate: "/caliper/event/validate",
873
+ list: "/caliper/events",
874
+ get: "/caliper/events/{id}",
875
+ jobStatus: "/jobs/{id}/status"
876
+ },
877
+ oneroster: {
878
+ rostering: "/ims/oneroster/rostering/v1p2",
879
+ gradebook: "/ims/oneroster/gradebook/v1p2",
880
+ resources: "/ims/oneroster/resources/v1p2"
881
+ },
882
+ edubridge: {
883
+ base: "/edubridge"
884
+ },
885
+ powerpath: {
886
+ base: "/powerpath"
887
+ },
888
+ clr: {
889
+ credentials: "/ims/clr/v2p0/credentials",
890
+ discovery: "/ims/clr/v2p0/discovery"
891
+ },
892
+ case: {
893
+ base: "/ims/case/v1p1"
894
+ },
895
+ webhooks: {
896
+ webhookList: "/webhooks/",
897
+ webhookGet: "/webhooks/{id}",
898
+ webhookCreate: "/webhooks/",
899
+ webhookUpdate: "/webhooks/{id}",
900
+ webhookDelete: "/webhooks/{id}",
901
+ webhookActivate: "/webhooks/{id}/activate",
902
+ webhookDeactivate: "/webhooks/{id}/deactivate",
903
+ webhookFilterList: "/webhook-filters/",
904
+ webhookFilterGet: "/webhook-filters/{id}",
905
+ webhookFilterCreate: "/webhook-filters/",
906
+ webhookFilterUpdate: "/webhook-filters/{id}",
907
+ webhookFilterDelete: "/webhook-filters/{id}",
908
+ webhookFiltersByWebhook: "/webhook-filters/webhook/{webhookId}"
909
+ }
910
+ };
911
+ var LEARNWITHAI_PATHS = {
912
+ caliper: {
913
+ send: "/events/1.0/",
914
+ validate: null,
915
+ list: null,
916
+ get: null,
917
+ jobStatus: null
918
+ },
919
+ oneroster: {
920
+ rostering: "/rostering/1.0",
921
+ gradebook: "/gradebook/1.0",
922
+ resources: "/resources/1.0"
923
+ },
924
+ webhooks: null,
925
+ edubridge: null,
926
+ powerpath: null,
927
+ clr: null,
928
+ case: null
929
+ };
930
+ var PLATFORM_PATHS = {
931
+ BEYOND_AI: BEYONDAI_PATHS,
932
+ LEARNWITH_AI: LEARNWITHAI_PATHS
933
+ };
934
+
935
+ // ../../internal/client-infra/src/config/provider.ts
936
+ function isEnvConfig(config) {
937
+ return "env" in config && !("baseUrl" in config) && !("services" in config);
938
+ }
939
+ function isExplicitConfig(config) {
940
+ return "baseUrl" in config && !("services" in config);
941
+ }
942
+ function isServicesConfig(config) {
943
+ return "services" in config;
944
+ }
945
+ function resolvePathProfiles(pathProfile, customPaths) {
946
+ const basePaths = pathProfile ? PLATFORM_PATHS[pathProfile] ?? BEYONDAI_PATHS : BEYONDAI_PATHS;
947
+ return {
948
+ caliper: customPaths?.caliper ?? basePaths.caliper,
949
+ oneroster: customPaths?.oneroster ?? basePaths.oneroster,
950
+ webhooks: customPaths?.webhooks ?? basePaths.webhooks,
951
+ edubridge: customPaths?.edubridge ?? basePaths.edubridge,
952
+ powerpath: customPaths?.powerpath ?? basePaths.powerpath,
953
+ clr: customPaths?.clr ?? basePaths.clr,
954
+ case: customPaths?.case ?? basePaths.case
955
+ };
956
+ }
957
+
958
+ class TimebackProvider {
959
+ platform;
960
+ env;
961
+ auth;
962
+ timeout;
963
+ endpoints;
964
+ authUrl;
965
+ pathProfiles;
966
+ tokenManagers = new Map;
967
+ constructor(config) {
968
+ this.timeout = config.timeout ?? 30000;
969
+ if (isEnvConfig(config)) {
970
+ this.auth = config.auth;
971
+ const platform = config.platform ?? DEFAULT_PLATFORM;
972
+ const env = config.env;
973
+ this.platform = platform;
974
+ this.env = env;
975
+ const platformEndpoints = PLATFORM_ENDPOINTS[platform];
976
+ if (!platformEndpoints) {
977
+ throw new Error(`Unknown platform: ${platform}`);
978
+ }
979
+ this.authUrl = platformEndpoints.token[env];
980
+ this.pathProfiles = PLATFORM_PATHS[platform] ?? BEYONDAI_PATHS;
981
+ this.endpoints = {
982
+ oneroster: {
983
+ baseUrl: platformEndpoints.api[env],
984
+ authUrl: this.authUrl
985
+ },
986
+ edubridge: {
987
+ baseUrl: platformEndpoints.api[env],
988
+ authUrl: this.authUrl
989
+ },
990
+ powerpath: {
991
+ baseUrl: platformEndpoints.api[env],
992
+ authUrl: this.authUrl
993
+ },
994
+ clr: {
995
+ baseUrl: platformEndpoints.api[env],
996
+ authUrl: this.authUrl
997
+ },
998
+ case: {
999
+ baseUrl: platformEndpoints.api[env],
1000
+ authUrl: this.authUrl
1001
+ },
1002
+ caliper: {
1003
+ baseUrl: platformEndpoints.caliper[env],
1004
+ authUrl: this.authUrl
1005
+ },
1006
+ webhooks: {
1007
+ baseUrl: platformEndpoints.caliper[env],
1008
+ authUrl: this.authUrl
1009
+ },
1010
+ qti: {
1011
+ baseUrl: platformEndpoints.qti[env],
1012
+ authUrl: this.authUrl
1013
+ }
1014
+ };
1015
+ } else if (isExplicitConfig(config)) {
1016
+ this.auth = config.auth;
1017
+ this.authUrl = config.authUrl;
1018
+ this.pathProfiles = resolvePathProfiles(config.pathProfile, config.paths);
1019
+ this.endpoints = {
1020
+ oneroster: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1021
+ edubridge: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1022
+ powerpath: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1023
+ clr: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1024
+ case: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1025
+ caliper: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1026
+ webhooks: { baseUrl: config.baseUrl, authUrl: this.authUrl },
1027
+ qti: { baseUrl: config.baseUrl, authUrl: this.authUrl }
1028
+ };
1029
+ } else if (isServicesConfig(config)) {
1030
+ this.auth = config.auth;
1031
+ this.authUrl = config.authUrl;
1032
+ this.pathProfiles = resolvePathProfiles(config.pathProfile, config.paths);
1033
+ this.endpoints = {};
1034
+ for (const [service, baseUrl] of Object.entries(config.services)) {
1035
+ if (baseUrl) {
1036
+ this.endpoints[service] = {
1037
+ baseUrl,
1038
+ authUrl: this.authUrl
1039
+ };
1040
+ }
1041
+ }
1042
+ } else {
1043
+ throw new Error("Invalid provider configuration");
1044
+ }
1045
+ for (const service of Object.keys(this.pathProfiles)) {
1046
+ if (this.pathProfiles[service] === null) {
1047
+ delete this.endpoints[service];
1048
+ }
1049
+ }
1050
+ }
1051
+ getEndpoint(service) {
1052
+ const endpoint = this.endpoints[service];
1053
+ if (!endpoint) {
1054
+ const pathKey = service;
1055
+ if (pathKey in this.pathProfiles && this.pathProfiles[pathKey] === null) {
1056
+ throw new Error(`Service "${service}" is not supported on ${this.platform ?? "this"} platform.`);
1057
+ }
1058
+ throw new Error(`Service "${service}" is not configured in this provider`);
1059
+ }
1060
+ return endpoint;
1061
+ }
1062
+ hasService(service) {
1063
+ return service in this.endpoints;
1064
+ }
1065
+ getAvailableServices() {
1066
+ return Object.keys(this.endpoints);
1067
+ }
1068
+ getTokenUrl() {
1069
+ return this.authUrl;
1070
+ }
1071
+ getEndpointWithPaths(service) {
1072
+ const endpoint = this.getEndpoint(service);
1073
+ const paths = this.getServicePaths(service);
1074
+ return { ...endpoint, paths };
1075
+ }
1076
+ getPaths() {
1077
+ return this.pathProfiles;
1078
+ }
1079
+ getServicePaths(service) {
1080
+ const paths = this.pathProfiles[service];
1081
+ if (!paths) {
1082
+ throw new Error(`Service "${service}" is not supported on ${this.platform ?? "this"} platform.`);
1083
+ }
1084
+ return paths;
1085
+ }
1086
+ hasServiceSupport(service) {
1087
+ return this.pathProfiles[service] !== null;
1088
+ }
1089
+ getTokenProvider(service) {
1090
+ const endpoint = this.getEndpoint(service);
1091
+ const { authUrl } = endpoint;
1092
+ if (!authUrl) {
1093
+ return;
1094
+ }
1095
+ if (!this.auth) {
1096
+ throw new Error(`Service "${service}" requires authentication but no credentials were provided`);
1097
+ }
1098
+ let manager = this.tokenManagers.get(authUrl);
1099
+ if (!manager) {
1100
+ manager = new TokenManager({
1101
+ tokenUrl: authUrl,
1102
+ credentials: {
1103
+ clientId: this.auth.clientId,
1104
+ clientSecret: this.auth.clientSecret
1105
+ }
1106
+ });
1107
+ this.tokenManagers.set(authUrl, manager);
1108
+ }
1109
+ return manager;
1110
+ }
1111
+ async checkAuth() {
1112
+ if (!this.authUrl || !this.auth) {
1113
+ throw new Error("No auth configured on this provider");
1114
+ }
1115
+ const startTime = Date.now();
1116
+ let manager = this.tokenManagers.get(this.authUrl);
1117
+ if (!manager) {
1118
+ manager = new TokenManager({
1119
+ tokenUrl: this.authUrl,
1120
+ credentials: {
1121
+ clientId: this.auth.clientId,
1122
+ clientSecret: this.auth.clientSecret
1123
+ }
1124
+ });
1125
+ this.tokenManagers.set(this.authUrl, manager);
1126
+ }
1127
+ try {
1128
+ await manager.getToken();
1129
+ return {
1130
+ ok: true,
1131
+ latencyMs: Date.now() - startTime,
1132
+ checks: { tokenAcquisition: true }
1133
+ };
1134
+ } catch (error) {
1135
+ return {
1136
+ ok: false,
1137
+ latencyMs: Date.now() - startTime,
1138
+ error: error instanceof Error ? error.message : String(error),
1139
+ checks: { tokenAcquisition: false }
1140
+ };
1141
+ }
1142
+ }
1143
+ invalidateTokens() {
1144
+ for (const manager of this.tokenManagers.values()) {
1145
+ manager.invalidate?.();
1146
+ }
1147
+ this.tokenManagers.clear();
1148
+ }
1149
+ }
1150
+ // ../../internal/client-infra/src/utils/utils.ts
1151
+ function getEnv(key) {
1152
+ try {
1153
+ if (typeof process === "undefined")
1154
+ return;
1155
+ if (typeof key === "string") {
1156
+ return process.env[key];
1157
+ }
1158
+ for (const k of key) {
1159
+ const value = process.env[k];
1160
+ if (value !== undefined)
1161
+ return value;
1162
+ }
1163
+ return;
1164
+ } catch {
1165
+ return;
1166
+ }
1167
+ }
1168
+ function isDebug2() {
1169
+ const debug = getEnv("DEBUG");
1170
+ return debug === "1" || debug === "true";
1171
+ }
1172
+ function generateRequestId() {
1173
+ return Math.random().toString(16).slice(2, 10);
1174
+ }
1175
+ function createScopedLogger(scope) {
1176
+ return createLogger({
1177
+ scope,
1178
+ minLevel: isDebug2() ? "debug" : "warn"
1179
+ });
1180
+ }
1181
+ // ../../internal/client-infra/src/errors/errors.ts
1182
+ class ApiError extends Error {
1183
+ statusCode;
1184
+ response;
1185
+ name = "ApiError";
1186
+ constructor(message, statusCode, response) {
1187
+ super(message);
1188
+ this.statusCode = statusCode;
1189
+ this.response = response;
1190
+ }
1191
+ get minorCodes() {
1192
+ const ims = this.response;
1193
+ if (!ims?.imsx_CodeMinor?.imsx_codeMinorField) {
1194
+ return [];
1195
+ }
1196
+ return ims.imsx_CodeMinor.imsx_codeMinorField.map((field) => ({
1197
+ field: field.imsx_codeMinorFieldName,
1198
+ value: field.imsx_codeMinorFieldValue
1199
+ }));
1200
+ }
1201
+ get details() {
1202
+ const ims = this.response;
1203
+ return ims?.imsx_error_details ?? [];
1204
+ }
1205
+ }
1206
+
1207
+ class UnauthorizedError extends ApiError {
1208
+ name = "UnauthorizedError";
1209
+ constructor(message = "Unauthorized", response) {
1210
+ super(message, 401, response);
1211
+ }
1212
+ }
1213
+
1214
+ class ForbiddenError extends ApiError {
1215
+ name = "ForbiddenError";
1216
+ constructor(message = "Forbidden", response) {
1217
+ super(message, 403, response);
1218
+ }
1219
+ }
1220
+
1221
+ class NotFoundError extends ApiError {
1222
+ name = "NotFoundError";
1223
+ constructor(message = "Not Found", response) {
1224
+ super(message, 404, response);
1225
+ }
1226
+ }
1227
+
1228
+ class ValidationError extends ApiError {
1229
+ name = "ValidationError";
1230
+ constructor(message = "Validation Error", response) {
1231
+ super(message, 422, response);
1232
+ }
1233
+ }
1234
+
1235
+ class InputValidationError extends ApiError {
1236
+ name = "InputValidationError";
1237
+ issues;
1238
+ constructor(message, issues) {
1239
+ const response = {
1240
+ imsx_codeMajor: "failure",
1241
+ imsx_severity: "error",
1242
+ imsx_description: message,
1243
+ imsx_error_details: issues.map((issue) => ({
1244
+ path: issue.path,
1245
+ message: issue.message
1246
+ }))
1247
+ };
1248
+ super(message, 400, response);
1249
+ this.issues = issues;
1250
+ }
1251
+ }
1252
+ function createInputValidationError(message, issues) {
1253
+ return new InputValidationError(message, issues);
1254
+ }
1255
+ // ../../internal/client-infra/src/transport/constants.ts
1256
+ var MAX_RETRIES = 3;
1257
+ var RETRY_STATUS_CODES = [429, 503];
1258
+ var INITIAL_RETRY_DELAY_MS = 1000;
1259
+
1260
+ // ../../internal/client-infra/src/transport/transport.ts
1261
+ class BaseTransport {
1262
+ config;
1263
+ log;
1264
+ constructor(options) {
1265
+ const { config, logger } = options;
1266
+ const fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
1267
+ let tokenProvider;
1268
+ if ("tokenProvider" in config && config.tokenProvider) {
1269
+ tokenProvider = config.tokenProvider;
1270
+ } else if ("auth" in config && config.auth) {
1271
+ tokenProvider = new TokenManager({
1272
+ tokenUrl: config.auth.authUrl,
1273
+ credentials: {
1274
+ clientId: config.auth.clientId,
1275
+ clientSecret: config.auth.clientSecret
1276
+ },
1277
+ fetch: fetchFn
1278
+ });
1279
+ }
1280
+ const normalizedBaseUrl = config.baseUrl.endsWith("/") ? config.baseUrl : `${config.baseUrl}/`;
1281
+ this.config = {
1282
+ baseUrl: normalizedBaseUrl,
1283
+ timeout: config.timeout ?? 30000,
1284
+ fetch: fetchFn,
1285
+ tokenProvider
1286
+ };
1287
+ this.log = logger.child("http");
1288
+ }
1289
+ get baseUrl() {
1290
+ return this.config.baseUrl;
1291
+ }
1292
+ async request(path, options = {}) {
1293
+ const response = await this.requestRaw(path, options);
1294
+ return this.handleResponse(response);
1295
+ }
1296
+ async requestRaw(path, options = {}) {
1297
+ const { method = "GET", params, body, headers = {} } = options;
1298
+ const url = this.buildUrl(path, params);
1299
+ const requestId = options.requestId ?? generateRequestId();
1300
+ const operationStart = Date.now();
1301
+ const operationDeadline = operationStart + this.config.timeout;
1302
+ for (let attempt = 0;attempt < MAX_RETRIES; attempt++) {
1303
+ const remainingTime = operationDeadline - Date.now();
1304
+ if (remainingTime <= 0) {
1305
+ this.log.error("Request timeout before attempt", isDebug2() ? { requestId, path } : { path });
1306
+ throw new ApiError("Request timeout", 408);
1307
+ }
1308
+ const token = await this.getAccessToken();
1309
+ const isLastAttempt = attempt === MAX_RETRIES - 1;
1310
+ const start = performance.now();
1311
+ this.log.debug(`→ ${method} ${url}`, {
1312
+ requestId,
1313
+ attempt: attempt > 0 ? attempt + 1 : undefined
1314
+ });
1315
+ const requestHeaders = {
1316
+ "Content-Type": "application/json",
1317
+ Accept: "application/json",
1318
+ "X-Request-ID": requestId,
1319
+ ...headers
1320
+ };
1321
+ if (token) {
1322
+ requestHeaders.Authorization = `Bearer ${token}`;
1323
+ }
1324
+ const response = await this.config.fetch(url, {
1325
+ method,
1326
+ headers: requestHeaders,
1327
+ body: body ? JSON.stringify(body) : undefined,
1328
+ signal: AbortSignal.timeout(Math.min(remainingTime, this.config.timeout))
1329
+ });
1330
+ const duration = Math.round(performance.now() - start);
1331
+ this.log.debug(`← ${response.status} ${response.statusText} (${duration}ms)`, {
1332
+ requestId
1333
+ });
1334
+ const shouldRetry = RETRY_STATUS_CODES.includes(response.status) && !isLastAttempt;
1335
+ if (shouldRetry) {
1336
+ const retryAfter = response.headers.get("Retry-After");
1337
+ const delayMs = this.parseRetryAfter(retryAfter, attempt);
1338
+ const timeRemaining = operationDeadline - Date.now();
1339
+ if (delayMs >= timeRemaining) {
1340
+ this.log.error("Request timeout during retry backoff", isDebug2() ? { requestId, path } : { path });
1341
+ throw new ApiError("Request timeout", 408);
1342
+ }
1343
+ this.log.warn(`Retrying in ${delayMs}ms (attempt ${attempt + 1}/${MAX_RETRIES})`, {
1344
+ ...isDebug2() && { requestId },
1345
+ status: response.status
1346
+ });
1347
+ await this.sleep(delayMs);
1348
+ continue;
1349
+ }
1350
+ if (!response.ok) {
1351
+ return this.handleErrorResponse(response, requestId);
1352
+ }
1353
+ return response;
1354
+ }
1355
+ this.log.error("Max retries exceeded", isDebug2() ? { requestId, path } : { path });
1356
+ throw new ApiError("Max retries exceeded");
1357
+ }
1358
+ getAccessToken() {
1359
+ if (!this.config.tokenProvider) {
1360
+ return Promise.resolve(undefined);
1361
+ }
1362
+ return this.config.tokenProvider.getToken();
1363
+ }
1364
+ buildUrl(path, params) {
1365
+ if (/^[a-z][a-z0-9+.-]*:/i.test(path)) {
1366
+ throw new Error(`Absolute URLs are not allowed in path: ${path}. Use relative paths only.`);
1367
+ }
1368
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
1369
+ const url = new URL(normalizedPath, this.config.baseUrl);
1370
+ if (params) {
1371
+ for (const [key, value] of Object.entries(params)) {
1372
+ if (value !== undefined) {
1373
+ url.searchParams.set(key, String(value));
1374
+ }
1375
+ }
1376
+ }
1377
+ return url.toString();
1378
+ }
1379
+ async handleResponse(response) {
1380
+ if (!response.ok) {
1381
+ await this.handleErrorResponse(response);
1382
+ }
1383
+ if (response.status === 204) {
1384
+ return;
1385
+ }
1386
+ const contentLength = response.headers.get("content-length");
1387
+ if (contentLength === "0") {
1388
+ return;
1389
+ }
1390
+ return this.parseJsonResponse(response);
1391
+ }
1392
+ async parseJsonResponse(response) {
1393
+ const text = await response.text();
1394
+ if (!text || text.trim() === "") {
1395
+ return;
1396
+ }
1397
+ try {
1398
+ return JSON.parse(text);
1399
+ } catch (error) {
1400
+ const preview = text.length > 200 ? text.slice(0, 200) + "..." : text;
1401
+ const parseError = error instanceof Error ? error.message : String(error);
1402
+ const url = response.url || "unknown";
1403
+ this.log.error("Failed to parse JSON response", {
1404
+ url,
1405
+ status: response.status,
1406
+ contentType: response.headers.get("content-type"),
1407
+ bodyPreview: preview,
1408
+ error: parseError
1409
+ });
1410
+ throw new ApiError(`Invalid JSON response from ${url}`, response.status, {
1411
+ parseError,
1412
+ body: preview
1413
+ });
1414
+ }
1415
+ }
1416
+ async handleErrorResponse(response, requestId) {
1417
+ let errorBody;
1418
+ const text = await response.text().catch(() => "");
1419
+ if (text) {
1420
+ try {
1421
+ errorBody = JSON.parse(text);
1422
+ } catch (parseError) {
1423
+ const parseWarning = parseError instanceof Error ? parseError.message : "Unknown parse error";
1424
+ errorBody = { rawBody: text.slice(0, 500), parseError: parseWarning };
1425
+ this.log.warn("Failed to parse error response as JSON", {
1426
+ ...isDebug2() && { requestId },
1427
+ url: response.url,
1428
+ status: response.status,
1429
+ parseError: parseWarning,
1430
+ bodyPreview: text.slice(0, 200)
1431
+ });
1432
+ }
1433
+ }
1434
+ const message = this.extractErrorMessage(errorBody, response.statusText);
1435
+ if (response.status !== 404) {
1436
+ this.log.error(`Request failed: ${response.status} ${message}`, isDebug2() ? { requestId } : undefined);
1437
+ }
1438
+ switch (response.status) {
1439
+ case 401:
1440
+ this.config.tokenProvider?.invalidate?.();
1441
+ throw new UnauthorizedError(message, errorBody);
1442
+ case 403:
1443
+ throw new ForbiddenError(message, errorBody);
1444
+ case 404:
1445
+ throw new NotFoundError(message, errorBody);
1446
+ case 422:
1447
+ throw new ValidationError(message, errorBody);
1448
+ default:
1449
+ throw new ApiError(message, response.status, errorBody);
1450
+ }
1451
+ }
1452
+ extractErrorMessage(body, fallback) {
1453
+ if (typeof body === "object" && body !== null) {
1454
+ const obj = body;
1455
+ if (typeof obj.message === "string")
1456
+ return obj.message;
1457
+ if (typeof obj.error === "string")
1458
+ return obj.error;
1459
+ if (typeof obj.imsx_description === "string")
1460
+ return obj.imsx_description;
1461
+ }
1462
+ return fallback;
1463
+ }
1464
+ sleep(ms) {
1465
+ return new Promise((resolve) => {
1466
+ setTimeout(resolve, ms);
1467
+ });
1468
+ }
1469
+ parseRetryAfter(retryAfter, attempt) {
1470
+ if (!retryAfter) {
1471
+ return INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt);
1472
+ }
1473
+ const seconds = parseInt(retryAfter, 10);
1474
+ if (!isNaN(seconds)) {
1475
+ return seconds * 1000;
1476
+ }
1477
+ const date = Date.parse(retryAfter);
1478
+ if (!isNaN(date)) {
1479
+ const delayMs = date - Date.now();
1480
+ return Math.max(0, delayMs);
1481
+ }
1482
+ return INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt);
1483
+ }
1484
+ }
1485
+ // ../../internal/client-infra/src/validation/index.ts
1486
+ function validateWithSchema(schema, data, context) {
1487
+ const result = schema.safeParse(data);
1488
+ if (result.success) {
1489
+ return;
1490
+ }
1491
+ const issues = result.error.issues.map((errorIssue) => ({
1492
+ path: errorIssue.path.join(".") || "(root)",
1493
+ message: errorIssue.message
1494
+ }));
1495
+ throw createInputValidationError(`Invalid ${context} data`, issues);
1496
+ }
1497
+ export {
1498
+ ValidationError,
1499
+ UnauthorizedError,
1500
+ NotFoundError,
1501
+ ApiError as MasteryTrackError,
1502
+ InputValidationError,
1503
+ ForbiddenError
1504
+ };