@timeback/sdk 0.1.6 → 0.1.8
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/README.md +91 -2
- package/dist/chunk-07j8zre9.js +2 -0
- package/dist/chunk-3886xy48.js +8 -0
- package/dist/chunk-9se82640.js +1 -0
- package/dist/chunk-ahy54f2r.js +2 -0
- package/dist/chunk-ewsp6v3b.js +16 -0
- package/dist/chunk-j1xdrfqj.js +2 -0
- package/dist/chunk-qaa129bd.js +2 -0
- package/dist/chunk-qr0bbnsr.js +1 -0
- package/dist/chunk-rgbpvxbv.js +1 -0
- package/dist/chunk-whc53e0y.js +11 -0
- package/dist/client/adapters/react/hooks/types.d.ts +61 -0
- package/dist/client/adapters/react/hooks/types.d.ts.map +1 -0
- package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts +42 -0
- package/dist/client/adapters/react/hooks/useTimebackProfile.d.ts.map +1 -0
- package/dist/client/adapters/react/hooks/useTimebackVerification.d.ts +18 -0
- package/dist/client/adapters/react/hooks/useTimebackVerification.d.ts.map +1 -0
- package/dist/client/adapters/react/index.d.ts +3 -0
- package/dist/client/adapters/react/index.d.ts.map +1 -1
- package/dist/client/adapters/react/index.js +2 -364
- package/dist/client/adapters/solid/index.d.ts +3 -0
- package/dist/client/adapters/solid/index.d.ts.map +1 -1
- package/dist/client/adapters/solid/index.ts +12 -0
- package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts +58 -0
- package/dist/client/adapters/solid/primitives/createTimebackProfile.d.ts.map +1 -0
- package/dist/client/adapters/solid/primitives/createTimebackProfile.ts +209 -0
- package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts +36 -0
- package/dist/client/adapters/solid/primitives/createTimebackVerification.d.ts.map +1 -0
- package/dist/client/adapters/solid/primitives/createTimebackVerification.ts +133 -0
- package/dist/client/adapters/solid/types.d.ts +86 -0
- package/dist/client/adapters/solid/types.d.ts.map +1 -0
- package/dist/client/adapters/solid/types.ts +85 -0
- package/dist/client/adapters/svelte/index.d.ts +2 -1
- package/dist/client/adapters/svelte/index.d.ts.map +1 -1
- package/dist/client/adapters/svelte/index.ts +11 -2
- package/dist/client/adapters/svelte/{stores.d.ts → stores/client.d.ts} +11 -9
- package/dist/client/adapters/svelte/stores/client.d.ts.map +1 -0
- package/dist/client/adapters/svelte/{stores.ts → stores/client.ts} +24 -52
- package/dist/client/adapters/svelte/stores/index.d.ts +10 -0
- package/dist/client/adapters/svelte/stores/index.d.ts.map +1 -0
- package/dist/client/adapters/svelte/stores/index.ts +22 -0
- package/dist/client/adapters/svelte/stores/profile.d.ts +66 -0
- package/dist/client/adapters/svelte/stores/profile.d.ts.map +1 -0
- package/dist/client/adapters/svelte/stores/profile.ts +168 -0
- package/dist/client/adapters/svelte/stores/verification.d.ts +43 -0
- package/dist/client/adapters/svelte/stores/verification.d.ts.map +1 -0
- package/dist/client/adapters/svelte/stores/verification.ts +126 -0
- package/dist/client/adapters/svelte/types.d.ts +35 -0
- package/dist/client/adapters/svelte/types.d.ts.map +1 -0
- package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts +51 -0
- package/dist/client/adapters/vue/composables/useTimebackProfile.d.ts.map +1 -0
- package/dist/client/adapters/vue/composables/useTimebackProfile.ts +186 -0
- package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts +44 -0
- package/dist/client/adapters/vue/composables/useTimebackVerification.d.ts.map +1 -0
- package/dist/client/adapters/vue/composables/useTimebackVerification.ts +128 -0
- package/dist/client/adapters/vue/index.d.ts +3 -0
- package/dist/client/adapters/vue/index.d.ts.map +1 -1
- package/dist/client/adapters/vue/index.ts +12 -1
- package/dist/client/adapters/vue/types.d.ts +86 -0
- package/dist/client/adapters/vue/types.d.ts.map +1 -0
- package/dist/client/adapters/vue/types.ts +85 -0
- package/dist/client/auth/bearer.d.ts +17 -0
- package/dist/client/auth/bearer.d.ts.map +1 -0
- package/dist/client/auth/index.d.ts +3 -0
- package/dist/client/auth/index.d.ts.map +1 -0
- package/dist/client/auth/types.d.ts +39 -0
- package/dist/client/auth/types.d.ts.map +1 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/lib/activity/activity.class.d.ts +5 -5
- package/dist/client/lib/activity/activity.class.d.ts.map +1 -1
- package/dist/client/lib/fetch.d.ts +19 -0
- package/dist/client/lib/fetch.d.ts.map +1 -0
- package/dist/client/lib/user-cache.d.ts +39 -0
- package/dist/client/lib/user-cache.d.ts.map +1 -0
- package/dist/client/lib/user-cache.ts +168 -0
- package/dist/client/namespaces/activity.d.ts +2 -3
- package/dist/client/namespaces/activity.d.ts.map +1 -1
- package/dist/client/namespaces/user.d.ts +25 -2
- package/dist/client/namespaces/user.d.ts.map +1 -1
- package/dist/client/timeback-client.class.d.ts +15 -0
- package/dist/client/timeback-client.class.d.ts.map +1 -1
- package/dist/client/timeback-client.d.ts +3 -0
- package/dist/client/timeback-client.d.ts.map +1 -1
- package/dist/client.d.ts +3 -2
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +1 -194
- package/dist/edge.js +1 -1149
- package/dist/identity.js +1 -1019
- package/dist/index.js +22 -104603
- package/dist/server/adapters/express.d.ts.map +1 -1
- package/dist/server/adapters/express.js +1 -85997
- package/dist/server/adapters/native.d.ts.map +1 -1
- package/dist/server/adapters/native.js +2 -190
- package/dist/server/adapters/nextjs.js +1 -202
- package/dist/server/adapters/nuxt.d.ts.map +1 -1
- package/dist/server/adapters/nuxt.js +1 -86066
- package/dist/server/adapters/solid-start.d.ts.map +1 -1
- package/dist/server/adapters/solid-start.js +1 -85965
- package/dist/server/adapters/svelte-kit.d.ts.map +1 -1
- package/dist/server/adapters/svelte-kit.js +1 -243
- package/dist/server/adapters/tanstack-start.d.ts.map +1 -1
- package/dist/server/adapters/tanstack-start.js +1 -85943
- package/dist/server/adapters/utils.d.ts +1 -1
- package/dist/server/adapters/utils.d.ts.map +1 -1
- package/dist/server/handlers/activity/attempts.d.ts +51 -0
- package/dist/server/handlers/activity/attempts.d.ts.map +1 -0
- package/dist/server/handlers/activity/caliper.d.ts +133 -0
- package/dist/server/handlers/activity/caliper.d.ts.map +1 -0
- package/dist/server/handlers/activity/completion.d.ts +43 -0
- package/dist/server/handlers/activity/completion.d.ts.map +1 -0
- package/dist/server/handlers/activity/handler.d.ts +32 -0
- package/dist/server/handlers/activity/handler.d.ts.map +1 -0
- package/dist/server/handlers/activity/index.d.ts +9 -0
- package/dist/server/handlers/activity/index.d.ts.map +1 -0
- package/dist/server/handlers/activity/progress.d.ts +47 -0
- package/dist/server/handlers/activity/progress.d.ts.map +1 -0
- package/dist/server/handlers/activity/resolve.d.ts +39 -0
- package/dist/server/handlers/activity/resolve.d.ts.map +1 -0
- package/dist/server/handlers/activity/schema.d.ts +51 -0
- package/dist/server/handlers/activity/schema.d.ts.map +1 -0
- package/dist/server/handlers/activity/types.d.ts +51 -0
- package/dist/server/handlers/activity/types.d.ts.map +1 -0
- package/dist/server/handlers/identity/handler.d.ts +14 -0
- package/dist/server/handlers/identity/handler.d.ts.map +1 -0
- package/dist/server/handlers/identity/index.d.ts +8 -0
- package/dist/server/handlers/identity/index.d.ts.map +1 -0
- package/dist/server/handlers/identity/oidc.d.ts +43 -0
- package/dist/server/handlers/identity/oidc.d.ts.map +1 -0
- package/dist/server/handlers/identity/types.d.ts +24 -0
- package/dist/server/handlers/identity/types.d.ts.map +1 -0
- package/dist/server/handlers/identity-only/handler.d.ts +15 -0
- package/dist/server/handlers/identity-only/handler.d.ts.map +1 -0
- package/dist/server/handlers/identity-only/index.d.ts +8 -0
- package/dist/server/handlers/identity-only/index.d.ts.map +1 -0
- package/dist/server/handlers/identity-only/oidc.d.ts +26 -0
- package/dist/server/handlers/identity-only/oidc.d.ts.map +1 -0
- package/dist/server/handlers/identity-only/types.d.ts +19 -0
- package/dist/server/handlers/identity-only/types.d.ts.map +1 -0
- package/dist/server/handlers/index.d.ts +5 -2
- package/dist/server/handlers/index.d.ts.map +1 -1
- package/dist/server/{lib/build-user-profile.d.ts → handlers/user/enrollments.d.ts} +7 -2
- package/dist/server/handlers/user/enrollments.d.ts.map +1 -0
- package/dist/server/handlers/user/handler.d.ts +17 -0
- package/dist/server/handlers/user/handler.d.ts.map +1 -0
- package/dist/server/handlers/user/index.d.ts +10 -0
- package/dist/server/handlers/user/index.d.ts.map +1 -0
- package/dist/server/handlers/user/profile.d.ts +22 -0
- package/dist/server/handlers/user/profile.d.ts.map +1 -0
- package/dist/server/handlers/user/types.d.ts +35 -0
- package/dist/server/handlers/user/types.d.ts.map +1 -0
- package/dist/server/handlers/user/verify.d.ts +25 -0
- package/dist/server/handlers/user/verify.d.ts.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/lib/index.d.ts +4 -5
- package/dist/server/lib/index.d.ts.map +1 -1
- package/dist/server/lib/resolve.d.ts +4 -42
- package/dist/server/lib/resolve.d.ts.map +1 -1
- package/dist/server/lib/sso.d.ts +86 -0
- package/dist/server/lib/sso.d.ts.map +1 -0
- package/dist/server/lib/utils.d.ts +93 -1
- package/dist/server/lib/utils.d.ts.map +1 -1
- package/dist/server/timeback-identity.d.ts.map +1 -1
- package/dist/server/timeback.d.ts.map +1 -1
- package/dist/server/types.d.ts +23 -10
- package/dist/server/types.d.ts.map +1 -1
- package/dist/shared/constants.d.ts +7 -0
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/types.d.ts +77 -8
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/xp-calculator.d.ts +25 -0
- package/dist/shared/xp-calculator.d.ts.map +1 -0
- package/package.json +8 -2
- package/dist/client/adapters/svelte/stores.d.ts.map +0 -1
- package/dist/server/handlers/activity.d.ts +0 -25
- package/dist/server/handlers/activity.d.ts.map +0 -1
- package/dist/server/handlers/identity-full.d.ts +0 -28
- package/dist/server/handlers/identity-full.d.ts.map +0 -1
- package/dist/server/handlers/identity-only.d.ts +0 -22
- package/dist/server/handlers/identity-only.d.ts.map +0 -1
- package/dist/server/handlers/user.d.ts +0 -31
- package/dist/server/handlers/user.d.ts.map +0 -1
- package/dist/server/lib/build-activity-events.d.ts +0 -67
- package/dist/server/lib/build-activity-events.d.ts.map +0 -1
- package/dist/server/lib/build-user-profile.d.ts.map +0 -1
|
@@ -12,7 +12,7 @@ type AnyHandlers = Handlers | IdentityOnlyHandlers;
|
|
|
12
12
|
/**
|
|
13
13
|
* A canonical route identifier for Timeback's built-in endpoints.
|
|
14
14
|
*/
|
|
15
|
-
type TimebackRouteId = 'identity.signIn' | 'identity.callback' | 'identity.signOut' | 'user.me' | 'activity';
|
|
15
|
+
type TimebackRouteId = 'identity.signIn' | 'identity.callback' | 'identity.signOut' | 'user.me' | 'user.verify' | 'activity';
|
|
16
16
|
/**
|
|
17
17
|
* Normalize a path-like string to a pathname only (no query string).
|
|
18
18
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C;;GAEG;AACH,KAAK,WAAW,GAAG,QAAQ,GAAG,oBAAoB,CAAA;AAElD;;GAEG;AACH,KAAK,eAAe,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,SAAS,GACT,UAAU,CAAA;AAEb;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBtD;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,eAAe,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAE/C;;GAEG;AACH,KAAK,WAAW,GAAG,QAAQ,GAAG,oBAAoB,CAAA;AAElD;;GAEG;AACH,KAAK,eAAe,GACjB,iBAAiB,GACjB,mBAAmB,GACnB,kBAAkB,GAClB,SAAS,GACT,aAAa,GACb,UAAU,CAAA;AAEb;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBtD;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,eAAe,GAAG,IAAI,CAwDzB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,WAAW,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE9E;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,GAAG,QAAQ,IAAI,QAAQ,CAE1E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Attempt Resolution (for process: true)
|
|
3
|
+
*
|
|
4
|
+
* Resolves attempt numbers for Caliper ActivityEvents when using `process: true`.
|
|
5
|
+
*
|
|
6
|
+
* When `process: true` is set, timeback-api-2 creates assessment line items and results
|
|
7
|
+
* using a specific ID format. This module computes the same line item ID so the SDK can
|
|
8
|
+
* query existing results and determine the correct attempt number before sending the event.
|
|
9
|
+
*
|
|
10
|
+
* Line Item ID formula (matches timeback-api-2's handleExternalUrl):
|
|
11
|
+
* `caliper_${sha256(objectId + "_" + courseSourcedId)}`
|
|
12
|
+
*
|
|
13
|
+
* Attempt semantics:
|
|
14
|
+
* - `attempt` is 1-based, stored in `metadata.attempt` on assessment results
|
|
15
|
+
* - Retry detection: if `endedAt` matches an existing result's `metadata.endedAt`,
|
|
16
|
+
* the same attempt number is reused (idempotent retry)
|
|
17
|
+
* - New attempt: if no matching `endedAt` is found, attempt is `max(existingAttempt) + 1`
|
|
18
|
+
*/
|
|
19
|
+
import type { TimebackClient } from '@timeback/core';
|
|
20
|
+
/**
|
|
21
|
+
* Compute the assessment line item sourcedId that timeback-api-2 creates for external URLs.
|
|
22
|
+
*
|
|
23
|
+
* This matches the logic in timeback-api-2's `handleExternalUrl` function:
|
|
24
|
+
* ```
|
|
25
|
+
* const idParts = [objectId, course.sourcedId].join("_")
|
|
26
|
+
* const hashedId = createHash("sha256").update(idParts).digest("hex")
|
|
27
|
+
* const sourcedId = `caliper_${hashedId}`
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
30
|
+
* @param objectId - The canonical activity URL (`object.id` in the Caliper event)
|
|
31
|
+
* @param courseSourcedId - The OneRoster course sourcedId
|
|
32
|
+
* @returns The line item sourcedId that timeback-api-2 will create
|
|
33
|
+
*/
|
|
34
|
+
export declare function computeCaliperLineItemId(objectId: string, courseSourcedId: string): string;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the attempt number for a Caliper ActivityEvent.
|
|
37
|
+
*
|
|
38
|
+
* This queries assessment results created by timeback-api-2 to determine
|
|
39
|
+
* the correct attempt number before sending the Caliper event.
|
|
40
|
+
*
|
|
41
|
+
* - If an existing result has `endedAt` matching the payload, return its attempt (retry).
|
|
42
|
+
* - Otherwise, return `max(metadata.attempt) + 1` (new attempt).
|
|
43
|
+
*
|
|
44
|
+
* @param client - Timeback client
|
|
45
|
+
* @param lineItemId - The assessment line item sourcedId (computed via `computeCaliperLineItemId`)
|
|
46
|
+
* @param timebackId - The student's Timeback user sourcedId
|
|
47
|
+
* @param endedAt - The activity end timestamp from the client payload
|
|
48
|
+
* @returns The attempt number to use (1-based)
|
|
49
|
+
*/
|
|
50
|
+
export declare function resolveCaliperAttemptNumber(client: TimebackClient, lineItemId: string, timebackId: string, endedAt: string): Promise<number>;
|
|
51
|
+
//# sourceMappingURL=attempts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attempts.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/attempts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AASpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAG1F;AAgED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,2BAA2B,CAChD,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CA4DjB"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { ActivityCompletedEvent, TimebackActivityContext, TimebackActivityMetric, TimeSpentEvent, TimeSpentMetric } from '@timeback/caliper';
|
|
2
|
+
import type { Environment, TimebackClient } from '@timeback/core';
|
|
3
|
+
import type { ActivityCourseRef, ActivityMetrics } from '../../../shared/types';
|
|
4
|
+
import type { ActivityBeforeSendData, AppConfig } from '../../types';
|
|
5
|
+
import type { ValidatedActivityPayload } from './types';
|
|
6
|
+
/**
|
|
7
|
+
* Activity Caliper Events
|
|
8
|
+
*
|
|
9
|
+
* Build and send Caliper events for activity submissions.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Error thrown when a course is missing a synced ID for the target environment.
|
|
13
|
+
*/
|
|
14
|
+
export declare class MissingSyncedCourseIdError extends Error {
|
|
15
|
+
readonly course: AppConfig['courses'][number];
|
|
16
|
+
readonly env: Environment;
|
|
17
|
+
constructor(course: AppConfig['courses'][number], env: Environment);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Error thrown when the sensor URL is invalid.
|
|
21
|
+
*/
|
|
22
|
+
export declare class InvalidSensorUrlError extends Error {
|
|
23
|
+
readonly sensor: string;
|
|
24
|
+
constructor(sensor: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build a canonical activity URL from sensor, course selector, and activity slug.
|
|
28
|
+
*
|
|
29
|
+
* The resulting URL uniquely identifies the activity and allows upstream systems
|
|
30
|
+
* to process it as an "external URL" activity without requiring pre-synced
|
|
31
|
+
* OneRoster component resources.
|
|
32
|
+
*
|
|
33
|
+
* URL structure:
|
|
34
|
+
* - Grade-based: `{sensor}/activities/{subject}/g{grade}/{slug}`
|
|
35
|
+
* - Grade-less: `{sensor}/activities/{code}/{slug}`
|
|
36
|
+
*
|
|
37
|
+
* @param sensor - Sensor URL (must be a valid absolute URL)
|
|
38
|
+
* @param selector - Course selector from activity payload
|
|
39
|
+
* @param slug - Activity slug (will be URI-encoded)
|
|
40
|
+
* @returns Canonical activity URL
|
|
41
|
+
* @throws {InvalidSensorUrlError} If sensor is not a valid absolute URL
|
|
42
|
+
*
|
|
43
|
+
* @example Grade-based
|
|
44
|
+
* ```typescript
|
|
45
|
+
* buildCanonicalActivityUrl(
|
|
46
|
+
* 'https://sensor.example.com',
|
|
47
|
+
* { subject: 'Math', grade: 3 },
|
|
48
|
+
* 'fractions-with-like-denominators'
|
|
49
|
+
* )
|
|
50
|
+
* // => 'https://sensor.example.com/activities/Math/g3/fractions-with-like-denominators'
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Grade-less
|
|
54
|
+
* ```typescript
|
|
55
|
+
* buildCanonicalActivityUrl(
|
|
56
|
+
* 'https://sensor.example.com',
|
|
57
|
+
* { code: 'CS-101' },
|
|
58
|
+
* 'intro-to-loops'
|
|
59
|
+
* )
|
|
60
|
+
* // => 'https://sensor.example.com/activities/CS-101/intro-to-loops'
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildCanonicalActivityUrl(sensor: string, selector: ActivityCourseRef, slug: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Build a Timeback activity context for Caliper events.
|
|
66
|
+
*
|
|
67
|
+
* Handles both grade-based and grade-less courses:
|
|
68
|
+
* - Grade-based: uses subject + grade for IDs
|
|
69
|
+
* - Grade-less: uses code for IDs
|
|
70
|
+
*
|
|
71
|
+
* The `id` field (`object.id` in Caliper) is a canonical URL derived from the
|
|
72
|
+
* sensor, course selector, and activity slug. This enables upstream systems to
|
|
73
|
+
* process the activity as an "external URL" activity without requiring
|
|
74
|
+
* pre-synced OneRoster component resources.
|
|
75
|
+
*
|
|
76
|
+
* The `activity` field contains only the human-readable `name` (no `id`),
|
|
77
|
+
* since the canonical URL in `object.id` serves as the stable identifier.
|
|
78
|
+
*
|
|
79
|
+
* @param payload - Validated activity payload
|
|
80
|
+
* @param course - Matched course config
|
|
81
|
+
* @param appName - Timeback app display name
|
|
82
|
+
* @param apiEnv - Target Timeback API environment
|
|
83
|
+
* @param sensor - Sensor URL for building the canonical activity URL
|
|
84
|
+
* @param onerosterBaseUrl - OneRoster API base URL for building course URL
|
|
85
|
+
* @returns Caliper activity context payload
|
|
86
|
+
*/
|
|
87
|
+
export declare function buildActivityContext(payload: {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
course: ActivityCourseRef;
|
|
91
|
+
}, course: AppConfig['courses'][number], appName: string, apiEnv: Environment, sensor: string, onerosterBaseUrl: string): TimebackActivityContext;
|
|
92
|
+
/**
|
|
93
|
+
* Build Caliper activity metrics from the client payload.
|
|
94
|
+
*
|
|
95
|
+
* @param metrics - Activity metrics from the client
|
|
96
|
+
* @returns Normalized Caliper activity metrics
|
|
97
|
+
*/
|
|
98
|
+
export declare function buildActivityMetrics(metrics: ActivityMetrics): TimebackActivityMetric[];
|
|
99
|
+
/**
|
|
100
|
+
* Build Caliper time spent metrics from elapsed and paused times.
|
|
101
|
+
*
|
|
102
|
+
* @param elapsedMs - Active time in milliseconds
|
|
103
|
+
* @param pausedMs - Paused time in milliseconds
|
|
104
|
+
* @returns Normalized Caliper time spent metrics
|
|
105
|
+
*/
|
|
106
|
+
export declare function buildTimeSpentMetrics(elapsedMs: number, pausedMs: number): TimeSpentMetric[];
|
|
107
|
+
/**
|
|
108
|
+
* Build Caliper events for an activity.
|
|
109
|
+
*
|
|
110
|
+
* @param params - Event building parameters
|
|
111
|
+
* @returns Built events and context
|
|
112
|
+
*/
|
|
113
|
+
export declare function buildActivityEvents(params: {
|
|
114
|
+
sensor: string;
|
|
115
|
+
timebackId: string;
|
|
116
|
+
email: string;
|
|
117
|
+
payload: ValidatedActivityPayload;
|
|
118
|
+
course: AppConfig['courses'][number];
|
|
119
|
+
appName: string;
|
|
120
|
+
apiEnv: Environment;
|
|
121
|
+
onerosterBaseUrl: string;
|
|
122
|
+
attempt?: number;
|
|
123
|
+
}): ActivityBeforeSendData;
|
|
124
|
+
/**
|
|
125
|
+
* Send a batch of Caliper events as a single envelope.
|
|
126
|
+
*
|
|
127
|
+
* @param client - Timeback API client
|
|
128
|
+
* @param sensor - Caliper sensor URL
|
|
129
|
+
* @param activityEvent - ActivityEvent payload
|
|
130
|
+
* @param timeSpentEvent - TimeSpentEvent payload
|
|
131
|
+
*/
|
|
132
|
+
export declare function sendCaliperEnvelope(client: TimebackClient, sensor: string, activityEvent: ActivityCompletedEvent, timeSpentEvent: TimeSpentEvent): Promise<void>;
|
|
133
|
+
//# sourceMappingURL=caliper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caliper.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/caliper.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EAEtB,cAAc,EACd,eAAe,EACf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACpE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAEvD;;;;GAIG;AAMH;;GAEG;AACH,qBAAa,0BAA2B,SAAQ,KAAK;IACpD,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IAC7C,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAA;IAEzB,YAAY,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,EAWjE;CACD;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IAEvB,YAAY,MAAM,EAAE,MAAM,EAMzB;CACD;AAuGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,yBAAyB,CACxC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,MAAM,GACV,MAAM,CAoBR;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,CAAA;CAAE,EAChE,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EACpC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,MAAM,GACtB,uBAAuB,CAuBzB;AAMD;;;;;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;AA2DD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE;IAC3C,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,wBAAwB,CAAA;IACjC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,WAAW,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;CAChB,GAAG,sBAAsB,CAkDzB;AAMD;;;;;;;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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mastery Completion Entry
|
|
3
|
+
*
|
|
4
|
+
* Creates a special "mastery-completion" line item + result when course mastery is achieved.
|
|
5
|
+
* This line item IS connected to `componentResource`, which triggers course completion
|
|
6
|
+
* on dashboards — unlike regular activity line items which intentionally omit the link
|
|
7
|
+
* to prevent premature completion.
|
|
8
|
+
*
|
|
9
|
+
* @see Playcademy's MasteryTracker.createCompletionEntry for the original pattern
|
|
10
|
+
*/
|
|
11
|
+
import type { TimebackClient } from '@timeback/core';
|
|
12
|
+
/**
|
|
13
|
+
* Parameters for maybeWriteCompletionEntry.
|
|
14
|
+
*/
|
|
15
|
+
interface CompletionEntryParams {
|
|
16
|
+
/** Timeback client instance */
|
|
17
|
+
client: TimebackClient;
|
|
18
|
+
/** Course sourcedId (synced from config) */
|
|
19
|
+
courseId: string;
|
|
20
|
+
/** Student's Timeback user ID */
|
|
21
|
+
timebackId: string;
|
|
22
|
+
/** Computed percentage complete (0-100) */
|
|
23
|
+
pctComplete: number | undefined;
|
|
24
|
+
/** Application name for metadata */
|
|
25
|
+
appName: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a mastery completion entry if the student has achieved 100% completion.
|
|
29
|
+
*
|
|
30
|
+
* This is a workaround for OneRoster/dashboard completion detection:
|
|
31
|
+
* - Regular line items are NOT connected to the component resource
|
|
32
|
+
* (to prevent the first fully-graded result from marking the course complete)
|
|
33
|
+
* - This special "mastery-completion" line item IS connected to the component resource
|
|
34
|
+
* - When mastery is achieved (pctComplete === 100), we create this line item + a fully graded result
|
|
35
|
+
* - This triggers course completion while allowing XP to aggregate normally
|
|
36
|
+
*
|
|
37
|
+
* XXX: errors are logged but do not fail the overall request.
|
|
38
|
+
*
|
|
39
|
+
* @param params - Completion entry parameters
|
|
40
|
+
*/
|
|
41
|
+
export declare function maybeWriteCompletionEntry(params: CompletionEntryParams): Promise<void>;
|
|
42
|
+
export {};
|
|
43
|
+
//# sourceMappingURL=completion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completion.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/completion.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIpD;;GAEG;AACH,UAAU,qBAAqB;IAC9B,+BAA+B;IAC/B,MAAM,EAAE,cAAc,CAAA;IACtB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAA;IAChB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF5F"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Handler
|
|
3
|
+
*
|
|
4
|
+
* HTTP route handler for activity submissions.
|
|
5
|
+
* Orchestrates validation, user resolution, gradebook writes, and Caliper event sending.
|
|
6
|
+
*/
|
|
7
|
+
import { maybeWriteCompletionEntry as maybeWriteCompletionEntryImpl } from './completion';
|
|
8
|
+
import { computeProgress as computeProgressImpl } from './progress';
|
|
9
|
+
import type { ActivityHandler, ActivityHandlerConfig } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies for handler.
|
|
12
|
+
*
|
|
13
|
+
* This interface enables unit tests to inject mock implementations of
|
|
14
|
+
* computeProgress and maybeWriteCompletionEntry without mocking the entire
|
|
15
|
+
* TimebackClient.
|
|
16
|
+
*
|
|
17
|
+
* Not part of the public API - only exposed for testing purposes.
|
|
18
|
+
*/
|
|
19
|
+
interface ActivityHandlerDeps {
|
|
20
|
+
computeProgress: typeof computeProgressImpl;
|
|
21
|
+
maybeWriteCompletionEntry: typeof maybeWriteCompletionEntryImpl;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create the activity POST handler.
|
|
25
|
+
*
|
|
26
|
+
* @param config - Handler configuration
|
|
27
|
+
* @param deps - Internal dependencies (for testing only, not part of public API)
|
|
28
|
+
* @returns The activity request handler
|
|
29
|
+
*/
|
|
30
|
+
export declare function createActivityHandler(config: ActivityHandlerConfig, deps?: ActivityHandlerDeps): ActivityHandler;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,OAAO,EAAE,yBAAyB,IAAI,6BAA6B,EAAE,MAAM,cAAc,CAAA;AACzF,OAAO,EAAE,eAAe,IAAI,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAKnE,OAAO,KAAK,EACX,eAAe,EACf,qBAAqB,EAGrB,MAAM,SAAS,CAAA;AAQhB;;;;;;;;GAQG;AACH,UAAU,mBAAmB;IAC5B,eAAe,EAAE,OAAO,mBAAmB,CAAA;IAC3C,yBAAyB,EAAE,OAAO,6BAA6B,CAAA;CAC/D;AA+HD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,qBAAqB,EAC7B,IAAI,GAAE,mBAAiC,GACrC,eAAe,CAuLjB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Handler
|
|
3
|
+
*
|
|
4
|
+
* Route handler for activity tracking and submission.
|
|
5
|
+
*/
|
|
6
|
+
export { createActivityHandler } from './handler';
|
|
7
|
+
export { buildActivityContext, buildActivityMetrics, buildTimeSpentMetrics, InvalidSensorUrlError, MissingSyncedCourseIdError, sendCaliperEnvelope, } from './caliper';
|
|
8
|
+
export type { ActivityHandler, ActivityHandlerConfig, ActivityUserInfo, ValidatedActivityPayload, ValidationResult, } from './types';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAA;AAEjD,OAAO,EACN,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,0BAA0B,EAC1B,mBAAmB,GACnB,MAAM,WAAW,CAAA;AAElB,YAAY,EACX,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EAChB,wBAAwB,EACxB,gBAAgB,GAChB,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Progress Computation
|
|
3
|
+
*
|
|
4
|
+
* Computes `pctComplete` by aggregating historical mastered units from EduBridge
|
|
5
|
+
* enrollment analytics and combining with the current submission's mastered units.
|
|
6
|
+
*/
|
|
7
|
+
import type { TimebackClient } from '@timeback/core';
|
|
8
|
+
import type { AppConfig, Environment } from '../../types';
|
|
9
|
+
import type { ValidatedActivityPayload } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Result of progress computation.
|
|
12
|
+
*/
|
|
13
|
+
interface ProgressResult {
|
|
14
|
+
/** Computed percentage (0-100) */
|
|
15
|
+
pctComplete: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve the total lessons denominator from course config.
|
|
19
|
+
*
|
|
20
|
+
* Checks env-specific overrides first, then falls back to base metadata.
|
|
21
|
+
*
|
|
22
|
+
* @param course - Course config
|
|
23
|
+
* @param env - Target environment
|
|
24
|
+
* @returns Total lessons count, or undefined if not configured
|
|
25
|
+
*/
|
|
26
|
+
export declare function resolveTotalLessons(course: AppConfig['courses'][number], env: Environment): number | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* Compute pctComplete for an activity submission.
|
|
29
|
+
*
|
|
30
|
+
* Only computes when:
|
|
31
|
+
* - `totalLessons` is configured (> 0) for the course
|
|
32
|
+
* - `metrics.masteredUnits` is present and > 0 in the payload
|
|
33
|
+
* - `pctComplete` is not already provided by the client
|
|
34
|
+
*
|
|
35
|
+
* @param params - Computation parameters
|
|
36
|
+
* @returns Progress result with pctComplete, or undefined if conditions not met
|
|
37
|
+
*/
|
|
38
|
+
export declare function computeProgress(params: {
|
|
39
|
+
client: TimebackClient;
|
|
40
|
+
courseId: string;
|
|
41
|
+
timebackId: string;
|
|
42
|
+
payload: ValidatedActivityPayload;
|
|
43
|
+
course: AppConfig['courses'][number];
|
|
44
|
+
env: Environment;
|
|
45
|
+
}): Promise<ProgressResult | undefined>;
|
|
46
|
+
export {};
|
|
47
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/progress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAIvD;;GAEG;AACH,UAAU,cAAc;IACvB,kCAAkC;IAClC,WAAW,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,EACpC,GAAG,EAAE,WAAW,GACd,MAAM,GAAG,SAAS,CAMpB;AAcD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC7C,MAAM,EAAE,cAAc,CAAA;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,wBAAwB,CAAA;IACjC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IACpC,GAAG,EAAE,WAAW,CAAA;CAChB,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAkLtC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Course Resolution
|
|
3
|
+
*
|
|
4
|
+
* Resolves course selectors from activity payloads to configured courses.
|
|
5
|
+
*/
|
|
6
|
+
import type { ActivityCourseRef } from '../../../shared/types';
|
|
7
|
+
import type { AppConfig } from '../../types';
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown when a course selector cannot be resolved against config.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ActivityCourseResolutionError extends Error {
|
|
12
|
+
readonly code: 'unknown_course' | 'ambiguous_course';
|
|
13
|
+
readonly selector: ActivityCourseRef;
|
|
14
|
+
readonly count?: number;
|
|
15
|
+
constructor(code: ActivityCourseResolutionError['code'], selector: ActivityCourseRef, count?: number);
|
|
16
|
+
/**
|
|
17
|
+
* Get a human-readable description of the selector.
|
|
18
|
+
*
|
|
19
|
+
* @returns Human-readable selector description
|
|
20
|
+
*/
|
|
21
|
+
get selectorDescription(): string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a course config entry from an activity course selector.
|
|
25
|
+
*
|
|
26
|
+
* **Use case:** Activity handler — match the client's course selector
|
|
27
|
+
* to a configured course in `timeback.config.json`.
|
|
28
|
+
*
|
|
29
|
+
* Supports two selector modes:
|
|
30
|
+
* - **subjectGrade**: Match by `(subject, grade)`
|
|
31
|
+
* - **courseCode**: Match by `courseCode`
|
|
32
|
+
*
|
|
33
|
+
* @param courses - Configured courses from `timeback.config.json`
|
|
34
|
+
* @param courseRef - Course selector from the client payload
|
|
35
|
+
* @returns Matched course config entry
|
|
36
|
+
* @throws {ActivityCourseResolutionError} When selector is unknown or ambiguous
|
|
37
|
+
*/
|
|
38
|
+
export declare function resolveActivityCourse(courses: AppConfig['courses'], courseRef: ActivityCourseRef): AppConfig['courses'][number];
|
|
39
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/resolve.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAE5C;;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;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CACpC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,EAC7B,SAAS,EAAE,iBAAiB,GAC1B,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAoB9B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Handler Schema
|
|
3
|
+
*
|
|
4
|
+
* Zod schemas and validation logic for activity submissions.
|
|
5
|
+
*/
|
|
6
|
+
import * as z from 'zod';
|
|
7
|
+
import type { AppConfig, Environment } from '../../types';
|
|
8
|
+
import type { ValidationResult } from './types';
|
|
9
|
+
/** Zod schema for validating activity payloads. */
|
|
10
|
+
export declare const activityPayloadSchema: z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
course: z.ZodUnion<readonly [z.ZodObject<{
|
|
14
|
+
subject: z.ZodEnum<{
|
|
15
|
+
FastMath: "FastMath";
|
|
16
|
+
Language: "Language";
|
|
17
|
+
Math: "Math";
|
|
18
|
+
None: "None";
|
|
19
|
+
Other: "Other";
|
|
20
|
+
Reading: "Reading";
|
|
21
|
+
Science: "Science";
|
|
22
|
+
"Social Studies": "Social Studies";
|
|
23
|
+
Vocabulary: "Vocabulary";
|
|
24
|
+
Writing: "Writing";
|
|
25
|
+
}>;
|
|
26
|
+
grade: z.ZodUnion<readonly [z.ZodLiteral<-1>, z.ZodLiteral<0>, z.ZodLiteral<1>, z.ZodLiteral<2>, z.ZodLiteral<3>, z.ZodLiteral<4>, z.ZodLiteral<5>, z.ZodLiteral<6>, z.ZodLiteral<7>, z.ZodLiteral<8>, z.ZodLiteral<9>, z.ZodLiteral<10>, z.ZodLiteral<11>, z.ZodLiteral<12>, z.ZodLiteral<13>]>;
|
|
27
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
28
|
+
code: z.ZodString;
|
|
29
|
+
}, z.core.$strip>]>;
|
|
30
|
+
startedAt: z.ZodISODateTime;
|
|
31
|
+
endedAt: z.ZodISODateTime;
|
|
32
|
+
elapsedMs: z.ZodNumber;
|
|
33
|
+
pausedMs: z.ZodNumber;
|
|
34
|
+
metrics: z.ZodObject<{
|
|
35
|
+
totalQuestions: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
correctQuestions: z.ZodOptional<z.ZodNumber>;
|
|
37
|
+
xpEarned: z.ZodOptional<z.ZodNumber>;
|
|
38
|
+
masteredUnits: z.ZodOptional<z.ZodNumber>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
pctComplete: z.ZodPipe<z.ZodOptional<z.ZodNumber>, z.ZodTransform<number | undefined, number | undefined>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
/**
|
|
43
|
+
* Validate the activity request body and resolve config dependencies.
|
|
44
|
+
*
|
|
45
|
+
* @param body - Raw request body
|
|
46
|
+
* @param appConfig - App configuration
|
|
47
|
+
* @param env - Environment
|
|
48
|
+
* @returns Validated data or error response
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateActivityRequest(body: unknown, appConfig: AppConfig, env: Environment): ValidationResult;
|
|
51
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/schema.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAWxB,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AA0E/C,mDAAmD;AACnD,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAahC,CAAA;AAmBF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,WAAW,GACd,gBAAgB,CAiHlB"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activity Handler Types
|
|
3
|
+
*
|
|
4
|
+
* Feature-local types for the activity submission flow.
|
|
5
|
+
*/
|
|
6
|
+
import type { ActivityCourseRef } from '../../../shared/types';
|
|
7
|
+
import type { ApiCredentials, AppConfig, Environment, IdentityConfig, TimebackConfig } from '../../types';
|
|
8
|
+
/** User identity info needed for activity submission. */
|
|
9
|
+
export interface ActivityUserInfo {
|
|
10
|
+
email: string;
|
|
11
|
+
/** Timeback ID if already resolved (SSO mode). When present, skip lookup. */
|
|
12
|
+
timebackId?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Validated activity payload ready for submission. */
|
|
15
|
+
export interface ValidatedActivityPayload {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
course: ActivityCourseRef;
|
|
19
|
+
startedAt: string;
|
|
20
|
+
endedAt: string;
|
|
21
|
+
elapsedMs: number;
|
|
22
|
+
pausedMs: number;
|
|
23
|
+
metrics: {
|
|
24
|
+
totalQuestions?: number;
|
|
25
|
+
correctQuestions?: number;
|
|
26
|
+
xpEarned?: number;
|
|
27
|
+
masteredUnits?: number;
|
|
28
|
+
};
|
|
29
|
+
pctComplete?: number;
|
|
30
|
+
}
|
|
31
|
+
/** Result of request validation - either valid data or an error response. */
|
|
32
|
+
export type ValidationResult = {
|
|
33
|
+
ok: true;
|
|
34
|
+
payload: ValidatedActivityPayload;
|
|
35
|
+
course: AppConfig['courses'][number];
|
|
36
|
+
sensor: string;
|
|
37
|
+
} | {
|
|
38
|
+
ok: false;
|
|
39
|
+
response: Response;
|
|
40
|
+
};
|
|
41
|
+
/** Configuration for the activity handler. */
|
|
42
|
+
export interface ActivityHandlerConfig {
|
|
43
|
+
env: Environment;
|
|
44
|
+
identity: IdentityConfig;
|
|
45
|
+
appConfig: AppConfig;
|
|
46
|
+
api: ApiCredentials;
|
|
47
|
+
hooks?: TimebackConfig['hooks'];
|
|
48
|
+
}
|
|
49
|
+
/** Activity handler type. */
|
|
50
|
+
export type ActivityHandler = (req: Request) => Promise<Response>;
|
|
51
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/activity/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,KAAK,EACX,cAAc,EACd,SAAS,EACT,WAAW,EACX,cAAc,EACd,cAAc,EACd,MAAM,aAAa,CAAA;AAMpB,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB;AAMD,uDAAuD;AACvD,MAAM,WAAW,wBAAwB;IACxC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,iBAAiB,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,aAAa,CAAC,EAAE,MAAM,CAAA;KACtB,CAAA;IACD,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAMD,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,GACzB;IACA,EAAE,EAAE,IAAI,CAAA;IACR,OAAO,EAAE,wBAAwB,CAAA;IACjC,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAA;IACpC,MAAM,EAAE,MAAM,CAAA;CACb,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,CAAA;AAMpC,8CAA8C;AAC9C,MAAM,WAAW,qBAAqB;IACrC,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,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Handlers (full SDK)
|
|
3
|
+
*
|
|
4
|
+
* This module includes Timeback user resolution and therefore depends on Timeback API access.
|
|
5
|
+
*/
|
|
6
|
+
import type { IdentityHandlerParams, IdentityHandlers } from './types';
|
|
7
|
+
/**
|
|
8
|
+
* Create identity route handlers (full SDK).
|
|
9
|
+
*
|
|
10
|
+
* @param params - Handler configuration
|
|
11
|
+
* @returns Identity handlers
|
|
12
|
+
*/
|
|
13
|
+
export declare function createIdentityHandlers<TState = unknown>(params: IdentityHandlerParams<TState>): IdentityHandlers;
|
|
14
|
+
//# sourceMappingURL=handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/identity/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAEtE;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,GAAG,OAAO,EACtD,MAAM,EAAE,qBAAqB,CAAC,MAAM,CAAC,GACnC,gBAAgB,CAQlB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Handler (full SDK)
|
|
3
|
+
*
|
|
4
|
+
* Route handlers for SSO authentication with Timeback user resolution.
|
|
5
|
+
*/
|
|
6
|
+
export { createIdentityHandlers } from './handler';
|
|
7
|
+
export type { IdentityHandlerParams, IdentityHandlers } from './types';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/identity/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAA;AAClD,YAAY,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity OIDC Flow
|
|
3
|
+
*
|
|
4
|
+
* Sign-in, callback, and token exchange for SSO authentication.
|
|
5
|
+
* This is the full SDK version that resolves Timeback users.
|
|
6
|
+
*/
|
|
7
|
+
import type { Environment, IdentityConfig } from '../../types';
|
|
8
|
+
import type { IdentityHandlerParams } from './types';
|
|
9
|
+
/**
|
|
10
|
+
* Handle sign-in request.
|
|
11
|
+
*
|
|
12
|
+
* @param req - Incoming request
|
|
13
|
+
* @param env - Environment configuration
|
|
14
|
+
* @param identity - Identity configuration
|
|
15
|
+
* @returns Redirect response to IdP
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleSignIn<TState>(req: Request, env: Environment, identity: IdentityConfig<TState>): Promise<Response>;
|
|
18
|
+
/**
|
|
19
|
+
* Exchange code for tokens and complete SSO flow (full SDK).
|
|
20
|
+
*
|
|
21
|
+
* @param code - Authorization code
|
|
22
|
+
* @param url - Callback URL
|
|
23
|
+
* @param state - Decoded state (if provided)
|
|
24
|
+
* @param req - Incoming request
|
|
25
|
+
* @param env - Environment configuration
|
|
26
|
+
* @param identity - SSO identity configuration
|
|
27
|
+
* @param api - Timeback API provider (credentials + shared client getter)
|
|
28
|
+
* @returns Success or error response
|
|
29
|
+
*/
|
|
30
|
+
export declare function completeCallback<TState>(code: string, url: URL, state: TState | undefined, req: Request, env: Environment, identity: IdentityConfig<TState> & {
|
|
31
|
+
mode: 'sso';
|
|
32
|
+
}, api: IdentityHandlerParams<TState>['api']): Promise<Response>;
|
|
33
|
+
/**
|
|
34
|
+
* Handle callback request.
|
|
35
|
+
*
|
|
36
|
+
* @param req - Incoming request
|
|
37
|
+
* @param env - Environment configuration
|
|
38
|
+
* @param identity - Identity configuration
|
|
39
|
+
* @param api - Timeback API provider (credentials + shared client getter)
|
|
40
|
+
* @returns Response from callback handler
|
|
41
|
+
*/
|
|
42
|
+
export declare function handleCallback<TState>(req: Request, env: Environment, identity: IdentityConfig<TState>, api: IdentityHandlerParams<TState>['api']): Promise<Response>;
|
|
43
|
+
//# sourceMappingURL=oidc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidc.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/identity/oidc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAqBH,OAAO,KAAK,EAA0B,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAMpD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,MAAM,EACxC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,GAC9B,OAAO,CAAC,QAAQ,CAAC,CAcnB;AAMD;;;;;;;;;;;GAWG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAC5C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,EAClD,GAAG,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GACvC,OAAO,CAAC,QAAQ,CAAC,CA0DnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAC1C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,WAAW,EAChB,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,EAChC,GAAG,EAAE,qBAAqB,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GACvC,OAAO,CAAC,QAAQ,CAAC,CAiBnB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Handler Types (full SDK)
|
|
3
|
+
*
|
|
4
|
+
* Feature-local types for the identity/SSO handlers.
|
|
5
|
+
*/
|
|
6
|
+
import type { TimebackClient } from '@timeback/core';
|
|
7
|
+
import type { ApiCredentials, CallbackErrorContext, CallbackSuccessContext, Environment, IdentityConfig, SsoIdentityConfig } from '../../types';
|
|
8
|
+
/** Configuration for identity handlers (full SDK). */
|
|
9
|
+
export interface IdentityHandlerParams<TState = unknown> {
|
|
10
|
+
env: Environment;
|
|
11
|
+
identity: IdentityConfig<TState>;
|
|
12
|
+
api: {
|
|
13
|
+
credentials: ApiCredentials;
|
|
14
|
+
getClient: () => TimebackClient;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/** Identity handlers returned by createIdentityHandlers. */
|
|
18
|
+
export interface IdentityHandlers {
|
|
19
|
+
signIn: (req: Request) => Promise<Response>;
|
|
20
|
+
callback: (req: Request) => Promise<Response>;
|
|
21
|
+
signOut: () => Response;
|
|
22
|
+
}
|
|
23
|
+
export type { CallbackErrorContext, CallbackSuccessContext, Environment, IdentityConfig, SsoIdentityConfig, };
|
|
24
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/server/handlers/identity/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EACX,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,MAAM,aAAa,CAAA;AAEpB,sDAAsD;AACtD,MAAM,WAAW,qBAAqB,CAAC,MAAM,GAAG,OAAO;IACtD,GAAG,EAAE,WAAW,CAAA;IAChB,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,CAAA;IAChC,GAAG,EAAE;QACJ,WAAW,EAAE,cAAc,CAAA;QAC3B,SAAS,EAAE,MAAM,cAAc,CAAA;KAC/B,CAAA;CACD;AAED,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC3C,QAAQ,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7C,OAAO,EAAE,MAAM,QAAQ,CAAA;CACvB;AAGD,YAAY,EACX,oBAAoB,EACpB,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,iBAAiB,GACjB,CAAA"}
|