feed-common 1.34.1 → 1.35.0

Sign up to get free protection for your applications and to get access to all the features.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ # [1.35.0](https://github.com/advertikon/package-maxify-feed-common/compare/v1.34.2...v1.35.0) (2024-08-13)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * fix bugs ([127d704](https://github.com/advertikon/package-maxify-feed-common/commit/127d704364f113830c1a9577749e1b2a11fc6016))
7
+ * sync package-json ([b32eb9a](https://github.com/advertikon/package-maxify-feed-common/commit/b32eb9af810477f4679ac657e35a4fbcdddd205f))
8
+
9
+
10
+ ### Features
11
+
12
+ * add facebook feed template ([ee2c896](https://github.com/advertikon/package-maxify-feed-common/commit/ee2c8960910f7848072d71c11acef168e42acbc4))
13
+ * add template resolution funciton ([5a9d51e](https://github.com/advertikon/package-maxify-feed-common/commit/5a9d51e63e1b9be970d8ec7d766ebc4a28877d6b))
14
+
15
+ ## [1.34.2](https://github.com/advertikon/package-maxify-feed-common/compare/v1.34.1...v1.34.2) (2024-08-09)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * update Proile type ([ce883c1](https://github.com/advertikon/package-maxify-feed-common/commit/ce883c1b32474a9a24d3084954991edde5ef7c70))
21
+
1
22
  ## [1.34.1](https://github.com/advertikon/package-maxify-feed-common/compare/v1.34.0...v1.34.1) (2024-08-08)
2
23
 
3
24
 
package/dist/index.d.ts CHANGED
@@ -8,4 +8,5 @@ export * from './types/shopify.types.js';
8
8
  export * from './utils/profile.js';
9
9
  export * from './utils/utils.js';
10
10
  export * from './utils/company.js';
11
+ export * from './utils/feed-templates';
11
12
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AAEjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AAEjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
package/dist/index.js CHANGED
@@ -8,4 +8,5 @@ export * from './types/shopify.types.js';
8
8
  export * from './utils/profile.js';
9
9
  export * from './utils/utils.js';
10
10
  export * from './utils/company.js';
11
+ export * from './utils/feed-templates';
11
12
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AAEjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AAEjD,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AAEzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,wBAAwB,CAAC"}
@@ -44,7 +44,7 @@ export type ProductUploadMapping = {
44
44
  type MappingFields = (typeof ProductUploadMappings)[number]['attribute'];
45
45
  export type BaseProductUploadProfile = {
46
46
  id: string;
47
- type?: XMLFeedType;
47
+ type: XMLFeedType;
48
48
  format: XmlFeedFormat | null;
49
49
  name: string;
50
50
  active: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"profile.types.d.ts","sourceRoot":"","sources":["../../src/types/profile.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"profile.types.d.ts","sourceRoot":"","sources":["../../src/types/profile.types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { XmlFeedTemplateType } from '../../types/profile.types';
2
+ export declare const customFeedTemplate: XmlFeedTemplateType;
3
+ //# sourceMappingURL=custom.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom.template.d.ts","sourceRoot":"","sources":["../../../src/utils/feed-templates/custom.template.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,eAAO,MAAM,kBAAkB,EAAE,mBAGhC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { XmlFeedFormat } from '../../constants/profile.constants';
2
+ export const customFeedTemplate = {
3
+ formats: [XmlFeedFormat.CSV, XmlFeedFormat.XMLS, XmlFeedFormat.TSV, XmlFeedFormat.XML],
4
+ mapping: [],
5
+ };
6
+ //# sourceMappingURL=custom.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom.template.js","sourceRoot":"","sources":["../../../src/utils/feed-templates/custom.template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGlE,MAAM,CAAC,MAAM,kBAAkB,GAAwB;IACnD,OAAO,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,GAAG,CAAC;IACtF,OAAO,EAAE,EAAE;CACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { XmlFeedTemplateType } from '../../types/profile.types';
2
+ export declare const facebookFeedTemplate: XmlFeedTemplateType;
3
+ //# sourceMappingURL=fecebook.template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fecebook.template.d.ts","sourceRoot":"","sources":["../../../src/utils/feed-templates/fecebook.template.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAiEhE,eAAO,MAAM,oBAAoB,EAAE,mBA6UlC,CAAC"}
@@ -0,0 +1,368 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable quotes */
3
+ import * as z from 'zod';
4
+ import { ulid } from 'ulid';
5
+ import { validate, validateIfNoMacro } from '.';
6
+ import { XmlFeedFormat } from '../../constants/profile.constants';
7
+ /* eslint-disable max-len */
8
+ const availabilityMapping = {
9
+ attribute: 'availability',
10
+ label: 'Availability',
11
+ description: "The current availability of the item. Supported values: in stock, out of stock. Out of stock items don't appear in ads, which prevents advertising items that aren't available. They do still appear in shops on Facebook and Instagram, but are marked as sold out",
12
+ required: true,
13
+ type: 'macro-input',
14
+ validator: (v) => validate(v, z.enum(['in stock', 'out of stock']), false),
15
+ };
16
+ const conditionMapping = {
17
+ attribute: 'condition',
18
+ label: 'Condition',
19
+ description: 'The condition of the item. Supported values: new, refurbished, used',
20
+ required: true,
21
+ type: 'macro-input',
22
+ validator: (v) => validate(v, z.enum(['new', 'refurbished', 'used'])),
23
+ };
24
+ const videoMapping = {
25
+ attribute: 'video[0].url',
26
+ label: 'Video URL 1',
27
+ description: 'Up to 20 fields each containing a link to a product video. video[0].url will be your default video and a 4:5 aspect ratio is recommended. To add multiple videos per product, such as alternative 1:1 or 9:16 aspect ratios, add additional video fields',
28
+ required: false,
29
+ type: 'macro-input',
30
+ defaultValue: '',
31
+ rules: { sections: [] },
32
+ validator: (v) => validateIfNoMacro(v, z.string().url()),
33
+ };
34
+ const customLabelMapping = {
35
+ attribute: 'custom_label_0',
36
+ label: 'Custom Label 1',
37
+ description: 'Up to five custom fields. Use these fields to create custom labels for your items. For example, you can use custom labels to filter your products in your Facebook catalog. Supported values: 0-100 characters',
38
+ required: false,
39
+ type: 'macro-input',
40
+ defaultValue: '',
41
+ rules: { sections: [] },
42
+ validator: (v) => validate(v, z.string().max(100)),
43
+ };
44
+ const customNumberMapping = {
45
+ attribute: '',
46
+ label: '',
47
+ description: 'Up to five custom fields for any additional number-related information you want to filter items by when you create product sets. These fields allow you to filter by number ranges (is greater than and is less than) when you create a set. For example, you could use a custom number field to indicate the year each item was produced, and then filter a certain year range into a set. Supported whole number from 0 to 4294967295',
48
+ required: false,
49
+ type: 'macro-input',
50
+ defaultValue: '',
51
+ rules: { sections: [] },
52
+ validator: (v) => validateIfNoMacro(v, z.string().refine(v => Number(v) >= 0 && Number(v) <= 4294967295 && Number.isInteger(Number(v)), {
53
+ message: 'Must be a whole number from 0 to 4294967295',
54
+ })),
55
+ };
56
+ export const facebookFeedTemplate = {
57
+ formats: [XmlFeedFormat.CSV, XmlFeedFormat.XMLS, XmlFeedFormat.TSV, XmlFeedFormat.XML],
58
+ documentation: 'https://www.facebook.com/business/help/120325381656392',
59
+ mapping: [
60
+ {
61
+ attribute: 'id',
62
+ label: 'ID',
63
+ description: "A unique content ID for the item. Use the item's stock keeping unit (SKU) number if possible. Each content ID must appear only once in your catalog. If you use the same content ID for multiple items, none of them will be uploaded. Character limit: 100",
64
+ required: true,
65
+ type: 'macro-input',
66
+ validator: v => validate(v, z.string().max(100), false),
67
+ defaultValue: '{{shopify.sku}}',
68
+ rules: { sections: [] },
69
+ },
70
+ {
71
+ attribute: 'title',
72
+ label: 'Title',
73
+ description: 'A specific, relevant title for the item, written in title case. Character limit: 200, but we recommend 65 maximum to avoid longer titles being cut off',
74
+ required: true,
75
+ type: 'macro-input',
76
+ validator: (v) => validate(v, z.string().max(200), false),
77
+ defaultValue: '{{shopify.title}}',
78
+ rules: { sections: [] },
79
+ },
80
+ {
81
+ attribute: 'description',
82
+ label: 'Description',
83
+ description: "A detailed description of the item. Include specific and unique product features like material or color. Use plain text only (to use HTML, see rich_text description) and don't enter text in all capital letters. The description should be different from the title. We recommend not including any links. See product description specifications. Character limit: 9,999",
84
+ required: true,
85
+ type: 'macro-input',
86
+ validator: (v) => validate(v, z.string().max(9999), false),
87
+ defaultValue: '{{shopify.description}}',
88
+ rules: { sections: [] },
89
+ },
90
+ {
91
+ ...availabilityMapping,
92
+ defaultValue: 'in stock',
93
+ rules: { sections: [] },
94
+ },
95
+ {
96
+ ...availabilityMapping,
97
+ defaultValue: 'out of stock',
98
+ rules: {
99
+ sections: [
100
+ {
101
+ id: ulid(),
102
+ ruleItems: [
103
+ {
104
+ id: ulid(),
105
+ attribute: 'inventory_quantity',
106
+ operator: 'equals',
107
+ value: 0,
108
+ },
109
+ ],
110
+ },
111
+ {
112
+ id: ulid(),
113
+ ruleItems: [
114
+ {
115
+ id: ulid(),
116
+ attribute: 'inventory_policy',
117
+ operator: 'equals',
118
+ value: 'deny',
119
+ },
120
+ ],
121
+ },
122
+ ],
123
+ },
124
+ },
125
+ {
126
+ ...conditionMapping,
127
+ defaultValue: 'new',
128
+ rules: {
129
+ sections: [],
130
+ },
131
+ },
132
+ {
133
+ attribute: 'price',
134
+ label: 'Price',
135
+ description: "The price of the item. Format the price as a number, followed by a space and then the 3-letter ISO 4217 currency code. Always use a period (.) as the decimal point, not a comma (,). Don't include currency symbols such as $, € or £. Only use one currency in your feed. To add prices in other currencies for selling in different countries, upload a country feed.",
136
+ required: true,
137
+ type: 'macro-input',
138
+ defaultValue: '{{shopify.price}} {{shopify.shop_currency}}',
139
+ rules: { sections: [] },
140
+ },
141
+ {
142
+ attribute: 'link',
143
+ label: 'Link',
144
+ description: "The link to the item's specific product page on your business's website where people can learn more about or buy the item. Links must begin with http:// or https://, be valid and be hosted on your business’s website domain",
145
+ required: true,
146
+ type: 'macro-input',
147
+ validator: (v) => validateIfNoMacro(v, z.string().url()),
148
+ defaultValue: '{{shopify.shop_domain}}/products/{{shopify.handle}}',
149
+ rules: { sections: [] },
150
+ },
151
+ {
152
+ attribute: 'image_link',
153
+ label: 'Image link',
154
+ description: 'The URL for the main image of your item. Images must be in JPEG or PNG format, at least 500 x 500 pixels and up to 8 MB',
155
+ required: true,
156
+ type: 'macro-input',
157
+ validator: (v) => validateIfNoMacro(v, z.string().url()),
158
+ defaultValue: '{{shopify.image}}',
159
+ rules: { sections: [] },
160
+ },
161
+ {
162
+ attribute: 'brand',
163
+ label: 'Brand',
164
+ description: 'The brand name of the item. Character limit: 100',
165
+ required: true,
166
+ type: 'macro-input',
167
+ validator: (v) => validate(v, z.string().max(100), false),
168
+ defaultValue: '{{shopify.vendor}}',
169
+ rules: { sections: [] },
170
+ },
171
+ {
172
+ attribute: 'quantity_to_sell_on_facebook',
173
+ label: 'Quantity to sell on Facebook',
174
+ description: "Checkout on Facebook and Instagram (US only). The quantity of this item that you have available to sell. Enter a whole number. To prevent overselling, an item's quantity is automatically reduced each time a purchase order is confirmed through checkout. When the quantity reaches 0, the item is marked as sold out in your shop on Facebook and Instagram. After 56 days, out of stock items stop appearing in your shop",
175
+ required: false,
176
+ type: 'macro-input',
177
+ validator: (v) => validateIfNoMacro(v, z.number().min(0)),
178
+ defaultValue: '{{shopify.inventory_quantity}}',
179
+ rules: { sections: [] },
180
+ },
181
+ {
182
+ attribute: 'size',
183
+ label: 'Size',
184
+ description: 'Required for items in specific product categories including clothing and shoes. The size of the item written as a word, abbreviation or number, such as "Small", "XL", "12" or "One size". Include a space between words and numbers (such as "US 12" or "15 months" instead of "US12" or "15months") and don\'t include the word "size" if not necessary (such as "XS" instead of "Size XS"). Character limit: 200',
185
+ required: false,
186
+ type: 'macro-input',
187
+ validator: (v) => validate(v, z.string().max(200)),
188
+ defaultValue: '',
189
+ rules: { sections: [] },
190
+ },
191
+ {
192
+ attribute: 'sale_price',
193
+ label: 'Sale price',
194
+ description: 'If the item is on sale, enter its discounted price. Use the same formatting as the price field',
195
+ required: false,
196
+ type: 'macro-input',
197
+ defaultValue: '',
198
+ rules: { sections: [] },
199
+ },
200
+ {
201
+ attribute: 'sale_price_effective_date',
202
+ label: 'Sale price effective date',
203
+ description: "The date, time and time zone when your sale starts and ends. If you don't add this field, any items with a sale_price remain on sale until you remove their sale price. Use this format: YYYY-MM-DDT23:59+00:00/YYYY-MM-DDT23:59+00:00",
204
+ required: false,
205
+ type: 'macro-input',
206
+ defaultValue: '',
207
+ rules: { sections: [] },
208
+ },
209
+ {
210
+ attribute: 'item_group_id',
211
+ label: 'Item group ID',
212
+ description: "Allows you to set up variants of the same product, such as different sizes, colors or patterns. Enter the same group ID in this field for all variants of the same product to indicate they're part of a group",
213
+ required: false,
214
+ type: 'macro-input',
215
+ defaultValue: '{{shopify.id}}',
216
+ rules: { sections: [] },
217
+ },
218
+ {
219
+ attribute: 'status',
220
+ label: 'Status',
221
+ description: 'Controls whether the item is active or archived in your catalog. Only active items can be seen by people in your ads, shops or any other channels. Supported values: active, archived. Items are active by default',
222
+ required: false,
223
+ type: 'macro-input',
224
+ defaultValue: '{{shopify.status}}',
225
+ rules: { sections: [] },
226
+ },
227
+ {
228
+ attribute: 'additional_image_link',
229
+ label: 'Additional image link',
230
+ description: 'Links to up to 20 additional images of your item, separated by a comma (,), semicolon (;), space ( ) or vertical bar (|). Follow the same image specifications as image_link',
231
+ required: false,
232
+ type: 'macro-input',
233
+ defaultValue: '{{shopify.images}}',
234
+ rules: { sections: [] },
235
+ },
236
+ {
237
+ attribute: 'gtin',
238
+ label: 'GTIN',
239
+ description: 'The item’s Global Trade Item Number (GTIN). Providing a GTIN is highly recommended to help classify the item. The GTIN may appear on the barcode, packaging or book cover. Not all items have a GTIN. Only provide one if you’re sure it’s correct. Don’t include dashes or spaces',
240
+ required: false,
241
+ type: 'macro-input',
242
+ defaultValue: '',
243
+ rules: { sections: [] },
244
+ },
245
+ {
246
+ attribute: 'mpn',
247
+ label: 'MPN',
248
+ description: 'The item’s manufacturer part number (MPN), a unique alphanumeric code assigned by the manufacturer in some industries to identify a specific item or part. It may appear on the packaging, label or etched directly onto the item. Providing a MPN is recommended to help classify the item if there is no GTIN. Not all items have a MPN. Only provide one if you’re sure it’s correct. Character limit: 100',
249
+ required: false,
250
+ type: 'macro-input',
251
+ defaultValue: '',
252
+ validator: (v) => validate(v, z.string()),
253
+ rules: { sections: [] },
254
+ },
255
+ {
256
+ attribute: 'google_product_category',
257
+ label: 'Google product category',
258
+ description: 'The category of the item according to the Google product taxonomy. Example: Apparel & Accessories > Clothing > Shirts & Tops or 212',
259
+ required: false,
260
+ type: 'macro-input',
261
+ defaultValue: '',
262
+ rules: { sections: [] },
263
+ },
264
+ {
265
+ attribute: 'fb_product_category',
266
+ label: 'Facebook product category',
267
+ description: "The category of the item according to Facebook's product taxonomy. Example: Clothing & Accessories > Clothing > Women's Clothing > Tops & T-Shirts or 430",
268
+ required: false,
269
+ type: 'macro-input',
270
+ defaultValue: '',
271
+ rules: { sections: [] },
272
+ },
273
+ {
274
+ attribute: 'color',
275
+ label: 'Color',
276
+ description: 'The main color of the item. Describe the color in words, not a hex code. Character limit: 200',
277
+ required: false,
278
+ type: 'macro-input',
279
+ defaultValue: '',
280
+ rules: { sections: [] },
281
+ validator: (v) => validate(v, z.string()),
282
+ },
283
+ {
284
+ attribute: 'gender',
285
+ label: 'Gender',
286
+ description: 'The gender your item is targeted towards. Supported values: female, male, unisex',
287
+ required: false,
288
+ type: 'macro-input',
289
+ defaultValue: '',
290
+ rules: { sections: [] },
291
+ validator: v => validate(v, z.enum(['female', 'male', 'unisex'])),
292
+ },
293
+ {
294
+ attribute: 'age_group',
295
+ label: 'Age group',
296
+ description: 'The age group that the item is targeted towards. Supported values: adult, all ages, teen, kids, toddler, infant, newborn',
297
+ required: false,
298
+ type: 'macro-input',
299
+ defaultValue: '',
300
+ rules: { sections: [] },
301
+ validator: v => validate(v, z.enum(['adult', 'all ages', 'teen', 'kids', 'toddler', 'infant', 'newborn'])),
302
+ },
303
+ {
304
+ attribute: 'material',
305
+ label: 'Material',
306
+ description: 'The material the item is made from, such as cotton, polyester, denim or leather. Character limit: 200',
307
+ required: false,
308
+ type: 'macro-input',
309
+ defaultValue: '',
310
+ rules: { sections: [] },
311
+ validator: (v) => validate(v, z.string()),
312
+ },
313
+ {
314
+ attribute: 'pattern',
315
+ label: 'Pattern',
316
+ description: 'The pattern or graphic print on the item. Character limit: 100',
317
+ required: false,
318
+ type: 'macro-input',
319
+ defaultValue: '',
320
+ rules: { sections: [] },
321
+ validator: (v) => validate(v, z.string().max(100)),
322
+ },
323
+ {
324
+ attribute: 'rich_text_description',
325
+ label: 'Rich text description',
326
+ description: 'A description of the item containing rich text (HTML) formatting such as bullet points or multiple paragraphs. We recommend using rich text if the description is longer than 200 characters to help make it easier to read. If this field is provided, it will display instead of the description field wherever possible, but you must still provide description as a backup option. Character limit: 9,999',
327
+ required: false,
328
+ type: 'macro-input',
329
+ defaultValue: '{{shopify.description_html}}',
330
+ rules: { sections: [] },
331
+ validator: (v) => validate(v, z.string()),
332
+ },
333
+ ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19].map(i => ({
334
+ ...videoMapping,
335
+ attribute: `video[${i}].url`,
336
+ label: `Video URL ${i + 1}`,
337
+ })),
338
+ {
339
+ attribute: 'shipping',
340
+ label: 'Shipping',
341
+ description: 'This field enables you to add the "free shipping" overlay in Advantage+ catalog ads. Enter shipping details for the item formatted as Country:Region:Service:Price Example: US:NY:Ground:9.99 USD, PH::Air:300 PHP',
342
+ required: false,
343
+ type: 'macro-input',
344
+ defaultValue: '',
345
+ rules: { sections: [] },
346
+ },
347
+ {
348
+ attribute: 'shipping_weight',
349
+ label: 'Shipping weight',
350
+ description: 'The shipping weight of the item in lb, oz, g or kg. Example: 0.3 kg',
351
+ required: false,
352
+ type: 'macro-input',
353
+ defaultValue: '{{shopify.weight}} {{shopify.weight_unit}}',
354
+ rules: { sections: [] },
355
+ },
356
+ ...[0, 1, 2, 3, 4].map(i => ({
357
+ ...customLabelMapping,
358
+ attribute: `custom_label_${i}`,
359
+ label: `Custom Label ${i + 1}`,
360
+ })),
361
+ ...[0, 1, 2, 3, 4].map(i => ({
362
+ ...customNumberMapping,
363
+ attribute: `custom_number_${i}`,
364
+ label: `Custom Number ${i + 1}`,
365
+ })),
366
+ ],
367
+ };
368
+ //# sourceMappingURL=fecebook.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fecebook.template.js","sourceRoot":"","sources":["../../../src/utils/feed-templates/fecebook.template.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { SafeParseReturnType, ZodType } from 'zod';
2
+ import { XMLFeedType } from '../../constants/profile.constants';
3
+ import { XmlFeedTemplateType } from '../../types/profile.types';
4
+ export declare const hasMacro: (v: string) => boolean;
5
+ export declare const removeMacro: (v: string) => string;
6
+ export declare function validate(value: string | number, validator: ZodType<any, any>, skipEmpty?: boolean): SafeParseReturnType<any, any>;
7
+ export declare function validateIfNoMacro(value: string | number, validator: ZodType<any, any>): SafeParseReturnType<any, any>;
8
+ export declare function getTemplate(type: XMLFeedType): XmlFeedTemplateType;
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/feed-templates/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAGhE,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,eAAO,MAAM,QAAQ,MAAO,MAAM,YAAwB,CAAC;AAC3D,eAAO,MAAM,WAAW,MAAO,MAAM,WAAmC,CAAC;AAEzE,wBAAgB,QAAQ,CACpB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAC5B,SAAS,UAAO,GACjB,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAY/B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAMrH;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,mBAAmB,CASlE"}
@@ -0,0 +1,32 @@
1
+ import { XMLFeedType } from '../../constants/profile.constants';
2
+ import { customFeedTemplate } from './custom.template';
3
+ import { facebookFeedTemplate } from './fecebook.template';
4
+ export const hasMacro = (v) => /{{[^}]+}}/.test(v);
5
+ export const removeMacro = (v) => v.replaceAll(/{{[^}]+}}/g, '');
6
+ export function validate(value, validator, skipEmpty = true) {
7
+ let valueToValidate = value;
8
+ if (typeof value === 'string') {
9
+ valueToValidate = removeMacro(value);
10
+ }
11
+ if (!value && skipEmpty) {
12
+ return { success: true, data: value };
13
+ }
14
+ return validator.safeParse(valueToValidate);
15
+ }
16
+ export function validateIfNoMacro(value, validator) {
17
+ if (typeof value === 'string' && hasMacro(value)) {
18
+ return { success: true, data: value };
19
+ }
20
+ return validator.safeParse(value);
21
+ }
22
+ export function getTemplate(type) {
23
+ switch (type) {
24
+ case XMLFeedType.Custom:
25
+ return customFeedTemplate;
26
+ case XMLFeedType.Facebook:
27
+ return facebookFeedTemplate;
28
+ default:
29
+ throw new Error(`Invalid feed type: ${type}`);
30
+ }
31
+ }
32
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/feed-templates/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAG3D,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAEzE,MAAM,UAAU,QAAQ,CACpB,KAAsB,EACtB,SAA4B,EAC5B,SAAS,GAAG,IAAI;IAEhB,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,eAAe,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,SAAS,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAsB,EAAE,SAA4B;IAClF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAiB;IACzC,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,WAAW,CAAC,MAAM;YACnB,OAAO,kBAAkB,CAAC;QAC9B,KAAK,WAAW,CAAC,QAAQ;YACrB,OAAO,oBAAoB,CAAC;QAChC;YACI,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feed-common",
3
- "version": "1.34.1",
3
+ "version": "1.35.0",
4
4
  "description": "Maxify feed common library",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -29,7 +29,8 @@
29
29
  },
30
30
  "peerDependencies": {
31
31
  "@shopify/shopify-api": "^9.2.0",
32
- "zod": "^3.23.8"
32
+ "zod": "^3.23.8",
33
+ "ulid": "^2.3.0"
33
34
  },
34
35
  "repository": {
35
36
  "type": "git",
package/src/index.ts CHANGED
@@ -9,4 +9,5 @@ export * from './types/shopify.types.js';
9
9
 
10
10
  export * from './utils/profile.js';
11
11
  export * from './utils/utils.js';
12
- export * from './utils/company.js';
12
+ export * from './utils/company.js';
13
+ export * from './utils/feed-templates';
@@ -53,7 +53,7 @@ type MappingFields = (typeof ProductUploadMappings)[number]['attribute'];
53
53
 
54
54
  export type BaseProductUploadProfile = {
55
55
  id: string;
56
- type?: XMLFeedType;
56
+ type: XMLFeedType;
57
57
  format: XmlFeedFormat | null;
58
58
  name: string;
59
59
  active: boolean;
@@ -0,0 +1,7 @@
1
+ import { XmlFeedFormat } from '../../constants/profile.constants';
2
+ import { XmlFeedTemplateType } from '../../types/profile.types';
3
+
4
+ export const customFeedTemplate: XmlFeedTemplateType = {
5
+ formats: [XmlFeedFormat.CSV, XmlFeedFormat.XMLS, XmlFeedFormat.TSV, XmlFeedFormat.XML],
6
+ mapping: [],
7
+ };
@@ -0,0 +1,404 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ /* eslint-disable quotes */
3
+ import * as z from 'zod';
4
+ import { ulid } from 'ulid';
5
+ import { validate, validateIfNoMacro } from '.';
6
+ import { XmlFeedTemplateType } from '../../types/profile.types';
7
+ import { XmlFeedFormat } from '../../constants/profile.constants';
8
+
9
+ /* eslint-disable max-len */
10
+ const availabilityMapping = {
11
+ attribute: 'availability',
12
+ label: 'Availability',
13
+ description:
14
+ "The current availability of the item. Supported values: in stock, out of stock. Out of stock items don't appear in ads, which prevents advertising items that aren't available. They do still appear in shops on Facebook and Instagram, but are marked as sold out",
15
+ required: true,
16
+ type: 'macro-input' as any,
17
+ validator: (v: string | number) => validate(v, z.enum(['in stock', 'out of stock']), false),
18
+ };
19
+
20
+ const conditionMapping = {
21
+ attribute: 'condition',
22
+ label: 'Condition',
23
+ description: 'The condition of the item. Supported values: new, refurbished, used',
24
+ required: true,
25
+ type: 'macro-input' as any,
26
+ validator: (v: string | number) => validate(v, z.enum(['new', 'refurbished', 'used'])),
27
+ };
28
+
29
+ const videoMapping = {
30
+ attribute: 'video[0].url',
31
+ label: 'Video URL 1',
32
+ description:
33
+ 'Up to 20 fields each containing a link to a product video. video[0].url will be your default video and a 4:5 aspect ratio is recommended. To add multiple videos per product, such as alternative 1:1 or 9:16 aspect ratios, add additional video fields',
34
+ required: false,
35
+ type: 'macro-input' as any,
36
+ defaultValue: '',
37
+ rules: { sections: [] },
38
+ validator: (v: string | number) => validateIfNoMacro(v, z.string().url()),
39
+ };
40
+
41
+ const customLabelMapping = {
42
+ attribute: 'custom_label_0',
43
+ label: 'Custom Label 1',
44
+ description:
45
+ 'Up to five custom fields. Use these fields to create custom labels for your items. For example, you can use custom labels to filter your products in your Facebook catalog. Supported values: 0-100 characters',
46
+ required: false,
47
+ type: 'macro-input' as any,
48
+ defaultValue: '',
49
+ rules: { sections: [] },
50
+ validator: (v: string | number) => validate(v, z.string().max(100)),
51
+ };
52
+
53
+ const customNumberMapping = {
54
+ attribute: '',
55
+ label: '',
56
+ description:
57
+ 'Up to five custom fields for any additional number-related information you want to filter items by when you create product sets. These fields allow you to filter by number ranges (is greater than and is less than) when you create a set. For example, you could use a custom number field to indicate the year each item was produced, and then filter a certain year range into a set. Supported whole number from 0 to 4294967295',
58
+ required: false,
59
+ type: 'macro-input' as any,
60
+ defaultValue: '',
61
+ rules: { sections: [] },
62
+ validator: (v: string | number) =>
63
+ validateIfNoMacro(
64
+ v,
65
+ z.string().refine(v => Number(v) >= 0 && Number(v) <= 4294967295 && Number.isInteger(Number(v)), {
66
+ message: 'Must be a whole number from 0 to 4294967295',
67
+ })
68
+ ),
69
+ };
70
+
71
+ export const facebookFeedTemplate: XmlFeedTemplateType = {
72
+ formats: [XmlFeedFormat.CSV, XmlFeedFormat.XMLS, XmlFeedFormat.TSV, XmlFeedFormat.XML],
73
+ documentation: 'https://www.facebook.com/business/help/120325381656392',
74
+ mapping: [
75
+ {
76
+ attribute: 'id',
77
+ label: 'ID',
78
+ description:
79
+ "A unique content ID for the item. Use the item's stock keeping unit (SKU) number if possible. Each content ID must appear only once in your catalog. If you use the same content ID for multiple items, none of them will be uploaded. Character limit: 100",
80
+ required: true,
81
+ type: 'macro-input',
82
+ validator: v => validate(v, z.string().max(100), false),
83
+ defaultValue: '{{shopify.sku}}',
84
+ rules: { sections: [] },
85
+ },
86
+ {
87
+ attribute: 'title',
88
+ label: 'Title',
89
+ description:
90
+ 'A specific, relevant title for the item, written in title case. Character limit: 200, but we recommend 65 maximum to avoid longer titles being cut off',
91
+ required: true,
92
+ type: 'macro-input',
93
+ validator: (v: string | number) => validate(v, z.string().max(200), false),
94
+ defaultValue: '{{shopify.title}}',
95
+ rules: { sections: [] },
96
+ },
97
+ {
98
+ attribute: 'description',
99
+ label: 'Description',
100
+ description:
101
+ "A detailed description of the item. Include specific and unique product features like material or color. Use plain text only (to use HTML, see rich_text description) and don't enter text in all capital letters. The description should be different from the title. We recommend not including any links. See product description specifications. Character limit: 9,999",
102
+ required: true,
103
+ type: 'macro-input',
104
+ validator: (v: string | number) => validate(v, z.string().max(9999), false),
105
+ defaultValue: '{{shopify.description}}',
106
+ rules: { sections: [] },
107
+ },
108
+ {
109
+ ...availabilityMapping,
110
+ defaultValue: 'in stock',
111
+ rules: { sections: [] },
112
+ },
113
+ {
114
+ ...availabilityMapping,
115
+ defaultValue: 'out of stock',
116
+ rules: {
117
+ sections: [
118
+ {
119
+ id: ulid(),
120
+ ruleItems: [
121
+ {
122
+ id: ulid(),
123
+ attribute: 'inventory_quantity',
124
+ operator: 'equals',
125
+ value: 0,
126
+ },
127
+ ],
128
+ },
129
+ {
130
+ id: ulid(),
131
+ ruleItems: [
132
+ {
133
+ id: ulid(),
134
+ attribute: 'inventory_policy',
135
+ operator: 'equals',
136
+ value: 'deny',
137
+ },
138
+ ],
139
+ },
140
+ ],
141
+ },
142
+ },
143
+ {
144
+ ...conditionMapping,
145
+ defaultValue: 'new',
146
+ rules: {
147
+ sections: [],
148
+ },
149
+ },
150
+ {
151
+ attribute: 'price',
152
+ label: 'Price',
153
+ description:
154
+ "The price of the item. Format the price as a number, followed by a space and then the 3-letter ISO 4217 currency code. Always use a period (.) as the decimal point, not a comma (,). Don't include currency symbols such as $, € or £. Only use one currency in your feed. To add prices in other currencies for selling in different countries, upload a country feed.",
155
+ required: true,
156
+ type: 'macro-input',
157
+ defaultValue: '{{shopify.price}} {{shopify.shop_currency}}',
158
+ rules: { sections: [] },
159
+ },
160
+ {
161
+ attribute: 'link',
162
+ label: 'Link',
163
+ description:
164
+ "The link to the item's specific product page on your business's website where people can learn more about or buy the item. Links must begin with http:// or https://, be valid and be hosted on your business’s website domain",
165
+ required: true,
166
+ type: 'macro-input',
167
+ validator: (v: string | number) => validateIfNoMacro(v, z.string().url()),
168
+ defaultValue: '{{shopify.shop_domain}}/products/{{shopify.handle}}',
169
+ rules: { sections: [] },
170
+ },
171
+ {
172
+ attribute: 'image_link',
173
+ label: 'Image link',
174
+ description:
175
+ 'The URL for the main image of your item. Images must be in JPEG or PNG format, at least 500 x 500 pixels and up to 8 MB',
176
+ required: true,
177
+ type: 'macro-input',
178
+ validator: (v: string | number) => validateIfNoMacro(v, z.string().url()),
179
+ defaultValue: '{{shopify.image}}',
180
+ rules: { sections: [] },
181
+ },
182
+ {
183
+ attribute: 'brand',
184
+ label: 'Brand',
185
+ description: 'The brand name of the item. Character limit: 100',
186
+ required: true,
187
+ type: 'macro-input',
188
+ validator: (v: string | number) => validate(v, z.string().max(100), false),
189
+ defaultValue: '{{shopify.vendor}}',
190
+ rules: { sections: [] },
191
+ },
192
+ {
193
+ attribute: 'quantity_to_sell_on_facebook',
194
+ label: 'Quantity to sell on Facebook',
195
+ description:
196
+ "Checkout on Facebook and Instagram (US only). The quantity of this item that you have available to sell. Enter a whole number. To prevent overselling, an item's quantity is automatically reduced each time a purchase order is confirmed through checkout. When the quantity reaches 0, the item is marked as sold out in your shop on Facebook and Instagram. After 56 days, out of stock items stop appearing in your shop",
197
+ required: false,
198
+ type: 'macro-input',
199
+ validator: (v: string | number) => validateIfNoMacro(v, z.number().min(0)),
200
+ defaultValue: '{{shopify.inventory_quantity}}',
201
+ rules: { sections: [] },
202
+ },
203
+ {
204
+ attribute: 'size',
205
+ label: 'Size',
206
+ description:
207
+ 'Required for items in specific product categories including clothing and shoes. The size of the item written as a word, abbreviation or number, such as "Small", "XL", "12" or "One size". Include a space between words and numbers (such as "US 12" or "15 months" instead of "US12" or "15months") and don\'t include the word "size" if not necessary (such as "XS" instead of "Size XS"). Character limit: 200',
208
+ required: false,
209
+ type: 'macro-input',
210
+ validator: (v: string | number) => validate(v, z.string().max(200)),
211
+ defaultValue: '',
212
+ rules: { sections: [] },
213
+ },
214
+ {
215
+ attribute: 'sale_price',
216
+ label: 'Sale price',
217
+ description:
218
+ 'If the item is on sale, enter its discounted price. Use the same formatting as the price field',
219
+ required: false,
220
+ type: 'macro-input',
221
+ defaultValue: '',
222
+ rules: { sections: [] },
223
+ },
224
+ {
225
+ attribute: 'sale_price_effective_date',
226
+ label: 'Sale price effective date',
227
+ description:
228
+ "The date, time and time zone when your sale starts and ends. If you don't add this field, any items with a sale_price remain on sale until you remove their sale price. Use this format: YYYY-MM-DDT23:59+00:00/YYYY-MM-DDT23:59+00:00",
229
+ required: false,
230
+ type: 'macro-input',
231
+ defaultValue: '',
232
+ rules: { sections: [] },
233
+ },
234
+ {
235
+ attribute: 'item_group_id',
236
+ label: 'Item group ID',
237
+ description:
238
+ "Allows you to set up variants of the same product, such as different sizes, colors or patterns. Enter the same group ID in this field for all variants of the same product to indicate they're part of a group",
239
+ required: false,
240
+ type: 'macro-input',
241
+ defaultValue: '{{shopify.id}}',
242
+ rules: { sections: [] },
243
+ },
244
+ {
245
+ attribute: 'status',
246
+ label: 'Status',
247
+ description:
248
+ 'Controls whether the item is active or archived in your catalog. Only active items can be seen by people in your ads, shops or any other channels. Supported values: active, archived. Items are active by default',
249
+ required: false,
250
+ type: 'macro-input',
251
+ defaultValue: '{{shopify.status}}',
252
+ rules: { sections: [] },
253
+ },
254
+ {
255
+ attribute: 'additional_image_link',
256
+ label: 'Additional image link',
257
+ description:
258
+ 'Links to up to 20 additional images of your item, separated by a comma (,), semicolon (;), space ( ) or vertical bar (|). Follow the same image specifications as image_link',
259
+ required: false,
260
+ type: 'macro-input',
261
+ defaultValue: '{{shopify.images}}',
262
+ rules: { sections: [] },
263
+ },
264
+ {
265
+ attribute: 'gtin',
266
+ label: 'GTIN',
267
+ description:
268
+ 'The item’s Global Trade Item Number (GTIN). Providing a GTIN is highly recommended to help classify the item. The GTIN may appear on the barcode, packaging or book cover. Not all items have a GTIN. Only provide one if you’re sure it’s correct. Don’t include dashes or spaces',
269
+ required: false,
270
+ type: 'macro-input',
271
+ defaultValue: '',
272
+ rules: { sections: [] },
273
+ },
274
+ {
275
+ attribute: 'mpn',
276
+ label: 'MPN',
277
+ description:
278
+ 'The item’s manufacturer part number (MPN), a unique alphanumeric code assigned by the manufacturer in some industries to identify a specific item or part. It may appear on the packaging, label or etched directly onto the item. Providing a MPN is recommended to help classify the item if there is no GTIN. Not all items have a MPN. Only provide one if you’re sure it’s correct. Character limit: 100',
279
+ required: false,
280
+ type: 'macro-input',
281
+ defaultValue: '',
282
+ validator: (v: string | number) => validate(v, z.string()),
283
+ rules: { sections: [] },
284
+ },
285
+ {
286
+ attribute: 'google_product_category',
287
+ label: 'Google product category',
288
+ description:
289
+ 'The category of the item according to the Google product taxonomy. Example: Apparel & Accessories > Clothing > Shirts & Tops or 212',
290
+ required: false,
291
+ type: 'macro-input',
292
+ defaultValue: '',
293
+ rules: { sections: [] },
294
+ },
295
+ {
296
+ attribute: 'fb_product_category',
297
+ label: 'Facebook product category',
298
+ description:
299
+ "The category of the item according to Facebook's product taxonomy. Example: Clothing & Accessories > Clothing > Women's Clothing > Tops & T-Shirts or 430",
300
+ required: false,
301
+ type: 'macro-input',
302
+ defaultValue: '',
303
+ rules: { sections: [] },
304
+ },
305
+ {
306
+ attribute: 'color',
307
+ label: 'Color',
308
+ description:
309
+ 'The main color of the item. Describe the color in words, not a hex code. Character limit: 200',
310
+ required: false,
311
+ type: 'macro-input',
312
+ defaultValue: '',
313
+ rules: { sections: [] },
314
+ validator: (v: string | number) => validate(v, z.string()),
315
+ },
316
+ {
317
+ attribute: 'gender',
318
+ label: 'Gender',
319
+ description: 'The gender your item is targeted towards. Supported values: female, male, unisex',
320
+ required: false,
321
+ type: 'macro-input',
322
+ defaultValue: '',
323
+ rules: { sections: [] },
324
+ validator: v => validate(v, z.enum(['female', 'male', 'unisex'])),
325
+ },
326
+ {
327
+ attribute: 'age_group',
328
+ label: 'Age group',
329
+ description:
330
+ 'The age group that the item is targeted towards. Supported values: adult, all ages, teen, kids, toddler, infant, newborn',
331
+ required: false,
332
+ type: 'macro-input',
333
+ defaultValue: '',
334
+ rules: { sections: [] },
335
+ validator: v => validate(v, z.enum(['adult', 'all ages', 'teen', 'kids', 'toddler', 'infant', 'newborn'])),
336
+ },
337
+ {
338
+ attribute: 'material',
339
+ label: 'Material',
340
+ description:
341
+ 'The material the item is made from, such as cotton, polyester, denim or leather. Character limit: 200',
342
+ required: false,
343
+ type: 'macro-input',
344
+ defaultValue: '',
345
+ rules: { sections: [] },
346
+ validator: (v: string | number) => validate(v, z.string()),
347
+ },
348
+ {
349
+ attribute: 'pattern',
350
+ label: 'Pattern',
351
+ description: 'The pattern or graphic print on the item. Character limit: 100',
352
+ required: false,
353
+ type: 'macro-input',
354
+ defaultValue: '',
355
+ rules: { sections: [] },
356
+ validator: (v: string | number) => validate(v, z.string().max(100)),
357
+ },
358
+ {
359
+ attribute: 'rich_text_description',
360
+ label: 'Rich text description',
361
+ description:
362
+ 'A description of the item containing rich text (HTML) formatting such as bullet points or multiple paragraphs. We recommend using rich text if the description is longer than 200 characters to help make it easier to read. If this field is provided, it will display instead of the description field wherever possible, but you must still provide description as a backup option. Character limit: 9,999',
363
+ required: false,
364
+ type: 'macro-input',
365
+ defaultValue: '{{shopify.description_html}}',
366
+ rules: { sections: [] },
367
+ validator: (v: string | number) => validate(v, z.string()),
368
+ },
369
+ ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19].map(i => ({
370
+ ...videoMapping,
371
+ attribute: `video[${i}].url`,
372
+ label: `Video URL ${i + 1}`,
373
+ })),
374
+ {
375
+ attribute: 'shipping',
376
+ label: 'Shipping',
377
+ description:
378
+ 'This field enables you to add the "free shipping" overlay in Advantage+ catalog ads. Enter shipping details for the item formatted as Country:Region:Service:Price Example: US:NY:Ground:9.99 USD, PH::Air:300 PHP',
379
+ required: false,
380
+ type: 'macro-input',
381
+ defaultValue: '',
382
+ rules: { sections: [] },
383
+ },
384
+ {
385
+ attribute: 'shipping_weight',
386
+ label: 'Shipping weight',
387
+ description: 'The shipping weight of the item in lb, oz, g or kg. Example: 0.3 kg',
388
+ required: false,
389
+ type: 'macro-input',
390
+ defaultValue: '{{shopify.weight}} {{shopify.weight_unit}}',
391
+ rules: { sections: [] },
392
+ },
393
+ ...[0, 1, 2, 3, 4].map(i => ({
394
+ ...customLabelMapping,
395
+ attribute: `custom_label_${i}`,
396
+ label: `Custom Label ${i + 1}`,
397
+ })),
398
+ ...[0, 1, 2, 3, 4].map(i => ({
399
+ ...customNumberMapping,
400
+ attribute: `custom_number_${i}`,
401
+ label: `Custom Number ${i + 1}`,
402
+ })),
403
+ ],
404
+ };
@@ -0,0 +1,46 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { SafeParseReturnType, ZodType } from 'zod';
3
+ import { XMLFeedType } from '../../constants/profile.constants';
4
+ import { customFeedTemplate } from './custom.template';
5
+ import { facebookFeedTemplate } from './fecebook.template';
6
+ import { XmlFeedTemplateType } from '../../types/profile.types';
7
+
8
+ export const hasMacro = (v: string) => /{{[^}]+}}/.test(v);
9
+ export const removeMacro = (v: string) => v.replaceAll(/{{[^}]+}}/g, '');
10
+
11
+ export function validate(
12
+ value: string | number,
13
+ validator: ZodType<any, any>,
14
+ skipEmpty = true
15
+ ): SafeParseReturnType<any, any> {
16
+ let valueToValidate = value;
17
+
18
+ if (typeof value === 'string') {
19
+ valueToValidate = removeMacro(value);
20
+ }
21
+
22
+ if (!value && skipEmpty) {
23
+ return { success: true, data: value };
24
+ }
25
+
26
+ return validator.safeParse(valueToValidate);
27
+ }
28
+
29
+ export function validateIfNoMacro(value: string | number, validator: ZodType<any, any>): SafeParseReturnType<any, any> {
30
+ if (typeof value === 'string' && hasMacro(value)) {
31
+ return { success: true, data: value };
32
+ }
33
+
34
+ return validator.safeParse(value);
35
+ }
36
+
37
+ export function getTemplate(type: XMLFeedType): XmlFeedTemplateType {
38
+ switch (type) {
39
+ case XMLFeedType.Custom:
40
+ return customFeedTemplate;
41
+ case XMLFeedType.Facebook:
42
+ return facebookFeedTemplate;
43
+ default:
44
+ throw new Error(`Invalid feed type: ${type}`);
45
+ }
46
+ }