@timeback/powerpath 0.2.3-beta.20260331232130 → 0.2.3-beta.20260403024308
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/{chunk-setst1c6.js → chunk-89bw8av5.js} +47 -14
- package/dist/errors.js +1 -1
- package/dist/index.d.ts +65 -33
- package/dist/index.js +8 -1
- package/package.json +1 -1
|
@@ -146,6 +146,17 @@ var TYPESCRIPT_RUNNER = {
|
|
|
146
146
|
var patterns = null;
|
|
147
147
|
var debugAll = false;
|
|
148
148
|
var debugEnvSet = false;
|
|
149
|
+
function hasDebugOptIn() {
|
|
150
|
+
try {
|
|
151
|
+
const debugValue = process.env.DEBUG?.trim();
|
|
152
|
+
if (!debugValue) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
return debugValue.split(",").some((part) => part.trim().length > 0);
|
|
156
|
+
} catch {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
149
160
|
function patternToRegex(pattern) {
|
|
150
161
|
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
151
162
|
const regexStr = escaped.replace(/\*/g, ".*");
|
|
@@ -155,7 +166,7 @@ function parseDebugEnv() {
|
|
|
155
166
|
if (patterns !== null)
|
|
156
167
|
return;
|
|
157
168
|
patterns = [];
|
|
158
|
-
if (
|
|
169
|
+
if (!hasDebugOptIn()) {
|
|
159
170
|
debugEnvSet = false;
|
|
160
171
|
return;
|
|
161
172
|
}
|
|
@@ -377,6 +388,19 @@ var browserFormatter = (entry) => {
|
|
|
377
388
|
};
|
|
378
389
|
// ../../internal/logger/src/logger.ts
|
|
379
390
|
var LOG_LEVELS = ["debug", "info", "warn", "error"];
|
|
391
|
+
var GLOBAL_LOGGING_CONFIG_KEY = Symbol.for("@timeback/internal-logger/config");
|
|
392
|
+
function shouldUseSilentFormatter() {
|
|
393
|
+
try {
|
|
394
|
+
return process.env["TIMEBACK_INTERNAL_LOGGER"] === "silent";
|
|
395
|
+
} catch {
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function getGlobalLoggingConfig() {
|
|
400
|
+
const globalState = globalThis;
|
|
401
|
+
globalState[GLOBAL_LOGGING_CONFIG_KEY] ??= {};
|
|
402
|
+
return globalState[GLOBAL_LOGGING_CONFIG_KEY];
|
|
403
|
+
}
|
|
380
404
|
function getFormatter(env) {
|
|
381
405
|
switch (env) {
|
|
382
406
|
case "terminal":
|
|
@@ -392,11 +416,14 @@ function getFormatter(env) {
|
|
|
392
416
|
}
|
|
393
417
|
}
|
|
394
418
|
function getDefaultMinLevel() {
|
|
395
|
-
if (
|
|
419
|
+
if (hasDebugOptIn()) {
|
|
396
420
|
return "debug";
|
|
397
421
|
}
|
|
398
422
|
return "info";
|
|
399
423
|
}
|
|
424
|
+
function getConfiguredFormatter(env, formatter) {
|
|
425
|
+
return formatter ?? getGlobalLoggingConfig().formatter ?? (shouldUseSilentFormatter() ? () => {} : getFormatter(env));
|
|
426
|
+
}
|
|
400
427
|
function shouldLog(level, minLevel) {
|
|
401
428
|
return LOG_LEVELS.indexOf(level) >= LOG_LEVELS.indexOf(minLevel);
|
|
402
429
|
}
|
|
@@ -405,14 +432,14 @@ class Logger {
|
|
|
405
432
|
scope;
|
|
406
433
|
minLevel;
|
|
407
434
|
environment;
|
|
408
|
-
|
|
435
|
+
explicitFormatter;
|
|
409
436
|
defaultContext;
|
|
410
437
|
constructor(options = {}) {
|
|
411
438
|
this.scope = options.scope;
|
|
412
439
|
this.minLevel = options.minLevel ?? getDefaultMinLevel();
|
|
413
440
|
this.defaultContext = options.defaultContext ?? {};
|
|
414
441
|
this.environment = options.environment ?? detectEnvironment();
|
|
415
|
-
this.
|
|
442
|
+
this.explicitFormatter = options.formatter;
|
|
416
443
|
}
|
|
417
444
|
child(scope) {
|
|
418
445
|
const childScope = this.scope ? `${this.scope}:${scope}` : scope;
|
|
@@ -420,7 +447,8 @@ class Logger {
|
|
|
420
447
|
scope: childScope,
|
|
421
448
|
minLevel: this.minLevel,
|
|
422
449
|
environment: this.environment,
|
|
423
|
-
defaultContext: { ...this.defaultContext }
|
|
450
|
+
defaultContext: { ...this.defaultContext },
|
|
451
|
+
formatter: this.explicitFormatter
|
|
424
452
|
});
|
|
425
453
|
}
|
|
426
454
|
withContext(context) {
|
|
@@ -428,7 +456,8 @@ class Logger {
|
|
|
428
456
|
scope: this.scope,
|
|
429
457
|
minLevel: this.minLevel,
|
|
430
458
|
environment: this.environment,
|
|
431
|
-
defaultContext: { ...this.defaultContext, ...context }
|
|
459
|
+
defaultContext: { ...this.defaultContext, ...context },
|
|
460
|
+
formatter: this.explicitFormatter
|
|
432
461
|
});
|
|
433
462
|
}
|
|
434
463
|
debug(message, context) {
|
|
@@ -457,7 +486,7 @@ class Logger {
|
|
|
457
486
|
context: context || Object.keys(this.defaultContext).length > 0 ? { ...this.defaultContext, ...context } : undefined,
|
|
458
487
|
timestamp: new Date
|
|
459
488
|
};
|
|
460
|
-
this.
|
|
489
|
+
getConfiguredFormatter(this.environment, this.explicitFormatter)(entry);
|
|
461
490
|
}
|
|
462
491
|
}
|
|
463
492
|
function createLogger(options = {}) {
|
|
@@ -472,7 +501,6 @@ function isDebug() {
|
|
|
472
501
|
return false;
|
|
473
502
|
}
|
|
474
503
|
}
|
|
475
|
-
var log = createLogger({ scope: "auth", minLevel: isDebug() ? "debug" : "warn" });
|
|
476
504
|
|
|
477
505
|
class TokenManager {
|
|
478
506
|
config;
|
|
@@ -480,17 +508,22 @@ class TokenManager {
|
|
|
480
508
|
tokenExpiry = 0;
|
|
481
509
|
pendingRequest = null;
|
|
482
510
|
fetchFn;
|
|
511
|
+
log;
|
|
483
512
|
constructor(config) {
|
|
484
513
|
this.config = config;
|
|
485
514
|
this.fetchFn = config.fetch ?? globalThis.fetch.bind(globalThis);
|
|
515
|
+
this.log = config.logger ?? createLogger({
|
|
516
|
+
scope: "auth",
|
|
517
|
+
minLevel: isDebug() ? "debug" : "warn"
|
|
518
|
+
});
|
|
486
519
|
}
|
|
487
520
|
async getToken() {
|
|
488
521
|
if (this.accessToken && Date.now() < this.tokenExpiry) {
|
|
489
|
-
log.debug("Using cached token");
|
|
522
|
+
this.log.debug("Using cached token");
|
|
490
523
|
return this.accessToken;
|
|
491
524
|
}
|
|
492
525
|
if (this.pendingRequest) {
|
|
493
|
-
log.debug("Waiting for in-flight token request");
|
|
526
|
+
this.log.debug("Waiting for in-flight token request");
|
|
494
527
|
return this.pendingRequest;
|
|
495
528
|
}
|
|
496
529
|
this.pendingRequest = this.fetchToken();
|
|
@@ -501,7 +534,7 @@ class TokenManager {
|
|
|
501
534
|
}
|
|
502
535
|
}
|
|
503
536
|
async fetchToken() {
|
|
504
|
-
log.debug("Fetching new access token...");
|
|
537
|
+
this.log.debug("Fetching new access token...");
|
|
505
538
|
const { clientId, clientSecret } = this.config.credentials;
|
|
506
539
|
const credentials = btoa(`${clientId}:${clientSecret}`);
|
|
507
540
|
const start = performance.now();
|
|
@@ -515,17 +548,17 @@ class TokenManager {
|
|
|
515
548
|
});
|
|
516
549
|
const duration = Math.round(performance.now() - start);
|
|
517
550
|
if (!response.ok) {
|
|
518
|
-
log.error(`Token request failed: ${response.status} ${response.statusText}`);
|
|
551
|
+
this.log.error(`Token request failed: ${response.status} ${response.statusText}`);
|
|
519
552
|
throw new Error(`Failed to obtain access token: ${response.status} ${response.statusText}`);
|
|
520
553
|
}
|
|
521
554
|
const data = await response.json();
|
|
522
555
|
this.accessToken = data.access_token;
|
|
523
556
|
this.tokenExpiry = Date.now() + (data.expires_in - 60) * 1000;
|
|
524
|
-
log.debug(`Token acquired (${duration}ms, expires in ${data.expires_in}s)`);
|
|
557
|
+
this.log.debug(`Token acquired (${duration}ms, expires in ${data.expires_in}s)`);
|
|
525
558
|
return this.accessToken;
|
|
526
559
|
}
|
|
527
560
|
invalidate() {
|
|
528
|
-
log.debug("Token invalidated");
|
|
561
|
+
this.log.debug("Token invalidated");
|
|
529
562
|
this.accessToken = null;
|
|
530
563
|
this.tokenExpiry = 0;
|
|
531
564
|
}
|
package/dist/errors.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -3,37 +3,6 @@ export { AssignmentResult, Attempt, BulkResult, CourseProgressResponse, CreateAt
|
|
|
3
3
|
import { CreateExternalPlacementTestInput, CreateExternalTestOutInput, CreateInternalTestInput, CreateNewAttemptInput, FinalStudentAssessmentResponseInput, GetAssessmentProgressParams, GetAttemptsParams, GetNextQuestionParams, ImportExternalTestAssignmentResultsParams, MakeExternalTestAssignmentInput, ResetAttemptInput, TestOutParams, UpdateStudentQuestionResponseInput, LessonPlansCreateInput, LessonPlanOperationsInput, LessonPlanUpdateStudentItemResponseInput, PlacementQueryParams, PlacementResetUserPlacementInput, RenderConfigUpsertInput, ScreeningResetSessionInput, ScreeningAssignTestInput, SyllabusQueryParams, TestAssignmentsListParams, TestAssignmentsCreateInput, TestAssignmentsUpdateInput, TestAssignmentsAdminParams, TestAssignmentsBulkInput, TestAssignmentsImportInput, MakeExternalStudentTestOutAssignmentInput } from '@timeback/types/zod';
|
|
4
4
|
export { CreateExternalPlacementTestInput, CreateExternalTestOutInput, CreateInternalTestInput, CreateNewAttemptInput, FinalStudentAssessmentResponseInput, GetAssessmentProgressParams, GetAttemptsParams, GetNextQuestionParams, ImportExternalTestAssignmentResultsParams, LessonPlanOperationInput, LessonPlanOperationsInput, LessonPlanUpdateStudentItemResponseInput, LessonPlansCreateInput, MakeExternalStudentTestOutAssignmentInput, MakeExternalTestAssignmentInput, PlacementQueryParams, PlacementResetUserPlacementInput, ResetAttemptInput, ScreeningAssignTestInput, ScreeningResetSessionInput, SyllabusQueryParams, TestAssignmentsAdminParams, TestAssignmentsBulkInput, TestAssignmentsCreateInput, TestAssignmentsImportInput, TestAssignmentsListParams, TestAssignmentsUpdateInput, TestOutParams, UpdateStudentQuestionResponseInput } from '@timeback/types/zod';
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Interface for obtaining OAuth2 access tokens.
|
|
8
|
-
*
|
|
9
|
-
* Implementations handle token caching and refresh automatically.
|
|
10
|
-
*/
|
|
11
|
-
interface TokenProvider {
|
|
12
|
-
/**
|
|
13
|
-
* Get a valid access token.
|
|
14
|
-
*
|
|
15
|
-
* Returns a cached token if still valid, otherwise fetches a new one.
|
|
16
|
-
*
|
|
17
|
-
* @returns A valid access token string
|
|
18
|
-
* @throws {Error} If token acquisition fails
|
|
19
|
-
*/
|
|
20
|
-
getToken(): Promise<string>;
|
|
21
|
-
/**
|
|
22
|
-
* Invalidate the cached token.
|
|
23
|
-
*
|
|
24
|
-
* Forces the next getToken() call to fetch a fresh token.
|
|
25
|
-
* Should be called when a request fails with 401 Unauthorized.
|
|
26
|
-
*
|
|
27
|
-
* Optional - not all implementations may support invalidation.
|
|
28
|
-
*/
|
|
29
|
-
invalidate?(): void;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* All supported platforms.
|
|
34
|
-
*/
|
|
35
|
-
declare const PLATFORMS: readonly ["BEYOND_AI", "LEARNWITH_AI"];
|
|
36
|
-
|
|
37
6
|
/**
|
|
38
7
|
* Type Definitions for `@timeback/internal-logger`
|
|
39
8
|
*
|
|
@@ -69,6 +38,24 @@ type Environment$2 = 'terminal' | 'ci' | 'production' | 'browser' | 'test';
|
|
|
69
38
|
* log.info('User created', { userId: 123, email: 'foo@bar.com' })
|
|
70
39
|
*/
|
|
71
40
|
type LogContext = Record<string, unknown>;
|
|
41
|
+
/**
|
|
42
|
+
* A single log entry before it's formatted for output.
|
|
43
|
+
*
|
|
44
|
+
* This is the internal representation passed to formatters.
|
|
45
|
+
* Formatters transform this into environment-specific output.
|
|
46
|
+
*/
|
|
47
|
+
interface LogEntry {
|
|
48
|
+
/** Severity level of this log entry */
|
|
49
|
+
level: LogLevel;
|
|
50
|
+
/** Human-readable log message */
|
|
51
|
+
message: string;
|
|
52
|
+
/** Optional namespace/category (e.g., "api", "db", "auth") */
|
|
53
|
+
scope?: string;
|
|
54
|
+
/** Optional structured data attached to this entry */
|
|
55
|
+
context?: LogContext;
|
|
56
|
+
/** When this log entry was created */
|
|
57
|
+
timestamp: Date;
|
|
58
|
+
}
|
|
72
59
|
/**
|
|
73
60
|
* Configuration options for creating a logger instance.
|
|
74
61
|
*/
|
|
@@ -94,7 +81,21 @@ interface LoggerOptions {
|
|
|
94
81
|
* Useful for request IDs, user IDs, etc.
|
|
95
82
|
*/
|
|
96
83
|
defaultContext?: LogContext;
|
|
84
|
+
/**
|
|
85
|
+
* Custom formatter override for this logger instance.
|
|
86
|
+
*
|
|
87
|
+
* When provided, this takes precedence over environment-based formatting.
|
|
88
|
+
* Useful for tests, custom sinks, or temporarily suppressing output.
|
|
89
|
+
*/
|
|
90
|
+
formatter?: Formatter;
|
|
97
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Function that outputs a log entry in a specific format.
|
|
94
|
+
*
|
|
95
|
+
* Each environment has its own formatter. Formatters are responsible
|
|
96
|
+
* for the actual console.log/write calls.
|
|
97
|
+
*/
|
|
98
|
+
type Formatter = (entry: LogEntry) => void;
|
|
98
99
|
|
|
99
100
|
/**
|
|
100
101
|
* Logger instance with environment-aware formatting.
|
|
@@ -109,8 +110,8 @@ declare class Logger {
|
|
|
109
110
|
private minLevel;
|
|
110
111
|
/** The detected or configured environment */
|
|
111
112
|
private environment;
|
|
112
|
-
/**
|
|
113
|
-
private
|
|
113
|
+
/** Optional explicit formatter override for this logger instance */
|
|
114
|
+
private explicitFormatter?;
|
|
114
115
|
/** Context added to every log entry from this logger */
|
|
115
116
|
private defaultContext;
|
|
116
117
|
/**
|
|
@@ -200,6 +201,37 @@ declare class Logger {
|
|
|
200
201
|
private log;
|
|
201
202
|
}
|
|
202
203
|
|
|
204
|
+
/**
|
|
205
|
+
* Interface for obtaining OAuth2 access tokens.
|
|
206
|
+
*
|
|
207
|
+
* Implementations handle token caching and refresh automatically.
|
|
208
|
+
*/
|
|
209
|
+
interface TokenProvider {
|
|
210
|
+
/**
|
|
211
|
+
* Get a valid access token.
|
|
212
|
+
*
|
|
213
|
+
* Returns a cached token if still valid, otherwise fetches a new one.
|
|
214
|
+
*
|
|
215
|
+
* @returns A valid access token string
|
|
216
|
+
* @throws {Error} If token acquisition fails
|
|
217
|
+
*/
|
|
218
|
+
getToken(): Promise<string>;
|
|
219
|
+
/**
|
|
220
|
+
* Invalidate the cached token.
|
|
221
|
+
*
|
|
222
|
+
* Forces the next getToken() call to fetch a fresh token.
|
|
223
|
+
* Should be called when a request fails with 401 Unauthorized.
|
|
224
|
+
*
|
|
225
|
+
* Optional - not all implementations may support invalidation.
|
|
226
|
+
*/
|
|
227
|
+
invalidate?(): void;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* All supported platforms.
|
|
232
|
+
*/
|
|
233
|
+
declare const PLATFORMS: readonly ["BEYOND_AI", "LEARNWITH_AI"];
|
|
234
|
+
|
|
203
235
|
/**
|
|
204
236
|
* Where Clause Types
|
|
205
237
|
*
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
resolveToProvider,
|
|
9
9
|
validateNonEmptyString,
|
|
10
10
|
validateWithSchema
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-89bw8av5.js";
|
|
12
12
|
import"./chunk-6jf1natv.js";
|
|
13
13
|
|
|
14
14
|
// src/constants.ts
|
|
@@ -101,6 +101,13 @@ var StringTimebackGrade = z.string().transform((value, ctx) => {
|
|
|
101
101
|
return z.NEVER;
|
|
102
102
|
}
|
|
103
103
|
const stripped = raw.replace(/\bgrade\b/g, "").replace(/(\d+)(st|nd|rd|th)\b/g, "$1").trim();
|
|
104
|
+
if (stripped === "") {
|
|
105
|
+
ctx.addIssue({
|
|
106
|
+
code: "custom",
|
|
107
|
+
message: "must be a valid Timeback grade"
|
|
108
|
+
});
|
|
109
|
+
return z.NEVER;
|
|
110
|
+
}
|
|
104
111
|
if (stripped === "pre-k" || stripped === "pk") {
|
|
105
112
|
return -1;
|
|
106
113
|
}
|