@cayuse-test/react 1.0.8 → 1.0.10
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/{chunk-M2L7SQBQ.js → chunk-6DB5M6WN.js} +3 -3
- package/dist/chunk-6DB5M6WN.js.map +1 -0
- package/dist/{chunk-SYDHZCBD.js → chunk-RJUCILWA.js} +48 -46
- package/dist/chunk-RJUCILWA.js.map +1 -0
- package/dist/{chunk-BVB7EXJY.js → chunk-XVA4YFXM.js} +2 -2
- package/dist/chunk-XVA4YFXM.js.map +1 -0
- package/dist/components/index.css +11 -19
- package/dist/components/index.css.map +1 -1
- package/dist/components/index.js +3 -3
- package/dist/hooks/index.js +1 -1
- package/dist/index.css +11 -19
- package/dist/index.css.map +1 -1
- package/dist/index.js +3 -3
- package/dist/services/upload-s3/index.d.ts +2 -2
- package/dist/services/upload-s3/index.js +1 -1
- package/package.json +13 -16
- package/dist/chunk-BVB7EXJY.js.map +0 -1
- package/dist/chunk-M2L7SQBQ.js.map +0 -1
- package/dist/chunk-SYDHZCBD.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
setDictionary,
|
|
68
68
|
setLoginTenantId,
|
|
69
69
|
useActiveColumns
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-RJUCILWA.js";
|
|
71
71
|
import {
|
|
72
72
|
useConfirmNavigation,
|
|
73
73
|
useDebounceCallback,
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
uppyInitialState,
|
|
84
84
|
useClickOutside,
|
|
85
85
|
useFileUploader
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-XVA4YFXM.js";
|
|
87
87
|
import {
|
|
88
88
|
alphaSortCollectionByKey,
|
|
89
89
|
capitalizeAndJoin,
|
|
@@ -157,7 +157,7 @@ import {
|
|
|
157
157
|
UploadError,
|
|
158
158
|
UploadService,
|
|
159
159
|
createUploadService
|
|
160
|
-
} from "./chunk-
|
|
160
|
+
} from "./chunk-6DB5M6WN.js";
|
|
161
161
|
export {
|
|
162
162
|
ACCESS_TOKEN,
|
|
163
163
|
APP_ENV,
|
|
@@ -23,12 +23,12 @@ type IUploadService = {
|
|
|
23
23
|
downloadUrl: (fileId: string) => Promise<string>;
|
|
24
24
|
download: (fileId: string, fileName: string) => Promise<void>;
|
|
25
25
|
};
|
|
26
|
-
declare const
|
|
26
|
+
declare const serviceDefaultProps: {
|
|
27
27
|
shouldUseMultipart: (fileSize: number) => boolean;
|
|
28
28
|
maxConcurrentUploads: number;
|
|
29
29
|
request: typeof fetch;
|
|
30
30
|
};
|
|
31
|
-
type UploadServiceProps = Partial<typeof
|
|
31
|
+
type UploadServiceProps = Partial<typeof serviceDefaultProps>;
|
|
32
32
|
declare const createUploadService: (props?: UploadServiceProps) => IUploadService;
|
|
33
33
|
declare const UploadService: IUploadService;
|
|
34
34
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cayuse-test/react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -30,24 +30,10 @@
|
|
|
30
30
|
"engines": {
|
|
31
31
|
"node": ">=20"
|
|
32
32
|
},
|
|
33
|
-
"packageManager": "pnpm@10.14.0",
|
|
34
33
|
"repository": {
|
|
35
34
|
"type": "git",
|
|
36
35
|
"url": "git+ssh://git@bitbucket.org/cayusellc/cayuse-react-components.git"
|
|
37
36
|
},
|
|
38
|
-
"scripts": {
|
|
39
|
-
"build": "tsup",
|
|
40
|
-
"dev": "tsup --watch",
|
|
41
|
-
"check-types": "tsc --noEmit",
|
|
42
|
-
"format": "prettier --write \"**/*.{js,ts,tsx,md}\"",
|
|
43
|
-
"prepare": "test -f scripts/install-hooks.sh && bash scripts/install-hooks.sh || true",
|
|
44
|
-
"lint": "eslint .",
|
|
45
|
-
"lint:fix": "eslint . --fix",
|
|
46
|
-
"storybook": "storybook dev -p 6006",
|
|
47
|
-
"build-storybook": "storybook build",
|
|
48
|
-
"test": "vitest",
|
|
49
|
-
"prepublishOnly": "pnpm run build"
|
|
50
|
-
},
|
|
51
37
|
"dependencies": {
|
|
52
38
|
"@fortawesome/fontawesome-svg-core": "6.7.2",
|
|
53
39
|
"@fortawesome/free-solid-svg-icons": "6.7.2",
|
|
@@ -114,5 +100,16 @@
|
|
|
114
100
|
"typescript-eslint": "^8.35.0",
|
|
115
101
|
"vite": "^7.1.3",
|
|
116
102
|
"vitest": "^3.2.4"
|
|
103
|
+
},
|
|
104
|
+
"scripts": {
|
|
105
|
+
"build": "tsup",
|
|
106
|
+
"dev": "tsup --watch",
|
|
107
|
+
"check-types": "tsc --noEmit",
|
|
108
|
+
"format": "prettier --write \"**/*.{js,ts,tsx,md}\"",
|
|
109
|
+
"lint": "eslint .",
|
|
110
|
+
"lint:fix": "eslint . --fix",
|
|
111
|
+
"storybook": "storybook dev -p 6006",
|
|
112
|
+
"build-storybook": "storybook build",
|
|
113
|
+
"test": "vitest"
|
|
117
114
|
}
|
|
118
|
-
}
|
|
115
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/hooks/use-file-uploader/uppy/constants.ts","../packages/hooks/use-file-uploader/uppy/api.ts","../packages/hooks/use-file-uploader/uppy/service.ts","../packages/hooks/use-file-uploader/use-file-uploader.tsx","../packages/hooks/use-click-outside/use-click-outside.tsx"],"sourcesContent":["export type UppyEvent =\n\t| 'file-added'\n\t| 'files-added'\n\t| 'file-removed'\n\t| 'upload'\n\t| 'progress'\n\t| 'preprocess-complete'\n\t| 'upload-progress'\n\t| 'upload-success'\n\t| 'complete'\n\t| 'error'\n\t| 'upload-error'\n\t| 'upload-retry'\n\t| 'retry-all'\n\t| 'info-visible'\n\t| 'info-hidden'\n\t| 'cancel-all'\n\t| 'restriction-failed'\n\t| 'reset-progress';\n\nexport const uppyEvents: UppyEvent[] = [\n\t'file-added',\n\t'files-added',\n\t'file-removed',\n\t'upload',\n\t'progress',\n\t'preprocess-complete',\n\t'upload-progress',\n\t'upload-success',\n\t'complete',\n\t'error',\n\t'upload-error',\n\t'upload-retry',\n\t'retry-all',\n\t'info-visible',\n\t'info-hidden',\n\t'cancel-all',\n\t'restriction-failed',\n\t'reset-progress',\n];\n\ninterface UppyState {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tplugins: { [key: string]: any };\n\terror: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tfiles: { [key: string]: any };\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcurrentUploads: { [key: string]: any };\n\tallowNewUpload: boolean;\n\tcapabilities: {\n\t\tuploadProgress: boolean;\n\t\tindividualCancellation: boolean;\n\t\tresumableUploads: boolean;\n\t};\n\ttotalProgress: number;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tmeta: { [key: string]: any };\n\tinfo: Array<{ type: string; message: string; details: string }>;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\trecoveredState: null | { [key: string]: any };\n}\n\nexport const uppyInitialState: UppyState = {\n\tplugins: {},\n\terror: '',\n\tfiles: {},\n\tcurrentUploads: {},\n\tallowNewUpload: true,\n\tcapabilities: {\n\t\tuploadProgress: true,\n\t\tindividualCancellation: true,\n\t\tresumableUploads: false,\n\t},\n\ttotalProgress: 0,\n\tmeta: {},\n\tinfo: [],\n\trecoveredState: null,\n};\n\nexport const MAX_FILE_SIZE_75_MB: number = 75 * Math.pow(1024, 2);\n\ninterface DefaultDictionary {\n\texeFileTypeRestriction: string;\n\t[key: string]: string;\n}\n\nexport const defaultDictionary: DefaultDictionary = {\n\texeFileTypeRestriction:\n\t\t'Attachments with filetype .exe cannot be accepted. Please try a different file type.',\n};\n","import { executeRequest } from '@/utils/http';\n\ninterface UploadUrlResponse {\n\tpreSignedUrl: string;\n\tuploadMetadataId: string;\n}\n\ninterface CompleteUploadResponse {\n\tcompletedAt: string;\n\tcreatedAt: string;\n\tfileName: string;\n\tfileSize: number;\n\tfinalizedAt: unknown;\n\tid: string;\n\ttenantId: string;\n\tuploadedBy: string;\n}\n\ninterface PersonDetails {\n\tid: string;\n\ttenantId: string;\n\tfirstName: string;\n\tlastName: string;\n\tfullName: string;\n\tmiddleName: string;\n\tcontactEmail: string;\n\tuserAccountId: string;\n}\n\ninterface UploadUrlRequestBody {\n\tfileName: string;\n\tfileSize: number;\n}\n\ninterface RequestOptions {\n\tsignal?: AbortSignal;\n}\n\nexport const api = {\n\tgetUploadURL: (\n\t\tbody: UploadUrlRequestBody,\n\t\toptions?: RequestOptions,\n\t): Promise<UploadUrlResponse> => {\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t\tbody: JSON.stringify(body),\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tsignal: options?.signal,\n\t\t};\n\n\t\treturn executeRequest('/api/v2/attachments/upload', requestOptions);\n\t},\n\n\tcompleteUpload: (id: string): Promise<CompleteUploadResponse> => {\n\t\tconst requestOptions = {\n\t\t\tmethod: 'POST',\n\t\t};\n\n\t\treturn executeRequest(\n\t\t\t`/api/v2/attachments/upload/${id}/complete`,\n\t\t\trequestOptions,\n\t\t);\n\t},\n\n\tgetDownloadUrl: (id: string): Promise<string> => {\n\t\treturn executeRequest(`/api/v2/attachments/download?uploadMetadataId=${id}`);\n\t},\n\n\tgetPersonDetailsById: (\n\t\tid: string,\n\t): Promise<PersonDetails | { errors: unknown[] }> => {\n\t\treturn executeRequest(`/api/v2/person/user/${id}`);\n\t},\n};\n","import { v4 as uuidv4 } from 'uuid';\nimport Uppy from '@uppy/core';\nimport AwsS3 from '@uppy/aws-s3';\nimport { merge } from 'lodash-es';\n\nimport { MAX_FILE_SIZE_75_MB, uppyEvents, UppyEvent } from './constants.js';\nimport { api } from './api.js';\n\ninterface UppyDefaultOptions {\n\tautoProceed?: boolean;\n\trestrictions?: {\n\t\tmaxFileSize?: number;\n\t\tmaxNumberOfFiles?: number;\n\t\tallowedFileTypes?: string[] | null;\n\t};\n}\n\ninterface UppyFile {\n\tid: string;\n\tname: string;\n\tsize: number;\n\ttype: string;\n\tmeta: {\n\t\tuploadMetadataId: string;\n\t\tuploadedBy: string;\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t[key: string]: any;\n\t};\n}\n\ninterface UploadUrlResponse {\n\tpreSignedUrl: string;\n\tuploadMetadataId: string;\n}\n\ninterface CompleteUploadResponse {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t[k: string]: any;\n\tcompletedAt: string;\n\tcreatedAt: string;\n\tfileName: string;\n\tfileSize: number;\n\tfinalizedAt: unknown;\n\tid: string;\n\ttenantId: string;\n\tuploadedBy: string;\n}\n\ninterface PersonDetails {\n\tfirstName: string;\n\tlastName: string;\n}\n\nexport class UppyService {\n\tprivate instances: Map<string, Uppy> = new Map();\n\tprivate retryCount: number = 0;\n\tprivate defaultOptions: UppyDefaultOptions = {\n\t\tautoProceed: true,\n\t\trestrictions: {\n\t\t\tmaxFileSize: MAX_FILE_SIZE_75_MB,\n\t\t\tmaxNumberOfFiles: 9,\n\t\t\tallowedFileTypes: null,\n\t\t},\n\t};\n\n\tgetInstance(id: string): Uppy | null {\n\t\treturn this.instances.get(id) || null;\n\t}\n\n\tregister(options: UppyDefaultOptions): Uppy {\n\t\tconst id: string = uuidv4();\n\n\t\tconst getUploadParameters =\n\t\t\t(instanceId: string) =>\n\t\t\tasync (\n\t\t\t\tfile: UppyFile,\n\t\t\t\t_options: { signal?: AbortSignal },\n\t\t\t): Promise<{\n\t\t\t\tmethod: string;\n\t\t\t\turl: string;\n\t\t\t\tfields: Record<string, never>;\n\t\t\t\theaders: { 'Content-Type': string };\n\t\t\t}> => {\n\t\t\t\tconst response: UploadUrlResponse = await api.getUploadURL(\n\t\t\t\t\t{\n\t\t\t\t\t\tfileName: file.name,\n\t\t\t\t\t\tfileSize: file.size,\n\t\t\t\t\t},\n\t\t\t\t\t_options,\n\t\t\t\t);\n\n\t\t\t\tconst instance = this.getInstance(instanceId);\n\t\t\t\tif (instance) {\n\t\t\t\t\t// @ts-expect-error type mismatch\n\t\t\t\t\tinstance.setFileMeta(file.id, response);\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tmethod: 'PUT',\n\t\t\t\t\turl: response.preSignedUrl,\n\t\t\t\t\tfields: {},\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t'Content-Type': file.type,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t};\n\n\t\tconst instance: Uppy = new Uppy(this.#getOptions(id, options)).use(AwsS3, {\n\t\t\t// @ts-expect-error type mismatch\n\t\t\tgetUploadParameters: getUploadParameters(id),\n\t\t});\n\n\t\tObject.defineProperty(instance, 'id', { value: id, enumerable: true });\n\n\t\tthis.instances.set(id, instance);\n\n\t\tthis.#subscribeOnEvents(id);\n\n\t\treturn instance;\n\t}\n\n\tdestroy(id: string): void {\n\t\tconst instance = this.getInstance(id);\n\t\t// @ts-expect-error type mismatch\n\t\tinstance?.close(() => this.instances.delete(id));\n\t}\n\n\tonAnyEvent(\n\t\tid: string,\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\teventCallback: (eventName: UppyEvent, ...args: any[]) => void,\n\t): void {\n\t\tconst inst = this.getInstance(id);\n\t\tif (inst) {\n\t\t\tuppyEvents.forEach((event: UppyEvent) => {\n\t\t\t\tinst.on(\n\t\t\t\t\t// @ts-expect-error type mismatch\n\t\t\t\t\tevent,\n\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t(...args: any[]) => {\n\t\t\t\t\t\teventCallback(event, ...args);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t#subscribeOnEvents(instanceId: string): void {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (instance) {\n\t\t\t// @ts-expect-error type miss match\n\t\t\tinstance.on('upload-success', async (file: UppyFile) => {\n\t\t\t\tawait this.#completeUploading(instanceId, file);\n\t\t\t});\n\t\t}\n\t}\n\n\t#getOptions(\n\t\tid: string,\n\t\toptions: UppyDefaultOptions,\n\t): UppyDefaultOptions & { id: string; debug: boolean } {\n\t\treturn {\n\t\t\t...merge(this.defaultOptions, options),\n\t\t\tid,\n\t\t\tdebug: true,\n\t\t};\n\t}\n\n\tasync #completeUploading(instanceId: string, file: UppyFile): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst completedResponse: CompleteUploadResponse = await api.completeUpload(\n\t\t\t\tfile.meta.uploadMetadataId,\n\t\t\t);\n\t\t\tinstance.setFileMeta(file.id, completedResponse);\n\n\t\t\tinstance.emit('complete', completedResponse);\n\n\t\t\tthis.#getDownloadUrl(instanceId, file.id);\n\t\t\tthis.#loadAdditionalFileMetadata(instanceId, file.id);\n\t\t} catch (error) {\n\t\t\t// @ts-expect-error type miss match\n\t\t\tinstance.emit('upload-error', file, error);\n\t\t}\n\t}\n\n\tasync #getDownloadUrl(instanceId: string, fileId: string): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst file = instance.getFile(fileId);\n\t\t\tif (!file) return;\n\n\t\t\tconst downloadUrl: string = await api.getDownloadUrl(\n\t\t\t\tfile.meta.uploadMetadataId as string,\n\t\t\t);\n\n\t\t\tif (typeof downloadUrl === 'string') {\n\t\t\t\tinstance.setFileMeta(fileId, { downloadUrl });\n\t\t\t} else {\n\t\t\t\tinstance.emit('error', downloadUrl);\n\t\t\t}\n\n\t\t\tinstance.emit('complete', { downloadUrl });\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tinstance.emit('error', error);\n\t\t}\n\t}\n\n\tasync #loadAdditionalFileMetadata(\n\t\tinstanceId: string,\n\t\tfileId: string,\n\t): Promise<void> {\n\t\tconst instance = this.getInstance(instanceId);\n\t\tif (!instance) return;\n\n\t\ttry {\n\t\t\tconst file = instance.getFile(fileId);\n\t\t\tif (!file) return;\n\n\t\t\tconst response: PersonDetails | { errors: unknown[] } =\n\t\t\t\tawait api.getPersonDetailsById(file.meta.uploadedBy as string);\n\n\t\t\tif ('firstName' in response) {\n\t\t\t\tinstance.setFileMeta(fileId, {\n\t\t\t\t\tuploadedByInfo: {\n\t\t\t\t\t\tfirstName: response.firstName,\n\t\t\t\t\t\tlastName: response.lastName,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tinstance.emit('error', response as any);\n\t\t\t}\n\n\t\t\tinstance.emit('complete', {});\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tinstance.emit('error', error);\n\t\t}\n\t}\n}\n","import React from 'react';\nimport { merge } from 'lodash-es';\nimport { prettierBytes } from '@transloadit/prettier-bytes';\nimport { isFunction } from '../../utils';\n\nimport {\n\tUppyService,\n\tuppyInitialState,\n\tdefaultDictionary,\n\tMAX_FILE_SIZE_75_MB,\n} from './uppy';\n\n// Type definitions\nexport interface FileObject {\n\tuppyId: string;\n\tid: string;\n\tname: string;\n\tsize: number;\n\tdownloadUrl: string;\n\tuploadedBy: string;\n\tcreatedAt: string;\n\tfinalizedAt: string;\n\tcompletedAt: string;\n\ttenantId: string;\n\ttype: string;\n\tprogress: {\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t[key: string]: any;\n\t};\n\tuploadMetadataId: string;\n\terror: string;\n}\n\nexport interface UppyInstance {\n\tid: string;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\temit: (eventName: string, ...args: any[]) => void;\n\taddFiles: (\n\t\tfiles: Array<{\n\t\t\tsource: string;\n\t\t\tname: string;\n\t\t\ttype: string;\n\t\t\tdata: File;\n\t\t}>,\n\t) => void;\n\tremoveFile: (fileId: string, reason?: string, event?: Event) => void;\n\tgetState: () => UppyState;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tlog: (message: any, ...args: any[]) => void;\n}\n\nexport interface UppyDefaultOptions {\n\tautoProceed?: boolean;\n\trestrictions?: {\n\t\tmaxFileSize?: number;\n\t\tmaxNumberOfFiles?: number;\n\t\tallowedFileTypes?: string[] | null;\n\t};\n}\n\nexport interface UseFileUploaderOptions {\n\tdictionary?: {\n\t\tfileUploaderHook?: {\n\t\t\t[key: string]: string;\n\t\t};\n\t};\n\toptions?: UppyDefaultOptions;\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tonErrorCallback?: (error: any) => void;\n}\n\nexport interface UppyState {\n\tfiles: {\n\t\t[key: string]: {\n\t\t\tid: string;\n\t\t\tname: string;\n\t\t\tsize: number;\n\t\t\tmeta: {\n\t\t\t\tid: string;\n\t\t\t\tdownloadUrl: string;\n\t\t\t\tuploadedBy: string;\n\t\t\t\tcreatedAt: string;\n\t\t\t\tfinalizedAt: string;\n\t\t\t\tcompletedAt: string;\n\t\t\t\ttenantId: string;\n\t\t\t\ttype: string;\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\tuploadedByInfo: any;\n\t\t\t\tuploadMetadataId: string;\n\t\t\t};\n\t\t\tprogress: {\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t[key: string]: any;\n\t\t\t};\n\t\t\terror: string;\n\t\t};\n\t};\n\tinfo: Array<{ type: string; message: string; details: string }>;\n\terror: string;\n}\n\nconst uppyService = new UppyService();\n\nconst notify =\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t(global as any).__CAYUSE__?.notify ??\n\t(() => {\n\t\tconsole.error(\n\t\t\t'function is not defined. check is banner-notification package install',\n\t\t);\n\t});\n\nconst defaultUseFileUploaderOptions: UseFileUploaderOptions = {\n\tdictionary: {},\n\toptions: {\n\t\trestrictions: {\n\t\t\tmaxFileSize: MAX_FILE_SIZE_75_MB,\n\t\t},\n\t},\n};\n\nexport const useFileUploader = (\n\thookProps: UseFileUploaderOptions = defaultUseFileUploaderOptions,\n) => {\n\tconst props = merge({}, hookProps, defaultUseFileUploaderOptions);\n\tconst uppyInstance = React.useRef<UppyInstance>({} as UppyInstance);\n\tconst [state, setState] = React.useState<UppyState>(uppyInitialState);\n\n\tconst dictionary = React.useMemo(\n\t\t() => merge({}, defaultDictionary, props.dictionary?.fileUploaderHook),\n\t\t[props.dictionary?.fileUploaderHook],\n\t);\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst onError = (error: any) => {\n\t\tif (isFunction(hookProps.onErrorCallback)) {\n\t\t\thookProps.onErrorCallback(error);\n\t\t}\n\t};\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconst handleEvent = (eventName: string, ...args: any[]) => {\n\t\tswitch (eventName) {\n\t\t\tcase 'error': {\n\t\t\t\tconst [error] = args;\n\t\t\t\tif (error.details !== 'File removed') {\n\t\t\t\t\tnotify(error.message, { type: 'error' });\n\t\t\t\t\tonError(error);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'restriction-failed': {\n\t\t\t\tconst [, error] = args;\n\t\t\t\tnotify(error.message, { type: 'error' });\n\t\t\t\tonError(error);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\tReact.useEffect(() => {\n\t\tconst uppyOptions = {\n\t\t\t...(props.options ?? {}),\n\t\t\tlocale: {\n\t\t\t\tstrings: dictionary,\n\t\t\t},\n\t\t};\n\n\t\t// @ts-expect-error correct type for UppyService\n\t\tuppyInstance.current = uppyService.register(uppyOptions);\n\n\t\tuppyService.onAnyEvent(\n\t\t\tuppyInstance.current.id,\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t(eventName: string, ...args: any[]) => {\n\t\t\t\tconst newState = uppyInstance.current.getState();\n\t\t\t\tsetState(newState);\n\t\t\t\tuppyInstance.current.log(`The state was updated by an event: ${eventName}`);\n\t\t\t\tuppyInstance.current.log(newState);\n\n\t\t\t\thandleEvent(eventName, ...args);\n\t\t\t},\n\t\t);\n\n\t\treturn () => {\n\t\t\tuppyService.destroy(uppyInstance.current.id);\n\t\t};\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, []);\n\n\tconst addFiles = (\n\t\tfiles: File[],\n\t\tonSuccessCallback?: (acceptedFiles: File[]) => void,\n\t\tonRejectCallback?: (\n\t\t\tinvalidExtensionFiles: File[],\n\t\t\texceedSizeFiles: File[],\n\t\t) => void,\n\t) => {\n\t\tconst exceedSizeDescriptors: Array<{\n\t\t\tsource: string;\n\t\t\tname: string;\n\t\t\ttype: string;\n\t\t\tdata: File;\n\t\t}> = [];\n\t\tconst descriptors: Array<{\n\t\t\tsource: string;\n\t\t\tname: string;\n\t\t\ttype: string;\n\t\t\tdata: File;\n\t\t}> = [];\n\t\tconst invalidExtensionFiles: File[] = [];\n\t\tconst exceedSizeFiles: File[] = [];\n\n\t\tconst { maxFileSize = MAX_FILE_SIZE_75_MB } = props?.options?.restrictions ?? {};\n\n\t\tfor (const file of files) {\n\t\t\tconst ext = file.name.split('.').reverse()?.[0]?.toLowerCase();\n\t\t\tconst descriptor = {\n\t\t\t\tsource: uppyInstance.current.id,\n\t\t\t\tname: file.name,\n\t\t\t\ttype: file.type,\n\t\t\t\tdata: file,\n\t\t\t};\n\n\t\t\tif (ext === 'exe') {\n\t\t\t\tinvalidExtensionFiles.push(file);\n\t\t\t\tuppyInstance.current.emit(\n\t\t\t\t\t'restriction-failed',\n\t\t\t\t\tdescriptor,\n\t\t\t\t\tnew Error(\n\t\t\t\t\t\t'Attachments with filetype .exe cannot be accepted. Please try a different file type.',\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else if (maxFileSize && file.size != null && file.size > maxFileSize) {\n\t\t\t\texceedSizeFiles.push(file);\n\t\t\t\texceedSizeDescriptors.push(descriptor);\n\t\t\t} else {\n\t\t\t\tdescriptors.push(descriptor);\n\t\t\t}\n\t\t}\n\n\t\tif (isFunction(onRejectCallback)) {\n\t\t\tonRejectCallback(invalidExtensionFiles, exceedSizeFiles);\n\t\t}\n\n\t\tif (files.length === 1 && exceedSizeDescriptors.length === 1) {\n\t\t\tuppyInstance.current.emit(\n\t\t\t\t'restriction-failed',\n\t\t\t\texceedSizeDescriptors[0],\n\t\t\t\tnew Error(\n\t\t\t\t\t`The uploaded file exceeds the ${prettierBytes(maxFileSize)} limit.`,\n\t\t\t\t),\n\t\t\t);\n\t\t} else if (files.length > 1 && exceedSizeDescriptors.length >= 1) {\n\t\t\tuppyInstance.current.emit(\n\t\t\t\t'restriction-failed',\n\t\t\t\texceedSizeDescriptors,\n\t\t\t\tnew Error(\n\t\t\t\t\t`${exceedSizeFiles.length} of the ${\n\t\t\t\t\t\tfiles.length\n\t\t\t\t\t} uploaded files exceed the ${prettierBytes(maxFileSize)} limit.`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\n\t\ttry {\n\t\t\tif (descriptors.length > 0) {\n\t\t\t\tuppyInstance.current.addFiles(descriptors);\n\t\t\t}\n\n\t\t\tif (isFunction(onSuccessCallback)) {\n\t\t\t\tconst acceptedFiles = files.filter((f) =>\n\t\t\t\t\tdescriptors.find((d) => d.name === f.name),\n\t\t\t\t);\n\t\t\t\tonSuccessCallback(acceptedFiles);\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tuppyInstance.current.log(err);\n\t\t\tonError(err);\n\t\t}\n\t};\n\n\tconst removeFile = (file: FileObject, reason: string, event?: Event) => {\n\t\tif (file.uppyId) {\n\t\t\tuppyInstance.current.removeFile(file.uppyId, reason, event);\n\t\t}\n\t};\n\n\tconst files = React.useMemo(() => {\n\t\treturn Object.entries(state.files).map(([, file]) => ({\n\t\t\tuppyId: file.id,\n\t\t\tid: file.meta.id,\n\t\t\tname: file.name,\n\t\t\tsize: Number(file.size),\n\t\t\tdownloadUrl: file.meta.downloadUrl,\n\t\t\tuploadedBy: file.meta.uploadedBy,\n\t\t\tcreatedAt: file.meta.createdAt,\n\t\t\tfinalizedAt: file.meta.finalizedAt,\n\t\t\tcompletedAt: file.meta.completedAt,\n\t\t\ttenantId: file.meta.tenantId,\n\t\t\ttype: file.meta.type,\n\t\t\tuploadedByInfo: file.meta.uploadedByInfo,\n\t\t\tprogress: file.progress,\n\t\t\tuploadMetadataId: file.meta.uploadMetadataId,\n\t\t\terror: file.error,\n\t\t}));\n\t}, [state.files]);\n\n\treturn {\n\t\tinfo: state.info,\n\t\terror: state.error,\n\t\tfiles,\n\t\taddFiles,\n\t\tremoveFile,\n\t};\n};\n","import { useEffect, RefObject } from 'react';\n\nexport const useClickOutside = <T extends HTMLElement>(\n\telementRef: RefObject<T>,\n\tcallback: () => void,\n): void => {\n\tuseEffect(() => {\n\t\tconst handleClickOutside = (event: MouseEvent): void => {\n\t\t\tif (\n\t\t\t\telementRef &&\n\t\t\t\telementRef.current &&\n\t\t\t\t!elementRef.current.contains(event.target as Node)\n\t\t\t) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t};\n\n\t\tdocument.addEventListener('click', handleClickOutside, true);\n\n\t\treturn () => {\n\t\t\tdocument.removeEventListener('click', handleClickOutside, true);\n\t\t};\n\t}, [elementRef, callback]);\n};\n"],"mappings":";;;;;;AAoBO,IAAM,aAA0B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAwBO,IAAM,mBAA8B;AAAA,EAC1C,SAAS,CAAC;AAAA,EACV,OAAO;AAAA,EACP,OAAO,CAAC;AAAA,EACR,gBAAgB,CAAC;AAAA,EACjB,gBAAgB;AAAA,EAChB,cAAc;AAAA,IACb,gBAAgB;AAAA,IAChB,wBAAwB;AAAA,IACxB,kBAAkB;AAAA,EACnB;AAAA,EACA,eAAe;AAAA,EACf,MAAM,CAAC;AAAA,EACP,MAAM,CAAC;AAAA,EACP,gBAAgB;AACjB;AAEO,IAAM,sBAA8B,KAAK,KAAK,IAAI,MAAM,CAAC;AAOzD,IAAM,oBAAuC;AAAA,EACnD,wBACC;AACF;;;ACpDO,IAAM,MAAM;AAAA,EAClB,cAAc,CACb,MACA,YACgC;AAChC,UAAM,iBAAiB;AAAA,MACtB,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,QAAQ,SAAS;AAAA,IAClB;AAEA,WAAO,eAAe,8BAA8B,cAAc;AAAA,EACnE;AAAA,EAEA,gBAAgB,CAAC,OAAgD;AAChE,UAAM,iBAAiB;AAAA,MACtB,QAAQ;AAAA,IACT;AAEA,WAAO;AAAA,MACN,8BAA8B,EAAE;AAAA,MAChC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,gBAAgB,CAAC,OAAgC;AAChD,WAAO,eAAe,iDAAiD,EAAE,EAAE;AAAA,EAC5E;AAAA,EAEA,sBAAsB,CACrB,OACoD;AACpD,WAAO,eAAe,uBAAuB,EAAE,EAAE;AAAA,EAClD;AACD;;;ACzEA,SAAS,MAAM,cAAc;AAC7B,OAAO,UAAU;AACjB,OAAO,WAAW;AAClB,SAAS,aAAa;AAkDf,IAAM,cAAN,MAAkB;AAAA,EAChB,YAA+B,oBAAI,IAAI;AAAA,EACvC,aAAqB;AAAA,EACrB,iBAAqC;AAAA,IAC5C,aAAa;AAAA,IACb,cAAc;AAAA,MACb,aAAa;AAAA,MACb,kBAAkB;AAAA,MAClB,kBAAkB;AAAA,IACnB;AAAA,EACD;AAAA,EAEA,YAAY,IAAyB;AACpC,WAAO,KAAK,UAAU,IAAI,EAAE,KAAK;AAAA,EAClC;AAAA,EAEA,SAAS,SAAmC;AAC3C,UAAM,KAAa,OAAO;AAE1B,UAAM,sBACL,CAAC,eACD,OACC,MACA,aAMK;AACL,YAAM,WAA8B,MAAM,IAAI;AAAA,QAC7C;AAAA,UACC,UAAU,KAAK;AAAA,UACf,UAAU,KAAK;AAAA,QAChB;AAAA,QACA;AAAA,MACD;AAEA,YAAMA,YAAW,KAAK,YAAY,UAAU;AAC5C,UAAIA,WAAU;AAEb,QAAAA,UAAS,YAAY,KAAK,IAAI,QAAQ;AAAA,MACvC;AAEA,aAAO;AAAA,QACN,QAAQ;AAAA,QACR,KAAK,SAAS;AAAA,QACd,QAAQ,CAAC;AAAA,QACT,SAAS;AAAA,UACR,gBAAgB,KAAK;AAAA,QACtB;AAAA,MACD;AAAA,IACD;AAED,UAAM,WAAiB,IAAI,KAAK,KAAK,YAAY,IAAI,OAAO,CAAC,EAAE,IAAI,OAAO;AAAA;AAAA,MAEzE,qBAAqB,oBAAoB,EAAE;AAAA,IAC5C,CAAC;AAED,WAAO,eAAe,UAAU,MAAM,EAAE,OAAO,IAAI,YAAY,KAAK,CAAC;AAErE,SAAK,UAAU,IAAI,IAAI,QAAQ;AAE/B,SAAK,mBAAmB,EAAE;AAE1B,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,IAAkB;AACzB,UAAM,WAAW,KAAK,YAAY,EAAE;AAEpC,cAAU,MAAM,MAAM,KAAK,UAAU,OAAO,EAAE,CAAC;AAAA,EAChD;AAAA,EAEA,WACC,IAEA,eACO;AACP,UAAM,OAAO,KAAK,YAAY,EAAE;AAChC,QAAI,MAAM;AACT,iBAAW,QAAQ,CAAC,UAAqB;AACxC,aAAK;AAAA;AAAA,UAEJ;AAAA;AAAA,UAEA,IAAI,SAAgB;AACnB,0BAAc,OAAO,GAAG,IAAI;AAAA,UAC7B;AAAA,QACD;AAAA,MACD,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,mBAAmB,YAA0B;AAC5C,UAAM,WAAW,KAAK,YAAY,UAAU;AAC5C,QAAI,UAAU;AAEb,eAAS,GAAG,kBAAkB,OAAO,SAAmB;AACvD,cAAM,KAAK,mBAAmB,YAAY,IAAI;AAAA,MAC/C,CAAC;AAAA,IACF;AAAA,EACD;AAAA,EAEA,YACC,IACA,SACsD;AACtD,WAAO;AAAA,MACN,GAAG,MAAM,KAAK,gBAAgB,OAAO;AAAA,MACrC;AAAA,MACA,OAAO;AAAA,IACR;AAAA,EACD;AAAA,EAEA,MAAM,mBAAmB,YAAoB,MAA+B;AAC3E,UAAM,WAAW,KAAK,YAAY,UAAU;AAC5C,QAAI,CAAC,SAAU;AAEf,QAAI;AACH,YAAM,oBAA4C,MAAM,IAAI;AAAA,QAC3D,KAAK,KAAK;AAAA,MACX;AACA,eAAS,YAAY,KAAK,IAAI,iBAAiB;AAE/C,eAAS,KAAK,YAAY,iBAAiB;AAE3C,WAAK,gBAAgB,YAAY,KAAK,EAAE;AACxC,WAAK,4BAA4B,YAAY,KAAK,EAAE;AAAA,IACrD,SAAS,OAAO;AAEf,eAAS,KAAK,gBAAgB,MAAM,KAAK;AAAA,IAC1C;AAAA,EACD;AAAA,EAEA,MAAM,gBAAgB,YAAoB,QAA+B;AACxE,UAAM,WAAW,KAAK,YAAY,UAAU;AAC5C,QAAI,CAAC,SAAU;AAEf,QAAI;AACH,YAAM,OAAO,SAAS,QAAQ,MAAM;AACpC,UAAI,CAAC,KAAM;AAEX,YAAM,cAAsB,MAAM,IAAI;AAAA,QACrC,KAAK,KAAK;AAAA,MACX;AAEA,UAAI,OAAO,gBAAgB,UAAU;AACpC,iBAAS,YAAY,QAAQ,EAAE,YAAY,CAAC;AAAA,MAC7C,OAAO;AACN,iBAAS,KAAK,SAAS,WAAW;AAAA,MACnC;AAEA,eAAS,KAAK,YAAY,EAAE,YAAY,CAAC;AAAA,IAE1C,SAAS,OAAY;AACpB,eAAS,KAAK,SAAS,KAAK;AAAA,IAC7B;AAAA,EACD;AAAA,EAEA,MAAM,4BACL,YACA,QACgB;AAChB,UAAM,WAAW,KAAK,YAAY,UAAU;AAC5C,QAAI,CAAC,SAAU;AAEf,QAAI;AACH,YAAM,OAAO,SAAS,QAAQ,MAAM;AACpC,UAAI,CAAC,KAAM;AAEX,YAAM,WACL,MAAM,IAAI,qBAAqB,KAAK,KAAK,UAAoB;AAE9D,UAAI,eAAe,UAAU;AAC5B,iBAAS,YAAY,QAAQ;AAAA,UAC5B,gBAAgB;AAAA,YACf,WAAW,SAAS;AAAA,YACpB,UAAU,SAAS;AAAA,UACpB;AAAA,QACD,CAAC;AAAA,MACF,OAAO;AAEN,iBAAS,KAAK,SAAS,QAAe;AAAA,MACvC;AAEA,eAAS,KAAK,YAAY,CAAC,CAAC;AAAA,IAE7B,SAAS,OAAY;AACpB,eAAS,KAAK,SAAS,KAAK;AAAA,IAC7B;AAAA,EACD;AACD;;;ACrPA,OAAO,WAAW;AAClB,SAAS,SAAAC,cAAa;AACtB,SAAS,qBAAqB;AAmG9B,IAAM,cAAc,IAAI,YAAY;AAEpC,IAAM;AAAA;AAAA,EAEJ,OAAe,YAAY,WAC3B,MAAM;AACN,YAAQ;AAAA,MACP;AAAA,IACD;AAAA,EACD;AAAA;AAED,IAAM,gCAAwD;AAAA,EAC7D,YAAY,CAAC;AAAA,EACb,SAAS;AAAA,IACR,cAAc;AAAA,MACb,aAAa;AAAA,IACd;AAAA,EACD;AACD;AAEO,IAAM,kBAAkB,CAC9B,YAAoC,kCAChC;AACJ,QAAM,QAAQC,OAAM,CAAC,GAAG,WAAW,6BAA6B;AAChE,QAAM,eAAe,MAAM,OAAqB,CAAC,CAAiB;AAClE,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAoB,gBAAgB;AAEpE,QAAM,aAAa,MAAM;AAAA,IACxB,MAAMA,OAAM,CAAC,GAAG,mBAAmB,MAAM,YAAY,gBAAgB;AAAA,IACrE,CAAC,MAAM,YAAY,gBAAgB;AAAA,EACpC;AAGA,QAAM,UAAU,CAAC,UAAe;AAC/B,QAAI,WAAW,UAAU,eAAe,GAAG;AAC1C,gBAAU,gBAAgB,KAAK;AAAA,IAChC;AAAA,EACD;AAGA,QAAM,cAAc,CAAC,cAAsB,SAAgB;AAC1D,YAAQ,WAAW;AAAA,MAClB,KAAK,SAAS;AACb,cAAM,CAAC,KAAK,IAAI;AAChB,YAAI,MAAM,YAAY,gBAAgB;AACrC,iBAAO,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC;AACvC,kBAAQ,KAAK;AAAA,QACd;AACA;AAAA,MACD;AAAA,MACA,KAAK,sBAAsB;AAC1B,cAAM,CAAC,EAAE,KAAK,IAAI;AAClB,eAAO,MAAM,SAAS,EAAE,MAAM,QAAQ,CAAC;AACvC,gBAAQ,KAAK;AACb;AAAA,MACD;AAAA,MACA;AACC;AAAA,IACF;AAAA,EACD;AAEA,QAAM,UAAU,MAAM;AACrB,UAAM,cAAc;AAAA,MACnB,GAAI,MAAM,WAAW,CAAC;AAAA,MACtB,QAAQ;AAAA,QACP,SAAS;AAAA,MACV;AAAA,IACD;AAGA,iBAAa,UAAU,YAAY,SAAS,WAAW;AAEvD,gBAAY;AAAA,MACX,aAAa,QAAQ;AAAA;AAAA,MAErB,CAAC,cAAsB,SAAgB;AACtC,cAAM,WAAW,aAAa,QAAQ,SAAS;AAC/C,iBAAS,QAAQ;AACjB,qBAAa,QAAQ,IAAI,sCAAsC,SAAS,EAAE;AAC1E,qBAAa,QAAQ,IAAI,QAAQ;AAEjC,oBAAY,WAAW,GAAG,IAAI;AAAA,MAC/B;AAAA,IACD;AAEA,WAAO,MAAM;AACZ,kBAAY,QAAQ,aAAa,QAAQ,EAAE;AAAA,IAC5C;AAAA,EAED,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,CAChBC,QACA,mBACA,qBAII;AACJ,UAAM,wBAKD,CAAC;AACN,UAAM,cAKD,CAAC;AACN,UAAM,wBAAgC,CAAC;AACvC,UAAM,kBAA0B,CAAC;AAEjC,UAAM,EAAE,cAAc,oBAAoB,IAAI,OAAO,SAAS,gBAAgB,CAAC;AAE/E,eAAW,QAAQA,QAAO;AACzB,YAAM,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE,QAAQ,IAAI,CAAC,GAAG,YAAY;AAC7D,YAAM,aAAa;AAAA,QAClB,QAAQ,aAAa,QAAQ;AAAA,QAC7B,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,MAAM;AAAA,MACP;AAEA,UAAI,QAAQ,OAAO;AAClB,8BAAsB,KAAK,IAAI;AAC/B,qBAAa,QAAQ;AAAA,UACpB;AAAA,UACA;AAAA,UACA,IAAI;AAAA,YACH;AAAA,UACD;AAAA,QACD;AAAA,MACD,WAAW,eAAe,KAAK,QAAQ,QAAQ,KAAK,OAAO,aAAa;AACvE,wBAAgB,KAAK,IAAI;AACzB,8BAAsB,KAAK,UAAU;AAAA,MACtC,OAAO;AACN,oBAAY,KAAK,UAAU;AAAA,MAC5B;AAAA,IACD;AAEA,QAAI,WAAW,gBAAgB,GAAG;AACjC,uBAAiB,uBAAuB,eAAe;AAAA,IACxD;AAEA,QAAIA,OAAM,WAAW,KAAK,sBAAsB,WAAW,GAAG;AAC7D,mBAAa,QAAQ;AAAA,QACpB;AAAA,QACA,sBAAsB,CAAC;AAAA,QACvB,IAAI;AAAA,UACH,iCAAiC,cAAc,WAAW,CAAC;AAAA,QAC5D;AAAA,MACD;AAAA,IACD,WAAWA,OAAM,SAAS,KAAK,sBAAsB,UAAU,GAAG;AACjE,mBAAa,QAAQ;AAAA,QACpB;AAAA,QACA;AAAA,QACA,IAAI;AAAA,UACH,GAAG,gBAAgB,MAAM,WACxBA,OAAM,MACP,8BAA8B,cAAc,WAAW,CAAC;AAAA,QACzD;AAAA,MACD;AAAA,IACD;AAEA,QAAI;AACH,UAAI,YAAY,SAAS,GAAG;AAC3B,qBAAa,QAAQ,SAAS,WAAW;AAAA,MAC1C;AAEA,UAAI,WAAW,iBAAiB,GAAG;AAClC,cAAM,gBAAgBA,OAAM;AAAA,UAAO,CAAC,MACnC,YAAY,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI;AAAA,QAC1C;AACA,0BAAkB,aAAa;AAAA,MAChC;AAAA,IACD,SAAS,KAAK;AACb,mBAAa,QAAQ,IAAI,GAAG;AAC5B,cAAQ,GAAG;AAAA,IACZ;AAAA,EACD;AAEA,QAAM,aAAa,CAAC,MAAkB,QAAgB,UAAkB;AACvE,QAAI,KAAK,QAAQ;AAChB,mBAAa,QAAQ,WAAW,KAAK,QAAQ,QAAQ,KAAK;AAAA,IAC3D;AAAA,EACD;AAEA,QAAM,QAAQ,MAAM,QAAQ,MAAM;AACjC,WAAO,OAAO,QAAQ,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,OAAO;AAAA,MACrD,QAAQ,KAAK;AAAA,MACb,IAAI,KAAK,KAAK;AAAA,MACd,MAAM,KAAK;AAAA,MACX,MAAM,OAAO,KAAK,IAAI;AAAA,MACtB,aAAa,KAAK,KAAK;AAAA,MACvB,YAAY,KAAK,KAAK;AAAA,MACtB,WAAW,KAAK,KAAK;AAAA,MACrB,aAAa,KAAK,KAAK;AAAA,MACvB,aAAa,KAAK,KAAK;AAAA,MACvB,UAAU,KAAK,KAAK;AAAA,MACpB,MAAM,KAAK,KAAK;AAAA,MAChB,gBAAgB,KAAK,KAAK;AAAA,MAC1B,UAAU,KAAK;AAAA,MACf,kBAAkB,KAAK,KAAK;AAAA,MAC5B,OAAO,KAAK;AAAA,IACb,EAAE;AAAA,EACH,GAAG,CAAC,MAAM,KAAK,CAAC;AAEhB,SAAO;AAAA,IACN,MAAM,MAAM;AAAA,IACZ,OAAO,MAAM;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACD;;;AC7TA,SAAS,iBAA4B;AAE9B,IAAM,kBAAkB,CAC9B,YACA,aACU;AACV,YAAU,MAAM;AACf,UAAM,qBAAqB,CAAC,UAA4B;AACvD,UACC,cACA,WAAW,WACX,CAAC,WAAW,QAAQ,SAAS,MAAM,MAAc,GAChD;AACD,iBAAS;AAAA,MACV;AAAA,IACD;AAEA,aAAS,iBAAiB,SAAS,oBAAoB,IAAI;AAE3D,WAAO,MAAM;AACZ,eAAS,oBAAoB,SAAS,oBAAoB,IAAI;AAAA,IAC/D;AAAA,EACD,GAAG,CAAC,YAAY,QAAQ,CAAC;AAC1B;","names":["instance","merge","merge","files"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../packages/services/upload-s3/UploadService.ts"],"sourcesContent":["import pLimit from 'p-limit';\n\nexport class UploadError extends Error {\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tcause: any;\n\n\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\tconstructor(message: string, e?: any) {\n\t\tsuper(message);\n\t\tthis.name = 'UploadError';\n\t\tthis.cause = e;\n\t\tthis.stack = e?.stack;\n\t}\n}\n\ntype SimpleUploadData = {\n\tpreSignedUrl: string;\n\tuploadMetadataId: string;\n};\n\ntype UploadData = {\n\tuploadMetadataId: string;\n\tuploadUrls: string[];\n\tuploadId?: string;\n};\n\ntype ETag = {\n\tpartNumber: number;\n\tetagId: string;\n};\n\nexport type UploadMetadataResource = {\n\tid: string;\n\ttenantId: string;\n\tfileName: string;\n\tcreatedAt: Date;\n\tfinalizedAt: Date;\n\tcompletedAt: Date;\n\tuploadedBy: string;\n\tfileSize: number;\n};\n\nexport type ProgressState = {\n\tstatus:\n\t\t| 'ready'\n\t\t| 'preparing'\n\t\t| 'uploading'\n\t\t| 'finalizing'\n\t\t| 'completed'\n\t\t| 'error'\n\t\t| 'cancelled';\n\tuploaded: number;\n\ttotalSize: number;\n\terror?: UploadError;\n};\n\nexport type IUploadService = {\n\tupload: (\n\t\tfile: File,\n\t\tonProgress: (progress: ProgressState) => void,\n\t) => Promise<UploadMetadataResource>;\n\tdownloadUrl: (fileId: string) => Promise<string>;\n\tdownload: (fileId: string, fileName: string) => Promise<void>;\n};\n\nconst DefaultProps = {\n\tshouldUseMultipart: (fileSize: number) => fileSize > 10 * 2 ** 20,\n\tmaxConcurrentUploads: 5,\n\trequest: fetch,\n};\n\nexport type UploadServiceProps = Partial<typeof DefaultProps>;\n\nconst throwIfFalse = (condition: boolean, message: string) => {\n\tif (!condition) {\n\t\tthrow new UploadError(message);\n\t}\n};\n\nexport const createUploadService = (props?: UploadServiceProps): IUploadService => {\n\tconst options = { ...DefaultProps, ...(props || {}) };\n\n\tconst limit = pLimit(options.maxConcurrentUploads);\n\tconst calcNumberOfParts = (fileSize: number) =>\n\t\tMath.floor(fileSize / (5 * 2 ** 20));\n\n\tconst createMultipartPresignedUrls = async (\n\t\tfileName: string,\n\t\tfileSize: number,\n\t): Promise<UploadData> => {\n\t\tconst numberOfParts = calcNumberOfParts(fileSize);\n\n\t\tconst response = await options.request('/api/v2/attachments/multipart/upload', {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ fileName, fileSize, numberOfParts }),\n\t\t});\n\n\t\treturn await response.json();\n\t};\n\n\tconst downloadUrl = async (fileId: string): Promise<string> => {\n\t\tconst response = await options.request(\n\t\t\t`/api/v2/attachments/download?uploadMetadataId=${fileId}`,\n\t\t);\n\n\t\treturn response.json();\n\t};\n\n\tconst download = async (fileId: string, fileName: string): Promise<void> => {\n\t\tconst url = await downloadUrl(fileId);\n\t\tconst link = document.createElement('a');\n\t\tlink.href = url;\n\t\tlink.download = fileName;\n\t\tlink.click();\n\t};\n\n\tconst createSinglePresignedUrl = async (\n\t\tfileName: string,\n\t\tfileSize: number,\n\t): Promise<SimpleUploadData> => {\n\t\tconst response = await options.request('/api/v2/attachments/upload', {\n\t\t\tmethod: 'POST',\n\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\tbody: JSON.stringify({ fileName, fileSize }),\n\t\t});\n\n\t\treturn await response.json();\n\t};\n\n\tconst preparePart = (blob: Blob, partNumber: number, partSize: number): Blob => {\n\t\tconst start = (partNumber - 1) * partSize;\n\t\tconst end = Math.min(start + partSize, blob.size);\n\n\t\treturn blob.slice(start, end);\n\t};\n\n\tconst uploadPart = async (uploadUrl: string, part: Blob) => {\n\t\tconst response = await fetch(uploadUrl, {\n\t\t\tmethod: 'PUT',\n\t\t\theaders: {\n\t\t\t\t'Content-Type': 'application/octet-stream',\n\t\t\t},\n\t\t\tbody: part,\n\t\t});\n\n\t\treturn response.headers.get('ETag');\n\t};\n\n\tconst completeUpload = async (\n\t\tuploadData: UploadData,\n\t\teTags: ETag[],\n\t): Promise<UploadMetadataResource> => {\n\t\tconst handle = async (response: Response) => {\n\t\t\tconst obj = await response.json();\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow new UploadError(obj?.message || 'Unknown error occured');\n\t\t\t}\n\n\t\t\treturn obj;\n\t\t};\n\n\t\tif (eTags && eTags.length > 1) {\n\t\t\tconst response = await options.request(\n\t\t\t\t`/api/v2/attachments/multipart/upload/${uploadData.uploadMetadataId}/complete`,\n\t\t\t\t{\n\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\theaders: { 'Content-Type': 'application/json' },\n\t\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t\tuploadId: uploadData.uploadId,\n\t\t\t\t\t\tetags: eTags,\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t);\n\n\t\t\treturn await handle(response);\n\t\t}\n\t\tconst response = await options.request(\n\t\t\t`/api/v2/attachments/upload/${uploadData.uploadMetadataId}/complete`,\n\t\t\t{\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t);\n\n\t\treturn await handle(response);\n\t};\n\n\tconst createPresignedUrls = async (file: File): Promise<UploadData> => {\n\t\tif (options.shouldUseMultipart(file.size)) {\n\t\t\treturn await createMultipartPresignedUrls(file.name, file.size);\n\t\t}\n\t\tconst data = await createSinglePresignedUrl(file.name, file.size);\n\n\t\treturn {\n\t\t\tuploadMetadataId: data.uploadMetadataId,\n\t\t\tuploadUrls: [data.preSignedUrl],\n\t\t};\n\t};\n\n\tconst createState = <T>(\n\t\tinitialState: T,\n\t\tonStateChange: (state: T) => void,\n\t): [T, (s: Partial<T>) => void] => {\n\t\tconst state = {};\n\n\t\tconst setState = (newState: Partial<T>): void => {\n\t\t\tObject.assign(state, newState);\n\t\t\tonStateChange({ ...(state as T) });\n\t\t};\n\n\t\tsetState(initialState); // initial state\n\n\t\treturn [state as T, setState];\n\t};\n\n\tconst uploadFile = async (\n\t\tfile: File,\n\t\tonProgress: (progress: ProgressState) => void,\n\t): Promise<UploadMetadataResource> => {\n\t\tconst initialState: ProgressState = {\n\t\t\tuploaded: 0,\n\t\t\ttotalSize: file.size,\n\t\t\tstatus: 'ready',\n\t\t};\n\t\tconst [state, setState] = createState(initialState, onProgress);\n\n\t\tsetState({ status: 'preparing' });\n\n\t\ttry {\n\t\t\tconst uploadData = await createPresignedUrls(file);\n\t\t\tsetState({ status: 'uploading' });\n\n\t\t\tconst numberOfParts = uploadData.uploadUrls.length;\n\t\t\tconst partSize = Math.ceil(file.size / numberOfParts);\n\n\t\t\t// prepare parts\n\t\t\tconst queuedParts = uploadData.uploadUrls.map((uploadUrl, index) =>\n\t\t\t\tlimit(async () => {\n\t\t\t\t\tconst partNumber = index + 1;\n\t\t\t\t\tconst part = preparePart(file, partNumber, partSize);\n\t\t\t\t\tconst etagId = await uploadPart(uploadUrl, part);\n\t\t\t\t\tsetState({\n\t\t\t\t\t\tuploaded: Math.min(state.uploaded + partSize, state.totalSize),\n\t\t\t\t\t});\n\n\t\t\t\t\treturn { partNumber, etagId };\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tconst results = await Promise.all(queuedParts);\n\n\t\t\tconst parts = results.filter((x) => !!x.etagId) as ETag[];\n\n\t\t\t// complete upload\n\t\t\tconst fileMetadata = await completeUpload(uploadData, parts);\n\t\t\tsetState({ status: 'completed' });\n\n\t\t\treturn fileMetadata;\n\t\t} catch (e) {\n\t\t\tif (e instanceof UploadError) {\n\t\t\t\tsetState({ status: 'error', error: e });\n\t\t\t\tthrow e;\n\t\t\t} else {\n\t\t\t\tconst overrideErr = new UploadError(\n\t\t\t\t\t'An error occurred while uploading the file',\n\t\t\t\t\te,\n\t\t\t\t);\n\t\t\t\tsetState({ status: 'error', error: overrideErr });\n\t\t\t\tthrow overrideErr;\n\t\t\t}\n\t\t}\n\t};\n\n\tconst getFilextension = (filename: string) => {\n\t\tconst parts = filename.toLocaleLowerCase().split('.');\n\t\tif (parts.length === 1) return;\n\t\treturn parts.pop();\n\t};\n\n\tconst upload = (\n\t\tfile: File,\n\t\tonProgress: (progress: ProgressState) => void,\n\t): Promise<UploadMetadataResource> => {\n\t\tthrowIfFalse(file.name.length > 0, 'File name must not be blank');\n\t\tthrowIfFalse(file.size > 0, 'File must not be blank');\n\t\tthrowIfFalse(file.size <= 75 * 2 ** 20, 'File size must be less than 75MB');\n\t\tthrowIfFalse(\n\t\t\tgetFilextension(file.name) !== 'exe',\n\t\t\t'Attachments with filetype .exe cannot be accepted. Please try a different file type.',\n\t\t);\n\n\t\treturn uploadFile(file, onProgress);\n\t};\n\n\treturn {\n\t\tdownloadUrl,\n\t\tdownload,\n\t\tupload,\n\t};\n};\n\nexport const UploadService = createUploadService({\n\trequest: (url, options) => {\n\t\tconst storedToken = localStorage?.getItem('fk_accessToken');\n\n\t\tconst opt = { headers: {}, ...(options ?? {}) };\n\n\t\treturn fetch(url, {\n\t\t\t...opt,\n\t\t\theaders: {\n\t\t\t\t...opt.headers,\n\t\t\t\tAuthorization: `Bearer ${storedToken}`,\n\t\t\t},\n\t\t});\n\t},\n});\n\nexport default UploadService;\n"],"mappings":"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","names":["response"]}
|