@contember/bindx-uploader 0.1.49 → 0.1.51
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/components/MultiUploader.d.ts +3 -3
- package/dist/components/MultiUploader.d.ts.map +1 -1
- package/dist/components/Uploader.d.ts +26 -5
- package/dist/components/Uploader.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/internal/hooks/index.d.ts +2 -2
- package/dist/internal/hooks/index.d.ts.map +1 -1
- package/dist/internal/hooks/useFillEntity.d.ts +13 -4
- package/dist/internal/hooks/useFillEntity.d.ts.map +1 -1
- package/dist/internal/hooks/useUploadState.d.ts +1 -1
- package/dist/internal/hooks/useUploadState.d.ts.map +1 -1
- package/dist/internal/hooks/useUploaderDoUpload.d.ts +8 -1
- package/dist/internal/hooks/useUploaderDoUpload.d.ts.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/uploadClient/S3UploadClient.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/components/MultiUploader.tsx +7 -15
- package/src/components/Uploader.tsx +33 -14
- package/src/index.ts +3 -0
- package/src/internal/hooks/index.ts +2 -2
- package/src/internal/hooks/useFillEntity.ts +36 -12
- package/src/internal/hooks/useUploadState.ts +1 -1
- package/src/internal/hooks/useUploaderDoUpload.ts +24 -1
- package/src/types.ts +11 -0
- package/src/uploadClient/S3UploadClient.ts +7 -0
- package/src/utils/urlSigner.ts +17 -48
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import type { HasManyRef } from '@contember/bindx';
|
|
3
3
|
import { BINDX_COMPONENT, type SelectionProvider } from '@contember/bindx-react';
|
|
4
|
-
import type { FileType } from '../types.js';
|
|
5
|
-
export interface MultiUploaderProps<TEntity = Record<string, unknown>> {
|
|
4
|
+
import type { FileType, UploaderEvents } from '../types.js';
|
|
5
|
+
export interface MultiUploaderProps<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
6
6
|
/**
|
|
7
7
|
* The has-many relation to add uploaded files to.
|
|
8
8
|
*/
|
|
@@ -35,7 +35,7 @@ export interface MultiUploaderProps<TEntity = Record<string, unknown>> {
|
|
|
35
35
|
* </MultiUploader>
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
|
-
export declare function MultiUploader<TEntity extends Record<string, unknown>>({ field, fileType, children, }: MultiUploaderProps<TEntity>): ReactNode;
|
|
38
|
+
export declare function MultiUploader<TEntity extends Record<string, unknown>>({ field, fileType, children, ...events }: MultiUploaderProps<TEntity>): ReactNode;
|
|
39
39
|
declare const multiUploaderWithSelection: typeof MultiUploader & SelectionProvider & {
|
|
40
40
|
[BINDX_COMPONENT]: true;
|
|
41
41
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiUploader.d.ts","sourceRoot":"","sources":["../../src/components/MultiUploader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAa,UAAU,EAAqC,MAAM,kBAAkB,CAAA;AAEhG,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAoC,MAAM,wBAAwB,CAAA;AAClH,OAAO,KAAK,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"MultiUploader.d.ts","sourceRoot":"","sources":["../../src/components/MultiUploader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAgC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACpE,OAAO,KAAK,EAAa,UAAU,EAAqC,MAAM,kBAAkB,CAAA;AAEhG,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAoC,MAAM,wBAAwB,CAAA;AAClH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAa3D,MAAM,WAAW,kBAAkB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,OAAO,CAAC,cAAc,CAAC;IACrG;;OAEG;IACH,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC1B;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC3B;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACtE,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,GAAG,MAAM,EACT,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,SAAS,CAwFzC;AA+BD,QAAA,MAAM,0BAA0B,EAAoB,OAAO,aAAa,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AA2B1H,OAAO,EAAE,0BAA0B,IAAI,qBAAqB,EAAE,CAAA"}
|
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
|
-
import type { EntityRef, HasOneRef } from '@contember/bindx';
|
|
3
2
|
import { BINDX_COMPONENT, type SelectionProvider } from '@contember/bindx-react';
|
|
4
|
-
import type { FileType } from '../types.js';
|
|
5
|
-
export interface UploaderProps<TEntity = Record<string, unknown>> {
|
|
3
|
+
import type { FileType, PrepareUploadTarget, UploaderEvents, UploaderFillTarget } from '../types.js';
|
|
4
|
+
export interface UploaderProps<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
6
5
|
/**
|
|
7
6
|
* The entity to fill with uploaded file data.
|
|
8
7
|
* Can be an EntityRef or HasOneRef.
|
|
9
8
|
*/
|
|
10
|
-
entity:
|
|
9
|
+
entity: UploaderFillTarget<TEntity>;
|
|
11
10
|
/**
|
|
12
11
|
* File type configuration defining accepted files and extractors.
|
|
13
12
|
* Must be created with the same entity type as the entity prop.
|
|
14
13
|
*/
|
|
15
14
|
fileType: FileType<TEntity>;
|
|
15
|
+
/**
|
|
16
|
+
* Resolves the target of an upload batch: it runs once, after the files pass the accept
|
|
17
|
+
* check and before the uploader disconnects or fills anything, and receives the accepted
|
|
18
|
+
* files. A rejected batch never reaches it. Return another target to fork first
|
|
19
|
+
* (copy-on-write); returning nothing keeps the entity prop.
|
|
20
|
+
*/
|
|
21
|
+
prepareTarget?: PrepareUploadTarget<UploaderFillTarget<TEntity>>;
|
|
16
22
|
/**
|
|
17
23
|
* Children to render within the uploader context.
|
|
18
24
|
*/
|
|
@@ -49,8 +55,23 @@ export interface UploaderProps<TEntity = Record<string, unknown>> {
|
|
|
49
55
|
* </UploaderEachFile>
|
|
50
56
|
* </Uploader>
|
|
51
57
|
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Copy-on-write: fork a shared asset so the upload lands on a fresh one
|
|
60
|
+
* ```tsx
|
|
61
|
+
* <Uploader
|
|
62
|
+
* entity={block.asset.image}
|
|
63
|
+
* fileType={imageFileType}
|
|
64
|
+
* prepareTarget={() => {
|
|
65
|
+
* block.asset.$disconnect()
|
|
66
|
+
* block.asset.$create()
|
|
67
|
+
* return block.asset.image
|
|
68
|
+
* }}
|
|
69
|
+
* >
|
|
70
|
+
* <DropZone />
|
|
71
|
+
* </Uploader>
|
|
72
|
+
* ```
|
|
52
73
|
*/
|
|
53
|
-
export declare function Uploader<TEntity extends Record<string, unknown>>({ entity, fileType, children, }: UploaderProps<TEntity>): ReactNode;
|
|
74
|
+
export declare function Uploader<TEntity extends Record<string, unknown>>({ entity, fileType, prepareTarget, children, ...events }: UploaderProps<TEntity>): ReactNode;
|
|
54
75
|
declare const uploaderWithSelection: typeof Uploader & SelectionProvider & {
|
|
55
76
|
[BINDX_COMPONENT]: true;
|
|
56
77
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Uploader.d.ts","sourceRoot":"","sources":["../../src/components/Uploader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"Uploader.d.ts","sourceRoot":"","sources":["../../src/components/Uploader.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG/C,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAwB,MAAM,wBAAwB,CAAA;AACtG,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAWpG,MAAM,WAAW,aAAa,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,OAAO,CAAC,cAAc,CAAC;IAChG;;;OAGG;IACH,MAAM,EAAE,kBAAkB,CAAC,OAAO,CAAC,CAAA;IACnC;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAA;IAChE;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,QAAQ,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EACjE,MAAM,EACN,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,GAAG,MAAM,EACT,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,SAAS,CA6BpC;AAsCD,QAAA,MAAM,qBAAqB,EAAe,OAAO,QAAQ,GAAG,iBAAiB,GAAG;IAAE,CAAC,eAAe,CAAC,EAAE,IAAI,CAAA;CAAE,CAAA;AAiC3G,OAAO,EAAE,qBAAqB,IAAI,gBAAgB,EAAE,CAAA"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { UploadClient, FileUploadResult, FileUploadProgress, UploadClientUploadArgs, FileWithMeta, UploaderFileState, UploaderFileStateInitial, UploaderFileStateUploading, UploaderFileStateFinalizing, UploaderFileStateSuccess, UploaderFileStateError, UploaderState, BeforeUploadEvent, StartUploadEvent, ProgressEvent, SuccessEvent, AfterUploadEvent, ErrorEvent, UploaderEvents, FileDataExtractor, FileDataExtractorPopulator, FileType, DiscriminatedFileType, DiscriminatedFileTypeMap, FieldName, UploaderOptions, UploaderErrorType, UploaderErrorOptions, } from './types.js';
|
|
1
|
+
export type { UploadClient, FileUploadResult, FileUploadProgress, UploadClientUploadArgs, FileWithMeta, UploaderFileState, UploaderFileStateInitial, UploaderFileStateUploading, UploaderFileStateFinalizing, UploaderFileStateSuccess, UploaderFileStateError, UploaderState, BeforeUploadEvent, StartUploadEvent, ProgressEvent, SuccessEvent, AfterUploadEvent, ErrorEvent, UploaderEvents, UploaderFillTarget, PrepareUploadTarget, FileDataExtractor, FileDataExtractorPopulator, FileType, DiscriminatedFileType, DiscriminatedFileTypeMap, FieldName, UploaderOptions, UploaderErrorType, UploaderErrorOptions, } from './types.js';
|
|
2
2
|
export { UploaderError } from './UploaderError.js';
|
|
3
3
|
export { UploaderUploadFilesContext, useUploaderUploadFiles, UploaderStateContext, useUploaderState, UploaderOptionsContext, useUploaderOptions, UploaderFileStateContext, useUploaderFileState, UploaderClientContext, useUploaderClient, UploaderDropzoneStateContext, useUploaderDropzoneState, } from './contexts.js';
|
|
4
4
|
export { S3UploadClient, type S3UploadClientOptions, type S3FileOptions, type S3Acl, type S3FileParameters, type S3SignedUrlResponse, type S3UrlSigner, } from './uploadClient/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAEX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EAEtB,YAAY,EAEZ,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,aAAa,EAEb,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,cAAc,EAEd,iBAAiB,EACjB,0BAA0B,EAE1B,QAAQ,EACR,qBAAqB,EACrB,wBAAwB,EAExB,SAAS,EAET,eAAe,EAEf,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,EACN,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,wBAAwB,GACxB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACN,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GAChB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,wBAAwB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGvF,OAAO,EACN,uBAAuB,EACvB,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,iCAAiC,EACtC,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,yBAAyB,EACzB,KAAK,2BAA2B,GAChC,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACN,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,sBAAsB,GAC3B,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACN,qBAAqB,EACrB,KAAK,WAAW,EAChB,WAAW,GACX,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACN,QAAQ,EACR,gBAAgB,EAChB,KAAK,aAAa,EAClB,aAAa,EACb,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,eAAe,EACf,KAAK,oBAAoB,EACzB,uBAAuB,EACvB,KAAK,4BAA4B,EACjC,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,oBAAoB,EACpB,KAAK,yBAAyB,GAC9B,MAAM,uBAAuB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EAEX,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,EAEtB,YAAY,EAEZ,iBAAiB,EACjB,wBAAwB,EACxB,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,sBAAsB,EACtB,aAAa,EAEb,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,cAAc,EAEd,kBAAkB,EAClB,mBAAmB,EAEnB,iBAAiB,EACjB,0BAA0B,EAE1B,QAAQ,EACR,qBAAqB,EACrB,wBAAwB,EAExB,SAAS,EAET,eAAe,EAEf,iBAAiB,EACjB,oBAAoB,GACpB,MAAM,YAAY,CAAA;AAGnB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,EACN,0BAA0B,EAC1B,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,4BAA4B,EAC5B,wBAAwB,GACxB,MAAM,eAAe,CAAA;AAGtB,OAAO,EACN,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAClB,KAAK,KAAK,EACV,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,WAAW,GAChB,MAAM,yBAAyB,CAAA;AAGhC,OAAO,EAAE,wBAAwB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAGvF,OAAO,EACN,uBAAuB,EACvB,KAAK,yBAAyB,EAC9B,+BAA+B,EAC/B,KAAK,iCAAiC,EACtC,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,yBAAyB,EACzB,KAAK,2BAA2B,GAChC,MAAM,uBAAuB,CAAA;AAG9B,OAAO,EACN,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,iBAAiB,EACjB,KAAK,sBAAsB,GAC3B,MAAM,sBAAsB,CAAA;AAG7B,OAAO,EACN,qBAAqB,EACrB,KAAK,WAAW,EAChB,WAAW,GACX,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACN,QAAQ,EACR,gBAAgB,EAChB,KAAK,aAAa,EAClB,aAAa,EACb,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,eAAe,EACf,KAAK,oBAAoB,EACzB,uBAAuB,EACvB,KAAK,4BAA4B,EACjC,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,oBAAoB,EACpB,KAAK,yBAAyB,GAC9B,MAAM,uBAAuB,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { useUploadState, type UseUploadStateResult } from './useUploadState.js';
|
|
2
|
-
export { useUploaderDoUpload } from './useUploaderDoUpload.js';
|
|
2
|
+
export { useUploaderDoUpload, type UseUploaderDoUploadArgs } from './useUploaderDoUpload.js';
|
|
3
3
|
export { useGetPreviewUrls } from './useGetPreviewUrls.js';
|
|
4
|
-
export { useFillEntity, type UseFillEntityArgs } from './useFillEntity.js';
|
|
4
|
+
export { useFillEntity, type UseFillEntityArgs, type UseFillEntityResult } from './useFillEntity.js';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC/E,OAAO,EAAE,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAC5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAA"}
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import type { EntityRef, HasOneAccessor } from '@contember/bindx';
|
|
2
|
-
import type { FileType, UploaderEvents } from '../../types.js';
|
|
3
|
-
|
|
2
|
+
import type { FileType, PrepareUploadTarget, UploaderEvents } from '../../types.js';
|
|
3
|
+
type FillTarget<TEntity> = EntityRef<TEntity> | HasOneAccessor<TEntity>;
|
|
4
|
+
export interface UseFillEntityArgs<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
4
5
|
/**
|
|
5
6
|
* The entity to fill. Can be:
|
|
6
7
|
* - EntityRef: fill the entity directly
|
|
7
8
|
* - HasOneAccessor: fill the related entity (disconnect first on upload start)
|
|
8
9
|
*/
|
|
9
|
-
entity:
|
|
10
|
+
entity: FillTarget<TEntity>;
|
|
10
11
|
fileType: FileType<TEntity>;
|
|
12
|
+
/**
|
|
13
|
+
* Resolves the target of a validated batch, before the upload disconnects or fills anything.
|
|
14
|
+
*/
|
|
15
|
+
prepareTarget?: PrepareUploadTarget<FillTarget<TEntity>>;
|
|
16
|
+
}
|
|
17
|
+
export interface UseFillEntityResult extends Partial<UploaderEvents> {
|
|
18
|
+
prepareUpload: (files: File[]) => Promise<void>;
|
|
11
19
|
}
|
|
12
20
|
/**
|
|
13
21
|
* Hook that connects upload events to entity field population.
|
|
14
22
|
* Handles both direct EntityRef and HasOneRef (for has-one relations).
|
|
15
23
|
*/
|
|
16
|
-
export declare const useFillEntity: <TEntity extends Record<string, unknown>>({ entity, fileType, ...events }: UseFillEntityArgs<TEntity>) =>
|
|
24
|
+
export declare const useFillEntity: <TEntity extends Record<string, unknown>>({ entity, fileType, prepareTarget, ...events }: UseFillEntityArgs<TEntity>) => UseFillEntityResult;
|
|
25
|
+
export {};
|
|
17
26
|
//# sourceMappingURL=useFillEntity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useFillEntity.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useFillEntity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAoB,cAAc,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"useFillEntity.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useFillEntity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAoB,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIrG,KAAK,UAAU,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;AAEvE,MAAM,WAAW,iBAAiB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,OAAO,CAAC,cAAc,CAAC;IACpG;;;;OAIG;IACH,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IAC3B,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC3B;;OAEG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;CACxD;AAED,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,cAAc,CAAC;IACnE,aAAa,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC/C;AAoBD;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,gDAKpE,iBAAiB,CAAC,OAAO,CAAC,KAAG,mBA2D/B,CAAA"}
|
|
@@ -8,5 +8,5 @@ export interface UseUploadStateResult extends UploaderEvents {
|
|
|
8
8
|
* Hook that manages the upload state machine.
|
|
9
9
|
* Tracks file states through the upload lifecycle: initial -> uploading -> finalizing -> success/error
|
|
10
10
|
*/
|
|
11
|
-
export declare const useUploadState: ({ onBeforeUpload, onStartUpload, onSuccess, onError, onProgress, onAfterUpload, }: UploaderEvents) => UseUploadStateResult;
|
|
11
|
+
export declare const useUploadState: ({ onBeforeUpload, onStartUpload, onSuccess, onError, onProgress, onAfterUpload, }: Partial<UploaderEvents>) => UseUploadStateResult;
|
|
12
12
|
//# sourceMappingURL=useUploadState.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUploadState.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useUploadState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAOX,cAAc,EAEd,aAAa,EACb,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC3D,KAAK,EAAE,aAAa,CAAA;IACpB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,mFAO5B,cAAc,KAAG,
|
|
1
|
+
{"version":3,"file":"useUploadState.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useUploadState.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAOX,cAAc,EAEd,aAAa,EACb,MAAM,gBAAgB,CAAA;AAEvB,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC3D,KAAK,EAAE,aAAa,CAAA;IACpB,UAAU,EAAE,MAAM,IAAI,CAAA;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAI,mFAO5B,OAAO,CAAC,cAAc,CAAC,KAAG,oBAgI5B,CAAA"}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
import type { UploaderEvents } from '../../types.js';
|
|
2
|
+
export interface UseUploaderDoUploadArgs extends Partial<UploaderEvents> {
|
|
3
|
+
/**
|
|
4
|
+
* Runs once per batch with the files that passed validation, before any of them is
|
|
5
|
+
* uploaded or written to the target. Skipped when no file passed.
|
|
6
|
+
*/
|
|
7
|
+
onPrepareUpload?: (files: File[]) => Promise<void> | void;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
* Hook that orchestrates the file upload process.
|
|
4
11
|
* Handles file preparation, validation, and upload execution.
|
|
5
12
|
*/
|
|
6
|
-
export declare const useUploaderDoUpload: ({ onBeforeUpload, onError, onProgress, onSuccess, onStartUpload, onAfterUpload, }:
|
|
13
|
+
export declare const useUploaderDoUpload: ({ onBeforeUpload, onError, onProgress, onSuccess, onStartUpload, onAfterUpload, onPrepareUpload, }: UseUploaderDoUploadArgs) => ((files: File[]) => Promise<void>);
|
|
7
14
|
//# sourceMappingURL=useUploaderDoUpload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUploaderDoUpload.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useUploaderDoUpload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAKlE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,
|
|
1
|
+
{"version":3,"file":"useUploaderDoUpload.d.ts","sourceRoot":"","sources":["../../../src/internal/hooks/useUploaderDoUpload.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAKlE,MAAM,WAAW,uBAAwB,SAAQ,OAAO,CAAC,cAAc,CAAC;IACvE;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CACzD;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,oGAQjC,uBAAuB,KAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CA6H7D,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityRef } from '@contember/bindx';
|
|
1
|
+
import type { EntityRef, HasOneRef } from '@contember/bindx';
|
|
2
2
|
export interface UploadClient<Options = unknown, Result extends FileUploadResult = FileUploadResult> {
|
|
3
3
|
upload: (args: UploadClientUploadArgs & Omit<Options, keyof UploadClientUploadArgs>) => Promise<Result>;
|
|
4
4
|
}
|
|
@@ -77,6 +77,15 @@ export interface ErrorEvent {
|
|
|
77
77
|
error: unknown;
|
|
78
78
|
fileType?: FileType;
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Fill target of a single-file uploader: an entity, or a has-one relation pointing at one.
|
|
82
|
+
*/
|
|
83
|
+
export type UploaderFillTarget<TEntity = Record<string, unknown>> = EntityRef<TEntity> | HasOneRef<TEntity>;
|
|
84
|
+
/**
|
|
85
|
+
* Resolves the target of an upload batch after the files pass validation and before
|
|
86
|
+
* the target is written. Returning nothing keeps the target the uploader was given.
|
|
87
|
+
*/
|
|
88
|
+
export type PrepareUploadTarget<TTarget> = (files: File[]) => TTarget | undefined | Promise<TTarget | undefined>;
|
|
80
89
|
export interface UploaderEvents {
|
|
81
90
|
onBeforeUpload: (event: BeforeUploadEvent) => Promise<FileType | undefined>;
|
|
82
91
|
onStartUpload: (event: StartUploadEvent) => void;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAwB,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAMlF,MAAM,WAAW,YAAY,CAC5B,OAAO,GAAG,OAAO,EACjB,MAAM,SAAS,gBAAgB,GAAG,gBAAgB;IAElD,MAAM,EAAE,CAAC,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,sBAAsB,CAAC,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACvG;AAED,MAAM,WAAW,gBAAgB;IAChC,SAAS,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,IAAI,CAAA;IACV,MAAM,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAA;CAClD;AAMD,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,eAAe,CAAA;CAChC;AAMD,MAAM,WAAW,wBAAwB;IACxC,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,YAAY,CAAA;CAClB;AAED,MAAM,WAAW,0BAA0B;IAC1C,KAAK,EAAE,WAAW,CAAA;IAClB,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,kBAAkB,CAAA;CAC5B;AAED,MAAM,WAAW,2BAA2B;IAC3C,KAAK,EAAE,YAAY,CAAA;IACnB,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,gBAAgB,CAAA;CACxB;AAED,MAAM,WAAW,wBAAwB;IACxC,KAAK,EAAE,SAAS,CAAA;IAChB,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,gBAAgB,CAAA;IACxB,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,IAAI,CAAA;CACnB;AAED,MAAM,MAAM,iBAAiB,GAC1B,wBAAwB,GACxB,0BAA0B,GAC1B,2BAA2B,GAC3B,wBAAwB,GACxB,sBAAsB,CAAA;AAEzB,MAAM,MAAM,aAAa,GAAG,iBAAiB,EAAE,CAAA;AAM/C,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,KAAK,CAAA;CACjC;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,YAAY,CAAA;IAClB,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,gBAAgB,CAAA;IACxB,QAAQ,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,YAAY,CAAA;IAClB,MAAM,EAAE,gBAAgB,CAAA;IACxB,QAAQ,EAAE,QAAQ,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,CAAC,EAAE,QAAQ,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;AAE3G;;;GAGG;AACH,MAAM,MAAM,mBAAmB,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAA;AAEhH,MAAM,WAAW,cAAc;IAC9B,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAA;IAC3E,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAChD,UAAU,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAA;IAC1C,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChE,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IACxC,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACpC;AAMD;;GAEG;AACH,MAAM,MAAM,SAAS,CAAC,OAAO,IAAI,MAAM,OAAO,GAAG,MAAM,CAAA;AAEvD;;GAEG;AACH,MAAM,MAAM,0BAA0B,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE;IAC3D,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;IAC1B,MAAM,EAAE,gBAAgB,CAAA;CACxB,KAAK,IAAI,CAAA;AAEV;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACnE;;;OAGG;IACH,aAAa,EAAE,MAAM,SAAS,CAAC,OAAO,CAAC,EAAE,CAAA;IAEzC;;OAEG;IACH,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,0BAA0B,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,GAAG,0BAA0B,CAAC,OAAO,CAAC,GAAG,SAAS,CAAA;IAEpJ;;OAEG;IACH,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAAC,MAAM,EAAE,gBAAgB,CAAA;KAAE,KAAK,IAAI,CAAA;CAC5F;AAMD;;GAEG;AACH,MAAM,WAAW,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,SAAS,CAAA;IAE7C;;OAEG;IACH,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAA;IAE1E;;OAEG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAA;IAEzC;;OAEG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,QAAQ,CAAC,OAAO,CAAC;IAClG;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,wBAAwB,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAA;AAMxH,MAAM,WAAW,eAAe;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACjC,QAAQ,EAAE,OAAO,CAAA;CACjB;AAMD,MAAM,MAAM,iBAAiB,GAC1B,cAAc,GACd,cAAc,GACd,WAAW,GACX,SAAS,GACT,SAAS,CAAA;AAEZ,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,iBAAiB,CAAA;IACvB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,KAAK,CAAC,EAAE,OAAO,CAAA;CACf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"S3UploadClient.d.ts","sourceRoot":"","sources":["../../src/uploadClient/S3UploadClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAuB,WAAW,EAAE,MAAM,YAAY,CAAA;AAGpF,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,WAAW,CAAA;IACpB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"S3UploadClient.d.ts","sourceRoot":"","sources":["../../src/uploadClient/S3UploadClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAuB,WAAW,EAAE,MAAM,YAAY,CAAA;AAGpF,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,WAAW,CAAA;IACpB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC5D,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAQrD,qBAAa,cAAe,YAAW,YAAY,CAAC,aAAa,CAAC;aAI9B,OAAO,EAAE,qBAAqB;IAHjE,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,aAAa,CAAwB;gBAEV,OAAO,EAAE,qBAAqB;IAEpD,MAAM,CAAC,EACnB,IAAI,EACJ,MAAM,EACN,UAAU,EACV,GAAG,OAAO,EACV,EAAE,sBAAsB,GAAG,aAAa,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;YAgB5D,gBAAgB;CAgB9B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/bindx-uploader",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.51",
|
|
4
4
|
"description": "File upload components for bindx data binding",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"react": ">=18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@contember/bindx": "0.1.
|
|
19
|
-
"@contember/bindx-react": "0.1.
|
|
20
|
-
"@contember/bindx-repeater": "0.1.
|
|
18
|
+
"@contember/bindx": "0.1.51",
|
|
19
|
+
"@contember/bindx-react": "0.1.51",
|
|
20
|
+
"@contember/bindx-repeater": "0.1.51",
|
|
21
21
|
"@radix-ui/react-slot": "^1.2.3",
|
|
22
22
|
"react-dropzone": "^14.3.8"
|
|
23
23
|
},
|
|
@@ -15,7 +15,7 @@ import { resolveAcceptingSingleType } from '../internal/utils/resolveAccept.js'
|
|
|
15
15
|
import { executeExtractors } from '../internal/utils/executeExtractors.js'
|
|
16
16
|
import { uploaderErrorHandler } from '../internal/utils/uploaderErrorHandler.js'
|
|
17
17
|
|
|
18
|
-
export interface MultiUploaderProps<TEntity = Record<string, unknown>> {
|
|
18
|
+
export interface MultiUploaderProps<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
19
19
|
/**
|
|
20
20
|
* The has-many relation to add uploaded files to.
|
|
21
21
|
*/
|
|
@@ -53,6 +53,7 @@ export function MultiUploader<TEntity extends Record<string, unknown>>({
|
|
|
53
53
|
field,
|
|
54
54
|
fileType,
|
|
55
55
|
children,
|
|
56
|
+
...events
|
|
56
57
|
}: MultiUploaderProps<TEntity>): ReactNode {
|
|
57
58
|
const fieldAccessor = useHasMany(field)
|
|
58
59
|
// Map file ID -> entity ID
|
|
@@ -71,7 +72,7 @@ export function MultiUploader<TEntity extends Record<string, unknown>>({
|
|
|
71
72
|
|
|
72
73
|
// Create entity for file and track mapping
|
|
73
74
|
const useCreateRepeaterEntityEvents = useCallback(
|
|
74
|
-
(events: UploaderEvents): UploaderEvents => ({
|
|
75
|
+
(events: Partial<UploaderEvents>): Partial<UploaderEvents> => ({
|
|
75
76
|
...events,
|
|
76
77
|
onBeforeUpload: async event => {
|
|
77
78
|
if (!(await resolveAcceptingSingleType(event.file, fileType as FileType))) {
|
|
@@ -115,19 +116,10 @@ export function MultiUploader<TEntity extends Record<string, unknown>>({
|
|
|
115
116
|
[field, fileType, getEntityForFile],
|
|
116
117
|
)
|
|
117
118
|
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
onBeforeUpload: async () => undefined,
|
|
123
|
-
onProgress: () => {},
|
|
124
|
-
onAfterUpload: async () => {},
|
|
125
|
-
onSuccess: () => {},
|
|
126
|
-
}),
|
|
127
|
-
[],
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
const fillEntityEvents = useCreateRepeaterEntityEvents(baseEvents)
|
|
119
|
+
const fillEntityEvents = useCreateRepeaterEntityEvents({
|
|
120
|
+
...events,
|
|
121
|
+
onError: events.onError ?? uploaderErrorHandler,
|
|
122
|
+
})
|
|
131
123
|
const { files, ...stateEvents } = useUploadState(fillEntityEvents)
|
|
132
124
|
const onDrop = useUploaderDoUpload(stateEvents)
|
|
133
125
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { useMemo, type ReactNode } from 'react'
|
|
2
|
-
import type {
|
|
2
|
+
import type { SelectionFieldMeta, SelectionMeta } from '@contember/bindx'
|
|
3
3
|
import { FIELD_REF_META } from '@contember/bindx'
|
|
4
4
|
import { BINDX_COMPONENT, type SelectionProvider, createEmptySelection } from '@contember/bindx-react'
|
|
5
|
-
import type { FileType } from '../types.js'
|
|
5
|
+
import type { FileType, PrepareUploadTarget, UploaderEvents, UploaderFillTarget } from '../types.js'
|
|
6
6
|
import {
|
|
7
7
|
UploaderOptionsContext,
|
|
8
8
|
UploaderStateContext,
|
|
@@ -13,25 +13,30 @@ import { useUploaderDoUpload } from '../internal/hooks/useUploaderDoUpload.js'
|
|
|
13
13
|
import { useFillEntity } from '../internal/hooks/useFillEntity.js'
|
|
14
14
|
import { uploaderErrorHandler } from '../internal/utils/uploaderErrorHandler.js'
|
|
15
15
|
|
|
16
|
-
export interface UploaderProps<TEntity = Record<string, unknown>> {
|
|
16
|
+
export interface UploaderProps<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
17
17
|
/**
|
|
18
18
|
* The entity to fill with uploaded file data.
|
|
19
19
|
* Can be an EntityRef or HasOneRef.
|
|
20
20
|
*/
|
|
21
|
-
entity:
|
|
21
|
+
entity: UploaderFillTarget<TEntity>
|
|
22
22
|
/**
|
|
23
23
|
* File type configuration defining accepted files and extractors.
|
|
24
24
|
* Must be created with the same entity type as the entity prop.
|
|
25
25
|
*/
|
|
26
26
|
fileType: FileType<TEntity>
|
|
27
|
+
/**
|
|
28
|
+
* Resolves the target of an upload batch: it runs once, after the files pass the accept
|
|
29
|
+
* check and before the uploader disconnects or fills anything, and receives the accepted
|
|
30
|
+
* files. A rejected batch never reaches it. Return another target to fork first
|
|
31
|
+
* (copy-on-write); returning nothing keeps the entity prop.
|
|
32
|
+
*/
|
|
33
|
+
prepareTarget?: PrepareUploadTarget<UploaderFillTarget<TEntity>>
|
|
27
34
|
/**
|
|
28
35
|
* Children to render within the uploader context.
|
|
29
36
|
*/
|
|
30
37
|
children?: ReactNode
|
|
31
38
|
}
|
|
32
39
|
|
|
33
|
-
const noop = (): Promise<undefined> => Promise.resolve(undefined)
|
|
34
|
-
|
|
35
40
|
/**
|
|
36
41
|
* Single file upload component for bindx.
|
|
37
42
|
* Provides upload state and upload function to children via context.
|
|
@@ -63,25 +68,39 @@ const noop = (): Promise<undefined> => Promise.resolve(undefined)
|
|
|
63
68
|
* </UploaderEachFile>
|
|
64
69
|
* </Uploader>
|
|
65
70
|
* ```
|
|
71
|
+
*
|
|
72
|
+
* @example Copy-on-write: fork a shared asset so the upload lands on a fresh one
|
|
73
|
+
* ```tsx
|
|
74
|
+
* <Uploader
|
|
75
|
+
* entity={block.asset.image}
|
|
76
|
+
* fileType={imageFileType}
|
|
77
|
+
* prepareTarget={() => {
|
|
78
|
+
* block.asset.$disconnect()
|
|
79
|
+
* block.asset.$create()
|
|
80
|
+
* return block.asset.image
|
|
81
|
+
* }}
|
|
82
|
+
* >
|
|
83
|
+
* <DropZone />
|
|
84
|
+
* </Uploader>
|
|
85
|
+
* ```
|
|
66
86
|
*/
|
|
67
87
|
export function Uploader<TEntity extends Record<string, unknown>>({
|
|
68
88
|
entity,
|
|
69
89
|
fileType,
|
|
90
|
+
prepareTarget,
|
|
70
91
|
children,
|
|
92
|
+
...events
|
|
71
93
|
}: UploaderProps<TEntity>): ReactNode {
|
|
72
|
-
const fillEntityEvents = useFillEntity({
|
|
94
|
+
const { prepareUpload, ...fillEntityEvents } = useFillEntity({
|
|
73
95
|
entity,
|
|
74
96
|
fileType,
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
onProgress: noop,
|
|
79
|
-
onAfterUpload: noop,
|
|
80
|
-
onSuccess: noop,
|
|
97
|
+
prepareTarget,
|
|
98
|
+
...events,
|
|
99
|
+
onError: events.onError ?? uploaderErrorHandler,
|
|
81
100
|
})
|
|
82
101
|
|
|
83
102
|
const { files, ...stateEvents } = useUploadState(fillEntityEvents)
|
|
84
|
-
const onDrop = useUploaderDoUpload(stateEvents)
|
|
103
|
+
const onDrop = useUploaderDoUpload({ ...stateEvents, onPrepareUpload: prepareUpload })
|
|
85
104
|
|
|
86
105
|
const options = useMemo(
|
|
87
106
|
() => ({
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { useUploadState, type UseUploadStateResult } from './useUploadState.js'
|
|
2
|
-
export { useUploaderDoUpload } from './useUploaderDoUpload.js'
|
|
2
|
+
export { useUploaderDoUpload, type UseUploaderDoUploadArgs } from './useUploaderDoUpload.js'
|
|
3
3
|
export { useGetPreviewUrls } from './useGetPreviewUrls.js'
|
|
4
|
-
export { useFillEntity, type UseFillEntityArgs } from './useFillEntity.js'
|
|
4
|
+
export { useFillEntity, type UseFillEntityArgs, type UseFillEntityResult } from './useFillEntity.js'
|
|
@@ -1,23 +1,33 @@
|
|
|
1
|
-
import { useCallback } from 'react'
|
|
1
|
+
import { useCallback, useRef } from 'react'
|
|
2
2
|
import type { EntityRef, HasOneAccessor } from '@contember/bindx'
|
|
3
|
-
import type { FileType, StartUploadEvent, UploaderEvents } from '../../types.js'
|
|
3
|
+
import type { FileType, PrepareUploadTarget, StartUploadEvent, UploaderEvents } from '../../types.js'
|
|
4
4
|
import { resolveAcceptingSingleType } from '../utils/resolveAccept.js'
|
|
5
5
|
import { executeExtractors } from '../utils/executeExtractors.js'
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
type FillTarget<TEntity> = EntityRef<TEntity> | HasOneAccessor<TEntity>
|
|
8
|
+
|
|
9
|
+
export interface UseFillEntityArgs<TEntity = Record<string, unknown>> extends Partial<UploaderEvents> {
|
|
8
10
|
/**
|
|
9
11
|
* The entity to fill. Can be:
|
|
10
12
|
* - EntityRef: fill the entity directly
|
|
11
13
|
* - HasOneAccessor: fill the related entity (disconnect first on upload start)
|
|
12
14
|
*/
|
|
13
|
-
entity:
|
|
15
|
+
entity: FillTarget<TEntity>
|
|
14
16
|
fileType: FileType<TEntity>
|
|
17
|
+
/**
|
|
18
|
+
* Resolves the target of a validated batch, before the upload disconnects or fills anything.
|
|
19
|
+
*/
|
|
20
|
+
prepareTarget?: PrepareUploadTarget<FillTarget<TEntity>>
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface UseFillEntityResult extends Partial<UploaderEvents> {
|
|
24
|
+
prepareUpload: (files: File[]) => Promise<void>
|
|
15
25
|
}
|
|
16
26
|
|
|
17
27
|
/**
|
|
18
28
|
* Checks if the entity is a HasOneRef (has $disconnect method)
|
|
19
29
|
*/
|
|
20
|
-
const isHasOneAccessor = <TEntity>(entity:
|
|
30
|
+
const isHasOneAccessor = <TEntity>(entity: FillTarget<TEntity>): entity is HasOneAccessor<TEntity> => {
|
|
21
31
|
return '$disconnect' in entity && typeof entity.$disconnect === 'function'
|
|
22
32
|
}
|
|
23
33
|
|
|
@@ -25,7 +35,7 @@ const isHasOneAccessor = <TEntity>(entity: EntityRef<TEntity> | HasOneAccessor<T
|
|
|
25
35
|
* Gets the target entity for filling.
|
|
26
36
|
* For HasOneAccessor, returns the related entity. For EntityRef, returns the entity itself.
|
|
27
37
|
*/
|
|
28
|
-
const getTargetEntity = <TEntity>(entity:
|
|
38
|
+
const getTargetEntity = <TEntity>(entity: FillTarget<TEntity>): EntityRef<TEntity> => {
|
|
29
39
|
if (isHasOneAccessor(entity)) {
|
|
30
40
|
return entity.$entity
|
|
31
41
|
}
|
|
@@ -39,8 +49,20 @@ const getTargetEntity = <TEntity>(entity: EntityRef<TEntity> | HasOneAccessor<TE
|
|
|
39
49
|
export const useFillEntity = <TEntity extends Record<string, unknown>>({
|
|
40
50
|
entity,
|
|
41
51
|
fileType,
|
|
52
|
+
prepareTarget,
|
|
42
53
|
...events
|
|
43
|
-
}: UseFillEntityArgs<TEntity>):
|
|
54
|
+
}: UseFillEntityArgs<TEntity>): UseFillEntityResult => {
|
|
55
|
+
const preparedTargetRef = useRef<FillTarget<TEntity> | undefined>(undefined)
|
|
56
|
+
|
|
57
|
+
const prepareUpload = useCallback(
|
|
58
|
+
async (files: File[]): Promise<void> => {
|
|
59
|
+
preparedTargetRef.current = await prepareTarget?.(files)
|
|
60
|
+
},
|
|
61
|
+
[prepareTarget],
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
const getTarget = useCallback((): FillTarget<TEntity> => preparedTargetRef.current ?? entity, [entity])
|
|
65
|
+
|
|
44
66
|
const handleBeforeUpload = useCallback(
|
|
45
67
|
async (event: Parameters<UploaderEvents['onBeforeUpload']>[0]): Promise<FileType | undefined> => {
|
|
46
68
|
if (!(await resolveAcceptingSingleType(event.file, fileType as FileType))) {
|
|
@@ -54,19 +76,20 @@ export const useFillEntity = <TEntity extends Record<string, unknown>>({
|
|
|
54
76
|
const handleStartUpload = useCallback(
|
|
55
77
|
(event: StartUploadEvent) => {
|
|
56
78
|
// Disconnect existing relation before upload
|
|
57
|
-
|
|
58
|
-
|
|
79
|
+
const target = getTarget()
|
|
80
|
+
if (isHasOneAccessor(target)) {
|
|
81
|
+
target.$disconnect()
|
|
59
82
|
}
|
|
60
83
|
events.onStartUpload?.(event)
|
|
61
84
|
},
|
|
62
|
-
[
|
|
85
|
+
[events, getTarget],
|
|
63
86
|
)
|
|
64
87
|
|
|
65
88
|
const handleAfterUpload = useCallback(
|
|
66
89
|
async (event: Parameters<UploaderEvents['onAfterUpload']>[0]) => {
|
|
67
90
|
await Promise.all([
|
|
68
91
|
(async () => {
|
|
69
|
-
const targetEntity = getTargetEntity(
|
|
92
|
+
const targetEntity = getTargetEntity(getTarget())
|
|
70
93
|
const extractionResult = await executeExtractors({
|
|
71
94
|
fileType: fileType as FileType,
|
|
72
95
|
result: event.result,
|
|
@@ -77,11 +100,12 @@ export const useFillEntity = <TEntity extends Record<string, unknown>>({
|
|
|
77
100
|
events.onAfterUpload?.(event),
|
|
78
101
|
])
|
|
79
102
|
},
|
|
80
|
-
[
|
|
103
|
+
[events, fileType, getTarget],
|
|
81
104
|
)
|
|
82
105
|
|
|
83
106
|
return {
|
|
84
107
|
...events,
|
|
108
|
+
prepareUpload,
|
|
85
109
|
onBeforeUpload: handleBeforeUpload,
|
|
86
110
|
onStartUpload: handleStartUpload,
|
|
87
111
|
onAfterUpload: handleAfterUpload,
|
|
@@ -28,7 +28,7 @@ export const useUploadState = ({
|
|
|
28
28
|
onError,
|
|
29
29
|
onProgress,
|
|
30
30
|
onAfterUpload,
|
|
31
|
-
}: UploaderEvents): UseUploadStateResult => {
|
|
31
|
+
}: Partial<UploaderEvents>): UseUploadStateResult => {
|
|
32
32
|
const [files, setFiles] = useState<Record<string, UploaderFileState>>({})
|
|
33
33
|
|
|
34
34
|
const purgeFinal = useCallback(() => {
|
|
@@ -4,6 +4,14 @@ import { UploaderError } from '../../UploaderError.js'
|
|
|
4
4
|
import { useUploaderClient } from '../../contexts.js'
|
|
5
5
|
import { useGetPreviewUrls } from './useGetPreviewUrls.js'
|
|
6
6
|
|
|
7
|
+
export interface UseUploaderDoUploadArgs extends Partial<UploaderEvents> {
|
|
8
|
+
/**
|
|
9
|
+
* Runs once per batch with the files that passed validation, before any of them is
|
|
10
|
+
* uploaded or written to the target. Skipped when no file passed.
|
|
11
|
+
*/
|
|
12
|
+
onPrepareUpload?: (files: File[]) => Promise<void> | void
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
/**
|
|
8
16
|
* Hook that orchestrates the file upload process.
|
|
9
17
|
* Handles file preparation, validation, and upload execution.
|
|
@@ -15,7 +23,8 @@ export const useUploaderDoUpload = ({
|
|
|
15
23
|
onSuccess,
|
|
16
24
|
onStartUpload,
|
|
17
25
|
onAfterUpload,
|
|
18
|
-
|
|
26
|
+
onPrepareUpload,
|
|
27
|
+
}: UseUploaderDoUploadArgs): ((files: File[]) => Promise<void>) => {
|
|
19
28
|
const getPreviewUrl = useGetPreviewUrls()
|
|
20
29
|
const defaultUploader = useUploaderClient()
|
|
21
30
|
|
|
@@ -73,6 +82,19 @@ export const useUploaderDoUpload = ({
|
|
|
73
82
|
)
|
|
74
83
|
.map(p => p.value)
|
|
75
84
|
|
|
85
|
+
if (preparedFiles.length === 0) {
|
|
86
|
+
return
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await onPrepareUpload?.(preparedFiles.map(({ file }) => file.file))
|
|
91
|
+
} catch (error) {
|
|
92
|
+
for (const { file } of preparedFiles) {
|
|
93
|
+
onError?.({ file, error })
|
|
94
|
+
}
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
|
|
76
98
|
// Upload files
|
|
77
99
|
await Promise.allSettled(
|
|
78
100
|
preparedFiles.map(async ({ file, fileType }) => {
|
|
@@ -121,6 +143,7 @@ export const useUploaderDoUpload = ({
|
|
|
121
143
|
onAfterUpload,
|
|
122
144
|
onBeforeUpload,
|
|
123
145
|
onError,
|
|
146
|
+
onPrepareUpload,
|
|
124
147
|
onProgress,
|
|
125
148
|
onStartUpload,
|
|
126
149
|
onSuccess,
|
package/src/types.ts
CHANGED
|
@@ -120,6 +120,17 @@ export interface ErrorEvent {
|
|
|
120
120
|
fileType?: FileType
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Fill target of a single-file uploader: an entity, or a has-one relation pointing at one.
|
|
125
|
+
*/
|
|
126
|
+
export type UploaderFillTarget<TEntity = Record<string, unknown>> = EntityRef<TEntity> | HasOneRef<TEntity>
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Resolves the target of an upload batch after the files pass validation and before
|
|
130
|
+
* the target is written. Returning nothing keeps the target the uploader was given.
|
|
131
|
+
*/
|
|
132
|
+
export type PrepareUploadTarget<TTarget> = (files: File[]) => TTarget | undefined | Promise<TTarget | undefined>
|
|
133
|
+
|
|
123
134
|
export interface UploaderEvents {
|
|
124
135
|
onBeforeUpload: (event: BeforeUploadEvent) => Promise<FileType | undefined>
|
|
125
136
|
onStartUpload: (event: StartUploadEvent) => void
|
|
@@ -10,6 +10,12 @@ export interface S3UploadClientOptions {
|
|
|
10
10
|
|
|
11
11
|
export type S3FileOptions = Partial<S3FileParameters>
|
|
12
12
|
|
|
13
|
+
// generateUploadUrl's `size` is a GraphQLInt (32-bit); larger files omit it rather than fail signing.
|
|
14
|
+
const MAX_GRAPHQL_INT = 2_147_483_647
|
|
15
|
+
|
|
16
|
+
const getDefaultSize = (file: File): number | undefined =>
|
|
17
|
+
file.size <= MAX_GRAPHQL_INT ? file.size : undefined
|
|
18
|
+
|
|
13
19
|
export class S3UploadClient implements UploadClient<S3FileOptions> {
|
|
14
20
|
private activeCount = 0
|
|
15
21
|
private resolverQueue: Array<() => void> = []
|
|
@@ -24,6 +30,7 @@ export class S3UploadClient implements UploadClient<S3FileOptions> {
|
|
|
24
30
|
}: UploadClientUploadArgs & S3FileOptions): Promise<{ publicUrl: string }> {
|
|
25
31
|
const parameters: S3FileParameters = {
|
|
26
32
|
contentType: file.type,
|
|
33
|
+
size: getDefaultSize(file),
|
|
27
34
|
...this.options.getUploadOptions?.(file),
|
|
28
35
|
...options,
|
|
29
36
|
}
|
package/src/utils/urlSigner.ts
CHANGED
|
@@ -57,55 +57,24 @@ function buildGenerateUploadUrlMutation(
|
|
|
57
57
|
const params = parameters[alias]
|
|
58
58
|
if (!params) continue
|
|
59
59
|
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
suffix: params.suffix,
|
|
72
|
-
fileName: params.fileName,
|
|
73
|
-
extension: params.extension,
|
|
74
|
-
}
|
|
75
|
-
fields.push(`${alias}: generateUploadUrl(input: $${inputVarName}) {
|
|
76
|
-
url
|
|
77
|
-
publicUrl
|
|
78
|
-
method
|
|
79
|
-
headers { key value }
|
|
80
|
-
}`)
|
|
81
|
-
} else {
|
|
82
|
-
const contentTypeVar = `contentType_${varIndex}`
|
|
83
|
-
const expirationVar = `expiration_${varIndex}`
|
|
84
|
-
const prefixVar = `prefix_${varIndex}`
|
|
85
|
-
const aclVar = `acl_${varIndex}`
|
|
86
|
-
|
|
87
|
-
variableDefinitions.push(`$${contentTypeVar}: String`)
|
|
88
|
-
variableDefinitions.push(`$${expirationVar}: Int`)
|
|
89
|
-
variableDefinitions.push(`$${prefixVar}: String`)
|
|
90
|
-
variableDefinitions.push(`$${aclVar}: S3Acl`)
|
|
91
|
-
|
|
92
|
-
variables[contentTypeVar] = params.contentType
|
|
93
|
-
variables[expirationVar] = params.expiration
|
|
94
|
-
variables[prefixVar] = params.prefix
|
|
95
|
-
variables[aclVar] = params.acl
|
|
96
|
-
|
|
97
|
-
fields.push(`${alias}: generateUploadUrl(
|
|
98
|
-
contentType: $${contentTypeVar}
|
|
99
|
-
expiration: $${expirationVar}
|
|
100
|
-
prefix: $${prefixVar}
|
|
101
|
-
acl: $${aclVar}
|
|
102
|
-
) {
|
|
103
|
-
url
|
|
104
|
-
publicUrl
|
|
105
|
-
method
|
|
106
|
-
headers { key value }
|
|
107
|
-
}`)
|
|
60
|
+
const inputVarName = `input_${varIndex}`
|
|
61
|
+
variableDefinitions.push(`$${inputVarName}: S3GenerateSignedUploadInput`)
|
|
62
|
+
variables[inputVarName] = {
|
|
63
|
+
contentType: params.contentType,
|
|
64
|
+
prefix: params.prefix,
|
|
65
|
+
expiration: params.expiration,
|
|
66
|
+
acl: params.acl,
|
|
67
|
+
size: params.size,
|
|
68
|
+
suffix: params.suffix,
|
|
69
|
+
fileName: params.fileName,
|
|
70
|
+
extension: params.extension,
|
|
108
71
|
}
|
|
72
|
+
fields.push(`${alias}: generateUploadUrl(input: $${inputVarName}) {
|
|
73
|
+
url
|
|
74
|
+
publicUrl
|
|
75
|
+
method
|
|
76
|
+
headers { key value }
|
|
77
|
+
}`)
|
|
109
78
|
varIndex++
|
|
110
79
|
}
|
|
111
80
|
|