@openstax/ts-utils 1.32.1 → 1.32.3
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/routing/index.d.ts +2 -20
- package/dist/cjs/routing/index.js +1 -10
- package/dist/cjs/services/apiGateway/index.d.ts +1 -1
- package/dist/cjs/services/authProvider/browser.d.ts +6 -38
- package/dist/cjs/services/authProvider/browser.js +1 -0
- package/dist/cjs/services/authProvider/index.d.ts +1 -0
- package/dist/cjs/services/authProvider/index.js +10 -5
- package/dist/cjs/services/authProvider/subrequest.js +8 -6
- package/dist/cjs/services/authProvider/utils/embeddedAuthProvider.d.ts +2 -2
- package/dist/cjs/services/fileServer/index.d.ts +0 -12
- package/dist/cjs/services/fileServer/localFileServer.js +1 -52
- package/dist/cjs/services/fileServer/s3FileServer.d.ts +0 -1
- package/dist/cjs/services/fileServer/s3FileServer.js +0 -78
- package/dist/cjs/services/launchParams/signer.d.ts +2 -2
- package/dist/cjs/services/searchProvider/openSearch.js +4 -6
- package/dist/cjs/tsconfig.without-specs.cjs.tsbuildinfo +1 -1
- package/dist/esm/routing/index.d.ts +2 -20
- package/dist/esm/routing/index.js +0 -8
- package/dist/esm/services/apiGateway/index.d.ts +1 -1
- package/dist/esm/services/authProvider/browser.d.ts +6 -38
- package/dist/esm/services/authProvider/browser.js +1 -0
- package/dist/esm/services/authProvider/index.d.ts +1 -0
- package/dist/esm/services/authProvider/index.js +10 -5
- package/dist/esm/services/authProvider/subrequest.js +8 -6
- package/dist/esm/services/authProvider/utils/embeddedAuthProvider.d.ts +2 -2
- package/dist/esm/services/fileServer/index.d.ts +0 -12
- package/dist/esm/services/fileServer/localFileServer.js +2 -53
- package/dist/esm/services/fileServer/s3FileServer.d.ts +0 -1
- package/dist/esm/services/fileServer/s3FileServer.js +1 -76
- package/dist/esm/services/launchParams/signer.d.ts +2 -2
- package/dist/esm/services/searchProvider/openSearch.js +4 -6
- package/dist/esm/tsconfig.without-specs.esm.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/script/bin/.init-params-script.bash.swp +0 -0
|
@@ -25,20 +25,6 @@ export type RouteMatchRecord<R> = R extends AnyRoute<R> ? {
|
|
|
25
25
|
route: R;
|
|
26
26
|
params: ParamsForRoute<R>;
|
|
27
27
|
} : never;
|
|
28
|
-
type Flatten<T> = T extends any ? {
|
|
29
|
-
[K in keyof T]: T[K];
|
|
30
|
-
} : never;
|
|
31
|
-
export type ExternalRoute<R> = R extends Route<infer N, infer P, infer Sa, infer Sr, infer Ri, infer Ro> & infer E ? Route<N, P, Sa, Sr extends {
|
|
32
|
-
payload: any;
|
|
33
|
-
} ? Flatten<Pick<Sr, 'payload'>> : Record<string, never>, Ri, Ro> & Flatten<Omit<E, 'name' | 'path' | 'handler' | 'requestServiceProvider'>> : never;
|
|
34
|
-
/** this utility simplifies the route type to remove stuff that is only
|
|
35
|
-
* relevant internal to the route, like the service types, keeping only
|
|
36
|
-
* the payload type which is necessary for the apiGateway
|
|
37
|
-
*
|
|
38
|
-
* this helps avoid the "type too complicated" error that typescript throws
|
|
39
|
-
* when there are a lot of routes with complex services
|
|
40
|
-
**/
|
|
41
|
-
export declare const routesList: <R>(routes: R[]) => ExternalRoute<R>[];
|
|
42
28
|
/**
|
|
43
29
|
* The conditional type for the payload for a given route, `R`. This isn't a route structure, its
|
|
44
30
|
* a convention based on the request middleware
|
|
@@ -154,9 +140,7 @@ export declare const makeCreateRoute: <Sa, Ri, Ex = {}>() => CreateRoute<Sa, Ri,
|
|
|
154
140
|
*/
|
|
155
141
|
export declare const makeRenderRouteUrl: <Ru extends {
|
|
156
142
|
path: string;
|
|
157
|
-
}>() => <R>(route:
|
|
158
|
-
path: string;
|
|
159
|
-
} : R extends Ru ? R : never, params: ParamsForRoute<R>, query?: QueryParams) => string;
|
|
143
|
+
}>() => <R extends Ru>(route: R, params: ParamsForRoute<R>, query?: QueryParams) => string;
|
|
160
144
|
/**
|
|
161
145
|
* A pre-made result from `makeRenderRouteUrl`, this function interpolates parameter and query
|
|
162
146
|
* arguments into a route path.
|
|
@@ -169,9 +153,7 @@ export declare const makeRenderRouteUrl: <Ru extends {
|
|
|
169
153
|
* @param query the query parameters to add to the route path
|
|
170
154
|
* @returns the interpolated route path
|
|
171
155
|
*/
|
|
172
|
-
export declare const renderAnyRouteUrl: <R>(route:
|
|
173
|
-
path: string;
|
|
174
|
-
} : R extends any ? R : never, params: ParamsForRoute<R>, query?: QueryParams) => string;
|
|
156
|
+
export declare const renderAnyRouteUrl: <R extends any>(route: R, params: ParamsForRoute<R>, query?: QueryParams) => string;
|
|
175
157
|
type RequestPathExtractor<Ri> = (request: Ri) => string;
|
|
176
158
|
type RequestLogExtractor<Ri> = (request: Ri) => JsonCompatibleStruct;
|
|
177
159
|
type RequestRouteMatcher<Ri, R> = (request: Ri, route: R) => boolean;
|
|
@@ -2,14 +2,6 @@ import * as pathToRegexp from 'path-to-regexp';
|
|
|
2
2
|
import queryString from 'query-string';
|
|
3
3
|
import { mapFind, memoize } from '../misc/helpers';
|
|
4
4
|
import { createConsoleLogger } from '../services/logger/console';
|
|
5
|
-
/** this utility simplifies the route type to remove stuff that is only
|
|
6
|
-
* relevant internal to the route, like the service types, keeping only
|
|
7
|
-
* the payload type which is necessary for the apiGateway
|
|
8
|
-
*
|
|
9
|
-
* this helps avoid the "type too complicated" error that typescript throws
|
|
10
|
-
* when there are a lot of routes with complex services
|
|
11
|
-
**/
|
|
12
|
-
export const routesList = (routes) => routes;
|
|
13
5
|
/**
|
|
14
6
|
* Makes a createRoute function that can be used to create routes (this is a factory factory). The
|
|
15
7
|
* `makeCreateRoute` function is typically called once in the backend and once in the frontend to
|
|
@@ -38,7 +38,7 @@ export type ApiClientResponse<Ro> = Ro extends any ? {
|
|
|
38
38
|
} : never;
|
|
39
39
|
export type ExpandRoute<T> = T extends ((...args: infer A) => infer R) & {
|
|
40
40
|
renderUrl: (...args: infer Ar) => Promise<string>;
|
|
41
|
-
} ? (
|
|
41
|
+
} ? (...args: A) => R & {
|
|
42
42
|
renderUrl: (...args: Ar) => Promise<string>;
|
|
43
43
|
} : never;
|
|
44
44
|
export type MapRoutesToClient<Ru> = [Ru] extends [AnyRoute<Ru>] ? {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ConfigProviderForConfig } from '../../config';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { GenericFetch } from '../../fetch';
|
|
3
|
+
import { UserData } from './utils/embeddedAuthProvider';
|
|
4
|
+
import { ApiUser, AuthProvider } from '.';
|
|
4
5
|
type Config = {
|
|
5
6
|
accountsBase: string;
|
|
6
7
|
};
|
|
@@ -27,46 +28,13 @@ export interface Window {
|
|
|
27
28
|
removeEventListener: (event: 'message', callback: EventHandler) => void;
|
|
28
29
|
}
|
|
29
30
|
export type UpdatableUserFields = Partial<Pick<ApiUser, 'consent_preferences' | 'first_name' | 'last_name'>>;
|
|
30
|
-
export
|
|
31
|
-
/**
|
|
32
|
-
* gets the authentication token
|
|
33
|
-
*/
|
|
34
|
-
getAuthToken: () => Promise<string | null>;
|
|
35
|
-
/**
|
|
36
|
-
* adds auth parameters to the url. this is only safe to use when using javascript to navigate
|
|
37
|
-
* within the current window, eg `window.location = 'https://my.otherservice.com';` anchors
|
|
38
|
-
* should use getAuthorizedLinkUrl for their href.
|
|
39
|
-
*
|
|
40
|
-
* result unreliable unless `getUser` is resolved first.
|
|
41
|
-
*/
|
|
31
|
+
export type BrowserAuthProvider = AuthProvider & {
|
|
42
32
|
getAuthorizedUrl: (urlString: string) => string;
|
|
43
|
-
/**
|
|
44
|
-
* all link href-s must be rendered with auth tokens so that they work when opened in a new tab
|
|
45
|
-
*
|
|
46
|
-
* result unreliable unless `getUser` is resolved first.
|
|
47
|
-
*/
|
|
48
33
|
getAuthorizedLinkUrl: (urlString: string) => string;
|
|
49
|
-
/**
|
|
50
|
-
* gets an authorized url for an iframe src. sets params on the url and saves its
|
|
51
|
-
* origin to trust releasing user identity to it
|
|
52
|
-
*/
|
|
53
34
|
getAuthorizedEmbedUrl: (urlString: string, extraParams?: {
|
|
54
35
|
[key: string]: string;
|
|
55
36
|
}) => string;
|
|
56
|
-
|
|
57
|
-
* gets second argument for `fetch` that has authentication token or cookie
|
|
58
|
-
*/
|
|
59
|
-
getAuthorizedFetchConfig: () => Promise<FetchConfig>;
|
|
60
|
-
/**
|
|
61
|
-
* loads current user identity. does not reflect changes in identity after being called the first time.
|
|
62
|
-
*/
|
|
63
|
-
getUser: () => Promise<User | undefined>;
|
|
64
|
-
/**
|
|
65
|
-
* updates user settings, for example the cookie consent preferences
|
|
66
|
-
*/
|
|
67
|
-
updateUser: (updates: UpdatableUserFields) => Promise<{
|
|
68
|
-
user: ApiUser;
|
|
69
|
-
token: string | null;
|
|
70
|
-
}>;
|
|
37
|
+
updateUser: (updates: UpdatableUserFields) => Promise<UserData<ApiUser>>;
|
|
71
38
|
};
|
|
39
|
+
export declare const browserAuthProvider: <C extends string = "auth">({ window, configSpace }: Initializer<C>) => (configProvider: { [_key in C]: ConfigProviderForConfig<Config>; }) => BrowserAuthProvider;
|
|
72
40
|
export {};
|
|
@@ -142,6 +142,7 @@ export const browserAuthProvider = ({ window, configSpace }) => (configProvider)
|
|
|
142
142
|
* loads current user identity. does not reflect changes in identity after being called the first time.
|
|
143
143
|
*/
|
|
144
144
|
getUser,
|
|
145
|
+
loadUserData: getUser,
|
|
145
146
|
/**
|
|
146
147
|
* updates user settings, for example the cookie consent preferences
|
|
147
148
|
*/
|
|
@@ -43,6 +43,7 @@ export type AuthProvider = {
|
|
|
43
43
|
* gets second argument for `fetch` that has authentication token or cookie
|
|
44
44
|
*/
|
|
45
45
|
getAuthorizedFetchConfig: () => Promise<FetchConfig>;
|
|
46
|
+
loadUserData: () => Promise<ApiUser | undefined>;
|
|
46
47
|
};
|
|
47
48
|
export type CookieAuthProviderRequest = {
|
|
48
49
|
cookies?: string[];
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import cookie from 'cookie';
|
|
2
2
|
import { tuple } from '../../misc/helpers';
|
|
3
3
|
import { getHeader } from '../../routing/helpers';
|
|
4
|
-
export const stubAuthProvider = (user) =>
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
export const stubAuthProvider = (user) => {
|
|
5
|
+
const getUser = () => Promise.resolve(user);
|
|
6
|
+
return {
|
|
7
|
+
getAuthToken: () => Promise.resolve('authToken'),
|
|
8
|
+
getUser,
|
|
9
|
+
getAuthorizedFetchConfig: () => Promise.resolve(user ? { headers: { Authorization: user.uuid } } : {}),
|
|
10
|
+
// This is not technically correct, but most tests won't care
|
|
11
|
+
loadUserData: getUser
|
|
12
|
+
};
|
|
13
|
+
};
|
|
9
14
|
export const getAuthTokenOrCookie = (request, cookieName, queryKey = 'auth') => {
|
|
10
15
|
var _a, _b;
|
|
11
16
|
const authParam = request.queryStringParameters ? request.queryStringParameters[queryKey] : undefined;
|
|
@@ -29,15 +29,17 @@ export const subrequestAuthProvider = (initializer) => (configProvider) => {
|
|
|
29
29
|
}
|
|
30
30
|
return user;
|
|
31
31
|
};
|
|
32
|
+
const getUser = async () => {
|
|
33
|
+
if (!user) {
|
|
34
|
+
user = await loadUser();
|
|
35
|
+
}
|
|
36
|
+
return user;
|
|
37
|
+
};
|
|
32
38
|
return {
|
|
33
39
|
getAuthToken,
|
|
34
40
|
getAuthorizedFetchConfig,
|
|
35
|
-
getUser
|
|
36
|
-
|
|
37
|
-
user = await loadUser();
|
|
38
|
-
}
|
|
39
|
-
return user;
|
|
40
|
-
}
|
|
41
|
+
getUser,
|
|
42
|
+
loadUserData: getUser
|
|
41
43
|
};
|
|
42
44
|
};
|
|
43
45
|
};
|
|
@@ -13,18 +13,6 @@ export declare const isFolderValue: (thing: any) => thing is FolderValue;
|
|
|
13
13
|
export interface FileServerAdapter {
|
|
14
14
|
putFileContent: (source: FileValue, content: string) => Promise<FileValue>;
|
|
15
15
|
getSignedViewerUrl: (source: FileValue) => Promise<string>;
|
|
16
|
-
getPublicViewerUrl: (source: FileValue) => Promise<string>;
|
|
17
16
|
getFileContent: (source: FileValue) => Promise<Buffer>;
|
|
18
|
-
getSignedFileUploadConfig: () => Promise<{
|
|
19
|
-
url: string;
|
|
20
|
-
payload: {
|
|
21
|
-
[key: string]: string;
|
|
22
|
-
};
|
|
23
|
-
}>;
|
|
24
|
-
copyFileTo: (source: FileValue, destinationPath: string) => Promise<FileValue>;
|
|
25
|
-
copyFileToDirectory: (source: FileValue, destinationDirectory: string) => Promise<FileValue>;
|
|
26
|
-
isTemporaryUpload: (source: FileValue) => boolean;
|
|
27
|
-
getFileChecksum: (source: FileValue) => Promise<string>;
|
|
28
|
-
filesEqual: (sourceA: FileValue, sourceB: FileValue) => Promise<boolean>;
|
|
29
17
|
}
|
|
30
18
|
export declare const isFileOrFolder: (thing: any) => thing is FileValue | FolderValue;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
/* cspell:ignore originalname */
|
|
2
|
-
import crypto from 'crypto';
|
|
3
2
|
import fs from 'fs';
|
|
4
3
|
import https from 'https';
|
|
5
4
|
import path from 'path';
|
|
6
5
|
import cors from 'cors';
|
|
7
6
|
import express from 'express';
|
|
8
7
|
import multer from 'multer';
|
|
9
|
-
import { v4 as uuid } from 'uuid';
|
|
10
8
|
import { assertString } from '../../assertions';
|
|
11
9
|
import { resolveConfigValue } from '../../config';
|
|
12
10
|
import { ifDefined } from '../../guards';
|
|
13
|
-
import {
|
|
11
|
+
import { once } from '../../misc/helpers';
|
|
14
12
|
/* istanbul ignore next */
|
|
15
|
-
const startServer =
|
|
13
|
+
const startServer = once((port, uploadDir) => {
|
|
16
14
|
// TODO - re-evaluate the `preservePath` behavior to match whatever s3 does
|
|
17
15
|
const upload = multer({ dest: uploadDir, preservePath: true });
|
|
18
16
|
const fileServerApp = express();
|
|
@@ -57,9 +55,6 @@ export const localFileServer = (initializer) => (configProvider) => {
|
|
|
57
55
|
const getSignedViewerUrl = async (source) => {
|
|
58
56
|
return `https://${await host}:${await port}/${source.path}`;
|
|
59
57
|
};
|
|
60
|
-
const getPublicViewerUrl = async (source) => {
|
|
61
|
-
return `https://${await host}:${await port}/${source.path}`;
|
|
62
|
-
};
|
|
63
58
|
const getFileContent = async (source) => {
|
|
64
59
|
const filePath = path.join(await fileDir, source.path);
|
|
65
60
|
return fs.promises.readFile(filePath);
|
|
@@ -71,55 +66,9 @@ export const localFileServer = (initializer) => (configProvider) => {
|
|
|
71
66
|
await fs.promises.writeFile(filePath, content);
|
|
72
67
|
return source;
|
|
73
68
|
};
|
|
74
|
-
const getSignedFileUploadConfig = async () => {
|
|
75
|
-
const prefix = 'uploads/' + uuid();
|
|
76
|
-
return {
|
|
77
|
-
url: `https://${await host}:${await port}/`,
|
|
78
|
-
payload: {
|
|
79
|
-
key: prefix + '/${filename}',
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
};
|
|
83
|
-
const copyFileTo = async (source, destinationPath) => {
|
|
84
|
-
const sourcePath = path.join(await fileDir, source.path);
|
|
85
|
-
const destPath = path.join(await fileDir, destinationPath);
|
|
86
|
-
const destDirectory = path.dirname(destPath);
|
|
87
|
-
await fs.promises.mkdir(destDirectory, { recursive: true });
|
|
88
|
-
await fs.promises.copyFile(sourcePath, destPath);
|
|
89
|
-
return {
|
|
90
|
-
...source,
|
|
91
|
-
path: destinationPath
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
const copyFileToDirectory = async (source, destination) => {
|
|
95
|
-
const destinationPath = path.join(destination, source.label);
|
|
96
|
-
return copyFileTo(source, destinationPath);
|
|
97
|
-
};
|
|
98
|
-
const isTemporaryUpload = (source) => {
|
|
99
|
-
return source.path.indexOf('uploads/') === 0;
|
|
100
|
-
};
|
|
101
|
-
const getFileChecksum = async (source) => {
|
|
102
|
-
const filePath = path.join(await fileDir, source.path);
|
|
103
|
-
const fileContent = await fs.promises.readFile(filePath);
|
|
104
|
-
return crypto.createHash('md5').update(fileContent).digest('hex');
|
|
105
|
-
};
|
|
106
|
-
const filesEqual = async (sourceA, sourceB) => {
|
|
107
|
-
const [aSum, bSum] = await Promise.all([
|
|
108
|
-
getFileChecksum(sourceA),
|
|
109
|
-
getFileChecksum(sourceB)
|
|
110
|
-
]);
|
|
111
|
-
return aSum === bSum;
|
|
112
|
-
};
|
|
113
69
|
return {
|
|
114
70
|
getSignedViewerUrl,
|
|
115
|
-
getPublicViewerUrl,
|
|
116
71
|
getFileContent,
|
|
117
72
|
putFileContent,
|
|
118
|
-
getSignedFileUploadConfig,
|
|
119
|
-
copyFileTo,
|
|
120
|
-
copyFileToDirectory,
|
|
121
|
-
isTemporaryUpload,
|
|
122
|
-
getFileChecksum,
|
|
123
|
-
filesEqual,
|
|
124
73
|
};
|
|
125
74
|
};
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
/* cspell:ignore presigner */
|
|
2
|
-
import
|
|
3
|
-
import { CopyObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
4
|
-
import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
|
|
2
|
+
import { GetObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
5
3
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
6
|
-
import { v4 as uuid } from 'uuid';
|
|
7
4
|
import { once } from '../..';
|
|
8
5
|
import { assertDefined } from '../../assertions';
|
|
9
6
|
import { resolveConfigValue } from '../../config';
|
|
@@ -12,9 +9,6 @@ export const s3FileServer = (initializer) => (configProvider) => {
|
|
|
12
9
|
const config = configProvider[ifDefined(initializer.configSpace, 'deployed')];
|
|
13
10
|
const bucketName = once(() => resolveConfigValue(config.bucketName));
|
|
14
11
|
const bucketRegion = once(() => resolveConfigValue(config.bucketRegion));
|
|
15
|
-
const publicViewerDomain = once(() => 'publicViewerDomain' in config && config.publicViewerDomain
|
|
16
|
-
? resolveConfigValue(config.publicViewerDomain)
|
|
17
|
-
: undefined);
|
|
18
12
|
const s3Service = once(async () => {
|
|
19
13
|
var _a, _b;
|
|
20
14
|
const args = { apiVersion: '2012-08-10', region: await bucketRegion() };
|
|
@@ -30,10 +24,6 @@ export const s3FileServer = (initializer) => (configProvider) => {
|
|
|
30
24
|
expiresIn: 3600, // 1 hour
|
|
31
25
|
});
|
|
32
26
|
};
|
|
33
|
-
const getPublicViewerUrl = async (source) => {
|
|
34
|
-
const host = assertDefined(await publicViewerDomain(), new Error(`Tried to get public viewer URL for ${source.path} but no publicViewerDomain configured`));
|
|
35
|
-
return `https://${host}/${source.path}`;
|
|
36
|
-
};
|
|
37
27
|
const getFileContent = async (source) => {
|
|
38
28
|
const bucket = await bucketName();
|
|
39
29
|
const command = new GetObjectCommand({ Bucket: bucket, Key: source.path });
|
|
@@ -51,74 +41,9 @@ export const s3FileServer = (initializer) => (configProvider) => {
|
|
|
51
41
|
await (await s3Service()).send(command);
|
|
52
42
|
return source;
|
|
53
43
|
};
|
|
54
|
-
/*
|
|
55
|
-
* https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_s3_presigned_post.html
|
|
56
|
-
* https://docs.aws.amazon.com/AmazonS3/latest/userguide/HTTPPOSTExamples.html
|
|
57
|
-
* https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
|
|
58
|
-
*/
|
|
59
|
-
const getSignedFileUploadConfig = async () => {
|
|
60
|
-
const prefix = 'uploads/' + uuid();
|
|
61
|
-
const bucket = (await bucketName());
|
|
62
|
-
const Conditions = [
|
|
63
|
-
{ acl: 'private' },
|
|
64
|
-
{ bucket },
|
|
65
|
-
['starts-with', '$key', prefix]
|
|
66
|
-
];
|
|
67
|
-
const defaultFields = {
|
|
68
|
-
acl: 'private',
|
|
69
|
-
};
|
|
70
|
-
const { url, fields } = await createPresignedPost(await s3Service(), {
|
|
71
|
-
Bucket: bucket,
|
|
72
|
-
Key: prefix + '/${filename}',
|
|
73
|
-
Conditions,
|
|
74
|
-
Fields: defaultFields,
|
|
75
|
-
Expires: 3600, // 1 hour
|
|
76
|
-
});
|
|
77
|
-
return {
|
|
78
|
-
url, payload: fields
|
|
79
|
-
};
|
|
80
|
-
};
|
|
81
|
-
const copyFileTo = async (source, destinationPath) => {
|
|
82
|
-
const bucket = (await bucketName());
|
|
83
|
-
const destinationPathWithoutLeadingSlash = destinationPath.replace(/^\//, '');
|
|
84
|
-
const command = new CopyObjectCommand({
|
|
85
|
-
Bucket: bucket,
|
|
86
|
-
Key: destinationPathWithoutLeadingSlash,
|
|
87
|
-
CopySource: path.join(bucket, source.path),
|
|
88
|
-
});
|
|
89
|
-
await (await s3Service()).send(command);
|
|
90
|
-
return {
|
|
91
|
-
...source,
|
|
92
|
-
path: destinationPathWithoutLeadingSlash
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
const copyFileToDirectory = async (source, destination) => {
|
|
96
|
-
const destinationPath = path.join(destination, source.label);
|
|
97
|
-
return copyFileTo(source, destinationPath);
|
|
98
|
-
};
|
|
99
|
-
const isTemporaryUpload = (source) => {
|
|
100
|
-
return source.path.indexOf('uploads/') === 0;
|
|
101
|
-
};
|
|
102
|
-
const getFileChecksum = async (source) => {
|
|
103
|
-
const bucket = (await bucketName());
|
|
104
|
-
const command = new HeadObjectCommand({ Bucket: bucket, Key: source.path });
|
|
105
|
-
const response = await (await s3Service()).send(command);
|
|
106
|
-
return assertDefined(response.ETag);
|
|
107
|
-
};
|
|
108
|
-
const filesEqual = async (sourceA, sourceB) => {
|
|
109
|
-
const [aSum, bSum] = await Promise.all([getFileChecksum(sourceA), getFileChecksum(sourceB)]);
|
|
110
|
-
return aSum === bSum;
|
|
111
|
-
};
|
|
112
44
|
return {
|
|
113
45
|
getFileContent,
|
|
114
46
|
putFileContent,
|
|
115
47
|
getSignedViewerUrl,
|
|
116
|
-
getPublicViewerUrl,
|
|
117
|
-
getSignedFileUploadConfig,
|
|
118
|
-
copyFileTo,
|
|
119
|
-
copyFileToDirectory,
|
|
120
|
-
isTemporaryUpload,
|
|
121
|
-
getFileChecksum,
|
|
122
|
-
filesEqual,
|
|
123
48
|
};
|
|
124
49
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { JWK } from 'node-jose';
|
|
2
2
|
import { ConfigProviderForConfig } from '../../config';
|
|
3
|
-
import type {
|
|
3
|
+
import type { JsonCompatibleStruct } from '../../routing';
|
|
4
4
|
type Config = {
|
|
5
5
|
alg: string;
|
|
6
6
|
expiresIn: string;
|
|
@@ -17,7 +17,7 @@ export declare const createLaunchSigner: <C extends string = "launch">({ configS
|
|
|
17
17
|
jwks: () => Promise<{
|
|
18
18
|
keys: JWK.RawKey[];
|
|
19
19
|
}>;
|
|
20
|
-
sign: (data:
|
|
20
|
+
sign: (data: JsonCompatibleStruct, subject: string, maxExp?: number | null) => Promise<string>;
|
|
21
21
|
};
|
|
22
22
|
export type LaunchSigner = ReturnType<ReturnType<typeof createLaunchSigner>>;
|
|
23
23
|
export {};
|
|
@@ -26,6 +26,10 @@ export const openSearchService = (initializer = {}) => (configProvider) => {
|
|
|
26
26
|
maxRetries: 4, // default is 3
|
|
27
27
|
requestTimeout: 5000, // default is 30000
|
|
28
28
|
pingTimeout: 2000, // default is 30000
|
|
29
|
+
sniffOnConnectionFault: true,
|
|
30
|
+
sniffOnStart: true,
|
|
31
|
+
resurrectStrategy: 'ping',
|
|
32
|
+
agent: { keepAlive: false },
|
|
29
33
|
node: await resolveConfigValue(config.node),
|
|
30
34
|
}));
|
|
31
35
|
return (indexConfig) => {
|
|
@@ -61,9 +65,6 @@ export const openSearchService = (initializer = {}) => (configProvider) => {
|
|
|
61
65
|
body: params.body,
|
|
62
66
|
id: params.id,
|
|
63
67
|
refresh: true
|
|
64
|
-
}, {
|
|
65
|
-
requestTimeout: 10000,
|
|
66
|
-
maxRetries: 1,
|
|
67
68
|
});
|
|
68
69
|
};
|
|
69
70
|
const bulkIndex = async (items) => {
|
|
@@ -75,9 +76,6 @@ export const openSearchService = (initializer = {}) => (configProvider) => {
|
|
|
75
76
|
item.body
|
|
76
77
|
]),
|
|
77
78
|
refresh: true
|
|
78
|
-
}, {
|
|
79
|
-
requestTimeout: 10000,
|
|
80
|
-
maxRetries: 1,
|
|
81
79
|
});
|
|
82
80
|
};
|
|
83
81
|
const search = async (options) => {
|