@teleporthq/teleport-plugin-next-data-source 0.43.55 → 0.43.59

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.
Files changed (110) hide show
  1. package/__tests__/array-mapper-cache-wiring.test.ts +425 -0
  2. package/__tests__/data-source-cache-wrapping.test.ts +152 -0
  3. package/__tests__/ecommerce-product-allow-backorders.test.ts +156 -0
  4. package/__tests__/ecommerce-product-model.test.ts +179 -0
  5. package/__tests__/ecommerce-product-storefront-tax.test.ts +118 -0
  6. package/dist/cjs/cache/ast.d.ts +71 -0
  7. package/dist/cjs/cache/ast.d.ts.map +1 -0
  8. package/dist/cjs/cache/ast.js +229 -0
  9. package/dist/cjs/cache/ast.js.map +1 -0
  10. package/dist/cjs/cache/config.d.ts +22 -0
  11. package/dist/cjs/cache/config.d.ts.map +1 -0
  12. package/dist/cjs/cache/config.js +67 -0
  13. package/dist/cjs/cache/config.js.map +1 -0
  14. package/dist/cjs/cache/types.d.ts +31 -0
  15. package/dist/cjs/cache/types.d.ts.map +1 -0
  16. package/dist/cjs/cache/types.js +3 -0
  17. package/dist/cjs/cache/types.js.map +1 -0
  18. package/dist/cjs/data-source-fetchers.d.ts +5 -3
  19. package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
  20. package/dist/cjs/data-source-fetchers.js +51 -8
  21. package/dist/cjs/data-source-fetchers.js.map +1 -1
  22. package/dist/cjs/fetchers/teleport.d.ts +2 -2
  23. package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
  24. package/dist/cjs/fetchers/teleport.js +3 -2
  25. package/dist/cjs/fetchers/teleport.js.map +1 -1
  26. package/dist/cjs/index.d.ts +2 -0
  27. package/dist/cjs/index.d.ts.map +1 -1
  28. package/dist/cjs/index.js +14 -9
  29. package/dist/cjs/index.js.map +1 -1
  30. package/dist/cjs/loading-state.d.ts.map +1 -1
  31. package/dist/cjs/loading-state.js +74 -2
  32. package/dist/cjs/loading-state.js.map +1 -1
  33. package/dist/cjs/pagination-plugin.d.ts.map +1 -1
  34. package/dist/cjs/pagination-plugin.js +204 -64
  35. package/dist/cjs/pagination-plugin.js.map +1 -1
  36. package/dist/cjs/transformations/ecommerce-product.d.ts +27 -1
  37. package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
  38. package/dist/cjs/transformations/ecommerce-product.js +8 -3
  39. package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
  40. package/dist/cjs/transformations/index.d.ts +14 -2
  41. package/dist/cjs/transformations/index.d.ts.map +1 -1
  42. package/dist/cjs/transformations/index.js +37 -3
  43. package/dist/cjs/transformations/index.js.map +1 -1
  44. package/dist/cjs/transformations/shared-utils.d.ts.map +1 -1
  45. package/dist/cjs/transformations/shared-utils.js +1 -1
  46. package/dist/cjs/transformations/shared-utils.js.map +1 -1
  47. package/dist/cjs/tsconfig.tsbuildinfo +1 -1
  48. package/dist/cjs/utils.d.ts +4 -3
  49. package/dist/cjs/utils.d.ts.map +1 -1
  50. package/dist/cjs/utils.js +6 -4
  51. package/dist/cjs/utils.js.map +1 -1
  52. package/dist/esm/cache/ast.d.ts +71 -0
  53. package/dist/esm/cache/ast.d.ts.map +1 -0
  54. package/dist/esm/cache/ast.js +196 -0
  55. package/dist/esm/cache/ast.js.map +1 -0
  56. package/dist/esm/cache/config.d.ts +22 -0
  57. package/dist/esm/cache/config.d.ts.map +1 -0
  58. package/dist/esm/cache/config.js +62 -0
  59. package/dist/esm/cache/config.js.map +1 -0
  60. package/dist/esm/cache/types.d.ts +31 -0
  61. package/dist/esm/cache/types.d.ts.map +1 -0
  62. package/dist/esm/cache/types.js +2 -0
  63. package/dist/esm/cache/types.js.map +1 -0
  64. package/dist/esm/data-source-fetchers.d.ts +5 -3
  65. package/dist/esm/data-source-fetchers.d.ts.map +1 -1
  66. package/dist/esm/data-source-fetchers.js +51 -8
  67. package/dist/esm/data-source-fetchers.js.map +1 -1
  68. package/dist/esm/fetchers/teleport.d.ts +2 -2
  69. package/dist/esm/fetchers/teleport.d.ts.map +1 -1
  70. package/dist/esm/fetchers/teleport.js +3 -2
  71. package/dist/esm/fetchers/teleport.js.map +1 -1
  72. package/dist/esm/index.d.ts +2 -0
  73. package/dist/esm/index.d.ts.map +1 -1
  74. package/dist/esm/index.js +12 -8
  75. package/dist/esm/index.js.map +1 -1
  76. package/dist/esm/loading-state.d.ts.map +1 -1
  77. package/dist/esm/loading-state.js +74 -2
  78. package/dist/esm/loading-state.js.map +1 -1
  79. package/dist/esm/pagination-plugin.d.ts.map +1 -1
  80. package/dist/esm/pagination-plugin.js +205 -65
  81. package/dist/esm/pagination-plugin.js.map +1 -1
  82. package/dist/esm/transformations/ecommerce-product.d.ts +27 -1
  83. package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
  84. package/dist/esm/transformations/ecommerce-product.js +8 -3
  85. package/dist/esm/transformations/ecommerce-product.js.map +1 -1
  86. package/dist/esm/transformations/index.d.ts +14 -2
  87. package/dist/esm/transformations/index.d.ts.map +1 -1
  88. package/dist/esm/transformations/index.js +36 -3
  89. package/dist/esm/transformations/index.js.map +1 -1
  90. package/dist/esm/transformations/shared-utils.d.ts.map +1 -1
  91. package/dist/esm/transformations/shared-utils.js +1 -1
  92. package/dist/esm/transformations/shared-utils.js.map +1 -1
  93. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  94. package/dist/esm/utils.d.ts +4 -3
  95. package/dist/esm/utils.d.ts.map +1 -1
  96. package/dist/esm/utils.js +6 -4
  97. package/dist/esm/utils.js.map +1 -1
  98. package/package.json +5 -5
  99. package/src/cache/ast.ts +265 -0
  100. package/src/cache/config.ts +79 -0
  101. package/src/cache/types.ts +31 -0
  102. package/src/data-source-fetchers.ts +66 -12
  103. package/src/fetchers/teleport.ts +3 -3
  104. package/src/index.ts +10 -4
  105. package/src/loading-state.ts +65 -2
  106. package/src/pagination-plugin.ts +315 -116
  107. package/src/transformations/ecommerce-product.ts +161 -5
  108. package/src/transformations/index.ts +43 -4
  109. package/src/transformations/shared-utils.ts +14 -0
  110. package/src/utils.ts +10 -5
@@ -1,4 +1,32 @@
1
1
  import type { UIDLEcommerceCategory } from '@teleporthq/teleport-types'
2
+ import { StorefrontTax } from '@teleporthq/teleport-shared'
3
+
4
+ /**
5
+ * Everything the product transform needs baked in at export time, beyond the
6
+ * row itself. An options OBJECT rather than positional parameters: the list has
7
+ * already grown twice and every caller in the chain has to forward it verbatim.
8
+ */
9
+ export interface EcommerceProductTransformOptions {
10
+ /** Category taxonomy — lives only in the UIDL, there is no DB table for it. */
11
+ categories?: UIDLEcommerceCategory[]
12
+ /**
13
+ * Percentage to ADD on top of every stored (NET) price for DISPLAY, or 0.
14
+ * Resolved by the caller through `StorefrontTax.resolveStorefrontTaxRate`.
15
+ */
16
+ storefrontTaxRate?: number
17
+ /**
18
+ * TRUE when stock levels must never gate purchasability in the storefront:
19
+ * the merchant disabled stock management entirely OR opted into backorders
20
+ * (`stockManagementConfig.allowBackorders`). Resolved by the caller through
21
+ * `buildProductTransformOptions`. Baked into the generated transform as
22
+ * `ALLOW_BACKORDERS`: `outOfStock` then always reads 'false' and every
23
+ * EXISTING variant combination counts as in stock — a combination that does
24
+ * not exist at all stays unavailable (there is nothing to backorder).
25
+ * Mirrors the GUI rule in
26
+ * `apps/gui/app/project-page/features/e-commerce/utils/product-variants.ts`.
27
+ */
28
+ allowBackorders?: boolean
29
+ }
2
30
 
3
31
  /**
4
32
  * Flattens the nested category tree (`ecommerceSettings.categories`, baked at
@@ -47,11 +75,22 @@ const flattenCategoriesById = (
47
75
  * that UIDL components expect.
48
76
  */
49
77
  export const generateEcommerceProductTransformationCode = (
50
- categories?: UIDLEcommerceCategory[]
78
+ options: EcommerceProductTransformOptions = {}
51
79
  ): string => {
52
- const categoriesByIdJson = JSON.stringify(flattenCategoriesById(categories))
80
+ const categoriesByIdJson = JSON.stringify(flattenCategoriesById(options.categories))
81
+ const taxHelperCode = StorefrontTax.generateStorefrontTaxHelperCode(
82
+ options.storefrontTaxRate ?? 0
83
+ )
84
+ const allowBackordersLiteral = options.allowBackorders === true ? 'true' : 'false'
53
85
 
54
86
  return `
87
+ ${taxHelperCode}
88
+
89
+ // Baked from the merchant's stock settings: TRUE when stock never blocks a
90
+ // purchase (stock management off OR backorders allowed). Regenerating the
91
+ // project refreshes it — do not hand-edit. See EcommerceProductTransformOptions.
92
+ var ALLOW_BACKORDERS = ${allowBackordersLiteral}
93
+
55
94
  // Category taxonomy (id -> {name, slug, translations}), baked in at export
56
95
  // time — see flattenCategoriesById in ecommerce-product.ts. Empty when the
57
96
  // store has no category taxonomy, or products.category_ids simply resolves
@@ -69,6 +108,50 @@ function resolveCategoryName(categoryInfo, currentLang, mainLang) {
69
108
  return categoryInfo.name
70
109
  }
71
110
 
111
+ // The merchant's "Show 3D model by default" toggle, as every backend may hand
112
+ // it back: a real boolean, 1/0, 'true'/'false'/'t'/'f' strings — and NULL /
113
+ // absent / '' as ON, because a product that has a model shows it unless the
114
+ // merchant switched it off. MUST mirror normalizeShowModelFlag in the GUI's
115
+ // features/e-commerce/constants/product-model.ts.
116
+ function normalizeShowModelFlag(raw) {
117
+ if (raw === null || raw === undefined || raw === '') return true
118
+ if (typeof raw === 'boolean') return raw
119
+ if (typeof raw === 'number') return raw !== 0
120
+ if (typeof raw === 'string') {
121
+ var token = raw.trim().toLowerCase()
122
+ return !(token === 'false' || token === 'f' || token === '0' || token === 'no' || token === 'off')
123
+ }
124
+ return true
125
+ }
126
+
127
+ // The product's media gallery in display order, HERO FIRST: the model when it
128
+ // is shown by default, otherwise the images with the model last. Each entry is
129
+ // { kind: 'image' | 'model', src, poster, thumbnail, alt }; 'thumbnail' is what
130
+ // a strip draws and is never empty for an entry that can appear in one. MUST
131
+ // mirror buildProductGalleryMedia in the GUI's
132
+ // features/e-commerce/utils/product-gallery-media.ts.
133
+ function buildProductGalleryMedia(params) {
134
+ var imageItems = []
135
+ for (var gi = 0; gi < params.images.length; gi++) {
136
+ imageItems.push({
137
+ kind: 'image',
138
+ src: params.images[gi],
139
+ poster: '',
140
+ thumbnail: params.images[gi],
141
+ alt: params.imageAlt || params.name,
142
+ })
143
+ }
144
+ if (!params.modelUrl) return imageItems
145
+ var modelItem = {
146
+ kind: 'model',
147
+ src: params.modelUrl,
148
+ poster: params.modelPoster || '',
149
+ thumbnail: params.modelPoster || params.mainImage || params.images[0] || '',
150
+ alt: params.name,
151
+ }
152
+ return params.showModel === 'true' ? [modelItem].concat(imageItems) : imageItems.concat([modelItem])
153
+ }
154
+
72
155
  // ============================================================
73
156
  // E-Commerce Product Transformation
74
157
  // ============================================================
@@ -294,6 +377,36 @@ function buildEcommerceProduct(record, options) {
294
377
  // Step 7: images = full resolved deduplicated array
295
378
  var images = resolvedImages
296
379
 
380
+ // -------------------------------------------------------
381
+ // 3D model (one per product; GUI: constants/product-model.ts)
382
+ // -------------------------------------------------------
383
+ // model_url / model_poster_url hold an asset id OR a raw URL like image_url.
384
+ // A poster the merchant never got (capture failed, plan cap) falls back to
385
+ // the main image so <model-viewer> always has something to paint first.
386
+ var modelUrl = resolveMediaUrl(record.model_url, assetMap)
387
+ var modelPoster = modelUrl ? resolveMediaUrl(record.model_poster_url, assetMap) || mainImage : null
388
+ var hasModel = modelUrl ? 'true' : 'false'
389
+ // STRING gate ('true'/'false') like outOfStock: whether the model replaces the
390
+ // main image on the card / details hero. A product whose only media is the
391
+ // model always shows it. An absent field must read as the IMAGE branch, so the
392
+ // builders gate the viewer on = 'true' and the image on != 'true'.
393
+ var showModel =
394
+ modelUrl && (normalizeShowModelFlag(record.show_model_by_default) || images.length === 0)
395
+ ? 'true'
396
+ : 'false'
397
+ var galleryMedia = buildProductGalleryMedia({
398
+ images: images,
399
+ mainImage: mainImage,
400
+ modelUrl: modelUrl,
401
+ modelPoster: modelPoster,
402
+ showModel: showModel,
403
+ imageAlt: imageAlt,
404
+ name: name,
405
+ })
406
+ // Everything that is not the hero — the details thumbnail strip. When the
407
+ // model is the hero the main image moves in here, so the modal stays reachable.
408
+ var galleryThumbnails = galleryMedia.slice(1)
409
+
297
410
  // Timestamps
298
411
  var rawCreatedAt = pickFirst(record.created_at, record.createdAt, record.created)
299
412
  var createdAt = normalizeTimestamp(rawCreatedAt)
@@ -311,7 +424,9 @@ function buildEcommerceProduct(record, options) {
311
424
  // string), leaving the Add to Cart button visible on out-of-stock
312
425
  // products. NULL/NaN quantity → 'false' (treated as "unlimited
313
426
  // stock", same as the upstream cart-availability rewriter).
314
- var outOfStock = (quantity !== null && !isNaN(quantity) && quantity <= 0) ? 'true' : 'false'
427
+ // With ALLOW_BACKORDERS the merchant sells past zero (or does not track
428
+ // stock at all), so nothing is ever presented as out of stock.
429
+ var outOfStock = (!ALLOW_BACKORDERS && quantity !== null && !isNaN(quantity) && quantity <= 0) ? 'true' : 'false'
315
430
 
316
431
  // Per-value availability + default-selection flags, derived from the
317
432
  // purchasable combinations, so the storefront picker renders its
@@ -349,6 +464,32 @@ function buildEcommerceProduct(record, options) {
349
464
  var hasInStockCombination = !!(firstVariant && isVariantInStock(firstVariant))
350
465
  var defaultVariantId = hasInStockCombination ? firstVariant.id : ''
351
466
  var defaultVariantPrice = firstVariant ? formatVariantPrice(firstVariant.price, price) : ''
467
+ // Gross (tax-inclusive) counterparts of the three price fields the STOREFRONT
468
+ // renders. \`price\` / \`defaultVariantPrice\` / \`variantsJson\` deliberately stay
469
+ // NET: the same transform feeds the merchant's admin panel, and every write
470
+ // path (add-to-cart, checkout, the invoice route) re-reads the raw row and
471
+ // must keep seeing the price the merchant typed. Only these three are safe to
472
+ // gross, because nothing writes them back.
473
+ //
474
+ // MUST mirror packages/renderer/src/utils/ecommerce-products.ts.
475
+ var displayPrice = grossMoney(price)
476
+ var defaultVariantDisplayPrice = firstVariant
477
+ ? grossMoney(formatVariantPrice(firstVariant.price, price))
478
+ : ''
479
+ var variantsDisplay = []
480
+ for (var dv = 0; dv < variants.length; dv++) {
481
+ var dvRow = variants[dv]
482
+ variantsDisplay.push({
483
+ id: dvRow.id,
484
+ options: dvRow.options,
485
+ // A null variant price INHERITS the product price, so gross the RESOLVED
486
+ // value — otherwise an inheriting combination would fall back to the net
487
+ // base price in the picker while an overriding one showed gross.
488
+ price: applyStorefrontTax(dvRow.price == null ? price : dvRow.price),
489
+ quantity: dvRow.quantity,
490
+ image_url: dvRow.image_url,
491
+ })
492
+ }
352
493
  // Can this product be added to the cart at all, before the shopper touches the
353
494
  // picker? A STRING, same convention as outOfStock/requiresVariantSelection.
354
495
  //
@@ -373,6 +514,7 @@ function buildEcommerceProduct(record, options) {
373
514
  // combinations + axes from these JSON strings via getAttribute.
374
515
  var variantOptionsJson = safeStringifyJson(variantOptions)
375
516
  var variantsJson = safeStringifyJson(variants)
517
+ var variantsDisplayJson = safeStringifyJson(variantsDisplay)
376
518
 
377
519
  return {
378
520
  id: id,
@@ -409,6 +551,12 @@ function buildEcommerceProduct(record, options) {
409
551
  image_url: mainImage,
410
552
  galleryImages: galleryImages,
411
553
  images: images,
554
+ modelUrl: modelUrl,
555
+ modelPoster: modelPoster,
556
+ hasModel: hasModel,
557
+ showModel: showModel,
558
+ galleryMedia: galleryMedia,
559
+ galleryThumbnails: galleryThumbnails,
412
560
  createdAt: createdAt,
413
561
  updatedAt: updatedAt,
414
562
  created: created,
@@ -418,16 +566,24 @@ function buildEcommerceProduct(record, options) {
418
566
  variants: variants,
419
567
  variantOptionsJson: variantOptionsJson,
420
568
  variantsJson: variantsJson,
569
+ variantsDisplayJson: variantsDisplayJson,
421
570
  defaultVariantId: defaultVariantId,
422
571
  defaultVariantPrice: defaultVariantPrice,
572
+ displayPrice: displayPrice,
573
+ defaultVariantDisplayPrice: defaultVariantDisplayPrice,
423
574
  hasPurchasableVariant: hasPurchasableVariant,
424
575
  }
425
576
  }
426
577
 
427
578
  // --- Variant availability helpers (mirror packages/renderer ecommerce-products) ---
428
- // A variant is in stock when its quantity is null (unlimited) or > 0.
579
+ // A variant is in stock when its quantity is null (unlimited) or > 0. With
580
+ // ALLOW_BACKORDERS every EXISTING combination is purchasable regardless of its
581
+ // quantity — but a missing combination (null) is still not in stock: there is
582
+ // no variant row to backorder.
429
583
  function isVariantInStock(v) {
430
- return !v ? false : v.quantity == null || v.quantity > 0
584
+ if (!v) return false
585
+ if (ALLOW_BACKORDERS) return true
586
+ return v.quantity == null || v.quantity > 0
431
587
  }
432
588
  function variantCoversAllAxes(v, axisKeys) {
433
589
  if (!v || !v.options) return false
@@ -1,7 +1,46 @@
1
- import type { UIDLEcommerceCategory } from '@teleporthq/teleport-types'
1
+ import type { GeneratorOptions } from '@teleporthq/teleport-types'
2
+ import { StorefrontTax } from '@teleporthq/teleport-shared'
2
3
  import { generateSharedTransformationCode } from './shared-utils'
3
4
  import { generateBlogPostTransformationCode } from './blog-post'
4
- import { generateEcommerceProductTransformationCode } from './ecommerce-product'
5
+ import {
6
+ generateEcommerceProductTransformationCode,
7
+ type EcommerceProductTransformOptions,
8
+ } from './ecommerce-product'
9
+
10
+ export type { EcommerceProductTransformOptions }
11
+
12
+ /**
13
+ * Stock never gates purchasability when the merchant disabled stock management
14
+ * entirely or opted into backorders. Mirrors the GUI rule in
15
+ * `apps/gui/app/project-page/features/e-commerce/utils/product-variants.ts`
16
+ * (`isVariantInStock`). A project without e-commerce settings keeps the
17
+ * strict default (stock gates apply) — same behaviour as before the flag.
18
+ */
19
+ const resolveAllowBackorders = (
20
+ settings: GeneratorOptions['ecommerceSettings'] | undefined
21
+ ): boolean => {
22
+ if (!settings) {
23
+ return false
24
+ }
25
+ return !settings.stockManagement || settings.stockManagementConfig?.allowBackorders === true
26
+ }
27
+
28
+ /**
29
+ * Collects everything the product transform bakes in from the generator
30
+ * options, in ONE place so every fetcher-emitting call site stays in step.
31
+ *
32
+ * `storefrontTaxRate` is what turns a NET catalogue price into the price the
33
+ * shopper is quoted; `resolveStorefrontTaxRate` returns 0 (a no-op) for
34
+ * tax-inclusive or untaxed stores. `allowBackorders` is the effective
35
+ * "stock never blocks a purchase" flag — see `resolveAllowBackorders`.
36
+ */
37
+ export const buildProductTransformOptions = (
38
+ options: Pick<GeneratorOptions, 'ecommerceSettings' | 'invoiceSettings'>
39
+ ): EcommerceProductTransformOptions => ({
40
+ categories: options.ecommerceSettings?.categories,
41
+ storefrontTaxRate: StorefrontTax.resolveStorefrontTaxRate(options.invoiceSettings),
42
+ allowBackorders: resolveAllowBackorders(options.ecommerceSettings),
43
+ })
5
44
 
6
45
  export type TransformationType = 'blog-post' | 'ecommerce-product' | null
7
46
 
@@ -51,7 +90,7 @@ export const detectTransformationType = (tableName: string): TransformationType
51
90
  */
52
91
  export const getTransformationCode = (
53
92
  tableName: string,
54
- categories?: UIDLEcommerceCategory[]
93
+ options: EcommerceProductTransformOptions = {}
55
94
  ): string => {
56
95
  const type = detectTransformationType(tableName)
57
96
  if (!type) {
@@ -64,7 +103,7 @@ export const getTransformationCode = (
64
103
  case 'blog-post':
65
104
  return shared + generateBlogPostTransformationCode()
66
105
  case 'ecommerce-product':
67
- return shared + generateEcommerceProductTransformationCode(categories)
106
+ return shared + generateEcommerceProductTransformationCode(options)
68
107
  default:
69
108
  return ''
70
109
  }
@@ -234,6 +234,20 @@ function resolveAssetUrl(value, assetMap) {
234
234
  return value
235
235
  }
236
236
 
237
+ // Whether an asset-id resolution produced a real URL. resolveAssetUrl returns
238
+ // an UNKNOWN id verbatim (asset deleted, teleport_assets not mirrored yet) and
239
+ // a bare 'TQ_...' must never reach a <model-viewer src> or a poster.
240
+ function isResolvedMediaUrl(value) {
241
+ return typeof value === 'string' && (isUrl(value) || value.charAt(0) === '/')
242
+ }
243
+
244
+ // resolveAssetUrl for MEDIA that has no safe fallback: a value that did not
245
+ // resolve to a URL is reported as absent (null) instead of passed through.
246
+ function resolveMediaUrl(value, assetMap) {
247
+ var resolved = resolveAssetUrl(value, assetMap)
248
+ return isResolvedMediaUrl(resolved) ? resolved : null
249
+ }
250
+
237
251
  function resolveAssetUrls(values, assetMap) {
238
252
  if (!Array.isArray(values)) return []
239
253
  return values
package/src/utils.ts CHANGED
@@ -7,12 +7,12 @@ import {
7
7
  UIDLDataSource,
8
8
  DataSourceType,
9
9
  ChunkType,
10
- UIDLEcommerceCategory,
11
10
  } from '@teleporthq/teleport-types'
12
11
  import * as types from '@babel/types'
13
12
  import { ASTUtils } from '@teleporthq/teleport-plugin-common'
14
13
  import { StringUtils } from '@teleporthq/teleport-shared'
15
14
  import { generateDataSourceFetcherWithCore } from './data-source-fetchers'
15
+ import type { EcommerceProductTransformOptions } from './transformations'
16
16
  import { DATA_SOURCE_ISR_REVALIDATE_SECONDS } from './isr'
17
17
 
18
18
  const VALID_DATA_SOURCE_TYPES: DataSourceType[] = [
@@ -192,7 +192,7 @@ export const extractDataSourceIntoNextAPIFolder = (
192
192
  dataSources: Record<string, UIDLDataSource>,
193
193
  componentChunk: ChunkDefinition,
194
194
  extractedResources: GeneratorOptions['extractedResources'],
195
- categories?: UIDLEcommerceCategory[]
195
+ transformOptions: EcommerceProductTransformOptions = {}
196
196
  ) => {
197
197
  try {
198
198
  // Validate node content structure
@@ -446,7 +446,12 @@ export default dataSourceModule.handler
446
446
  // Generate fetcher code for API route (exports just the handler)
447
447
  let fetcherCode: string
448
448
  try {
449
- fetcherCode = generateDataSourceFetcherWithCore(dataSource, tableName || '', true, categories)
449
+ fetcherCode = generateDataSourceFetcherWithCore(
450
+ dataSource,
451
+ tableName || '',
452
+ true,
453
+ transformOptions
454
+ )
450
455
  } catch (error) {
451
456
  return
452
457
  }
@@ -896,7 +901,7 @@ export const extractDataSourceIntoGetStaticProps = (
896
901
  dependencies: Record<string, any>,
897
902
  dynamicRouteAttr?: string,
898
903
  folderPath?: string[],
899
- categories?: UIDLEcommerceCategory[]
904
+ transformOptions: EcommerceProductTransformOptions = {}
900
905
  ): { success: boolean; chunk?: any } => {
901
906
  try {
902
907
  // Validate node content
@@ -1224,7 +1229,7 @@ export const extractDataSourceIntoGetStaticProps = (
1224
1229
  dataSource,
1225
1230
  tableName || '',
1226
1231
  false,
1227
- categories
1232
+ transformOptions
1228
1233
  )
1229
1234
  } catch (error) {
1230
1235
  // tslint:disable-next-line:no-console