@cirrobio/sdk 0.4.3 → 0.9.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.
Files changed (118) hide show
  1. package/README.md +7 -0
  2. package/dist/index.esm.js +759 -0
  3. package/dist/index.esm.js.map +1 -0
  4. package/dist/index.js +815 -19
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/api/config.d.ts +6 -0
  7. package/dist/{api → types/api}/error-handler.d.ts +0 -4
  8. package/dist/types/api/error.d.ts +4 -0
  9. package/dist/types/api.d.ts +2 -0
  10. package/dist/types/auth/authentication-provider.d.ts +24 -0
  11. package/dist/types/auth/current-user.d.ts +16 -0
  12. package/dist/types/auth/static-token-auth.d.ts +11 -0
  13. package/dist/types/auth.d.ts +3 -0
  14. package/dist/types/data/data.service.d.ts +44 -0
  15. package/dist/types/data.d.ts +1 -0
  16. package/dist/{file → types/file}/calculate-size.d.ts +1 -1
  17. package/dist/{file → types/file}/file.service.d.ts +9 -6
  18. package/dist/types/file/manifest-parser.d.ts +14 -0
  19. package/dist/types/file/models/assets.d.ts +8 -0
  20. package/dist/{file → types/file/models}/file-object.model.d.ts +1 -1
  21. package/dist/types/file/models/file.d.ts +14 -0
  22. package/dist/types/file/models/folder.d.ts +13 -0
  23. package/dist/{file → types/file}/shared.d.ts +1 -1
  24. package/dist/types/file/util/get-parent.fn.d.ts +4 -0
  25. package/dist/{file.d.ts → types/file.d.ts} +5 -2
  26. package/dist/{index.d.ts → types/index.d.ts} +2 -0
  27. package/dist/types/util/get-resource-name.d.ts +1 -0
  28. package/dist/{util.d.ts → types/util.d.ts} +1 -0
  29. package/package.json +20 -15
  30. package/dist/api/error-handler.js +0 -37
  31. package/dist/api.d.ts +0 -1
  32. package/dist/api.js +0 -6
  33. package/dist/file/__test__/s3-utils.test.d.ts +0 -1
  34. package/dist/file/__test__/s3-utils.test.js +0 -16
  35. package/dist/file/actions/delete.fn.js +0 -15
  36. package/dist/file/actions/sign-url.fn.js +0 -27
  37. package/dist/file/actions/upload.fn.js +0 -23
  38. package/dist/file/calculate-size.js +0 -16
  39. package/dist/file/extensions.fn.js +0 -77
  40. package/dist/file/file-object.model.js +0 -8
  41. package/dist/file/file.service.js +0 -81
  42. package/dist/file/project-access-context.js +0 -24
  43. package/dist/file/shared.js +0 -11
  44. package/dist/file/util/credentials-mutex.so.js +0 -32
  45. package/dist/file/util/s3-client.js +0 -19
  46. package/dist/file/util/s3-utils.js +0 -17
  47. package/dist/file.js +0 -43
  48. package/dist/formatters/bytes-to-string.js +0 -30
  49. package/dist/formatters/json-pretty-print.js +0 -12
  50. package/dist/formatters/normalize-date.js +0 -16
  51. package/dist/formatters/normalize-string.js +0 -13
  52. package/dist/formatters/slash.js +0 -19
  53. package/dist/formatters/to-date-format.js +0 -16
  54. package/dist/formatters/to-friendly-name.js +0 -17
  55. package/dist/formatters/to-money.js +0 -16
  56. package/dist/formatters/to-pascal-case.js +0 -12
  57. package/dist/formatters/to-title-case.js +0 -14
  58. package/dist/formatters.js +0 -24
  59. package/dist/util/download.js +0 -22
  60. package/dist/util/extract-from-object.js +0 -15
  61. package/dist/util/handle-promise.js +0 -11
  62. package/dist/util.js +0 -10
  63. package/src/api/error-handler.ts +0 -36
  64. package/src/api.ts +0 -1
  65. package/src/file/__test__/s3-utils.test.ts +0 -17
  66. package/src/file/actions/delete.fn.ts +0 -18
  67. package/src/file/actions/sign-url.fn.ts +0 -36
  68. package/src/file/actions/upload.fn.ts +0 -30
  69. package/src/file/calculate-size.ts +0 -14
  70. package/src/file/extensions.fn.ts +0 -88
  71. package/src/file/file-object.model.ts +0 -57
  72. package/src/file/file.service.ts +0 -86
  73. package/src/file/project-access-context.ts +0 -26
  74. package/src/file/shared.ts +0 -7
  75. package/src/file/util/credentials-mutex.so.ts +0 -33
  76. package/src/file/util/s3-client.ts +0 -17
  77. package/src/file/util/s3-utils.ts +0 -14
  78. package/src/file.ts +0 -13
  79. package/src/formatters/__tests__/formatters.spec.ts +0 -65
  80. package/src/formatters/bytes-to-string.ts +0 -32
  81. package/src/formatters/json-pretty-print.ts +0 -8
  82. package/src/formatters/normalize-date.ts +0 -10
  83. package/src/formatters/normalize-string.ts +0 -8
  84. package/src/formatters/slash.ts +0 -15
  85. package/src/formatters/to-date-format.ts +0 -12
  86. package/src/formatters/to-friendly-name.ts +0 -14
  87. package/src/formatters/to-money.ts +0 -13
  88. package/src/formatters/to-pascal-case.ts +0 -8
  89. package/src/formatters/to-title-case.ts +0 -9
  90. package/src/formatters.ts +0 -10
  91. package/src/index.ts +0 -4
  92. package/src/util/download.ts +0 -18
  93. package/src/util/extract-from-object.ts +0 -11
  94. package/src/util/handle-promise.ts +0 -7
  95. package/src/util.ts +0 -3
  96. package/tsconfig.json +0 -21
  97. /package/dist/{file → types/file}/actions/delete.fn.d.ts +0 -0
  98. /package/dist/{file → types/file}/actions/sign-url.fn.d.ts +0 -0
  99. /package/dist/{file → types/file}/actions/upload.fn.d.ts +0 -0
  100. /package/dist/{file → types/file}/extensions.fn.d.ts +0 -0
  101. /package/dist/{file → types/file}/project-access-context.d.ts +0 -0
  102. /package/dist/{file → types/file}/util/credentials-mutex.so.d.ts +0 -0
  103. /package/dist/{file → types/file}/util/s3-client.d.ts +0 -0
  104. /package/dist/{file → types/file}/util/s3-utils.d.ts +0 -0
  105. /package/dist/{formatters → types/formatters}/bytes-to-string.d.ts +0 -0
  106. /package/dist/{formatters → types/formatters}/json-pretty-print.d.ts +0 -0
  107. /package/dist/{formatters → types/formatters}/normalize-date.d.ts +0 -0
  108. /package/dist/{formatters → types/formatters}/normalize-string.d.ts +0 -0
  109. /package/dist/{formatters → types/formatters}/slash.d.ts +0 -0
  110. /package/dist/{formatters → types/formatters}/to-date-format.d.ts +0 -0
  111. /package/dist/{formatters → types/formatters}/to-friendly-name.d.ts +0 -0
  112. /package/dist/{formatters → types/formatters}/to-money.d.ts +0 -0
  113. /package/dist/{formatters → types/formatters}/to-pascal-case.d.ts +0 -0
  114. /package/dist/{formatters → types/formatters}/to-title-case.d.ts +0 -0
  115. /package/dist/{formatters.d.ts → types/formatters.d.ts} +0 -0
  116. /package/dist/{util → types/util}/download.d.ts +0 -0
  117. /package/dist/{util → types/util}/extract-from-object.d.ts +0 -0
  118. /package/dist/{util → types/util}/handle-promise.d.ts +0 -0
@@ -1,17 +0,0 @@
1
- import { s3UriToParams } from "../../file";
2
-
3
-
4
- describe("s3-utils", () => {
5
- describe("s3UriToParams", () => {
6
- it("should parse a valid s3 URI", () => {
7
- const uri = "s3://my-bucket/my-key/nested/folder";
8
- const result = s3UriToParams(uri);
9
- expect(result).toEqual({ Bucket: "my-bucket", Key: "my-key/nested/folder" });
10
- });
11
-
12
- it("should throw an error for an invalid URI", () => {
13
- const uri = "invalid-uri";
14
- expect(() => s3UriToParams(uri)).toThrowError(`Received invalid uri: '${uri}'`);
15
- });
16
- });
17
- })
@@ -1,18 +0,0 @@
1
- import { AWSCredentials } from "@cirrobio/api-client";
2
- import { DeleteObjectCommand } from "@aws-sdk/client-s3";
3
- import { s3UriToParams } from "../util/s3-utils";
4
- import { createS3Client } from "../util/s3-client";
5
-
6
- export interface DeleteFileParams {
7
- url: string;
8
- credentials: AWSCredentials;
9
- }
10
-
11
- /**
12
- * Delete a file from S3 given its URL and credentials.
13
- */
14
- export async function deleteFile({ url, credentials }: DeleteFileParams): Promise<void> {
15
- const { Bucket, Key } = s3UriToParams(url);
16
- const cmd = new DeleteObjectCommand({ Bucket, Key });
17
- await createS3Client(credentials).send(cmd);
18
- }
@@ -1,36 +0,0 @@
1
- import { AWSCredentials } from "@cirrobio/api-client";
2
- import { GetObjectCommand, GetObjectCommandInput } from "@aws-sdk/client-s3";
3
- import { getSignedUrl as getSignedUrlInternal } from "@aws-sdk/s3-request-presigner";
4
- import { createS3Client } from "../util/s3-client";
5
- import { s3UriToParams } from "../util/s3-utils";
6
-
7
- export interface GetFileUrlParams extends GetSignedUrlOptions {
8
- url: string;
9
- credentials?: AWSCredentials;
10
- }
11
-
12
- export interface GetSignedUrlOptions {
13
- download?: boolean;
14
- gzip?: boolean;
15
- timeout?: number;
16
- filename?: string;
17
- }
18
-
19
- /**
20
- * Get a signed URL for a file in S3 given its S3 URI.
21
- * Defaults to a 5 minute timeout.
22
- */
23
- export function getSignedUrl({ url, credentials, ...params }: GetFileUrlParams): Promise<string> {
24
- const client = createS3Client(credentials);
25
- const { Bucket, Key } = s3UriToParams(url);
26
- const fileName = params.filename ?? Key.split('/').pop();
27
- const args: GetObjectCommandInput = { Bucket, Key };
28
- if (params?.download) {
29
- args.ResponseContentDisposition = `attachment; filename="${fileName}"`
30
- }
31
- if (params?.gzip) {
32
- args.ResponseContentEncoding = 'gzip'
33
- }
34
- const command = new GetObjectCommand(args);
35
- return getSignedUrlInternal(client, command, { expiresIn: 60 * (params?.timeout ?? 5) });
36
- }
@@ -1,30 +0,0 @@
1
- import { Upload } from "@aws-sdk/lib-storage";
2
- import { AWSCredentials } from '@cirrobio/api-client';
3
- import { createS3Client } from "../util/s3-client";
4
-
5
- export interface UploadFileParams {
6
- bucket: string;
7
- path: string;
8
- file: File;
9
- credentials: AWSCredentials;
10
- metadata?: Record<string, string>;
11
- }
12
-
13
- /**
14
- * Upload a file to S3
15
- */
16
- export function uploadFile({ bucket, path, file, credentials, metadata }: UploadFileParams): Upload {
17
- const params = {
18
- Bucket: bucket,
19
- Key: path,
20
- Body: file,
21
- ContentType: file.type,
22
- Metadata: metadata,
23
- };
24
- return new Upload({
25
- client: createS3Client(credentials),
26
- queueSize: 4,
27
- params,
28
- });
29
- }
30
-
@@ -1,14 +0,0 @@
1
- import { FileSystemObject } from "./file-object.model";
2
-
3
- /**
4
- * Calculate the total size of all files in a directory.
5
- * @param files - An array of FileSystemObject representing the files in the directory.
6
- * @return The total size of all files in bytes.
7
- */
8
- export function calculateTotalSize(files: Array<FileSystemObject>): number {
9
- let totalSize = 0;
10
- for (const file of files) {
11
- totalSize += file.size;
12
- }
13
- return totalSize;
14
- }
@@ -1,88 +0,0 @@
1
-
2
- /**
3
- * An array of file extensions that can be rendered in a genome viewer
4
- */
5
- export const FILE_TRACK_ANNOTATION = ['bed', 'bed.gz', 'gtf', 'gtf.gz'];
6
- export const FILE_TRACK_ALIGNMENTS = ['cram', 'cram.gz']; // TODO: put back bam
7
- export const FILE_TRACK_VARIANT = ['vcf', 'vcf.gz'];
8
- export const FILE_TRACK_WIG = ['wig', 'wig.gz', 'bw', 'bw.gz', 'bigwig', 'bigwig.gz'];
9
- export const FILE_TRACK_SEG = ['seg', 'seg.gz'];
10
- export const FILE_TRACK_INDEX_EXTENSIONS = ['tbi', 'bai', 'crai', 'csi'];
11
- export const FILE_VITESSCE_EXTENSIONS = ['hdf5', 'h5ad', 'loom'];
12
- export const FILE_TRACK_EXTENSIONS_NO_INDEX = [
13
- ...FILE_TRACK_ANNOTATION,
14
- ...FILE_TRACK_ALIGNMENTS,
15
- ...FILE_TRACK_VARIANT,
16
- ...FILE_TRACK_WIG,
17
- ...FILE_TRACK_SEG
18
- ];
19
- export const FILE_TRACK_EXTENSIONS = [
20
- ...FILE_TRACK_EXTENSIONS_NO_INDEX,
21
- ...FILE_TRACK_INDEX_EXTENSIONS
22
- ]
23
-
24
-
25
- export const FILE_BROWSER_EXTENSIONS = ['html', 'pdf'];
26
-
27
-
28
- /**
29
- * An array of file extensions that are protein structure files.
30
- */
31
- export const FILE_PROTEIN_STRUCTURE_EXTENSIONS = ['pdb', 'pdb.gz', 'cif', 'cif.gz', 'ent', 'ent.gz', 'mmtf', 'mmtf.gz'];
32
- /**
33
- * An array of file extensions that are considered tabular files.
34
- */
35
- export const FILE_DSV_EXTENSIONS = ['tab', 'csv', 'tsv', 'dsv'];
36
- /**
37
- * An array of file extensions that contain genomic sequence content.
38
- */
39
- export const FILE_TXT_GENOMICS_EXTENSIONS = ['fasta', 'fna', 'fsa', 'fa', 'fastp', 'fastq', 'faa', 'gbk', 'gff', 'vcf', 'seq'];
40
-
41
- /**
42
- * An array of file extensions that are considered TXT files.
43
- */
44
- export const FILE_TXT_EXTENSIONS = ['txt', 'log', 'yml', 'cfg', 'config', 'xml', 'yaml', ...FILE_DSV_EXTENSIONS, ...FILE_TXT_GENOMICS_EXTENSIONS];
45
-
46
-
47
- /**
48
- * An array of file extensions that are considered image files.
49
- */
50
- export const FILE_IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'svg'];
51
-
52
- /**
53
- * An array of file extensions that are considered OME (Open Microscopy Environment) files.
54
- */
55
- export const FILE_OME_EXTENSIONS = ['tif', 'ome.tif', 'ome.tiff', 'ome.tif.gz', 'ome.tiff.gz'];
56
-
57
- /**
58
- * An array of file extensions that can be opened in the browser.
59
- * Includes common document formats such as HTML, PDF, and JSON, as well as image, DSV, TXT, and OME file formats.
60
- */
61
- export const FILE_EXTENSIONS_TO_OPEN = ['html', 'pdf', 'json', 'fcs',
62
- ...FILE_IMAGE_EXTENSIONS,
63
- ...FILE_TXT_EXTENSIONS,
64
- ...FILE_TRACK_EXTENSIONS,
65
- ...FILE_PROTEIN_STRUCTURE_EXTENSIONS
66
- ];
67
-
68
-
69
- /**
70
- * Checks if a file has an extension that matches one in the provided list.
71
- * @param filePath The file to check the extension of.
72
- * @param extensions A list of file endings to check the file against.
73
- * @returns True or false if the file has an ending in the extensions list.
74
- */
75
- export function matchesExtension(filePath: string, extensions: string[]): boolean {
76
- filePath = filePath.toLowerCase();
77
-
78
- // Decompress the filePath if it ends with .gz
79
- if (filePath.endsWith('.gz')) {
80
- filePath = filePath.slice(0, -3); // remove the .gz extension
81
- }
82
-
83
- // Now, get the extension of the file
84
- const fileExtension = filePath.slice(filePath.lastIndexOf('.') + 1);
85
-
86
- // Check if the fileExtension is in the list of extensions
87
- return extensions.includes(fileExtension);
88
- }
@@ -1,57 +0,0 @@
1
- import { ProjectFileAccessContext } from "./project-access-context";
2
-
3
- export enum FileSystemObjectType {
4
- FILE = 'file',
5
- FOLDER = 'folder'
6
- }
7
-
8
- /**
9
- * Represents a file that can be downloaded
10
- */
11
- export interface DownloadableFile {
12
- url: string;
13
- name?: string;
14
- fileAccessContext: ProjectFileAccessContext;
15
- }
16
-
17
- /**
18
- * Represents a file in Cirro
19
- */
20
- export interface FileSystemObject extends DownloadableFile {
21
- /**
22
- * Unique Id For Object
23
- */
24
- id: string;
25
- /**
26
- * Object S3 Url
27
- */
28
- url: string;
29
- /**
30
- * Object Path
31
- */
32
- path: string;
33
- /**
34
- * Object Name
35
- */
36
- name: string;
37
- /**
38
- * Object Size
39
- */
40
- size: number;
41
- /**
42
- * Object Kind (PNG, TXT)
43
- */
44
- kind: string;
45
- /**
46
- * Object Type (File or Folder)
47
- */
48
- type: FileSystemObjectType;
49
- /**
50
- * Metadata
51
- */
52
- metadata?: Record<string, any>;
53
- /**
54
- * Access context
55
- */
56
- fileAccessContext: ProjectFileAccessContext;
57
- }
@@ -1,86 +0,0 @@
1
- import { ProjectAccessType, AWSCredentials, FileApi } from "@cirrobio/api-client";
2
- import { ProjectFileAccessContext } from "./project-access-context";
3
- import { DownloadableFile } from "./file-object.model";
4
- import { credentialsCache, credentialsMutex } from "./util/credentials-mutex.so";
5
- import { GetFileUrlParams, getSignedUrl, GetSignedUrlOptions } from "./actions/sign-url.fn";
6
- import { getProjectS3Bucket } from "./shared";
7
-
8
- /**
9
- * Service for viewing files in Cirro
10
- * currently this only operates on files within a project
11
- */
12
- export class FileService {
13
- constructor(
14
- private readonly fileApi: FileApi
15
- ) {}
16
-
17
- /**
18
- * Get contents of a file
19
- */
20
- async getProjectFile(file: DownloadableFile): Promise<Response> {
21
- const url = await this.getSignedUrlFromProjectFile(file);
22
- return fetch(url);
23
- }
24
-
25
- /**
26
- * Get a signed URL for a file
27
- */
28
- async getSignedUrlFromProjectFile(file: DownloadableFile, params?: GetSignedUrlOptions): Promise<string> {
29
- const credentials = await this.getProjectAccessCredentials(file.fileAccessContext);
30
- const _params: GetFileUrlParams = {
31
- ...params,
32
- filename: file.name,
33
- url: file.url,
34
- credentials,
35
- };
36
- return getSignedUrl(_params);
37
- }
38
-
39
- /**
40
- * Get a signed URL for a file given a path
41
- */
42
- async getSignedUrlFromProjectPath(fileAccessContext: ProjectFileAccessContext, path: string, params?: GetFileUrlParams): Promise<string> {
43
- const credentials = await this.getProjectAccessCredentials(fileAccessContext);
44
- const _params: GetFileUrlParams = {
45
- ...params,
46
- filename: path.split('/').pop(),
47
- url: `s3://${getProjectS3Bucket(fileAccessContext.project.id)}/${path}`,
48
- credentials,
49
- };
50
- return getSignedUrl(_params);
51
- }
52
-
53
- /**
54
- * Get credentials for accessing a project file
55
- */
56
- async getProjectAccessCredentials(fileAccessContext: ProjectFileAccessContext): Promise<AWSCredentials> {
57
- const accessType = fileAccessContext.fileAccessRequest.accessType;
58
- // Special case for project download, since we can cache the credentials
59
- if (accessType === ProjectAccessType.ProjectDownload || accessType === ProjectAccessType.SharedDatasetDownload) {
60
- return this.getProjectReadCredentials(fileAccessContext);
61
- }
62
- return this.fileApi.generateProjectFileAccessToken({ projectId: fileAccessContext.project.id, projectFileAccessRequest: fileAccessContext.fileAccessRequest });
63
- }
64
-
65
- private async getProjectReadCredentials(fileAccessContext: ProjectFileAccessContext): Promise<AWSCredentials> {
66
- const projectId = fileAccessContext.project.id;
67
- // Append datasetId to cache key for shared dataset downloads since we need to generate a new token for each dataset
68
- let cacheKey = projectId;
69
- if (fileAccessContext.fileAccessRequest.accessType === ProjectAccessType.SharedDatasetDownload) {
70
- cacheKey = `${projectId}-${fileAccessContext.fileAccessRequest.datasetId}`;
71
- }
72
-
73
- return credentialsMutex.dispatch(async () => {
74
- const cachedCredentials = credentialsCache.get(cacheKey);
75
- const expirationTime = cachedCredentials ? cachedCredentials?.expiration : null;
76
- const fetchNewCredentials = !expirationTime || expirationTime < new Date();
77
- if (fetchNewCredentials) {
78
- const projectFileAccessRequest = fileAccessContext.fileAccessRequest;
79
- const credentials = await this.fileApi.generateProjectFileAccessToken({ projectId, projectFileAccessRequest });
80
- credentialsCache.set(cacheKey, credentials);
81
- return credentials;
82
- }
83
- return cachedCredentials;
84
- });
85
- }
86
- }
@@ -1,26 +0,0 @@
1
- import { ProjectAccessType, DatasetDetail, ProjectFileAccessRequest, Project } from "@cirrobio/api-client";
2
-
3
- type ProjectIdentifiable = Pick<Project, 'id'>;
4
-
5
- /**
6
- * Helper class to encapsulate the file access for a project.
7
- */
8
- export class ProjectFileAccessContext {
9
- constructor(
10
- readonly project: ProjectIdentifiable,
11
- readonly dataset: DatasetDetail,
12
- readonly fileAccessRequest: ProjectFileAccessRequest
13
- ) {
14
- }
15
-
16
- static projectDownload(project: ProjectIdentifiable): ProjectFileAccessContext {
17
- const request: ProjectFileAccessRequest = { accessType: ProjectAccessType.ProjectDownload };
18
- return new ProjectFileAccessContext(project, null, request);
19
- }
20
-
21
- static datasetDownload(project: ProjectIdentifiable, dataset: DatasetDetail): ProjectFileAccessContext {
22
- const accessType = dataset.share ? ProjectAccessType.SharedDatasetDownload : ProjectAccessType.ProjectDownload;
23
- const request: ProjectFileAccessRequest = { accessType, datasetId: dataset.id };
24
- return new ProjectFileAccessContext(project, dataset, request);
25
- }
26
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * Get the S3 bucket name for a project.
3
- * Will be deprecated in the future.
4
- */
5
- export function getProjectS3Bucket(projectId: string): string {
6
- return `project-${projectId}`;
7
- }
@@ -1,33 +0,0 @@
1
- import { AWSCredentials } from '@cirrobio/api-client';
2
-
3
- class Mutex<T> {
4
- private mutex = Promise.resolve();
5
-
6
- lock(): PromiseLike<() => void> {
7
- let begin: (unlock: () => void) => void = () => { /* Do nothing */ };
8
-
9
- this.mutex = this.mutex.then(() => new Promise(begin));
10
-
11
- return new Promise((res) => {
12
- begin = res;
13
- });
14
- }
15
-
16
- async dispatch(fn: (() => T) | (() => PromiseLike<T>)): Promise<T> {
17
- const unlock = await this.lock();
18
- try {
19
- return await Promise.resolve(fn());
20
- } finally {
21
- unlock();
22
- }
23
- }
24
- }
25
-
26
- /**
27
- * A mutex to ensure that only one request for credentials is made at a time.
28
- */
29
- export const credentialsMutex = new Mutex<AWSCredentials>();
30
- /**
31
- * A cache of credentials to avoid making multiple requests for the same credentials.
32
- */
33
- export const credentialsCache: Map<string, AWSCredentials> = new Map<string, AWSCredentials>();
@@ -1,17 +0,0 @@
1
- import { S3Client } from "@aws-sdk/client-s3";
2
- import { AWSCredentials } from "@cirrobio/api-client";
3
-
4
- /**
5
- * Creates an S3 client using the provided credentials.
6
- */
7
- export function createS3Client(credentials: AWSCredentials): S3Client {
8
- return new S3Client({
9
- credentials: {
10
- accessKeyId: credentials.accessKeyId,
11
- secretAccessKey: credentials.secretAccessKey,
12
- sessionToken: credentials.sessionToken,
13
- },
14
- region: credentials.region,
15
- useDualstackEndpoint: true,
16
- });
17
- }
@@ -1,14 +0,0 @@
1
- /**
2
- * Converts an S3 URI to a bucket and key
3
- */
4
- export function s3UriToParams(uri: string): { Bucket: string, Key: string } {
5
- const matches = /^s3:\/\/([^/]+)\/(.+)$/.exec(uri);
6
- if (!matches) {
7
- throw new Error(`Received invalid uri: '${uri}'`);
8
- }
9
- return {
10
- Bucket: matches[1],
11
- Key: matches[2],
12
- };
13
- }
14
-
package/src/file.ts DELETED
@@ -1,13 +0,0 @@
1
- export * from './file/extensions.fn'
2
- export { FileService } from './file/file.service'
3
- export { deleteFile, DeleteFileParams } from './file/actions/delete.fn'
4
- export { getSignedUrl, GetSignedUrlOptions } from './file/actions/sign-url.fn'
5
- export { uploadFile, UploadFileParams } from './file/actions/upload.fn'
6
- export { ProjectFileAccessContext } from './file/project-access-context'
7
- export { FileSystemObject, FileSystemObjectType } from './file/file-object.model'
8
- export { s3UriToParams } from './file/util/s3-utils'
9
- export { createS3Client } from './file/util/s3-client'
10
- export { credentialsCache, credentialsMutex } from './file/util/credentials-mutex.so';
11
- export { getProjectS3Bucket } from './file/shared'
12
- export { calculateTotalSize } from './file/calculate-size'
13
- export { Progress, Upload } from '@aws-sdk/lib-storage';
@@ -1,65 +0,0 @@
1
- import { bytesToString } from "../bytes-to-string";
2
- import { normalizeDate } from "../normalize-date";
3
- import { removeEndingSlash, removeStartingSlash } from "../slash";
4
- import { toFriendlyName } from "../to-friendly-name";
5
- import { toMoney } from "../to-money";
6
- import { toTitleCase } from "../to-title-case";
7
-
8
- describe('bytesToString', () => {
9
- it('should convert IEC bytes to string', () => {
10
- expect(bytesToString(12521, false)).toBe('12.2 KiB');
11
- });
12
-
13
- it('should convert SI bytes to string', () => {
14
- expect(bytesToString(12521, true, 2)).toBe('12.52 kB');
15
- });
16
- });
17
-
18
- describe('normalizeDate', () => {
19
- it('should work on a string input', () => {
20
- const dateString = '2022-12-01'
21
- const output = normalizeDate(dateString).toISOString().split('T')[0]
22
- expect(output).toEqual(dateString);
23
- });
24
-
25
- it('should work on a Date object input', () => {
26
- const dateString = '2022-12-01'
27
- const output = normalizeDate(new Date(dateString)).toISOString().split('T')[0]
28
- expect(output).toEqual(dateString);
29
- });
30
- });
31
-
32
- describe('removeStartingSlash', () => {
33
- it('should remove the starting slash from a string', () => {
34
- expect(removeStartingSlash('/example/path/')).toBe('example/path/');
35
- });
36
- });
37
-
38
- describe('removeEndingSlash', () => {
39
- it('should remove the ending slash from a string', () => {
40
- expect(removeEndingSlash('/example/path/')).toBe('/example/path');
41
- });
42
- });
43
-
44
- describe('toFriendlyName', () => {
45
- it('should add correct spaces to a string', () => {
46
- expect(toFriendlyName('ExampleUnfriendly|Name_here')).toBe('Example unfriendly name here');
47
-
48
- });
49
- });
50
-
51
- describe('toMoney', () => {
52
- it('convert an integer value to a money-formatted string', () => {
53
- expect(toMoney(25)).toBe('$25.00');
54
- });
55
-
56
- it('convert a float value to a money-formatted string', () => {
57
- expect(toMoney(117.15)).toBe('$117.15');
58
- });
59
- });
60
-
61
- describe('toTitleCase', () => {
62
- it('should convert a string to title case', () => {
63
- expect(toTitleCase('convert To Title case')).toBe('Convert to title case');
64
- });
65
- });
@@ -1,32 +0,0 @@
1
- /**
2
- * Format bytes as human-readable text.
3
- * @param bytes Number of bytes.
4
- * @param si True to use metric(SI) units, aka powers of 1000. False to use
5
- * binary(IEC), aka powers of 1024.
6
- * @param dp Number of decimal places to display.
7
- *
8
- * @return Formatted string.
9
- */
10
- export function bytesToString(bytes, si = false, dp = 1): string {
11
- const thresh = si ? 1000 : 1024;
12
-
13
- if (Math.abs(bytes) < thresh) {
14
- return `${bytes} B`;
15
- }
16
-
17
- const units = si
18
- ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
19
- : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
20
- let u = -1;
21
- const r = 10 ** dp;
22
-
23
- do {
24
- bytes /= thresh;
25
- ++u;
26
- } while (
27
- Math.round(Math.abs(bytes) * r) / r >= thresh
28
- && u < units.length - 1
29
- );
30
-
31
- return `${bytes.toFixed(dp)} ${units[u]}`;
32
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Pretty prints a JSON object with the specified indentation level.
3
- * @param obj JSON object to be pretty printed.
4
- * @param indentLevel Number of spaces to use for indentation.
5
- */
6
- export function jsonPrettyPrint(obj: object, indentLevel=2): string {
7
- return JSON.stringify(obj, null, indentLevel);
8
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * Normalizes a date to UTC by adjusting for the timezone offset.
3
- * Useful when you are working with dates that may not include time information.
4
- * @param date
5
- */
6
- export function normalizeDate(date: Date | string | undefined | null): Date {
7
- if (!date) throw new Error("Attempt to normalize undefined");
8
- if (!(date instanceof Date)) date = new Date(date);
9
- return new Date(date.getTime() - date.getTimezoneOffset() * -60000);
10
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Normalize a string by trimming it and returning null if it is empty.
3
- * @param input The string to normalize.
4
- */
5
- export function normalizeString(input: string): string {
6
- if (!input?.trim()) return null;
7
- return input.trim();
8
- }
@@ -1,15 +0,0 @@
1
- /**
2
- * Removes the starting slash from a path.
3
- * @param path Input path
4
- */
5
- export function removeStartingSlash(path: string): string {
6
- return path?.startsWith('/') ? path.substring(1) : path;
7
- }
8
-
9
- /**
10
- * Removes the ending slash from a path.
11
- * @param path Input path
12
- */
13
- export function removeEndingSlash(path: string): string {
14
- return path?.endsWith('/') ? path.slice(0, -1) : path;
15
- }
@@ -1,12 +0,0 @@
1
- const dateFormat = new Intl.DateTimeFormat('en-US', { month: '2-digit', day: '2-digit', year: '2-digit' });
2
-
3
- /**
4
- * Converts a date string or Date object to MM/DD/YY date string.
5
- * Ex., "2023-10-01" -> "10/01/23"
6
- * @param date Input date string or Date object.
7
- */
8
- export function toDateFormat(date: string | Date): string {
9
- if (!date) return null;
10
- const d: Date = (typeof date === 'string') ? new Date(date) : date
11
- return dateFormat.format(d);
12
- }
@@ -1,14 +0,0 @@
1
- import { toTitleCase } from './to-title-case';
2
-
3
- /**
4
- * Converts a field name to a more human-readable format.
5
- * Ex., "helloWorld" -> "Hello World"
6
- * @param value The value to convert.
7
- */
8
- export function toFriendlyName(value: string): string {
9
- let _value = value.split(/(?=[A-Z])/).join(' ');
10
- _value = _value.split('_').join(' ');
11
- _value = _value.split('|').join(' ');
12
- _value = _value.replace(/ +/g, ' ');
13
- return toTitleCase(_value);
14
- }
@@ -1,13 +0,0 @@
1
- const money = new Intl.NumberFormat('en-US', {
2
- style: 'currency',
3
- currency: 'USD',
4
- });
5
-
6
- /**
7
- * Converts a number or bigint to a formatted money string.
8
- * Ex., 1234.56 -> $1,234.56
9
- * @param value Input number or bigint value.
10
- */
11
- export function toMoney(value: number | bigint): string {
12
- return money.format(value);
13
- }
@@ -1,8 +0,0 @@
1
- /**
2
- * Converts a string to PascalCase.
3
- * Ex., "hello world" -> "HelloWorld"
4
- * @param value The string to convert.
5
- */
6
- export function toPascalCase(value: string): string {
7
- return value.replace(/(\w)(\w*)/g, (g0, g1, g2) => g1.toUpperCase() + g2.toLowerCase());
8
- }