You're Invited: Meet the Socket team at BSidesSF and RSAC - April 27 - May 1.RSVP
Socket
Sign inDemoInstall
Socket

@lokalise/file-storage-service-sdk

Package Overview
Dependencies
Maintainers
11
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lokalise/file-storage-service-sdk - npm Package Compare versions

Comparing version

to
4.1.0

dist/lib/sdk/utils/restUtils.d.ts

5

dist/lib/sdk/fileStorageClient.d.ts

@@ -0,4 +1,5 @@

/// <reference types="node" />
import type { Either } from '@lokalise/node-core/dist/src/errors/either';
import type { FileStorageClientConfig } from './configModels';
import type { FileData, FileMetadata, FileUploadData, HttpRequestContext } from './model';
import type { DownloadError, FileData, FileMetadata, FileUploadData, HttpRequestContext } from './model';
import type { ContentHeaders, ErrorResponse, UseCaseEnum } from './schema/storageSchemas';

@@ -13,2 +14,4 @@ export declare class FileStorageClient {

getFileDownloadUrl(ownerId: string, fileId: string, useCase: UseCaseEnum, requestContext: HttpRequestContext): Promise<Either<ErrorResponse, string>>;
downloadFile(projectId: string, fileId: string, useCase: UseCaseEnum, requestContext: HttpRequestContext): Promise<Either<DownloadError, Blob>>;
private isTemporaryErrorResponseCode;
deleteFile(ownerId: string, fileId: string, requestContext: HttpRequestContext): Promise<Either<ErrorResponse, boolean>>;

@@ -15,0 +18,0 @@ private getOwnerEndpoint;

@@ -6,2 +6,3 @@ "use strict";

const configModels_1 = require("./configModels");
const restUtils_1 = require("./utils/restUtils");
class FileStorageClient {

@@ -90,2 +91,30 @@ retryConfig;

}
async downloadFile(projectId, fileId, useCase, requestContext) {
const downloadUrlResult = await this.getFileDownloadUrl(projectId, fileId, useCase, requestContext);
if (downloadUrlResult.error) {
if (downloadUrlResult.error.statusCode === 404) {
return { error: 'FILE_NOT_FOUND' };
}
if (this.isTemporaryErrorResponseCode(downloadUrlResult.error.statusCode)) {
return { error: 'TEMPORARY_ERROR' };
}
return { error: 'UNKNOWN_ERROR' };
}
const url = new URL(downloadUrlResult.result);
const result = await (0, node_core_1.sendGet)((0, node_core_1.buildClient)(url.origin), url.pathname, {
query: (0, restUtils_1.getUrlQuery)(url),
retryConfig: {
...this.retryConfig,
blobBody: true,
},
throwOnError: false,
});
if (result.error) {
return { error: 'UNKNOWN_ERROR' };
}
return { result: result.result.body };
}
isTemporaryErrorResponseCode(statusCode) {
return (statusCode >= 500 && statusCode < 600) || statusCode === 429;
}
async deleteFile(ownerId, fileId, requestContext) {

@@ -92,0 +121,0 @@ const endpoint = this.getOwnerEndpoint(ownerId, fileId);

73

dist/lib/sdk/fileStorageClient.spec.js

@@ -8,2 +8,3 @@ "use strict";

const mockServer = (0, mockttp_1.getLocal)();
const mockStorageServer = (0, mockttp_1.getLocal)();
describe('fileStorageClient', () => {

@@ -19,5 +20,7 @@ let fileStorageClient;

await mockServer.start(8085);
await mockStorageServer.start(8086);
});
afterEach(async () => {
await mockServer.stop();
await mockStorageServer.stop();
});

@@ -51,4 +54,2 @@ it('The download URL is returned on request', async () => {

it('Attempts to upload a file correctly', async () => {
const mockStorageServer = (0, mockttp_1.getLocal)();
await mockStorageServer.start(8086);
const uploadHost = 'http://localhost:8086';

@@ -69,7 +70,4 @@ const uploadPath = '/upload-files-here';

await expect(fileStorageClient.uploadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, 'import', testFs_1.FS_TEST_DATA.FILE_DESCRIPTION, {}, testFs_1.FS_TEST_DATA.REQUEST_CONTEXT)).resolves.toEqual({ result: fileId });
await mockStorageServer.stop();
});
it('Attempts to upload a file correctly with query params', async () => {
const mockStorageServer = (0, mockttp_1.getLocal)();
await mockStorageServer.start(8086);
const uploadHost = 'http://localhost:8086';

@@ -91,3 +89,2 @@ const uploadPath = '/upload-files-here';

await expect(fileStorageClient.uploadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, 'import', testFs_1.FS_TEST_DATA.FILE_DESCRIPTION, {}, testFs_1.FS_TEST_DATA.REQUEST_CONTEXT)).resolves.toEqual({ result: fileId });
await mockStorageServer.stop();
});

@@ -107,4 +104,2 @@ it('returns error on file upload', async () => {

it('returns error on uploading file by generated upload url', async () => {
const mockStorageServer = (0, mockttp_1.getLocal)();
await mockStorageServer.start(8086);
const uploadHost = 'http://localhost:8086';

@@ -135,3 +130,2 @@ const uploadPath = '/upload-files-here';

await expect(fileStorageClient.uploadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, 'import', testFs_1.FS_TEST_DATA.FILE_DESCRIPTION, {}, testFs_1.FS_TEST_DATA.REQUEST_CONTEXT)).resolves.toEqual({ error: testFs_1.FS_TEST_DATA.ERROR_REPLY });
await mockStorageServer.stop();
});

@@ -185,3 +179,64 @@ it('get file metadata successful', async () => {

});
it('downloads file from FSS', async () => {
const downloadUrl = 'http://localhost:8086/path-to-file';
const reply = {
data: {
downloadUrl,
filename: 'someFile.zip',
mimeType: 'application/zip',
fileSize: 22,
},
};
await mockServer.forGet(testStorageClient_1.downloadInterceptData.path).thenReply(200, JSON.stringify(reply), {
'content-type': 'application/json',
});
await mockStorageServer.forGet(downloadUrl).thenReply(200, 'file-contents');
const contentsResult = await fileStorageClient.downloadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, testFs_1.FS_TEST_DATA.FILE_ID, 'import', testFs_1.FS_TEST_DATA.REQUEST_CONTEXT);
const contentsString = await contentsResult.result?.text();
expect(contentsString).toBe('file-contents');
});
it('file on FSS not found', async () => {
await mockServer
.forGet(testStorageClient_1.downloadInterceptData.path)
.thenReply(404, JSON.stringify({ statusCode: 404, message: 'Not found' }), {
'content-type': 'application/json',
});
const result = await fileStorageClient.downloadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, testFs_1.FS_TEST_DATA.FILE_ID, 'import', testFs_1.FS_TEST_DATA.REQUEST_CONTEXT);
expect(result.error).toBe('FILE_NOT_FOUND');
});
it('unknown error on downloadUrl call', async () => {
await mockServer.forGet(testStorageClient_1.downloadInterceptData.path).thenReply(500, JSON.stringify({}), {
'content-type': 'application/json',
});
const result = await fileStorageClient.downloadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, testFs_1.FS_TEST_DATA.FILE_ID, 'import', testFs_1.FS_TEST_DATA.REQUEST_CONTEXT);
expect(result.error).toBe('UNKNOWN_ERROR');
});
it('unknown error on file download', async () => {
const downloadUrl = 'http://localhost:8086/path-to-file';
const reply = {
data: {
downloadUrl,
filename: 'someFile.zip',
mimeType: 'application/zip',
fileSize: 22,
},
};
await mockServer.forGet(testStorageClient_1.downloadInterceptData.path).thenReply(200, JSON.stringify(reply), {
'content-type': 'application/json',
});
await mockStorageServer.forGet(downloadUrl).thenReply(404, 'Not found');
const result = await fileStorageClient.downloadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, testFs_1.FS_TEST_DATA.FILE_ID, 'import', testFs_1.FS_TEST_DATA.REQUEST_CONTEXT);
expect(result.error).toBe('UNKNOWN_ERROR');
});
it('temporary error on download', async () => {
await mockServer.forGet(testStorageClient_1.downloadInterceptData.path).thenReply(503, JSON.stringify({
statusCode: 503,
message: 'Something went wrong',
}), {
'content-type': 'application/json',
});
const result = await fileStorageClient.downloadFile(testFs_1.FS_TEST_DATA.PROJECT_ID, testFs_1.FS_TEST_DATA.FILE_ID, 'import', testFs_1.FS_TEST_DATA.REQUEST_CONTEXT);
expect(result.error).toBe('TEMPORARY_ERROR');
});
});
//# sourceMappingURL=fileStorageClient.spec.js.map

@@ -5,2 +5,3 @@ /// <reference types="node" />

import type { StatusEnum } from './schema/storageSchemas';
export type DownloadError = 'FILE_NOT_FOUND' | 'TEMPORARY_ERROR' | 'UNKNOWN_ERROR';
export interface HttpRequestContext {

@@ -7,0 +8,0 @@ reqId: string;

{
"name": "@lokalise/file-storage-service-sdk",
"version": "4.0.1",
"version": "4.1.0",
"description": "SDK for file-storage-service",

@@ -49,4 +49,4 @@ "author": {

"@types/node": "^18.13.0",
"@typescript-eslint/eslint-plugin": "^5.52.0",
"@typescript-eslint/parser": "^5.52.0",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"auto-changelog": "^2.4.0",

@@ -53,0 +53,0 @@ "eslint": "^8.34.0",

@@ -14,2 +14,3 @@ # file-storage-service-sdk

#### Authorization
Authorization will require a valid `jwtToken`.

@@ -22,4 +23,5 @@

#### Error handling
All function returning monad `Either<L, R>` where `L` - Left is a potential error and
`R` - Right is a potential result, one of these will always present in response.
Consumer of the api is responsible to handle result/error.
All function returning monad `Either<L, R>` where `L` - Left is a potential error and
`R` - Right is a potential result, one of these will always present in response.
Consumer of the api is responsible to handle result/error.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet