@openstax/ts-utils 1.29.0 → 1.30.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/dist/cjs/assertions/index.d.ts +7 -3
- package/dist/cjs/config/envConfig.d.ts +1 -1
- package/dist/cjs/config/index.d.ts +7 -7
- package/dist/cjs/config/resolveConfigValue.d.ts +2 -2
- package/dist/cjs/fetch/index.d.ts +16 -16
- package/dist/cjs/fetch/index.js +1 -1
- package/dist/cjs/middleware/apiErrorHandler.d.ts +3 -3
- package/dist/cjs/middleware/apiSlowResponseMiddleware.d.ts +1 -1
- package/dist/cjs/middleware/index.d.ts +7 -7
- package/dist/cjs/middleware/lambdaCorsResponseMiddleware.d.ts +1 -1
- package/dist/cjs/misc/hashValue.d.ts +2 -2
- package/dist/cjs/misc/helpers.d.ts +11 -11
- package/dist/cjs/misc/merge.d.ts +2 -2
- package/dist/cjs/misc/partitionSequence.d.ts +2 -2
- package/dist/cjs/pagination/index.d.ts +1 -1
- package/dist/cjs/routing/index.d.ts +30 -30
- package/dist/cjs/routing/index.js +18 -8
- package/dist/cjs/routing/validators/zod.d.ts +1 -1
- package/dist/cjs/routing/validators/zod.js +3 -1
- package/dist/cjs/services/accountsGateway/index.d.ts +17 -20
- package/dist/cjs/services/apiGateway/index.d.ts +10 -10
- package/dist/cjs/services/apiGateway/index.js +17 -7
- package/dist/cjs/services/authProvider/browser.d.ts +5 -7
- package/dist/cjs/services/authProvider/decryption.d.ts +3 -7
- package/dist/cjs/services/authProvider/index.d.ts +8 -8
- package/dist/cjs/services/authProvider/subrequest.d.ts +2 -5
- package/dist/cjs/services/authProvider/utils/decryptAndVerify.d.ts +1 -2
- package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.d.ts +4 -4
- package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.js +1 -1
- package/dist/cjs/services/authProvider/utils/userRoleValidator.d.ts +2 -2
- package/dist/cjs/services/documentStore/index.d.ts +7 -7
- package/dist/cjs/services/documentStore/unversioned/dynamodb.d.ts +7 -9
- package/dist/cjs/services/documentStore/unversioned/file-system.d.ts +7 -9
- package/dist/cjs/services/documentStore/unversioned/file-system.js +17 -7
- package/dist/cjs/services/documentStore/unversioned/index.d.ts +1 -1
- package/dist/cjs/services/documentStore/versioned/dynamodb.d.ts +7 -9
- package/dist/cjs/services/documentStore/versioned/file-system.d.ts +6 -8
- package/dist/cjs/services/documentStore/versioned/index.d.ts +4 -4
- package/dist/cjs/services/exercisesGateway/index.d.ts +9 -13
- package/dist/cjs/services/exercisesGateway/index.js +17 -7
- package/dist/cjs/services/fileServer/index.d.ts +13 -3
- package/dist/cjs/services/fileServer/localFileServer.d.ts +2 -6
- package/dist/cjs/services/fileServer/localFileServer.js +47 -0
- package/dist/cjs/services/fileServer/s3FileServer.d.ts +2 -5
- package/dist/cjs/services/fileServer/s3FileServer.js +70 -0
- package/dist/cjs/services/launchParams/signer.d.ts +4 -9
- package/dist/cjs/services/launchParams/verifier.d.ts +4 -7
- package/dist/cjs/services/launchParams/verifier.js +17 -7
- package/dist/cjs/services/logger/index.d.ts +2 -2
- package/dist/cjs/services/logger/index.js +1 -1
- package/dist/cjs/services/lrsGateway/addStatementDefaultFields.d.ts +1 -1
- package/dist/cjs/services/lrsGateway/attempt-utils.d.ts +34 -34
- package/dist/cjs/services/lrsGateway/file-system.d.ts +2 -4
- package/dist/cjs/services/lrsGateway/file-system.js +17 -7
- package/dist/cjs/services/lrsGateway/index.d.ts +29 -32
- package/dist/cjs/services/lrsGateway/index.js +17 -7
- package/dist/cjs/services/lrsGateway/xapiUtils.d.ts +23 -23
- package/dist/cjs/services/postgresConnection/index.d.ts +3 -10
- package/dist/cjs/services/searchProvider/index.d.ts +7 -7
- package/dist/cjs/services/searchProvider/memorySearchTheBadWay.d.ts +1 -1
- package/dist/cjs/services/searchProvider/openSearch.d.ts +3 -6
- package/dist/cjs/services/searchProvider/openSearch.js +7 -3
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +5 -5
- package/dist/esm/assertions/index.d.ts +7 -3
- package/dist/esm/config/envConfig.d.ts +1 -1
- package/dist/esm/config/index.d.ts +7 -7
- package/dist/esm/config/resolveConfigValue.d.ts +2 -2
- package/dist/esm/fetch/index.d.ts +16 -16
- package/dist/esm/middleware/apiErrorHandler.d.ts +3 -3
- package/dist/esm/middleware/apiSlowResponseMiddleware.d.ts +1 -1
- package/dist/esm/middleware/index.d.ts +7 -7
- package/dist/esm/middleware/lambdaCorsResponseMiddleware.d.ts +1 -1
- package/dist/esm/misc/hashValue.d.ts +2 -2
- package/dist/esm/misc/helpers.d.ts +11 -11
- package/dist/esm/misc/merge.d.ts +2 -2
- package/dist/esm/misc/partitionSequence.d.ts +2 -2
- package/dist/esm/pagination/index.d.ts +1 -1
- package/dist/esm/routing/index.d.ts +30 -30
- package/dist/esm/routing/validators/zod.d.ts +1 -1
- package/dist/esm/routing/validators/zod.js +3 -1
- package/dist/esm/services/accountsGateway/index.d.ts +17 -20
- package/dist/esm/services/apiGateway/index.d.ts +10 -10
- package/dist/esm/services/authProvider/browser.d.ts +5 -7
- package/dist/esm/services/authProvider/decryption.d.ts +3 -7
- package/dist/esm/services/authProvider/index.d.ts +8 -8
- package/dist/esm/services/authProvider/subrequest.d.ts +2 -5
- package/dist/esm/services/authProvider/utils/decryptAndVerify.d.ts +1 -2
- package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +4 -4
- package/dist/esm/services/authProvider/utils/userRoleValidator.d.ts +2 -2
- package/dist/esm/services/documentStore/index.d.ts +7 -7
- package/dist/esm/services/documentStore/unversioned/dynamodb.d.ts +7 -9
- package/dist/esm/services/documentStore/unversioned/file-system.d.ts +7 -9
- package/dist/esm/services/documentStore/unversioned/index.d.ts +1 -1
- package/dist/esm/services/documentStore/versioned/dynamodb.d.ts +7 -9
- package/dist/esm/services/documentStore/versioned/file-system.d.ts +6 -8
- package/dist/esm/services/documentStore/versioned/index.d.ts +4 -4
- package/dist/esm/services/exercisesGateway/index.d.ts +9 -13
- package/dist/esm/services/fileServer/index.d.ts +13 -3
- package/dist/esm/services/fileServer/localFileServer.d.ts +2 -6
- package/dist/esm/services/fileServer/localFileServer.js +47 -0
- package/dist/esm/services/fileServer/s3FileServer.d.ts +2 -5
- package/dist/esm/services/fileServer/s3FileServer.js +68 -1
- package/dist/esm/services/launchParams/signer.d.ts +4 -9
- package/dist/esm/services/launchParams/verifier.d.ts +4 -7
- package/dist/esm/services/logger/index.d.ts +2 -2
- package/dist/esm/services/lrsGateway/addStatementDefaultFields.d.ts +1 -1
- package/dist/esm/services/lrsGateway/attempt-utils.d.ts +34 -34
- package/dist/esm/services/lrsGateway/file-system.d.ts +2 -4
- package/dist/esm/services/lrsGateway/index.d.ts +29 -32
- package/dist/esm/services/lrsGateway/xapiUtils.d.ts +23 -23
- package/dist/esm/services/postgresConnection/index.d.ts +3 -10
- package/dist/esm/services/searchProvider/index.d.ts +7 -7
- package/dist/esm/services/searchProvider/memorySearchTheBadWay.d.ts +1 -1
- package/dist/esm/services/searchProvider/openSearch.d.ts +3 -6
- package/dist/esm/services/searchProvider/openSearch.js +7 -3
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +5 -5
- package/package.json +10 -9
- package/script/bin/.init-params-script.bash.swp +0 -0
- package/script/bin/copy-from-template.bash +6 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/* cspell:ignore originalname */
|
|
2
|
+
import crypto from 'crypto';
|
|
2
3
|
import fs from 'fs';
|
|
3
4
|
import https from 'https';
|
|
4
5
|
import path from 'path';
|
|
5
6
|
import cors from 'cors';
|
|
6
7
|
import express from 'express';
|
|
7
8
|
import multer from 'multer';
|
|
9
|
+
import { v4 as uuid } from 'uuid';
|
|
8
10
|
import { assertString } from '../../assertions';
|
|
9
11
|
import { resolveConfigValue } from '../../config';
|
|
10
12
|
import { ifDefined } from '../../guards';
|
|
@@ -66,9 +68,54 @@ export const localFileServer = (initializer) => (configProvider) => {
|
|
|
66
68
|
await fs.promises.writeFile(filePath, content);
|
|
67
69
|
return source;
|
|
68
70
|
};
|
|
71
|
+
const getSignedFileUploadConfig = async () => {
|
|
72
|
+
const prefix = 'uploads/' + uuid();
|
|
73
|
+
return {
|
|
74
|
+
url: `https://${await host}:${await port}/`,
|
|
75
|
+
payload: {
|
|
76
|
+
key: prefix + '/${filename}',
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
const copyFileTo = async (source, destinationPath) => {
|
|
81
|
+
const sourcePath = path.join(await fileDir, source.path);
|
|
82
|
+
const destPath = path.join(await fileDir, destinationPath);
|
|
83
|
+
const destDirectory = path.dirname(destPath);
|
|
84
|
+
await fs.promises.mkdir(destDirectory, { recursive: true });
|
|
85
|
+
await fs.promises.copyFile(sourcePath, destPath);
|
|
86
|
+
return {
|
|
87
|
+
...source,
|
|
88
|
+
path: destinationPath
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
const copyFileToDirectory = async (source, destination) => {
|
|
92
|
+
const destinationPath = path.join(destination, source.label);
|
|
93
|
+
return copyFileTo(source, destinationPath);
|
|
94
|
+
};
|
|
95
|
+
const isTemporaryUpload = (source) => {
|
|
96
|
+
return source.path.indexOf('uploads/') === 0;
|
|
97
|
+
};
|
|
98
|
+
const getFileChecksum = async (source) => {
|
|
99
|
+
const filePath = path.join(await fileDir, source.path);
|
|
100
|
+
const fileContent = await fs.promises.readFile(filePath);
|
|
101
|
+
return crypto.createHash('md5').update(fileContent).digest('hex');
|
|
102
|
+
};
|
|
103
|
+
const filesEqual = async (sourceA, sourceB) => {
|
|
104
|
+
const [aSum, bSum] = await Promise.all([
|
|
105
|
+
getFileChecksum(sourceA),
|
|
106
|
+
getFileChecksum(sourceB)
|
|
107
|
+
]);
|
|
108
|
+
return aSum === bSum;
|
|
109
|
+
};
|
|
69
110
|
return {
|
|
70
111
|
getSignedViewerUrl,
|
|
71
112
|
getFileContent,
|
|
72
113
|
putFileContent,
|
|
114
|
+
getSignedFileUploadConfig,
|
|
115
|
+
copyFileTo,
|
|
116
|
+
copyFileToDirectory,
|
|
117
|
+
isTemporaryUpload,
|
|
118
|
+
getFileChecksum,
|
|
119
|
+
filesEqual,
|
|
73
120
|
};
|
|
74
121
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { S3Client } from '@aws-sdk/client-s3';
|
|
2
2
|
import { ConfigProviderForConfig } from '../../config';
|
|
3
3
|
import { FileServerAdapter } from '.';
|
|
4
|
-
export
|
|
4
|
+
export type Config = {
|
|
5
5
|
bucketName: string;
|
|
6
6
|
bucketRegion: string;
|
|
7
7
|
};
|
|
@@ -9,8 +9,5 @@ interface Initializer<C> {
|
|
|
9
9
|
configSpace?: C;
|
|
10
10
|
getS3Client?: (...args: ConstructorParameters<typeof S3Client>) => S3Client;
|
|
11
11
|
}
|
|
12
|
-
export declare const s3FileServer: <C extends string = "deployed">(initializer: Initializer<C>) => (configProvider: { [
|
|
13
|
-
bucketName: import("../../config").ConfigValueProvider<string>;
|
|
14
|
-
bucketRegion: import("../../config").ConfigValueProvider<string>;
|
|
15
|
-
}; }) => FileServerAdapter;
|
|
12
|
+
export declare const s3FileServer: <C extends string = "deployed">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => FileServerAdapter;
|
|
16
13
|
export {};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/* cspell:ignore presigner */
|
|
2
|
-
import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
2
|
+
import { CopyObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
3
|
+
import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
|
|
3
4
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { v4 as uuid } from 'uuid';
|
|
4
7
|
import { once } from '../..';
|
|
5
8
|
import { assertDefined } from '../../assertions';
|
|
6
9
|
import { resolveConfigValue } from '../../config';
|
|
@@ -41,9 +44,73 @@ export const s3FileServer = (initializer) => (configProvider) => {
|
|
|
41
44
|
await (await s3Service()).send(command);
|
|
42
45
|
return source;
|
|
43
46
|
};
|
|
47
|
+
/*
|
|
48
|
+
* https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_s3_presigned_post.html
|
|
49
|
+
* https://docs.aws.amazon.com/AmazonS3/latest/userguide/HTTPPOSTExamples.html
|
|
50
|
+
* https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
|
|
51
|
+
*/
|
|
52
|
+
const getSignedFileUploadConfig = async () => {
|
|
53
|
+
const prefix = 'uploads/' + uuid();
|
|
54
|
+
const bucket = (await bucketName());
|
|
55
|
+
const Conditions = [
|
|
56
|
+
{ acl: 'private' },
|
|
57
|
+
{ bucket },
|
|
58
|
+
['starts-with', '$key', prefix]
|
|
59
|
+
];
|
|
60
|
+
const defaultFields = {
|
|
61
|
+
acl: 'private',
|
|
62
|
+
};
|
|
63
|
+
const { url, fields } = await createPresignedPost(await s3Service(), {
|
|
64
|
+
Bucket: bucket,
|
|
65
|
+
Key: prefix + '/${filename}',
|
|
66
|
+
Conditions,
|
|
67
|
+
Fields: defaultFields,
|
|
68
|
+
Expires: 3600, // 1 hour
|
|
69
|
+
});
|
|
70
|
+
return {
|
|
71
|
+
url, payload: fields
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const copyFileTo = async (source, destinationPath) => {
|
|
75
|
+
const bucket = (await bucketName());
|
|
76
|
+
const destinationPathWithoutLeadingSlash = destinationPath.replace(/^\//, '');
|
|
77
|
+
const command = new CopyObjectCommand({
|
|
78
|
+
Bucket: bucket,
|
|
79
|
+
Key: destinationPathWithoutLeadingSlash,
|
|
80
|
+
CopySource: path.join(bucket, source.path),
|
|
81
|
+
});
|
|
82
|
+
await (await s3Service()).send(command);
|
|
83
|
+
return {
|
|
84
|
+
...source,
|
|
85
|
+
path: destinationPathWithoutLeadingSlash
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
const copyFileToDirectory = async (source, destination) => {
|
|
89
|
+
const destinationPath = path.join(destination, source.label);
|
|
90
|
+
return copyFileTo(source, destinationPath);
|
|
91
|
+
};
|
|
92
|
+
const isTemporaryUpload = (source) => {
|
|
93
|
+
return source.path.indexOf('uploads/') === 0;
|
|
94
|
+
};
|
|
95
|
+
const getFileChecksum = async (source) => {
|
|
96
|
+
const bucket = (await bucketName());
|
|
97
|
+
const command = new HeadObjectCommand({ Bucket: bucket, Key: source.path });
|
|
98
|
+
const response = await (await s3Service()).send(command);
|
|
99
|
+
return assertDefined(response.ETag);
|
|
100
|
+
};
|
|
101
|
+
const filesEqual = async (sourceA, sourceB) => {
|
|
102
|
+
const [aSum, bSum] = await Promise.all([getFileChecksum(sourceA), getFileChecksum(sourceB)]);
|
|
103
|
+
return aSum === bSum;
|
|
104
|
+
};
|
|
44
105
|
return {
|
|
45
106
|
getFileContent,
|
|
46
107
|
putFileContent,
|
|
47
108
|
getSignedViewerUrl,
|
|
109
|
+
getSignedFileUploadConfig,
|
|
110
|
+
copyFileTo,
|
|
111
|
+
copyFileToDirectory,
|
|
112
|
+
isTemporaryUpload,
|
|
113
|
+
getFileChecksum,
|
|
114
|
+
filesEqual,
|
|
48
115
|
};
|
|
49
116
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JWK } from 'node-jose';
|
|
2
2
|
import { ConfigProviderForConfig } from '../../config';
|
|
3
3
|
import type { JsonCompatibleValue } from '../../routing';
|
|
4
|
-
|
|
4
|
+
type Config = {
|
|
5
5
|
alg: string;
|
|
6
6
|
expiresIn: string;
|
|
7
7
|
iss: string;
|
|
@@ -13,16 +13,11 @@ interface Initializer<C> {
|
|
|
13
13
|
/**
|
|
14
14
|
* Creates a class that can sign launch params
|
|
15
15
|
*/
|
|
16
|
-
export declare const createLaunchSigner: <C extends string = "launch">({ configSpace }: Initializer<C>) => (configProvider: { [
|
|
17
|
-
alg: import("../../config").ConfigValueProvider<string>;
|
|
18
|
-
expiresIn: import("../../config").ConfigValueProvider<string>;
|
|
19
|
-
iss: import("../../config").ConfigValueProvider<string>;
|
|
20
|
-
privateKey: import("../../config").ConfigValueProvider<string>;
|
|
21
|
-
}; }) => {
|
|
16
|
+
export declare const createLaunchSigner: <C extends string = "launch">({ configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => {
|
|
22
17
|
jwks: () => Promise<{
|
|
23
18
|
keys: JWK.RawKey[];
|
|
24
19
|
}>;
|
|
25
|
-
sign: (data: Record<string, JsonCompatibleValue>, subject: string, maxExp?: number | null
|
|
20
|
+
sign: (data: Record<string, JsonCompatibleValue>, subject: string, maxExp?: number | null) => Promise<string>;
|
|
26
21
|
};
|
|
27
|
-
export
|
|
22
|
+
export type LaunchSigner = ReturnType<ReturnType<typeof createLaunchSigner>>;
|
|
28
23
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import jwt from 'jsonwebtoken';
|
|
2
2
|
import type { JWK } from 'node-jose';
|
|
3
3
|
import { ConfigProviderForConfig } from '../../config';
|
|
4
|
-
|
|
4
|
+
type Config = {
|
|
5
5
|
trustedDomain: string;
|
|
6
6
|
bypassSignatureVerification: string;
|
|
7
7
|
};
|
|
@@ -14,11 +14,8 @@ interface Initializer<C> {
|
|
|
14
14
|
/**
|
|
15
15
|
* Creates a class that can verify launch params
|
|
16
16
|
*/
|
|
17
|
-
export declare const createLaunchVerifier: <C extends string = "launch">({ configSpace, fetcher }: Initializer<C>) => (configProvider: { [
|
|
18
|
-
|
|
19
|
-
bypassSignatureVerification: import("../../config").ConfigValueProvider<string>;
|
|
20
|
-
}; }) => (_services: {}, getDefaultToken?: (() => string) | undefined) => {
|
|
21
|
-
verify: <T = undefined>(...args: T extends undefined ? [] | [string] : [(input: any) => T] | [string, (input: any) => T]) => Promise<T extends undefined ? jwt.JwtPayload : T>;
|
|
17
|
+
export declare const createLaunchVerifier: <C extends string = "launch">({ configSpace, fetcher }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => (_services: {}, getDefaultToken?: () => string) => {
|
|
18
|
+
verify: <T = undefined>(...args: T extends undefined ? ([] | [string]) : ([(input: any) => T] | [string, (input: any) => T])) => Promise<T extends undefined ? jwt.JwtPayload : T>;
|
|
22
19
|
};
|
|
23
|
-
export
|
|
20
|
+
export type LaunchVerifier = ReturnType<ReturnType<ReturnType<typeof createLaunchVerifier>>>;
|
|
24
21
|
export {};
|
|
@@ -13,7 +13,7 @@ export declare enum Level {
|
|
|
13
13
|
* @param level - log level
|
|
14
14
|
* @param event - event to log
|
|
15
15
|
*/
|
|
16
|
-
export
|
|
16
|
+
export type LogEvent = (level: Level, event: JsonCompatibleStruct) => void;
|
|
17
17
|
/**
|
|
18
18
|
* A logger that can be used to log events.
|
|
19
19
|
*
|
|
@@ -36,4 +36,4 @@ export interface Logger {
|
|
|
36
36
|
* (the context is returned when messages are logged with the logger)
|
|
37
37
|
* @returns a Logger
|
|
38
38
|
*/
|
|
39
|
-
export declare const createCoreLogger: (driver: LogEvent, getParentContext?: (
|
|
39
|
+
export declare const createCoreLogger: (driver: LogEvent, getParentContext?: () => JsonCompatibleStruct) => Logger;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { User } from '../authProvider';
|
|
2
2
|
import { EagerXapiStatement, UXapiStatement, XapiStatement } from '.';
|
|
3
|
-
export declare const addStatementDefaultFields: (statement: (Pick<XapiStatement,
|
|
3
|
+
export declare const addStatementDefaultFields: (statement: (Pick<XapiStatement, "object" | "verb" | "context" | "result"> & {
|
|
4
4
|
id?: string;
|
|
5
5
|
}) | UXapiStatement, user: User) => EagerXapiStatement;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LrsGateway, UXapiStatement } from '.';
|
|
2
|
-
export
|
|
2
|
+
export type ActivityState = {
|
|
3
3
|
attempts: number;
|
|
4
4
|
completedAttempts: number;
|
|
5
5
|
currentAttempt?: UXapiStatement;
|
|
@@ -11,60 +11,60 @@ export declare type ActivityState = {
|
|
|
11
11
|
export declare const matchAttempt: (statement: UXapiStatement) => boolean;
|
|
12
12
|
export declare const matchAttemptCompleted: (attempt: UXapiStatement) => (statement: UXapiStatement) => boolean;
|
|
13
13
|
export declare const resolveAttempts: (statements: UXapiStatement[], options?: {
|
|
14
|
-
activityIRI?: string
|
|
15
|
-
parentActivityAttempt?: string
|
|
16
|
-
}
|
|
17
|
-
export declare const resolveCompletedForAttempt: (statements: UXapiStatement[], attempt: UXapiStatement, activityIRI?: string
|
|
14
|
+
activityIRI?: string;
|
|
15
|
+
parentActivityAttempt?: string;
|
|
16
|
+
}) => UXapiStatement[];
|
|
17
|
+
export declare const resolveCompletedForAttempt: (statements: UXapiStatement[], attempt: UXapiStatement, activityIRI?: string) => UXapiStatement | undefined;
|
|
18
18
|
export declare const oldestStatement: (statements: UXapiStatement[]) => UXapiStatement | undefined;
|
|
19
19
|
export declare const mostRecentStatement: (statements: UXapiStatement[]) => UXapiStatement | undefined;
|
|
20
20
|
export declare const resolveAttemptInfo: (statements: UXapiStatement[], options?: {
|
|
21
|
-
activityIRI?: string
|
|
22
|
-
currentAttempt?: string
|
|
23
|
-
parentActivityAttempt?: string
|
|
24
|
-
currentPreference?: "latest" | "oldest"
|
|
25
|
-
}
|
|
21
|
+
activityIRI?: string;
|
|
22
|
+
currentAttempt?: string;
|
|
23
|
+
parentActivityAttempt?: string;
|
|
24
|
+
currentPreference?: "latest" | "oldest";
|
|
25
|
+
}) => ActivityState;
|
|
26
26
|
export declare const loadStatementsForActivityAndFirstChildren: (gateway: LrsGateway, activityIRI: string, options?: {
|
|
27
|
-
anyUser?: boolean
|
|
28
|
-
attempt?: string
|
|
29
|
-
ensureSync?: boolean
|
|
30
|
-
user?: string
|
|
31
|
-
}
|
|
27
|
+
anyUser?: boolean;
|
|
28
|
+
attempt?: string;
|
|
29
|
+
ensureSync?: boolean;
|
|
30
|
+
user?: string;
|
|
31
|
+
}) => Promise<import(".").XapiStatement[]>;
|
|
32
32
|
export declare const loadActivityAttemptInfo: (gateway: LrsGateway, activityIRI: string, options?: {
|
|
33
|
-
currentAttempt?: string
|
|
34
|
-
parentActivityAttempt?: string
|
|
35
|
-
ensureSync?: boolean
|
|
36
|
-
}
|
|
37
|
-
export declare const createStatement: (verb: UXapiStatement[
|
|
33
|
+
currentAttempt?: string;
|
|
34
|
+
parentActivityAttempt?: string;
|
|
35
|
+
ensureSync?: boolean;
|
|
36
|
+
}) => Promise<ActivityState>;
|
|
37
|
+
export declare const createStatement: (verb: UXapiStatement["verb"], activity: {
|
|
38
38
|
iri: string;
|
|
39
39
|
type: string;
|
|
40
40
|
name: string;
|
|
41
41
|
extensions?: {
|
|
42
42
|
[key: string]: string;
|
|
43
|
-
}
|
|
44
|
-
}, attempt: string, parentActivityIRI?: string
|
|
43
|
+
};
|
|
44
|
+
}, attempt: string, parentActivityIRI?: string) => Pick<UXapiStatement, "object" | "verb" | "context">;
|
|
45
45
|
export declare const createAttemptStatement: (activity: {
|
|
46
46
|
iri: string;
|
|
47
47
|
type: string;
|
|
48
48
|
name: string;
|
|
49
49
|
extensions?: {
|
|
50
50
|
[key: string]: string;
|
|
51
|
-
}
|
|
51
|
+
};
|
|
52
52
|
}, parentActivity?: {
|
|
53
|
-
iri?: string
|
|
54
|
-
attempt?: string
|
|
55
|
-
}
|
|
53
|
+
iri?: string;
|
|
54
|
+
attempt?: string;
|
|
55
|
+
}) => Pick<UXapiStatement, "object" | "verb" | "context">;
|
|
56
56
|
export declare const putAttemptStatement: (gateway: LrsGateway, activity: {
|
|
57
57
|
iri: string;
|
|
58
58
|
type: string;
|
|
59
59
|
name: string;
|
|
60
60
|
extensions?: {
|
|
61
61
|
[key: string]: string;
|
|
62
|
-
}
|
|
62
|
+
};
|
|
63
63
|
}, parentActivity?: {
|
|
64
|
-
iri?: string
|
|
65
|
-
attempt?: string
|
|
66
|
-
}
|
|
67
|
-
export declare const createAttemptActivityStatement: (attemptStatement: UXapiStatement, verb: UXapiStatement[
|
|
68
|
-
export declare const putAttemptActivityStatement: (gateway: LrsGateway, attemptStatement: UXapiStatement, verb: UXapiStatement[
|
|
69
|
-
export declare const createCompletedStatement: (attemptStatement: UXapiStatement, result?: UXapiStatement[
|
|
70
|
-
export declare const putCompletedStatement: (gateway: LrsGateway, attemptStatement: UXapiStatement, result: UXapiStatement[
|
|
64
|
+
iri?: string;
|
|
65
|
+
attempt?: string;
|
|
66
|
+
}) => Promise<import(".").EagerXapiStatement>;
|
|
67
|
+
export declare const createAttemptActivityStatement: (attemptStatement: UXapiStatement, verb: UXapiStatement["verb"], result?: UXapiStatement["result"]) => Pick<UXapiStatement, "object" | "verb" | "context" | "result">;
|
|
68
|
+
export declare const putAttemptActivityStatement: (gateway: LrsGateway, attemptStatement: UXapiStatement, verb: UXapiStatement["verb"], result?: UXapiStatement["result"]) => Promise<import(".").EagerXapiStatement>;
|
|
69
|
+
export declare const createCompletedStatement: (attemptStatement: UXapiStatement, result?: UXapiStatement["result"]) => Pick<UXapiStatement, "object" | "verb" | "context" | "result">;
|
|
70
|
+
export declare const putCompletedStatement: (gateway: LrsGateway, attemptStatement: UXapiStatement, result: UXapiStatement["result"]) => Promise<import(".").EagerXapiStatement>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConfigProviderForConfig } from '../../config';
|
|
2
2
|
import { AuthProvider } from '../authProvider';
|
|
3
3
|
import { LrsGateway } from '.';
|
|
4
|
-
|
|
4
|
+
type Config = {
|
|
5
5
|
name: string;
|
|
6
6
|
};
|
|
7
7
|
interface Initializer<C> {
|
|
@@ -9,9 +9,7 @@ interface Initializer<C> {
|
|
|
9
9
|
fs?: Pick<typeof import('fs'), 'readFile' | 'writeFile'>;
|
|
10
10
|
configSpace?: C;
|
|
11
11
|
}
|
|
12
|
-
export declare const fileSystemLrsGateway: <C extends string = "fileSystem">(initializer: Initializer<C>) => (configProvider: { [
|
|
13
|
-
name: import("../../config").ConfigValueProvider<string>;
|
|
14
|
-
}; }) => ({ authProvider }: {
|
|
12
|
+
export declare const fileSystemLrsGateway: <C extends string = "fileSystem">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => ({ authProvider }: {
|
|
15
13
|
authProvider: AuthProvider;
|
|
16
14
|
}) => LrsGateway;
|
|
17
15
|
export {};
|
|
@@ -3,7 +3,7 @@ import { GenericFetch } from '../../fetch';
|
|
|
3
3
|
import { WithRequired } from '../../types';
|
|
4
4
|
import { AuthProvider } from '../authProvider';
|
|
5
5
|
import { Logger } from '../logger';
|
|
6
|
-
|
|
6
|
+
type Config = {
|
|
7
7
|
lrsHost: string;
|
|
8
8
|
lrsAuthorization: string;
|
|
9
9
|
};
|
|
@@ -73,32 +73,29 @@ export interface XapiStatement {
|
|
|
73
73
|
timestamp: string;
|
|
74
74
|
stored?: string;
|
|
75
75
|
}
|
|
76
|
-
export
|
|
77
|
-
export
|
|
78
|
-
export
|
|
79
|
-
export
|
|
80
|
-
export
|
|
81
|
-
export declare const lrsGateway: <C extends string = "lrs">(initializer: Initializer<C>) => (configProvider: { [
|
|
82
|
-
lrsHost: import("../../config").ConfigValueProvider<string>;
|
|
83
|
-
lrsAuthorization: import("../../config").ConfigValueProvider<string>;
|
|
84
|
-
}; }) => ({ authProvider, logger }: {
|
|
76
|
+
export type SavedXapiStatement = WithRequired<XapiStatement, 'stored'>;
|
|
77
|
+
export type EagerXapiStatement = Omit<XapiStatement, 'stored'>;
|
|
78
|
+
export type UXapiStatement = XapiStatement | EagerXapiStatement | SavedXapiStatement;
|
|
79
|
+
export type LrsGateway = ReturnType<ReturnType<ReturnType<typeof lrsGateway>>>;
|
|
80
|
+
export type LrsProvider = ReturnType<ReturnType<typeof lrsGateway>>;
|
|
81
|
+
export declare const lrsGateway: <C extends string = "lrs">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => ({ authProvider, logger }: {
|
|
85
82
|
authProvider: AuthProvider;
|
|
86
83
|
logger: Logger;
|
|
87
84
|
}) => {
|
|
88
|
-
putXapiStatements: (statements: Array<(Pick<XapiStatement,
|
|
85
|
+
putXapiStatements: (statements: Array<(Pick<XapiStatement, "object" | "verb" | "context" | "result"> & {
|
|
89
86
|
id?: string;
|
|
90
87
|
}) | UXapiStatement>) => Promise<EagerXapiStatement[]>;
|
|
91
88
|
getXapiStatements: (params: {
|
|
92
|
-
verb?: string
|
|
93
|
-
activity?: string
|
|
94
|
-
registration?: string
|
|
95
|
-
related_activities?: boolean
|
|
96
|
-
user?: string
|
|
97
|
-
anyUser?: boolean
|
|
98
|
-
since?: string
|
|
99
|
-
until?: string
|
|
89
|
+
verb?: string;
|
|
90
|
+
activity?: string;
|
|
91
|
+
registration?: string;
|
|
92
|
+
related_activities?: boolean;
|
|
93
|
+
user?: string;
|
|
94
|
+
anyUser?: boolean;
|
|
95
|
+
since?: string;
|
|
96
|
+
until?: string;
|
|
100
97
|
} & {
|
|
101
|
-
ensureSync?: boolean
|
|
98
|
+
ensureSync?: boolean;
|
|
102
99
|
}) => Promise<{
|
|
103
100
|
more: string;
|
|
104
101
|
statements: XapiStatement[];
|
|
@@ -107,19 +104,19 @@ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initial
|
|
|
107
104
|
more: string;
|
|
108
105
|
statements: XapiStatement[];
|
|
109
106
|
}>;
|
|
110
|
-
getAllXapiStatements: ({ fetchUntil, ...params }: {
|
|
111
|
-
verb?: string
|
|
112
|
-
activity?: string
|
|
113
|
-
registration?: string
|
|
114
|
-
related_activities?: boolean
|
|
115
|
-
user?: string
|
|
116
|
-
anyUser?: boolean
|
|
117
|
-
since?: string
|
|
118
|
-
until?: string
|
|
119
|
-
} & {
|
|
120
|
-
ensureSync?: boolean | undefined;
|
|
107
|
+
getAllXapiStatements: ({ fetchUntil, ...params }: ({
|
|
108
|
+
verb?: string;
|
|
109
|
+
activity?: string;
|
|
110
|
+
registration?: string;
|
|
111
|
+
related_activities?: boolean;
|
|
112
|
+
user?: string;
|
|
113
|
+
anyUser?: boolean;
|
|
114
|
+
since?: string;
|
|
115
|
+
until?: string;
|
|
121
116
|
} & {
|
|
122
|
-
|
|
117
|
+
ensureSync?: boolean;
|
|
118
|
+
}) & {
|
|
119
|
+
fetchUntil?: (statements: XapiStatement[]) => boolean;
|
|
123
120
|
}) => Promise<XapiStatement[]>;
|
|
124
121
|
};
|
|
125
122
|
export {};
|
|
@@ -11,12 +11,12 @@ export interface Grade {
|
|
|
11
11
|
userId?: string;
|
|
12
12
|
}
|
|
13
13
|
export declare const getRegistrationAttemptInfo: (lrs: LrsGateway, registration: string, options?: {
|
|
14
|
-
activity?: string
|
|
15
|
-
anyUser?: boolean
|
|
16
|
-
currentPreference?: "latest" | "oldest"
|
|
17
|
-
ensureSync?: boolean
|
|
18
|
-
user?: string
|
|
19
|
-
}
|
|
14
|
+
activity?: string;
|
|
15
|
+
anyUser?: boolean;
|
|
16
|
+
currentPreference?: "latest" | "oldest";
|
|
17
|
+
ensureSync?: boolean;
|
|
18
|
+
user?: string;
|
|
19
|
+
}) => Promise<{
|
|
20
20
|
[key: string]: ActivityState;
|
|
21
21
|
}>;
|
|
22
22
|
export declare const getScoreGrade: (score: {
|
|
@@ -24,13 +24,13 @@ export declare const getScoreGrade: (score: {
|
|
|
24
24
|
raw?: number;
|
|
25
25
|
min?: number;
|
|
26
26
|
max?: number;
|
|
27
|
-
}, completed: boolean, userId?: string
|
|
28
|
-
export
|
|
27
|
+
}, completed: boolean, userId?: string, maxScore?: number) => Grade;
|
|
28
|
+
export type Progress = {
|
|
29
29
|
scaled: number;
|
|
30
30
|
max?: number;
|
|
31
31
|
raw?: number;
|
|
32
32
|
};
|
|
33
|
-
export
|
|
33
|
+
export type GradeAndProgress = {
|
|
34
34
|
grade: Grade;
|
|
35
35
|
progress: Progress;
|
|
36
36
|
name?: string;
|
|
@@ -39,21 +39,21 @@ export declare const getCurrentGrade: (services: {
|
|
|
39
39
|
lrs: LrsGateway;
|
|
40
40
|
ltiAuthProvider: AuthProvider;
|
|
41
41
|
}, registration: string, options?: {
|
|
42
|
-
currentPreference?: "latest" | "oldest"
|
|
43
|
-
incompleteAttemptCallback?: (
|
|
44
|
-
name?: string
|
|
45
|
-
scoreMaximum?: number
|
|
46
|
-
userId?: string
|
|
47
|
-
}
|
|
48
|
-
export
|
|
42
|
+
currentPreference?: "latest" | "oldest";
|
|
43
|
+
incompleteAttemptCallback?: (info: ActivityState) => Promise<GradeAndProgress>;
|
|
44
|
+
name?: string;
|
|
45
|
+
scoreMaximum?: number;
|
|
46
|
+
userId?: string;
|
|
47
|
+
}) => Promise<GradeAndProgress | null>;
|
|
48
|
+
export type UserActivityInfo = MappedUserInfo<ActivityState>;
|
|
49
49
|
export declare const getAssignmentGrades: (services: {
|
|
50
50
|
accountsGateway: AccountsGateway;
|
|
51
51
|
lrs: LrsGateway;
|
|
52
52
|
}, assignmentIRI: string, registration: string, options?: {
|
|
53
|
-
anyUser?: boolean
|
|
54
|
-
currentPreference?: "latest" | "oldest"
|
|
55
|
-
incompleteAttemptsCallback?: (
|
|
56
|
-
platformId?: string
|
|
57
|
-
scoreMaximum?: number
|
|
58
|
-
user?: string
|
|
59
|
-
}
|
|
53
|
+
anyUser?: boolean;
|
|
54
|
+
currentPreference?: "latest" | "oldest";
|
|
55
|
+
incompleteAttemptsCallback?: (mappedInfo: UserActivityInfo[]) => Promise<GradeAndProgress[]>;
|
|
56
|
+
platformId?: string;
|
|
57
|
+
scoreMaximum?: number;
|
|
58
|
+
user?: string;
|
|
59
|
+
}) => Promise<GradeAndProgress[]>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import postgres, { Sql } from 'postgres';
|
|
2
2
|
import { ConfigProviderForConfig } from '../../config';
|
|
3
3
|
import type { Logger } from '../logger';
|
|
4
|
-
|
|
4
|
+
type Config = {
|
|
5
5
|
host: string;
|
|
6
6
|
readHost: string;
|
|
7
7
|
port: string;
|
|
@@ -12,14 +12,7 @@ declare type Config = {
|
|
|
12
12
|
interface Initializer<C> {
|
|
13
13
|
configSpace?: C;
|
|
14
14
|
}
|
|
15
|
-
export declare const postgresConnection: <C extends string = "local">(initializer: Initializer<C>) => (configProvider: { [
|
|
16
|
-
host: import("../../config").ConfigValueProvider<string>;
|
|
17
|
-
readHost: import("../../config").ConfigValueProvider<string>;
|
|
18
|
-
port: import("../../config").ConfigValueProvider<string>;
|
|
19
|
-
database: import("../../config").ConfigValueProvider<string>;
|
|
20
|
-
username: import("../../config").ConfigValueProvider<string>;
|
|
21
|
-
password: import("../../config").ConfigValueProvider<string>;
|
|
22
|
-
}; }) => (services: {
|
|
15
|
+
export declare const postgresConnection: <C extends string = "local">(initializer: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => (services: {
|
|
23
16
|
logger: Logger;
|
|
24
17
|
}) => {
|
|
25
18
|
db: () => Promise<postgres.Sql<{}>>;
|
|
@@ -27,7 +20,7 @@ export declare const postgresConnection: <C extends string = "local">(initialize
|
|
|
27
20
|
migrate: (migrations: Migration[]) => Promise<void>;
|
|
28
21
|
down: () => Promise<void[]>;
|
|
29
22
|
};
|
|
30
|
-
export
|
|
23
|
+
export type PostgresConnection = ReturnType<ReturnType<ReturnType<typeof postgresConnection>>>;
|
|
31
24
|
export interface Migration {
|
|
32
25
|
name: string;
|
|
33
26
|
up: (db: Sql) => Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
1
|
+
export type FieldType = string | string[] | number | boolean;
|
|
2
|
+
export type ESFilter = {
|
|
3
3
|
terms: Record<string, FieldType>;
|
|
4
4
|
} | {
|
|
5
5
|
term: Record<string, FieldType>;
|
|
@@ -15,18 +15,18 @@ export declare type ESFilter = {
|
|
|
15
15
|
} | {
|
|
16
16
|
bool: BoolFilter;
|
|
17
17
|
};
|
|
18
|
-
export
|
|
18
|
+
export type Filter = {
|
|
19
19
|
key: string;
|
|
20
20
|
value: FieldType;
|
|
21
21
|
} | ESFilter;
|
|
22
|
-
export
|
|
22
|
+
export type BoolFilter = {
|
|
23
23
|
must?: Filter[];
|
|
24
24
|
must_not?: Filter[];
|
|
25
25
|
should?: Filter[];
|
|
26
26
|
filter?: Filter[];
|
|
27
27
|
minimum_should_match?: number;
|
|
28
28
|
};
|
|
29
|
-
|
|
29
|
+
type Field = {
|
|
30
30
|
key: string;
|
|
31
31
|
type?: 'text';
|
|
32
32
|
weight: number;
|
|
@@ -41,7 +41,7 @@ export interface IndexOptions<T> {
|
|
|
41
41
|
body: T;
|
|
42
42
|
id: string;
|
|
43
43
|
}
|
|
44
|
-
export
|
|
44
|
+
export type FieldMapping = {
|
|
45
45
|
type: 'keyword' | 'text' | 'boolean';
|
|
46
46
|
} | {
|
|
47
47
|
type: 'date';
|
|
@@ -50,7 +50,7 @@ export declare type FieldMapping = {
|
|
|
50
50
|
type?: 'nested' | 'object';
|
|
51
51
|
properties: Record<string, FieldMapping>;
|
|
52
52
|
};
|
|
53
|
-
export
|
|
53
|
+
export type FieldMappings = Record<string, FieldMapping>;
|
|
54
54
|
export interface SearchOptions {
|
|
55
55
|
page?: number;
|
|
56
56
|
query: string | undefined;
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { ConfigProviderForConfig } from '../../config';
|
|
2
2
|
import { FieldMappings, IndexOptions, SearchOptions } from '.';
|
|
3
|
-
export
|
|
3
|
+
export type Config = {
|
|
4
4
|
node: string;
|
|
5
5
|
region: string;
|
|
6
6
|
};
|
|
7
7
|
export interface Initializer<C> {
|
|
8
8
|
configSpace?: C;
|
|
9
9
|
}
|
|
10
|
-
export
|
|
10
|
+
export type IndexConfig = {
|
|
11
11
|
name: string;
|
|
12
12
|
mappings: FieldMappings;
|
|
13
13
|
pageSize?: number;
|
|
14
14
|
};
|
|
15
|
-
export declare const openSearchService: <C extends string = "deployed">(initializer?: Initializer<C>) => (configProvider: { [
|
|
16
|
-
node: import("../../config").ConfigValueProvider<string>;
|
|
17
|
-
region: import("../../config").ConfigValueProvider<string>;
|
|
18
|
-
}; }) => <T>(indexConfig: IndexConfig) => {
|
|
15
|
+
export declare const openSearchService: <C extends string = "deployed">(initializer?: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => <T>(indexConfig: IndexConfig) => {
|
|
19
16
|
ensureIndexCreated: () => Promise<void>;
|
|
20
17
|
deleteIndexIfExists: () => Promise<void>;
|
|
21
18
|
index: (params: IndexOptions<T>) => Promise<void>;
|