oneentry 1.0.169 → 1.0.171
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/changelog.md +26 -0
- package/dist/attribute-sets/attributeSetsInterfaces.d.ts +114 -12
- package/dist/base/utils.d.ts +1 -1
- package/dist/forms-data/formsDataApi.d.ts +25 -1
- package/dist/forms-data/formsDataApi.js +52 -8
- package/dist/forms-data/formsDataInterfaces.d.ts +10 -6
- package/esm/attribute-sets/attributeSetsInterfaces.d.ts +114 -12
- package/esm/base/utils.d.ts +1 -1
- package/esm/forms-data/formsDataApi.d.ts +25 -1
- package/esm/forms-data/formsDataApi.js +52 -8
- package/esm/forms-data/formsDataInterfaces.d.ts +10 -6
- package/package.json +2 -2
package/changelog.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# SDK Change Log
|
|
2
2
|
|
|
3
|
+
## v.1.0.171
|
|
4
|
+
|
|
5
|
+
### What's Fixed
|
|
6
|
+
|
|
7
|
+
- **`postFormsData` threw `fd.value.map is not a function` on the value its own uploader returns.** For a `file`, `image` or `groupOfImages` field the method converted the value — an array was uploaded file by file, a lone `File`/`Blob` into a single object — and then called `fd.value.map(...)` **unconditionally**, to strip `contentType`. A value the package had not converted reached `.map` as a non-array and the call died inside the library, before any request was made. That value is not an exotic one: it is exactly what `FileUploading.upload` returns, the natural thing to pass when the file is already in storage. The other plausible reading — an array of those descriptors — was re-uploaded as if the descriptors were files, and the platform refused the result with `formData's marker 'resume' value[0].filename is required`, naming the field the SDK itself had replaced. It cost a shipped pilot its application form: every visitor who attached a document got a generic refusal while the submission counter stayed at 0, and the only trace was the `TypeError` in the site log. Now only a `File` or a `Blob` is uploaded, an entry already in storage is passed through untouched — the two may be mixed in one array — and `contentType` is stripped from an array of values and from a lone value object alike. A value of any other shape is sent as it came, so the endpoint names the field it cannot read instead of the library throwing (CMS-990).
|
|
8
|
+
|
|
9
|
+
- **The accepted shapes of a file value were not declared.** `IBodyTypeFile.value` and `IBodyTypeImageGroupOfImages.value` described a hand-built `IFileValue` / `IImageValue` only — neither a raw `File`/`Blob`, which the SDK has always uploaded on the caller's behalf, nor the descriptor the uploader returns for a file already in storage. Both are in the types now, mixable in one array, and the JSDoc states what the endpoint does with them: a submission wants an **array**, so a lone descriptor or `IFileValue` answers `400 formData's marker '<marker>' value must be an array` while a lone `File`/`Blob` works because the upload result is already one. `fileQuery` is also declared where the SDK actually reads it — on the field; `IBodyPostFormData.fileQuery` is kept for compatibility, but setting it there changes nothing. Measured on js-sdk-tests.oneentry.cloud, 2026-10-08.
|
|
10
|
+
|
|
11
|
+
### Tests
|
|
12
|
+
|
|
13
|
+
- **`formsdata` pins the file already in storage.** The new case uploads a probe with `FileUploading.upload`, submits the descriptor it returns as a one-element array — which used to be re-uploaded and refused — and then submits the same descriptor alone, which must come back as the endpoint's own `400 … value must be an array`, not as a `TypeError` from inside the package.
|
|
14
|
+
|
|
15
|
+
## v.1.0.170
|
|
16
|
+
|
|
17
|
+
### What's Changed
|
|
18
|
+
|
|
19
|
+
- **`IAttributeValidators` named four validators of the eighteen the platform accepts.** The interface gave a shape to `requiredValidator`, `stringInspectionValidator`, `emailInspectionValidator` and `defaultValueValidator`, and closed with `[key: string]: unknown`; its JSDoc said only that the set is extensible. A developer reading the types learned that a required flag, a length constraint, an e-mail toggle and a default value exist, and did not learn that a **regular expression**, an **input mask**, a **whitespace trim** and **date bounds** exist — fourteen capabilities absent from the model of the platform, which on one pilot reached three client-facing documents as the sentence "a field has exactly four validators; there are no regular expressions and no phone check". All eighteen names are now declared with the shape the platform stores: `requiredValidator`, `trimValidator`, `stringInspectionValidator`, `urlInspectionValidator`, `emailInspectionValidator`, `checkForNumberValidator`, `roundingNumberValidator`, `booleanValidator`, `comparisonValidator`, `regExpValidator`, `fieldMaskValidator`, `checkForAGivenList`, `defaultValueValidator`, `sizeInPixelsValidator`, `checkingFilesValidator`, `minMaxDateValidator`, `valueValidator`, `checkForLettersValidator` (CMS-983).
|
|
20
|
+
|
|
21
|
+
- **A misspelt validator name is a compile error instead of a `400`.** The index signature `[key: string]: unknown` made the gap silent in the other direction too: `emailValidator` typechecked and the platform refused the write at run time with `schema contains unknown validator name(s)`. The signature is gone, so an unknown name is caught where it is written. Code that still needs a name the SDK does not know can cast at that one place.
|
|
22
|
+
|
|
23
|
+
- **Shapes follow what the platform executes, not what reads well.** `regExpValidator` takes `{ patternValue, invert, flags }` and not `{ regExp }`, `fieldMaskValidator` takes `{ maskValue }`, `checkForAGivenList` carries no `Validator` suffix, and `minMaxDateValidator` stores `minDateTimeValue` / `maxDateTimeValue`. The toggles — `requiredValidator`, `trimValidator`, `urlInspectionValidator`, `emailInspectionValidator` — are typed `object | boolean`, because both forms are in live data: an e-mail check is stored as the boolean `true` on seven fields of the stands checked and as an object on one. Every validator may also carry `customErrorText`, which is now in the type. `valueValidator` is kept with the same shape as `defaultValueValidator`: it is the panel's own name for that control, and the API stores it.
|
|
24
|
+
|
|
25
|
+
- **The attribute JSDoc in `base/utils.ts` named `regexValidator`,** which does not exist. It points at `IAttributeValidators` for the full list instead.
|
|
26
|
+
|
|
27
|
+
Types and documentation only; the wire format did not change.
|
|
28
|
+
|
|
3
29
|
## v.1.0.169
|
|
4
30
|
|
|
5
31
|
### What's Fixed
|
|
@@ -189,28 +189,130 @@ interface IAttributeSchemaItem {
|
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
191
|
* @interface IAttributeValidators
|
|
192
|
-
* @property {object} [requiredValidator] -
|
|
193
|
-
* @property {object} [
|
|
194
|
-
* @property {
|
|
195
|
-
* @property {object} [
|
|
196
|
-
* @
|
|
192
|
+
* @property {object | boolean} [requiredValidator] - Field must be filled in. Shape: `{ strict: boolean }`. Example: `{ strict: true }`.
|
|
193
|
+
* @property {object | boolean} [trimValidator] - Leading and trailing whitespace is stripped from the value. Stored as an empty object when the toggle is on. Example: `{}`.
|
|
194
|
+
* @property {object} [stringInspectionValidator] - Length constraints for string fields. Example: `{ stringLength: 0, stringMin: 2, stringMax: 60 }`.
|
|
195
|
+
* @property {object | boolean} [urlInspectionValidator] - Value must look like a URL. Stored either as `true` or as an object. Example: `true`.
|
|
196
|
+
* @property {object | boolean} [emailInspectionValidator] - Value must look like an e-mail address. Stored either as `true` or as an object. Example: `true`.
|
|
197
|
+
* @property {object} [checkForNumberValidator] - Value must be a number, optionally an integer within bounds. `0` disables a bound. Example: `{ integerOnly: true, minValue: 1, maxValue: 10 }`.
|
|
198
|
+
* @property {object} [roundingNumberValidator] - Rounds the number before storing it. Example: `{ integerOnly: false, numberOfDecimals: 2, direction: 'round' }`.
|
|
199
|
+
* @property {object} [booleanValidator] - Value must equal one of the two declared values. Example: `{ trueValue: 1, falseValue: 0 }`.
|
|
200
|
+
* @property {object} [comparisonValidator] - Compares the value with another attribute or with a constant. Example: `{ compareAttribute: 'notChoosed', compareValue: '10', type: 'number', operator: 'equality' }`.
|
|
201
|
+
* @property {object} [regExpValidator] - Value must match a regular expression; `invert` refuses matches instead. Example: `{ patternValue: '^[0-9]{5}$', invert: false, flags: ['i'] }`.
|
|
202
|
+
* @property {object} [fieldMaskValidator] - Value must match an input mask (`9` digit, `A` upper letter, `a` lower letter, `*` any, `$` one of `()+-`). Example: `{ maskValue: '+9 (999) 999-99-99' }`.
|
|
203
|
+
* @property {object} [checkForAGivenList] - Value must be in the list, or outside it when `notValue` is true. Example: `{ rangeValue: ['red', 'green'], notValue: false }`.
|
|
204
|
+
* @property {object} [defaultValueValidator] - Value substituted when the field is left empty. Example: `{ fieldDefaultValue: 'USD' }`.
|
|
205
|
+
* @property {object} [sizeInPixelsValidator] - Image bounds in pixels; executed by the admin panel. Example: `{ maxX: 1920, maxY: 1080 }`.
|
|
206
|
+
* @property {object} [checkingFilesValidator] - File size bounds and allowed extensions; executed by the admin panel. Example: `{ minValue: 0, maxValue: 5, minUnits: 'kb', maxUnits: 'mb', extensions: ['pdf'] }`.
|
|
207
|
+
* @property {object} [minMaxDateValidator] - Date bounds; executed by the admin panel. Example: `{ minDateTimeValue: '2026-01-01', maxDateTimeValue: '2026-12-31' }`.
|
|
208
|
+
* @property {object} [valueValidator] - The panel's "default value" control; it writes `defaultValueValidator`, and this name is kept because the API accepts and stores it. Example: `{ fieldDefaultValue: 'USD' }`.
|
|
209
|
+
* @property {object} [checkForLettersValidator] - Letters-only check by pattern; executed by the admin panel. Example: `{ patternValue: '^[A-Za-z ]+$' }`.
|
|
210
|
+
* @description Map of validators applied to an attribute or form field, keyed by validator name.
|
|
211
|
+
*
|
|
212
|
+
* These eighteen names are the full set the API accepts in
|
|
213
|
+
* `attributes_sets.schema.<attribute>.validators.<langCode>`; any other name is refused
|
|
214
|
+
* with `400`. The first thirteen are executed by the platform on write, the last five are
|
|
215
|
+
* stored as given and executed by the admin panel.
|
|
216
|
+
*
|
|
217
|
+
* Every validator may also carry `customErrorText` — the message shown instead of the
|
|
218
|
+
* default one when the value is refused.
|
|
197
219
|
*/
|
|
198
220
|
interface IAttributeValidators {
|
|
199
221
|
requiredValidator?: {
|
|
200
|
-
strict
|
|
201
|
-
|
|
222
|
+
strict?: boolean;
|
|
223
|
+
customErrorText?: string;
|
|
224
|
+
} | boolean;
|
|
225
|
+
trimValidator?: {
|
|
226
|
+
strict?: boolean;
|
|
227
|
+
customErrorText?: string;
|
|
228
|
+
} | boolean;
|
|
202
229
|
stringInspectionValidator?: {
|
|
203
|
-
stringMin
|
|
204
|
-
stringMax
|
|
205
|
-
stringLength
|
|
230
|
+
stringMin?: number;
|
|
231
|
+
stringMax?: number;
|
|
232
|
+
stringLength?: number;
|
|
233
|
+
customErrorText?: string;
|
|
234
|
+
};
|
|
235
|
+
urlInspectionValidator?: {
|
|
236
|
+
strict?: boolean;
|
|
237
|
+
customErrorText?: string;
|
|
238
|
+
} | boolean;
|
|
239
|
+
emailInspectionValidator?: {
|
|
240
|
+
strict?: boolean;
|
|
241
|
+
customErrorText?: string;
|
|
242
|
+
} | boolean;
|
|
243
|
+
checkForNumberValidator?: {
|
|
244
|
+
integerOnly?: boolean;
|
|
245
|
+
minValue?: number;
|
|
246
|
+
maxValue?: number;
|
|
247
|
+
customErrorText?: string;
|
|
248
|
+
};
|
|
249
|
+
roundingNumberValidator?: {
|
|
250
|
+
integerOnly?: boolean;
|
|
251
|
+
numberOfDecimals?: number;
|
|
252
|
+
direction?: 'round' | 'up' | 'down' | 'truncate';
|
|
253
|
+
customErrorText?: string;
|
|
254
|
+
};
|
|
255
|
+
booleanValidator?: {
|
|
256
|
+
trueValue?: unknown;
|
|
257
|
+
falseValue?: unknown;
|
|
258
|
+
customErrorText?: string;
|
|
259
|
+
};
|
|
260
|
+
comparisonValidator?: {
|
|
261
|
+
compareAttribute?: string;
|
|
262
|
+
compareValue?: string;
|
|
263
|
+
compareValue2?: string;
|
|
264
|
+
type?: string;
|
|
265
|
+
operator?: string;
|
|
266
|
+
customErrorText?: string;
|
|
267
|
+
};
|
|
268
|
+
regExpValidator?: {
|
|
269
|
+
patternValue?: string;
|
|
270
|
+
invert?: boolean;
|
|
271
|
+
flags?: string[];
|
|
272
|
+
customErrorText?: string;
|
|
273
|
+
};
|
|
274
|
+
fieldMaskValidator?: {
|
|
275
|
+
maskValue?: string;
|
|
276
|
+
customErrorText?: string;
|
|
277
|
+
};
|
|
278
|
+
checkForAGivenList?: {
|
|
279
|
+
rangeValue?: unknown[];
|
|
280
|
+
rangeValue2?: unknown[];
|
|
281
|
+
notValue?: boolean;
|
|
282
|
+
customErrorText?: string;
|
|
206
283
|
};
|
|
207
|
-
emailInspectionValidator?: boolean;
|
|
208
284
|
defaultValueValidator?: {
|
|
285
|
+
fieldDefaultValue?: unknown;
|
|
286
|
+
fieldDefaultValue2?: unknown;
|
|
287
|
+
customErrorText?: string;
|
|
288
|
+
};
|
|
289
|
+
sizeInPixelsValidator?: {
|
|
290
|
+
maxX?: number;
|
|
291
|
+
maxY?: number;
|
|
209
292
|
customErrorText?: string;
|
|
293
|
+
};
|
|
294
|
+
checkingFilesValidator?: {
|
|
295
|
+
minValue?: number;
|
|
296
|
+
maxValue?: number;
|
|
297
|
+
minUnits?: 'kb' | 'mb';
|
|
298
|
+
maxUnits?: 'kb' | 'mb';
|
|
299
|
+
extensions?: string[];
|
|
300
|
+
customErrorText?: string;
|
|
301
|
+
};
|
|
302
|
+
minMaxDateValidator?: {
|
|
303
|
+
minDateTimeValue?: string;
|
|
304
|
+
maxDateTimeValue?: string;
|
|
305
|
+
customErrorText?: string;
|
|
306
|
+
};
|
|
307
|
+
valueValidator?: {
|
|
210
308
|
fieldDefaultValue?: unknown;
|
|
211
309
|
fieldDefaultValue2?: unknown;
|
|
310
|
+
customErrorText?: string;
|
|
311
|
+
};
|
|
312
|
+
checkForLettersValidator?: {
|
|
313
|
+
patternValue?: string;
|
|
314
|
+
customErrorText?: string;
|
|
212
315
|
};
|
|
213
|
-
[key: string]: unknown;
|
|
214
316
|
}
|
|
215
317
|
/**
|
|
216
318
|
* Represents an attribute set entity.
|
package/dist/base/utils.d.ts
CHANGED
|
@@ -96,7 +96,7 @@ interface IConfig {
|
|
|
96
96
|
* @property {boolean} isVisible - Whether the attribute is exposed in the public API/UI. Example: true.
|
|
97
97
|
* @property {string} type - Attribute data type (e.g. "string", "integer", "list", "file", "image").
|
|
98
98
|
* @property {Record<string, unknown>} [settings] - Type-specific configuration (e.g. min/max for numbers, accepted MIME types for files). Optional.
|
|
99
|
-
* @property {Record<string, unknown>} validators - Validation rules applied to the attribute value (e.g. `requiredValidator`, `
|
|
99
|
+
* @property {Record<string, unknown>} validators - Validation rules applied to the attribute value, keyed by validator name (e.g. `requiredValidator`, `regExpValidator`); the full set of names is listed on `IAttributeValidators`. Example: { "requiredValidator": { "strict": true } }.
|
|
100
100
|
* @property {Record<string, IAttributes>} [additionalFields] - Nested sub-attributes attached to this attribute, keyed by marker. Optional.
|
|
101
101
|
* @property {boolean} [isIcon] - Block/preview attribute flag — whether the field is treated as an icon. Optional.
|
|
102
102
|
* @property {boolean} [isProductPreview] - Block/preview attribute flag — whether the field is shown in product preview. Optional.
|
|
@@ -56,10 +56,34 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
|
|
|
56
56
|
* @param {string} [langCode] - Language code. Default: "en_US".
|
|
57
57
|
* @returns {Promise<IPostFormResponse | IError>} Returns an object containing the created form data entry and message.
|
|
58
58
|
* @throws {IError} When isShell=false and an error occurs during the fetch
|
|
59
|
-
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
59
|
+
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
60
|
+
*
|
|
61
|
+
* A file value may be a `File`/`Blob` (a `FileList` too), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which the SDK passes through untouched; or a hand-built {@link IFileValue} / {@link IImageValue}. The three may be mixed in one array. `contentType` is stripped from all of them, and a value of none of these shapes is sent as it came — the endpoint then names the field it cannot read, instead of the SDK throwing before the request.
|
|
62
|
+
*
|
|
63
|
+
* The endpoint wants file values in an **array**: a lone descriptor or `IFileValue` answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` works because the upload result is already one.
|
|
60
64
|
* @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
|
|
61
65
|
*/
|
|
62
66
|
postFormsData(body: IBodyPostFormData, langCode?: string): Promise<IPostFormResponse | IError>;
|
|
67
|
+
/**
|
|
68
|
+
* Tells a file the SDK still has to upload from one already in storage.
|
|
69
|
+
* @param {unknown} value - One value of a `file` / `image` / `groupOfImages` field.
|
|
70
|
+
* @returns {boolean} True when the value is a `File` or a `Blob`, which has to be uploaded first.
|
|
71
|
+
* @description Only a `File` or a `Blob` is uploaded. Anything else — above all the
|
|
72
|
+
* descriptor `FileUploading.upload` returns for a file already in storage — is sent
|
|
73
|
+
* as it came: re-uploading it would send the descriptor as the file itself.
|
|
74
|
+
*/
|
|
75
|
+
private _isUploadable;
|
|
76
|
+
/**
|
|
77
|
+
* Removes `contentType` from a file value, which the endpoint does not accept.
|
|
78
|
+
* @param {T} value - Value of a `file` / `image` / `groupOfImages` field, after the uploads.
|
|
79
|
+
* @returns {T} The same value, without `contentType`.
|
|
80
|
+
* @description `FileUploading.upload` returns `contentType` and form data rejects it,
|
|
81
|
+
* so it is stripped from an array of values and from a lone value object alike. A value
|
|
82
|
+
* of any other shape is returned untouched and the endpoint names the field it cannot
|
|
83
|
+
* read — instead of the library dying on `value.map is not a function` before the
|
|
84
|
+
* request is made (CMS-990).
|
|
85
|
+
*/
|
|
86
|
+
private _stripContentType;
|
|
63
87
|
/**
|
|
64
88
|
* Drops the date bounds the endpoint refuses to parse.
|
|
65
89
|
*
|
|
@@ -96,7 +96,11 @@ class FormsDataApi extends asyncModules_1.default {
|
|
|
96
96
|
* @param {string} [langCode] - Language code. Default: "en_US".
|
|
97
97
|
* @returns {Promise<IPostFormResponse | IError>} Returns an object containing the created form data entry and message.
|
|
98
98
|
* @throws {IError} When isShell=false and an error occurs during the fetch
|
|
99
|
-
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
99
|
+
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
100
|
+
*
|
|
101
|
+
* A file value may be a `File`/`Blob` (a `FileList` too), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which the SDK passes through untouched; or a hand-built {@link IFileValue} / {@link IImageValue}. The three may be mixed in one array. `contentType` is stripped from all of them, and a value of none of these shapes is sent as it came — the endpoint then names the field it cannot read, instead of the SDK throwing before the request.
|
|
102
|
+
*
|
|
103
|
+
* The endpoint wants file values in an **array**: a lone descriptor or `IFileValue` answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` works because the upload result is already one.
|
|
100
104
|
* @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
|
|
101
105
|
*/
|
|
102
106
|
async postFormsData(body, langCode = this.state.lang) {
|
|
@@ -132,23 +136,27 @@ class FormsDataApi extends asyncModules_1.default {
|
|
|
132
136
|
const filesArray = typeof FileList !== 'undefined' && fd.value instanceof FileList
|
|
133
137
|
? Array.from(fd.value)
|
|
134
138
|
: fd.value;
|
|
135
|
-
// If filesArray is an array, upload
|
|
139
|
+
// If filesArray is an array, upload the files it holds asynchronously
|
|
136
140
|
if (Array.isArray(filesArray)) {
|
|
137
|
-
const uploadPromises = filesArray.map((file) =>
|
|
141
|
+
const uploadPromises = filesArray.map((file) =>
|
|
142
|
+
// An entry that is already in storage is passed through: a
|
|
143
|
+
// second upload would send the descriptor itself as the file
|
|
144
|
+
// and the endpoint answers `value[0].filename is required`.
|
|
145
|
+
this._isUploadable(file)
|
|
146
|
+
? fileUploader.upload(file, fd.fileQuery).catch((e) => e)
|
|
147
|
+
: file);
|
|
138
148
|
fd.value = (await Promise.all(uploadPromises)).flat();
|
|
139
149
|
}
|
|
140
150
|
// If fd.value is a single File or Blob, upload it
|
|
141
|
-
else if (
|
|
151
|
+
else if (this._isUploadable(fd.value)) {
|
|
142
152
|
fd.value = await fileUploader
|
|
143
153
|
.upload(fd.value, fd.fileQuery)
|
|
144
154
|
.catch((e) => e); // Catch any errors during upload
|
|
145
155
|
}
|
|
146
156
|
// Remove the 'fileQuery' property from the object after processing
|
|
147
157
|
delete fd.fileQuery;
|
|
148
|
-
// Remove
|
|
149
|
-
fd.value.
|
|
150
|
-
delete file.contentType;
|
|
151
|
-
});
|
|
158
|
+
// Remove the 'contentType' property from the file object because it is not needed and not valid
|
|
159
|
+
fd.value = this._stripContentType(fd.value);
|
|
152
160
|
}
|
|
153
161
|
// Return the processed form data element
|
|
154
162
|
return fd;
|
|
@@ -160,6 +168,42 @@ class FormsDataApi extends asyncModules_1.default {
|
|
|
160
168
|
const validated = await this._validateResponse(result, schema('PostFormResponseSchema'));
|
|
161
169
|
return this._normalizeData(validated);
|
|
162
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* Tells a file the SDK still has to upload from one already in storage.
|
|
173
|
+
* @param {unknown} value - One value of a `file` / `image` / `groupOfImages` field.
|
|
174
|
+
* @returns {boolean} True when the value is a `File` or a `Blob`, which has to be uploaded first.
|
|
175
|
+
* @description Only a `File` or a `Blob` is uploaded. Anything else — above all the
|
|
176
|
+
* descriptor `FileUploading.upload` returns for a file already in storage — is sent
|
|
177
|
+
* as it came: re-uploading it would send the descriptor as the file itself.
|
|
178
|
+
*/
|
|
179
|
+
_isUploadable(value) {
|
|
180
|
+
return ((typeof File !== 'undefined' && value instanceof File) ||
|
|
181
|
+
(typeof Blob !== 'undefined' && value instanceof Blob));
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Removes `contentType` from a file value, which the endpoint does not accept.
|
|
185
|
+
* @param {T} value - Value of a `file` / `image` / `groupOfImages` field, after the uploads.
|
|
186
|
+
* @returns {T} The same value, without `contentType`.
|
|
187
|
+
* @description `FileUploading.upload` returns `contentType` and form data rejects it,
|
|
188
|
+
* so it is stripped from an array of values and from a lone value object alike. A value
|
|
189
|
+
* of any other shape is returned untouched and the endpoint names the field it cannot
|
|
190
|
+
* read — instead of the library dying on `value.map is not a function` before the
|
|
191
|
+
* request is made (CMS-990).
|
|
192
|
+
*/
|
|
193
|
+
_stripContentType(value) {
|
|
194
|
+
const strip = (item) => {
|
|
195
|
+
if (item && typeof item === 'object' && !Array.isArray(item)) {
|
|
196
|
+
delete item.contentType;
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
value.forEach(strip);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
strip(value);
|
|
204
|
+
}
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
163
207
|
/**
|
|
164
208
|
* Drops the date bounds the endpoint refuses to parse.
|
|
165
209
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IError } from '../base/utils';
|
|
2
|
-
import type { IUploadingQuery } from '../file-uploading/fileUploadingInterfaces';
|
|
2
|
+
import type { IUploadingQuery, IUploadingReturn } from '../file-uploading/fileUploadingInterfaces';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for retrieving and posting form data in the system.
|
|
5
5
|
* @interface IFormsData
|
|
@@ -567,7 +567,7 @@ interface ICaptchaValue {
|
|
|
567
567
|
* @property {string} formData[].marker - The marker identifying the form field. Example: "name".
|
|
568
568
|
* @property {string} formData[].type - The type of the form field. Example: "string".
|
|
569
569
|
* @property {string} formData[].value - The value of the form field. Example: "name".
|
|
570
|
-
* @property {IUploadingQuery} [fileQuery] - Optional file query for uploading files.
|
|
570
|
+
* @property {IUploadingQuery} [fileQuery] - Optional file query for uploading files. Kept for compatibility: the SDK reads `fileQuery` from the **file field itself** (see IBodyTypeFile), not from the body, so one set here does not change where a file is uploaded.
|
|
571
571
|
* @example
|
|
572
572
|
{
|
|
573
573
|
"type": "page",
|
|
@@ -715,7 +715,7 @@ interface ITextWithHeaderValue {
|
|
|
715
715
|
* @interface IBodyTypeImageGroupOfImages
|
|
716
716
|
* @property {string} marker - marker name. Example: "avatar".
|
|
717
717
|
* @property {'image' | 'groupOfImages'} type - Type value — must match the attribute type in the set, note the plural in "groupOfImages". Example: "image".
|
|
718
|
-
* @property {object} value -
|
|
718
|
+
* @property {object} value - The attached image. The same three shapes as a `file` field accepts, mixable in one array: a `File`/`Blob` (also a `FileList`), which the SDK uploads first; the descriptor `FileUploading.upload` returns for an image **already in storage**, passed through as it is; or a hand-built {@link IImageValue}. In a SUBMISSION the value must be an **array**, as for `file` — a lone object answers `400 formData's marker '<marker>' value must be an array`. Measured on js-sdk-tests.oneentry.cloud, 2026-10-08 (CMS-990).
|
|
719
719
|
* @example
|
|
720
720
|
[
|
|
721
721
|
{
|
|
@@ -728,12 +728,14 @@ interface ITextWithHeaderValue {
|
|
|
728
728
|
}
|
|
729
729
|
}
|
|
730
730
|
]
|
|
731
|
+
* @property {IUploadingQuery} [fileQuery] - Where the SDK uploads a `File`/`Blob` value to. Read **per field**, not from the body; omitted, the SDK uploads to `page`/`editor` under a random id. Ignored for an image already in storage. Example: `{ "type": "page", "entity": "editor", "id": 3787 }`.
|
|
731
732
|
* @description Represents an image or a group of images with their details, including filename, download link, size, preview link, and parameters for image compression.
|
|
732
733
|
*/
|
|
733
734
|
interface IBodyTypeImageGroupOfImages {
|
|
734
735
|
marker: string;
|
|
735
736
|
type: 'image' | 'groupOfImages';
|
|
736
|
-
value: IImageValue | IImageValue[];
|
|
737
|
+
value: IImageValue | IUploadingReturn | File | Blob | (IImageValue | IUploadingReturn | File | Blob)[];
|
|
738
|
+
fileQuery?: IUploadingQuery;
|
|
737
739
|
}
|
|
738
740
|
/**
|
|
739
741
|
* @interface IImageValueParams
|
|
@@ -764,7 +766,7 @@ interface IImageValue {
|
|
|
764
766
|
* @interface IBodyTypeFile
|
|
765
767
|
* @property {string} marker - marker name. Example: "picture".
|
|
766
768
|
* @property {'file'} type - Type value. Example: "file".
|
|
767
|
-
* @property {object} value - File
|
|
769
|
+
* @property {object} value - The attached file. Three shapes are accepted and may be mixed in one array: a `File`/`Blob` (also a `FileList`), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which is passed through as it is; or a hand-built {@link IFileValue}. In a SUBMISSION the value must be an **array** — a lone descriptor or {@link IFileValue} answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` is fine because the SDK wraps the upload result. A READ returns a single attached file as the object itself. Measured on js-sdk-tests.oneentry.cloud, 2026-10-08 (CMS-990).
|
|
768
770
|
* @example
|
|
769
771
|
[
|
|
770
772
|
{
|
|
@@ -773,12 +775,14 @@ interface IImageValue {
|
|
|
773
775
|
"size": 392585
|
|
774
776
|
}
|
|
775
777
|
]
|
|
778
|
+
* @property {IUploadingQuery} [fileQuery] - Where the SDK uploads a `File`/`Blob` value to. Read **per field**, not from the body; omitted, the SDK uploads to `page`/`editor` under a random id. Ignored for a file already in storage. Example: `{ "type": "page", "entity": "editor", "id": 3787 }`.
|
|
776
779
|
* @description Represents a file with its details, including filename, download link, and size.
|
|
777
780
|
*/
|
|
778
781
|
interface IBodyTypeFile {
|
|
779
782
|
marker: string;
|
|
780
783
|
type: 'file';
|
|
781
|
-
value: IFileValue | IFileValue[];
|
|
784
|
+
value: IFileValue | IUploadingReturn | File | Blob | (IFileValue | IUploadingReturn | File | Blob)[];
|
|
785
|
+
fileQuery?: IUploadingQuery;
|
|
782
786
|
}
|
|
783
787
|
/**
|
|
784
788
|
* @interface IFileValue
|
|
@@ -189,28 +189,130 @@ interface IAttributeSchemaItem {
|
|
|
189
189
|
}
|
|
190
190
|
/**
|
|
191
191
|
* @interface IAttributeValidators
|
|
192
|
-
* @property {object} [requiredValidator] -
|
|
193
|
-
* @property {object} [
|
|
194
|
-
* @property {
|
|
195
|
-
* @property {object} [
|
|
196
|
-
* @
|
|
192
|
+
* @property {object | boolean} [requiredValidator] - Field must be filled in. Shape: `{ strict: boolean }`. Example: `{ strict: true }`.
|
|
193
|
+
* @property {object | boolean} [trimValidator] - Leading and trailing whitespace is stripped from the value. Stored as an empty object when the toggle is on. Example: `{}`.
|
|
194
|
+
* @property {object} [stringInspectionValidator] - Length constraints for string fields. Example: `{ stringLength: 0, stringMin: 2, stringMax: 60 }`.
|
|
195
|
+
* @property {object | boolean} [urlInspectionValidator] - Value must look like a URL. Stored either as `true` or as an object. Example: `true`.
|
|
196
|
+
* @property {object | boolean} [emailInspectionValidator] - Value must look like an e-mail address. Stored either as `true` or as an object. Example: `true`.
|
|
197
|
+
* @property {object} [checkForNumberValidator] - Value must be a number, optionally an integer within bounds. `0` disables a bound. Example: `{ integerOnly: true, minValue: 1, maxValue: 10 }`.
|
|
198
|
+
* @property {object} [roundingNumberValidator] - Rounds the number before storing it. Example: `{ integerOnly: false, numberOfDecimals: 2, direction: 'round' }`.
|
|
199
|
+
* @property {object} [booleanValidator] - Value must equal one of the two declared values. Example: `{ trueValue: 1, falseValue: 0 }`.
|
|
200
|
+
* @property {object} [comparisonValidator] - Compares the value with another attribute or with a constant. Example: `{ compareAttribute: 'notChoosed', compareValue: '10', type: 'number', operator: 'equality' }`.
|
|
201
|
+
* @property {object} [regExpValidator] - Value must match a regular expression; `invert` refuses matches instead. Example: `{ patternValue: '^[0-9]{5}$', invert: false, flags: ['i'] }`.
|
|
202
|
+
* @property {object} [fieldMaskValidator] - Value must match an input mask (`9` digit, `A` upper letter, `a` lower letter, `*` any, `$` one of `()+-`). Example: `{ maskValue: '+9 (999) 999-99-99' }`.
|
|
203
|
+
* @property {object} [checkForAGivenList] - Value must be in the list, or outside it when `notValue` is true. Example: `{ rangeValue: ['red', 'green'], notValue: false }`.
|
|
204
|
+
* @property {object} [defaultValueValidator] - Value substituted when the field is left empty. Example: `{ fieldDefaultValue: 'USD' }`.
|
|
205
|
+
* @property {object} [sizeInPixelsValidator] - Image bounds in pixels; executed by the admin panel. Example: `{ maxX: 1920, maxY: 1080 }`.
|
|
206
|
+
* @property {object} [checkingFilesValidator] - File size bounds and allowed extensions; executed by the admin panel. Example: `{ minValue: 0, maxValue: 5, minUnits: 'kb', maxUnits: 'mb', extensions: ['pdf'] }`.
|
|
207
|
+
* @property {object} [minMaxDateValidator] - Date bounds; executed by the admin panel. Example: `{ minDateTimeValue: '2026-01-01', maxDateTimeValue: '2026-12-31' }`.
|
|
208
|
+
* @property {object} [valueValidator] - The panel's "default value" control; it writes `defaultValueValidator`, and this name is kept because the API accepts and stores it. Example: `{ fieldDefaultValue: 'USD' }`.
|
|
209
|
+
* @property {object} [checkForLettersValidator] - Letters-only check by pattern; executed by the admin panel. Example: `{ patternValue: '^[A-Za-z ]+$' }`.
|
|
210
|
+
* @description Map of validators applied to an attribute or form field, keyed by validator name.
|
|
211
|
+
*
|
|
212
|
+
* These eighteen names are the full set the API accepts in
|
|
213
|
+
* `attributes_sets.schema.<attribute>.validators.<langCode>`; any other name is refused
|
|
214
|
+
* with `400`. The first thirteen are executed by the platform on write, the last five are
|
|
215
|
+
* stored as given and executed by the admin panel.
|
|
216
|
+
*
|
|
217
|
+
* Every validator may also carry `customErrorText` — the message shown instead of the
|
|
218
|
+
* default one when the value is refused.
|
|
197
219
|
*/
|
|
198
220
|
interface IAttributeValidators {
|
|
199
221
|
requiredValidator?: {
|
|
200
|
-
strict
|
|
201
|
-
|
|
222
|
+
strict?: boolean;
|
|
223
|
+
customErrorText?: string;
|
|
224
|
+
} | boolean;
|
|
225
|
+
trimValidator?: {
|
|
226
|
+
strict?: boolean;
|
|
227
|
+
customErrorText?: string;
|
|
228
|
+
} | boolean;
|
|
202
229
|
stringInspectionValidator?: {
|
|
203
|
-
stringMin
|
|
204
|
-
stringMax
|
|
205
|
-
stringLength
|
|
230
|
+
stringMin?: number;
|
|
231
|
+
stringMax?: number;
|
|
232
|
+
stringLength?: number;
|
|
233
|
+
customErrorText?: string;
|
|
234
|
+
};
|
|
235
|
+
urlInspectionValidator?: {
|
|
236
|
+
strict?: boolean;
|
|
237
|
+
customErrorText?: string;
|
|
238
|
+
} | boolean;
|
|
239
|
+
emailInspectionValidator?: {
|
|
240
|
+
strict?: boolean;
|
|
241
|
+
customErrorText?: string;
|
|
242
|
+
} | boolean;
|
|
243
|
+
checkForNumberValidator?: {
|
|
244
|
+
integerOnly?: boolean;
|
|
245
|
+
minValue?: number;
|
|
246
|
+
maxValue?: number;
|
|
247
|
+
customErrorText?: string;
|
|
248
|
+
};
|
|
249
|
+
roundingNumberValidator?: {
|
|
250
|
+
integerOnly?: boolean;
|
|
251
|
+
numberOfDecimals?: number;
|
|
252
|
+
direction?: 'round' | 'up' | 'down' | 'truncate';
|
|
253
|
+
customErrorText?: string;
|
|
254
|
+
};
|
|
255
|
+
booleanValidator?: {
|
|
256
|
+
trueValue?: unknown;
|
|
257
|
+
falseValue?: unknown;
|
|
258
|
+
customErrorText?: string;
|
|
259
|
+
};
|
|
260
|
+
comparisonValidator?: {
|
|
261
|
+
compareAttribute?: string;
|
|
262
|
+
compareValue?: string;
|
|
263
|
+
compareValue2?: string;
|
|
264
|
+
type?: string;
|
|
265
|
+
operator?: string;
|
|
266
|
+
customErrorText?: string;
|
|
267
|
+
};
|
|
268
|
+
regExpValidator?: {
|
|
269
|
+
patternValue?: string;
|
|
270
|
+
invert?: boolean;
|
|
271
|
+
flags?: string[];
|
|
272
|
+
customErrorText?: string;
|
|
273
|
+
};
|
|
274
|
+
fieldMaskValidator?: {
|
|
275
|
+
maskValue?: string;
|
|
276
|
+
customErrorText?: string;
|
|
277
|
+
};
|
|
278
|
+
checkForAGivenList?: {
|
|
279
|
+
rangeValue?: unknown[];
|
|
280
|
+
rangeValue2?: unknown[];
|
|
281
|
+
notValue?: boolean;
|
|
282
|
+
customErrorText?: string;
|
|
206
283
|
};
|
|
207
|
-
emailInspectionValidator?: boolean;
|
|
208
284
|
defaultValueValidator?: {
|
|
285
|
+
fieldDefaultValue?: unknown;
|
|
286
|
+
fieldDefaultValue2?: unknown;
|
|
287
|
+
customErrorText?: string;
|
|
288
|
+
};
|
|
289
|
+
sizeInPixelsValidator?: {
|
|
290
|
+
maxX?: number;
|
|
291
|
+
maxY?: number;
|
|
209
292
|
customErrorText?: string;
|
|
293
|
+
};
|
|
294
|
+
checkingFilesValidator?: {
|
|
295
|
+
minValue?: number;
|
|
296
|
+
maxValue?: number;
|
|
297
|
+
minUnits?: 'kb' | 'mb';
|
|
298
|
+
maxUnits?: 'kb' | 'mb';
|
|
299
|
+
extensions?: string[];
|
|
300
|
+
customErrorText?: string;
|
|
301
|
+
};
|
|
302
|
+
minMaxDateValidator?: {
|
|
303
|
+
minDateTimeValue?: string;
|
|
304
|
+
maxDateTimeValue?: string;
|
|
305
|
+
customErrorText?: string;
|
|
306
|
+
};
|
|
307
|
+
valueValidator?: {
|
|
210
308
|
fieldDefaultValue?: unknown;
|
|
211
309
|
fieldDefaultValue2?: unknown;
|
|
310
|
+
customErrorText?: string;
|
|
311
|
+
};
|
|
312
|
+
checkForLettersValidator?: {
|
|
313
|
+
patternValue?: string;
|
|
314
|
+
customErrorText?: string;
|
|
212
315
|
};
|
|
213
|
-
[key: string]: unknown;
|
|
214
316
|
}
|
|
215
317
|
/**
|
|
216
318
|
* Represents an attribute set entity.
|
package/esm/base/utils.d.ts
CHANGED
|
@@ -96,7 +96,7 @@ interface IConfig {
|
|
|
96
96
|
* @property {boolean} isVisible - Whether the attribute is exposed in the public API/UI. Example: true.
|
|
97
97
|
* @property {string} type - Attribute data type (e.g. "string", "integer", "list", "file", "image").
|
|
98
98
|
* @property {Record<string, unknown>} [settings] - Type-specific configuration (e.g. min/max for numbers, accepted MIME types for files). Optional.
|
|
99
|
-
* @property {Record<string, unknown>} validators - Validation rules applied to the attribute value (e.g. `requiredValidator`, `
|
|
99
|
+
* @property {Record<string, unknown>} validators - Validation rules applied to the attribute value, keyed by validator name (e.g. `requiredValidator`, `regExpValidator`); the full set of names is listed on `IAttributeValidators`. Example: { "requiredValidator": { "strict": true } }.
|
|
100
100
|
* @property {Record<string, IAttributes>} [additionalFields] - Nested sub-attributes attached to this attribute, keyed by marker. Optional.
|
|
101
101
|
* @property {boolean} [isIcon] - Block/preview attribute flag — whether the field is treated as an icon. Optional.
|
|
102
102
|
* @property {boolean} [isProductPreview] - Block/preview attribute flag — whether the field is shown in product preview. Optional.
|
|
@@ -56,10 +56,34 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
|
|
|
56
56
|
* @param {string} [langCode] - Language code. Default: "en_US".
|
|
57
57
|
* @returns {Promise<IPostFormResponse | IError>} Returns an object containing the created form data entry and message.
|
|
58
58
|
* @throws {IError} When isShell=false and an error occurs during the fetch
|
|
59
|
-
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
59
|
+
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
60
|
+
*
|
|
61
|
+
* A file value may be a `File`/`Blob` (a `FileList` too), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which the SDK passes through untouched; or a hand-built {@link IFileValue} / {@link IImageValue}. The three may be mixed in one array. `contentType` is stripped from all of them, and a value of none of these shapes is sent as it came — the endpoint then names the field it cannot read, instead of the SDK throwing before the request.
|
|
62
|
+
*
|
|
63
|
+
* The endpoint wants file values in an **array**: a lone descriptor or `IFileValue` answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` works because the upload result is already one.
|
|
60
64
|
* @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
|
|
61
65
|
*/
|
|
62
66
|
postFormsData(body: IBodyPostFormData, langCode?: string): Promise<IPostFormResponse | IError>;
|
|
67
|
+
/**
|
|
68
|
+
* Tells a file the SDK still has to upload from one already in storage.
|
|
69
|
+
* @param {unknown} value - One value of a `file` / `image` / `groupOfImages` field.
|
|
70
|
+
* @returns {boolean} True when the value is a `File` or a `Blob`, which has to be uploaded first.
|
|
71
|
+
* @description Only a `File` or a `Blob` is uploaded. Anything else — above all the
|
|
72
|
+
* descriptor `FileUploading.upload` returns for a file already in storage — is sent
|
|
73
|
+
* as it came: re-uploading it would send the descriptor as the file itself.
|
|
74
|
+
*/
|
|
75
|
+
private _isUploadable;
|
|
76
|
+
/**
|
|
77
|
+
* Removes `contentType` from a file value, which the endpoint does not accept.
|
|
78
|
+
* @param {T} value - Value of a `file` / `image` / `groupOfImages` field, after the uploads.
|
|
79
|
+
* @returns {T} The same value, without `contentType`.
|
|
80
|
+
* @description `FileUploading.upload` returns `contentType` and form data rejects it,
|
|
81
|
+
* so it is stripped from an array of values and from a lone value object alike. A value
|
|
82
|
+
* of any other shape is returned untouched and the endpoint names the field it cannot
|
|
83
|
+
* read — instead of the library dying on `value.map is not a function` before the
|
|
84
|
+
* request is made (CMS-990).
|
|
85
|
+
*/
|
|
86
|
+
private _stripContentType;
|
|
63
87
|
/**
|
|
64
88
|
* Drops the date bounds the endpoint refuses to parse.
|
|
65
89
|
*
|
|
@@ -58,7 +58,11 @@ export default class FormsDataApi extends AsyncModules {
|
|
|
58
58
|
* @param {string} [langCode] - Language code. Default: "en_US".
|
|
59
59
|
* @returns {Promise<IPostFormResponse | IError>} Returns an object containing the created form data entry and message.
|
|
60
60
|
* @throws {IError} When isShell=false and an error occurs during the fetch
|
|
61
|
-
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
61
|
+
* @description Field values are typed per field type by {@link FormDataType}. For attached files see {@link IImageValue} (`image`, `groupOfImages`) and {@link IFileValue} (`file`) — the shape the endpoint expects, which is **not** what `FileUploading.upload` returns: that object carries `contentType`, which form data rejects.
|
|
62
|
+
*
|
|
63
|
+
* A file value may be a `File`/`Blob` (a `FileList` too), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which the SDK passes through untouched; or a hand-built {@link IFileValue} / {@link IImageValue}. The three may be mixed in one array. `contentType` is stripped from all of them, and a value of none of these shapes is sent as it came — the endpoint then names the field it cannot read, instead of the SDK throwing before the request.
|
|
64
|
+
*
|
|
65
|
+
* The endpoint wants file values in an **array**: a lone descriptor or `IFileValue` answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` works because the upload result is already one.
|
|
62
66
|
* @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
|
|
63
67
|
*/
|
|
64
68
|
async postFormsData(body, langCode = this.state.lang) {
|
|
@@ -94,23 +98,27 @@ export default class FormsDataApi extends AsyncModules {
|
|
|
94
98
|
const filesArray = typeof FileList !== 'undefined' && fd.value instanceof FileList
|
|
95
99
|
? Array.from(fd.value)
|
|
96
100
|
: fd.value;
|
|
97
|
-
// If filesArray is an array, upload
|
|
101
|
+
// If filesArray is an array, upload the files it holds asynchronously
|
|
98
102
|
if (Array.isArray(filesArray)) {
|
|
99
|
-
const uploadPromises = filesArray.map((file) =>
|
|
103
|
+
const uploadPromises = filesArray.map((file) =>
|
|
104
|
+
// An entry that is already in storage is passed through: a
|
|
105
|
+
// second upload would send the descriptor itself as the file
|
|
106
|
+
// and the endpoint answers `value[0].filename is required`.
|
|
107
|
+
this._isUploadable(file)
|
|
108
|
+
? fileUploader.upload(file, fd.fileQuery).catch((e) => e)
|
|
109
|
+
: file);
|
|
100
110
|
fd.value = (await Promise.all(uploadPromises)).flat();
|
|
101
111
|
}
|
|
102
112
|
// If fd.value is a single File or Blob, upload it
|
|
103
|
-
else if (
|
|
113
|
+
else if (this._isUploadable(fd.value)) {
|
|
104
114
|
fd.value = await fileUploader
|
|
105
115
|
.upload(fd.value, fd.fileQuery)
|
|
106
116
|
.catch((e) => e); // Catch any errors during upload
|
|
107
117
|
}
|
|
108
118
|
// Remove the 'fileQuery' property from the object after processing
|
|
109
119
|
delete fd.fileQuery;
|
|
110
|
-
// Remove
|
|
111
|
-
fd.value.
|
|
112
|
-
delete file.contentType;
|
|
113
|
-
});
|
|
120
|
+
// Remove the 'contentType' property from the file object because it is not needed and not valid
|
|
121
|
+
fd.value = this._stripContentType(fd.value);
|
|
114
122
|
}
|
|
115
123
|
// Return the processed form data element
|
|
116
124
|
return fd;
|
|
@@ -122,6 +130,42 @@ export default class FormsDataApi extends AsyncModules {
|
|
|
122
130
|
const validated = await this._validateResponse(result, schema('PostFormResponseSchema'));
|
|
123
131
|
return this._normalizeData(validated);
|
|
124
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Tells a file the SDK still has to upload from one already in storage.
|
|
135
|
+
* @param {unknown} value - One value of a `file` / `image` / `groupOfImages` field.
|
|
136
|
+
* @returns {boolean} True when the value is a `File` or a `Blob`, which has to be uploaded first.
|
|
137
|
+
* @description Only a `File` or a `Blob` is uploaded. Anything else — above all the
|
|
138
|
+
* descriptor `FileUploading.upload` returns for a file already in storage — is sent
|
|
139
|
+
* as it came: re-uploading it would send the descriptor as the file itself.
|
|
140
|
+
*/
|
|
141
|
+
_isUploadable(value) {
|
|
142
|
+
return ((typeof File !== 'undefined' && value instanceof File) ||
|
|
143
|
+
(typeof Blob !== 'undefined' && value instanceof Blob));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Removes `contentType` from a file value, which the endpoint does not accept.
|
|
147
|
+
* @param {T} value - Value of a `file` / `image` / `groupOfImages` field, after the uploads.
|
|
148
|
+
* @returns {T} The same value, without `contentType`.
|
|
149
|
+
* @description `FileUploading.upload` returns `contentType` and form data rejects it,
|
|
150
|
+
* so it is stripped from an array of values and from a lone value object alike. A value
|
|
151
|
+
* of any other shape is returned untouched and the endpoint names the field it cannot
|
|
152
|
+
* read — instead of the library dying on `value.map is not a function` before the
|
|
153
|
+
* request is made (CMS-990).
|
|
154
|
+
*/
|
|
155
|
+
_stripContentType(value) {
|
|
156
|
+
const strip = (item) => {
|
|
157
|
+
if (item && typeof item === 'object' && !Array.isArray(item)) {
|
|
158
|
+
delete item.contentType;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
if (Array.isArray(value)) {
|
|
162
|
+
value.forEach(strip);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
strip(value);
|
|
166
|
+
}
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
125
169
|
/**
|
|
126
170
|
* Drops the date bounds the endpoint refuses to parse.
|
|
127
171
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IError } from '../base/utils.js';
|
|
2
|
-
import type { IUploadingQuery } from '../file-uploading/fileUploadingInterfaces.js';
|
|
2
|
+
import type { IUploadingQuery, IUploadingReturn } from '../file-uploading/fileUploadingInterfaces.js';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for retrieving and posting form data in the system.
|
|
5
5
|
* @interface IFormsData
|
|
@@ -567,7 +567,7 @@ interface ICaptchaValue {
|
|
|
567
567
|
* @property {string} formData[].marker - The marker identifying the form field. Example: "name".
|
|
568
568
|
* @property {string} formData[].type - The type of the form field. Example: "string".
|
|
569
569
|
* @property {string} formData[].value - The value of the form field. Example: "name".
|
|
570
|
-
* @property {IUploadingQuery} [fileQuery] - Optional file query for uploading files.
|
|
570
|
+
* @property {IUploadingQuery} [fileQuery] - Optional file query for uploading files. Kept for compatibility: the SDK reads `fileQuery` from the **file field itself** (see IBodyTypeFile), not from the body, so one set here does not change where a file is uploaded.
|
|
571
571
|
* @example
|
|
572
572
|
{
|
|
573
573
|
"type": "page",
|
|
@@ -715,7 +715,7 @@ interface ITextWithHeaderValue {
|
|
|
715
715
|
* @interface IBodyTypeImageGroupOfImages
|
|
716
716
|
* @property {string} marker - marker name. Example: "avatar".
|
|
717
717
|
* @property {'image' | 'groupOfImages'} type - Type value — must match the attribute type in the set, note the plural in "groupOfImages". Example: "image".
|
|
718
|
-
* @property {object} value -
|
|
718
|
+
* @property {object} value - The attached image. The same three shapes as a `file` field accepts, mixable in one array: a `File`/`Blob` (also a `FileList`), which the SDK uploads first; the descriptor `FileUploading.upload` returns for an image **already in storage**, passed through as it is; or a hand-built {@link IImageValue}. In a SUBMISSION the value must be an **array**, as for `file` — a lone object answers `400 formData's marker '<marker>' value must be an array`. Measured on js-sdk-tests.oneentry.cloud, 2026-10-08 (CMS-990).
|
|
719
719
|
* @example
|
|
720
720
|
[
|
|
721
721
|
{
|
|
@@ -728,12 +728,14 @@ interface ITextWithHeaderValue {
|
|
|
728
728
|
}
|
|
729
729
|
}
|
|
730
730
|
]
|
|
731
|
+
* @property {IUploadingQuery} [fileQuery] - Where the SDK uploads a `File`/`Blob` value to. Read **per field**, not from the body; omitted, the SDK uploads to `page`/`editor` under a random id. Ignored for an image already in storage. Example: `{ "type": "page", "entity": "editor", "id": 3787 }`.
|
|
731
732
|
* @description Represents an image or a group of images with their details, including filename, download link, size, preview link, and parameters for image compression.
|
|
732
733
|
*/
|
|
733
734
|
interface IBodyTypeImageGroupOfImages {
|
|
734
735
|
marker: string;
|
|
735
736
|
type: 'image' | 'groupOfImages';
|
|
736
|
-
value: IImageValue | IImageValue[];
|
|
737
|
+
value: IImageValue | IUploadingReturn | File | Blob | (IImageValue | IUploadingReturn | File | Blob)[];
|
|
738
|
+
fileQuery?: IUploadingQuery;
|
|
737
739
|
}
|
|
738
740
|
/**
|
|
739
741
|
* @interface IImageValueParams
|
|
@@ -764,7 +766,7 @@ interface IImageValue {
|
|
|
764
766
|
* @interface IBodyTypeFile
|
|
765
767
|
* @property {string} marker - marker name. Example: "picture".
|
|
766
768
|
* @property {'file'} type - Type value. Example: "file".
|
|
767
|
-
* @property {object} value - File
|
|
769
|
+
* @property {object} value - The attached file. Three shapes are accepted and may be mixed in one array: a `File`/`Blob` (also a `FileList`), which the SDK uploads first; the descriptor `FileUploading.upload` returns for a file **already in storage**, which is passed through as it is; or a hand-built {@link IFileValue}. In a SUBMISSION the value must be an **array** — a lone descriptor or {@link IFileValue} answers `400 formData's marker '<marker>' value must be an array`, while a lone `File`/`Blob` is fine because the SDK wraps the upload result. A READ returns a single attached file as the object itself. Measured on js-sdk-tests.oneentry.cloud, 2026-10-08 (CMS-990).
|
|
768
770
|
* @example
|
|
769
771
|
[
|
|
770
772
|
{
|
|
@@ -773,12 +775,14 @@ interface IImageValue {
|
|
|
773
775
|
"size": 392585
|
|
774
776
|
}
|
|
775
777
|
]
|
|
778
|
+
* @property {IUploadingQuery} [fileQuery] - Where the SDK uploads a `File`/`Blob` value to. Read **per field**, not from the body; omitted, the SDK uploads to `page`/`editor` under a random id. Ignored for a file already in storage. Example: `{ "type": "page", "entity": "editor", "id": 3787 }`.
|
|
776
779
|
* @description Represents a file with its details, including filename, download link, and size.
|
|
777
780
|
*/
|
|
778
781
|
interface IBodyTypeFile {
|
|
779
782
|
marker: string;
|
|
780
783
|
type: 'file';
|
|
781
|
-
value: IFileValue | IFileValue[];
|
|
784
|
+
value: IFileValue | IUploadingReturn | File | Blob | (IFileValue | IUploadingReturn | File | Blob)[];
|
|
785
|
+
fileQuery?: IUploadingQuery;
|
|
782
786
|
}
|
|
783
787
|
/**
|
|
784
788
|
* @interface IFileValue
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oneentry",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.171",
|
|
4
4
|
"description": "OneEntry NPM package",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"prepublishOnly": "node ../scripts/smoke-pack.js --files-only",
|
|
51
|
-
"postpublish": "node ../scripts/verify-published.js --named defineOneEntry --expect 1.0.
|
|
51
|
+
"postpublish": "node ../scripts/verify-published.js --named defineOneEntry --expect 1.0.171"
|
|
52
52
|
},
|
|
53
53
|
"sideEffects": false,
|
|
54
54
|
"files": [
|