oneentry 1.0.164 → 1.0.165

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 CHANGED
@@ -1,5 +1,19 @@
1
1
  # SDK Change Log
2
2
 
3
+ ## v.1.0.165
4
+
5
+ ### What's New
6
+
7
+ - **`AttributeType` now includes `json`.** The platform has a `json` attribute type, but the union listed every other type and not that one. Because `IAttributesSetsEntity.type` and `IAttributeSchemaItem.type` (and, through them, `IFormAttribute.type`) are typed by that union, a set containing a `json` field made `switch (field.type)` miss the branch and `field.type === 'json'` fail to compile with "This comparison appears to be unintentional" — the type the API actually sends was the one value the compiler refused to accept. Types only; the data has always come through.
8
+
9
+ ### What's Fixed
10
+
11
+ - **FormData > `getFormsDataByMarker` no longer fails on an empty date filter.** `IFormsDataFilter` documents an empty string as "no bound" on `dateFrom`/`dateTo`, and that is how the endpoint used to read it — it now validates the pair as dates first and answers `400 dateFrom must be a valid date in format "YYYY-MM-DD" or "YYYY-MM-DD HH:MM:SS"`. So a filter built the documented way (`{ status: ['approved'], dateFrom: '', dateTo: '' }`) took down the whole request: no records, and an error about a bound the caller deliberately did not set. Every other field still treats `""` as "no filter", which made the failure look like anything but the date. The SDK now strips empty `dateFrom`/`dateTo` from the body before sending, restoring the documented meaning; a non-empty value the API cannot parse is still rejected, as it should be.
12
+
13
+ ### What's Deleted
14
+
15
+ - **`textEditor` is gone from the text-attribute narrowing.** No such attribute type exists on the platform — rich text is `text` — but `IStringAttributeValue.type` declared `'string' | 'text' | 'textEditor'` and `isStringAttribute` checked for it. A value that never arrives cost nothing at runtime, yet it read as documentation: the union told everyone the CMS had a separate rich-text type, so `case 'textEditor'` branches were written and silently never taken, and someone looking for that type in the panel could not find it. `IStringAttributeValue.type` is now `'string' | 'text'`, the guard drops the third comparison, and the test case for it is removed.
16
+
3
17
  ## v.1.0.164
4
18
 
5
19
  ### What's Fixed
@@ -77,7 +77,7 @@ interface IListTitleExtended {
77
77
  * @type {AttributeType}
78
78
  * @description This type defines the possible values for attribute types used in the system.
79
79
  */
80
- type AttributeType = 'string' | 'text' | 'textWithHeader' | 'integer' | 'real' | 'float' | 'dateTime' | 'date' | 'time' | 'file' | 'image' | 'groupOfImages' | 'radioButton' | 'list' | 'button' | 'spam' | 'entity' | 'timeInterval';
80
+ type AttributeType = 'string' | 'text' | 'textWithHeader' | 'integer' | 'real' | 'float' | 'dateTime' | 'date' | 'time' | 'file' | 'image' | 'groupOfImages' | 'radioButton' | 'list' | 'button' | 'spam' | 'entity' | 'timeInterval' | 'json';
81
81
  /**
82
82
  * Represents an attribute set entity.
83
83
  * @interface IAttributesSetsEntity
@@ -61,7 +61,7 @@ export declare function getAttributeFile(attr: IAttributeValue | undefined): IAt
61
61
  /**
62
62
  * Narrows an attribute value to a text attribute.
63
63
  * @param {IAttributeValue | undefined} attr - The attribute value to test.
64
- * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
64
+ * @returns {boolean} True when the attribute is a `string` or `text` carrying a string (or nothing).
65
65
  */
66
66
  export declare function isStringAttribute(attr: IAttributeValue | undefined): attr is IStringAttributeValue;
67
67
  /**
@@ -101,13 +101,11 @@ function getAttributeFile(attr) {
101
101
  /**
102
102
  * Narrows an attribute value to a text attribute.
103
103
  * @param {IAttributeValue | undefined} attr - The attribute value to test.
104
- * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
104
+ * @returns {boolean} True when the attribute is a `string` or `text` carrying a string (or nothing).
105
105
  */
106
106
  function isStringAttribute(attr) {
107
107
  return (!!attr &&
108
- (attr.type === 'string' ||
109
- attr.type === 'text' ||
110
- attr.type === 'textEditor') &&
108
+ (attr.type === 'string' || attr.type === 'text') &&
111
109
  (attr.value === null || typeof attr.value === 'string'));
112
110
  }
113
111
  /**
@@ -325,12 +325,12 @@ interface IFileAttributeValue extends IAttributeValue {
325
325
  }
326
326
  /**
327
327
  * @interface IStringAttributeValue
328
- * @property {'string' | 'text' | 'textEditor'} type - Discriminant identifying the attribute as text-bearing.
328
+ * @property {'string' | 'text'} type - Discriminant identifying the attribute as text-bearing.
329
329
  * @property {string | null} value - The text; `null` when no value is set.
330
330
  * @description {@link IAttributeValue} narrowed to text attributes. Narrow to it with `isStringAttribute`.
331
331
  */
332
332
  interface IStringAttributeValue extends IAttributeValue {
333
- type: 'string' | 'text' | 'textEditor';
333
+ type: 'string' | 'text';
334
334
  value: string | null;
335
335
  }
336
336
  /**
@@ -60,6 +60,21 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
60
60
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
61
61
  */
62
62
  postFormsData(body: IBodyPostFormData, langCode?: string): Promise<IPostFormResponse | IError>;
63
+ /**
64
+ * Drops the date bounds the endpoint refuses to parse.
65
+ *
66
+ * An empty string means "no filter" on every field of {@link IFormsDataFilter},
67
+ * and that is still how `entityIdentifier`, `userIdentifier` and an empty
68
+ * `status` array behave. The date pair is the exception: the endpoint now runs
69
+ * `dateFrom` / `dateTo` through a date validator before it builds the filter,
70
+ * so `dateFrom: ''` no longer means "no bound" — it fails the whole request
71
+ * with `400 dateFrom must be a valid date in format "YYYY-MM-DD"…` and takes
72
+ * the records down with it. An empty bound is therefore removed from the body
73
+ * rather than sent, which the API reads as "no bound", the documented meaning.
74
+ * @param {IFormsDataFilter} body - Filter body as passed by the caller.
75
+ * @returns {IFormsDataFilter} The same filter without empty date bounds.
76
+ */
77
+ private _stripEmptyDates;
63
78
  /**
64
79
  * Get one object of form data by marker.
65
80
  * @handleName getFormsDataByMarker
@@ -79,8 +94,8 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
79
94
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
80
95
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
81
96
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
82
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An unparsable value fails the request with a `500`. Example: "2025-01-01".
83
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. Example: "2025-12-31".
97
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
98
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
84
99
  * @param {number} [isExtended] - Flag for getting additional fields. Example: 1.
85
100
  * @param {string} [langCode] - Language code. Default: "en_US".
86
101
  * @param {number} [offset] - Parameter for pagination. Default: 0.
@@ -90,6 +105,8 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
90
105
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
91
106
  *
92
107
  * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
108
+ *
109
+ * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
93
110
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
94
111
  */
95
112
  getFormsDataByMarker(marker: string, formModuleConfigId: number, body?: IFormsDataFilter, isExtended?: number, langCode?: string, offset?: number, limit?: number): Promise<IFormsByMarkerDataEntity | IError>;
@@ -160,6 +160,28 @@ class FormsDataApi extends asyncModules_1.default {
160
160
  const validated = await this._validateResponse(result, schema('PostFormResponseSchema'));
161
161
  return this._normalizeData(validated);
162
162
  }
163
+ /**
164
+ * Drops the date bounds the endpoint refuses to parse.
165
+ *
166
+ * An empty string means "no filter" on every field of {@link IFormsDataFilter},
167
+ * and that is still how `entityIdentifier`, `userIdentifier` and an empty
168
+ * `status` array behave. The date pair is the exception: the endpoint now runs
169
+ * `dateFrom` / `dateTo` through a date validator before it builds the filter,
170
+ * so `dateFrom: ''` no longer means "no bound" — it fails the whole request
171
+ * with `400 dateFrom must be a valid date in format "YYYY-MM-DD"…` and takes
172
+ * the records down with it. An empty bound is therefore removed from the body
173
+ * rather than sent, which the API reads as "no bound", the documented meaning.
174
+ * @param {IFormsDataFilter} body - Filter body as passed by the caller.
175
+ * @returns {IFormsDataFilter} The same filter without empty date bounds.
176
+ */
177
+ _stripEmptyDates(body) {
178
+ const { dateFrom, dateTo, ...rest } = body;
179
+ return {
180
+ ...rest,
181
+ ...(dateFrom ? { dateFrom } : {}),
182
+ ...(dateTo ? { dateTo } : {}),
183
+ };
184
+ }
163
185
  /**
164
186
  * Get one object of form data by marker.
165
187
  * @handleName getFormsDataByMarker
@@ -179,8 +201,8 @@ class FormsDataApi extends asyncModules_1.default {
179
201
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
180
202
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
181
203
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
182
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An unparsable value fails the request with a `500`. Example: "2025-01-01".
183
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. Example: "2025-12-31".
204
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
205
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
184
206
  * @param {number} [isExtended] - Flag for getting additional fields. Example: 1.
185
207
  * @param {string} [langCode] - Language code. Default: "en_US".
186
208
  * @param {number} [offset] - Parameter for pagination. Default: 0.
@@ -190,10 +212,12 @@ class FormsDataApi extends asyncModules_1.default {
190
212
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
191
213
  *
192
214
  * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
215
+ *
216
+ * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
193
217
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
194
218
  */
195
219
  async getFormsDataByMarker(marker, formModuleConfigId, body = {}, isExtended = 0, langCode = this.state.lang, offset = 0, limit = 30) {
196
- const result = await this._fetchPost(`/marker/${marker}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, body);
220
+ const result = await this._fetchPost(`/marker/${marker}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, this._stripEmptyDates(body));
197
221
  // Validate response if validation is enabled
198
222
  const validated = await this._validateResponse(result, schema('FormsByMarkerDataResponseSchema'));
199
223
  return this._normalizeData(validated, langCode);
@@ -52,7 +52,7 @@ interface IFormsData {
52
52
  * @handleName getFormsDataByMarker
53
53
  * @param {string} marker - The marker identifying the form data. Example: "contact_form_data".
54
54
  * @param {number} formModuleConfigId - The form module configuration ID. Example: 4.
55
- * @param {IFormsDataFilter} [body] - Filter for the records to return. Default: {}. Every field is optional; an omitted or empty one is not applied. Valid `status` values: "sent", "moderation", "approved", "banned", "deleted".
55
+ * @param {IFormsDataFilter} [body] - Filter for the records to return. Default: {}. Every field is optional; an omitted or empty one is not applied — an empty `dateFrom`/`dateTo` is stripped from the body, because the endpoint rejects an empty date with a `400`. Valid `status` values: "sent", "moderation", "approved", "banned", "deleted".
56
56
  * @example
57
57
  {
58
58
  "entityIdentifier": "blog",
@@ -113,8 +113,8 @@ type FormDataStatus = 'sent' | 'moderation' | 'approved' | 'banned' | 'deleted';
113
113
  * @property {number} [parentId] - Identifier of the parent record — the way to fetch replies to one comment. Example: 10.
114
114
  * @property {string} [userIdentifier] - Text identifier of the sender; an empty string means "no filter". Example: "admin".
115
115
  * @property {FormDataStatus[]} [status] - Moderation statuses to keep. Must be an array — a bare string is rejected with `400`. An empty array means "no filter". Example: ["approved"].
116
- * @property {string} [dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound". A value the API cannot parse fails the request with a `500`. Example: "2025-01-01".
117
- * @property {string} [dateTo] - Upper bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound". Example: "2025-12-31".
116
+ * @property {string} [dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound" — `getFormsDataByMarker` strips it from the body, since the endpoint rejects an empty date with a `400`. A non-empty value the API cannot parse still fails the request. Example: "2025-01-01".
117
+ * @property {string} [dateTo] - Upper bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
118
118
  * @description Filter for reading form submissions. Every field is optional and an omitted one is simply not applied.
119
119
  *
120
120
  * Typed rather than left as `object` on purpose: the API **ignores** a field it
@@ -77,7 +77,7 @@ interface IListTitleExtended {
77
77
  * @type {AttributeType}
78
78
  * @description This type defines the possible values for attribute types used in the system.
79
79
  */
80
- type AttributeType = 'string' | 'text' | 'textWithHeader' | 'integer' | 'real' | 'float' | 'dateTime' | 'date' | 'time' | 'file' | 'image' | 'groupOfImages' | 'radioButton' | 'list' | 'button' | 'spam' | 'entity' | 'timeInterval';
80
+ type AttributeType = 'string' | 'text' | 'textWithHeader' | 'integer' | 'real' | 'float' | 'dateTime' | 'date' | 'time' | 'file' | 'image' | 'groupOfImages' | 'radioButton' | 'list' | 'button' | 'spam' | 'entity' | 'timeInterval' | 'json';
81
81
  /**
82
82
  * Represents an attribute set entity.
83
83
  * @interface IAttributesSetsEntity
@@ -61,7 +61,7 @@ export declare function getAttributeFile(attr: IAttributeValue | undefined): IAt
61
61
  /**
62
62
  * Narrows an attribute value to a text attribute.
63
63
  * @param {IAttributeValue | undefined} attr - The attribute value to test.
64
- * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
64
+ * @returns {boolean} True when the attribute is a `string` or `text` carrying a string (or nothing).
65
65
  */
66
66
  export declare function isStringAttribute(attr: IAttributeValue | undefined): attr is IStringAttributeValue;
67
67
  /**
@@ -92,13 +92,11 @@ export function getAttributeFile(attr) {
92
92
  /**
93
93
  * Narrows an attribute value to a text attribute.
94
94
  * @param {IAttributeValue | undefined} attr - The attribute value to test.
95
- * @returns {boolean} True when the attribute is a `string`, `text` or `textEditor` carrying a string (or nothing).
95
+ * @returns {boolean} True when the attribute is a `string` or `text` carrying a string (or nothing).
96
96
  */
97
97
  export function isStringAttribute(attr) {
98
98
  return (!!attr &&
99
- (attr.type === 'string' ||
100
- attr.type === 'text' ||
101
- attr.type === 'textEditor') &&
99
+ (attr.type === 'string' || attr.type === 'text') &&
102
100
  (attr.value === null || typeof attr.value === 'string'));
103
101
  }
104
102
  /**
@@ -325,12 +325,12 @@ interface IFileAttributeValue extends IAttributeValue {
325
325
  }
326
326
  /**
327
327
  * @interface IStringAttributeValue
328
- * @property {'string' | 'text' | 'textEditor'} type - Discriminant identifying the attribute as text-bearing.
328
+ * @property {'string' | 'text'} type - Discriminant identifying the attribute as text-bearing.
329
329
  * @property {string | null} value - The text; `null` when no value is set.
330
330
  * @description {@link IAttributeValue} narrowed to text attributes. Narrow to it with `isStringAttribute`.
331
331
  */
332
332
  interface IStringAttributeValue extends IAttributeValue {
333
- type: 'string' | 'text' | 'textEditor';
333
+ type: 'string' | 'text';
334
334
  value: string | null;
335
335
  }
336
336
  /**
@@ -60,6 +60,21 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
60
60
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/postFormsData postFormsData} documentation.
61
61
  */
62
62
  postFormsData(body: IBodyPostFormData, langCode?: string): Promise<IPostFormResponse | IError>;
63
+ /**
64
+ * Drops the date bounds the endpoint refuses to parse.
65
+ *
66
+ * An empty string means "no filter" on every field of {@link IFormsDataFilter},
67
+ * and that is still how `entityIdentifier`, `userIdentifier` and an empty
68
+ * `status` array behave. The date pair is the exception: the endpoint now runs
69
+ * `dateFrom` / `dateTo` through a date validator before it builds the filter,
70
+ * so `dateFrom: ''` no longer means "no bound" — it fails the whole request
71
+ * with `400 dateFrom must be a valid date in format "YYYY-MM-DD"…` and takes
72
+ * the records down with it. An empty bound is therefore removed from the body
73
+ * rather than sent, which the API reads as "no bound", the documented meaning.
74
+ * @param {IFormsDataFilter} body - Filter body as passed by the caller.
75
+ * @returns {IFormsDataFilter} The same filter without empty date bounds.
76
+ */
77
+ private _stripEmptyDates;
63
78
  /**
64
79
  * Get one object of form data by marker.
65
80
  * @handleName getFormsDataByMarker
@@ -79,8 +94,8 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
79
94
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
80
95
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
81
96
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
82
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An unparsable value fails the request with a `500`. Example: "2025-01-01".
83
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. Example: "2025-12-31".
97
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
98
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
84
99
  * @param {number} [isExtended] - Flag for getting additional fields. Example: 1.
85
100
  * @param {string} [langCode] - Language code. Default: "en_US".
86
101
  * @param {number} [offset] - Parameter for pagination. Default: 0.
@@ -90,6 +105,8 @@ export default class FormsDataApi extends AsyncModules implements IFormsData {
90
105
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
91
106
  *
92
107
  * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
108
+ *
109
+ * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
93
110
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
94
111
  */
95
112
  getFormsDataByMarker(marker: string, formModuleConfigId: number, body?: IFormsDataFilter, isExtended?: number, langCode?: string, offset?: number, limit?: number): Promise<IFormsByMarkerDataEntity | IError>;
@@ -122,6 +122,28 @@ export default class FormsDataApi extends AsyncModules {
122
122
  const validated = await this._validateResponse(result, schema('PostFormResponseSchema'));
123
123
  return this._normalizeData(validated);
124
124
  }
125
+ /**
126
+ * Drops the date bounds the endpoint refuses to parse.
127
+ *
128
+ * An empty string means "no filter" on every field of {@link IFormsDataFilter},
129
+ * and that is still how `entityIdentifier`, `userIdentifier` and an empty
130
+ * `status` array behave. The date pair is the exception: the endpoint now runs
131
+ * `dateFrom` / `dateTo` through a date validator before it builds the filter,
132
+ * so `dateFrom: ''` no longer means "no bound" — it fails the whole request
133
+ * with `400 dateFrom must be a valid date in format "YYYY-MM-DD"…` and takes
134
+ * the records down with it. An empty bound is therefore removed from the body
135
+ * rather than sent, which the API reads as "no bound", the documented meaning.
136
+ * @param {IFormsDataFilter} body - Filter body as passed by the caller.
137
+ * @returns {IFormsDataFilter} The same filter without empty date bounds.
138
+ */
139
+ _stripEmptyDates(body) {
140
+ const { dateFrom, dateTo, ...rest } = body;
141
+ return {
142
+ ...rest,
143
+ ...(dateFrom ? { dateFrom } : {}),
144
+ ...(dateTo ? { dateTo } : {}),
145
+ };
146
+ }
125
147
  /**
126
148
  * Get one object of form data by marker.
127
149
  * @handleName getFormsDataByMarker
@@ -141,8 +163,8 @@ export default class FormsDataApi extends AsyncModules {
141
163
  * @param {number} [body.parentId] - Identifier of the parent record, to fetch replies to one submission. Example: 10.
142
164
  * @param {string} [body.userIdentifier] - Text identifier of the sender. Example: "admin".
143
165
  * @param {FormDataStatus[]} [body.status] - Moderation statuses to keep: "sent", "moderation", "approved", "banned", "deleted". Must be an array; anything outside the set is rejected with `400 each value in status must be a valid enum value`. Example: ["approved"].
144
- * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An unparsable value fails the request with a `500`. Example: "2025-01-01".
145
- * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. Example: "2025-12-31".
166
+ * @param {string} [body.dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound" — the SDK removes it from the body, because the endpoint answers `400 dateFrom must be a valid date in format "YYYY-MM-DD"` to one. An unparsable non-empty value still fails the request. Example: "2025-01-01".
167
+ * @param {string} [body.dateTo] - Upper bound of the submission date, `YYYY-MM-DD`. An empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
146
168
  * @param {number} [isExtended] - Flag for getting additional fields. Example: 1.
147
169
  * @param {string} [langCode] - Language code. Default: "en_US".
148
170
  * @param {number} [offset] - Parameter for pagination. Default: 0.
@@ -152,10 +174,12 @@ export default class FormsDataApi extends AsyncModules {
152
174
  * @description Each record's `formData` comes back **already unwrapped from its locale**. The API sends `formData: { "en_US": [ … ] }`; the SDK normalizes the response and hands over the array for `langCode`, so read `record.formData` — `record.formData[langCode]` is `undefined` and yields an empty list with no error. This holds for both values of `isExtended`.
153
175
  *
154
176
  * The filter body is typed for a reason: the API silently ignores a field it does not know, so a misspelled `statuses` returns every record — unmoderated ones included — and the code looks like it works.
177
+ *
178
+ * Empty `dateFrom` / `dateTo` are stripped from the body before it is sent: the endpoint validates the pair as dates and rejects an empty string with a `400`, while every other field still treats "" as "no filter".
155
179
  * @see {@link https://js-sdk.oneentry.cloud/docs/forms-data/getFormsDataByMarker getFormsDataByMarker} documentation.
156
180
  */
157
181
  async getFormsDataByMarker(marker, formModuleConfigId, body = {}, isExtended = 0, langCode = this.state.lang, offset = 0, limit = 30) {
158
- const result = await this._fetchPost(`/marker/${marker}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, body);
182
+ const result = await this._fetchPost(`/marker/${marker}?formModuleConfigId=${formModuleConfigId}&isExtended=${isExtended}&langCode=${langCode}&offset=${offset}&limit=${limit}`, this._stripEmptyDates(body));
159
183
  // Validate response if validation is enabled
160
184
  const validated = await this._validateResponse(result, schema('FormsByMarkerDataResponseSchema'));
161
185
  return this._normalizeData(validated, langCode);
@@ -52,7 +52,7 @@ interface IFormsData {
52
52
  * @handleName getFormsDataByMarker
53
53
  * @param {string} marker - The marker identifying the form data. Example: "contact_form_data".
54
54
  * @param {number} formModuleConfigId - The form module configuration ID. Example: 4.
55
- * @param {IFormsDataFilter} [body] - Filter for the records to return. Default: {}. Every field is optional; an omitted or empty one is not applied. Valid `status` values: "sent", "moderation", "approved", "banned", "deleted".
55
+ * @param {IFormsDataFilter} [body] - Filter for the records to return. Default: {}. Every field is optional; an omitted or empty one is not applied — an empty `dateFrom`/`dateTo` is stripped from the body, because the endpoint rejects an empty date with a `400`. Valid `status` values: "sent", "moderation", "approved", "banned", "deleted".
56
56
  * @example
57
57
  {
58
58
  "entityIdentifier": "blog",
@@ -113,8 +113,8 @@ type FormDataStatus = 'sent' | 'moderation' | 'approved' | 'banned' | 'deleted';
113
113
  * @property {number} [parentId] - Identifier of the parent record — the way to fetch replies to one comment. Example: 10.
114
114
  * @property {string} [userIdentifier] - Text identifier of the sender; an empty string means "no filter". Example: "admin".
115
115
  * @property {FormDataStatus[]} [status] - Moderation statuses to keep. Must be an array — a bare string is rejected with `400`. An empty array means "no filter". Example: ["approved"].
116
- * @property {string} [dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound". A value the API cannot parse fails the request with a `500`. Example: "2025-01-01".
117
- * @property {string} [dateTo] - Upper bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound". Example: "2025-12-31".
116
+ * @property {string} [dateFrom] - Lower bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound" — `getFormsDataByMarker` strips it from the body, since the endpoint rejects an empty date with a `400`. A non-empty value the API cannot parse still fails the request. Example: "2025-01-01".
117
+ * @property {string} [dateTo] - Upper bound of the submission date, `YYYY-MM-DD`; an empty string means "no bound", handled like `dateFrom`. Example: "2025-12-31".
118
118
  * @description Filter for reading form submissions. Every field is optional and an omitted one is simply not applied.
119
119
  *
120
120
  * Typed rather than left as `object` on purpose: the API **ignores** a field it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oneentry",
3
- "version": "1.0.164",
3
+ "version": "1.0.165",
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.164"
51
+ "postpublish": "node ../scripts/verify-published.js --named defineOneEntry --expect 1.0.165"
52
52
  },
53
53
  "sideEffects": false,
54
54
  "files": [