@modulus-learning/lti 0.0.0-stage → 0.11.1
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/LICENSE +661 -0
- package/dist/access-token.d.ts +15 -0
- package/dist/access-token.d.ts.map +1 -0
- package/dist/access-token.js +1 -0
- package/dist/constants.d.ts +24 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +26 -0
- package/dist/contract.d.ts +125 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +18 -0
- package/dist/cutoff.d.ts +11 -0
- package/dist/cutoff.d.ts.map +1 -0
- package/dist/cutoff.js +19 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/login.d.ts +60 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +46 -0
- package/dist/messages/platform-originating/base-message.d.ts +26 -0
- package/dist/messages/platform-originating/base-message.d.ts.map +1 -0
- package/dist/messages/platform-originating/base-message.js +44 -0
- package/dist/messages/platform-originating/deep-linking-request.d.ts +40 -0
- package/dist/messages/platform-originating/deep-linking-request.d.ts.map +1 -0
- package/dist/messages/platform-originating/deep-linking-request.js +26 -0
- package/dist/messages/platform-originating/platform-message.d.ts +69 -0
- package/dist/messages/platform-originating/platform-message.d.ts.map +1 -0
- package/dist/messages/platform-originating/platform-message.js +8 -0
- package/dist/messages/platform-originating/resource-link-launch-request.d.ts +33 -0
- package/dist/messages/platform-originating/resource-link-launch-request.d.ts.map +1 -0
- package/dist/messages/platform-originating/resource-link-launch-request.js +11 -0
- package/dist/messages/tool-originating/deep-linking-response.d.ts +103 -0
- package/dist/messages/tool-originating/deep-linking-response.d.ts.map +1 -0
- package/dist/messages/tool-originating/deep-linking-response.js +60 -0
- package/dist/score.d.ts +84 -0
- package/dist/score.d.ts.map +1 -0
- package/dist/score.js +13 -0
- package/package.json +48 -3
- package/README.md +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const SCOPE_AGS_LINEITEM = "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem";
|
|
2
|
+
export declare const SCOPE_AGS_LINEITEM_READONLY = "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly";
|
|
3
|
+
export declare const SCOPE_AGS_SCORE = "https://purl.imsglobal.org/spec/lti-ags/scope/score";
|
|
4
|
+
export declare const SCOPE_AGS_RESULT_READONLY = "https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly";
|
|
5
|
+
export declare const SCOPE_NRPS_CONTEXT_MEMBERSHIP_READONLY = "https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly";
|
|
6
|
+
export declare const SCOPE_REG_REGISTRATION_READONLY = "https://purl.imsglobal.org/spec/lti-reg/scope/registration.readonly";
|
|
7
|
+
export declare const CLAIM_MESSAGE_TYPE = "https://purl.imsglobal.org/spec/lti/claim/message_type";
|
|
8
|
+
export declare const CLAIM_VERSION = "https://purl.imsglobal.org/spec/lti/claim/version";
|
|
9
|
+
export declare const CLAIM_DEPLOYMENT_ID = "https://purl.imsglobal.org/spec/lti/claim/deployment_id";
|
|
10
|
+
export declare const CLAIM_TARGET_LINK_URI = "https://purl.imsglobal.org/spec/lti/claim/target_link_uri";
|
|
11
|
+
export declare const CLAIM_RESOURCE_LINK = "https://purl.imsglobal.org/spec/lti/claim/resource_link";
|
|
12
|
+
export declare const CLAIM_ROLES = "https://purl.imsglobal.org/spec/lti/claim/roles";
|
|
13
|
+
export declare const CLAIM_CUSTOM = "https://purl.imsglobal.org/spec/lti/claim/custom";
|
|
14
|
+
export declare const CLAIM_AGS_ENDPOINT = "https://purl.imsglobal.org/spec/lti-ags/claim/endpoint";
|
|
15
|
+
export declare const CLAIM_DEEP_LINKING_SETTINGS = "https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings";
|
|
16
|
+
export declare const CLAIM_DEEP_LINKING_DATA = "https://purl.imsglobal.org/spec/lti-dl/claim/data";
|
|
17
|
+
export declare const CLAIM_DEEP_LINKING_CONTENT = "https://purl.imsglobal.org/spec/lti-dl/claim/content_items";
|
|
18
|
+
export declare const CLAIM_DEEP_LINKING_MSG = "https://purl.imsglobal.org/spec/lti-dl/claim/msg";
|
|
19
|
+
export declare const CLAIM_DEEP_LINKING_LOG = "https://purl.imsglobal.org/spec/lti-dl/claim/log";
|
|
20
|
+
export declare const CLAIM_DEEP_LINKING_ERRORMSG = "https://purl.imsglobal.org/spec/lti-dl/claim/errormsg";
|
|
21
|
+
export declare const CLAIM_DEEP_LINKING_ERRORLOG = "https://purl.imsglobal.org/spec/lti-dl/claim/errorlog";
|
|
22
|
+
export declare const TOOL_CONFIGURATION = "https://purl.imsglobal.org/spec/lti-tool-configuration";
|
|
23
|
+
export declare const PLATFORM_CONFIGURATION = "https://purl.imsglobal.org/spec/lti-platform-configuration";
|
|
24
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,kBAAkB,2DAA2D,CAAA;AAC1F,eAAO,MAAM,2BAA2B,oEAC2B,CAAA;AACnE,eAAO,MAAM,eAAe,wDAAwD,CAAA;AACpF,eAAO,MAAM,yBAAyB,kEAC2B,CAAA;AACjE,eAAO,MAAM,sCAAsC,8EAC0B,CAAA;AAC7E,eAAO,MAAM,+BAA+B,wEAC2B,CAAA;AAGvE,eAAO,MAAM,kBAAkB,2DAA2D,CAAA;AAC1F,eAAO,MAAM,aAAa,sDAAsD,CAAA;AAChF,eAAO,MAAM,mBAAmB,4DAA4D,CAAA;AAC5F,eAAO,MAAM,qBAAqB,8DAA8D,CAAA;AAChG,eAAO,MAAM,mBAAmB,4DAA4D,CAAA;AAC5F,eAAO,MAAM,WAAW,oDAAoD,CAAA;AAC5E,eAAO,MAAM,YAAY,qDAAqD,CAAA;AAC9E,eAAO,MAAM,kBAAkB,2DAA2D,CAAA;AAC1F,eAAO,MAAM,2BAA2B,uEAC8B,CAAA;AACtE,eAAO,MAAM,uBAAuB,sDAAsD,CAAA;AAC1F,eAAO,MAAM,0BAA0B,+DACuB,CAAA;AAC9D,eAAO,MAAM,sBAAsB,qDAAqD,CAAA;AACxF,eAAO,MAAM,sBAAsB,qDAAqD,CAAA;AACxF,eAAO,MAAM,2BAA2B,0DAA0D,CAAA;AAClG,eAAO,MAAM,2BAA2B,0DAA0D,CAAA;AAGlG,eAAO,MAAM,kBAAkB,2DAA2D,CAAA;AAC1F,eAAO,MAAM,sBAAsB,+DAA+D,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Scopes
|
|
2
|
+
export const SCOPE_AGS_LINEITEM = 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem';
|
|
3
|
+
export const SCOPE_AGS_LINEITEM_READONLY = 'https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly';
|
|
4
|
+
export const SCOPE_AGS_SCORE = 'https://purl.imsglobal.org/spec/lti-ags/scope/score';
|
|
5
|
+
export const SCOPE_AGS_RESULT_READONLY = 'https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly';
|
|
6
|
+
export const SCOPE_NRPS_CONTEXT_MEMBERSHIP_READONLY = 'https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly';
|
|
7
|
+
export const SCOPE_REG_REGISTRATION_READONLY = 'https://purl.imsglobal.org/spec/lti-reg/scope/registration.readonly';
|
|
8
|
+
// Claims
|
|
9
|
+
export const CLAIM_MESSAGE_TYPE = 'https://purl.imsglobal.org/spec/lti/claim/message_type';
|
|
10
|
+
export const CLAIM_VERSION = 'https://purl.imsglobal.org/spec/lti/claim/version';
|
|
11
|
+
export const CLAIM_DEPLOYMENT_ID = 'https://purl.imsglobal.org/spec/lti/claim/deployment_id';
|
|
12
|
+
export const CLAIM_TARGET_LINK_URI = 'https://purl.imsglobal.org/spec/lti/claim/target_link_uri';
|
|
13
|
+
export const CLAIM_RESOURCE_LINK = 'https://purl.imsglobal.org/spec/lti/claim/resource_link';
|
|
14
|
+
export const CLAIM_ROLES = 'https://purl.imsglobal.org/spec/lti/claim/roles';
|
|
15
|
+
export const CLAIM_CUSTOM = 'https://purl.imsglobal.org/spec/lti/claim/custom';
|
|
16
|
+
export const CLAIM_AGS_ENDPOINT = 'https://purl.imsglobal.org/spec/lti-ags/claim/endpoint';
|
|
17
|
+
export const CLAIM_DEEP_LINKING_SETTINGS = 'https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings';
|
|
18
|
+
export const CLAIM_DEEP_LINKING_DATA = 'https://purl.imsglobal.org/spec/lti-dl/claim/data';
|
|
19
|
+
export const CLAIM_DEEP_LINKING_CONTENT = 'https://purl.imsglobal.org/spec/lti-dl/claim/content_items';
|
|
20
|
+
export const CLAIM_DEEP_LINKING_MSG = 'https://purl.imsglobal.org/spec/lti-dl/claim/msg';
|
|
21
|
+
export const CLAIM_DEEP_LINKING_LOG = 'https://purl.imsglobal.org/spec/lti-dl/claim/log';
|
|
22
|
+
export const CLAIM_DEEP_LINKING_ERRORMSG = 'https://purl.imsglobal.org/spec/lti-dl/claim/errormsg';
|
|
23
|
+
export const CLAIM_DEEP_LINKING_ERRORLOG = 'https://purl.imsglobal.org/spec/lti-dl/claim/errorlog';
|
|
24
|
+
// CONFIG
|
|
25
|
+
export const TOOL_CONFIGURATION = 'https://purl.imsglobal.org/spec/lti-tool-configuration';
|
|
26
|
+
export const PLATFORM_CONFIGURATION = 'https://purl.imsglobal.org/spec/lti-platform-configuration';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LMS adapter contract: everything core needs from the one LMS an
|
|
3
|
+
* installation is connected to, as neutral values. Core calls the adapter;
|
|
4
|
+
* the adapter never calls into core.
|
|
5
|
+
*
|
|
6
|
+
* See specs/2026-10-25-canvas-lti-package-extraction-spec.md. Launch
|
|
7
|
+
* verification, the OIDC request and token exchange still live in core; they
|
|
8
|
+
* move behind the adapter in a later increment.
|
|
9
|
+
*/
|
|
10
|
+
import type { PlatformMessage } from './messages/platform-originating/platform-message.js';
|
|
11
|
+
import type { AccessTokenSource, LtiAgsClient, LtiLogger, LtiRegistration } from './score.js';
|
|
12
|
+
/** Incremented on any change to what an adapter must provide or what core assumes. */
|
|
13
|
+
export declare const LMS_CONTRACT_VERSION = 1;
|
|
14
|
+
export type LmsCapabilities = {
|
|
15
|
+
/** Course-designer content selection (LTI deep linking). */
|
|
16
|
+
deepLinking: boolean;
|
|
17
|
+
/** Launches carry an academic term, used to scope progress. */
|
|
18
|
+
termMetadata: boolean;
|
|
19
|
+
/** The adapter can generate the LMS-side registration configuration. */
|
|
20
|
+
registrationConfig: boolean;
|
|
21
|
+
};
|
|
22
|
+
/** How usable a vendor-supplied field was, for fallback diagnostics. */
|
|
23
|
+
export type FieldQuality = 'missing' | 'empty' | 'unexpanded' | 'malformed' | 'usable';
|
|
24
|
+
/** An academic term as the LMS reports it; core maps it to an opaque scope. */
|
|
25
|
+
export type NormalizedTerm = {
|
|
26
|
+
external_id: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
starts_at?: Date;
|
|
29
|
+
ends_at?: Date;
|
|
30
|
+
};
|
|
31
|
+
export type TermInspection = {
|
|
32
|
+
term?: NormalizedTerm;
|
|
33
|
+
quality: Record<'term_id' | 'name' | 'starts_at' | 'ends_at', FieldQuality>;
|
|
34
|
+
};
|
|
35
|
+
/** What a verified launch means, in neutral terms. Core applies the policy. */
|
|
36
|
+
export type LaunchInterpretation = {
|
|
37
|
+
/** Whether the launch's roles make the user an instructor for Modulus. */
|
|
38
|
+
isInstructor: boolean;
|
|
39
|
+
/** The launch's academic term, with field-quality diagnostics. */
|
|
40
|
+
term: TermInspection;
|
|
41
|
+
/**
|
|
42
|
+
* The vendor's own assignment-cutoff value, consulted only when the standard
|
|
43
|
+
* `ResourceLink.available.endDateTime` custom field is not usable.
|
|
44
|
+
*/
|
|
45
|
+
cutoffFallback?: unknown;
|
|
46
|
+
};
|
|
47
|
+
/** Endpoints an LMS registration needs, derived from its issuer. */
|
|
48
|
+
export type RegistrationEndpoints = {
|
|
49
|
+
authorization_endpoint: string;
|
|
50
|
+
token_endpoint: string;
|
|
51
|
+
jwks_uri: string;
|
|
52
|
+
authorization_server: string;
|
|
53
|
+
};
|
|
54
|
+
export type RegistrationConfigInput = {
|
|
55
|
+
/** The installation's public base URL. */
|
|
56
|
+
baseUrl: string;
|
|
57
|
+
/** The installation's host name. */
|
|
58
|
+
host: string;
|
|
59
|
+
/** The tool's public signing key, as published at its JWKS endpoint. */
|
|
60
|
+
publicJwk: unknown;
|
|
61
|
+
title?: string;
|
|
62
|
+
description?: string;
|
|
63
|
+
tool_id?: string;
|
|
64
|
+
platform?: string;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Concurrency pacing for one registration's score passback. Core asks for the
|
|
68
|
+
* current target, never exceeds its own configured cap, and reports each
|
|
69
|
+
* response's scheduling signal and each hard rate limit.
|
|
70
|
+
*/
|
|
71
|
+
export interface SchedulingPolicy {
|
|
72
|
+
/** The concurrency the policy currently allows (core caps it). */
|
|
73
|
+
target(): number;
|
|
74
|
+
/** Observe a response's scheduling signal (opaque to core). */
|
|
75
|
+
record(signal: unknown): void;
|
|
76
|
+
/** Return to a cold start, e.g. after a rate limit or an incident. */
|
|
77
|
+
reset(): void;
|
|
78
|
+
}
|
|
79
|
+
/** Core's score-submission settings that a score client and its policy use. */
|
|
80
|
+
export type ScoreClientSettings = {
|
|
81
|
+
/** Abort a platform request after this long. */
|
|
82
|
+
requestTimeoutSeconds: number;
|
|
83
|
+
/** Core's concurrency cap for one registration. */
|
|
84
|
+
maxConcurrentSubmissions: number;
|
|
85
|
+
/** Quota the policy keeps in reserve. */
|
|
86
|
+
quotaReserveRequests: number;
|
|
87
|
+
/** How long quota readings stay relevant. */
|
|
88
|
+
quotaWindowMs: number;
|
|
89
|
+
/** The minimum interval between concurrency increases. */
|
|
90
|
+
quotaRampIntervalMs: number;
|
|
91
|
+
};
|
|
92
|
+
export type ScoreClientDeps = {
|
|
93
|
+
registration: LtiRegistration;
|
|
94
|
+
accessTokens: AccessTokenSource;
|
|
95
|
+
logger: LtiLogger;
|
|
96
|
+
settings: ScoreClientSettings;
|
|
97
|
+
};
|
|
98
|
+
/** A registration-bound score client and its scheduling policy. */
|
|
99
|
+
export type LmsScoreClient = {
|
|
100
|
+
client: LtiAgsClient;
|
|
101
|
+
scheduling: SchedulingPolicy;
|
|
102
|
+
};
|
|
103
|
+
export interface LmsAdapter {
|
|
104
|
+
/** Stable adapter identifier, e.g. `canvas`. */
|
|
105
|
+
readonly id: string;
|
|
106
|
+
/** The contract version the adapter implements; core refuses a mismatch. */
|
|
107
|
+
readonly contractVersion: number;
|
|
108
|
+
readonly capabilities: LmsCapabilities;
|
|
109
|
+
/** Interpret a verified launch's claims. */
|
|
110
|
+
interpretLaunch(launch: PlatformMessage): LaunchInterpretation;
|
|
111
|
+
/**
|
|
112
|
+
* Custom fields the adapter adds to every deep-link content item, typically
|
|
113
|
+
* the LMS's substitution variables. Core's own `modulus_*` fields always win.
|
|
114
|
+
*/
|
|
115
|
+
deepLinkCustomFields(): Record<string, string>;
|
|
116
|
+
/** The endpoints a registration for `issuer` uses. */
|
|
117
|
+
registrationEndpoints(issuer: string): RegistrationEndpoints;
|
|
118
|
+
/** The LMS-side registration configuration, as JSON (capability `registrationConfig`). */
|
|
119
|
+
registrationConfig?(input: RegistrationConfigInput): string;
|
|
120
|
+
/** A score client bound to one registration. */
|
|
121
|
+
createScoreClient(deps: ScoreClientDeps): LmsScoreClient;
|
|
122
|
+
}
|
|
123
|
+
/** Fail fast when an adapter implements a different contract version. */
|
|
124
|
+
export declare const assertLmsAdapter: (adapter: LmsAdapter) => LmsAdapter;
|
|
125
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LMS adapter contract: everything core needs from the one LMS an
|
|
3
|
+
* installation is connected to, as neutral values. Core calls the adapter;
|
|
4
|
+
* the adapter never calls into core.
|
|
5
|
+
*
|
|
6
|
+
* See specs/2026-10-25-canvas-lti-package-extraction-spec.md. Launch
|
|
7
|
+
* verification, the OIDC request and token exchange still live in core; they
|
|
8
|
+
* move behind the adapter in a later increment.
|
|
9
|
+
*/
|
|
10
|
+
/** Incremented on any change to what an adapter must provide or what core assumes. */
|
|
11
|
+
export const LMS_CONTRACT_VERSION = 1;
|
|
12
|
+
/** Fail fast when an adapter implements a different contract version. */
|
|
13
|
+
export const assertLmsAdapter = (adapter) => {
|
|
14
|
+
if (adapter.contractVersion !== LMS_CONTRACT_VERSION) {
|
|
15
|
+
throw new Error(`LMS adapter "${adapter.id}" implements contract version ${adapter.contractVersion}; this build requires ${LMS_CONTRACT_VERSION}`);
|
|
16
|
+
}
|
|
17
|
+
return adapter;
|
|
18
|
+
};
|
package/dist/cutoff.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assignment cutoff a launch carries. The standard LTI substitution
|
|
3
|
+
* variable comes first — Modulus's deep-link content items map
|
|
4
|
+
* `$ResourceLink.available.endDateTime` to the custom field of the same name —
|
|
5
|
+
* and an adapter's own fallback is consulted only when it is not usable.
|
|
6
|
+
*/
|
|
7
|
+
export declare const STANDARD_CUTOFF_FIELD = "ResourceLink.available.endDateTime";
|
|
8
|
+
/** The first value that is a `Date.parse`-able string, as a `Date`. */
|
|
9
|
+
export declare const firstDate: (values: unknown[]) => Date | undefined;
|
|
10
|
+
export declare const effectiveCutoff: (custom: Record<string, unknown>, adapterFallback: unknown) => Date | undefined;
|
|
11
|
+
//# sourceMappingURL=cutoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cutoff.d.ts","sourceRoot":"","sources":["../src/cutoff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,uCAAuC,CAAA;AAEzE,uEAAuE;AACvE,eAAO,MAAM,SAAS,WAAY,OAAO,EAAE,KAAG,IAAI,GAAG,SASpD,CAAA;AAED,eAAO,MAAM,eAAe,WAClB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,mBACd,OAAO,KACvB,IAAI,GAAG,SAAwE,CAAA"}
|
package/dist/cutoff.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The assignment cutoff a launch carries. The standard LTI substitution
|
|
3
|
+
* variable comes first — Modulus's deep-link content items map
|
|
4
|
+
* `$ResourceLink.available.endDateTime` to the custom field of the same name —
|
|
5
|
+
* and an adapter's own fallback is consulted only when it is not usable.
|
|
6
|
+
*/
|
|
7
|
+
export const STANDARD_CUTOFF_FIELD = 'ResourceLink.available.endDateTime';
|
|
8
|
+
/** The first value that is a `Date.parse`-able string, as a `Date`. */
|
|
9
|
+
export const firstDate = (values) => {
|
|
10
|
+
for (const value of values) {
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
const timestamp = Date.parse(value);
|
|
13
|
+
if (!Number.isNaN(timestamp)) {
|
|
14
|
+
return new Date(timestamp);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
export const effectiveCutoff = (custom, adapterFallback) => firstDate([custom[STANDARD_CUTOFF_FIELD], adapterFallback]);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@modulus-learning/lti` — shared LTI 1.3 vocabulary and the LMS adapter
|
|
3
|
+
* contract. No core, database, host framework, or vendor dependency.
|
|
4
|
+
*/
|
|
5
|
+
export * from './access-token.js';
|
|
6
|
+
export * from './constants.js';
|
|
7
|
+
export * from './contract.js';
|
|
8
|
+
export * from './cutoff.js';
|
|
9
|
+
export * from './login.js';
|
|
10
|
+
export * from './messages/platform-originating/base-message.js';
|
|
11
|
+
export * from './messages/platform-originating/deep-linking-request.js';
|
|
12
|
+
export * from './messages/platform-originating/platform-message.js';
|
|
13
|
+
export * from './messages/platform-originating/resource-link-launch-request.js';
|
|
14
|
+
export * from './messages/tool-originating/deep-linking-response.js';
|
|
15
|
+
export * from './score.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,mBAAmB,CAAA;AACjC,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,iDAAiD,CAAA;AAC/D,cAAc,yDAAyD,CAAA;AACvE,cAAc,qDAAqD,CAAA;AACnE,cAAc,iEAAiE,CAAA;AAC/E,cAAc,sDAAsD,CAAA;AACpE,cAAc,YAAY,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@modulus-learning/lti` — shared LTI 1.3 vocabulary and the LMS adapter
|
|
3
|
+
* contract. No core, database, host framework, or vendor dependency.
|
|
4
|
+
*/
|
|
5
|
+
export * from './access-token.js';
|
|
6
|
+
export * from './constants.js';
|
|
7
|
+
export * from './contract.js';
|
|
8
|
+
export * from './cutoff.js';
|
|
9
|
+
export * from './login.js';
|
|
10
|
+
export * from './messages/platform-originating/base-message.js';
|
|
11
|
+
export * from './messages/platform-originating/deep-linking-request.js';
|
|
12
|
+
export * from './messages/platform-originating/platform-message.js';
|
|
13
|
+
export * from './messages/platform-originating/resource-link-launch-request.js';
|
|
14
|
+
export * from './messages/tool-originating/deep-linking-response.js';
|
|
15
|
+
export * from './score.js';
|
package/dist/login.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The data sent from platform to tool in an init login request.
|
|
4
|
+
*
|
|
5
|
+
* https://www.imsglobal.org/spec/security/v1p0/#step-1-third-party-initiated-login
|
|
6
|
+
* https://www.imsglobal.org/spec/lti/v1p3#additional-login-parameters
|
|
7
|
+
*/
|
|
8
|
+
export declare const initLoginRequestSchema: z.ZodObject<{
|
|
9
|
+
iss: z.ZodString;
|
|
10
|
+
login_hint: z.ZodString;
|
|
11
|
+
target_link_uri: z.ZodString;
|
|
12
|
+
lti_message_hint: z.ZodOptional<z.ZodString>;
|
|
13
|
+
lti_deployment_id: z.ZodOptional<z.ZodString>;
|
|
14
|
+
client_id: z.ZodOptional<z.ZodString>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type InitLoginRequest = z.infer<typeof initLoginRequestSchema>;
|
|
17
|
+
/**
|
|
18
|
+
* The data used to construct the response to an init login request. The actual
|
|
19
|
+
* response is an HTTP redirect to the given redirect_url, with a Set-Cookie
|
|
20
|
+
* header based on the given 'state' value.
|
|
21
|
+
*/
|
|
22
|
+
export interface AuthenticationRedirect {
|
|
23
|
+
redirectUrl: string;
|
|
24
|
+
stateId: string;
|
|
25
|
+
stateValue: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The parameters sent from tool to platform in response to an init login
|
|
29
|
+
* request. This data is bundled into the query string of the redirect_url of an
|
|
30
|
+
* AuthRedirect.
|
|
31
|
+
*
|
|
32
|
+
* https://www.imsglobal.org/spec/security/v1p0/#step-2-authentication-request
|
|
33
|
+
* https://www.imsglobal.org/spec/lti/v1p3#lti_message_hint-login-parameter
|
|
34
|
+
*/
|
|
35
|
+
export declare const authenticationRequestSchema: z.ZodObject<{
|
|
36
|
+
scope: z.ZodLiteral<"openid">;
|
|
37
|
+
response_type: z.ZodLiteral<"id_token">;
|
|
38
|
+
client_id: z.ZodString;
|
|
39
|
+
redirect_uri: z.ZodString;
|
|
40
|
+
login_hint: z.ZodString;
|
|
41
|
+
state: z.ZodString;
|
|
42
|
+
response_mode: z.ZodLiteral<"form_post">;
|
|
43
|
+
nonce: z.ZodString;
|
|
44
|
+
prompt: z.ZodLiteral<"none">;
|
|
45
|
+
lti_message_hint: z.ZodOptional<z.ZodString>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export type AuthenticationRequest = z.infer<typeof authenticationRequestSchema>;
|
|
48
|
+
/**
|
|
49
|
+
* The response the platform sends back to the tool in response to an
|
|
50
|
+
* AuthRedirect (on success)
|
|
51
|
+
*
|
|
52
|
+
* TODO: Canvas returns a few other values, including 'authenticity_token' and
|
|
53
|
+
* 'lti_storage_target'. Do we have a use for them?
|
|
54
|
+
*/
|
|
55
|
+
export declare const authenticationResponseSchema: z.ZodObject<{
|
|
56
|
+
id_token: z.ZodString;
|
|
57
|
+
state: z.ZodString;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
export type AuthenticationResponse = z.infer<typeof authenticationResponseSchema>;
|
|
60
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;;;;;iBAOjC,CAAA;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;GAOG;AAEH,eAAO,MAAM,2BAA2B;;;;;;;;;;;iBAWtC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAE/E;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B;;;iBAGvC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA"}
|
package/dist/login.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* The data sent from platform to tool in an init login request.
|
|
4
|
+
*
|
|
5
|
+
* https://www.imsglobal.org/spec/security/v1p0/#step-1-third-party-initiated-login
|
|
6
|
+
* https://www.imsglobal.org/spec/lti/v1p3#additional-login-parameters
|
|
7
|
+
*/
|
|
8
|
+
export const initLoginRequestSchema = z.object({
|
|
9
|
+
iss: z.string(),
|
|
10
|
+
login_hint: z.string(),
|
|
11
|
+
target_link_uri: z.string(),
|
|
12
|
+
lti_message_hint: z.string().optional(),
|
|
13
|
+
lti_deployment_id: z.string().optional(),
|
|
14
|
+
client_id: z.string().optional(),
|
|
15
|
+
});
|
|
16
|
+
/**
|
|
17
|
+
* The parameters sent from tool to platform in response to an init login
|
|
18
|
+
* request. This data is bundled into the query string of the redirect_url of an
|
|
19
|
+
* AuthRedirect.
|
|
20
|
+
*
|
|
21
|
+
* https://www.imsglobal.org/spec/security/v1p0/#step-2-authentication-request
|
|
22
|
+
* https://www.imsglobal.org/spec/lti/v1p3#lti_message_hint-login-parameter
|
|
23
|
+
*/
|
|
24
|
+
export const authenticationRequestSchema = z.object({
|
|
25
|
+
scope: z.literal('openid'),
|
|
26
|
+
response_type: z.literal('id_token'),
|
|
27
|
+
client_id: z.string(),
|
|
28
|
+
redirect_uri: z.string(),
|
|
29
|
+
login_hint: z.string(),
|
|
30
|
+
state: z.string(),
|
|
31
|
+
response_mode: z.literal('form_post'),
|
|
32
|
+
nonce: z.string(),
|
|
33
|
+
prompt: z.literal('none'),
|
|
34
|
+
lti_message_hint: z.string().optional(),
|
|
35
|
+
});
|
|
36
|
+
/**
|
|
37
|
+
* The response the platform sends back to the tool in response to an
|
|
38
|
+
* AuthRedirect (on success)
|
|
39
|
+
*
|
|
40
|
+
* TODO: Canvas returns a few other values, including 'authenticity_token' and
|
|
41
|
+
* 'lti_storage_target'. Do we have a use for them?
|
|
42
|
+
*/
|
|
43
|
+
export const authenticationResponseSchema = z.object({
|
|
44
|
+
id_token: z.string(),
|
|
45
|
+
state: z.string(),
|
|
46
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const baseMessageSchema: z.ZodObject<{
|
|
3
|
+
iss: z.ZodString;
|
|
4
|
+
aud: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
5
|
+
sub: z.ZodString;
|
|
6
|
+
exp: z.ZodNumber;
|
|
7
|
+
iat: z.ZodNumber;
|
|
8
|
+
nonce: z.ZodString;
|
|
9
|
+
azp: z.ZodOptional<z.ZodString>;
|
|
10
|
+
given_name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
family_name: z.ZodOptional<z.ZodString>;
|
|
12
|
+
name: z.ZodOptional<z.ZodString>;
|
|
13
|
+
email: z.ZodOptional<z.ZodString>;
|
|
14
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
15
|
+
"https://purl.imsglobal.org/spec/lti/claim/version": z.ZodLiteral<"1.3.0">;
|
|
16
|
+
"https://purl.imsglobal.org/spec/lti/claim/deployment_id": z.ZodString;
|
|
17
|
+
"https://purl.imsglobal.org/spec/lti/claim/target_link_uri": z.ZodString;
|
|
18
|
+
"https://purl.imsglobal.org/spec/lti/claim/roles": z.ZodArray<z.ZodString>;
|
|
19
|
+
"https://purl.imsglobal.org/spec/lti-ags/claim/endpoint": z.ZodOptional<z.ZodObject<{
|
|
20
|
+
lineitems: z.ZodOptional<z.ZodString>;
|
|
21
|
+
lineitem: z.ZodOptional<z.ZodString>;
|
|
22
|
+
scope: z.ZodArray<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
"https://purl.imsglobal.org/spec/lti/claim/custom": z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>>;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
//# sourceMappingURL=base-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-message.d.ts","sourceRoot":"","sources":["../../../src/messages/platform-originating/base-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAWvB,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;iBA8C5B,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CLAIM_AGS_ENDPOINT, CLAIM_CUSTOM, CLAIM_DEPLOYMENT_ID, CLAIM_ROLES, CLAIM_TARGET_LINK_URI, CLAIM_VERSION, } from '../../constants.js';
|
|
3
|
+
export const baseMessageSchema = z.object({
|
|
4
|
+
// Core claims
|
|
5
|
+
// https://www.imsglobal.org/spec/security/v1p0/#id-token
|
|
6
|
+
// TODO: sub is apparently optional in case of anonymous resource link request messages?
|
|
7
|
+
// https://www.imsglobal.org/spec/lti/v1p3/#anonymous-launch-case
|
|
8
|
+
iss: z.string(),
|
|
9
|
+
aud: z.union([z.string(), z.array(z.string())]),
|
|
10
|
+
sub: z.string(),
|
|
11
|
+
exp: z.number(),
|
|
12
|
+
iat: z.number(),
|
|
13
|
+
nonce: z.string(),
|
|
14
|
+
azp: z.optional(z.string()),
|
|
15
|
+
// Potentially lots of additional openid-style claims about the user. For
|
|
16
|
+
// some additional possibilities, see
|
|
17
|
+
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
|
|
18
|
+
given_name: z.optional(z.string()),
|
|
19
|
+
family_name: z.optional(z.string()),
|
|
20
|
+
name: z.optional(z.string()),
|
|
21
|
+
email: z.optional(z.string()),
|
|
22
|
+
locale: z.optional(z.string()),
|
|
23
|
+
// LTI claims
|
|
24
|
+
[CLAIM_VERSION]: z.literal('1.3.0'),
|
|
25
|
+
[CLAIM_DEPLOYMENT_ID]: z.string(),
|
|
26
|
+
[CLAIM_TARGET_LINK_URI]: z.string(),
|
|
27
|
+
[CLAIM_ROLES]: z.array(z.string()),
|
|
28
|
+
[CLAIM_AGS_ENDPOINT]: z.optional(z.object({
|
|
29
|
+
lineitems: z.string().optional(),
|
|
30
|
+
lineitem: z.string().optional(),
|
|
31
|
+
scope: z.string().array(),
|
|
32
|
+
})),
|
|
33
|
+
[CLAIM_CUSTOM]: z.record(z.string(), z.union([z.string(), z.boolean()]).nullable()).prefault({}),
|
|
34
|
+
// TODO: Lots more go here, possibly including
|
|
35
|
+
// https://purl.imsglobal.org/spec/lti/claim/lis
|
|
36
|
+
// https://purl.imsglobal.org/spec/lti/claim/context
|
|
37
|
+
// https://purl.imsglobal.org/spec/lti/claim/tool_platform
|
|
38
|
+
// https://purl.imsglobal.org/spec/lti/claim/launch_presentation
|
|
39
|
+
// https://purl.imsglobal.org/spec/lti/claim/custom
|
|
40
|
+
// https://purl.imsglobal.org/spec/lti-bo/claim/basicoutcome
|
|
41
|
+
// https://purl.imsglobal.org/spec/lti/claim/ext
|
|
42
|
+
// https://purl.imsglobal.org/spec/lti-nrps/claim/namesroleservice
|
|
43
|
+
// And a few canvas-specific ones...
|
|
44
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const deepLinkingRequestSchema: z.ZodObject<{
|
|
3
|
+
iss: z.ZodString;
|
|
4
|
+
aud: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
5
|
+
sub: z.ZodString;
|
|
6
|
+
exp: z.ZodNumber;
|
|
7
|
+
iat: z.ZodNumber;
|
|
8
|
+
nonce: z.ZodString;
|
|
9
|
+
azp: z.ZodOptional<z.ZodString>;
|
|
10
|
+
given_name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
family_name: z.ZodOptional<z.ZodString>;
|
|
12
|
+
name: z.ZodOptional<z.ZodString>;
|
|
13
|
+
email: z.ZodOptional<z.ZodString>;
|
|
14
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
15
|
+
"https://purl.imsglobal.org/spec/lti/claim/version": z.ZodLiteral<"1.3.0">;
|
|
16
|
+
"https://purl.imsglobal.org/spec/lti/claim/deployment_id": z.ZodString;
|
|
17
|
+
"https://purl.imsglobal.org/spec/lti/claim/target_link_uri": z.ZodString;
|
|
18
|
+
"https://purl.imsglobal.org/spec/lti/claim/roles": z.ZodArray<z.ZodString>;
|
|
19
|
+
"https://purl.imsglobal.org/spec/lti-ags/claim/endpoint": z.ZodOptional<z.ZodObject<{
|
|
20
|
+
lineitems: z.ZodOptional<z.ZodString>;
|
|
21
|
+
lineitem: z.ZodOptional<z.ZodString>;
|
|
22
|
+
scope: z.ZodArray<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
"https://purl.imsglobal.org/spec/lti/claim/custom": z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>>;
|
|
25
|
+
"https://purl.imsglobal.org/spec/lti/claim/message_type": z.ZodLiteral<"LtiDeepLinkingRequest">;
|
|
26
|
+
"https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings": z.ZodObject<{
|
|
27
|
+
deep_link_return_url: z.ZodString;
|
|
28
|
+
accept_types: z.ZodArray<z.ZodString>;
|
|
29
|
+
accept_presentation_document_targets: z.ZodArray<z.ZodString>;
|
|
30
|
+
accept_media_types: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
31
|
+
accept_multiple: z.ZodPrefault<z.ZodBoolean>;
|
|
32
|
+
accept_lineitem: z.ZodOptional<z.ZodBoolean>;
|
|
33
|
+
auto_create: z.ZodPrefault<z.ZodBoolean>;
|
|
34
|
+
title: z.ZodOptional<z.ZodString>;
|
|
35
|
+
text: z.ZodOptional<z.ZodString>;
|
|
36
|
+
data: z.ZodOptional<z.ZodAny>;
|
|
37
|
+
}, z.core.$strip>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
export type DeepLinkingRequest = z.infer<typeof deepLinkingRequestSchema>;
|
|
40
|
+
//# sourceMappingURL=deep-linking-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deep-linking-request.d.ts","sourceRoot":"","sources":["../../../src/messages/platform-originating/deep-linking-request.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AASvB,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkBnC,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CLAIM_DEEP_LINKING_SETTINGS, CLAIM_MESSAGE_TYPE } from '../../constants.js';
|
|
3
|
+
import { baseMessageSchema } from './base-message.js';
|
|
4
|
+
// Same claims as a resource link launch request, except the
|
|
5
|
+
// CLAIM_MESSAGE_TYPE must be 'LtiDeepLinkingRequest', and
|
|
6
|
+
// CLAIM_DEEP_LINKING_SETTINGS must be present.
|
|
7
|
+
// https://www.imsglobal.org/spec/lti-dl/v2p0#deep-linking-request-message
|
|
8
|
+
export const deepLinkingRequestSchema = baseMessageSchema.extend({
|
|
9
|
+
[CLAIM_MESSAGE_TYPE]: z.literal('LtiDeepLinkingRequest'),
|
|
10
|
+
[CLAIM_DEEP_LINKING_SETTINGS]: z.object({
|
|
11
|
+
deep_link_return_url: z.string(),
|
|
12
|
+
accept_types: z.array(z.string()),
|
|
13
|
+
accept_presentation_document_targets: z.array(z.string()),
|
|
14
|
+
accept_media_types: z.optional(z.union([z.string(), z.array(z.string())])),
|
|
15
|
+
accept_multiple: z.boolean().prefault(false),
|
|
16
|
+
// Don't add a default for accept_lineitem -- if not specified, we can't
|
|
17
|
+
// assume either true or false:
|
|
18
|
+
// https://www.imsglobal.org/spec/lti-dl/v2p0#deep-linking-settings
|
|
19
|
+
accept_lineitem: z.optional(z.boolean()),
|
|
20
|
+
auto_create: z.boolean().prefault(false),
|
|
21
|
+
title: z.optional(z.string()),
|
|
22
|
+
text: z.optional(z.string()),
|
|
23
|
+
data: z.optional(z.any()),
|
|
24
|
+
// TODO: Any canvas specific entries?
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const platformMessageSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
3
|
+
iss: z.ZodString;
|
|
4
|
+
aud: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
5
|
+
sub: z.ZodString;
|
|
6
|
+
exp: z.ZodNumber;
|
|
7
|
+
iat: z.ZodNumber;
|
|
8
|
+
nonce: z.ZodString;
|
|
9
|
+
azp: z.ZodOptional<z.ZodString>;
|
|
10
|
+
given_name: z.ZodOptional<z.ZodString>;
|
|
11
|
+
family_name: z.ZodOptional<z.ZodString>;
|
|
12
|
+
name: z.ZodOptional<z.ZodString>;
|
|
13
|
+
email: z.ZodOptional<z.ZodString>;
|
|
14
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
15
|
+
"https://purl.imsglobal.org/spec/lti/claim/version": z.ZodLiteral<"1.3.0">;
|
|
16
|
+
"https://purl.imsglobal.org/spec/lti/claim/deployment_id": z.ZodString;
|
|
17
|
+
"https://purl.imsglobal.org/spec/lti/claim/target_link_uri": z.ZodString;
|
|
18
|
+
"https://purl.imsglobal.org/spec/lti/claim/roles": z.ZodArray<z.ZodString>;
|
|
19
|
+
"https://purl.imsglobal.org/spec/lti-ags/claim/endpoint": z.ZodOptional<z.ZodObject<{
|
|
20
|
+
lineitems: z.ZodOptional<z.ZodString>;
|
|
21
|
+
lineitem: z.ZodOptional<z.ZodString>;
|
|
22
|
+
scope: z.ZodArray<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
"https://purl.imsglobal.org/spec/lti/claim/custom": z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>>;
|
|
25
|
+
"https://purl.imsglobal.org/spec/lti/claim/message_type": z.ZodLiteral<"LtiResourceLinkRequest">;
|
|
26
|
+
"https://purl.imsglobal.org/spec/lti/claim/resource_link": z.ZodObject<{
|
|
27
|
+
id: z.ZodString;
|
|
28
|
+
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
29
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
32
|
+
iss: z.ZodString;
|
|
33
|
+
aud: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
|
|
34
|
+
sub: z.ZodString;
|
|
35
|
+
exp: z.ZodNumber;
|
|
36
|
+
iat: z.ZodNumber;
|
|
37
|
+
nonce: z.ZodString;
|
|
38
|
+
azp: z.ZodOptional<z.ZodString>;
|
|
39
|
+
given_name: z.ZodOptional<z.ZodString>;
|
|
40
|
+
family_name: z.ZodOptional<z.ZodString>;
|
|
41
|
+
name: z.ZodOptional<z.ZodString>;
|
|
42
|
+
email: z.ZodOptional<z.ZodString>;
|
|
43
|
+
locale: z.ZodOptional<z.ZodString>;
|
|
44
|
+
"https://purl.imsglobal.org/spec/lti/claim/version": z.ZodLiteral<"1.3.0">;
|
|
45
|
+
"https://purl.imsglobal.org/spec/lti/claim/deployment_id": z.ZodString;
|
|
46
|
+
"https://purl.imsglobal.org/spec/lti/claim/target_link_uri": z.ZodString;
|
|
47
|
+
"https://purl.imsglobal.org/spec/lti/claim/roles": z.ZodArray<z.ZodString>;
|
|
48
|
+
"https://purl.imsglobal.org/spec/lti-ags/claim/endpoint": z.ZodOptional<z.ZodObject<{
|
|
49
|
+
lineitems: z.ZodOptional<z.ZodString>;
|
|
50
|
+
lineitem: z.ZodOptional<z.ZodString>;
|
|
51
|
+
scope: z.ZodArray<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>>;
|
|
53
|
+
"https://purl.imsglobal.org/spec/lti/claim/custom": z.ZodPrefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodBoolean]>>>>;
|
|
54
|
+
"https://purl.imsglobal.org/spec/lti/claim/message_type": z.ZodLiteral<"LtiDeepLinkingRequest">;
|
|
55
|
+
"https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings": z.ZodObject<{
|
|
56
|
+
deep_link_return_url: z.ZodString;
|
|
57
|
+
accept_types: z.ZodArray<z.ZodString>;
|
|
58
|
+
accept_presentation_document_targets: z.ZodArray<z.ZodString>;
|
|
59
|
+
accept_media_types: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
60
|
+
accept_multiple: z.ZodPrefault<z.ZodBoolean>;
|
|
61
|
+
accept_lineitem: z.ZodOptional<z.ZodBoolean>;
|
|
62
|
+
auto_create: z.ZodPrefault<z.ZodBoolean>;
|
|
63
|
+
title: z.ZodOptional<z.ZodString>;
|
|
64
|
+
text: z.ZodOptional<z.ZodString>;
|
|
65
|
+
data: z.ZodOptional<z.ZodAny>;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
}, z.core.$strip>], "https://purl.imsglobal.org/spec/lti/claim/message_type">;
|
|
68
|
+
export type PlatformMessage = z.infer<typeof platformMessageSchema>;
|
|
69
|
+
//# sourceMappingURL=platform-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-message.d.ts","sourceRoot":"","sources":["../../../src/messages/platform-originating/platform-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAMvB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6EAGhC,CAAA;AAEF,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CLAIM_MESSAGE_TYPE } from '../../constants.js';
|
|
3
|
+
import { deepLinkingRequestSchema } from './deep-linking-request.js';
|
|
4
|
+
import { resourceLinkLaunchRequestSchema } from './resource-link-launch-request.js';
|
|
5
|
+
export const platformMessageSchema = z.discriminatedUnion(CLAIM_MESSAGE_TYPE, [
|
|
6
|
+
resourceLinkLaunchRequestSchema,
|
|
7
|
+
deepLinkingRequestSchema,
|
|
8
|
+
]);
|