@timeback/core 0.2.1 → 0.2.2-beta.20260320221119

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/index.d.ts CHANGED
@@ -1,30 +1,1364 @@
1
+ import { CaliperClientInstance } from '@timeback/caliper';
2
+ import { CaseClientInstance } from '@timeback/case';
3
+ import { ClrClientInstance } from '@timeback/clr';
4
+ import { EdubridgeClientInstance } from '@timeback/edubridge';
5
+ import { OneRosterClientInstance } from '@timeback/oneroster';
6
+ import { PowerPathClientInstance } from '@timeback/powerpath';
7
+ import { QtiClientInstance } from '@timeback/qti';
8
+ import { ReportingClientInstance } from '@timeback/reporting';
9
+ import { WebhooksClientInstance } from '@timeback/webhooks';
10
+
11
+ /**
12
+ * Interface for obtaining OAuth2 access tokens.
13
+ *
14
+ * Implementations handle token caching and refresh automatically.
15
+ */
16
+ interface TokenProvider {
17
+ /**
18
+ * Get a valid access token.
19
+ *
20
+ * Returns a cached token if still valid, otherwise fetches a new one.
21
+ *
22
+ * @returns A valid access token string
23
+ * @throws {Error} If token acquisition fails
24
+ */
25
+ getToken(): Promise<string>;
26
+ /**
27
+ * Invalidate the cached token.
28
+ *
29
+ * Forces the next getToken() call to fetch a fresh token.
30
+ * Should be called when a request fails with 401 Unauthorized.
31
+ *
32
+ * Optional - not all implementations may support invalidation.
33
+ */
34
+ invalidate?(): void;
35
+ }
36
+
37
+ /**
38
+ * All supported platforms.
39
+ */
40
+ declare const PLATFORMS$1: readonly ["BEYOND_AI", "LEARNWITH_AI"];
41
+
42
+ /**
43
+ * Where Clause Types
44
+ *
45
+ * Type-safe object syntax for building filter expressions.
46
+ */
47
+ /**
48
+ * Primitive value types that can be used in filters.
49
+ */
50
+ type FilterValue = string | number | boolean | Date;
51
+ /**
52
+ * Operators for a single field.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * { status: { ne: 'deleted' } }
57
+ * { score: { gt: 90 } }
58
+ * { email: { contains: '@school.edu' } }
59
+ * { role: { in: ['teacher', 'aide'] } }
60
+ * ```
61
+ */
62
+ interface FieldOperators<T> {
63
+ /** Not equal */
64
+ ne?: T;
65
+ /** Greater than */
66
+ gt?: T;
67
+ /** Greater than or equal */
68
+ gte?: T;
69
+ /** Less than */
70
+ lt?: T;
71
+ /** Less than or equal */
72
+ lte?: T;
73
+ /** Contains substring (strings only) */
74
+ contains?: T extends string ? string : never;
75
+ /** Match any of the values */
76
+ in?: T[];
77
+ /** Match none of the values */
78
+ notIn?: T[];
79
+ }
80
+ /**
81
+ * A field condition can be:
82
+ * - A direct value (implies equality)
83
+ * - An object with operators
84
+ */
85
+ type FieldCondition<T> = T | FieldOperators<T>;
86
+ /**
87
+ * Map filter field types to field conditions.
88
+ *
89
+ * Each field in F becomes an optional filter condition.
90
+ *
91
+ * @typeParam F - Filter fields type (e.g., UserFilterFields)
92
+ */
93
+ type FilterFields<F> = {
94
+ [K in keyof F]?: FieldCondition<F[K] & FilterValue>;
95
+ };
96
+ /**
97
+ * OR condition for combining multiple field conditions.
98
+ */
99
+ interface OrCondition<F> {
100
+ OR: WhereClause<F>[];
101
+ }
102
+ /**
103
+ * A where clause for filtering entities.
104
+ *
105
+ * The type parameter F should be a filter fields type that defines
106
+ * the available fields and their value types for filtering.
107
+ *
108
+ * Multiple fields at the same level are combined with AND.
109
+ * Use `OR` for explicit OR logic.
110
+ *
111
+ * @typeParam F - Filter fields type (e.g., UserFilterFields)
112
+ *
113
+ * @example
114
+ * ```typescript
115
+ * // Simple equality (implicit AND)
116
+ * { status: 'active', role: 'teacher' }
117
+ * // → status='active' AND role='teacher'
118
+ * ```
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * // With operators
123
+ * { status: { ne: 'deleted' }, score: { gte: 90 } }
124
+ * // → status!='deleted' AND score>=90
125
+ * ```
126
+ *
127
+ * @example
128
+ * ```typescript
129
+ * // OR condition
130
+ * { OR: [{ role: 'teacher' }, { role: 'aide' }] }
131
+ * // → role='teacher' OR role='aide'
132
+ * ```
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * // Match multiple values
137
+ * { role: { in: ['teacher', 'aide'] } }
138
+ * // → role='teacher' OR role='aide'
139
+ * ```
140
+ */
141
+ type WhereClause<F> = FilterFields<F> | OrCondition<F>;
142
+
143
+ /**
144
+ * Where Clause to Filter String Conversion
145
+ *
146
+ * Converts type-safe where clause objects to OneRoster-compatible filter strings.
147
+ */
148
+
149
+ /**
150
+ * Converts a type-safe WhereClause to a OneRoster-compatible filter string.
151
+ *
152
+ * This is the primary function for converting the object-based filter syntax
153
+ * to the string format expected by the OneRoster API.
154
+ *
155
+ * @typeParam T - Entity type being filtered
156
+ * @param where - The where clause object
157
+ * @returns The filter string, or `undefined` if the clause is empty
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * // Simple equality
162
+ * whereToFilter({ status: 'active' })
163
+ * // → "status='active'"
164
+ * ```
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * // Multiple fields (implicit AND)
169
+ * whereToFilter({ status: 'active', role: 'teacher' })
170
+ * // → "status='active' AND role='teacher'"
171
+ * ```
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * // Comparison operators
176
+ * whereToFilter({ score: { gte: 90, lte: 100 } })
177
+ * // → "score>=90 AND score<=100"
178
+ * ```
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * // Not equal
183
+ * whereToFilter({ status: { ne: 'deleted' } })
184
+ * // → "status!='deleted'"
185
+ * ```
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * // Contains (substring match)
190
+ * whereToFilter({ email: { contains: '@school.edu' } })
191
+ * // → "email~'@school.edu'"
192
+ * ```
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // Match any value (OR)
197
+ * whereToFilter({ role: { in: ['teacher', 'aide'] } })
198
+ * // → "role='teacher' OR role='aide'"
199
+ * ```
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * // Explicit OR across fields
204
+ * whereToFilter({ OR: [{ role: 'teacher' }, { status: 'active' }] })
205
+ * // → "role='teacher' OR status='active'"
206
+ * ```
207
+ */
208
+ declare function whereToFilter<T>(where: WhereClause<T>): string | undefined;
209
+
210
+ /**
211
+ * Shared Types
212
+ *
213
+ * Common types for API client infrastructure.
214
+ */
215
+
216
+ /**
217
+ * Result of an auth check operation.
218
+ */
219
+ interface AuthCheckResult$1 {
220
+ /** Whether auth succeeded */
221
+ ok: boolean;
222
+ /** Time taken to complete the check (ms) */
223
+ latencyMs: number;
224
+ /** Error message if failed */
225
+ error?: string;
226
+ /** Detailed check results */
227
+ checks: {
228
+ /** Token acquisition succeeded */
229
+ tokenAcquisition: boolean;
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Config Types
235
+ *
236
+ * Types for TimebackProvider and provider resolution.
237
+ */
238
+
239
+ /**
240
+ * Caliper API path profile.
241
+ * Defines paths for Caliper operations. Use `null` for unsupported operations.
242
+ */
243
+ interface CaliperPaths {
244
+ /** Path for sending events (POST) */
245
+ send: string;
246
+ /** Path for validating events (POST), null if not supported */
247
+ validate: string | null;
248
+ /** Path for listing events (GET), null if not supported */
249
+ list: string | null;
250
+ /** Path template for getting single event (GET), use {id} placeholder */
251
+ get: string | null;
252
+ /** Path template for job status (GET), use {id} placeholder */
253
+ jobStatus: string | null;
254
+ }
255
+ /**
256
+ * Webhook API path profile.
257
+ * Defines paths for webhook management operations.
258
+ * Nullability is at the platform level (`webhooks: WebhookPaths | null` in PlatformPaths).
259
+ */
260
+ interface WebhookPaths {
261
+ /** Path for listing webhooks (GET) */
262
+ webhookList: string;
263
+ /** Path template for getting a single webhook (GET), use {id} placeholder */
264
+ webhookGet: string;
265
+ /** Path for creating a webhook (POST) */
266
+ webhookCreate: string;
267
+ /** Path template for updating a webhook (PUT), use {id} placeholder */
268
+ webhookUpdate: string;
269
+ /** Path template for deleting a webhook (DELETE), use {id} placeholder */
270
+ webhookDelete: string;
271
+ /** Path template for activating a webhook (PUT), use {id} placeholder */
272
+ webhookActivate: string;
273
+ /** Path template for deactivating a webhook (PUT), use {id} placeholder */
274
+ webhookDeactivate: string;
275
+ /** Path for listing all webhook filters (GET) */
276
+ webhookFilterList: string;
277
+ /** Path template for getting a single webhook filter (GET), use {id} placeholder */
278
+ webhookFilterGet: string;
279
+ /** Path for creating a webhook filter (POST) */
280
+ webhookFilterCreate: string;
281
+ /** Path template for updating a webhook filter (PUT), use {id} placeholder */
282
+ webhookFilterUpdate: string;
283
+ /** Path template for deleting a webhook filter (DELETE), use {id} placeholder */
284
+ webhookFilterDelete: string;
285
+ /** Path template for listing filters by webhook (GET), use {webhookId} placeholder */
286
+ webhookFiltersByWebhook: string;
287
+ }
288
+ /**
289
+ * Reporting API path profile.
290
+ * Defines paths for reporting MCP and REST operations.
291
+ * Nullability is at the platform level (`reporting: ReportingPaths | null` in PlatformPaths).
292
+ */
293
+ interface ReportingPaths {
294
+ /** Path for the reporting MCP JSON-RPC endpoint (POST) */
295
+ mcp: string;
296
+ /** Path template for executing a saved query (GET), use {id} placeholder */
297
+ savedQueryExecute: string;
298
+ /** Path template for checking reporting group membership (GET), use {email} placeholder */
299
+ adminGroupCheck: string;
300
+ /** Path template for adding a user to the reporting group (POST), use {email} placeholder */
301
+ adminGroupAdd: string;
302
+ /** Path template for removing a user from the reporting group (DELETE), use {email} placeholder */
303
+ adminGroupRemove: string;
304
+ }
305
+ /**
306
+ * OneRoster API path profile.
307
+ * Defines the base path prefix for all OneRoster resources.
308
+ */
309
+ interface OneRosterPaths {
310
+ /** Base path prefix for rostering resources (users, schools, classes, etc.) */
311
+ rostering: string;
312
+ /** Base path prefix for gradebook resources (lineItems, results, etc.) */
313
+ gradebook: string;
314
+ /** Base path prefix for resources API (digital learning resources) */
315
+ resources: string;
316
+ }
317
+ /**
318
+ * Edubridge API path profile.
319
+ * Defines path prefixes for Edubridge operations.
320
+ */
321
+ interface EdubridgePaths {
322
+ /** Base path prefix for all Edubridge resources */
323
+ base: string;
324
+ }
325
+ /**
326
+ * PowerPath API path profile.
327
+ * Defines path prefixes for PowerPath operations.
328
+ */
329
+ interface PowerPathPaths {
330
+ /** Base path prefix for all PowerPath resources */
331
+ base: string;
332
+ }
333
+ /**
334
+ * CASE API path profile.
335
+ * Defines path prefix for CASE (Competency and Academic Standards Exchange) operations.
336
+ */
337
+ interface CasePaths {
338
+ /** Base path prefix for all CASE resources */
339
+ base: string;
340
+ }
341
+ /**
342
+ * CLR API path profile.
343
+ * Defines path prefixes for CLR (Comprehensive Learner Record) operations.
344
+ */
345
+ interface ClrPaths {
346
+ /** Path for upserting CLR credentials (POST) */
347
+ credentials: string;
348
+ /** Path for API discovery (GET) */
349
+ discovery: string;
350
+ }
351
+ /**
352
+ * Platform path profiles for all services.
353
+ * Use `null` to indicate a service is not supported on the platform.
354
+ */
355
+ interface PlatformPaths {
356
+ caliper: CaliperPaths;
357
+ oneroster: OneRosterPaths;
358
+ webhooks: WebhookPaths | null;
359
+ reporting: ReportingPaths | null;
360
+ edubridge: EdubridgePaths | null;
361
+ powerpath: PowerPathPaths | null;
362
+ clr: ClrPaths | null;
363
+ case: CasePaths | null;
364
+ }
365
+ /**
366
+ * Services that have path configuration.
367
+ * Subset of ServiceName - excludes services without path profiles (e.g., 'qti').
368
+ */
369
+ type PathEnabledService = keyof PlatformPaths;
370
+ /**
371
+ * Supported Timeback platform implementations.
372
+ */
373
+ type Platform$1 = (typeof PLATFORMS$1)[number];
374
+ /**
375
+ * Supported deployment environments.
376
+ */
377
+ type Environment$1 = 'staging' | 'production';
378
+ /**
379
+ * Supported service names.
380
+ */
381
+ type ServiceName = 'oneroster' | 'caliper' | 'webhooks' | 'reporting' | 'edubridge' | 'qti' | 'powerpath' | 'clr' | 'case';
382
+ /**
383
+ * Resolved endpoint for a single service.
384
+ */
385
+ interface ResolvedEndpoint {
386
+ /** Base URL for the service API */
387
+ baseUrl: string;
388
+ /** OAuth2 token URL for this endpoint. Undefined for public/no-auth services. */
389
+ authUrl?: string;
390
+ }
391
+ /**
392
+ * Auth credentials for a provider.
393
+ */
394
+ interface ProviderAuth {
395
+ clientId: string;
396
+ clientSecret: string;
397
+ }
398
+ /**
399
+ * Configuration for environment-based provider.
400
+ * Uses known Timeback platform endpoints.
401
+ */
402
+ interface ProviderEnvConfig {
403
+ /** Timeback platform (defaults to 'BEYOND_AI') */
404
+ platform?: Platform$1;
405
+ /** Target environment */
406
+ env: Environment$1;
407
+ /** OAuth2 credentials */
408
+ auth: ProviderAuth;
409
+ /** Request timeout in milliseconds */
410
+ timeout?: number;
411
+ }
412
+ /**
413
+ * Configuration for explicit URL provider.
414
+ * Single base URL for all services.
415
+ */
416
+ interface ProviderExplicitConfig {
417
+ /** Base URL for all services */
418
+ baseUrl: string;
419
+ /** OAuth2 token URL. Omit for public/no-auth services. */
420
+ authUrl?: string;
421
+ /** OAuth2 credentials. Required if authUrl is provided. */
422
+ auth?: ProviderAuth;
423
+ /** Request timeout in milliseconds */
424
+ timeout?: number;
425
+ /**
426
+ * Use a built-in path profile by name.
427
+ * Defaults to 'BEYOND_AI' if neither pathProfile nor paths is specified.
428
+ */
429
+ pathProfile?: Platform$1;
430
+ /** Custom path overrides (takes precedence over pathProfile) */
431
+ paths?: Partial<PlatformPaths>;
432
+ }
433
+ /**
434
+ * Configuration for multi-service provider.
435
+ * Different URLs for different services.
436
+ */
437
+ interface ProviderServicesConfig {
438
+ /** Per-service base URLs */
439
+ services: Partial<Record<ServiceName, string>>;
440
+ /** OAuth2 token URL. Omit for public/no-auth services. */
441
+ authUrl?: string;
442
+ /** OAuth2 credentials. Required if authUrl is provided. */
443
+ auth?: ProviderAuth;
444
+ /** Request timeout in milliseconds */
445
+ timeout?: number;
446
+ /**
447
+ * Use a built-in path profile by name.
448
+ * Defaults to 'BEYOND_AI' if neither pathProfile nor paths is specified.
449
+ */
450
+ pathProfile?: Platform$1;
451
+ /** Custom path overrides (takes precedence over pathProfile) */
452
+ paths?: Partial<PlatformPaths>;
453
+ }
454
+ /**
455
+ * Union of all provider configuration types.
456
+ */
457
+ type TimebackProviderConfig = ProviderEnvConfig | ProviderExplicitConfig | ProviderServicesConfig;
458
+
459
+ /**
460
+ * Timeback Provider
461
+ *
462
+ * Encapsulates platform connection configuration including endpoints and auth.
463
+ * Providers are complete "connection" objects that clients consume.
464
+ */
465
+
466
+ /**
467
+ * Timeback Provider - encapsulates a complete platform connection.
468
+ *
469
+ * A provider contains everything needed to connect to Timeback APIs:
470
+ * - Service endpoints (URLs)
471
+ * - Authentication credentials
472
+ * - Configuration options
473
+ *
474
+ * Providers can be created from:
475
+ * - Platform + environment (uses known Timeback endpoints)
476
+ * - Explicit base URL (single URL for all services)
477
+ * - Per-service URLs (different URLs for each service)
478
+ *
479
+ * @example
480
+ * ```typescript
481
+ * // Environment-based provider (Timeback hosted)
482
+ * const provider = new TimebackProvider({
483
+ * platform: 'BEYOND_AI',
484
+ * env: 'staging',
485
+ * auth: { clientId: '...', clientSecret: '...' },
486
+ * })
487
+ * ```
488
+ *
489
+ * @example
490
+ * ```typescript
491
+ * // Explicit URL provider (self-hosted)
492
+ * const provider = new TimebackProvider({
493
+ * baseUrl: 'https://api.myschool.edu',
494
+ * authUrl: 'https://auth.myschool.edu/oauth/token',
495
+ * auth: { clientId: '...', clientSecret: '...' },
496
+ * })
497
+ * ```
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * // Per-service URLs
502
+ * const provider = new TimebackProvider({
503
+ * services: {
504
+ * oneroster: 'https://roster.myschool.edu',
505
+ * caliper: 'https://analytics.myschool.edu',
506
+ * },
507
+ * authUrl: 'https://auth.myschool.edu/oauth/token',
508
+ * auth: { clientId: '...', clientSecret: '...' },
509
+ * })
510
+ * ```
511
+ */
512
+ declare class TimebackProvider {
513
+ /** Platform identifier (if using known platform) */
514
+ readonly platform?: Platform$1;
515
+ /** Environment (if using known platform) */
516
+ readonly env?: Environment$1;
517
+ /** OAuth2 credentials. Undefined for public/no-auth services. */
518
+ readonly auth?: ProviderAuth;
519
+ /** Request timeout in milliseconds */
520
+ readonly timeout: number;
521
+ /** Resolved endpoints for each service */
522
+ /** @internal */
523
+ readonly _endpoints: Partial<Record<ServiceName, ResolvedEndpoint>>;
524
+ /** Token URL for authentication. Undefined for public/no-auth services. */
525
+ /** @internal */
526
+ readonly _authUrl?: string;
527
+ /** OAuth2 scope to request with access tokens. */
528
+ /** @internal */
529
+ readonly _tokenScope?: string;
530
+ /** API path profiles for this platform */
531
+ /** @internal */
532
+ readonly _pathProfiles: PlatformPaths;
533
+ /** Cached TokenManagers by authUrl (for token sharing) */
534
+ /** @internal */
535
+ readonly _tokenManagers: Map<string, TokenProvider>;
536
+ /**
537
+ * Create a new TimebackProvider.
538
+ *
539
+ * @param config - Provider configuration (env-based, explicit URL, or per-service)
540
+ * @throws {Error} If configuration is invalid or missing required fields
541
+ */
542
+ constructor(config: TimebackProviderConfig);
543
+ /**
544
+ * Get the resolved endpoint for a specific service.
545
+ *
546
+ * @param service - Service name (oneroster, caliper, edubridge, qti, powerpath)
547
+ * @returns Resolved endpoint with baseUrl and authUrl
548
+ * @throws If the service is not configured in this provider
549
+ */
550
+ getEndpoint(service: ServiceName): ResolvedEndpoint;
551
+ /**
552
+ * Check if a service is available in this provider.
553
+ *
554
+ * @param service - Service name to check
555
+ * @returns True if the service is configured
556
+ */
557
+ hasService(service: ServiceName): boolean;
558
+ /**
559
+ * Get all configured service names.
560
+ *
561
+ * @returns Array of service names available in this provider
562
+ */
563
+ getAvailableServices(): ServiceName[];
564
+ /**
565
+ * Get the token URL for this provider.
566
+ * @returns The token URL for authentication
567
+ */
568
+ getTokenUrl(): string | undefined;
569
+ /**
570
+ * Get endpoint with paths for a service that has path configuration.
571
+ *
572
+ * @param service - Service name that has paths in PlatformPaths
573
+ * @returns Resolved endpoint with baseUrl, authUrl, and paths
574
+ * @throws If service is not configured or not supported on this platform
575
+ */
576
+ getEndpointWithPaths<S extends PathEnabledService>(service: S & ServiceName): ResolvedEndpoint & {
577
+ paths: NonNullable<PlatformPaths[S]>;
578
+ };
579
+ /**
580
+ * Get all path profiles for this provider (raw, may contain nulls).
581
+ *
582
+ * @returns Platform path profiles
583
+ */
584
+ getPaths(): PlatformPaths;
585
+ /**
586
+ * Get paths for a specific service.
587
+ *
588
+ * @param service - Service name
589
+ * @returns Path configuration for the service
590
+ * @throws If the service is not supported on this platform
591
+ */
592
+ getServicePaths<S extends PathEnabledService>(service: S): NonNullable<PlatformPaths[S]>;
593
+ /**
594
+ * Check if a service is supported on this platform.
595
+ *
596
+ * @param service - Service name
597
+ * @returns true if the service has path configuration
598
+ */
599
+ hasServiceSupport(service: PathEnabledService): boolean;
600
+ /**
601
+ * Get a TokenProvider for a specific service.
602
+ *
603
+ * TokenProviders are cached by authUrl, so services sharing the same
604
+ * token endpoint will share the same cached OAuth tokens.
605
+ *
606
+ * @param service - Service name (oneroster, caliper, edubridge, qti, powerpath)
607
+ * @returns Cached TokenProvider for the service's token endpoint, or undefined for public/no-auth services
608
+ * @throws If the service is not configured in this provider
609
+ * @throws If auth is required but not configured
610
+ */
611
+ getTokenProvider(service: ServiceName): TokenProvider | undefined;
612
+ /**
613
+ * Verify that OAuth authentication is working.
614
+ *
615
+ * Attempts to acquire a token using the provider's credentials.
616
+ * Returns a health check result with success/failure and latency info.
617
+ *
618
+ * @returns Auth check result
619
+ * @throws {Error} If no auth is configured on this provider
620
+ */
621
+ checkAuth(): Promise<AuthCheckResult$1>;
622
+ /**
623
+ * Invalidate all cached OAuth tokens.
624
+ *
625
+ * Call this when closing the client or when tokens need to be refreshed.
626
+ * New tokens will be acquired on the next API call.
627
+ */
628
+ invalidateTokens(): void;
629
+ }
630
+
631
+ /**
632
+ * Transport Types
633
+ *
634
+ * Types for HTTP transport layer.
635
+ */
636
+
637
+ /**
638
+ * Result of an auth check operation.
639
+ */
640
+ interface AuthCheckResult {
641
+ /** Whether auth succeeded */
642
+ ok: boolean;
643
+ /** Time taken to complete the check (ms) */
644
+ latencyMs: number;
645
+ /** Error message if failed */
646
+ error?: string;
647
+ /** Detailed check results */
648
+ checks: {
649
+ /** Token acquisition succeeded */
650
+ tokenAcquisition: boolean;
651
+ };
652
+ }
653
+
654
+ /**
655
+ * API Error Classes
656
+ *
657
+ * Base error classes for HTTP API failures.
658
+ * Includes IMS Global error response parsing (OneRoster, QTI, etc.).
659
+ */
660
+
661
+ /**
662
+ * Base error class for all API errors.
663
+ *
664
+ * Provides access to the HTTP status code and raw response body.
665
+ * Includes IMS Global error parsing (minorCodes, details) for
666
+ * IMS-standard APIs like OneRoster and QTI.
667
+ *
668
+ * @example
669
+ * ```typescript
670
+ * // Catching and inspecting errors
671
+ * try {
672
+ * await client.users.get('non-existent-id')
673
+ * } catch (error) {
674
+ * if (error instanceof ApiError) {
675
+ * console.log(`Error ${error.statusCode}: ${error.message}`)
676
+ * console.log('Minor codes:', error.minorCodes)
677
+ * console.log('Details:', error.details)
678
+ * }
679
+ * }
680
+ * ```
681
+ */
682
+ declare class ApiError extends Error {
683
+ readonly statusCode?: number | undefined;
684
+ readonly response?: unknown;
685
+ readonly name: string;
686
+ /**
687
+ * Creates a new ApiError.
688
+ *
689
+ * @param message - Human-readable error message
690
+ * @param statusCode - HTTP status code
691
+ * @param response - Raw response body (if available)
692
+ */
693
+ constructor(message: string, statusCode?: number | undefined, response?: unknown);
694
+ /**
695
+ * Minor error codes from IMS Global error response.
696
+ *
697
+ * For IMS-standard APIs (OneRoster, QTI), provides specific error codes
698
+ * like "unknownobject" or "invaliddata".
699
+ *
700
+ * @returns Array of field/value pairs, or empty array if not IMS format
701
+ */
702
+ get minorCodes(): Array<{
703
+ field: string;
704
+ value: string;
705
+ }>;
706
+ /**
707
+ * Additional error details from IMS Global response.
708
+ *
709
+ * May contain field-level validation errors or other structured details.
710
+ *
711
+ * @returns Array of key-value objects, or empty array if not present
712
+ */
713
+ get details(): Array<Record<string, string>>;
714
+ }
715
+ /**
716
+ * Error thrown when authentication fails (HTTP 401).
717
+ *
718
+ * Typically indicates invalid or expired credentials.
719
+ */
720
+ declare class UnauthorizedError extends ApiError {
721
+ readonly name = "UnauthorizedError";
722
+ constructor(message?: string, response?: unknown);
723
+ }
724
+ /**
725
+ * Error thrown when the client lacks permission for the operation (HTTP 403).
726
+ *
727
+ * The credentials are valid, but the client is not authorized for this action.
728
+ */
729
+ declare class ForbiddenError extends ApiError {
730
+ readonly name = "ForbiddenError";
731
+ constructor(message?: string, response?: unknown);
732
+ }
733
+ /**
734
+ * Error thrown when a requested resource is not found (HTTP 404).
735
+ */
736
+ declare class NotFoundError extends ApiError {
737
+ readonly name = "NotFoundError";
738
+ constructor(message?: string, response?: unknown);
739
+ }
740
+ /**
741
+ * Error thrown when request data is invalid (HTTP 422).
742
+ *
743
+ * Check the `details` property for field-level validation errors.
744
+ */
745
+ declare class ValidationError extends ApiError {
746
+ readonly name = "ValidationError";
747
+ constructor(message?: string, response?: unknown);
748
+ }
749
+ /**
750
+ * Type guard to check if an error is an ApiError.
751
+ *
752
+ * Uses duck typing to work across module boundaries where `instanceof`
753
+ * may fail due to multiple package copies.
754
+ * @param error - The error to check
755
+ * @returns True if error is an ApiError
756
+ */
757
+ declare function isApiError(error: unknown): error is ApiError;
758
+
759
+ /**
760
+ * All supported platforms.
761
+ */
762
+ declare const PLATFORMS: readonly ["BEYOND_AI", "LEARNWITH_AI"];
763
+
764
+ /**
765
+ * Timeback Core Types
766
+ *
767
+ * Configuration types for the unified Timeback client,
768
+ * plus re-exports of entity types from all services.
769
+ *
770
+ * @example
771
+ * ```typescript
772
+ * import type { User, School, Organization } from '@timeback/core/types'
773
+ * ```
774
+ */
775
+
776
+ /**
777
+ * Supported Timeback platform implementations.
778
+ * Derived from the PLATFORMS constant.
779
+ */
780
+ type Platform = (typeof PLATFORMS)[number];
781
+ /**
782
+ * Timeback deployment environment.
783
+ */
784
+ type Environment = 'staging' | 'production';
785
+ /**
786
+ * Resolved service URLs for environment mode.
787
+ * @internal
788
+ */
789
+ interface EnvServiceUrls {
790
+ oneroster: string;
791
+ caliper: string;
792
+ webhooks: string;
793
+ edubridge: string;
794
+ qti: string;
795
+ powerpath?: string;
796
+ authUrl: string;
797
+ }
798
+ /**
799
+ * OAuth2 client credentials for environment mode.
800
+ * Token URL is derived from the environment.
801
+ */
802
+ interface EnvAuthCredentials {
803
+ clientId: string;
804
+ clientSecret: string;
805
+ }
806
+ /**
807
+ * OAuth2 client credentials with explicit token URL.
808
+ * Required when using baseUrl or services mode.
809
+ */
810
+ interface ExplicitAuthCredentials {
811
+ clientId: string;
812
+ clientSecret: string;
813
+ authUrl: string;
814
+ }
815
+ /**
816
+ * Service endpoint configuration.
817
+ * Can be a simple URL string or an object with baseUrl and optional authUrl override.
818
+ */
819
+ type ServiceEndpoint = string | {
820
+ baseUrl: string;
821
+ authUrl?: string;
822
+ };
823
+ /**
824
+ * Explicit URLs for each service.
825
+ * All fields optional — only configure services you need.
826
+ */
827
+ interface ServiceUrls {
828
+ /** OneRoster API endpoint */
829
+ oneroster?: ServiceEndpoint;
830
+ /** Caliper API endpoint */
831
+ caliper?: ServiceEndpoint;
832
+ /** Webhooks API endpoint */
833
+ webhooks?: ServiceEndpoint;
834
+ /** Edubridge API endpoint */
835
+ edubridge?: ServiceEndpoint;
836
+ /** QTI API endpoint */
837
+ qti?: ServiceEndpoint;
838
+ /** PowerPath API endpoint */
839
+ powerpath?: ServiceEndpoint;
840
+ }
841
+ /**
842
+ * Environment mode: URLs derived from platform and environment.
843
+ *
844
+ * @example
845
+ * ```typescript
846
+ * // BeyondAI platform (default)
847
+ * const client = new TimebackClient({
848
+ * env: 'staging',
849
+ * auth: { clientId: '...', clientSecret: '...' },
850
+ * })
851
+ *
852
+ * // LearnWith.AI platform
853
+ * const client = new TimebackClient({
854
+ * platform: 'LEARNWITH_AI',
855
+ * env: 'production',
856
+ * auth: { clientId: '...', clientSecret: '...' },
857
+ * })
858
+ * ```
859
+ */
860
+ interface EnvConfig {
861
+ platform?: Platform;
862
+ env: Environment;
863
+ auth?: Partial<EnvAuthCredentials>;
864
+ timeout?: number;
865
+ }
866
+ /**
867
+ * Base URL mode: Single base URL, service paths derived automatically.
868
+ *
869
+ * @example
870
+ * ```typescript
871
+ * const client = new TimebackClient({
872
+ * baseUrl: 'https://timeback.myschool.edu',
873
+ * auth: {
874
+ * clientId: '...',
875
+ * clientSecret: '...',
876
+ * authUrl: 'https://timeback.myschool.edu/oauth/token',
877
+ * },
878
+ * })
879
+ * ```
880
+ */
881
+ interface BaseUrlConfig {
882
+ baseUrl: string;
883
+ auth: ExplicitAuthCredentials;
884
+ timeout?: number;
885
+ }
886
+ /**
887
+ * Explicit services mode: Full control over each service URL.
888
+ *
889
+ * @example
890
+ * ```typescript
891
+ * const client = new TimebackClient({
892
+ * services: {
893
+ * oneroster: 'https://roster.example.com/v1p2',
894
+ * caliper: 'https://analytics.example.com/caliper',
895
+ * edubridge: 'https://api.example.com/edubridge',
896
+ * qti: 'https://qti.example.com/api',
897
+ * },
898
+ * auth: {
899
+ * clientId: '...',
900
+ * clientSecret: '...',
901
+ * authUrl: 'https://auth.example.com/oauth/token',
902
+ * },
903
+ * })
904
+ * ```
905
+ */
906
+ interface ServicesConfig {
907
+ services: ServiceUrls;
908
+ auth: ExplicitAuthCredentials;
909
+ timeout?: number;
910
+ }
911
+ /**
912
+ * Provider mode: use a pre-built TimebackProvider.
913
+ *
914
+ * @example
915
+ * ```typescript
916
+ * import { TimebackProvider } from '@timeback/core'
917
+ *
918
+ * const provider = new TimebackProvider({
919
+ * platform: 'BEYOND_AI',
920
+ * env: 'staging',
921
+ * auth: { clientId: '...', clientSecret: '...' },
922
+ * })
923
+ *
924
+ * const client = new TimebackClient({ provider })
925
+ * ```
926
+ */
927
+ interface ProviderConfig {
928
+ provider: TimebackProvider;
929
+ }
930
+ /**
931
+ * Configuration for the unified Timeback client.
932
+ *
933
+ * Supports four modes:
934
+ * - **Provider**: `{ provider: TimebackProvider }` — pre-built provider
935
+ * - **Environment**: `{ env: 'staging' | 'production', auth: {...} }`
936
+ * - **Base URL**: `{ baseUrl: '...', auth: {..., authUrl: '...' } }`
937
+ * - **Explicit services**: `{ services: {...}, auth: {..., authUrl: '...' } }`
938
+ */
939
+ type TimebackClientConfig = ProviderConfig | EnvConfig | BaseUrlConfig | ServicesConfig;
940
+ /**
941
+ * Result of a broadcast operation for a single client.
942
+ * Similar to PromiseSettledResult but with simpler `ok` boolean.
943
+ */
944
+ type BroadcastResult<T> = {
945
+ ok: true;
946
+ value: T;
947
+ } | {
948
+ ok: false;
949
+ error: Error;
950
+ };
951
+ /**
952
+ * Convenience methods available on broadcast results.
953
+ *
954
+ * @typeParam T - The value type returned by successful operations
955
+ * @typeParam TNames - Union of client names (for typed tuples)
956
+ */
957
+ interface BroadcastResultMethods<T, TNames extends string = string> {
958
+ /** Get all successful results as [name, value] tuples */
959
+ readonly succeeded: Array<[TNames, T]>;
960
+ /** Get all failed results as [name, error] tuples */
961
+ readonly failed: Array<[TNames, Error]>;
962
+ /** True if all operations succeeded */
963
+ readonly allSucceeded: boolean;
964
+ /** True if any operation failed */
965
+ readonly anyFailed: boolean;
966
+ /** Get all successful values (throws if any failed) */
967
+ values(): T[];
968
+ }
969
+ /**
970
+ * Broadcast results with both direct property access and convenience methods.
971
+ *
972
+ * Access results directly by name or use helper methods:
973
+ *
974
+ * @typeParam T - The value type returned by successful operations
975
+ * @typeParam TNames - Union of client names (enables autocomplete)
976
+ *
977
+ * @example
978
+ * ```typescript
979
+ * const results = await manager.broadcast(c => c.oneroster.users.create(user))
980
+ *
981
+ * // Direct access (like a plain object):
982
+ * results.alpha.ok
983
+ * results['beta'].error
984
+ *
985
+ * // Convenience methods:
986
+ * if (results.allSucceeded) {
987
+ * console.log('All platforms synced!')
988
+ * }
989
+ *
990
+ * results.succeeded.forEach(([name, user]) => {
991
+ * console.log(`Created on ${name}:`, user.id)
992
+ * })
993
+ *
994
+ * results.failed.forEach(([name, error]) => {
995
+ * console.error(`Failed on ${name}:`, error.message)
996
+ * })
997
+ * ```
998
+ */
999
+ type BroadcastResults<T, TNames extends string = string> = {
1000
+ [K in TNames]: BroadcastResult<T>;
1001
+ } & BroadcastResultMethods<T, TNames>;
1002
+
1003
+ /**
1004
+ * Timeback Client
1005
+ *
1006
+ * Unified client for all Timeback education APIs.
1007
+ */
1
1008
  /**
2
1009
  * Unified client for Timeback education APIs.
3
1010
  *
1011
+ * Provides access to all Timeback APIs with shared authentication:
1012
+ * - **OneRoster**: Rostering and gradebook data
1013
+ * - **Edubridge**: Simplified enrollments and analytics
1014
+ * - **Caliper**: Learning analytics events
1015
+ * - **Reporting**: Ad-hoc queries and saved reporting endpoints
1016
+ * - **QTI**: Assessment content management
1017
+ * - **PowerPath**: Placement tests, lesson plans, and assessments
1018
+ * - **CLR**: Comprehensive Learner Record credentials
1019
+ * - **CASE**: Competency and Academic Standards Exchange
1020
+ *
1021
+ * All sub-clients share a single OAuth token, reducing auth requests.
1022
+ *
4
1023
  * @example
5
1024
  * ```typescript
6
- * import { TimebackClient } from '@timeback/core'
1025
+ * // Environment mode
1026
+ * const timeback = new TimebackClient({
1027
+ * env: 'staging',
1028
+ * auth: { clientId: '...', clientSecret: '...' },
1029
+ * })
1030
+ * ```
7
1031
  *
1032
+ * @example
1033
+ * ```typescript
1034
+ * // Platform selection
8
1035
  * const timeback = new TimebackClient({
1036
+ * platform: 'LEARNWITH_AI',
1037
+ * env: 'production',
1038
+ * auth: { clientId: '...', clientSecret: '...' },
1039
+ * })
1040
+ * ```
1041
+ *
1042
+ * @example
1043
+ * ```typescript
1044
+ * // Provider mode (pre-built provider)
1045
+ * import { TimebackProvider } from '@timeback/core'
1046
+ *
1047
+ * const provider = new TimebackProvider({
1048
+ * platform: 'BEYOND_AI',
9
1049
  * env: 'staging',
1050
+ * auth: { clientId: '...', clientSecret: '...' },
1051
+ * })
1052
+ *
1053
+ * const timeback = new TimebackClient({ provider })
1054
+ * ```
1055
+ *
1056
+ * @example
1057
+ * ```typescript
1058
+ * // Base URL mode (self-hosted)
1059
+ * const timeback = new TimebackClient({
1060
+ * baseUrl: 'https://timeback.myschool.edu',
10
1061
  * auth: {
11
- * clientId: process.env.CLIENT_ID,
12
- * clientSecret: process.env.CLIENT_SECRET,
1062
+ * clientId: '...',
1063
+ * clientSecret: '...',
1064
+ * authUrl: 'https://timeback.myschool.edu/oauth/token',
13
1065
  * },
14
1066
  * })
1067
+ * ```
1068
+ */
1069
+ declare class TimebackClient {
1070
+ private readonly provider;
1071
+ private _closed;
1072
+ private _oneroster?;
1073
+ private _edubridge?;
1074
+ private _caliper?;
1075
+ private _qti?;
1076
+ private _powerpath?;
1077
+ private _clr?;
1078
+ private _case?;
1079
+ private _reporting?;
1080
+ private _webhooks?;
1081
+ /**
1082
+ * Creates a new Timeback client.
1083
+ *
1084
+ * @param config - Client configuration (env, baseUrl, provider, or services mode).
1085
+ * If omitted, reads from TIMEBACK_ENV, TIMEBACK_CLIENT_ID,
1086
+ * and TIMEBACK_CLIENT_SECRET environment variables.
1087
+ */
1088
+ constructor(config?: TimebackClientConfig);
1089
+ /**
1090
+ * OneRoster API client for rostering and gradebook operations.
1091
+ *
1092
+ * Lazily initialized on first access. Shares OAuth tokens with other
1093
+ * sub-clients through the provider.
1094
+ *
1095
+ * @returns The OneRoster client instance
1096
+ * @throws {Error} If client has been closed or service not configured
1097
+ */
1098
+ get oneroster(): OneRosterClientInstance;
1099
+ /**
1100
+ * Edubridge API client for simplified enrollments and analytics.
1101
+ *
1102
+ * Lazily initialized on first access. Shares OAuth tokens with other
1103
+ * sub-clients through the provider.
1104
+ *
1105
+ * @returns The Edubridge client instance
1106
+ * @throws {Error} If client has been closed or service not configured
1107
+ */
1108
+ get edubridge(): EdubridgeClientInstance;
1109
+ /**
1110
+ * Caliper API client for learning analytics events.
1111
+ *
1112
+ * Lazily initialized on first access. Shares OAuth tokens with other
1113
+ * sub-clients through the provider.
1114
+ *
1115
+ * @returns The Caliper client instance
1116
+ * @throws {Error} If client has been closed or service not configured
1117
+ */
1118
+ get caliper(): CaliperClientInstance;
1119
+ /**
1120
+ * QTI API client for assessment content management.
1121
+ *
1122
+ * Lazily initialized on first access. Shares OAuth tokens with other
1123
+ * sub-clients through the provider.
1124
+ *
1125
+ * @returns The QTI client instance
1126
+ * @throws {Error} If client has been closed or service not configured
1127
+ */
1128
+ get qti(): QtiClientInstance;
1129
+ /**
1130
+ * PowerPath API client for placement tests and lesson plans.
1131
+ *
1132
+ * Lazily initialized on first access. Shares OAuth tokens with other
1133
+ * sub-clients through the provider.
1134
+ *
1135
+ * @returns The PowerPath client instance
1136
+ * @throws {Error} If client has been closed or service not configured
1137
+ */
1138
+ get powerpath(): PowerPathClientInstance;
1139
+ /**
1140
+ * CLR API client for Comprehensive Learner Record credentials.
1141
+ *
1142
+ * Lazily initialized on first access. Shares OAuth tokens with other
1143
+ * sub-clients through the provider.
1144
+ *
1145
+ * @returns The CLR client instance
1146
+ * @throws {Error} If client has been closed or service not configured
1147
+ */
1148
+ get clr(): ClrClientInstance;
1149
+ /**
1150
+ * CASE API client for Competency and Academic Standards Exchange.
1151
+ *
1152
+ * Lazily initialized on first access. Shares OAuth tokens with other
1153
+ * sub-clients through the provider.
1154
+ *
1155
+ * @returns The CASE client instance
1156
+ * @throws {Error} If client has been closed or service not configured
1157
+ */
1158
+ get case(): CaseClientInstance;
1159
+ /**
1160
+ * Reporting API client for reporting queries and saved reporting endpoints.
1161
+ *
1162
+ * Lazily initialized on first access. Shares OAuth tokens with other
1163
+ * sub-clients through the provider.
1164
+ *
1165
+ * @returns The Reporting client instance
1166
+ * @throws {Error} If client has been closed or service not configured
1167
+ */
1168
+ get reporting(): ReportingClientInstance;
1169
+ /**
1170
+ * Webhooks API client for managing webhook registrations and filters.
1171
+ *
1172
+ * Lazily initialized on first access. Shares OAuth tokens with other
1173
+ * sub-clients through the provider.
1174
+ *
1175
+ * @returns The Webhooks client instance
1176
+ * @throws {Error} If client has been closed or service not configured
1177
+ */
1178
+ get webhooks(): WebhooksClientInstance;
1179
+ /**
1180
+ * Verify that OAuth authentication is working.
1181
+ *
1182
+ * Attempts to acquire a token using the provider's credentials.
1183
+ * Returns a health check result with success/failure and latency info.
1184
+ *
1185
+ * @returns Auth check result
1186
+ * @throws {Error} If client has been closed
1187
+ */
1188
+ checkAuth(): Promise<AuthCheckResult>;
1189
+ /**
1190
+ * Close the client and release resources.
1191
+ *
1192
+ * After calling close():
1193
+ * - Cached OAuth tokens are invalidated
1194
+ * - Sub-client references are cleared
1195
+ * - Further API calls will throw an error
1196
+ */
1197
+ close(): void;
1198
+ /**
1199
+ * Check if the client has been closed.
1200
+ * @returns True if closed
1201
+ */
1202
+ get closed(): boolean;
1203
+ /**
1204
+ * Get the underlying provider for advanced use cases.
1205
+ *
1206
+ * @returns The TimebackProvider instance used by this client
1207
+ */
1208
+ getProvider(): TimebackProvider;
1209
+ /**
1210
+ * Throw if the client has been closed.
1211
+ */
1212
+ private assertOpen;
1213
+ /**
1214
+ * Throw if a service is not configured.
1215
+ * @param service - Service name to check
1216
+ */
1217
+ private assertService;
1218
+ }
1219
+
1220
+ /**
1221
+ * Timeback Manager
15
1222
  *
16
- * for await (const school of timeback.oneroster.schools.list()) {
17
- * console.log(school.name)
18
- * }
1223
+ * Orchestration layer for managing multiple TimebackClient instances.
1224
+ * Enables operations across multiple clients from a single interface.
1225
+ */
1226
+
1227
+ /**
1228
+ * Manages multiple TimebackClient instances.
1229
+ *
1230
+ * Use this when you need to:
1231
+ * - Manage multiple clients with different configurations
1232
+ * - Fan-out requests to multiple clients simultaneously
1233
+ * - Aggregate data from multiple sources
1234
+ *
1235
+ * The manager tracks registered client names at the type level,
1236
+ * providing autocomplete for `get()` and `has()`.
1237
+ *
1238
+ * @typeParam TNames - Union of registered client names (tracked automatically)
1239
+ *
1240
+ * @example
1241
+ * ```typescript
1242
+ * const manager = new TimebackManager()
1243
+ * .register('alpha', { env: 'production', auth: { ... } })
1244
+ * .register('beta', { env: 'production', auth: { ... } })
1245
+ *
1246
+ * // Autocomplete suggests 'alpha' | 'beta'
1247
+ * const users = await manager.get('alpha').oneroster.users.list()
1248
+ *
1249
+ * // Fan-out to all clients
1250
+ * const results = await manager.broadcast(client => client.oneroster.users.create(user))
1251
+ * // { alpha: { ok: true, value: {...} }, beta: { ok: true, value: {...} } }
19
1252
  * ```
20
1253
  */
21
- export { TimebackClient } from './client';
22
- export { TimebackManager } from './manager';
23
- export type { BroadcastResult, BroadcastResultMethods, BroadcastResults } from './types/index';
24
- export { ApiError, ForbiddenError, isApiError, NotFoundError, UnauthorizedError, ValidationError, } from '@timeback/internal-client-infra';
25
- export { whereToFilter } from '@timeback/internal-client-infra';
26
- export type { FieldCondition, FieldOperators, FilterValue, OrCondition, WhereClause, } from '@timeback/internal-client-infra';
27
- export { getServiceUrlsForEnv } from './constants';
28
- export type { Environment, EnvServiceUrls, TimebackClientConfig } from './types/index';
29
- export type { AuthCheckResult } from '@timeback/internal-client-infra';
30
- //# sourceMappingURL=index.d.ts.map
1254
+ declare class TimebackManager<TNames extends string = never> {
1255
+ private readonly clients;
1256
+ /**
1257
+ * Register a new client with a given name.
1258
+ *
1259
+ * Returns a new manager type that includes the registered name,
1260
+ * enabling autocomplete for `get()`.
1261
+ *
1262
+ * @param {string} name - Unique identifier for this client
1263
+ * @param {TimebackClientConfig} config - Configuration for the TimebackClient
1264
+ * @returns {TimebackManager<TNames | N>} - A new manager type that includes the registered name, enabling autocomplete for `get()`
1265
+ * @throws {Error} If a client with this name is already registered
1266
+ */
1267
+ register<N extends string>(name: N, config: TimebackClientConfig): TimebackManager<TNames | N>;
1268
+ /**
1269
+ * Get a registered client by name.
1270
+ *
1271
+ * @param name - The name used when registering the client (autocomplete enabled)
1272
+ * @returns The TimebackClient instance
1273
+ * @throws {Error} If no client with this name is registered
1274
+ *
1275
+ * @example
1276
+ * ```typescript
1277
+ * const client = manager.get('alpha') // autocomplete suggests registered names
1278
+ * const schools = await client.oneroster.schools.list()
1279
+ * ```
1280
+ */
1281
+ get(name: TNames): TimebackClient;
1282
+ /**
1283
+ * Check if a client with the given name is registered.
1284
+ *
1285
+ * Accepts any string since it's a runtime check.
1286
+ * Returns true only for registered names.
1287
+ *
1288
+ * @param name - The name to check
1289
+ * @returns True if registered
1290
+ */
1291
+ has(name: string): name is TNames;
1292
+ /**
1293
+ * Get all registered client names.
1294
+ * @returns Array of registered client names
1295
+ */
1296
+ get names(): string[];
1297
+ /**
1298
+ * Get the number of registered clients.
1299
+ * @returns Number of registered clients
1300
+ */
1301
+ get size(): number;
1302
+ /**
1303
+ * Execute a function on all registered clients.
1304
+ *
1305
+ * Uses `Promise.allSettled` semantics — always completes, never throws.
1306
+ * Each result indicates success or failure per client.
1307
+ *
1308
+ * All operations run in parallel.
1309
+ *
1310
+ * @param fn - Function to execute on each client (name is typed)
1311
+ * @returns BroadcastResults with typed property access and convenience methods
1312
+ *
1313
+ * @example
1314
+ * ```typescript
1315
+ * const results = await manager.broadcast(c => c.oneroster.users.create(user))
1316
+ *
1317
+ * // Typed property access (autocomplete works)
1318
+ * results.alpha.ok
1319
+ *
1320
+ * if (results.allSucceeded) {
1321
+ * console.log('Synced to all platforms!')
1322
+ * }
1323
+ *
1324
+ * results.succeeded.forEach(([name, user]) => {
1325
+ * console.log(`Created on ${name}:`, user.id)
1326
+ * })
1327
+ * ```
1328
+ */
1329
+ broadcast<T>(fn: (client: TimebackClient, name: TNames) => T | Promise<T>): Promise<BroadcastResults<T, TNames>>;
1330
+ /**
1331
+ * Unregister and close a client.
1332
+ *
1333
+ * Note: This doesn't update the type — use a new manager if you need
1334
+ * type-safe tracking after unregistration.
1335
+ *
1336
+ * @param name - The name of the client to remove
1337
+ * @returns true if the client was removed, false if it didn't exist
1338
+ */
1339
+ unregister(name: TNames): boolean;
1340
+ /**
1341
+ * Close all registered clients and clear the registry.
1342
+ *
1343
+ * Call this during application shutdown to release resources.
1344
+ */
1345
+ close(): void;
1346
+ }
1347
+
1348
+ /**
1349
+ * Timeback API Endpoints
1350
+ *
1351
+ * Re-exports URL constants from the internal constants package.
1352
+ */
1353
+
1354
+ /**
1355
+ * Get all service URLs for a given platform and environment.
1356
+ *
1357
+ * @param env - Target environment (staging or production)
1358
+ * @param platform - Target platform (defaults to 'BEYOND_AI')
1359
+ * @returns Service URLs for the environment
1360
+ */
1361
+ declare function getServiceUrlsForEnv(env: Environment, platform?: Platform): EnvServiceUrls;
1362
+
1363
+ export { ApiError, ForbiddenError, NotFoundError, TimebackClient, TimebackManager, TimebackProvider, UnauthorizedError, ValidationError, getServiceUrlsForEnv, isApiError, whereToFilter };
1364
+ export type { AuthCheckResult, BroadcastResult, BroadcastResultMethods, BroadcastResults, EnvServiceUrls, Environment, FieldCondition, FieldOperators, FilterValue, OrCondition, TimebackClientConfig, WhereClause };