@teleporthq/teleport-plugin-next-data-source 0.43.54 → 0.43.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/array-mapper-cache-wiring.test.ts +425 -0
- package/__tests__/data-source-cache-wrapping.test.ts +152 -0
- package/__tests__/ecommerce-product-storefront-tax.test.ts +118 -0
- package/__tests__/ecommerce-product-variant-availability.test.ts +264 -0
- package/dist/cjs/cache/ast.d.ts +71 -0
- package/dist/cjs/cache/ast.d.ts.map +1 -0
- package/dist/cjs/cache/ast.js +229 -0
- package/dist/cjs/cache/ast.js.map +1 -0
- package/dist/cjs/cache/config.d.ts +22 -0
- package/dist/cjs/cache/config.d.ts.map +1 -0
- package/dist/cjs/cache/config.js +67 -0
- package/dist/cjs/cache/config.js.map +1 -0
- package/dist/cjs/cache/types.d.ts +31 -0
- package/dist/cjs/cache/types.d.ts.map +1 -0
- package/dist/cjs/cache/types.js +3 -0
- package/dist/cjs/cache/types.js.map +1 -0
- package/dist/cjs/data-source-fetchers.d.ts +5 -3
- package/dist/cjs/data-source-fetchers.d.ts.map +1 -1
- package/dist/cjs/data-source-fetchers.js +51 -8
- package/dist/cjs/data-source-fetchers.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts +2 -2
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +3 -2
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/loading-state.d.ts.map +1 -1
- package/dist/cjs/loading-state.js +74 -2
- package/dist/cjs/loading-state.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +204 -64
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts +15 -1
- package/dist/cjs/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/cjs/transformations/ecommerce-product.js +7 -3
- package/dist/cjs/transformations/ecommerce-product.js.map +1 -1
- package/dist/cjs/transformations/index.d.ts +13 -2
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +33 -5
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts +4 -3
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +6 -4
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/cache/ast.d.ts +71 -0
- package/dist/esm/cache/ast.d.ts.map +1 -0
- package/dist/esm/cache/ast.js +196 -0
- package/dist/esm/cache/ast.js.map +1 -0
- package/dist/esm/cache/config.d.ts +22 -0
- package/dist/esm/cache/config.d.ts.map +1 -0
- package/dist/esm/cache/config.js +62 -0
- package/dist/esm/cache/config.js.map +1 -0
- package/dist/esm/cache/types.d.ts +31 -0
- package/dist/esm/cache/types.d.ts.map +1 -0
- package/dist/esm/cache/types.js +2 -0
- package/dist/esm/cache/types.js.map +1 -0
- package/dist/esm/data-source-fetchers.d.ts +5 -3
- package/dist/esm/data-source-fetchers.d.ts.map +1 -1
- package/dist/esm/data-source-fetchers.js +51 -8
- package/dist/esm/data-source-fetchers.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts +2 -2
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +3 -2
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +12 -8
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/loading-state.d.ts.map +1 -1
- package/dist/esm/loading-state.js +74 -2
- package/dist/esm/loading-state.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +205 -65
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/transformations/ecommerce-product.d.ts +15 -1
- package/dist/esm/transformations/ecommerce-product.d.ts.map +1 -1
- package/dist/esm/transformations/ecommerce-product.js +7 -3
- package/dist/esm/transformations/ecommerce-product.js.map +1 -1
- package/dist/esm/transformations/index.d.ts +13 -2
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +32 -5
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts +4 -3
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +6 -4
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/cache/ast.ts +265 -0
- package/src/cache/config.ts +79 -0
- package/src/cache/types.ts +31 -0
- package/src/data-source-fetchers.ts +66 -12
- package/src/fetchers/teleport.ts +3 -3
- package/src/index.ts +10 -4
- package/src/loading-state.ts +65 -2
- package/src/pagination-plugin.ts +315 -116
- package/src/transformations/ecommerce-product.ts +107 -11
- package/src/transformations/index.ts +48 -7
- package/src/utils.ts +10 -5
|
@@ -1,4 +1,20 @@
|
|
|
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
|
+
}
|
|
2
18
|
|
|
3
19
|
/**
|
|
4
20
|
* Flattens the nested category tree (`ecommerceSettings.categories`, baked at
|
|
@@ -47,11 +63,16 @@ const flattenCategoriesById = (
|
|
|
47
63
|
* that UIDL components expect.
|
|
48
64
|
*/
|
|
49
65
|
export const generateEcommerceProductTransformationCode = (
|
|
50
|
-
|
|
66
|
+
options: EcommerceProductTransformOptions = {}
|
|
51
67
|
): string => {
|
|
52
|
-
const categoriesByIdJson = JSON.stringify(flattenCategoriesById(categories))
|
|
68
|
+
const categoriesByIdJson = JSON.stringify(flattenCategoriesById(options.categories))
|
|
69
|
+
const taxHelperCode = StorefrontTax.generateStorefrontTaxHelperCode(
|
|
70
|
+
options.storefrontTaxRate ?? 0
|
|
71
|
+
)
|
|
53
72
|
|
|
54
73
|
return `
|
|
74
|
+
${taxHelperCode}
|
|
75
|
+
|
|
55
76
|
// Category taxonomy (id -> {name, slug, translations}), baked in at export
|
|
56
77
|
// time — see flattenCategoriesById in ecommerce-product.ts. Empty when the
|
|
57
78
|
// store has no category taxonomy, or products.category_ids simply resolves
|
|
@@ -191,6 +212,12 @@ function buildEcommerceProduct(record, options) {
|
|
|
191
212
|
// transformRecords and passed in via options.variantsByProductId, keyed by
|
|
192
213
|
// product id. The storefront card/details read these to default-select the
|
|
193
214
|
// first in-stock variant, disable dead options, and resolve the chosen id.
|
|
215
|
+
//
|
|
216
|
+
// NULL (not {}) means the lookup could not run — the table is missing, or the
|
|
217
|
+
// query failed. That is "combinations UNKNOWN", which is NOT "this product has
|
|
218
|
+
// none": a transient DB failure must never turn every variant product in the
|
|
219
|
+
// catalogue into an unbuyable one. See hasPurchasableVariant below.
|
|
220
|
+
var variantsResolved = options.variantsByProductId != null
|
|
194
221
|
var variantsByProductId = options.variantsByProductId || {}
|
|
195
222
|
var rawVariants = variantsByProductId[id] || []
|
|
196
223
|
var variants = []
|
|
@@ -227,7 +254,12 @@ function buildEcommerceProduct(record, options) {
|
|
|
227
254
|
assetMap: assetMap,
|
|
228
255
|
currentLanguage: currentLang,
|
|
229
256
|
mainLanguage: mainLang,
|
|
230
|
-
|
|
257
|
+
// Passed through UNCOALESCED so a related product inherits the same
|
|
258
|
+
// known/unknown answer as its parent — \`|| {}\` here would tell the nested
|
|
259
|
+
// build "the lookup ran and found nothing" and strike out every related
|
|
260
|
+
// card's picker. The batched query includes the related ids for exactly
|
|
261
|
+
// this reason (see getTransformWrapperCode).
|
|
262
|
+
variantsByProductId: options.variantsByProductId,
|
|
231
263
|
}
|
|
232
264
|
for (var rp = 0; rp < relatedProductIds.length; rp++) {
|
|
233
265
|
var relatedId = relatedProductIds[rp]
|
|
@@ -312,7 +344,7 @@ function buildEcommerceProduct(record, options) {
|
|
|
312
344
|
var variantAxisKeys = []
|
|
313
345
|
for (var ak = 0; ak < variantOptions.length; ak++) { variantAxisKeys.push(variantOptions[ak].key) }
|
|
314
346
|
var firstVariant = pickFirstAvailableVariant(variants, variantAxisKeys)
|
|
315
|
-
var deadValueKeys = computeDeadVariantKeys(variants, variantOptions)
|
|
347
|
+
var deadValueKeys = computeDeadVariantKeys(variants, variantOptions, variantsResolved)
|
|
316
348
|
for (var ai = 0; ai < variantOptions.length; ai++) {
|
|
317
349
|
var vax = variantOptions[ai]
|
|
318
350
|
for (var vj = 0; vj < vax.values.length; vj++) {
|
|
@@ -332,13 +364,63 @@ function buildEcommerceProduct(record, options) {
|
|
|
332
364
|
vval.showSwatch = vax.type === 'color' && vval.color ? 'true' : 'false'
|
|
333
365
|
}
|
|
334
366
|
}
|
|
335
|
-
|
|
367
|
+
// The combination the picker auto-selects on first paint: the first in-stock
|
|
368
|
+
// one covering every axis. Absent means there is nothing the shopper could add
|
|
369
|
+
// without choosing — which is what gates the buy button below.
|
|
370
|
+
var hasInStockCombination = !!(firstVariant && isVariantInStock(firstVariant))
|
|
371
|
+
var defaultVariantId = hasInStockCombination ? firstVariant.id : ''
|
|
336
372
|
var defaultVariantPrice = firstVariant ? formatVariantPrice(firstVariant.price, price) : ''
|
|
373
|
+
// Gross (tax-inclusive) counterparts of the three price fields the STOREFRONT
|
|
374
|
+
// renders. \`price\` / \`defaultVariantPrice\` / \`variantsJson\` deliberately stay
|
|
375
|
+
// NET: the same transform feeds the merchant's admin panel, and every write
|
|
376
|
+
// path (add-to-cart, checkout, the invoice route) re-reads the raw row and
|
|
377
|
+
// must keep seeing the price the merchant typed. Only these three are safe to
|
|
378
|
+
// gross, because nothing writes them back.
|
|
379
|
+
//
|
|
380
|
+
// MUST mirror packages/renderer/src/utils/ecommerce-products.ts.
|
|
381
|
+
var displayPrice = grossMoney(price)
|
|
382
|
+
var defaultVariantDisplayPrice = firstVariant
|
|
383
|
+
? grossMoney(formatVariantPrice(firstVariant.price, price))
|
|
384
|
+
: ''
|
|
385
|
+
var variantsDisplay = []
|
|
386
|
+
for (var dv = 0; dv < variants.length; dv++) {
|
|
387
|
+
var dvRow = variants[dv]
|
|
388
|
+
variantsDisplay.push({
|
|
389
|
+
id: dvRow.id,
|
|
390
|
+
options: dvRow.options,
|
|
391
|
+
// A null variant price INHERITS the product price, so gross the RESOLVED
|
|
392
|
+
// value — otherwise an inheriting combination would fall back to the net
|
|
393
|
+
// base price in the picker while an overriding one showed gross.
|
|
394
|
+
price: applyStorefrontTax(dvRow.price == null ? price : dvRow.price),
|
|
395
|
+
quantity: dvRow.quantity,
|
|
396
|
+
image_url: dvRow.image_url,
|
|
397
|
+
})
|
|
398
|
+
}
|
|
399
|
+
// Can this product be added to the cart at all, before the shopper touches the
|
|
400
|
+
// picker? A STRING, same convention as outOfStock/requiresVariantSelection.
|
|
401
|
+
//
|
|
402
|
+
// flat product -> 'true' (stock is governed by outOfStock)
|
|
403
|
+
// combinations UNKNOWN -> 'true' (the lookup could not run; a transient DB
|
|
404
|
+
// failure must never make a whole catalogue
|
|
405
|
+
// unbuyable — same permissive rule as
|
|
406
|
+
// dead-marking)
|
|
407
|
+
// otherwise -> whether an in-stock combination covering every axis
|
|
408
|
+
// exists. 'false' therefore covers BOTH "every
|
|
409
|
+
// combination is sold out" AND "the axes have no
|
|
410
|
+
// combinations at all" — to a shopper those are the
|
|
411
|
+
// same thing: there is no size to pick.
|
|
412
|
+
//
|
|
413
|
+
// MUST mirror packages/renderer/src/utils/ecommerce-products.ts.
|
|
414
|
+
var hasPurchasableVariant =
|
|
415
|
+
(requiresVariantSelection !== 'true' || !variantsResolved || hasInStockCombination)
|
|
416
|
+
? 'true'
|
|
417
|
+
: 'false'
|
|
337
418
|
// Stringified companions: a data-* attr bound to an ARRAY renders
|
|
338
419
|
// '[object Object]', so the picker's on-mount/click workflows read the
|
|
339
420
|
// combinations + axes from these JSON strings via getAttribute.
|
|
340
421
|
var variantOptionsJson = safeStringifyJson(variantOptions)
|
|
341
422
|
var variantsJson = safeStringifyJson(variants)
|
|
423
|
+
var variantsDisplayJson = safeStringifyJson(variantsDisplay)
|
|
342
424
|
|
|
343
425
|
return {
|
|
344
426
|
id: id,
|
|
@@ -384,8 +466,12 @@ function buildEcommerceProduct(record, options) {
|
|
|
384
466
|
variants: variants,
|
|
385
467
|
variantOptionsJson: variantOptionsJson,
|
|
386
468
|
variantsJson: variantsJson,
|
|
469
|
+
variantsDisplayJson: variantsDisplayJson,
|
|
387
470
|
defaultVariantId: defaultVariantId,
|
|
388
471
|
defaultVariantPrice: defaultVariantPrice,
|
|
472
|
+
displayPrice: displayPrice,
|
|
473
|
+
defaultVariantDisplayPrice: defaultVariantDisplayPrice,
|
|
474
|
+
hasPurchasableVariant: hasPurchasableVariant,
|
|
389
475
|
}
|
|
390
476
|
}
|
|
391
477
|
|
|
@@ -416,11 +502,14 @@ function pickFirstAvailableVariant(variants, axisKeys) {
|
|
|
416
502
|
}
|
|
417
503
|
// Map of composite "axisKey|valueKey" -> true for every value that appears in
|
|
418
504
|
// NO in-stock combination (rendered as the Unavailable state).
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
505
|
+
//
|
|
506
|
+
// variantsResolved is the whole subtlety: dead-marking is only meaningful
|
|
507
|
+
// against combinations we actually LOOKED UP. When the lookup could not run,
|
|
508
|
+
// nothing is dead — a missing table or a failed query must not grey out every
|
|
509
|
+
// picker in the store. When it DID run, an empty list is a fact, not a gap:
|
|
510
|
+
// every value is unbuyable and renders as Unavailable.
|
|
511
|
+
function computeDeadVariantKeys(variants, axes, variantsResolved) {
|
|
512
|
+
if (!variantsResolved || !Array.isArray(variants)) return {}
|
|
424
513
|
var alive = {}
|
|
425
514
|
for (var i = 0; i < variants.length; i++) {
|
|
426
515
|
var v = variants[i]
|
|
@@ -651,6 +740,10 @@ async function getRelatedProductsMap(getClientFn, records) {
|
|
|
651
740
|
return map
|
|
652
741
|
}
|
|
653
742
|
|
|
743
|
+
// Combinations for every product on the page, keyed by product id. Returns NULL
|
|
744
|
+
// when the lookup could not run, which the transform reads as "unknown" and
|
|
745
|
+
// stays permissive with; an empty map means the query ran and this catalogue
|
|
746
|
+
// simply has no combinations.
|
|
654
747
|
async function getVariantsMap(getClientFn, productIds) {
|
|
655
748
|
var map = {}
|
|
656
749
|
if (!Array.isArray(productIds) || productIds.length === 0) return map
|
|
@@ -678,7 +771,10 @@ async function getVariantsMap(getClientFn, productIds) {
|
|
|
678
771
|
}
|
|
679
772
|
}
|
|
680
773
|
} catch (e) {
|
|
681
|
-
// teleport_product_variants may not exist for a non-variant store
|
|
774
|
+
// teleport_product_variants may not exist for a non-variant store, or the
|
|
775
|
+
// query may have failed. Either way the combinations are UNKNOWN — null
|
|
776
|
+
// keeps every picker selectable instead of declaring the catalogue unbuyable.
|
|
777
|
+
map = null
|
|
682
778
|
} finally {
|
|
683
779
|
if (client) {
|
|
684
780
|
try { await client.end() } catch (e) { /* ignore */ }
|
|
@@ -1,7 +1,28 @@
|
|
|
1
|
-
import type {
|
|
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 {
|
|
5
|
+
import {
|
|
6
|
+
generateEcommerceProductTransformationCode,
|
|
7
|
+
type EcommerceProductTransformOptions,
|
|
8
|
+
} from './ecommerce-product'
|
|
9
|
+
|
|
10
|
+
export type { EcommerceProductTransformOptions }
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Collects everything the product transform bakes in from the generator
|
|
14
|
+
* options, in ONE place so every fetcher-emitting call site stays in step.
|
|
15
|
+
*
|
|
16
|
+
* `storefrontTaxRate` is what turns a NET catalogue price into the price the
|
|
17
|
+
* shopper is quoted; `resolveStorefrontTaxRate` returns 0 (a no-op) for
|
|
18
|
+
* tax-inclusive or untaxed stores.
|
|
19
|
+
*/
|
|
20
|
+
export const buildProductTransformOptions = (
|
|
21
|
+
options: Pick<GeneratorOptions, 'ecommerceSettings' | 'invoiceSettings'>
|
|
22
|
+
): EcommerceProductTransformOptions => ({
|
|
23
|
+
categories: options.ecommerceSettings?.categories,
|
|
24
|
+
storefrontTaxRate: StorefrontTax.resolveStorefrontTaxRate(options.invoiceSettings),
|
|
25
|
+
})
|
|
5
26
|
|
|
6
27
|
export type TransformationType = 'blog-post' | 'ecommerce-product' | null
|
|
7
28
|
|
|
@@ -51,7 +72,7 @@ export const detectTransformationType = (tableName: string): TransformationType
|
|
|
51
72
|
*/
|
|
52
73
|
export const getTransformationCode = (
|
|
53
74
|
tableName: string,
|
|
54
|
-
|
|
75
|
+
options: EcommerceProductTransformOptions = {}
|
|
55
76
|
): string => {
|
|
56
77
|
const type = detectTransformationType(tableName)
|
|
57
78
|
if (!type) {
|
|
@@ -64,7 +85,7 @@ export const getTransformationCode = (
|
|
|
64
85
|
case 'blog-post':
|
|
65
86
|
return shared + generateBlogPostTransformationCode()
|
|
66
87
|
case 'ecommerce-product':
|
|
67
|
-
return shared + generateEcommerceProductTransformationCode(
|
|
88
|
+
return shared + generateEcommerceProductTransformationCode(options)
|
|
68
89
|
default:
|
|
69
90
|
return ''
|
|
70
91
|
}
|
|
@@ -107,18 +128,38 @@ export const getTransformWrapperCode = (tableName: string): string => {
|
|
|
107
128
|
|
|
108
129
|
// Products additionally get their purchasable variant combinations attached in
|
|
109
130
|
// ONE batched query (keyed by product id). Blog posts have no such enrichment.
|
|
131
|
+
//
|
|
132
|
+
// ⛔ The map starts as NULL and stays null when the query cannot run. The
|
|
133
|
+
// transform reads null as "combinations unknown" and keeps every picker
|
|
134
|
+
// selectable; a `{}` would mean "the lookup ran and this catalogue has none",
|
|
135
|
+
// which strikes out every value and hides every buy button. A transient DB
|
|
136
|
+
// failure must not be able to say that.
|
|
137
|
+
//
|
|
138
|
+
// Runs AFTER the related-items lookup so the related rows — which the details
|
|
139
|
+
// page draws as real product cards, each with its own picker — get their
|
|
140
|
+
// combinations from the SAME query instead of transforming as variant-less.
|
|
110
141
|
const variantEnrichment =
|
|
111
142
|
type === 'ecommerce-product'
|
|
112
143
|
? `
|
|
113
|
-
var variantsByProductId =
|
|
144
|
+
var variantsByProductId = null
|
|
114
145
|
try {
|
|
115
146
|
var __variantPids = []
|
|
116
147
|
for (var __i = 0; __i < records.length; __i++) {
|
|
117
148
|
if (records[__i] && records[__i].id != null) __variantPids.push(records[__i].id)
|
|
118
149
|
}
|
|
150
|
+
if (relatedProductsById) {
|
|
151
|
+
for (var __rk in relatedProductsById) {
|
|
152
|
+
if (!Object.prototype.hasOwnProperty.call(relatedProductsById, __rk)) continue
|
|
153
|
+
// The ROW's own id, not the map key: the key was stringified when the map
|
|
154
|
+
// was built, and a query parameter array of mixed types is one the driver
|
|
155
|
+
// cannot type against the product_id column.
|
|
156
|
+
var __rrow = relatedProductsById[__rk]
|
|
157
|
+
if (__rrow && __rrow.id != null) __variantPids.push(__rrow.id)
|
|
158
|
+
}
|
|
159
|
+
}
|
|
119
160
|
variantsByProductId = await getVariantsMap(getClientFn, __variantPids)
|
|
120
161
|
} catch (e) {
|
|
121
|
-
//
|
|
162
|
+
// Leaves the map null — "unknown", never "none".
|
|
122
163
|
}`
|
|
123
164
|
: ''
|
|
124
165
|
|
|
@@ -155,7 +196,7 @@ async function transformRecords(records, getClientFn, reqQuery) {
|
|
|
155
196
|
assetMap = await getAssetMap(getClientFn)
|
|
156
197
|
} catch (e) {
|
|
157
198
|
// Asset resolution is best-effort; continue without it
|
|
158
|
-
}${
|
|
199
|
+
}${relatedEnrichment}${variantEnrichment}
|
|
159
200
|
var currentLanguage = (reqQuery && reqQuery.lang) || null
|
|
160
201
|
var mainLanguage = (reqQuery && reqQuery.mainLang) || null
|
|
161
202
|
var options = { assetMap: assetMap, currentLanguage: currentLanguage, mainLanguage: mainLanguage${variantOption}, ${relatedMapVar}: ${relatedMapVar} }
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
1232
|
+
transformOptions
|
|
1228
1233
|
)
|
|
1229
1234
|
} catch (error) {
|
|
1230
1235
|
// tslint:disable-next-line:no-console
|