[Files] Update the public client with missing routes (#138798)

* updated types for public file client

* remove "this" from file client

* implement missing endpoints in the file client

* added test
This commit is contained in:
Jean-Louis Leysens 2022-08-16 09:45:52 +02:00 committed by GitHub
parent 416123a980
commit 77221101ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 207 additions and 24 deletions

View file

@ -0,0 +1,56 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { apiRoutes } from './files_client';
describe('apiRoutes', () => {
test('generates expected paths', () => {
expect(apiRoutes.getCreateFileRoute('test')).toMatchInlineSnapshot(`"/api/files/files/test"`);
expect(apiRoutes.getUploadRoute('test', '123')).toMatchInlineSnapshot(
`"/api/files/files/test/123/blob"`
);
expect(apiRoutes.getDownloadRoute('test', '123', 'my-file.png')).toMatchInlineSnapshot(
`"/api/files/files/test/123/blob/my-file.png"`
);
expect(apiRoutes.getUpdateRoute('test', '123')).toMatchInlineSnapshot(
`"/api/files/files/test/123"`
);
expect(apiRoutes.getDeleteRoute('test', '123')).toMatchInlineSnapshot(
`"/api/files/files/test/123"`
);
expect(apiRoutes.getListRoute('test', 1, 1)).toMatchInlineSnapshot(
`"/api/files/files/test/list?page=1&perPage=1"`
);
expect(apiRoutes.getByIdRoute('test', '123')).toMatchInlineSnapshot(
`"/api/files/files/test/123"`
);
expect(apiRoutes.getShareRoute('test', '123')).toMatchInlineSnapshot(
`"/api/files/shares/test/123"`
);
expect(apiRoutes.getListSharesRoute('test', 1, 1)).toMatchInlineSnapshot(
`"/api/files/shares/test?page=1&perPage=1"`
);
expect(apiRoutes.getPublicDownloadRoute('test', 'my-file.pdf')).toMatchInlineSnapshot(
`"/api/files/public/blob/my-file.pdf?token=test"`
);
expect(apiRoutes.getFindRoute(1, 1)).toMatchInlineSnapshot(
`"/api/files/find?page=1&perPage=1"`
);
expect(apiRoutes.getMetricsRoute()).toMatchInlineSnapshot(`"/api/files/metrics"`);
});
});

View file

@ -5,23 +5,64 @@
* 2.0.
*/
import { pipe } from 'fp-ts/lib/function';
import * as qs from 'query-string';
import type { HttpStart } from '@kbn/core/public';
import type { FilesClient } from '../types';
import { FILES_API_BASE_PATH } from '../../common/api_routes';
import {
API_BASE_PATH,
FILES_API_BASE_PATH,
FILES_PUBLIC_API_BASE_PATH,
FILES_SHARE_API_BASE_PATH,
} from '../../common/api_routes';
const apiRoutes = {
const addQueryParams =
(queryParams: object) =>
(path: string): string => {
const stringified = qs.stringify(queryParams);
return `${path}${stringified ? `?${stringified}` : ''}`;
};
/**
* @internal
*/
export const apiRoutes = {
/**
* Scoped to file kind
*/
getCreateFileRoute: (fileKind: string) => `${FILES_API_BASE_PATH}/${fileKind}`,
getUploadRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}/blob`,
getDownloadRoute: (fileKind: string, id: string, fileName?: string) =>
`${FILES_API_BASE_PATH}/${fileKind}/${id}/blob/${fileName ? fileName : ''}`,
`${FILES_API_BASE_PATH}/${fileKind}/${id}/blob${fileName ? '/' + fileName : ''}`,
getUpdateRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
getDeleteRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
getListRoute: (fileKind: string, page?: number, perPage?: number) => {
const qParams = qs.stringify({ page, perPage });
return `${FILES_API_BASE_PATH}/${fileKind}/list${qParams ? `?${qParams}` : ''}`;
return pipe(`${FILES_API_BASE_PATH}/${fileKind}/list`, addQueryParams({ page, perPage }));
},
getByIdRoute: (fileKind: string, id: string) => `${FILES_API_BASE_PATH}/${fileKind}/${id}`,
/**
* Scope to file shares and file kind
*/
getShareRoute: (fileKind: string, id: string) => `${FILES_SHARE_API_BASE_PATH}/${fileKind}/${id}`,
getListSharesRoute: (fileKind: string, page?: number, perPage?: number, forFileId?: string) =>
pipe(`${FILES_SHARE_API_BASE_PATH}/${fileKind}`, addQueryParams({ page, perPage, forFileId })),
/**
* Public routes
*/
getPublicDownloadRoute: (token: string, fileName?: string) =>
pipe(
`${FILES_PUBLIC_API_BASE_PATH}/blob${fileName ? '/' + fileName : ''}`,
addQueryParams({ token })
),
/**
* Top-level routes
*/
getFindRoute: (page?: number, perPage?: number) =>
pipe(`${API_BASE_PATH}/find`, addQueryParams({ page, perPage })),
getMetricsRoute: () => `${API_BASE_PATH}/metrics`,
};
interface Args {
@ -29,40 +70,72 @@ interface Args {
http: HttpStart;
}
const commonBodyHeaders = {
headers: {
'content-type': 'application/json',
},
};
export const createFilesClient = ({ http, fileKind }: Args): FilesClient => {
return {
create(args) {
create: (args) => {
return http.post(apiRoutes.getCreateFileRoute(fileKind), {
headers: {
'content-type': 'application/json',
},
headers: commonBodyHeaders,
body: JSON.stringify(args),
});
},
delete(args) {
delete: (args) => {
return http.delete(apiRoutes.getDeleteRoute(fileKind, args.id));
},
download(args) {
download: (args) => {
return http.get(apiRoutes.getDownloadRoute(fileKind, args.id, args.fileName));
},
getById(args) {
getById: (args) => {
return http.get(apiRoutes.getByIdRoute(fileKind, args.id));
},
list(args) {
return http.get(apiRoutes.getListRoute(fileKind, args.page, args.perPage));
list: ({ page, perPage }) => {
return http.get(apiRoutes.getListRoute(fileKind, page, perPage));
},
update({ id, ...body }) {
update: ({ id, ...body }) => {
return http.patch(apiRoutes.getUpdateRoute(fileKind, id), {
headers: {
'content-type': 'application/json',
},
headers: commonBodyHeaders,
body: JSON.stringify(body),
});
},
upload(args) {
upload: (args) => {
return http.put(apiRoutes.getUploadRoute(fileKind, args.id), {
headers: {
'content-type': 'application/octet-stream',
},
body: args.body,
});
},
share: ({ fileId, name, validUntil }) => {
return http.post(apiRoutes.getShareRoute(fileKind, fileId), {
headers: commonBodyHeaders,
body: JSON.stringify({ name, validUntil }),
});
},
unshare: ({ id }) => {
return http.delete(apiRoutes.getShareRoute(fileKind, id));
},
getShare: ({ id }) => {
return http.get(apiRoutes.getShareRoute(fileKind, id));
},
listShares: ({ forFileId, page, perPage }) => {
return http.get(apiRoutes.getListSharesRoute(fileKind, page, perPage, forFileId));
},
find: ({ page, perPage, ...filterArgs }) => {
return http.post(apiRoutes.getFindRoute(page, perPage), {
headers: commonBodyHeaders,
body: JSON.stringify(filterArgs),
});
},
getMetrics: () => {
return http.get(apiRoutes.getMetricsRoute());
},
publicDownload: ({ token, fileName }) => {
return http.get(apiRoutes.getPublicDownloadRoute(token, fileName));
},
};
};

View file

@ -6,14 +6,21 @@
*/
import type {
HttpApiInterfaceEntryDefinition,
CreateFileKindHttpEndpoint,
DeleteFileKindHttpEndpoint,
DownloadFileKindHttpEndpoint,
GetByIdFileKindHttpEndpoint,
FindFilesHttpEndpoint,
FileShareHttpEndpoint,
FileUnshareHttpEndpoint,
FileGetShareHttpEndpoint,
FilesMetricsHttpEndpoint,
ListFileKindHttpEndpoint,
CreateFileKindHttpEndpoint,
FileListSharesHttpEndpoint,
UpdateFileKindHttpEndpoint,
UploadFileKindHttpEndpoint,
DeleteFileKindHttpEndpoint,
GetByIdFileKindHttpEndpoint,
DownloadFileKindHttpEndpoint,
FilePublicDownloadHttpEndpoint,
HttpApiInterfaceEntryDefinition,
} from '../common/api_routes';
/**
@ -51,6 +58,12 @@ export interface FilesClient {
* @param args - list files args
*/
list: ClientMethodFrom<ListFileKindHttpEndpoint>;
/**
* Find a set of files given some filters.
*
* @param args - File filters
*/
find: ClientMethodFrom<FindFilesHttpEndpoint>;
/**
* Update a set of of metadata values of the file object.
*
@ -69,6 +82,47 @@ export interface FilesClient {
* @param args - download file args
*/
download: ClientMethodFrom<DownloadFileKindHttpEndpoint>;
/**
* Share a file by creating a new file share instance.
*
* @note This returns the secret token that can be used
* to access a file via the public download enpoint.
*
* @param args - File share arguments
*/
share: ClientMethodFrom<FileShareHttpEndpoint>;
/**
* Delete a file share instance.
*
* @param args - File unshare arguments
*/
unshare: ClientMethodFrom<FileUnshareHttpEndpoint>;
/**
* Get a file share instance.
*
* @param args - Get file share arguments
*/
getShare: ClientMethodFrom<FileGetShareHttpEndpoint>;
/**
* List all file shares. Optionally scoping to a specific
* file.
*
* @param args - Get file share arguments
*/
listShares: ClientMethodFrom<FileListSharesHttpEndpoint>;
/**
* Get metrics of file system, like storage usage.
*
* @param args - Get metrics arguments
*/
getMetrics: ClientMethodFrom<FilesMetricsHttpEndpoint>;
/**
* Download a file, bypassing regular security by way of a
* secret share token.
*
* @param args - Get public download arguments.
*/
publicDownload: ClientMethodFrom<FilePublicDownloadHttpEndpoint>;
}
/**