@openstax/ts-utils 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ const routing_1 = require("../routing");
6
6
  const createLambdaCorsResponseMiddleware = (config) => (responsePromise, { request }) => {
7
7
  const cors = async () => {
8
8
  const allowedHost = await (0, resolveConfigValue_1.resolveConfigValue)(config.corsAllowedHostRegex);
9
- if (request.headers.origin && new URL(request.headers.origin).hostname.match(new RegExp(allowedHost))) {
9
+ if (request.headers.origin && request.headers.origin !== 'null' && new URL(request.headers.origin).hostname.match(new RegExp(allowedHost))) {
10
10
  return {
11
11
  'Access-Control-Allow-Origin': request.headers.origin,
12
12
  'Access-Control-Allow-Credentials': 'true',
@@ -48,7 +48,9 @@ export declare const browserAuthProvider: <C extends string = "auth">({ window,
48
48
  * gets an authorized url for an iframe src. sets params on the url and saves its
49
49
  * origin to trust releasing user identity to it
50
50
  */
51
- getAuthorizedEmbedUrl: (urlString: string) => string;
51
+ getAuthorizedEmbedUrl: (urlString: string, extraParams?: {
52
+ [key: string]: string;
53
+ } | undefined) => string;
52
54
  /**
53
55
  * gets second argument for `fetch` that has authentication token or cookie
54
56
  */
@@ -14,7 +14,9 @@ export declare const embeddedAuthProvider: (getUserData: UserDataLoader, { query
14
14
  window: Window;
15
15
  }) => {
16
16
  embeddedQueryValue: string;
17
- getAuthorizedEmbedUrl: (urlString: string) => string;
17
+ getAuthorizedEmbedUrl: (urlString: string, extraParams?: {
18
+ [key: string]: string;
19
+ } | undefined) => string;
18
20
  unmount: () => void;
19
21
  };
20
22
  export {};
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.embeddedAuthProvider = exports.PostMessageTypes = void 0;
7
+ const query_string_1 = __importDefault(require("query-string"));
4
8
  var PostMessageTypes;
5
9
  (function (PostMessageTypes) {
6
10
  PostMessageTypes["ReceiveUser"] = "receive-user";
@@ -17,10 +21,11 @@ const embeddedAuthProvider = (getUserData, { queryKey = 'auth', window }) => {
17
21
  }
18
22
  };
19
23
  window.addEventListener('message', messageHandler);
20
- const getAuthorizedEmbedUrl = (urlString) => {
24
+ const getAuthorizedEmbedUrl = (urlString, extraParams) => {
21
25
  const url = new URL(urlString);
22
26
  trustedEmbeds.add(url.origin);
23
- url.searchParams.set(queryKey, embeddedQueryValue);
27
+ const params = query_string_1.default.parse(url.search);
28
+ url.search = query_string_1.default.stringify({ ...params, ...extraParams, [queryKey]: embeddedQueryValue });
24
29
  return url.href;
25
30
  };
26
31
  return {
@@ -19,12 +19,21 @@ export declare const resolveActivityAttemptInfo: (statements: XapiStatement[], a
19
19
  parentActivityAttempt?: string | undefined;
20
20
  currentPreference?: "latest" | "oldest" | undefined;
21
21
  } | undefined) => ActivityState;
22
- export declare const loadStatementsForActivityAndFirstChildren: (gateway: LrsGateway, activityIRI: string, attempt?: string | undefined) => Promise<XapiStatement[]>;
23
- export declare const loadStatementsForAttempt: (gateway: LrsGateway, attempt: string) => Promise<XapiStatement[]>;
24
- export declare const loadStatementsForActivity: (gateway: LrsGateway, activityIRI: string, attempt?: string | undefined) => Promise<XapiStatement[]>;
22
+ export declare const loadStatementsForActivityAndFirstChildren: (gateway: LrsGateway, activityIRI: string, options?: {
23
+ attempt?: string | undefined;
24
+ ensureSync?: boolean | undefined;
25
+ } | undefined) => Promise<XapiStatement[]>;
26
+ export declare const loadStatementsForAttempt: (gateway: LrsGateway, attempt: string, options?: {
27
+ ensureSync?: boolean | undefined;
28
+ } | undefined) => Promise<XapiStatement[]>;
29
+ export declare const loadStatementsForActivity: (gateway: LrsGateway, activityIRI: string, options?: {
30
+ attempt?: string | undefined;
31
+ ensureSync?: boolean | undefined;
32
+ } | undefined) => Promise<XapiStatement[]>;
25
33
  export declare const loadActivityAttemptInfo: (gateway: LrsGateway, activityIRI: string, options?: {
26
34
  currentAttempt?: string | undefined;
27
35
  parentActivityAttempt?: string | undefined;
36
+ ensureSync?: boolean | undefined;
28
37
  } | undefined) => Promise<ActivityState>;
29
38
  export declare const createStatement: (verb: XapiStatement['verb'], activity: {
30
39
  iri: string;
@@ -91,35 +91,42 @@ exports.resolveActivityAttemptInfo = resolveActivityAttemptInfo;
91
91
  * statements would then have to be fetched using `loadStatementsForActivity(gateway, childActivityIRI, childAttemptStatementID)`. this
92
92
  * is because child activities could have multiple attempts under one attempt on the parent activity.
93
93
  */
94
- const loadStatementsForActivityAndFirstChildren = (gateway, activityIRI, attempt) => {
94
+ const loadStatementsForActivityAndFirstChildren = (gateway, activityIRI, options) => {
95
+ const { attempt, ...partialOptions } = options ? options : { attempt: undefined };
96
+ const getOptions = attempt ? { registration: attempt, ...partialOptions } : partialOptions;
95
97
  return gateway.getAllXapiStatements({
96
98
  activity: activityIRI,
97
99
  related_activities: true,
98
- ...(attempt ? { registration: attempt } : {})
100
+ ...getOptions,
99
101
  });
100
102
  };
101
103
  exports.loadStatementsForActivityAndFirstChildren = loadStatementsForActivityAndFirstChildren;
102
104
  /*
103
105
  * loads all statements (for this actor) that have the given parent attempt (registration)
104
106
  */
105
- const loadStatementsForAttempt = (gateway, attempt) => {
107
+ const loadStatementsForAttempt = (gateway, attempt, options) => {
106
108
  return gateway.getAllXapiStatements({
107
- registration: attempt
109
+ registration: attempt,
110
+ ...(options ? options : {})
108
111
  });
109
112
  };
110
113
  exports.loadStatementsForAttempt = loadStatementsForAttempt;
111
114
  /*
112
115
  * loads all statements (for this actor) that have the given activityIRI as the object.id
113
116
  */
114
- const loadStatementsForActivity = (gateway, activityIRI, attempt) => {
117
+ const loadStatementsForActivity = (gateway, activityIRI, options) => {
118
+ const { attempt, ...partialOptions } = options ? options : { attempt: undefined };
119
+ const getOptions = attempt ? { registration: attempt, ...partialOptions } : partialOptions;
115
120
  return gateway.getAllXapiStatements({
116
121
  activity: activityIRI,
117
- ...(attempt ? { registration: attempt } : {})
122
+ ...getOptions,
118
123
  });
119
124
  };
120
125
  exports.loadStatementsForActivity = loadStatementsForActivity;
121
126
  const loadActivityAttemptInfo = async (gateway, activityIRI, options) => {
122
- return (0, exports.resolveActivityAttemptInfo)(await (0, exports.loadStatementsForActivity)(gateway, activityIRI, options === null || options === void 0 ? void 0 : options.parentActivityAttempt), activityIRI, options);
127
+ const { parentActivityAttempt, ...partialOptions } = options ? options : { parentActivityAttempt: undefined };
128
+ const loadOptions = parentActivityAttempt ? { attempt: parentActivityAttempt } : partialOptions;
129
+ return (0, exports.resolveActivityAttemptInfo)(await (0, exports.loadStatementsForActivity)(gateway, activityIRI, loadOptions), activityIRI, options);
123
130
  };
124
131
  exports.loadActivityAttemptInfo = loadActivityAttemptInfo;
125
132
  const createStatement = (verb, activity, attempt, parentActivityIRI) => {
@@ -83,11 +83,12 @@ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initial
83
83
  putXapiStatements: (statements: Array<Pick<XapiStatement, 'object' | 'verb' | 'context' | 'result'> & {
84
84
  id?: string;
85
85
  }>) => Promise<EagerXapiStatement[]>;
86
- getXapiStatements: ({ user, anyUser, ...options }: {
86
+ getXapiStatements: (params: {
87
87
  verb?: string | undefined;
88
88
  activity?: string | undefined;
89
89
  registration?: string | undefined;
90
90
  related_activities?: boolean | undefined;
91
+ ensureSync?: boolean | undefined;
91
92
  user?: string | undefined;
92
93
  anyUser?: boolean | undefined;
93
94
  }) => Promise<{
@@ -98,11 +99,12 @@ export declare const lrsGateway: <C extends string = "lrs">(initializer: Initial
98
99
  more: string;
99
100
  statements: XapiStatement[];
100
101
  }>;
101
- getAllXapiStatements: (args_0: {
102
+ getAllXapiStatements: (params: {
102
103
  verb?: string | undefined;
103
104
  activity?: string | undefined;
104
105
  registration?: string | undefined;
105
106
  related_activities?: boolean | undefined;
107
+ ensureSync?: boolean | undefined;
106
108
  user?: string | undefined;
107
109
  anyUser?: boolean | undefined;
108
110
  }) => Promise<XapiStatement[]>;
@@ -88,7 +88,7 @@ ${await response.text()}`);
88
88
  'X-Experience-API-Version': '1.0.0',
89
89
  },
90
90
  }));
91
- const getXapiStatements = async ({ user, anyUser, ...options }) => formatGetXapiStatementsResponse(initializer.fetch((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements?' + queryString.stringify({
91
+ const fetchXapiStatements = async ({ user, anyUser, ...options }) => initializer.fetch((await lrsHost()).replace(/\/+$/, '') + '/data/xAPI/statements?' + queryString.stringify({
92
92
  ...options,
93
93
  ...(anyUser === true ? {} : {
94
94
  agent: JSON.stringify({
@@ -104,8 +104,25 @@ ${await response.text()}`);
104
104
  Authorization: await lrsAuthorization(),
105
105
  'X-Experience-API-Version': '1.0.0',
106
106
  },
107
- }));
108
- const getAllXapiStatements = async (...args) => {
107
+ });
108
+ const getXapiStatements = async (params) => {
109
+ if (params.ensureSync) {
110
+ const date = new Date();
111
+ return (0, __1.retryWithDelay)(async () => {
112
+ const responsePromise = fetchXapiStatements(params);
113
+ const response = await responsePromise;
114
+ const consistentThrough = response.headers.get('X-Experience-API-Consistent-Through');
115
+ if (!consistentThrough || new Date(consistentThrough) < date) {
116
+ throw new Error(`xAPI consistent through ${consistentThrough}; not in sync with current date ${date}.`);
117
+ }
118
+ return formatGetXapiStatementsResponse(responsePromise);
119
+ });
120
+ }
121
+ else {
122
+ return formatGetXapiStatementsResponse(fetchXapiStatements(params));
123
+ }
124
+ };
125
+ const getAllXapiStatements = async (params) => {
109
126
  const loadRemaining = async (result) => {
110
127
  if (!result.more) {
111
128
  return result.statements;
@@ -113,7 +130,7 @@ ${await response.text()}`);
113
130
  const { more, statements } = await getMoreXapiStatements(result.more);
114
131
  return loadRemaining({ more, statements: [...result.statements, ...statements] });
115
132
  };
116
- return loadRemaining(await getXapiStatements(...args));
133
+ return loadRemaining(await getXapiStatements(params));
117
134
  };
118
135
  return {
119
136
  putXapiStatements,