@timeback/sdk 0.1.4 → 0.1.5

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 (66) hide show
  1. package/README.md +37 -13
  2. package/dist/client/adapters/react/index.d.ts +1 -2
  3. package/dist/client/adapters/react/index.d.ts.map +1 -1
  4. package/dist/client/adapters/react/index.js +30 -33
  5. package/dist/client/adapters/react/provider.d.ts +1 -2
  6. package/dist/client/adapters/react/provider.d.ts.map +1 -1
  7. package/dist/client/adapters/solid/context.d.ts +1 -2
  8. package/dist/client/adapters/solid/context.d.ts.map +1 -1
  9. package/dist/client/adapters/solid/context.tsx +1 -2
  10. package/dist/client/adapters/solid/index.d.ts +1 -2
  11. package/dist/client/adapters/solid/index.d.ts.map +1 -1
  12. package/dist/client/adapters/solid/index.ts +1 -2
  13. package/dist/client/adapters/svelte/index.d.ts +1 -2
  14. package/dist/client/adapters/svelte/index.d.ts.map +1 -1
  15. package/dist/client/adapters/svelte/index.ts +1 -2
  16. package/dist/client/adapters/svelte/stores.d.ts +1 -2
  17. package/dist/client/adapters/svelte/stores.d.ts.map +1 -1
  18. package/dist/client/adapters/svelte/stores.ts +1 -2
  19. package/dist/client/adapters/vue/index.d.ts +1 -2
  20. package/dist/client/adapters/vue/index.d.ts.map +1 -1
  21. package/dist/client/adapters/vue/index.ts +1 -2
  22. package/dist/client/adapters/vue/provider.d.ts +1 -2
  23. package/dist/client/adapters/vue/provider.d.ts.map +1 -1
  24. package/dist/client/adapters/vue/provider.ts +1 -2
  25. package/dist/client/index.d.ts +1 -1
  26. package/dist/client/index.d.ts.map +1 -1
  27. package/dist/client/lib/activity/activity.class.d.ts +21 -21
  28. package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
  29. package/dist/client/lib/activity/index.d.ts +0 -1
  30. package/dist/client/lib/activity/index.d.ts.map +1 -1
  31. package/dist/client/namespaces/activity.d.ts +13 -8
  32. package/dist/client/namespaces/activity.d.ts.map +1 -1
  33. package/dist/client.d.ts +4 -4
  34. package/dist/client.d.ts.map +1 -1
  35. package/dist/client.js +30 -34
  36. package/dist/index.d.ts +1 -5
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +25547 -6016
  39. package/dist/server/adapters/express.js +19359 -819
  40. package/dist/server/adapters/nuxt.js +19363 -823
  41. package/dist/server/adapters/solid-start.js +19361 -821
  42. package/dist/server/adapters/tanstack-start.js +19359 -819
  43. package/dist/server/handlers/activity.d.ts +4 -7
  44. package/dist/server/handlers/activity.d.ts.map +1 -1
  45. package/dist/server/handlers/user.d.ts.map +1 -1
  46. package/dist/server/lib/build-activity-events.d.ts +29 -1
  47. package/dist/server/lib/build-activity-events.d.ts.map +1 -1
  48. package/dist/server/lib/index.d.ts +2 -4
  49. package/dist/server/lib/index.d.ts.map +1 -1
  50. package/dist/server/lib/resolve.d.ts +112 -0
  51. package/dist/server/lib/resolve.d.ts.map +1 -0
  52. package/dist/server/timeback.d.ts +2 -2
  53. package/dist/server/timeback.d.ts.map +1 -1
  54. package/dist/server/types.d.ts +150 -25
  55. package/dist/server/types.d.ts.map +1 -1
  56. package/dist/shared/types.d.ts +116 -7
  57. package/dist/shared/types.d.ts.map +1 -1
  58. package/package.json +3 -3
  59. package/dist/client/lib/activity/activity.d.ts +0 -16
  60. package/dist/client/lib/activity/activity.d.ts.map +0 -1
  61. package/dist/server/lib/resolve-activity-course.d.ts +0 -22
  62. package/dist/server/lib/resolve-activity-course.d.ts.map +0 -1
  63. package/dist/server/lib/resolve-timeback-id.d.ts +0 -28
  64. package/dist/server/lib/resolve-timeback-id.d.ts.map +0 -1
  65. package/dist/server/lib/resolve-timeback-user.d.ts +0 -42
  66. package/dist/server/lib/resolve-timeback-user.d.ts.map +0 -1
@@ -3,19 +3,16 @@
3
3
  *
4
4
  * Route handlers for activity tracking.
5
5
  */
6
- import type { ApiCredentials, AppConfig, Environment, IdentityConfig } from '../types';
7
- /**
8
- * Configuration for the activity handler.
9
- */
6
+ import type { ApiCredentials, AppConfig, Environment, IdentityConfig, TimebackConfig } from '../types';
7
+ /** Configuration for the activity handler. */
10
8
  interface ActivityHandlerConfig {
11
9
  env: Environment;
12
10
  identity: IdentityConfig;
13
11
  appConfig: AppConfig;
14
12
  api: ApiCredentials;
13
+ hooks?: TimebackConfig['hooks'];
15
14
  }
16
- /**
17
- * Activity handler type.
18
- */
15
+ /** Activity handler type. */
19
16
  type ActivityHandler = (req: Request) => Promise<Response>;
20
17
  /**
21
18
  * Create the activity POST handler.
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAuFtF;;GAEG;AACH,UAAU,qBAAqB;IAC9B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;CACnB;AAED;;GAEG;AACH,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAE1D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAqIpF"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA4BH,OAAO,KAAK,EAEX,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,cAAc,EACd,MAAM,UAAU,CAAA;AA4CjB,8CAA8C;AAC9C,UAAU,qBAAqB;IAC9B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,SAAS,EAAE,SAAS,CAAA;IACpB,GAAG,EAAE,cAAc,CAAA;IACnB,KAAK,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;CAC/B;AAED,6BAA6B;AAC7B,KAAK,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AA4S1D;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,eAAe,CAmFpF"}
@@ -1 +1 @@
1
- {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAItF;;GAEG;AACH,UAAU,iBAAiB;IAC1B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;CACpB;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAyFxE"}
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/server/handlers/user.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAkBH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAItF;;GAEG;AACH,UAAU,iBAAiB;IAC1B,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAA;IACxB,GAAG,EAAE,cAAc,CAAA;IACnB,SAAS,EAAE,SAAS,CAAA;CACpB;AAED;;GAEG;AACH,KAAK,WAAW,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAEtD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAuGxE"}
@@ -2,16 +2,44 @@ import type { ActivityCompletedEvent, TimebackActivityContext, TimebackActivityM
2
2
  import type { TimebackClient } from '@timeback/core';
3
3
  import type { ActivityEndPayload, ActivityMetrics } from '../../shared/types';
4
4
  import type { AppConfig } from '../types';
5
+ /**
6
+ * Error thrown when a course is missing a synced ID for the target environment.
7
+ */
8
+ export declare class MissingSyncedCourseIdError extends Error {
9
+ readonly course: AppConfig['courses'][number];
10
+ readonly env: 'staging' | 'production';
11
+ constructor(course: AppConfig['courses'][number], env: 'staging' | 'production');
12
+ }
13
+ /**
14
+ * Error thrown when the sensor URL is invalid.
15
+ */
16
+ export declare class InvalidSensorUrlError extends Error {
17
+ readonly sensor: string;
18
+ constructor(sensor: string);
19
+ }
5
20
  /**
6
21
  * Build a Timeback activity context for Caliper events.
7
22
  *
23
+ * Handles both grade-based and grade-less courses:
24
+ * - Grade-based: uses subject + grade for IDs
25
+ * - Grade-less: uses code for IDs
26
+ *
27
+ * The `id` field (`object.id` in Caliper) is a canonical URL derived from the
28
+ * sensor, course selector, and activity slug. This enables upstream systems to
29
+ * process the activity as an "external URL" activity without requiring
30
+ * pre-synced OneRoster component resources.
31
+ *
32
+ * The `activity` field contains only the human-readable `name` (no `id`),
33
+ * since the canonical URL in `object.id` serves as the stable identifier.
34
+ *
8
35
  * @param payload - Validated activity payload
9
36
  * @param course - Matched course config
10
37
  * @param appName - Timeback app display name
11
38
  * @param apiEnv - Target Timeback API environment
39
+ * @param sensor - Sensor URL for building the canonical activity URL
12
40
  * @returns Caliper activity context payload
13
41
  */
14
- export declare function buildActivityContext(payload: ActivityEndPayload, course: AppConfig['courses'][number], appName: string, apiEnv: 'staging' | 'production'): TimebackActivityContext;
42
+ export declare function buildActivityContext(payload: ActivityEndPayload, course: AppConfig['courses'][number], appName: string, apiEnv: 'staging' | 'production', sensor: string): TimebackActivityContext;
15
43
  /**
16
44
  * Build Caliper activity metrics from the client payload.
17
45
  *
@@ -1 +1 @@
1
- {"version":3,"file":"build-activity-events.d.ts","sourceRoot":"","sources":["../../../src/server/lib/build-activity-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EAEtB,cAAc,EACd,eAAe,EACf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,GAAG,YAAY,GAC9B,uBAAuB,CAgBzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,sBAAsB,EAAE,CAoBvF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAQ5F;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACxC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,sBAAsB,EACrC,cAAc,EAAE,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"build-activity-events.d.ts","sourceRoot":"","sources":["../../../src/server/lib/build-activity-events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EAEtB,cAAc,EACd,eAAe,EACf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAqB,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAChG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEzC;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IAC7C,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG,YAAY,CAAA;IAEtC,YAAY,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,SAAS,GAAG,YAAY,EAW9E;CACD;AA8CD;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,YAAY,MAAM,EAAE,MAAM,EAMzB;CACD;AAiED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,kBAAkB,EAC3B,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,GAAG,YAAY,EAChC,MAAM,EAAE,MAAM,GACZ,uBAAuB,CAYzB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,sBAAsB,EAAE,CAoBvF;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAQ5F;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACxC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,sBAAsB,EACrC,cAAc,EAAE,cAAc,GAC5B,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -6,9 +6,7 @@
6
6
  export { getIssuer, buildAuthorizationUrl, exchangeCodeForTokens, getUserInfo } from './oidc';
7
7
  export { jsonResponse, redirectResponse, encodeBase64Url, decodeBase64Url, mapEnvForApi, } from './utils';
8
8
  export { ssoLog, oidcLog, createScopedLogger } from './logger';
9
- export { resolveTimebackUserByEmail, TimebackUserResolutionError } from './resolve-timeback-user';
10
- export { buildActivityContext, buildActivityMetrics, buildTimeSpentMetrics, sendCaliperEnvelope, } from './build-activity-events';
11
- export { resolveActivityCourse, ActivityCourseResolutionError } from './resolve-activity-course';
12
- export { resolveStatusForUserResolutionError, resolveTimebackIdForActivity, } from './resolve-timeback-id';
9
+ export { ActivityCourseResolutionError, lookupTimebackIdByEmail, resolveActivityCourse, resolveStatusForUserResolutionError, resolveTimebackUserByEmail, TimebackUserResolutionError, } from './resolve';
10
+ export { buildActivityContext, buildActivityMetrics, buildTimeSpentMetrics, InvalidSensorUrlError, MissingSyncedCourseIdError, sendCaliperEnvelope, } from './build-activity-events';
13
11
  export { buildCourseLookup, getUtcDayRange, mapEnrollmentsToCourses, pickGoalsFromEnrollments, sumXp, } from './build-user-profile';
14
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC7F,OAAO,EACN,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AACjG,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,EACN,mCAAmC,EACnC,4BAA4B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,KAAK,GACL,MAAM,sBAAsB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/lib/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AAC7F,OAAO,EACN,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,eAAe,EACf,YAAY,GACZ,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,EACN,6BAA6B,EAC7B,uBAAuB,EACvB,qBAAqB,EACrB,mCAAmC,EACnC,0BAA0B,EAC1B,2BAA2B,GAC3B,MAAM,WAAW,CAAA;AAClB,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,GACnB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACN,iBAAiB,EACjB,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,KAAK,GACL,MAAM,sBAAsB,CAAA"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Resolution Utilities
3
+ *
4
+ * Functions for resolving Timeback users and activity courses.
5
+ *
6
+ * ## User Resolution
7
+ *
8
+ * - `resolveTimebackUserByEmail` — Full user resolution returning profile + IdP claims.
9
+ * Used by SSO callback to build the authenticated user object.
10
+ *
11
+ * - `lookupTimebackIdByEmail` — Simple lookup returning just the timebackId.
12
+ * Used by activity/user handlers when only the ID is needed.
13
+ *
14
+ * - `resolveStatusForUserResolutionError` — Maps error codes to HTTP status.
15
+ * Used by handlers to return appropriate status codes on resolution failure.
16
+ *
17
+ * ## Course Resolution
18
+ *
19
+ * - `resolveActivityCourse` — Resolves a course selector to a config entry.
20
+ * Used by activity handler to match client payload to configured courses.
21
+ */
22
+ import { TimebackClient } from '@timeback/core';
23
+ import type { ActivityCourseRef, TimebackAuthUser } from '../../shared/types';
24
+ import type { ApiCredentials, AppConfig, Environment, OIDCUserInfo, TimebackUserResolutionErrorCode } from '../types';
25
+ /**
26
+ * Error thrown when Timeback user resolution fails.
27
+ */
28
+ export declare class TimebackUserResolutionError extends Error {
29
+ readonly code: TimebackUserResolutionErrorCode;
30
+ constructor(message: string, code: TimebackUserResolutionErrorCode);
31
+ }
32
+ /**
33
+ * Map a user resolution error to an HTTP status code.
34
+ *
35
+ * @param err - Timeback user resolution error
36
+ * @returns HTTP status code (409 for ambiguous, 404 otherwise)
37
+ */
38
+ export declare function resolveStatusForUserResolutionError(err: TimebackUserResolutionError): number;
39
+ interface ResolveTimebackUserByEmailParams {
40
+ /** Environment (staging/production) */
41
+ env: Environment;
42
+ /** API credentials for Timeback API */
43
+ apiCredentials: ApiCredentials;
44
+ /** OIDC user info from the IdP */
45
+ userInfo: OIDCUserInfo;
46
+ /**
47
+ * Optional pre-configured Timeback client.
48
+ * When provided, this function will use it and will NOT close it.
49
+ */
50
+ client?: TimebackClient;
51
+ }
52
+ interface LookupTimebackIdByEmailParams {
53
+ /** User's email address */
54
+ email: string;
55
+ /** Pre-configured Timeback client */
56
+ client: TimebackClient;
57
+ }
58
+ /**
59
+ * Resolve a full TimebackAuthUser by email.
60
+ *
61
+ * **Use case:** SSO callback — after OIDC authentication, look up the Timeback
62
+ * user and return a complete auth object with profile data and IdP claims.
63
+ *
64
+ * @param params - Resolution parameters including OIDC userInfo
65
+ * @returns TimebackAuthUser with profile and IdP claims
66
+ * @throws {TimebackUserResolutionError} If resolution fails
67
+ */
68
+ export declare function resolveTimebackUserByEmail(params: ResolveTimebackUserByEmailParams): Promise<TimebackAuthUser>;
69
+ /**
70
+ * Look up the Timeback user ID by email.
71
+ *
72
+ * **Use case:** Activity/user handlers — when you only need the timebackId,
73
+ * not the full auth object.
74
+ *
75
+ * @param params - Email and pre-configured client
76
+ * @returns The Timeback user ID (sourcedId)
77
+ * @throws {TimebackUserResolutionError} If lookup fails
78
+ */
79
+ export declare function lookupTimebackIdByEmail(params: LookupTimebackIdByEmailParams): Promise<string>;
80
+ /**
81
+ * Error thrown when a course selector cannot be resolved against config.
82
+ */
83
+ export declare class ActivityCourseResolutionError extends Error {
84
+ readonly code: 'unknown_course' | 'ambiguous_course';
85
+ readonly selector: ActivityCourseRef;
86
+ readonly count?: number;
87
+ constructor(code: ActivityCourseResolutionError['code'], selector: ActivityCourseRef, count?: number);
88
+ /**
89
+ * Get a human-readable description of the selector.
90
+ *
91
+ * @returns Human-readable selector description
92
+ */
93
+ get selectorDescription(): string;
94
+ }
95
+ /**
96
+ * Resolve a course config entry from an activity course selector.
97
+ *
98
+ * **Use case:** Activity handler — match the client's course selector
99
+ * to a configured course in `timeback.config.ts`.
100
+ *
101
+ * Supports two selector modes:
102
+ * - **subjectGrade**: Match by `(subject, grade)`
103
+ * - **courseCode**: Match by `courseCode`
104
+ *
105
+ * @param courses - Configured courses from `timeback.config.ts`
106
+ * @param courseRef - Course selector from the client payload
107
+ * @returns Matched course config entry
108
+ * @throws {ActivityCourseResolutionError} When selector is unknown or ambiguous
109
+ */
110
+ export declare function resolveActivityCourse(courses: AppConfig['courses'], courseRef: ActivityCourseRef): AppConfig['courses'][number];
111
+ export {};
112
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/server/lib/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAM/C,OAAO,KAAK,EACX,iBAAiB,EAEjB,gBAAgB,EAEhB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EACX,cAAc,EACd,SAAS,EACT,WAAW,EACX,YAAY,EACZ,+BAA+B,EAC/B,MAAM,UAAU,CAAA;AAQjB;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;aAGpC,IAAI,EAAE,+BAA+B;IAFtD,YACC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,+BAA+B,EAIrD;CACD;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,2BAA2B,GAAG,MAAM,CAE5F;AAMD,UAAU,gCAAgC;IACzC,uCAAuC;IACvC,GAAG,EAAE,WAAW,CAAA;IAChB,uCAAuC;IACvC,cAAc,EAAE,cAAc,CAAA;IAC9B,kCAAkC;IAClC,QAAQ,EAAE,YAAY,CAAA;IACtB;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;CACvB;AAED,UAAU,6BAA6B;IACtC,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,qCAAqC;IACrC,MAAM,EAAE,cAAc,CAAA;CACtB;AA2FD;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC/C,MAAM,EAAE,gCAAgC,GACtC,OAAO,CAAC,gBAAgB,CAAC,CAsD3B;AAED;;;;;;;;;GASG;AACH,wBAAsB,uBAAuB,CAC5C,MAAM,EAAE,6BAA6B,GACnC,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAMD;;GAEG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IACvD,QAAQ,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,CAAA;IACpD,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAA;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IAEvB,YACC,IAAI,EAAE,6BAA6B,CAAC,MAAM,CAAC,EAC3C,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,CAAC,EAAE,MAAM,EAMd;IAED;;;;OAIG;IACH,IAAI,mBAAmB,IAAI,MAAM,CAKhC;CACD;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,EAC7B,SAAS,EAAE,iBAAiB,GAC1B,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAoB9B"}
@@ -56,9 +56,9 @@ import type { TimebackConfig, TimebackInstance } from './types';
56
56
  * api: { ... },
57
57
  * identity: {
58
58
  * mode: 'custom',
59
- * getUser: async (req) => {
59
+ * getEmail: async (req) => {
60
60
  * const session = await getSession(req)
61
- * return session ? { id: session.userId, email: session.email } : undefined
61
+ * return session?.email
62
62
  * },
63
63
  * },
64
64
  * })
@@ -1 +1 @@
1
- {"version":3,"file":"timeback.d.ts","sourceRoot":"","sources":["../../src/server/timeback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAG,OAAO,EACpD,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAsEnC"}
1
+ {"version":3,"file":"timeback.d.ts","sourceRoot":"","sources":["../../src/server/timeback.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAa,cAAc,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAsB1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAG,OAAO,EACpD,MAAM,EAAE,cAAc,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAuEnC"}
@@ -3,8 +3,9 @@
3
3
  *
4
4
  * Configuration and internal types for the server SDK.
5
5
  */
6
+ import type { ActivityCompletedEvent, TimeSpentEvent } from '@timeback/caliper';
6
7
  import type { TimebackClient } from '@timeback/core';
7
- import type { TimebackAuthUser, TimebackIdentity } from '../shared/types';
8
+ import type { ActivityEndPayload, TimebackAuthUser, TimebackIdentity } from '../shared/types';
8
9
  /**
9
10
  * Environment configuration.
10
11
  */
@@ -278,20 +279,65 @@ export interface SsoIdentityConfig<TState = unknown, TSuccessContext = CallbackS
278
279
  export interface CustomIdentityConfig {
279
280
  mode: 'custom';
280
281
  /**
281
- * Get the current user from the request.
282
+ * Get the current user's email from the request.
282
283
  *
283
- * Read your session cookie/JWT and return the user, or undefined if not authenticated.
284
+ * Read your session cookie/JWT and return the user's email, or undefined if not authenticated.
285
+ * The SDK resolves the Timeback user by email.
284
286
  * Can return synchronously or as a Promise.
285
287
  *
286
288
  * @param req - The incoming request
287
- * @returns User object or undefined (sync or async)
289
+ * @returns User's email or undefined (sync or async)
290
+ *
291
+ * @example
292
+ * ```typescript
293
+ * // From session cookie
294
+ * getEmail: req => getSessionFromCookie(req)?.email
295
+ *
296
+ * // From JWT
297
+ * getEmail: async req => {
298
+ * const token = await verifyToken(req)
299
+ * return token?.email
300
+ * }
301
+ * ```
288
302
  */
289
- getUser(req: Request): Promise<TimebackIdentity | undefined> | TimebackIdentity | undefined;
303
+ getEmail(req: Request): Promise<string | undefined> | string | undefined;
290
304
  }
291
305
  /**
292
306
  * Identity configuration (SSO or custom).
293
307
  */
294
308
  export type IdentityConfig<TState = unknown> = SsoIdentityConfig<TState> | CustomIdentityConfig;
309
+ /**
310
+ * Data provided to `hooks.beforeActivitySend`.
311
+ *
312
+ * This is the payload the client POSTed plus the Caliper events the SDK built.
313
+ * Returning `null` from the hook skips sending.
314
+ */
315
+ export interface ActivityBeforeSendData {
316
+ /** Sensor URL selected for the event submission */
317
+ sensor: string;
318
+ /** Actor object used in generated Caliper events */
319
+ actor: {
320
+ id: string;
321
+ type: 'TimebackUser';
322
+ email: string;
323
+ };
324
+ /** Caliper context object (shape depends on SDK internals) */
325
+ object: unknown;
326
+ /** Built events (ActivityEvent + TimeSpentEvent) */
327
+ events: [ActivityCompletedEvent, TimeSpentEvent];
328
+ /** Original payload posted by the client */
329
+ payload: ActivityEndPayload;
330
+ /** Matched course from `timeback.config.ts` */
331
+ course: AppConfig['courses'][number];
332
+ /** App name (from config) */
333
+ appName: string;
334
+ /** API environment used for resolution */
335
+ apiEnv: 'staging' | 'production';
336
+ /** User email */
337
+ email: string;
338
+ /** Canonical Timeback user id */
339
+ timebackId: string;
340
+ }
295
341
  /**
296
342
  * Full Timeback SDK configuration.
297
343
  */
@@ -304,6 +350,24 @@ export interface TimebackConfig<TState = unknown> {
304
350
  api: ApiCredentials;
305
351
  /** Identity configuration */
306
352
  identity: IdentityConfig<TState>;
353
+ /**
354
+ * Optional hooks for customizing SDK handler behavior.
355
+ *
356
+ * These are primarily useful for testing, demos, and advanced integrations.
357
+ */
358
+ hooks?: {
359
+ /**
360
+ * Called after Caliper events are built, right before sending.
361
+ *
362
+ * - Return the (optionally modified) data to proceed with sending
363
+ * - Return `null` to skip sending (handler still returns success)
364
+ * - Throw to fail the request
365
+ *
366
+ * @param data - Built activity events + context
367
+ * @returns Modified data to send, or null to skip
368
+ */
369
+ beforeActivitySend?: (data: ActivityBeforeSendData) => ActivityBeforeSendData | null | Promise<ActivityBeforeSendData | null>;
370
+ };
307
371
  }
308
372
  /**
309
373
  * Request handlers namespace.
@@ -326,31 +390,92 @@ export interface Handlers {
326
390
  me: (req: Request) => Promise<Response>;
327
391
  };
328
392
  }
393
+ type AppCourseMetadata = {
394
+ goals?: {
395
+ dailyXp?: number;
396
+ dailyLessons?: number;
397
+ dailyActiveMinutes?: number;
398
+ dailyAccuracy?: number;
399
+ dailyMasteredUnits?: number;
400
+ };
401
+ };
402
+ type AppCourseBase = {
403
+ subject: string;
404
+ level?: string;
405
+ ids?: {
406
+ staging?: string;
407
+ production?: string;
408
+ } | null;
409
+ /** Per-course sensor URL (overrides top-level sensor). */
410
+ sensor?: string;
411
+ /** Per-course launch URL (overrides top-level launchUrl). */
412
+ launchUrl?: string;
413
+ /**
414
+ * Environment-specific overrides for non-identity fields.
415
+ *
416
+ * These are applied when syncing/editing a course for a specific env.
417
+ * For activity sending, the env-specific sensor override (when present)
418
+ * takes precedence over base `sensor` and top-level `sensor`.
419
+ */
420
+ overrides?: {
421
+ staging?: {
422
+ level?: string;
423
+ sensor?: string;
424
+ launchUrl?: string;
425
+ metadata?: AppCourseMetadata;
426
+ };
427
+ production?: {
428
+ level?: string;
429
+ sensor?: string;
430
+ launchUrl?: string;
431
+ metadata?: AppCourseMetadata;
432
+ };
433
+ };
434
+ metadata?: AppCourseMetadata;
435
+ };
436
+ /**
437
+ * Course config as used by the SDK server handlers.
438
+ *
439
+ * Identity rules:
440
+ * - Grade-based: `grade` is set, `courseCode` optional
441
+ * - Grade-less: `grade` is undefined, `courseCode` required
442
+ */
443
+ type AppCourse = (AppCourseBase & {
444
+ /** Grade level. */
445
+ grade: number;
446
+ /** Course code. Optional for grade-based courses. */
447
+ courseCode?: string;
448
+ }) | (AppCourseBase & {
449
+ /** Grade-less course. */
450
+ grade?: undefined;
451
+ /** Course code. Required for grade-less courses. */
452
+ courseCode: string;
453
+ });
329
454
  /**
330
455
  * App configuration from timeback.config.ts.
456
+ *
457
+ * Note: Config invariants are validated at runtime by `@timeback/types/zod`.
458
+ * The stricter unions here help keep SDK handler code type-safe.
459
+ *
460
+ * Course identity rules:
461
+ * - Grade-based: `grade` is set
462
+ * - Grade-less: `grade` is undefined, `courseCode` is required
463
+ *
464
+ * Sensor resolution:
465
+ * - Every course must have an effective sensor
466
+ * (`course.overrides[env].sensor ?? course.sensor ?? config.sensor`).
467
+ * - This is enforced by zod validation at config load time.
468
+ *
469
+ * LaunchUrl resolution:
470
+ * - Every course must have an effective launchUrl
471
+ * (`course.overrides[env].launchUrl ?? course.launchUrl ?? config.launchUrl`).
472
+ * - This is enforced by zod validation at config load time.
331
473
  */
332
474
  export interface AppConfig {
333
475
  name: string;
334
- sensors: string[];
335
- courses: Array<{
336
- subject: string;
337
- grade: number;
338
- courseCode?: string;
339
- level?: string;
340
- ids?: {
341
- staging?: string;
342
- production?: string;
343
- } | null;
344
- metadata?: {
345
- goals?: {
346
- dailyXp?: number;
347
- dailyLessons?: number;
348
- dailyActiveMinutes?: number;
349
- dailyAccuracy?: number;
350
- dailyMasteredUnits?: number;
351
- };
352
- };
353
- }>;
476
+ sensor?: string;
477
+ launchUrl?: string;
478
+ courses: AppCourse[];
354
479
  }
355
480
  /**
356
481
  * Timeback SDK instance (framework-agnostic).
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,8 @@ export interface TimebackProfile {
47
47
  dailyXp?: number;
48
48
  dailyLessons?: number;
49
49
  dailyActiveMinutes?: number;
50
+ dailyAccuracy?: number;
51
+ dailyMasteredUnits?: number;
50
52
  };
51
53
  }
52
54
  /**
@@ -96,21 +98,102 @@ export interface TimebackAuthUser extends TimebackProfile {
96
98
  claims: IdentityClaims;
97
99
  }
98
100
  /**
99
- * Course selector for activity tracking.
101
+ * Course selector by subject and grade (grade-based apps).
100
102
  *
101
- * This should correspond to a unique course entry in `timeback.config.ts`.
103
+ * Use this for traditional K-12 apps where courses are identified by subject + grade.
102
104
  */
103
- export interface ActivityCourseRef {
105
+ export interface SubjectGradeCourseRef {
104
106
  subject: TimebackSubject;
105
107
  grade: TimebackGrade;
106
108
  }
109
+ /**
110
+ * Course selector by code (grade-less apps).
111
+ *
112
+ * Use this for apps without grade levels (e.g., CS platforms) where courses
113
+ * are identified by a unique course code.
114
+ */
115
+ export interface CourseCodeRef {
116
+ code: string;
117
+ }
118
+ /**
119
+ * Course selector for activity tracking.
120
+ *
121
+ * This should correspond to a unique course entry in `timeback.config.ts`.
122
+ *
123
+ * Two selector modes are supported:
124
+ * - **Grade-based**: `{ subject, grade }` — K-12 style
125
+ * - **Grade-less**: `{ code }` — CS/skill-based
126
+ *
127
+ * @example Grade-based
128
+ * ```typescript
129
+ * { subject: 'Math', grade: 3 }
130
+ * ```
131
+ *
132
+ * @example Grade-less
133
+ * ```typescript
134
+ * { code: 'CS-101' }
135
+ * ```
136
+ */
137
+ export type ActivityCourseRef = SubjectGradeCourseRef | CourseCodeRef;
138
+ /**
139
+ * Type guard: Check if a course ref uses subject+grade identity.
140
+ *
141
+ * @param ref - Course reference to check
142
+ * @returns True if grade-based selector
143
+ */
144
+ export declare function isSubjectGradeCourseRef(ref: ActivityCourseRef): ref is SubjectGradeCourseRef;
107
145
  /**
108
146
  * Activity start parameters.
147
+ *
148
+ * @remarks
149
+ * The `id` field is treated as a **slug** (not a URL). The SDK derives the
150
+ * canonical activity URL (`event.object.id`) from:
151
+ * - The configured sensor URL
152
+ * - The course selector (subject + grade or code)
153
+ * - This slug (URI-encoded)
154
+ *
155
+ * This allows upstream systems to process activities without requiring
156
+ * pre-synced OneRoster component resources.
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * // Grade-based course
161
+ * timeback.activity.start({
162
+ * id: 'fractions-with-like-denominators', // slug
163
+ * name: 'Fractions with Like Denominators', // human-readable
164
+ * course: { subject: 'Math', grade: 3 },
165
+ * })
166
+ * // => object.id: https://sensor.example.com/activities/Math/g3/fractions-with-like-denominators
167
+ *
168
+ * // Grade-less course
169
+ * timeback.activity.start({
170
+ * id: 'intro-to-loops',
171
+ * name: 'Introduction to Loops',
172
+ * course: { code: 'CS-101' },
173
+ * })
174
+ * // => object.id: https://sensor.example.com/activities/CS-101/intro-to-loops
175
+ * ```
109
176
  */
110
177
  export interface ActivityParams {
111
- /** Unique identifier for the learning object */
178
+ /**
179
+ * Activity slug (stable identifier for the learning object).
180
+ *
181
+ * This is used to construct the canonical activity URL sent to Caliper.
182
+ * Use a short, URL-safe slug like `"fractions-with-like-denominators"` or
183
+ * `"lesson-1"`. Special characters will be URI-encoded.
184
+ *
185
+ * @example 'fractions-with-like-denominators'
186
+ * @example 'ccss.math.content.3.nf.a.1'
187
+ * @example 'lesson-1'
188
+ */
112
189
  id: string;
113
- /** Display name of the activity */
190
+ /**
191
+ * Human-readable display name of the activity.
192
+ *
193
+ * This is sent as `object.activity.name` in Caliper events.
194
+ *
195
+ * @example 'Fractions with Like Denominators'
196
+ */
114
197
  name: string;
115
198
  /** Course selector (must match a unique course in timeback.config.ts) */
116
199
  course: ActivityCourseRef;
@@ -130,11 +213,21 @@ export interface ActivityMetrics {
130
213
  }
131
214
  /**
132
215
  * Activity state sent to the server when ending.
216
+ *
217
+ * @see {@link ActivityParams} for documentation on `id` and `name` semantics.
133
218
  */
134
219
  export interface ActivityEndPayload {
135
- /** Unique identifier for the learning object */
220
+ /**
221
+ * Activity slug (stable identifier for the learning object).
222
+ *
223
+ * @see {@link ActivityParams.id}
224
+ */
136
225
  id: string;
137
- /** Display name of the activity */
226
+ /**
227
+ * Human-readable display name of the activity.
228
+ *
229
+ * @see {@link ActivityParams.name}
230
+ */
138
231
  name: string;
139
232
  /** Course selector (must match a unique course in timeback.config.ts) */
140
233
  course: ActivityCourseRef;
@@ -148,6 +241,22 @@ export interface ActivityEndPayload {
148
241
  pausedMs: number;
149
242
  /** Activity metrics */
150
243
  metrics: ActivityMetrics;
244
+ /**
245
+ * Attempt number for this activity (1-based).
246
+ *
247
+ * If provided, this is forwarded to Caliper events as `generated.attempt`.
248
+ */
249
+ attemptNumber?: number;
250
+ /**
251
+ * App-reported course progress (per enrollment), as a percentage from 0–100.
252
+ *
253
+ * This is forwarded to Caliper events as `generated.extensions.pctCompleteApp`.
254
+ *
255
+ * @remarks
256
+ * - Scale: 0 to 100 (not 0 to 1)
257
+ * - Values outside 0–100 are clamped by the SDK server handler if present
258
+ */
259
+ pctCompleteApp?: number;
151
260
  }
152
261
  /**
153
262
  * Activity submission response.