@lti-tool/core 0.9.0 → 0.10.0
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/CHANGELOG.md +6 -0
- package/dist/ltiTool.d.ts +70 -3
- package/dist/ltiTool.d.ts.map +1 -1
- package/dist/ltiTool.js +116 -3
- package/dist/schemas/client.schema.d.ts +1 -1
- package/dist/schemas/client.schema.d.ts.map +1 -1
- package/dist/schemas/client.schema.js +1 -1
- package/dist/schemas/common.schema.d.ts +1 -1
- package/dist/schemas/common.schema.d.ts.map +1 -1
- package/dist/schemas/common.schema.js +1 -1
- package/dist/schemas/deployment.schema.d.ts +1 -1
- package/dist/schemas/deployment.schema.d.ts.map +1 -1
- package/dist/schemas/deployment.schema.js +1 -1
- package/dist/schemas/lti13/ags/lineItem.schema.d.ts +80 -0
- package/dist/schemas/lti13/ags/lineItem.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/ags/lineItem.schema.js +49 -0
- package/dist/schemas/lti13/ags/result.schema.d.ts +65 -0
- package/dist/schemas/lti13/ags/result.schema.d.ts.map +1 -0
- package/dist/schemas/lti13/ags/result.schema.js +35 -0
- package/dist/schemas/lti13/ags/scoreSubmission.schema.d.ts +25 -4
- package/dist/schemas/lti13/ags/scoreSubmission.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/ags/scoreSubmission.schema.js +2 -1
- package/dist/schemas/lti13/claims/baseJwtClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/baseJwtClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/baseJwtClaims.schema.js +1 -1
- package/dist/schemas/lti13/claims/contextClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/contextClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/contextClaims.schema.js +1 -1
- package/dist/schemas/lti13/claims/coreLtiClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/coreLtiClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/coreLtiClaims.schema.js +1 -1
- package/dist/schemas/lti13/claims/platformClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/platformClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/platformClaims.schema.js +1 -1
- package/dist/schemas/lti13/claims/privacyClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/privacyClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/privacyClaims.schema.js +1 -1
- package/dist/schemas/lti13/claims/serviceClaims.schema.d.ts +1 -1
- package/dist/schemas/lti13/claims/serviceClaims.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/claims/serviceClaims.schema.js +1 -1
- package/dist/schemas/lti13/lti13JwtPayload.schema.d.ts +1 -1
- package/dist/schemas/lti13/lti13JwtPayload.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/lti13JwtPayload.schema.js +1 -1
- package/dist/schemas/lti13/lti13Launch.schema.d.ts +1 -1
- package/dist/schemas/lti13/lti13Launch.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/lti13Launch.schema.js +1 -1
- package/dist/schemas/lti13/lti13Login.schema.d.ts +1 -1
- package/dist/schemas/lti13/lti13Login.schema.d.ts.map +1 -1
- package/dist/schemas/lti13/lti13Login.schema.js +1 -1
- package/dist/services/ags.service.d.ts +86 -0
- package/dist/services/ags.service.d.ts.map +1 -1
- package/dist/services/ags.service.js +184 -8
- package/dist/services/token.service.d.ts.map +1 -1
- package/dist/services/token.service.js +2 -1
- package/package.json +1 -1
- package/src/ltiTool.ts +144 -5
- package/src/schemas/client.schema.ts +1 -1
- package/src/schemas/common.schema.ts +1 -1
- package/src/schemas/deployment.schema.ts +1 -1
- package/src/schemas/lti13/ags/lineItem.schema.ts +85 -0
- package/src/schemas/lti13/ags/result.schema.ts +55 -0
- package/src/schemas/lti13/ags/scoreSubmission.schema.ts +3 -1
- package/src/schemas/lti13/claims/baseJwtClaims.schema.ts +1 -1
- package/src/schemas/lti13/claims/contextClaims.schema.ts +1 -1
- package/src/schemas/lti13/claims/coreLtiClaims.schema.ts +1 -1
- package/src/schemas/lti13/claims/platformClaims.schema.ts +1 -1
- package/src/schemas/lti13/claims/privacyClaims.schema.ts +1 -1
- package/src/schemas/lti13/claims/serviceClaims.schema.ts +1 -1
- package/src/schemas/lti13/lti13JwtPayload.schema.ts +1 -1
- package/src/schemas/lti13/lti13Launch.schema.ts +1 -1
- package/src/schemas/lti13/lti13Login.schema.ts +1 -1
- package/src/services/ags.service.ts +253 -16
- package/src/services/token.service.ts +4 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from 'zod';
|
|
2
2
|
export declare const CoreLtiClaimsSchema: z.ZodObject<{
|
|
3
3
|
'https://purl.imsglobal.org/spec/lti/claim/message_type': z.ZodUnion<readonly [z.ZodLiteral<"LtiResourceLinkRequest">, z.ZodLiteral<"LtiDeepLinkingRequest">]>;
|
|
4
4
|
'https://purl.imsglobal.org/spec/lti/claim/version': z.ZodLiteral<"1.3.0">;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coreLtiClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/coreLtiClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"coreLtiClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/coreLtiClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,mBAAmB;;;;;;iBAS9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"platformClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/platformClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"platformClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/platformClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,kBAAkB;;;;;;;;kBAUlB,CAAC;AAEd,eAAO,MAAM,wBAAwB;;;;kBAMxB,CAAC;AAEd,eAAO,MAAM,SAAS;;kBAIT,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"privacyClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/privacyClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"privacyClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/privacyClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serviceClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/serviceClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"serviceClaims.schema.d.ts","sourceRoot":"","sources":["../../../../src/schemas/lti13/claims/serviceClaims.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,iBAAiB;;;;kBAMjB,CAAC;AAEd,eAAO,MAAM,iBAAiB;;;kBAKjB,CAAC;AAEd,eAAO,MAAM,yBAAyB;;;;;;;;kBAUzB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lti13JwtPayload.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13JwtPayload.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"lti13JwtPayload.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13JwtPayload.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAiBzB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgB9B,CAAC;AAEL,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as z from 'zod';
|
|
2
2
|
import { BaseJwtClaimsSchema } from './claims/baseJwtClaims.schema.js';
|
|
3
3
|
import { ContextSchema, ResourceLinkSchema } from './claims/contextClaims.schema.js';
|
|
4
4
|
import { CoreLtiClaimsSchema } from './claims/coreLtiClaims.schema.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lti13Launch.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13Launch.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"lti13Launch.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13Launch.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,iBAAiB;;;iBAG5B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,wBAAwB;;;iBAGnC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lti13Login.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13Login.schema.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"lti13Login.schema.d.ts","sourceRoot":"","sources":["../../../src/schemas/lti13/lti13Login.schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,eAAO,MAAM,gBAAgB;;;;;;;iBAO3B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;iBAElC,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BaseLogger } from 'pino';
|
|
2
2
|
import type { LTISession } from '../interfaces/ltiSession.js';
|
|
3
3
|
import type { LTIStorage } from '../interfaces/ltiStorage.js';
|
|
4
|
+
import type { CreateLineItem, UpdateLineItem } from '../schemas/lti13/ags/lineItem.schema.js';
|
|
4
5
|
import type { ScoreSubmission } from '../schemas/lti13/ags/scoreSubmission.schema.js';
|
|
5
6
|
import type { TokenService } from './token.service.js';
|
|
6
7
|
/**
|
|
@@ -34,5 +35,90 @@ export declare class AGSService {
|
|
|
34
35
|
* ```
|
|
35
36
|
*/
|
|
36
37
|
submitScore(session: LTISession, score: ScoreSubmission): Promise<Response>;
|
|
38
|
+
/**
|
|
39
|
+
* Retrieves all scores for a specific line item from the platform using Assignment and Grade Services.
|
|
40
|
+
*
|
|
41
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
42
|
+
* @returns Promise resolving to the HTTP response containing scores data for the line item
|
|
43
|
+
* @throws {Error} When AGS line item service is not available for the session or request fails
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const response = await agsService.getScores(session);
|
|
48
|
+
* const scores = await response.json();
|
|
49
|
+
* console.log('All scores for this line item:', scores);
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
getScores(session: LTISession): Promise<Response>;
|
|
53
|
+
/**
|
|
54
|
+
* Retrieves line items (gradebook columns) from the platform using Assignment and Grade Services.
|
|
55
|
+
*
|
|
56
|
+
* @param session - Active LTI session containing AGS line items endpoint configuration
|
|
57
|
+
* @returns Promise resolving to the HTTP response containing line items data
|
|
58
|
+
* @throws {Error} When AGS line items service is not available for the session or request fails
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const response = await agsService.listLineItems(session);
|
|
63
|
+
* const lineItems = await response.json();
|
|
64
|
+
* console.log('Available gradebook columns:', lineItems);
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
listLineItems(session: LTISession): Promise<Response>;
|
|
68
|
+
/**
|
|
69
|
+
* Retrieves a specific line item (gradebook column) from the platform using Assignment and Grade Services.
|
|
70
|
+
*
|
|
71
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
72
|
+
* @returns Promise resolving to the HTTP response containing the line item data
|
|
73
|
+
* @throws {Error} When AGS line item service is not available for the session or request fails
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const response = await agsService.getLineItem(session);
|
|
78
|
+
* const lineItem = await response.json();
|
|
79
|
+
* console.log('Line item details:', lineItem);
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
getLineItem(session: LTISession): Promise<Response>;
|
|
83
|
+
/**
|
|
84
|
+
* Creates a new line item (gradebook column) on the platform using Assignment and Grade Services.
|
|
85
|
+
*
|
|
86
|
+
* @param session - Active LTI session containing AGS line items endpoint configuration
|
|
87
|
+
* @param createLineItem - Line item data including label, scoreMaximum, and optional metadata
|
|
88
|
+
* @returns Promise resolving to the HTTP response containing the created line item with generated ID
|
|
89
|
+
* @throws {Error} When AGS line item creation service is not available for the session or creation fails
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const response = await agsService.createLineItem(session, {
|
|
94
|
+
* label: 'Quiz 1',
|
|
95
|
+
* scoreMaximum: 100,
|
|
96
|
+
* tag: 'quiz',
|
|
97
|
+
* resourceId: 'quiz-001'
|
|
98
|
+
* });
|
|
99
|
+
* const newLineItem = await response.json();
|
|
100
|
+
* console.log('Created line item:', newLineItem.id);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
createLineItem(session: LTISession, createLineItem: CreateLineItem): Promise<Response>;
|
|
104
|
+
/**
|
|
105
|
+
* Updates an existing line item (gradebook column) on the platform using Assignment and Grade Services.
|
|
106
|
+
*
|
|
107
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
108
|
+
* @param updateLineItem - Updated line item data including all required fields
|
|
109
|
+
* @returns Promise resolving to the HTTP response containing the updated line item
|
|
110
|
+
* @throws {Error} When AGS line item service is not available for the session or update fails
|
|
111
|
+
*/
|
|
112
|
+
updateLineItem(session: LTISession, updateLineItem: UpdateLineItem): Promise<Response>;
|
|
113
|
+
/**
|
|
114
|
+
* Deletes a line item (gradebook column) from the platform using Assignment and Grade Services.
|
|
115
|
+
*
|
|
116
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
117
|
+
* @returns Promise resolving to the HTTP response (typically 204 No Content on success)
|
|
118
|
+
* @throws {Error} When AGS line item service is not available for the session or deletion fails
|
|
119
|
+
*/
|
|
120
|
+
deleteLineItem(session: LTISession): Promise<Response>;
|
|
121
|
+
private getAGSToken;
|
|
122
|
+
private validateAGSResponse;
|
|
37
123
|
}
|
|
38
124
|
//# sourceMappingURL=ags.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ags.service.d.ts","sourceRoot":"","sources":["../../src/services/ags.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAGtF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;gBAFN,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,UAAU;IAG5B;;;;;;;;;;;;;;;;;;OAkBG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"ags.service.d.ts","sourceRoot":"","sources":["../../src/services/ags.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EACf,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AAGtF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AACH,qBAAa,UAAU;IAEnB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;gBAFN,YAAY,EAAE,YAAY,EAC1B,OAAO,EAAE,UAAU,EACnB,MAAM,EAAE,UAAU;IAG5B;;;;;;;;;;;;;;;;;;OAkBG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC;IAiCjF;;;;;;;;;;;;;OAaG;IACG,SAAS,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IA4BvD;;;;;;;;;;;;;OAaG;IACG,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsB3D;;;;;;;;;;;;;OAaG;IACG,WAAW,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;IAsBzD;;;;;;;;;;;;;;;;;;;OAmBG;IACG,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAuBpB;;;;;;;OAOG;IACG,cAAc,CAClB,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,QAAQ,CAAC;IAuBpB;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC;YAqB9C,WAAW;YAeX,mBAAmB;CAalC"}
|
|
@@ -37,11 +37,7 @@ export class AGSService {
|
|
|
37
37
|
if (!session.services?.ags?.lineitem) {
|
|
38
38
|
throw new Error('AGS not available for this session');
|
|
39
39
|
}
|
|
40
|
-
|
|
41
|
-
const launchConfig = await getValidLaunchConfig(this.storage, session.platform.issuer, session.platform.clientId, session.platform.deploymentId);
|
|
42
|
-
const token = await this.tokenService.getBearerToken(session.platform.clientId,
|
|
43
|
-
// Need to get token URL from platform storage
|
|
44
|
-
launchConfig.tokenUrl, 'https://purl.imsglobal.org/spec/lti-ags/scope/score');
|
|
40
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/score');
|
|
45
41
|
const scorePayload = {
|
|
46
42
|
userId: score.userId,
|
|
47
43
|
scoreGiven: score.scoreGiven,
|
|
@@ -59,11 +55,191 @@ export class AGSService {
|
|
|
59
55
|
},
|
|
60
56
|
body: JSON.stringify(scorePayload),
|
|
61
57
|
});
|
|
58
|
+
await this.validateAGSResponse(response, 'score submission');
|
|
59
|
+
return response;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves all scores for a specific line item from the platform using Assignment and Grade Services.
|
|
63
|
+
*
|
|
64
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
65
|
+
* @returns Promise resolving to the HTTP response containing scores data for the line item
|
|
66
|
+
* @throws {Error} When AGS line item service is not available for the session or request fails
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const response = await agsService.getScores(session);
|
|
71
|
+
* const scores = await response.json();
|
|
72
|
+
* console.log('All scores for this line item:', scores);
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
async getScores(session) {
|
|
76
|
+
if (!session.services?.ags?.lineitem) {
|
|
77
|
+
throw new Error('AGS line item not available for this session');
|
|
78
|
+
}
|
|
79
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly');
|
|
80
|
+
// cleanse the results URL
|
|
81
|
+
// we cannot include a search / query param
|
|
82
|
+
const lineItemUrl = new URL(session.services.ags.lineitem);
|
|
83
|
+
lineItemUrl.search = '';
|
|
84
|
+
const resultsUrl = `${lineItemUrl.toString()}/results`;
|
|
85
|
+
const response = await fetch(resultsUrl, {
|
|
86
|
+
method: 'GET',
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${token}`,
|
|
89
|
+
Accept: 'application/vnd.ims.lis.v2.resultcontainer+json',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
await this.validateAGSResponse(response, 'get scores');
|
|
93
|
+
return response;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Retrieves line items (gradebook columns) from the platform using Assignment and Grade Services.
|
|
97
|
+
*
|
|
98
|
+
* @param session - Active LTI session containing AGS line items endpoint configuration
|
|
99
|
+
* @returns Promise resolving to the HTTP response containing line items data
|
|
100
|
+
* @throws {Error} When AGS line items service is not available for the session or request fails
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* const response = await agsService.listLineItems(session);
|
|
105
|
+
* const lineItems = await response.json();
|
|
106
|
+
* console.log('Available gradebook columns:', lineItems);
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
async listLineItems(session) {
|
|
110
|
+
if (!session.services?.ags?.lineitems) {
|
|
111
|
+
throw new Error('AGS list line items not available for this session');
|
|
112
|
+
}
|
|
113
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly');
|
|
114
|
+
const response = await fetch(`${session.services.ags.lineitems}`, {
|
|
115
|
+
method: 'GET',
|
|
116
|
+
headers: {
|
|
117
|
+
Authorization: `Bearer ${token}`,
|
|
118
|
+
Accept: 'application/vnd.ims.lis.v2.lineitemcontainer+json',
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
await this.validateAGSResponse(response, 'list line items');
|
|
122
|
+
return response;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Retrieves a specific line item (gradebook column) from the platform using Assignment and Grade Services.
|
|
126
|
+
*
|
|
127
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
128
|
+
* @returns Promise resolving to the HTTP response containing the line item data
|
|
129
|
+
* @throws {Error} When AGS line item service is not available for the session or request fails
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const response = await agsService.getLineItem(session);
|
|
134
|
+
* const lineItem = await response.json();
|
|
135
|
+
* console.log('Line item details:', lineItem);
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
async getLineItem(session) {
|
|
139
|
+
if (!session.services?.ags?.lineitem) {
|
|
140
|
+
throw new Error('AGS line item not available for this session');
|
|
141
|
+
}
|
|
142
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly');
|
|
143
|
+
const response = await fetch(`${session.services.ags.lineitem}`, {
|
|
144
|
+
method: 'GET',
|
|
145
|
+
headers: {
|
|
146
|
+
Authorization: `Bearer ${token}`,
|
|
147
|
+
Accept: 'application/vnd.ims.lis.v2.lineitem+json',
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
await this.validateAGSResponse(response, 'get line item');
|
|
151
|
+
return response;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Creates a new line item (gradebook column) on the platform using Assignment and Grade Services.
|
|
155
|
+
*
|
|
156
|
+
* @param session - Active LTI session containing AGS line items endpoint configuration
|
|
157
|
+
* @param createLineItem - Line item data including label, scoreMaximum, and optional metadata
|
|
158
|
+
* @returns Promise resolving to the HTTP response containing the created line item with generated ID
|
|
159
|
+
* @throws {Error} When AGS line item creation service is not available for the session or creation fails
|
|
160
|
+
*
|
|
161
|
+
* @example
|
|
162
|
+
* ```typescript
|
|
163
|
+
* const response = await agsService.createLineItem(session, {
|
|
164
|
+
* label: 'Quiz 1',
|
|
165
|
+
* scoreMaximum: 100,
|
|
166
|
+
* tag: 'quiz',
|
|
167
|
+
* resourceId: 'quiz-001'
|
|
168
|
+
* });
|
|
169
|
+
* const newLineItem = await response.json();
|
|
170
|
+
* console.log('Created line item:', newLineItem.id);
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
async createLineItem(session, createLineItem) {
|
|
174
|
+
if (!session.services?.ags?.lineitems) {
|
|
175
|
+
throw new Error('AGS create line items not available for this session');
|
|
176
|
+
}
|
|
177
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem');
|
|
178
|
+
const response = await fetch(`${session.services.ags.lineitems}`, {
|
|
179
|
+
method: 'POST',
|
|
180
|
+
headers: {
|
|
181
|
+
Authorization: `Bearer ${token}`,
|
|
182
|
+
'Content-Type': 'application/vnd.ims.lis.v2.lineitem+json',
|
|
183
|
+
},
|
|
184
|
+
body: JSON.stringify(createLineItem),
|
|
185
|
+
});
|
|
186
|
+
await this.validateAGSResponse(response, 'create line item');
|
|
187
|
+
return response;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Updates an existing line item (gradebook column) on the platform using Assignment and Grade Services.
|
|
191
|
+
*
|
|
192
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
193
|
+
* @param updateLineItem - Updated line item data including all required fields
|
|
194
|
+
* @returns Promise resolving to the HTTP response containing the updated line item
|
|
195
|
+
* @throws {Error} When AGS line item service is not available for the session or update fails
|
|
196
|
+
*/
|
|
197
|
+
async updateLineItem(session, updateLineItem) {
|
|
198
|
+
if (!session.services?.ags?.lineitem) {
|
|
199
|
+
throw new Error('AGS line item not available for this session');
|
|
200
|
+
}
|
|
201
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem');
|
|
202
|
+
const response = await fetch(session.services.ags.lineitem, {
|
|
203
|
+
method: 'PUT',
|
|
204
|
+
headers: {
|
|
205
|
+
Authorization: `Bearer ${token}`,
|
|
206
|
+
'Content-Type': 'application/vnd.ims.lis.v2.lineitem+json',
|
|
207
|
+
},
|
|
208
|
+
body: JSON.stringify(updateLineItem),
|
|
209
|
+
});
|
|
210
|
+
await this.validateAGSResponse(response, 'update line item');
|
|
211
|
+
return response;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Deletes a line item (gradebook column) from the platform using Assignment and Grade Services.
|
|
215
|
+
*
|
|
216
|
+
* @param session - Active LTI session containing AGS line item endpoint configuration
|
|
217
|
+
* @returns Promise resolving to the HTTP response (typically 204 No Content on success)
|
|
218
|
+
* @throws {Error} When AGS line item service is not available for the session or deletion fails
|
|
219
|
+
*/
|
|
220
|
+
async deleteLineItem(session) {
|
|
221
|
+
if (!session.services?.ags?.lineitem) {
|
|
222
|
+
throw new Error('AGS line item not available for this session');
|
|
223
|
+
}
|
|
224
|
+
const token = await this.getAGSToken(session, 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem');
|
|
225
|
+
const response = await fetch(session.services.ags.lineitem, {
|
|
226
|
+
method: 'DELETE',
|
|
227
|
+
headers: {
|
|
228
|
+
Authorization: `Bearer ${token}`,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
await this.validateAGSResponse(response, 'delete line item');
|
|
232
|
+
return response;
|
|
233
|
+
}
|
|
234
|
+
async getAGSToken(session, scope) {
|
|
235
|
+
const launchConfig = await getValidLaunchConfig(this.storage, session.platform.issuer, session.platform.clientId, session.platform.deploymentId);
|
|
236
|
+
return this.tokenService.getBearerToken(session.platform.clientId, launchConfig.tokenUrl, scope);
|
|
237
|
+
}
|
|
238
|
+
async validateAGSResponse(response, operation) {
|
|
62
239
|
if (!response.ok) {
|
|
63
240
|
const error = await response.json();
|
|
64
|
-
this.logger.error({ error, status: response.status, statusText: response.statusText },
|
|
65
|
-
throw new Error(`AGS
|
|
241
|
+
this.logger.error({ error, status: response.status, statusText: response.statusText }, `AGS ${operation} failed`);
|
|
242
|
+
throw new Error(`AGS ${operation} failed: ${response.statusText} ${error}`);
|
|
66
243
|
}
|
|
67
|
-
return response;
|
|
68
244
|
}
|
|
69
245
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token.service.d.ts","sourceRoot":"","sources":["../../src/services/token.service.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,YAAY;IAQrB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;IARf;;;;;OAKG;gBAEO,OAAO,EAAE,aAAa,EACtB,KAAK,SAAS;IAGxB;;;;;;OAMG;IACG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhF;;;;;;;OAOG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"token.service.d.ts","sourceRoot":"","sources":["../../src/services/token.service.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,qBAAa,YAAY;IAQrB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;IARf;;;;;OAKG;gBAEO,OAAO,EAAE,aAAa,EACtB,KAAK,SAAS;IAGxB;;;;;;OAMG;IACG,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhF;;;;;;;OAOG;IACG,cAAc,CAClB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC;CA6BnB"}
|
|
@@ -63,7 +63,8 @@ export class TokenService {
|
|
|
63
63
|
}),
|
|
64
64
|
});
|
|
65
65
|
if (!response.ok) {
|
|
66
|
-
|
|
66
|
+
const errorDetail = await response.json();
|
|
67
|
+
throw new Error(`Token request failed: ${response.status} ${response.statusText} ${errorDetail}`);
|
|
67
68
|
}
|
|
68
69
|
const tokenData = await response.json();
|
|
69
70
|
if (!tokenData.access_token) {
|