@uploadcare/file-uploader 1.22.0 → 1.23.0
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/abstract/UploaderBlock.d.ts.map +1 -1
- package/abstract/UploaderBlock.js +27 -5
- package/abstract/UploaderPublicApi.d.ts.map +1 -1
- package/abstract/UploaderPublicApi.js +9 -1
- package/abstract/managers/ValidationManager.d.ts +71 -12
- package/abstract/managers/ValidationManager.d.ts.map +1 -1
- package/abstract/managers/ValidationManager.js +229 -53
- package/abstract/uploadEntrySchema.d.ts +10 -2
- package/abstract/uploadEntrySchema.d.ts.map +1 -1
- package/abstract/uploadEntrySchema.js +10 -2
- package/blocks/CloudImageEditor/src/CloudImageEditorBlock.js +1 -1
- package/blocks/Config/initialConfig.d.ts.map +1 -1
- package/blocks/Config/initialConfig.js +2 -0
- package/blocks/Config/normalizeConfigValue.d.ts.map +1 -1
- package/blocks/Config/normalizeConfigValue.js +2 -0
- package/blocks/FileItem/FileItem.d.ts +1 -1
- package/blocks/FileItem/FileItem.d.ts.map +1 -1
- package/blocks/FileItem/FileItem.js +68 -49
- package/blocks/UploadList/UploadList.d.ts +2 -0
- package/blocks/UploadList/UploadList.d.ts.map +1 -1
- package/blocks/UploadList/UploadList.js +18 -20
- package/env.d.ts +1 -1
- package/env.js +1 -1
- package/index.ssr.d.ts +1 -1
- package/index.ssr.d.ts.map +1 -1
- package/index.ssr.js +5 -1
- package/locales/file-uploader/ar.d.ts +3 -1
- package/locales/file-uploader/ar.js +4 -2
- package/locales/file-uploader/az.d.ts +3 -1
- package/locales/file-uploader/az.js +5 -2
- package/locales/file-uploader/ca.d.ts +3 -1
- package/locales/file-uploader/ca.js +5 -2
- package/locales/file-uploader/cs.d.ts +3 -1
- package/locales/file-uploader/cs.js +5 -2
- package/locales/file-uploader/da.d.ts +3 -1
- package/locales/file-uploader/da.js +5 -2
- package/locales/file-uploader/de.d.ts +3 -1
- package/locales/file-uploader/de.js +5 -2
- package/locales/file-uploader/el.d.ts +3 -1
- package/locales/file-uploader/el.js +5 -2
- package/locales/file-uploader/en.d.ts +3 -1
- package/locales/file-uploader/en.js +4 -2
- package/locales/file-uploader/es.d.ts +3 -1
- package/locales/file-uploader/es.js +5 -2
- package/locales/file-uploader/et.d.ts +3 -1
- package/locales/file-uploader/et.js +5 -2
- package/locales/file-uploader/fi.d.ts +3 -1
- package/locales/file-uploader/fi.js +5 -2
- package/locales/file-uploader/fr.d.ts +3 -1
- package/locales/file-uploader/fr.js +5 -2
- package/locales/file-uploader/he.d.ts +3 -1
- package/locales/file-uploader/he.js +5 -2
- package/locales/file-uploader/hy.d.ts +3 -1
- package/locales/file-uploader/hy.js +4 -2
- package/locales/file-uploader/is.d.ts +3 -1
- package/locales/file-uploader/is.js +5 -2
- package/locales/file-uploader/it.d.ts +3 -1
- package/locales/file-uploader/it.js +5 -2
- package/locales/file-uploader/ja.d.ts +3 -1
- package/locales/file-uploader/ja.js +5 -2
- package/locales/file-uploader/ka.d.ts +3 -1
- package/locales/file-uploader/ka.js +5 -2
- package/locales/file-uploader/kk.d.ts +3 -1
- package/locales/file-uploader/kk.js +5 -2
- package/locales/file-uploader/ko.d.ts +3 -1
- package/locales/file-uploader/ko.js +5 -2
- package/locales/file-uploader/lv.d.ts +3 -1
- package/locales/file-uploader/lv.js +5 -2
- package/locales/file-uploader/nb.d.ts +3 -1
- package/locales/file-uploader/nb.js +5 -2
- package/locales/file-uploader/nl.d.ts +3 -1
- package/locales/file-uploader/nl.js +5 -2
- package/locales/file-uploader/pl.d.ts +3 -1
- package/locales/file-uploader/pl.js +5 -2
- package/locales/file-uploader/pt.d.ts +3 -1
- package/locales/file-uploader/pt.js +5 -2
- package/locales/file-uploader/ro.d.ts +3 -1
- package/locales/file-uploader/ro.js +5 -2
- package/locales/file-uploader/ru.d.ts +3 -1
- package/locales/file-uploader/ru.js +5 -2
- package/locales/file-uploader/sk.d.ts +3 -1
- package/locales/file-uploader/sk.js +5 -2
- package/locales/file-uploader/sr.d.ts +3 -1
- package/locales/file-uploader/sr.js +5 -2
- package/locales/file-uploader/sv.d.ts +3 -1
- package/locales/file-uploader/sv.js +5 -2
- package/locales/file-uploader/tr.d.ts +3 -1
- package/locales/file-uploader/tr.js +5 -2
- package/locales/file-uploader/uk.d.ts +3 -1
- package/locales/file-uploader/uk.js +5 -2
- package/locales/file-uploader/vi.d.ts +3 -1
- package/locales/file-uploader/vi.js +5 -2
- package/locales/file-uploader/zh-TW.d.ts +3 -1
- package/locales/file-uploader/zh-TW.js +5 -2
- package/locales/file-uploader/zh.d.ts +3 -1
- package/locales/file-uploader/zh.js +5 -2
- package/package.json +8 -8
- package/types/exported.d.ts +26 -4
- package/utils/withResolvers.d.ts +6 -0
- package/utils/withResolvers.d.ts.map +1 -0
- package/utils/withResolvers.js +18 -0
- package/utils/withResolvers.test.d.ts +2 -0
- package/utils/withResolvers.test.d.ts.map +1 -0
- package/utils/withResolvers.test.js +36 -0
- package/web/file-uploader.iife.min.js +4 -4
- package/web/file-uploader.min.js +4 -4
- package/web/uc-cloud-image-editor.min.js +4 -4
- package/web/uc-file-uploader-inline.min.js +4 -4
- package/web/uc-file-uploader-minimal.min.js +4 -4
- package/web/uc-file-uploader-regular.min.js +4 -4
- package/web/uc-img.min.js +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploaderBlock.d.ts","sourceRoot":"","sources":["UploaderBlock.js"],"names":[],"mappings":"AAmBA;IACE,iBAAiB;IACjB,mCAAwB;IAExB,eAAe;IACf,mBAAmB;IAEnB;;;;;;;;;;;;;;MAA+B;IAE/B,eAAe;IACf,0BAOC;
|
|
1
|
+
{"version":3,"file":"UploaderBlock.d.ts","sourceRoot":"","sources":["UploaderBlock.js"],"names":[],"mappings":"AAmBA;IACE,iBAAiB;IACjB,mCAAwB;IAExB,eAAe;IACf,mBAAmB;IAEnB;;;;;;;;;;;;;;MAA+B;IAE/B,eAAe;IACf,0BAOC;IAmCD;;;OAGG;IACH,mCAHa,iBAAiB,CAQ7B;IAED,mCAAmC;IACnC,WADc,iBAAiB,CAM9B;IAED,4BAEC;IAED,2DAA2D;IAC3D,wBADc,eAAe,CAAC,OAAO,iBAAiB,CAAC,CAMtD;IAgCD,eAAe;IACf,sBAYC;IAED,eAAe;IACf,iCAUC;IAPC,eAAe;IACf,6BAAiG;IAEjG,eAAe;IACf,uCAEC;IAGH,eAAe;IACf,mCAMC;IAED;;;OAGG;IACH,qBAkBC;IAED,eAAe;IACf,0BAYQ;IAER;;;OAGG;IACH,gCAwCE;IAEF;;;OAGG;IACH,0CAqGE;IAEF,eAAe;IACf,mCAsBE;IAEF,6BAiBC;IAED,eAAe;IACf,uBAyDC;IAED;;;OAGG;IACH,kCAHW,MAAM,qEAWhB;IAED;;;OAGG;IACH,oCAHa,OAAO,CAAC,OAAO,2BAA2B,EAAE,eAAe,CAAC,CA4BxE;IAED,kEAAkE;IAClE,iBADc,OAAO,sBAAsB,EAAE,eAAe,EAAE,CAK7D;CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAngB6B,oBAAoB;qCAWb,oCAAoC;kCAGvC,iCAAiC;kCADjC,wBAAwB;gCAD1B,sBAAsB;kCAGpB,wBAAwB"}
|
|
@@ -43,7 +43,15 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
43
43
|
if (!this.has('*uploadCollection')) {
|
|
44
44
|
let uploadCollection = new TypedCollection({
|
|
45
45
|
typedSchema: uploadEntrySchema,
|
|
46
|
-
watchList: [
|
|
46
|
+
watchList: [
|
|
47
|
+
'uploadProgress',
|
|
48
|
+
'uploadError',
|
|
49
|
+
'fileInfo',
|
|
50
|
+
'errors',
|
|
51
|
+
'cdnUrl',
|
|
52
|
+
'isUploading',
|
|
53
|
+
'isValidationPending',
|
|
54
|
+
],
|
|
47
55
|
});
|
|
48
56
|
this.add('*uploadCollection', uploadCollection);
|
|
49
57
|
}
|
|
@@ -206,8 +214,11 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
206
214
|
if (added.size || removed.size) {
|
|
207
215
|
this.$['*groupInfo'] = null;
|
|
208
216
|
}
|
|
209
|
-
|
|
210
|
-
this.validationManager.
|
|
217
|
+
|
|
218
|
+
this.validationManager.runFileValidators(
|
|
219
|
+
'add',
|
|
220
|
+
[...added].map((e) => e.uid),
|
|
221
|
+
);
|
|
211
222
|
|
|
212
223
|
for (const entry of added) {
|
|
213
224
|
if (!entry.getValue('silent')) {
|
|
@@ -215,9 +226,12 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
215
226
|
}
|
|
216
227
|
}
|
|
217
228
|
|
|
229
|
+
this.validationManager.runCollectionValidators();
|
|
230
|
+
|
|
218
231
|
for (const entry of removed) {
|
|
219
232
|
/** @type {Set<string>} */ (this.$['*uploadTrigger']).delete(entry.uid);
|
|
220
233
|
|
|
234
|
+
this.validationManager.cleanupValidationForEntry(entry);
|
|
221
235
|
entry.getValue('abortController')?.abort();
|
|
222
236
|
entry.setMultipleValues({
|
|
223
237
|
isRemoved: true,
|
|
@@ -249,7 +263,7 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
249
263
|
const entriesToRunValidation = [
|
|
250
264
|
...new Set(
|
|
251
265
|
Object.entries(changeMap)
|
|
252
|
-
.filter(([key]) => ['uploadError', 'fileInfo'].includes(key))
|
|
266
|
+
.filter(([key]) => ['uploadError', 'fileInfo', 'cdnUrl', 'cdnUrlModifiers'].includes(key))
|
|
253
267
|
.map(([, ids]) => [...ids])
|
|
254
268
|
.flat(),
|
|
255
269
|
),
|
|
@@ -258,7 +272,13 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
258
272
|
entriesToRunValidation.length > 0 &&
|
|
259
273
|
setTimeout(() => {
|
|
260
274
|
// We can't modify entry properties in the same tick, so we need to wait a bit
|
|
261
|
-
|
|
275
|
+
const entriesToRunOnUpload = entriesToRunValidation.filter(
|
|
276
|
+
(entryId) => changeMap.fileInfo?.has(entryId) && !!Data.getCtx(entryId).store.fileInfo,
|
|
277
|
+
);
|
|
278
|
+
if (entriesToRunOnUpload.length > 0) {
|
|
279
|
+
this.validationManager.runFileValidators('upload', entriesToRunOnUpload);
|
|
280
|
+
}
|
|
281
|
+
this.validationManager.runFileValidators('change', entriesToRunValidation);
|
|
262
282
|
});
|
|
263
283
|
|
|
264
284
|
if (changeMap.uploadProgress) {
|
|
@@ -295,6 +315,8 @@ export class UploaderBlock extends ActivityBlock {
|
|
|
295
315
|
}
|
|
296
316
|
}
|
|
297
317
|
if (changeMap.errors) {
|
|
318
|
+
this.validationManager.runCollectionValidators();
|
|
319
|
+
|
|
298
320
|
for (const entryId of changeMap.errors) {
|
|
299
321
|
const { errors } = Data.getCtx(entryId).store;
|
|
300
322
|
if (errors.length > 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UploaderPublicApi.d.ts","sourceRoot":"","sources":["UploaderPublicApi.js"],"names":[],"mappings":"AAqBA;IAOE,8DAA8D;IAC9D,iBADY,OAAO,oBAAoB,EAAE,aAAa,EAGrD;IATD;;;OAGG;IACH,aAAK;IAOL,eAAe;IACf,gCAEC;IAED,yCAEC;IAED;;iBAEC;IAED;;;;;;OAMG;IACH,iBAAkB,KAJP,MAIU,EAAE,+BAHZ;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGT,KAF3C,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,kBAAmB,MAJR,MAIY,EAAE,+BAHd;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGP,KAF7C,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,oBAAqB,QAJV,MAIgB,EAAE,+BAHlB;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGH,KAFjD,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAgBrD;IAEF;;;;OAIG;IACH,oBAAqB,MAJV,IAIc,EAAE,yCAHhB;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAGd,KAFzD,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAcrD;IAEF,iCAAiC;IACjC,yBAA0B,YADd,MACwB,UAKlC;IAEF,uBAEC;IAED,
|
|
1
|
+
{"version":3,"file":"UploaderPublicApi.d.ts","sourceRoot":"","sources":["UploaderPublicApi.js"],"names":[],"mappings":"AAqBA;IAOE,8DAA8D;IAC9D,iBADY,OAAO,oBAAoB,EAAE,aAAa,EAGrD;IATD;;;OAGG;IACH,aAAK;IAOL,eAAe;IACf,gCAEC;IAED,yCAEC;IAED;;iBAEC;IAED;;;;;;OAMG;IACH,iBAAkB,KAJP,MAIU,EAAE,+BAHZ;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGT,KAF3C,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,kBAAmB,MAJR,MAIY,EAAE,+BAHd;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGP,KAF7C,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAUrD;IAEF;;;;OAIG;IACH,oBAAqB,QAJV,MAIgB,EAAE,+BAHlB;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAGH,KAFjD,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAgBrD;IAEF;;;;OAIG;IACH,oBAAqB,MAJV,IAIc,EAAE,yCAHhB;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAGd,KAFzD,OAAO,UAAU,EAAE,eAAe,CAAC,MAAM,CAAC,CAcrD;IAEF,iCAAiC;IACjC,yBAA0B,YADd,MACwB,UAKlC;IAEF,uBAEC;IAED,sBAuBE;IAEF,8HAA8H;IAC9H,mBAAoB,UADR;QAAE,aAAa,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,qCAAqC,EAAE,cAAc,CAAA;KAChF,UA6D9B;IAEF;;;;OAIG;IACH,cAJmD,OAAO,SAA7C,OAAQ,UAAU,EAAE,gBAAiB,WACvC,MAAM,GACJ,OAAO,sBAAsB,EAAE,eAAe,CAAC,OAAO,CAAC,CAgDnE;IAED,oEAAoE;IACpE,yBAD0D,OAAO,SAAnD,OAAQ,UAAU,EAAE,sBAAuB,KAErC,UAAU,CAAC,OAAO,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAGzE;IAED,+BAA+B;IAC/B,WAAY,eAAa,UA6DvB;IAEF,qBAQE;IAEF;;;;;;;;;OASG;IACH,oBATU,CAAC,CAAC,SAAS,OAAO,oBAAoB,EAAE,YAAY,EACzD,YAAY,EAAE,CAAC,EACnB,GAAO,MAAM,EAAE,CAAC,SAAS,MAAM,OAAO,oBAAoB,EAAE,iBAAiB,GACrE,CAAC,OAAO,oBAAoB,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,GACnD,CAAC,SAAS,OAAO,oBAAoB,EAAE,sBAAsB,GAC3D,CAAC,SAAS,CAAC,CAAC,GACZ,CAAC,GAAG,CAAC,CAAC,KACT,IAAI,CAWV;IAEF,2DAA2D;IAC3D,0BADc,OAAO,oBAAoB,EAAE,YAAY,CAGrD;IAEF,8BAA8B;IAC9B,gBAAiB,QADL,OACW,UAYrB;IAEF;;;OAGG;IACH,0BAOC;CACF;2CAnY0C,iCAAiC"}
|
|
@@ -132,7 +132,14 @@ export class UploaderPublicApi {
|
|
|
132
132
|
const itemsToUpload = this._uploadCollection.items().filter((id) => {
|
|
133
133
|
const entry = this._uploadCollection.read(id);
|
|
134
134
|
if (!entry) return false;
|
|
135
|
-
return
|
|
135
|
+
return (
|
|
136
|
+
!entry.getValue('isRemoved') &&
|
|
137
|
+
!entry.getValue('isUploading') &&
|
|
138
|
+
!entry.getValue('fileInfo') &&
|
|
139
|
+
entry.getValue('errors').length === 0 &&
|
|
140
|
+
!entry.getValue('isValidationPending') &&
|
|
141
|
+
!entry.getValue('isQueuedForValidation')
|
|
142
|
+
);
|
|
136
143
|
});
|
|
137
144
|
|
|
138
145
|
if (itemsToUpload.length === 0) {
|
|
@@ -254,6 +261,7 @@ export class UploaderPublicApi {
|
|
|
254
261
|
isUploading: status === 'uploading',
|
|
255
262
|
isFailed: status === 'failed',
|
|
256
263
|
isRemoved: status === 'removed',
|
|
264
|
+
isValidationPending: uploadEntryData.isValidationPending,
|
|
257
265
|
errors: /** @type {import('../types/exported.js').OutputFileEntry['errors']} */ (uploadEntryData.errors),
|
|
258
266
|
status,
|
|
259
267
|
source: uploadEntryData?.source,
|
|
@@ -7,9 +7,30 @@ export class ValidationManager {
|
|
|
7
7
|
*/
|
|
8
8
|
private _blockInstance;
|
|
9
9
|
/** @type {FuncFileValidator[]} */
|
|
10
|
-
|
|
10
|
+
_commonFileValidators: FuncFileValidator[];
|
|
11
11
|
/** @type {FuncCollectionValidator[]} */
|
|
12
|
-
|
|
12
|
+
_commonCollectionValidators: FuncCollectionValidator[];
|
|
13
|
+
_queue: Queue;
|
|
14
|
+
_runQueueDebounced: (() => void) & {
|
|
15
|
+
cancel: () => void;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* @type {Map<
|
|
19
|
+
* string,
|
|
20
|
+
* {
|
|
21
|
+
* abortController?: AbortController;
|
|
22
|
+
* skippedValidators: WeakSet<FuncFileValidator>;
|
|
23
|
+
* promise?: Promise<void>;
|
|
24
|
+
* lastErrorThrownByValidator: WeakMap<FuncFileValidator, import('../../types').OutputErrorFile | undefined>;
|
|
25
|
+
* }
|
|
26
|
+
* >}
|
|
27
|
+
*/
|
|
28
|
+
_entryValidationState: Map<string, {
|
|
29
|
+
abortController?: AbortController;
|
|
30
|
+
skippedValidators: WeakSet<FuncFileValidator>;
|
|
31
|
+
promise?: Promise<void>;
|
|
32
|
+
lastErrorThrownByValidator: WeakMap<FuncFileValidator, import("../../types").OutputErrorFile | undefined>;
|
|
33
|
+
}>;
|
|
13
34
|
_uploadCollection: import("../TypedCollection.js").TypedCollection<Readonly<{
|
|
14
35
|
file: Readonly<{
|
|
15
36
|
type: {
|
|
@@ -114,7 +135,7 @@ export class ValidationManager {
|
|
|
114
135
|
}>;
|
|
115
136
|
errors: Readonly<{
|
|
116
137
|
type: ArrayConstructor;
|
|
117
|
-
value:
|
|
138
|
+
value: import("../../types").OutputErrorFile[];
|
|
118
139
|
}>;
|
|
119
140
|
uploadError: Readonly<{
|
|
120
141
|
type: ErrorConstructor;
|
|
@@ -125,26 +146,64 @@ export class ValidationManager {
|
|
|
125
146
|
type: BooleanConstructor;
|
|
126
147
|
value: false;
|
|
127
148
|
}>;
|
|
128
|
-
|
|
149
|
+
isQueuedForUploading: Readonly<{
|
|
150
|
+
type: BooleanConstructor;
|
|
151
|
+
value: false;
|
|
152
|
+
}>;
|
|
153
|
+
isValidationPending: Readonly<{
|
|
154
|
+
type: BooleanConstructor;
|
|
155
|
+
value: false;
|
|
156
|
+
}>;
|
|
157
|
+
isQueuedForValidation: Readonly<{
|
|
129
158
|
type: BooleanConstructor;
|
|
130
159
|
value: false;
|
|
131
160
|
}>;
|
|
132
161
|
}>>;
|
|
133
|
-
/**
|
|
134
|
-
|
|
162
|
+
/**
|
|
163
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
164
|
+
* @param {string[]} [entryIds]
|
|
165
|
+
*/
|
|
166
|
+
runFileValidators(runOn: FileValidatorDescriptor["runOn"], entryIds?: string[]): void;
|
|
135
167
|
runCollectionValidators(): void;
|
|
168
|
+
/** @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry */
|
|
169
|
+
cleanupValidationForEntry(entry: import("../TypedData.js").TypedData<typeof import("../uploadEntrySchema.js").uploadEntrySchema>): void;
|
|
136
170
|
/**
|
|
137
171
|
* @private
|
|
138
172
|
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
173
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
139
174
|
*/
|
|
140
175
|
private _runFileValidatorsForEntry;
|
|
141
176
|
/**
|
|
142
|
-
* @
|
|
143
|
-
* @
|
|
144
|
-
*
|
|
177
|
+
* @private
|
|
178
|
+
* @template {import('../../types').OutputError<
|
|
179
|
+
* import('../../types').OutputFileErrorType | import('../../types').OutputCollectionErrorType
|
|
180
|
+
* >} T
|
|
181
|
+
* @param {T} error
|
|
182
|
+
* @returns {T}
|
|
183
|
+
*/
|
|
184
|
+
private _addCustomTypeToValidationError;
|
|
185
|
+
/**
|
|
186
|
+
* @private
|
|
187
|
+
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
188
|
+
*/
|
|
189
|
+
private _getEntryValidationState;
|
|
190
|
+
/** @private */
|
|
191
|
+
private _getValidatorDescriptors;
|
|
192
|
+
/**
|
|
193
|
+
* @private
|
|
194
|
+
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
195
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
145
196
|
*/
|
|
146
|
-
|
|
197
|
+
private _getValidatorDescriptorsForEntry;
|
|
147
198
|
}
|
|
148
|
-
export type FuncFileValidator = (outputEntry: import("../../types
|
|
149
|
-
|
|
199
|
+
export type FuncFileValidator = (outputEntry: import("../../types").OutputFileEntry, api: import("../UploaderPublicApi.js").UploaderPublicApi, options?: {
|
|
200
|
+
signal?: AbortSignal;
|
|
201
|
+
}) => (undefined | import("../../types").OutputErrorFile) | Promise<undefined | import("../../types").OutputErrorFile>;
|
|
202
|
+
export type FileValidatorDescriptor = {
|
|
203
|
+
runOn: "add" | "upload" | "change";
|
|
204
|
+
validator: FuncFileValidator;
|
|
205
|
+
};
|
|
206
|
+
export type FileValidator = FileValidatorDescriptor | FuncFileValidator;
|
|
207
|
+
export type FuncCollectionValidator = (collection: ReturnType<typeof import("../buildOutputCollectionState.js").buildOutputCollectionState<import("../../types").OutputCollectionStatus>>, api: import("../UploaderPublicApi.js").UploaderPublicApi) => undefined | import("../../types").OutputErrorCollection;
|
|
208
|
+
import { Queue } from '@uploadcare/upload-client';
|
|
150
209
|
//# sourceMappingURL=ValidationManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ValidationManager.d.ts","sourceRoot":"","sources":["ValidationManager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ValidationManager.d.ts","sourceRoot":"","sources":["ValidationManager.js"],"names":[],"mappings":"AA6DA;IA+BE,yEAAyE;IACzE,2BADY,OAAO,qBAAqB,EAAE,aAAa,EAqBtD;IAnDD;;;OAGG;IACH,uBAAe;IAEf,kCAAkC;IAClC,uBADW,iBAAiB,EAAE,CACyE;IAEvG,wCAAwC;IACxC,6BADW,uBAAuB,EAAE,CAC4C;IAEhF,cAAuB;IACvB;;MAEQ;IAER;;;;;;;;;;OAUG;IACH,uBAVU,GAAG,CACZ,MAAU,EACV;QACM,eAAe,CAAC,EAAE,eAAe,CAAC;QAClC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC9C,OAAO,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACxB,0BAA0B,EAAE,OAAO,CAAC,iBAAiB,EAAE,OAAO,aAAa,EAAE,eAAe,GAAG,SAAS,CAAC,CAAC;KAC3G,CACF,CAE8B;IAMhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAA6D;IAmB/D;;;OAGG;IACH,yBAHW,uBAAuB,CAAC,OAAO,CAAC,aAChC,MAAM,EAAE,QAUlB;IAED,gCAkCC;IAED,qHAAqH;IACrH,iCADY,OAAO,iBAAiB,EAAE,SAAS,CAAC,cAAc,yBAAyB,EAAE,iBAAiB,CAAC,QAO1G;IAED;;;;OAIG;IACH,mCAyGC;IAED;;;;;;;OAOG;IACH,wCAKC;IAED;;;OAGG;IACH,iCAgBC;IAED,eAAe;IACf,iCAEC;IAED;;;;OAIG;IACH,yCAKC;CACF;gCArUY,CACR,WAAW,EAAE,OAAO,aAAa,EAAE,eAAe,EAClD,GAAG,EAAE,OAAO,yBAAyB,EAAE,iBAAiB,EACxD,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAEhC,CAAC,SAAS,GAAG,OAAO,aAAa,EAAE,eAAe,CAAC,GACnD,OAAO,CAAC,SAAS,GAAG,OAAO,aAAa,EAAE,eAAe,CAAC;sCAIpD;IACR,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACnC,SAAS,EAAE,iBAAiB,CAAC;CAC9B;4BAGU,uBAAuB,GAAG,iBAAiB;sCAG5C,CACR,UAAU,EAAE,UAAU,CAC1B,cAAoB,kCAAkC,EAAE,0BAA0B,CAClF,OAAe,aAAa,EAAE,sBAAsB,CAC7C,CACF,EACD,GAAG,EAAE,OAAO,yBAAyB,EAAE,iBAAiB,KACrD,SAAS,GAAG,OAAO,aAAa,EAAE,qBAAqB;sBA/BzC,2BAA2B"}
|
|
@@ -7,29 +7,56 @@ import {
|
|
|
7
7
|
validateUploadError,
|
|
8
8
|
} from '../../utils/validators/file/index.js';
|
|
9
9
|
import { validateMultiple, validateCollectionUploadError } from '../../utils/validators/collection/index.js';
|
|
10
|
+
import { Queue } from '@uploadcare/upload-client';
|
|
11
|
+
import { withResolvers } from '../../utils/withResolvers.js';
|
|
12
|
+
import { debounce } from '../../blocks/utils/debounce.js';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* @typedef {(
|
|
13
|
-
* outputEntry: import('../../types
|
|
16
|
+
* outputEntry: import('../../types').OutputFileEntry,
|
|
14
17
|
* api: import('../UploaderPublicApi.js').UploaderPublicApi,
|
|
15
|
-
*
|
|
18
|
+
* options?: { signal?: AbortSignal },
|
|
19
|
+
* ) =>
|
|
20
|
+
* | (undefined | import('../../types').OutputErrorFile)
|
|
21
|
+
* | Promise<undefined | import('../../types').OutputErrorFile>} FuncFileValidator
|
|
16
22
|
*/
|
|
17
23
|
|
|
24
|
+
/**
|
|
25
|
+
* @typedef {{
|
|
26
|
+
* runOn: 'add' | 'upload' | 'change';
|
|
27
|
+
* validator: FuncFileValidator;
|
|
28
|
+
* }} FileValidatorDescriptor
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** @typedef {FileValidatorDescriptor | FuncFileValidator} FileValidator */
|
|
32
|
+
|
|
18
33
|
/**
|
|
19
34
|
* @typedef {(
|
|
20
35
|
* collection: ReturnType<
|
|
21
36
|
* typeof import('../buildOutputCollectionState.js').buildOutputCollectionState<
|
|
22
|
-
* import('../../types
|
|
37
|
+
* import('../../types').OutputCollectionStatus
|
|
23
38
|
* >
|
|
24
39
|
* >,
|
|
25
40
|
* api: import('../UploaderPublicApi.js').UploaderPublicApi,
|
|
26
|
-
* ) => undefined | import('../../types
|
|
41
|
+
* ) => undefined | import('../../types').OutputErrorCollection} FuncCollectionValidator
|
|
27
42
|
*/
|
|
28
43
|
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
44
|
+
const LOG_TEXT = {
|
|
45
|
+
FILE_VALIDATION_FAILED: 'File validator execution has failed',
|
|
46
|
+
FILE_VALIDATION_TIMEOUT: 'File validator execution has timed out',
|
|
47
|
+
COLLECTION_VALIDATION_FAILED: 'Collection validator execution has failed',
|
|
48
|
+
MISSING_ERROR_MESSAGE: 'Missing message. We recommend adding message: value.',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @param {FileValidator} validator
|
|
53
|
+
* @returns {FileValidatorDescriptor}
|
|
54
|
+
*/
|
|
55
|
+
const getValidatorDescriptor = (validator) => {
|
|
56
|
+
if (typeof validator === 'function') {
|
|
57
|
+
return { runOn: 'change', validator };
|
|
58
|
+
}
|
|
59
|
+
return validator;
|
|
33
60
|
};
|
|
34
61
|
|
|
35
62
|
export class ValidationManager {
|
|
@@ -40,10 +67,28 @@ export class ValidationManager {
|
|
|
40
67
|
_blockInstance;
|
|
41
68
|
|
|
42
69
|
/** @type {FuncFileValidator[]} */
|
|
43
|
-
|
|
70
|
+
_commonFileValidators = [validateIsImage, validateFileType, validateMaxSizeLimit, validateUploadError];
|
|
44
71
|
|
|
45
72
|
/** @type {FuncCollectionValidator[]} */
|
|
46
|
-
|
|
73
|
+
_commonCollectionValidators = [validateMultiple, validateCollectionUploadError];
|
|
74
|
+
|
|
75
|
+
_queue = new Queue(20);
|
|
76
|
+
_runQueueDebounced = debounce(() => {
|
|
77
|
+
this._queue.run();
|
|
78
|
+
}, 500);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @type {Map<
|
|
82
|
+
* string,
|
|
83
|
+
* {
|
|
84
|
+
* abortController?: AbortController;
|
|
85
|
+
* skippedValidators: WeakSet<FuncFileValidator>;
|
|
86
|
+
* promise?: Promise<void>;
|
|
87
|
+
* lastErrorThrownByValidator: WeakMap<FuncFileValidator, import('../../types').OutputErrorFile | undefined>;
|
|
88
|
+
* }
|
|
89
|
+
* >}
|
|
90
|
+
*/
|
|
91
|
+
_entryValidationState = new Map();
|
|
47
92
|
|
|
48
93
|
/** @param {import('../UploaderBlock.js').UploaderBlock} blockInstance */
|
|
49
94
|
constructor(blockInstance) {
|
|
@@ -52,7 +97,7 @@ export class ValidationManager {
|
|
|
52
97
|
this._uploadCollection = this._blockInstance.uploadCollection;
|
|
53
98
|
|
|
54
99
|
const runAllValidators = () => {
|
|
55
|
-
this.runFileValidators();
|
|
100
|
+
this.runFileValidators('change');
|
|
56
101
|
this.runCollectionValidators();
|
|
57
102
|
};
|
|
58
103
|
|
|
@@ -62,15 +107,22 @@ export class ValidationManager {
|
|
|
62
107
|
this._blockInstance.subConfigValue('multiple', runAllValidators);
|
|
63
108
|
this._blockInstance.subConfigValue('imgOnly', runAllValidators);
|
|
64
109
|
this._blockInstance.subConfigValue('accept', runAllValidators);
|
|
110
|
+
|
|
111
|
+
this._blockInstance.subConfigValue('validationConcurrency', (concurrency) => {
|
|
112
|
+
this._queue.concurrency = concurrency;
|
|
113
|
+
});
|
|
65
114
|
}
|
|
66
115
|
|
|
67
|
-
/**
|
|
68
|
-
|
|
116
|
+
/**
|
|
117
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
118
|
+
* @param {string[]} [entryIds]
|
|
119
|
+
*/
|
|
120
|
+
runFileValidators(runOn, entryIds) {
|
|
69
121
|
const ids = entryIds ?? this._uploadCollection.items();
|
|
70
122
|
for (const id of ids) {
|
|
71
123
|
const entry = this._uploadCollection.read(id);
|
|
72
124
|
if (entry) {
|
|
73
|
-
this._runFileValidatorsForEntry(entry);
|
|
125
|
+
void this._runFileValidatorsForEntry(entry, runOn);
|
|
74
126
|
}
|
|
75
127
|
}
|
|
76
128
|
}
|
|
@@ -79,25 +131,21 @@ export class ValidationManager {
|
|
|
79
131
|
const collection = this._blockInstance.api.getOutputCollectionState();
|
|
80
132
|
const errors = [];
|
|
81
133
|
|
|
82
|
-
for (const validator of [
|
|
83
|
-
...this._collectionValidators,
|
|
84
|
-
...this._addCustomTypeToValidators(this._blockInstance.cfg.collectionValidators),
|
|
85
|
-
]) {
|
|
134
|
+
for (const validator of [...this._commonCollectionValidators, ...this._blockInstance.cfg.collectionValidators]) {
|
|
86
135
|
try {
|
|
87
|
-
const
|
|
88
|
-
if (!
|
|
136
|
+
const error = validator(collection, this._blockInstance.api);
|
|
137
|
+
if (!error) {
|
|
89
138
|
continue;
|
|
90
139
|
}
|
|
91
|
-
if (
|
|
92
|
-
errors.push(
|
|
140
|
+
if (error) {
|
|
141
|
+
errors.push(this._addCustomTypeToValidationError(error));
|
|
93
142
|
|
|
94
|
-
if (!
|
|
95
|
-
console.warn(
|
|
143
|
+
if (!error.message) {
|
|
144
|
+
console.warn(LOG_TEXT.MISSING_ERROR_MESSAGE);
|
|
96
145
|
}
|
|
97
146
|
}
|
|
98
147
|
} catch (error) {
|
|
99
|
-
console.warn(
|
|
100
|
-
this._blockInstance.telemetryManager.sendEventError(error, `collection validator. ${LOGGER.collection}`);
|
|
148
|
+
console.warn(LOG_TEXT.COLLECTION_VALIDATION_FAILED, error);
|
|
101
149
|
}
|
|
102
150
|
}
|
|
103
151
|
|
|
@@ -107,7 +155,7 @@ export class ValidationManager {
|
|
|
107
155
|
this._blockInstance.emit(
|
|
108
156
|
EventType.COMMON_UPLOAD_FAILED,
|
|
109
157
|
() =>
|
|
110
|
-
/** @type {import('../../types
|
|
158
|
+
/** @type {import('../../types').OutputCollectionState<'failed'>} */ (
|
|
111
159
|
this._blockInstance.api.getOutputCollectionState()
|
|
112
160
|
),
|
|
113
161
|
{ debounce: true },
|
|
@@ -115,50 +163,178 @@ export class ValidationManager {
|
|
|
115
163
|
}
|
|
116
164
|
}
|
|
117
165
|
|
|
166
|
+
/** @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry */
|
|
167
|
+
cleanupValidationForEntry(entry) {
|
|
168
|
+
const state = this._entryValidationState.get(entry.uid);
|
|
169
|
+
if (state) {
|
|
170
|
+
state.abortController?.abort();
|
|
171
|
+
this._entryValidationState.delete(entry.uid);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
118
175
|
/**
|
|
119
176
|
* @private
|
|
120
177
|
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
178
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
121
179
|
*/
|
|
122
|
-
_runFileValidatorsForEntry(entry) {
|
|
180
|
+
async _runFileValidatorsForEntry(entry, runOn) {
|
|
181
|
+
const entryDescriptors = this._getValidatorDescriptorsForEntry(entry, runOn);
|
|
182
|
+
if (entryDescriptors.length === 0) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
entry.setMultipleValues({
|
|
186
|
+
isQueuedForValidation: true,
|
|
187
|
+
isValidationPending: true,
|
|
188
|
+
});
|
|
123
189
|
const outputEntry = this._blockInstance.api.getOutputItem(entry.uid);
|
|
190
|
+
const state = this._getEntryValidationState(entry);
|
|
191
|
+
|
|
192
|
+
if (state.promise) {
|
|
193
|
+
await state.promise;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const { promise, resolve } = withResolvers();
|
|
197
|
+
state.promise = promise;
|
|
198
|
+
const abortController = new AbortController();
|
|
199
|
+
state.abortController = abortController;
|
|
200
|
+
|
|
201
|
+
const timeoutMs = this._blockInstance.cfg.validationTimeout;
|
|
202
|
+
const allDescriptors = this._getValidatorDescriptors();
|
|
203
|
+
|
|
204
|
+
const entryValidatorSet = new Set(entryDescriptors.map((d) => d.validator));
|
|
205
|
+
/** @type {import('../../types').OutputErrorFile[]} */
|
|
124
206
|
const errors = [];
|
|
207
|
+
for (const descriptor of allDescriptors) {
|
|
208
|
+
if (!entryValidatorSet.has(descriptor.validator)) {
|
|
209
|
+
const error = state.lastErrorThrownByValidator.get(descriptor.validator);
|
|
210
|
+
if (error) errors.push(error);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const tasks = entryDescriptors.map((validatorDescriptor) => async () => {
|
|
215
|
+
if (!this._blockInstance.isConnected) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const timeoutId = setTimeout(() => {
|
|
219
|
+
state.skippedValidators.add(validatorDescriptor.validator);
|
|
220
|
+
abortController.abort();
|
|
221
|
+
console.warn(LOG_TEXT.FILE_VALIDATION_TIMEOUT);
|
|
222
|
+
}, timeoutMs);
|
|
125
223
|
|
|
126
|
-
for (const validator of [
|
|
127
|
-
...this._fileValidators,
|
|
128
|
-
...this._addCustomTypeToValidators(this._blockInstance.cfg.fileValidators),
|
|
129
|
-
]) {
|
|
130
224
|
try {
|
|
131
|
-
const error = validator(outputEntry, this._blockInstance.api
|
|
132
|
-
|
|
133
|
-
|
|
225
|
+
const error = await validatorDescriptor.validator(outputEntry, this._blockInstance.api, {
|
|
226
|
+
signal: abortController.signal,
|
|
227
|
+
});
|
|
228
|
+
if (!error || abortController.signal.aborted) {
|
|
229
|
+
state.lastErrorThrownByValidator.set(validatorDescriptor.validator, undefined);
|
|
230
|
+
return;
|
|
134
231
|
}
|
|
135
|
-
|
|
136
|
-
|
|
232
|
+
const normalizedError = this._addCustomTypeToValidationError(error);
|
|
233
|
+
state.lastErrorThrownByValidator.set(validatorDescriptor.validator, normalizedError);
|
|
234
|
+
errors.push(normalizedError);
|
|
137
235
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
236
|
+
if (!error.message) {
|
|
237
|
+
console.warn(LOG_TEXT.MISSING_ERROR_MESSAGE);
|
|
141
238
|
}
|
|
142
239
|
} catch (error) {
|
|
143
|
-
|
|
144
|
-
|
|
240
|
+
if (!abortController.signal.aborted) {
|
|
241
|
+
state.skippedValidators.add(validatorDescriptor.validator);
|
|
242
|
+
|
|
243
|
+
console.warn(LOG_TEXT.FILE_VALIDATION_FAILED, error);
|
|
244
|
+
this._blockInstance.telemetryManager.sendEventError(
|
|
245
|
+
error,
|
|
246
|
+
`file validator. ${LOG_TEXT.FILE_VALIDATION_FAILED}`,
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
} finally {
|
|
250
|
+
clearTimeout(timeoutId);
|
|
251
|
+
if (validatorDescriptor.runOn !== 'change') {
|
|
252
|
+
state.skippedValidators.add(validatorDescriptor.validator);
|
|
253
|
+
}
|
|
145
254
|
}
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
this._runQueueDebounced();
|
|
258
|
+
|
|
259
|
+
await this._queue.add(
|
|
260
|
+
async () => {
|
|
261
|
+
entry.setValue('isQueuedForValidation', false);
|
|
262
|
+
await Promise.all(tasks.map((task) => task())).catch(() => {});
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
autoRun: false,
|
|
266
|
+
},
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
if (abortController.signal.aborted) {
|
|
270
|
+
entry.setMultipleValues({
|
|
271
|
+
isQueuedForValidation: false,
|
|
272
|
+
isValidationPending: false,
|
|
273
|
+
});
|
|
274
|
+
resolve();
|
|
275
|
+
return;
|
|
146
276
|
}
|
|
147
|
-
|
|
277
|
+
|
|
278
|
+
entry.setMultipleValues({
|
|
279
|
+
isValidationPending: false,
|
|
280
|
+
isQueuedForValidation: false,
|
|
281
|
+
errors,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
resolve();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @private
|
|
289
|
+
* @template {import('../../types').OutputError<
|
|
290
|
+
* import('../../types').OutputFileErrorType | import('../../types').OutputCollectionErrorType
|
|
291
|
+
* >} T
|
|
292
|
+
* @param {T} error
|
|
293
|
+
* @returns {T}
|
|
294
|
+
*/
|
|
295
|
+
_addCustomTypeToValidationError(error) {
|
|
296
|
+
return {
|
|
297
|
+
...error,
|
|
298
|
+
type: error.type ?? 'CUSTOM_ERROR',
|
|
299
|
+
};
|
|
148
300
|
}
|
|
149
301
|
|
|
150
302
|
/**
|
|
151
|
-
* @
|
|
152
|
-
* @param {
|
|
153
|
-
* @returns {T[]}
|
|
303
|
+
* @private
|
|
304
|
+
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
154
305
|
*/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
306
|
+
_getEntryValidationState(entry) {
|
|
307
|
+
const currentState = this._entryValidationState.get(entry.uid);
|
|
308
|
+
if (currentState) {
|
|
309
|
+
return currentState;
|
|
310
|
+
}
|
|
160
311
|
|
|
161
|
-
|
|
162
|
-
|
|
312
|
+
const newState = {
|
|
313
|
+
abortController: undefined,
|
|
314
|
+
skippedValidators: new WeakSet(),
|
|
315
|
+
promise: undefined,
|
|
316
|
+
lastErrorThrownByValidator: /** @type {WeakMap<FuncFileValidator, import('../../types').OutputErrorFile>} */ (
|
|
317
|
+
new WeakMap()
|
|
318
|
+
),
|
|
319
|
+
};
|
|
320
|
+
this._entryValidationState.set(entry.uid, newState);
|
|
321
|
+
return newState;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** @private */
|
|
325
|
+
_getValidatorDescriptors() {
|
|
326
|
+
return [...this._commonFileValidators, ...this._blockInstance.cfg.fileValidators].map(getValidatorDescriptor);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @private
|
|
331
|
+
* @param {import('../TypedData.js').TypedData<typeof import('../uploadEntrySchema.js').uploadEntrySchema>} entry
|
|
332
|
+
* @param {FileValidatorDescriptor['runOn']} runOn
|
|
333
|
+
*/
|
|
334
|
+
_getValidatorDescriptorsForEntry(entry, runOn) {
|
|
335
|
+
const state = this._getEntryValidationState(entry);
|
|
336
|
+
return this._getValidatorDescriptors()
|
|
337
|
+
.filter((descriptor) => !state.skippedValidators.has(descriptor.validator))
|
|
338
|
+
.filter((descriptor) => descriptor.runOn === runOn);
|
|
163
339
|
}
|
|
164
340
|
}
|
|
@@ -103,7 +103,7 @@ export const uploadEntrySchema: Readonly<{
|
|
|
103
103
|
}>;
|
|
104
104
|
errors: Readonly<{
|
|
105
105
|
type: ArrayConstructor;
|
|
106
|
-
value:
|
|
106
|
+
value: import("../types").OutputErrorFile[];
|
|
107
107
|
}>;
|
|
108
108
|
uploadError: Readonly<{
|
|
109
109
|
type: ErrorConstructor;
|
|
@@ -114,7 +114,15 @@ export const uploadEntrySchema: Readonly<{
|
|
|
114
114
|
type: BooleanConstructor;
|
|
115
115
|
value: false;
|
|
116
116
|
}>;
|
|
117
|
-
|
|
117
|
+
isQueuedForUploading: Readonly<{
|
|
118
|
+
type: BooleanConstructor;
|
|
119
|
+
value: false;
|
|
120
|
+
}>;
|
|
121
|
+
isValidationPending: Readonly<{
|
|
122
|
+
type: BooleanConstructor;
|
|
123
|
+
value: false;
|
|
124
|
+
}>;
|
|
125
|
+
isQueuedForValidation: Readonly<{
|
|
118
126
|
type: BooleanConstructor;
|
|
119
127
|
value: false;
|
|
120
128
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadEntrySchema.d.ts","sourceRoot":"","sources":["uploadEntrySchema.js"],"names":[],"mappings":"AAGA,gBAAgB;AAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAkGsB,
|
|
1
|
+
{"version":3,"file":"uploadEntrySchema.d.ts","sourceRoot":"","sources":["uploadEntrySchema.js"],"names":[],"mappings":"AAGA,gBAAgB;AAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAkGsB,OAAO,UAAU,EAAE,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;;;;GAuBvD;8BAEW,OAAO,aAAa,EAAE,qBAAqB,CAAC,OAAO,iBAAiB,CAAC;mCAErE,OAAO,gBAAgB,EAAE,SAAS,CAAC,OAAO,iBAAiB,CAAC;8BAE5D,OAAO,gBAAgB,EAAE,qBAAqB,CAAC,OAAO,iBAAiB,CAAC;+BAlIvD,2BAA2B"}
|