feed-common 1.62.0 → 1.64.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +14 -0
- package/dist/constants/profile.constants.d.ts +26 -5
- package/dist/constants/profile.constants.d.ts.map +1 -1
- package/dist/constants/profile.constants.js +35 -26
- package/dist/constants/profile.constants.js.map +1 -1
- package/dist/utils/feed-templates/google-api.template.js.map +1 -1
- package/dist/utils/feed-templates/google.template.d.ts.map +1 -1
- package/dist/utils/feed-templates/google.template.js +147 -57
- package/dist/utils/feed-templates/google.template.js.map +1 -1
- package/package.json +1 -1
- package/src/constants/profile.constants.ts +35 -27
- package/src/utils/feed-templates/google-api.template.ts +1 -1
- package/src/utils/feed-templates/google.template.ts +177 -56
@@ -27,6 +27,7 @@ export const SOURCE_GOOGLE_SIZE_SYSTEM = 'source.google_size_system';
|
|
27
27
|
export const SOURCE_GOOGLE_GMC_DESTINATIONS = 'source.google_gmc_destinations';
|
28
28
|
export const SOURCE_GOOGLE_SHIPPING = 'source.google_shipping';
|
29
29
|
export const SOURCE_GOOGLE_TAX = 'source.google_tax';
|
30
|
+
export const SOURCE_GOOGLE_FREE_SHIPPING_THRESHOLD = 'source.google_free_shipping_threshold';
|
30
31
|
|
31
32
|
export const SOURCE_CUSTOM = 'custom_input';
|
32
33
|
|
@@ -345,45 +346,46 @@ export const SOURCE_SHOPIFY_DESCRIPTION_HTML = 'shopify.description_html';
|
|
345
346
|
export const SOURCE_SHOPIFY_STATUS = 'shopify.status';
|
346
347
|
|
347
348
|
export const ShopifyProductSource = {
|
348
|
-
id: { label: 'ID', value: SOURCE_SHOPIFY_ID, type: MappingSourceValueType.STRING },
|
349
|
-
handle: { label: 'Handle', value: SOURCE_SHOPIFY_HANDLE, type: MappingSourceValueType.STRING },
|
350
|
-
variant_id: { label: 'Variant ID', value: SOURCE_SHOPIFY_VARIANT_ID, type: MappingSourceValueType.STRING },
|
351
|
-
title: { label: 'Title', value: SOURCE_SHOPIFY_TITLE, type: MappingSourceValueType.STRING },
|
352
|
-
variant_title: { label: 'Variant Title', value: SOURCE_SHOPIFY_VARIANT_TITLE, type: MappingSourceValueType.STRING },
|
353
|
-
description: { label: 'Description', value: SOURCE_SHOPIFY_DESCRIPTION, type: MappingSourceValueType.STRING },
|
349
|
+
id: { label: 'ID', value: SOURCE_SHOPIFY_ID, type: MappingSourceValueType.STRING, description: 'Product ID' },
|
350
|
+
handle: { label: 'Handle', value: SOURCE_SHOPIFY_HANDLE, type: MappingSourceValueType.STRING, description: 'Product handle' },
|
351
|
+
variant_id: { label: 'Variant ID', value: SOURCE_SHOPIFY_VARIANT_ID, type: MappingSourceValueType.STRING, description: 'Variant ID' },
|
352
|
+
title: { label: 'Title', value: SOURCE_SHOPIFY_TITLE, type: MappingSourceValueType.STRING, description: 'Product title' },
|
353
|
+
variant_title: { label: 'Variant Title', value: SOURCE_SHOPIFY_VARIANT_TITLE, type: MappingSourceValueType.STRING, description: 'Variant title' },
|
354
|
+
description: { label: 'Description', value: SOURCE_SHOPIFY_DESCRIPTION, type: MappingSourceValueType.STRING, description: 'Product description' },
|
354
355
|
description_html: {
|
355
356
|
label: 'Description HTML',
|
356
357
|
value: SOURCE_SHOPIFY_DESCRIPTION_HTML,
|
357
358
|
type: MappingSourceValueType.STRING,
|
359
|
+
description: 'Product description in HTML format',
|
358
360
|
},
|
359
|
-
sku: { label: 'SKU', value: SOURCE_SHOPIFY_SKU, type: MappingSourceValueType.STRING },
|
360
|
-
barcode: { label: ' Barcode', value: SOURCE_SHOPIFY_BARCODE, type: MappingSourceValueType.STRING },
|
361
|
-
price: { label: 'Price', value: SOURCE_SHOPIFY_PRICE, type: MappingSourceValueType.FLOAT },
|
361
|
+
sku: { label: 'SKU', value: SOURCE_SHOPIFY_SKU, type: MappingSourceValueType.STRING, description: 'Product SKU' },
|
362
|
+
barcode: { label: ' Barcode', value: SOURCE_SHOPIFY_BARCODE, type: MappingSourceValueType.STRING, description: 'Product barcode' },
|
363
|
+
price: { label: 'Price', value: SOURCE_SHOPIFY_PRICE, type: MappingSourceValueType.FLOAT, description: 'Product price' },
|
362
364
|
compare_at_price: {
|
363
365
|
label: 'Compare At Price',
|
364
366
|
value: SOURCE_SHOPIFY_COMPARE_AT_PRICE,
|
365
367
|
type: MappingSourceValueType.FLOAT,
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
368
|
+
description: 'Product compare at price',
|
369
|
+
},
|
370
|
+
vendor: { label: 'Vendor', value: SOURCE_SHOPIFY_VENDOR, type: MappingSourceValueType.STRING, description: 'Product vendor' },
|
371
|
+
image: { label: 'Image', value: SOURCE_SHOPIFY_IMAGE, type: MappingSourceValueType.STRING, description: 'Product main image' },
|
372
|
+
images: { label: 'Images', value: SOURCE_SHOPIFY_IMAGES, type: MappingSourceValueType.STRING, description: 'Comma-separated list of product images' },
|
373
|
+
product_type: { label: 'Product Type', value: SOURCE_SHOPIFY_PRODUCT_TYPE, type: MappingSourceValueType.STRING, description: 'Product type' },
|
374
|
+
collections: { label: 'Collections', value: SOURCE_SHOPIFY_COLLECTIONS, type: MappingSourceValueType.STRING, description: 'Comma-separated list of collections' },
|
375
|
+
category: { label: 'Category', value: SOURCE_SHOPIFY_CATEGORY, type: MappingSourceValueType.STRING, description: 'Product category' },
|
376
|
+
tags: { label: 'Tags', value: SOURCE_SHOPIFY_TAGS, type: MappingSourceValueType.STRING, description: 'Comma-separated list of product tags' },
|
374
377
|
inventory_quantity: {
|
375
378
|
label: 'Inventory Quantity',
|
376
379
|
value: SOURCE_SHOPIFY_INVENTORY_QUANTITY,
|
377
380
|
type: MappingSourceValueType.INT,
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
custom: { label: 'Custom input', value: SOURCE_CUSTOM, type: MappingSourceValueType.STRING },
|
381
|
+
description: 'Product inventory quantity',
|
382
|
+
},
|
383
|
+
weight: { label: 'Weight', value: SOURCE_SHOPIFY_WEIGHT, type: MappingSourceValueType.FLOAT, description: 'Product weight' },
|
384
|
+
weight_unit: { label: 'Weight Unit', value: SOURCE_SHOPIFY_WEIGHT_UNIT, type: MappingSourceValueType.STRING, description: 'Product weight unit' },
|
385
|
+
shop_domain: { label: 'Shop Domain', value: SOURCE_SHOPIFY_SHOP_DOMAIN, type: MappingSourceValueType.STRING, description: 'Shop domain' },
|
386
|
+
shop_country: { label: 'Shop Country', value: SOURCE_SHOPIFY_SHOP_COUNTRY, type: MappingSourceValueType.STRING, description: 'Shop country' },
|
387
|
+
shop_currency: { label: 'Shop Currency', value: SOURCE_SHOPIFY_SHOP_CURRENCY, type: MappingSourceValueType.STRING, description: 'Shop currency' },
|
388
|
+
status: { label: 'Status', value: SOURCE_SHOPIFY_STATUS, type: MappingSourceValueType.STRING, description: 'Product status' },
|
387
389
|
};
|
388
390
|
|
389
391
|
export const MappingSourceSources: MappingSourceSourceType[] = [
|
@@ -542,7 +544,13 @@ export const MappingSourceSources: MappingSourceSourceType[] = [
|
|
542
544
|
description: "List of tax options",
|
543
545
|
type: MappingSourceValueType.STRING,
|
544
546
|
value: SOURCE_GOOGLE_TAX,
|
545
|
-
}
|
547
|
+
},
|
548
|
+
{
|
549
|
+
label: "Free Shipping Threshold",
|
550
|
+
description: "List of free shipping thresholds",
|
551
|
+
type: MappingSourceValueType.STRING,
|
552
|
+
value: SOURCE_GOOGLE_FREE_SHIPPING_THRESHOLD,
|
553
|
+
},
|
546
554
|
]
|
547
555
|
|
548
556
|
export const CHANNEL = 'online';
|
@@ -2,7 +2,7 @@
|
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
3
3
|
/* eslint-disable max-len */
|
4
4
|
import { countrySchema, dateRangeSchema, languageSchema, measureUnitsSchema, priceSchema, validateIfNoMacro } from './index.js';
|
5
|
-
import {
|
5
|
+
import { XmlFeedFormat } from '../../constants/profile.constants.js';
|
6
6
|
import { ProductUploadMapSource, XmlFeedTemplateType } from '../../types/profile.types.js';
|
7
7
|
import { z } from 'zod';
|
8
8
|
import { ulid } from 'ulid';
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/* eslint-disable quotes */
|
2
2
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
3
3
|
/* eslint-disable max-len */
|
4
|
-
import { dateRangeSchema, measureUnitsSchema, validateIfNoMacro } from './index.js';
|
4
|
+
import { dateRangeSchema, measureUnitsSchema, priceSchema, validateIfNoMacro } from './index.js';
|
5
5
|
import { SOURCE_LANGUAGE, XmlFeedFormat } from '../../constants/profile.constants.js';
|
6
6
|
import { ProductUploadMapSource, XmlFeedTemplateType } from '../../types/profile.types.js';
|
7
7
|
import { z } from 'zod';
|
@@ -39,6 +39,8 @@ const availabilityMapping: ProductUploadMapSource = {
|
|
39
39
|
rules: { sections: [] },
|
40
40
|
baseMode: true,
|
41
41
|
defaultValue: '',
|
42
|
+
singleChoice: true,
|
43
|
+
fixedValue: true,
|
42
44
|
};
|
43
45
|
|
44
46
|
const customLabelMapping: ProductUploadMapSource = {
|
@@ -102,6 +104,7 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
102
104
|
defaultValue: 'https://{{shopify.shop_domain}}/products/{{shopify.handle}}',
|
103
105
|
rules: { sections: [] },
|
104
106
|
baseMode: true,
|
107
|
+
singleChoice: true,
|
105
108
|
},
|
106
109
|
{
|
107
110
|
attribute: 'image_link',
|
@@ -113,6 +116,7 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
113
116
|
defaultValue: '{{shopify.image}}',
|
114
117
|
rules: { sections: [] },
|
115
118
|
baseMode: true,
|
119
|
+
singleChoice: true,
|
116
120
|
},
|
117
121
|
...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map(() => ({
|
118
122
|
...(additionalImageLinkMapping as any),
|
@@ -155,12 +159,12 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
155
159
|
},
|
156
160
|
{
|
157
161
|
...availabilityMapping,
|
158
|
-
defaultValue: 'in_stock',
|
162
|
+
defaultValue: '{{source.google_availability:[{"label": "In Stock", "value": "in_stock"}]}}',
|
159
163
|
rules: { sections: [] },
|
160
164
|
},
|
161
165
|
{
|
162
166
|
...availabilityMapping,
|
163
|
-
defaultValue: 'out_of_stock',
|
167
|
+
defaultValue: '{{source.google_availability:[{"label": "Out of Stock", "value": "out_of_stock"}]}}',
|
164
168
|
rules: {
|
165
169
|
sections: [
|
166
170
|
{
|
@@ -201,12 +205,13 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
201
205
|
v,
|
202
206
|
z
|
203
207
|
.string()
|
204
|
-
.refine(v => !v || z.string().
|
205
|
-
.refine(v => !v || new Date(v).getTime()
|
208
|
+
.refine(v => !v || z.string().datetime({ offset: true }).safeParse(v).success, { message: 'invalid date' })
|
209
|
+
.refine(v => !v || new Date(v).getTime() < (1000 * 60 * 60 * 24 * 365 + new Date().getTime()), {
|
206
210
|
message: 'The date should be up to one year in the future',
|
207
211
|
})
|
208
212
|
),
|
209
|
-
defaultValue: '',
|
213
|
+
defaultValue: '{{source.date:}}',
|
214
|
+
fixedValue: true,
|
210
215
|
rules: { sections: [] },
|
211
216
|
},
|
212
217
|
{
|
@@ -217,6 +222,7 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
217
222
|
required: false,
|
218
223
|
type: 'macro-input',
|
219
224
|
defaultValue: '',
|
225
|
+
validator: (v: string | number) => validateIfNoMacro(v, priceSchema()),
|
220
226
|
rules: { sections: [] },
|
221
227
|
},
|
222
228
|
{
|
@@ -231,13 +237,14 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
231
237
|
v,
|
232
238
|
z
|
233
239
|
.string()
|
234
|
-
.refine(v => !v || z.string().datetime().safeParse(v).success, { message: 'invalid date' })
|
235
|
-
.refine(v => !v || new Date(v).getTime()
|
240
|
+
.refine(v => !v || z.string().datetime({ offset: true }).safeParse(v).success, { message: 'invalid date' })
|
241
|
+
.refine(v => !v || new Date(v).getTime() < (1000 * 60 * 60 * 24 * 30 + new Date().getTime()), {
|
236
242
|
message: 'The date should be less than 30 days in the future',
|
237
243
|
})
|
238
244
|
),
|
239
|
-
defaultValue: '',
|
245
|
+
defaultValue: '{{source.date:}}',
|
240
246
|
rules: { sections: [] },
|
247
|
+
fixedValue: true,
|
241
248
|
},
|
242
249
|
// TODO: add condition, checking if sale price is set
|
243
250
|
{
|
@@ -251,6 +258,7 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
251
258
|
defaultValue: '{{shopify.price}} {{shopify.shop_currency}}',
|
252
259
|
rules: { sections: [] },
|
253
260
|
baseMode: true,
|
261
|
+
singleChoice: true,
|
254
262
|
},
|
255
263
|
{
|
256
264
|
attribute: 'sale_price',
|
@@ -270,8 +278,9 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
270
278
|
required: false,
|
271
279
|
type: 'macro-input',
|
272
280
|
validator: (v: string | number) => validateIfNoMacro(v, dateRangeSchema),
|
273
|
-
defaultValue: '',
|
281
|
+
defaultValue: '{{source.date_range:}}',
|
274
282
|
rules: { sections: [] },
|
283
|
+
fixedValue: true,
|
275
284
|
},
|
276
285
|
{
|
277
286
|
attribute: 'unit_pricing_measure',
|
@@ -309,6 +318,7 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
309
318
|
),
|
310
319
|
defaultValue: '',
|
311
320
|
rules: { sections: [] },
|
321
|
+
singleChoice: true,
|
312
322
|
},
|
313
323
|
{
|
314
324
|
attribute: 'unit_pricing_base_measure',
|
@@ -354,8 +364,34 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
354
364
|
"Details of an installment payment plan. This attribute uses 4 sub-attributes: Months [months] (Required) Integer, the number of installments the buyer has to pay. Amount [amount] (Required) ISO 4217, the amount the buyer has to pay per month. Downpayment [downpayment] (Optional) ISO 4217, the amount the buyer has to pay upfront as a one time payment. Note: if you don't submit the sub-attribute, the default value is 0 or “no down payment”. Credit type [credit_type] (Optional). This sub-attributes uses the following supported values: Finance [finance], Lease [lease]. Example: 6:30 EUR or 6:30 EUR:10 EUR:finance",
|
355
365
|
required: false,
|
356
366
|
type: 'macro-input',
|
357
|
-
|
358
|
-
|
367
|
+
defaultValue: '{{source.google_instalment:}}',
|
368
|
+
fixedValue: true,
|
369
|
+
validator: (v: string | number) =>
|
370
|
+
validateIfNoMacro(
|
371
|
+
v,
|
372
|
+
z.string().superRefine((v, ctx) => {
|
373
|
+
if (!v) {
|
374
|
+
return true;
|
375
|
+
}
|
376
|
+
|
377
|
+
const [months, amount] = v.split(':');
|
378
|
+
|
379
|
+
if (!z.coerce.number().min(1).int().safeParse(months).success) {
|
380
|
+
ctx.addIssue({
|
381
|
+
code: z.ZodIssueCode.custom,
|
382
|
+
message: 'Months should be a positive whole number',
|
383
|
+
});
|
384
|
+
}
|
385
|
+
|
386
|
+
const result = priceSchema().safeParse(amount);
|
387
|
+
if (!result.success) {
|
388
|
+
ctx.addIssue({
|
389
|
+
code: z.ZodIssueCode.custom,
|
390
|
+
message: result.error.issues[0].message,
|
391
|
+
});
|
392
|
+
}
|
393
|
+
})
|
394
|
+
),
|
359
395
|
rules: { sections: [] },
|
360
396
|
},
|
361
397
|
{
|
@@ -365,8 +401,41 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
365
401
|
'Details a monthly or annual payment plan that bundles a communications service contract with a wireless product. Optional (available in certain countries for showing wireless products and services only). Syntax: Period [period] (Required), The duration of a single subscription period. This sub-attribute uses the following supported values: Month [month] Year [year]. Period length [period_length] (Required), Integer, the number of subscription periods (months or years) that the buyer must pay. Amount [amount] (Required), ISO 4217, the amount the buyer has to pay per subscription period. Example: month:12:30.00EUR',
|
366
402
|
required: false,
|
367
403
|
type: 'macro-input',
|
368
|
-
|
369
|
-
|
404
|
+
validator: (v: string | number) =>
|
405
|
+
validateIfNoMacro(
|
406
|
+
v,
|
407
|
+
z.string().superRefine((v, ctx) => {
|
408
|
+
if (!v) {
|
409
|
+
return true;
|
410
|
+
}
|
411
|
+
|
412
|
+
const [period, periodLength, amount] = v.split(':');
|
413
|
+
|
414
|
+
if (!['year', 'month'].includes(period)) {
|
415
|
+
ctx.addIssue({
|
416
|
+
code: z.ZodIssueCode.custom,
|
417
|
+
message: 'Period should be either year or month',
|
418
|
+
});
|
419
|
+
}
|
420
|
+
|
421
|
+
if (!z.coerce.number().min(1).int().safeParse(periodLength).success) {
|
422
|
+
ctx.addIssue({
|
423
|
+
code: z.ZodIssueCode.custom,
|
424
|
+
message: 'Period length should be a positive whole number',
|
425
|
+
});
|
426
|
+
}
|
427
|
+
|
428
|
+
const result = priceSchema().safeParse(amount);
|
429
|
+
if (!result.success) {
|
430
|
+
ctx.addIssue({
|
431
|
+
code: z.ZodIssueCode.custom,
|
432
|
+
message: result.error.issues[0].message,
|
433
|
+
});
|
434
|
+
}
|
435
|
+
})
|
436
|
+
),
|
437
|
+
defaultValue: '{{source.google_subscription:}}',
|
438
|
+
fixedValue: true,
|
370
439
|
rules: { sections: [] },
|
371
440
|
},
|
372
441
|
{
|
@@ -396,8 +465,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
396
465
|
'Google-defined product category for your product. Example: Apparel & Accessories > Clothing > Outerwear > Coats & Jackets or 371',
|
397
466
|
required: false,
|
398
467
|
type: 'macro-input',
|
399
|
-
defaultValue: '',
|
468
|
+
defaultValue: '{{source.google_category:}}',
|
400
469
|
rules: { sections: [] },
|
470
|
+
fixedValue: true,
|
471
|
+
singleChoice: true,
|
401
472
|
},
|
402
473
|
{
|
403
474
|
attribute: 'product_type',
|
@@ -451,8 +522,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
451
522
|
required: false,
|
452
523
|
type: 'macro-input',
|
453
524
|
validator: (v: string | number) => validateIfNoMacro(v, z.enum(['yes', 'no', ''])),
|
454
|
-
defaultValue: 'yes',
|
525
|
+
defaultValue: '{{source.yes_no:[{"label": "Yes", "value": "yes"}]}}',
|
455
526
|
rules: { sections: [] },
|
527
|
+
fixedValue: true,
|
528
|
+
singleChoice: true,
|
456
529
|
},
|
457
530
|
{
|
458
531
|
attribute: 'condition',
|
@@ -462,8 +535,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
462
535
|
required: false,
|
463
536
|
type: 'macro-input',
|
464
537
|
validator: (v: string | number) => validateIfNoMacro(v, z.enum(['new', 'refurbished', 'used', ''])),
|
465
|
-
defaultValue: '',
|
538
|
+
defaultValue: '{{source.google_condition:}}',
|
466
539
|
rules: { sections: [] },
|
540
|
+
singleChoice: true,
|
541
|
+
fixedValue: true,
|
467
542
|
},
|
468
543
|
{
|
469
544
|
attribute: 'adult',
|
@@ -473,8 +548,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
473
548
|
required: false,
|
474
549
|
type: 'macro-input',
|
475
550
|
validator: (v: string | number) => validateIfNoMacro(v, z.enum(['yes', 'no', ''])),
|
476
|
-
defaultValue: '',
|
551
|
+
defaultValue: '{{source.yes_no:}]}}',
|
477
552
|
rules: { sections: [] },
|
553
|
+
singleChoice: true,
|
554
|
+
fixedValue: true,
|
478
555
|
},
|
479
556
|
{
|
480
557
|
attribute: 'multipack',
|
@@ -495,8 +572,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
495
572
|
required: false,
|
496
573
|
type: 'macro-input',
|
497
574
|
validator: (v: string | number) => validateIfNoMacro(v, z.enum(['yes', 'no', ''])),
|
498
|
-
defaultValue: '',
|
575
|
+
defaultValue: '{{source.yes_no:}}',
|
499
576
|
rules: { sections: [] },
|
577
|
+
singleChoice: true,
|
578
|
+
fixedValue: true,
|
500
579
|
},
|
501
580
|
{
|
502
581
|
attribute: 'certification',
|
@@ -517,8 +596,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
517
596
|
type: 'macro-input',
|
518
597
|
validator: (v: string | number) =>
|
519
598
|
validateIfNoMacro(v, z.enum(['A', 'A+', 'A++', 'A+++', 'B', 'C', 'D', 'E', 'F', 'G', ''])),
|
520
|
-
defaultValue: '',
|
599
|
+
defaultValue: '{{source.energy_efficiency:}}',
|
521
600
|
rules: { sections: [] },
|
601
|
+
singleChoice: true,
|
602
|
+
fixedValue: true,
|
522
603
|
},
|
523
604
|
{
|
524
605
|
attribute: 'age_group',
|
@@ -530,8 +611,10 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
530
611
|
// TODO: add to check if product is apparel
|
531
612
|
validator: (v: string | number) =>
|
532
613
|
validateIfNoMacro(v, z.enum(['newborn', 'infant', 'toddler', 'kids', 'adult', ''])),
|
533
|
-
defaultValue: '',
|
614
|
+
defaultValue: '{{source.google_age_group:}}',
|
534
615
|
rules: { sections: [] },
|
616
|
+
singleChoice: true,
|
617
|
+
fixedValue: true,
|
535
618
|
},
|
536
619
|
{
|
537
620
|
attribute: 'color',
|
@@ -555,7 +638,9 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
555
638
|
// TODO: add to check if product is apparel
|
556
639
|
validator: (v: string | number) => validateIfNoMacro(v, z.enum(['male', 'female', 'unisex', ''])),
|
557
640
|
rules: { sections: [] },
|
558
|
-
defaultValue: '',
|
641
|
+
defaultValue: '{{source.google_gender:}}',
|
642
|
+
singleChoice: true,
|
643
|
+
fixedValue: true,
|
559
644
|
},
|
560
645
|
{
|
561
646
|
attribute: 'material',
|
@@ -618,7 +703,8 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
618
703
|
)
|
619
704
|
),
|
620
705
|
rules: { sections: [] },
|
621
|
-
defaultValue: '',
|
706
|
+
defaultValue: '{{source.google_size_type:}}',
|
707
|
+
fixedValue: true,
|
622
708
|
},
|
623
709
|
{
|
624
710
|
attribute: 'size_system',
|
@@ -630,7 +716,9 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
630
716
|
validator: (v: string | number) =>
|
631
717
|
validateIfNoMacro(v, z.enum(['US', 'EU', 'UK', 'DE', 'FR', 'JP', 'CN', 'IT', 'BR', 'MEX', 'AU', ''])),
|
632
718
|
rules: { sections: [] },
|
633
|
-
defaultValue: '',
|
719
|
+
defaultValue: '{{source.google_size_system:}}',
|
720
|
+
singleChoice: true,
|
721
|
+
fixedValue: true,
|
634
722
|
},
|
635
723
|
{
|
636
724
|
attribute: 'item_group_id',
|
@@ -694,7 +782,14 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
694
782
|
"Technical specifications or additional details of your product. This attribute uses 3 sub-attributes: Section name: Max 140 characters. Attribute name: Max 140 characters. Attribute value: Max 1000 characters. Don't add information covered in other attributes, all capital letters, gimmicky foreign characters, promotion text, or list keywords or search terms. Example: General:Product Type:Digital player",
|
695
783
|
required: false,
|
696
784
|
type: 'macro-input',
|
697
|
-
validator: (v: string | number) =>
|
785
|
+
validator: (v: string | number) =>
|
786
|
+
validateIfNoMacro(
|
787
|
+
v,
|
788
|
+
z
|
789
|
+
.string()
|
790
|
+
.max(1280)
|
791
|
+
.refine(v => !v || v.split(':').length === 3, { message: 'Invalid format' })
|
792
|
+
),
|
698
793
|
defaultValue: '',
|
699
794
|
rules: { sections: [] },
|
700
795
|
},
|
@@ -783,18 +878,29 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
783
878
|
validator: (v: string | number) =>
|
784
879
|
validateIfNoMacro(
|
785
880
|
v,
|
786
|
-
z
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
881
|
+
z
|
882
|
+
.string()
|
883
|
+
.refine(
|
884
|
+
v =>
|
885
|
+
!v ||
|
886
|
+
v
|
887
|
+
.split(',')
|
888
|
+
.every((val: string) =>
|
889
|
+
[
|
890
|
+
'Shopping_ads',
|
891
|
+
'Buy_on_Google_listings',
|
892
|
+
'Display_ads',
|
893
|
+
'Local_inventory_ads',
|
894
|
+
'Free_listings',
|
895
|
+
'Free_local_listings',
|
896
|
+
'YouTube_Shopping',
|
897
|
+
].includes(val.trim())
|
898
|
+
),
|
899
|
+
{ message: 'Invalid value' }
|
900
|
+
)
|
796
901
|
),
|
797
|
-
defaultValue: '',
|
902
|
+
defaultValue: '{{source.google_gmc_destinations:}}',
|
903
|
+
fixedValue: true,
|
798
904
|
rules: { sections: [] },
|
799
905
|
},
|
800
906
|
{
|
@@ -807,18 +913,29 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
807
913
|
validator: (v: string | number) =>
|
808
914
|
validateIfNoMacro(
|
809
915
|
v,
|
810
|
-
z
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
916
|
+
z
|
917
|
+
.string()
|
918
|
+
.refine(
|
919
|
+
v =>
|
920
|
+
!v ||
|
921
|
+
v
|
922
|
+
.split(',')
|
923
|
+
.every((val: string) =>
|
924
|
+
[
|
925
|
+
'Shopping_ads',
|
926
|
+
'Buy_on_Google_listings',
|
927
|
+
'Display_ads',
|
928
|
+
'Local_inventory_ads',
|
929
|
+
'Free_listings',
|
930
|
+
'Free_local_listings',
|
931
|
+
'YouTube_Shopping',
|
932
|
+
].includes(val.trim())
|
933
|
+
),
|
934
|
+
{ message: 'Invalid value' }
|
935
|
+
)
|
820
936
|
),
|
821
|
-
defaultValue: '',
|
937
|
+
defaultValue: '{{source.google_gmc_destinations:}}',
|
938
|
+
fixedValue: true,
|
822
939
|
rules: { sections: [] },
|
823
940
|
},
|
824
941
|
{
|
@@ -827,9 +944,9 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
827
944
|
description:
|
828
945
|
'A setting that allows you to exclude countries where your products are advertised on Shopping ads. 2 characters. Must be an ISO_3166-1_alpha-2 country code. Only available for Shopping ads. Example: DE',
|
829
946
|
required: false,
|
830
|
-
type: '
|
831
|
-
|
832
|
-
|
947
|
+
type: 'macro-input',
|
948
|
+
defaultValue: '{{source.country:}}',
|
949
|
+
fixedValue: true,
|
833
950
|
rules: { sections: [] },
|
834
951
|
},
|
835
952
|
{
|
@@ -850,7 +967,8 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
850
967
|
"Your product's shipping cost, shipping speeds, and the locations your product ships to. Shipping costs are required for Shopping ads and free listings for the following countries: Australia, Austria, Belgium, Canada, Czechia, France, Germany, India, Ireland, Israel, Italy, New Zealand, Japan, the Netherlands, Poland, Romania, South Korea, Spain, Switzerland, the UK, and the US. This attribute uses the following sub-attributes: Country (Required) ISO 3166 country code. Region (Optional). Postal code (Optional). Location ID (Optional). Location group name (Optional). Service (Optional) Service class or shipping speed. Price (Optional) Fixed shipping cost, including VAT if required. Minimum handling time and maximum handling time (Optional) To specify handling time. Minimum transit time and maximum transit time (Optional) To specify transit time. Supported prices: 0-1000 USD. Example: US:CA:Overnight:16.00 USD:1:1:2:3",
|
851
968
|
required: false,
|
852
969
|
type: 'macro-input',
|
853
|
-
defaultValue: '',
|
970
|
+
defaultValue: '{{source.google_shipping:}}',
|
971
|
+
fixedValue: true,
|
854
972
|
rules: { sections: [] },
|
855
973
|
},
|
856
974
|
{
|
@@ -913,10 +1031,11 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
913
1031
|
description:
|
914
1032
|
'A setting that allows you to provide the country from which your product will typically ship. 2 characters. Must be an ISO_3166-1_alpha-2 country code. Example: DE',
|
915
1033
|
required: false,
|
916
|
-
type: '
|
917
|
-
|
918
|
-
defaultValue: '',
|
1034
|
+
type: 'macro-input',
|
1035
|
+
defaultValue: '{{source.language:}}',
|
919
1036
|
rules: { sections: [] },
|
1037
|
+
singleChoice: true,
|
1038
|
+
fixedValue: true,
|
920
1039
|
},
|
921
1040
|
{
|
922
1041
|
attribute: 'max_handling_time',
|
@@ -958,7 +1077,8 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
958
1077
|
'Order cost above which shipping is free. This attribute uses the following sub-attributes: Country (Required) ISO 3166 country code. Price threshold (Required) Order cost above which shipping is free. Example: US:16.00 USD',
|
959
1078
|
required: false,
|
960
1079
|
type: 'macro-input',
|
961
|
-
defaultValue: '',
|
1080
|
+
defaultValue: '{{source.google_free_shipping_threshold:}}',
|
1081
|
+
fixedValue: true,
|
962
1082
|
rules: { sections: [] },
|
963
1083
|
},
|
964
1084
|
{
|
@@ -968,7 +1088,8 @@ export const googleFeedTemplate: XmlFeedTemplateType = {
|
|
968
1088
|
'Your product’s sales tax rate in percent. Required (Available for the US only). This attribute uses 4 sub-attributes: Country (optional) ISO 3166 country code. Region or postal code or location ID (optional). Rate (required) Tax rate as a percentage. Shipping tax (optional) Specify if you charge tax on shipping, supported values: yes, no. Example: US:CA:5.00:y',
|
969
1089
|
required: false,
|
970
1090
|
type: 'macro-input',
|
971
|
-
defaultValue: '',
|
1091
|
+
defaultValue: '{{source.google_tax:}}',
|
1092
|
+
fixedValue: true,
|
972
1093
|
// TODO: add validator to check if US
|
973
1094
|
rules: { sections: [] },
|
974
1095
|
},
|