@capillarytech/creatives-library 8.0.114-alpha.1 → 8.0.114
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/package.json +1 -1
- package/utils/commonUtils.js +3 -359
- package/utils/tagValidations.js +5 -20
- package/utils/tests/commonUtil.test.js +171 -474
- package/utils/tests/tagValidations.test.js +2 -89
- package/v2Components/ErrorInfoNote/index.js +46 -114
- package/v2Components/ErrorInfoNote/messages.js +0 -25
- package/v2Components/ErrorInfoNote/style.scss +1 -14
- package/v2Components/FormBuilder/index.js +127 -204
- package/v2Components/FormBuilder/messages.js +1 -1
- package/v2Containers/Cap/reducer.js +4 -4
- package/v2Containers/CreativesContainer/SlideBoxContent.js +3 -23
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +1 -3
- package/v2Containers/CreativesContainer/constants.js +1 -4
- package/v2Containers/CreativesContainer/index.js +19 -44
- package/v2Containers/CreativesContainer/messages.js +0 -4
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +3 -21
- package/v2Containers/Ebill/index.js +3 -3
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +1 -1
- package/v2Containers/InApp/index.js +50 -123
- package/v2Containers/InApp/tests/index.test.js +1 -1
- package/v2Containers/InApp/tests/sagas.test.js +1 -1
- package/v2Containers/InApp/utils.js +0 -37
- package/v2Containers/MobilePush/Create/index.js +20 -24
- package/v2Containers/MobilePush/Edit/index.js +2 -6
- package/v2Containers/MobilepushWrapper/index.js +0 -2
- package/v2Containers/Sms/Create/index.js +0 -1
- package/v2Containers/Sms/Edit/index.js +0 -2
- package/v2Containers/SmsWrapper/index.js +0 -2
- package/v2Containers/Whatsapp/constants.js +1 -1
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +57476 -0
- package/v2Containers/Whatsapp/tests/index.test.js +88 -0
- package/v2Components/ErrorInfoNote/ErrorTypeRenderer.js +0 -127
- package/v2Components/ErrorInfoNote/ErrorTypeRenderer.test.js +0 -147
- package/v2Components/ErrorInfoNote/utils.js +0 -38
- package/v2Components/ErrorInfoNote/utils.test.js +0 -156
- package/v2Containers/InApp/tests/utils.test.js +0 -41
package/package.json
CHANGED
package/utils/commonUtils.js
CHANGED
|
@@ -1,22 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { FormattedMessage } from 'react-intl';
|
|
3
3
|
import get from 'lodash/get';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
EDIT,
|
|
8
|
-
EMAIL,
|
|
9
|
-
INAPP,
|
|
10
|
-
PREVIEW,
|
|
11
|
-
} from "../v2Containers/App/constants";
|
|
12
|
-
import {
|
|
13
|
-
MOBILE_PUSH,
|
|
14
|
-
SMS,
|
|
15
|
-
ANDROID,
|
|
16
|
-
IOS,
|
|
17
|
-
} from "../v2Containers/CreativesContainer/constants";
|
|
18
|
-
import { GLOBAL_CONVERT_OPTIONS } from "../v2Components/FormBuilder/constants";
|
|
19
|
-
import { checkSupport, extractNames } from "./tagValidations";
|
|
4
|
+
import { EMBEDDED } from '../v2Containers/Whatsapp/constants';
|
|
5
|
+
import { EDIT, PREVIEW } from '../v2Containers/App/constants';
|
|
6
|
+
|
|
20
7
|
export const apiMessageFormatHandler = (id, fallback) => (
|
|
21
8
|
<FormattedMessage id={id} defaultMessage={fallback} />
|
|
22
9
|
);
|
|
@@ -96,346 +83,3 @@ export const transformCustomFieldsData = (customFields) => {
|
|
|
96
83
|
};
|
|
97
84
|
|
|
98
85
|
export const isTagIncluded = (value) => value && value.includes('{{') && value.includes('}}');
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
*
|
|
103
|
-
* @param {*} channel
|
|
104
|
-
* @param {*} formData
|
|
105
|
-
* @returns
|
|
106
|
-
*/
|
|
107
|
-
export const getChannelData = (channel, formData, baseLanguage) => {
|
|
108
|
-
switch (channel?.toUpperCase()) {
|
|
109
|
-
case EMAIL.toUpperCase():
|
|
110
|
-
return convert(
|
|
111
|
-
formData?.base?.[baseLanguage]?.["template-content"] || "",
|
|
112
|
-
GLOBAL_CONVERT_OPTIONS
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
case SMS:
|
|
116
|
-
return (
|
|
117
|
-
`${formData?.base?.["sms-editor"]} ${formData?.["template-name"]}` || ""
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
default:
|
|
121
|
-
return JSON.stringify(formData);
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Validates liquid template content for a given channel and options.
|
|
127
|
-
* @param {string} content - The content to validate.
|
|
128
|
-
* @param {string} channel - Channel type (e.g., EMAIL, SMS, MOBILE_PUSH).
|
|
129
|
-
* @param {object} options - Validation options and callbacks.
|
|
130
|
-
* @returns {Promise} Resolves to the validation result.
|
|
131
|
-
*/
|
|
132
|
-
export const validateLiquidTemplateContent = async (
|
|
133
|
-
content,
|
|
134
|
-
options
|
|
135
|
-
) => {
|
|
136
|
-
const {
|
|
137
|
-
getLiquidTags,
|
|
138
|
-
formatMessage,
|
|
139
|
-
messages,
|
|
140
|
-
onError = () => {},
|
|
141
|
-
onSuccess = () => {},
|
|
142
|
-
tagLookupMap,
|
|
143
|
-
eventContextTags,
|
|
144
|
-
isLiquidFlow,
|
|
145
|
-
forwardedTags = {},
|
|
146
|
-
tabType,
|
|
147
|
-
skipTags = () => false,
|
|
148
|
-
} = options;
|
|
149
|
-
const emptyBodyError = formatMessage(messages?.emailBodyEmptyError);
|
|
150
|
-
const somethingWrongMsg = formatMessage(messages?.somethingWentWrong);
|
|
151
|
-
// Empty content check
|
|
152
|
-
|
|
153
|
-
if (!content || content.trim() === "") {
|
|
154
|
-
onError({
|
|
155
|
-
standardErrors: [emptyBodyError],
|
|
156
|
-
liquidErrors: [],
|
|
157
|
-
tabType,
|
|
158
|
-
});
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Await getLiquidTags as a promise if it doesn't already return one
|
|
163
|
-
const getLiquidTagsAsync = (inputContent) => new Promise((resolve) => {
|
|
164
|
-
getLiquidTags(inputContent, (result) => {
|
|
165
|
-
resolve(result);
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
const result = await getLiquidTagsAsync(content);
|
|
170
|
-
const validString = /\S/.test(content);
|
|
171
|
-
|
|
172
|
-
// Handle API errors or empty content
|
|
173
|
-
if (result?.errors?.length > 0 || !validString) {
|
|
174
|
-
let standardErrors = [];
|
|
175
|
-
if (!validString) {
|
|
176
|
-
standardErrors = [emptyBodyError];
|
|
177
|
-
}
|
|
178
|
-
let liquidErrors;
|
|
179
|
-
if (result && Array.isArray(result?.errors)) {
|
|
180
|
-
liquidErrors = result?.errors?.map((error) => {
|
|
181
|
-
const message = typeof error?.message === "string"
|
|
182
|
-
? error.message
|
|
183
|
-
: somethingWrongMsg;
|
|
184
|
-
return message;
|
|
185
|
-
});
|
|
186
|
-
} else {
|
|
187
|
-
liquidErrors = [somethingWrongMsg];
|
|
188
|
-
}
|
|
189
|
-
onError({
|
|
190
|
-
standardErrors,
|
|
191
|
-
liquidErrors,
|
|
192
|
-
tabType,
|
|
193
|
-
});
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Extract and validate tags
|
|
198
|
-
const extractedLiquidTags = extractNames(result?.data || []);
|
|
199
|
-
// Get supported tags
|
|
200
|
-
const supportedLiquidTags = checkSupport(
|
|
201
|
-
result,
|
|
202
|
-
tagLookupMap,
|
|
203
|
-
eventContextTags,
|
|
204
|
-
isLiquidFlow,
|
|
205
|
-
forwardedTags
|
|
206
|
-
);
|
|
207
|
-
// Find unsupported tags
|
|
208
|
-
const unsupportedLiquidTags = extractedLiquidTags?.filter(
|
|
209
|
-
(tag) => !supportedLiquidTags?.includes(tag) && !skipTags(tag)
|
|
210
|
-
);
|
|
211
|
-
// Handle unsupported tags
|
|
212
|
-
if (unsupportedLiquidTags?.length > 0) {
|
|
213
|
-
const errorMsg = formatMessage(messages.unsupportedTagsValidationError, {
|
|
214
|
-
unsupportedTags: unsupportedLiquidTags.join(", "),
|
|
215
|
-
});
|
|
216
|
-
onError({
|
|
217
|
-
standardErrors: [],
|
|
218
|
-
liquidErrors: [errorMsg],
|
|
219
|
-
tabType,
|
|
220
|
-
});
|
|
221
|
-
return false;
|
|
222
|
-
}
|
|
223
|
-
// All validations passed
|
|
224
|
-
onSuccess(content, tabType);
|
|
225
|
-
return true;
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
// Internal helper function to validate platform-specific content
|
|
229
|
-
export const _validatePlatformSpecificContent = async (
|
|
230
|
-
androidContent,
|
|
231
|
-
iosContent,
|
|
232
|
-
channel,
|
|
233
|
-
options // Contains parent's onError and other options for validateLiquidTemplateContent
|
|
234
|
-
) => {
|
|
235
|
-
const {
|
|
236
|
-
singleTab,
|
|
237
|
-
onError: parentOnError, // The onError callback from the calling function (e.g., validateMobilePushContent)
|
|
238
|
-
...commonVltcOptions // Other options like getLiquidTags, formatMessage, messages, currentTab, etc.
|
|
239
|
-
} = options;
|
|
240
|
-
console.log("androidContent.....", androidContent, iosContent, singleTab);
|
|
241
|
-
let isAndroidValid = false;
|
|
242
|
-
let isIosValid = false;
|
|
243
|
-
|
|
244
|
-
// This aggregator is passed to validateLiquidTemplateContent.
|
|
245
|
-
// It accumulates errors in the new structure and calls the parentOnError
|
|
246
|
-
const internalOnErrorAggregator = ({
|
|
247
|
-
standardErrors = [],
|
|
248
|
-
liquidErrors = [],
|
|
249
|
-
tabType: tabTypeFromVLTC,
|
|
250
|
-
}) => {
|
|
251
|
-
console.log("internalOnErrorAggregator.....", standardErrors, liquidErrors, tabTypeFromVLTC);
|
|
252
|
-
aggregatedErrors.standardErrors[tabTypeFromVLTC?.toUpperCase() ?? ''].push(
|
|
253
|
-
...standardErrors
|
|
254
|
-
);
|
|
255
|
-
aggregatedErrors.liquidErrors[tabTypeFromVLTC?.toUpperCase() ?? ''].push(
|
|
256
|
-
...liquidErrors
|
|
257
|
-
);
|
|
258
|
-
parentOnError(aggregatedErrors);
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
// Base options for calling validateLiquidTemplateContent
|
|
262
|
-
const vltcCallOptions = {
|
|
263
|
-
...commonVltcOptions,
|
|
264
|
-
onError: internalOnErrorAggregator,
|
|
265
|
-
onSuccess: () => {},
|
|
266
|
-
};
|
|
267
|
-
// Initialize error structure with platform-specific categories
|
|
268
|
-
const aggregatedErrors = {
|
|
269
|
-
standardErrors: {
|
|
270
|
-
[ANDROID]: [],
|
|
271
|
-
[IOS]: [],
|
|
272
|
-
generic: [],
|
|
273
|
-
},
|
|
274
|
-
liquidErrors: {
|
|
275
|
-
[ANDROID]: [],
|
|
276
|
-
[IOS]: [],
|
|
277
|
-
generic: [],
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
|
|
281
|
-
if (androidContent && (singleTab === ANDROID || !singleTab)) {
|
|
282
|
-
console.log("androidContent.....validateLiquidTemplateContent", androidContent);
|
|
283
|
-
isAndroidValid = await validateLiquidTemplateContent(
|
|
284
|
-
androidContent,
|
|
285
|
-
{ ...vltcCallOptions, tabType: ANDROID }
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (iosContent && (singleTab === IOS || !singleTab)) {
|
|
290
|
-
console.log("iosContent.....validateLiquidTemplateContent", iosContent);
|
|
291
|
-
isIosValid = await validateLiquidTemplateContent(
|
|
292
|
-
iosContent,
|
|
293
|
-
{ ...vltcCallOptions, tabType: IOS }
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
//if singleTab is android, then validate only android content and make ios valid by default
|
|
297
|
-
if (singleTab === ANDROID) {
|
|
298
|
-
isIosValid = true;
|
|
299
|
-
}
|
|
300
|
-
//if singleTab is ios, then validate only ios content and make android valid by default
|
|
301
|
-
if (singleTab === IOS) {
|
|
302
|
-
isAndroidValid = true;
|
|
303
|
-
}
|
|
304
|
-
console.log("isAndroidValid.....validateLiquidTemplateContent", isAndroidValid, isIosValid);
|
|
305
|
-
return isAndroidValid && isIosValid; // Overall success
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Validate Mobile Push content for both Android and iOS tabs
|
|
310
|
-
* @param {object} formData - Form data containing Android and iOS content
|
|
311
|
-
* @param {object} options - Options for validation
|
|
312
|
-
* @returns {Promise} - Promise that resolves when validation completes
|
|
313
|
-
*/
|
|
314
|
-
export const validateMobilePushContent = async (formData, options) => {
|
|
315
|
-
const {
|
|
316
|
-
currentTab,
|
|
317
|
-
onError, // This is the onError callback passed by the caller of validateMobilePushContent
|
|
318
|
-
onSuccess, // This is the FINAL success callback for MobilePush
|
|
319
|
-
...restOptions // Options for validateLiquidTemplateContent (getLiquidTags, formatMessage, etc.)
|
|
320
|
-
} = options;
|
|
321
|
-
// Clear previous errors by calling the passed onError
|
|
322
|
-
onError({ standardErrors: [], liquidErrors: [] });
|
|
323
|
-
|
|
324
|
-
const androidContent = JSON.stringify(formData?.[0]);
|
|
325
|
-
const iosContent = JSON.stringify(formData?.[1]);
|
|
326
|
-
console.log("_validatePlatformSpecificContent.....", androidContent, iosContent);
|
|
327
|
-
// Pass the original 'onError' from this function's arguments,
|
|
328
|
-
// 'currentTab', and other relevant options to the helper.
|
|
329
|
-
const overallSuccess = await _validatePlatformSpecificContent(
|
|
330
|
-
androidContent,
|
|
331
|
-
iosContent,
|
|
332
|
-
MOBILE_PUSH,
|
|
333
|
-
{ ...restOptions, currentTab, onError }
|
|
334
|
-
);
|
|
335
|
-
const getContentToSubmit = () => {
|
|
336
|
-
if (currentTab === 1 && androidContent) return [androidContent, ANDROID?.toLowerCase()];
|
|
337
|
-
if (currentTab === 2 && iosContent) return [iosContent, IOS?.toLowerCase()];
|
|
338
|
-
if (androidContent) return [androidContent, ANDROID?.toLowerCase()];
|
|
339
|
-
if (iosContent) return [iosContent, IOS?.toLowerCase()];
|
|
340
|
-
return ["", ""];
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
if (overallSuccess) {
|
|
344
|
-
const [contentToSubmit, tabTypeToSubmit] = getContentToSubmit();
|
|
345
|
-
// Call the FINAL onSuccess only ONCE here
|
|
346
|
-
onSuccess(contentToSubmit, tabTypeToSubmit);
|
|
347
|
-
return true;
|
|
348
|
-
}
|
|
349
|
-
return false;
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Validate INAPP content for both Android and iOS
|
|
354
|
-
* @param {object} formData - Form data containing Android and iOS content
|
|
355
|
-
* @param {object} options - Options for validation
|
|
356
|
-
* @returns {Promise} - Promise that resolves when validation completes
|
|
357
|
-
*/
|
|
358
|
-
export const validateInAppContent = async (formData, options) => {
|
|
359
|
-
const {
|
|
360
|
-
onError, // This is the onError callback passed by the caller of validateInAppContent
|
|
361
|
-
onSuccess, // FINAL success callback
|
|
362
|
-
...restOptions // Options for validateLiquidTemplateContent
|
|
363
|
-
} = options;
|
|
364
|
-
|
|
365
|
-
// Clear previous errors with new structure
|
|
366
|
-
onError({
|
|
367
|
-
standardErrors: {
|
|
368
|
-
[ANDROID]: [],
|
|
369
|
-
[IOS]: [],
|
|
370
|
-
generic: [],
|
|
371
|
-
},
|
|
372
|
-
liquidErrors: {
|
|
373
|
-
[ANDROID]: [],
|
|
374
|
-
[IOS]: [],
|
|
375
|
-
generic: [],
|
|
376
|
-
},
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
let androidContent = "";
|
|
380
|
-
let iosContent = "";
|
|
381
|
-
let parseError = null;
|
|
382
|
-
|
|
383
|
-
// Extract content
|
|
384
|
-
try {
|
|
385
|
-
const androidData = formData?.versions?.base?.content?.ANDROID;
|
|
386
|
-
console.log("androidContent androidData.....", androidData);
|
|
387
|
-
if (androidData) {
|
|
388
|
-
androidContent = [
|
|
389
|
-
androidData?.title,
|
|
390
|
-
androidData?.message,
|
|
391
|
-
...(androidData?.ctas?.map((cta) => cta?.text || cta?.actionLink) || []),
|
|
392
|
-
]
|
|
393
|
-
.filter(Boolean)
|
|
394
|
-
.join(" ");
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const iosData = formData?.versions?.base?.content?.IOS;
|
|
398
|
-
if (iosData) {
|
|
399
|
-
iosContent = [
|
|
400
|
-
iosData?.title,
|
|
401
|
-
iosData?.message,
|
|
402
|
-
...(iosData?.ctas?.map((cta) => cta?.text || cta?.actionLink) || []),
|
|
403
|
-
]
|
|
404
|
-
.filter(Boolean)
|
|
405
|
-
.join(" ");
|
|
406
|
-
}
|
|
407
|
-
} catch (error) {
|
|
408
|
-
parseError = error; // Capture parsing error
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
// Check if *any* content exists
|
|
412
|
-
if (parseError) {
|
|
413
|
-
onError((prevErrors) => ({
|
|
414
|
-
...prevErrors,
|
|
415
|
-
standardErrors: {
|
|
416
|
-
...prevErrors.standardErrors,
|
|
417
|
-
generic: [
|
|
418
|
-
restOptions.formatMessage(restOptions.messages.somethingWentWrong),
|
|
419
|
-
],
|
|
420
|
-
},
|
|
421
|
-
}));
|
|
422
|
-
return false;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
// Pass the original 'onError' from this function's arguments
|
|
426
|
-
// and other relevant options to the helper.
|
|
427
|
-
const overallSuccess = await _validatePlatformSpecificContent(
|
|
428
|
-
androidContent,
|
|
429
|
-
iosContent,
|
|
430
|
-
INAPP,
|
|
431
|
-
{ ...restOptions, onError }
|
|
432
|
-
);
|
|
433
|
-
|
|
434
|
-
if (overallSuccess) {
|
|
435
|
-
// Call FINAL onSuccess ONCE
|
|
436
|
-
onSuccess();
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
// Errors already reported via the 'onError' callback passed to _validatePlatformSpecificContent
|
|
440
|
-
return false;
|
|
441
|
-
};
|
package/utils/tagValidations.js
CHANGED
|
@@ -115,20 +115,6 @@ export function extractNames(data) {
|
|
|
115
115
|
return names;
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
// Helper to check if a tag is inside a {% ... %} block
|
|
119
|
-
export const isInsideLiquidBlock = (content, tagIndex) => {
|
|
120
|
-
const blockRegex = /{%(.*?)%}/gs;
|
|
121
|
-
let match;
|
|
122
|
-
for (match = blockRegex.exec(content); match !== null; match = blockRegex.exec(content)) {
|
|
123
|
-
const blockStart = match.index;
|
|
124
|
-
const blockEnd = blockStart + match[0].length;
|
|
125
|
-
if (tagIndex >= blockStart && tagIndex < blockEnd) {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return false;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
118
|
/**
|
|
133
119
|
* Validates the tags based on the provided parameters.
|
|
134
120
|
* @param {Object} params - The parameters for tag validation.
|
|
@@ -144,6 +130,7 @@ export const validateTags = ({
|
|
|
144
130
|
const tags = tagsParam;
|
|
145
131
|
const injectedTags = transformInjectedTags(injectedTagsParams);
|
|
146
132
|
let currentModule = location?.query?.module ? location?.query?.module : DEFAULT;
|
|
133
|
+
|
|
147
134
|
if (tagModule) {
|
|
148
135
|
currentModule = tagModule;
|
|
149
136
|
}
|
|
@@ -173,7 +160,6 @@ export const validateTags = ({
|
|
|
173
160
|
let match = regex.exec(content);
|
|
174
161
|
while (match !== null) {
|
|
175
162
|
const tagValue = match[0].substring(indexOfEnd(match[0], '{{'), match[0].indexOf('}}'));
|
|
176
|
-
const tagIndex = match?.index;
|
|
177
163
|
match = regex.exec(content);
|
|
178
164
|
let ifSupported = false;
|
|
179
165
|
lodashForEach(tags, (tag) => {
|
|
@@ -184,10 +170,10 @@ export const validateTags = ({
|
|
|
184
170
|
const ifSkipped = skipTags(tagValue);
|
|
185
171
|
if (ifSkipped) {
|
|
186
172
|
ifSupported = true;
|
|
187
|
-
|
|
173
|
+
let isUnsubscribeSkipped = tagValue.indexOf("unsubscribe") != -1 ;
|
|
188
174
|
if (isUnsubscribeSkipped) {
|
|
189
175
|
const missingTagIndex = response.missingTags.indexOf("unsubscribe");
|
|
190
|
-
if
|
|
176
|
+
if(missingTagIndex != -1) { //skip regex tags for mandatory tags also
|
|
191
177
|
response.missingTags.splice(missingTagIndex, 1);
|
|
192
178
|
}
|
|
193
179
|
}
|
|
@@ -199,12 +185,11 @@ export const validateTags = ({
|
|
|
199
185
|
}
|
|
200
186
|
});
|
|
201
187
|
ifSupported = ifSupported || checkIfSupportedTag(tagValue, injectedTags);
|
|
202
|
-
|
|
203
|
-
if (!ifSupported && !isInsideLiquidBlock(content, tagIndex) && tagValue?.indexOf('.') === -1) {
|
|
188
|
+
if (!ifSupported) {
|
|
204
189
|
response.unsupportedTags.push(tagValue);
|
|
205
190
|
response.valid = false;
|
|
206
191
|
}
|
|
207
|
-
if (response.unsupportedTags.length
|
|
192
|
+
if (response.unsupportedTags.length == 0 && response.missingTags.length == 0 ) {
|
|
208
193
|
response.valid = true;
|
|
209
194
|
}
|
|
210
195
|
}
|