@teleporthq/teleport-plugin-next-data-source 0.43.74 → 0.44.0
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__/_helpers/pagination-widget-fixture.ts +95 -5
- package/__tests__/blog-adjacent-arranged.test.ts +176 -0
- package/__tests__/blog-post-contents.test.ts +212 -0
- package/__tests__/blog-post-page-enrichment.test.ts +28 -5
- package/__tests__/blog-post-picture-stand-in.test.ts +48 -0
- package/__tests__/blog-post-reading-time.test.ts +55 -0
- package/__tests__/booking-item-transform.test.ts +120 -0
- package/__tests__/browser-row-policy.test.ts +13 -3
- package/__tests__/content-preset-wiring.test.ts +108 -0
- package/__tests__/fetchers.test.ts +1 -1
- package/__tests__/fixed-list-sort.test.ts +183 -0
- package/__tests__/infinite-scroll.test.ts +154 -5
- package/__tests__/list-sort-order.test.ts +61 -0
- package/__tests__/null-filter-where.test.ts +132 -0
- package/__tests__/pagination-filter-groups.test.ts +186 -0
- package/__tests__/pg-date-parser.test.ts +73 -0
- package/__tests__/plain-list-sort.test.ts +215 -0
- package/__tests__/product-price-sort.ts +58 -25
- package/__tests__/range-control.test.ts +159 -0
- package/__tests__/rest-api-key-header.test.ts +18 -0
- package/__tests__/search-input-marker.test.ts +86 -0
- package/__tests__/search-url-sync.test.ts +61 -16
- package/__tests__/shared-resource-prefetch.test.ts +65 -0
- package/__tests__/table-read-route-protected-tables.test.ts +33 -3
- package/dist/cjs/count-effect.d.ts +7 -1
- package/dist/cjs/count-effect.d.ts.map +1 -1
- package/dist/cjs/count-effect.js +15 -5
- package/dist/cjs/count-effect.js.map +1 -1
- package/dist/cjs/fetchers/pg-client-import.d.ts +12 -0
- package/dist/cjs/fetchers/pg-client-import.d.ts.map +1 -0
- package/dist/cjs/fetchers/pg-client-import.js +15 -0
- package/dist/cjs/fetchers/pg-client-import.js.map +1 -0
- package/dist/cjs/fetchers/postgresql.d.ts.map +1 -1
- package/dist/cjs/fetchers/postgresql.js +4 -1
- package/dist/cjs/fetchers/postgresql.js.map +1 -1
- package/dist/cjs/fetchers/raw-query.d.ts.map +1 -1
- package/dist/cjs/fetchers/raw-query.js +2 -1
- package/dist/cjs/fetchers/raw-query.js.map +1 -1
- package/dist/cjs/fetchers/rest-api.d.ts.map +1 -1
- package/dist/cjs/fetchers/rest-api.js +3 -1
- package/dist/cjs/fetchers/rest-api.js.map +1 -1
- package/dist/cjs/fetchers/teleport.d.ts.map +1 -1
- package/dist/cjs/fetchers/teleport.js +5 -2
- package/dist/cjs/fetchers/teleport.js.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts +7 -6
- package/dist/cjs/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/cjs/fetchers/utils/browser-row-policy.js +7 -33
- package/dist/cjs/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/cjs/filter-utils.d.ts +19 -7
- package/dist/cjs/filter-utils.d.ts.map +1 -1
- package/dist/cjs/filter-utils.js +49 -13
- package/dist/cjs/filter-utils.js.map +1 -1
- package/dist/cjs/infinite-scroll.d.ts +25 -2
- package/dist/cjs/infinite-scroll.d.ts.map +1 -1
- package/dist/cjs/infinite-scroll.js +144 -33
- package/dist/cjs/infinite-scroll.js.map +1 -1
- package/dist/cjs/list-sort-order.d.ts +14 -0
- package/dist/cjs/list-sort-order.d.ts.map +1 -0
- package/dist/cjs/list-sort-order.js +36 -0
- package/dist/cjs/list-sort-order.js.map +1 -0
- package/dist/cjs/pagination-controls.d.ts +22 -3
- package/dist/cjs/pagination-controls.d.ts.map +1 -1
- package/dist/cjs/pagination-controls.js +29 -3
- package/dist/cjs/pagination-controls.js.map +1 -1
- package/dist/cjs/pagination-plugin.d.ts.map +1 -1
- package/dist/cjs/pagination-plugin.js +267 -212
- package/dist/cjs/pagination-plugin.js.map +1 -1
- package/dist/cjs/product-price-sort.d.ts +0 -9
- package/dist/cjs/product-price-sort.d.ts.map +1 -1
- package/dist/cjs/product-price-sort.js +1 -13
- package/dist/cjs/product-price-sort.js.map +1 -1
- package/dist/cjs/range-control.d.ts +45 -0
- package/dist/cjs/range-control.d.ts.map +1 -0
- package/dist/cjs/range-control.js +165 -0
- package/dist/cjs/range-control.js.map +1 -0
- package/dist/cjs/row-order.d.ts +20 -0
- package/dist/cjs/row-order.d.ts.map +1 -0
- package/dist/cjs/row-order.js +46 -0
- package/dist/cjs/row-order.js.map +1 -0
- package/dist/cjs/search-input.d.ts +42 -0
- package/dist/cjs/search-input.d.ts.map +1 -0
- package/dist/cjs/search-input.js +158 -0
- package/dist/cjs/search-input.js.map +1 -0
- package/dist/cjs/sort-utils.d.ts +10 -0
- package/dist/cjs/sort-utils.d.ts.map +1 -1
- package/dist/cjs/sort-utils.js +22 -1
- package/dist/cjs/sort-utils.js.map +1 -1
- package/dist/cjs/transformations/blog-adjacent-posts.d.ts +11 -1
- package/dist/cjs/transformations/blog-adjacent-posts.d.ts.map +1 -1
- package/dist/cjs/transformations/blog-adjacent-posts.js +14 -1
- package/dist/cjs/transformations/blog-adjacent-posts.js.map +1 -1
- package/dist/cjs/transformations/blog-comments.d.ts +1 -1
- package/dist/cjs/transformations/blog-comments.d.ts.map +1 -1
- package/dist/cjs/transformations/blog-comments.js +1 -1
- package/dist/cjs/transformations/blog-comments.js.map +1 -1
- package/dist/cjs/transformations/blog-post.d.ts +14 -0
- package/dist/cjs/transformations/blog-post.d.ts.map +1 -1
- package/dist/cjs/transformations/blog-post.js +4 -1
- package/dist/cjs/transformations/blog-post.js.map +1 -1
- package/dist/cjs/transformations/booking-item.d.ts +24 -0
- package/dist/cjs/transformations/booking-item.d.ts.map +1 -0
- package/dist/cjs/transformations/booking-item.js +27 -0
- package/dist/cjs/transformations/booking-item.js.map +1 -0
- package/dist/cjs/transformations/heading-anchors.d.ts +32 -8
- package/dist/cjs/transformations/heading-anchors.d.ts.map +1 -1
- package/dist/cjs/transformations/heading-anchors.js +34 -10
- package/dist/cjs/transformations/heading-anchors.js.map +1 -1
- package/dist/cjs/transformations/index.d.ts +27 -13
- package/dist/cjs/transformations/index.d.ts.map +1 -1
- package/dist/cjs/transformations/index.js +73 -16
- package/dist/cjs/transformations/index.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/cjs/utils.d.ts.map +1 -1
- package/dist/cjs/utils.js +52 -3
- package/dist/cjs/utils.js.map +1 -1
- package/dist/esm/count-effect.d.ts +7 -1
- package/dist/esm/count-effect.d.ts.map +1 -1
- package/dist/esm/count-effect.js +15 -5
- package/dist/esm/count-effect.js.map +1 -1
- package/dist/esm/fetchers/pg-client-import.d.ts +12 -0
- package/dist/esm/fetchers/pg-client-import.d.ts.map +1 -0
- package/dist/esm/fetchers/pg-client-import.js +12 -0
- package/dist/esm/fetchers/pg-client-import.js.map +1 -0
- package/dist/esm/fetchers/postgresql.d.ts.map +1 -1
- package/dist/esm/fetchers/postgresql.js +5 -2
- package/dist/esm/fetchers/postgresql.js.map +1 -1
- package/dist/esm/fetchers/raw-query.d.ts.map +1 -1
- package/dist/esm/fetchers/raw-query.js +2 -1
- package/dist/esm/fetchers/raw-query.js.map +1 -1
- package/dist/esm/fetchers/rest-api.d.ts.map +1 -1
- package/dist/esm/fetchers/rest-api.js +3 -1
- package/dist/esm/fetchers/rest-api.js.map +1 -1
- package/dist/esm/fetchers/teleport.d.ts.map +1 -1
- package/dist/esm/fetchers/teleport.js +6 -3
- package/dist/esm/fetchers/teleport.js.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts +7 -6
- package/dist/esm/fetchers/utils/browser-row-policy.d.ts.map +1 -1
- package/dist/esm/fetchers/utils/browser-row-policy.js +5 -31
- package/dist/esm/fetchers/utils/browser-row-policy.js.map +1 -1
- package/dist/esm/filter-utils.d.ts +19 -7
- package/dist/esm/filter-utils.d.ts.map +1 -1
- package/dist/esm/filter-utils.js +46 -12
- package/dist/esm/filter-utils.js.map +1 -1
- package/dist/esm/infinite-scroll.d.ts +25 -2
- package/dist/esm/infinite-scroll.d.ts.map +1 -1
- package/dist/esm/infinite-scroll.js +142 -32
- package/dist/esm/infinite-scroll.js.map +1 -1
- package/dist/esm/list-sort-order.d.ts +14 -0
- package/dist/esm/list-sort-order.d.ts.map +1 -0
- package/dist/esm/list-sort-order.js +32 -0
- package/dist/esm/list-sort-order.js.map +1 -0
- package/dist/esm/pagination-controls.d.ts +22 -3
- package/dist/esm/pagination-controls.d.ts.map +1 -1
- package/dist/esm/pagination-controls.js +28 -2
- package/dist/esm/pagination-controls.js.map +1 -1
- package/dist/esm/pagination-plugin.d.ts.map +1 -1
- package/dist/esm/pagination-plugin.js +271 -216
- package/dist/esm/pagination-plugin.js.map +1 -1
- package/dist/esm/product-price-sort.d.ts +0 -9
- package/dist/esm/product-price-sort.d.ts.map +1 -1
- package/dist/esm/product-price-sort.js +0 -11
- package/dist/esm/product-price-sort.js.map +1 -1
- package/dist/esm/range-control.d.ts +45 -0
- package/dist/esm/range-control.d.ts.map +1 -0
- package/dist/esm/range-control.js +137 -0
- package/dist/esm/range-control.js.map +1 -0
- package/dist/esm/row-order.d.ts +20 -0
- package/dist/esm/row-order.d.ts.map +1 -0
- package/dist/esm/row-order.js +41 -0
- package/dist/esm/row-order.js.map +1 -0
- package/dist/esm/search-input.d.ts +42 -0
- package/dist/esm/search-input.d.ts.map +1 -0
- package/dist/esm/search-input.js +129 -0
- package/dist/esm/search-input.js.map +1 -0
- package/dist/esm/sort-utils.d.ts +10 -0
- package/dist/esm/sort-utils.d.ts.map +1 -1
- package/dist/esm/sort-utils.js +20 -0
- package/dist/esm/sort-utils.js.map +1 -1
- package/dist/esm/transformations/blog-adjacent-posts.d.ts +11 -1
- package/dist/esm/transformations/blog-adjacent-posts.d.ts.map +1 -1
- package/dist/esm/transformations/blog-adjacent-posts.js +14 -1
- package/dist/esm/transformations/blog-adjacent-posts.js.map +1 -1
- package/dist/esm/transformations/blog-comments.d.ts +1 -1
- package/dist/esm/transformations/blog-comments.d.ts.map +1 -1
- package/dist/esm/transformations/blog-comments.js +1 -1
- package/dist/esm/transformations/blog-comments.js.map +1 -1
- package/dist/esm/transformations/blog-post.d.ts +14 -0
- package/dist/esm/transformations/blog-post.d.ts.map +1 -1
- package/dist/esm/transformations/blog-post.js +4 -1
- package/dist/esm/transformations/blog-post.js.map +1 -1
- package/dist/esm/transformations/booking-item.d.ts +24 -0
- package/dist/esm/transformations/booking-item.d.ts.map +1 -0
- package/dist/esm/transformations/booking-item.js +23 -0
- package/dist/esm/transformations/booking-item.js.map +1 -0
- package/dist/esm/transformations/heading-anchors.d.ts +32 -8
- package/dist/esm/transformations/heading-anchors.d.ts.map +1 -1
- package/dist/esm/transformations/heading-anchors.js +33 -9
- package/dist/esm/transformations/heading-anchors.js.map +1 -1
- package/dist/esm/transformations/index.d.ts +27 -13
- package/dist/esm/transformations/index.d.ts.map +1 -1
- package/dist/esm/transformations/index.js +72 -16
- package/dist/esm/transformations/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/utils.d.ts.map +1 -1
- package/dist/esm/utils.js +52 -3
- package/dist/esm/utils.js.map +1 -1
- package/package.json +5 -5
- package/src/count-effect.ts +31 -8
- package/src/fetchers/pg-client-import.ts +16 -0
- package/src/fetchers/postgresql.ts +25 -23
- package/src/fetchers/raw-query.ts +2 -1
- package/src/fetchers/rest-api.ts +3 -1
- package/src/fetchers/teleport.ts +22 -23
- package/src/fetchers/utils/browser-row-policy.ts +10 -20
- package/src/filter-utils.ts +102 -28
- package/src/infinite-scroll.ts +240 -79
- package/src/list-sort-order.ts +34 -0
- package/src/pagination-controls.ts +26 -3
- package/src/pagination-plugin.ts +370 -306
- package/src/product-price-sort.ts +0 -11
- package/src/range-control.ts +207 -0
- package/src/row-order.ts +55 -0
- package/src/search-input.ts +190 -0
- package/src/sort-utils.ts +25 -0
- package/src/transformations/blog-adjacent-posts.ts +89 -3
- package/src/transformations/blog-comments.ts +5 -5
- package/src/transformations/blog-post.ts +64 -13
- package/src/transformations/booking-item.ts +71 -0
- package/src/transformations/heading-anchors.ts +79 -16
- package/src/transformations/index.ts +104 -14
- package/src/utils.ts +74 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blog-post.d.ts","sourceRoot":"","sources":["../../../src/transformations/blog-post.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"blog-post.d.ts","sourceRoot":"","sources":["../../../src/transformations/blog-post.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AACvE,OAAO,EAAE,aAAa,EAA0B,MAAM,6BAA6B,CAAA;AAMnF,kFAAkF;AAClF,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,aAAa,CAAA;IACpC,+EAA+E;IAC/E,UAAU,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACpC,yEAAyE;IACzE,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,yGAAyG;IACzG,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,aACpC,wBAAwB,KAChC,MA0SF,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ContentTables, RichTextContentCodegen } from '@teleporthq/teleport-shared';
|
|
1
2
|
import { generateCategoryTaxonomyCode } from './category-taxonomy';
|
|
2
3
|
import { generateAdjacentPostsCode } from './blog-adjacent-posts';
|
|
3
4
|
import { generateBlogCommentsCode } from './blog-comments';
|
|
@@ -8,7 +9,9 @@ import { generateHeadingAnchorsCode } from './heading-anchors';
|
|
|
8
9
|
* that UIDL components expect.
|
|
9
10
|
*/
|
|
10
11
|
export var generateBlogPostTransformationCode = function (options) {
|
|
12
|
+
var _a, _b;
|
|
11
13
|
if (options === void 0) { options = {}; }
|
|
12
|
-
return "\n// ============================================================\n// Blog Post Transformation\n// ============================================================\n".concat(generateCategoryTaxonomyCode('BLOG_CATEGORIES_BY_ID', options.categories), "\n").concat(generateBlogCommentsCode(), "\n").concat(generateAdjacentPostsCode(), "\n").concat(generateHeadingAnchorsCode(), "\nvar BLOG_HEADING_ANCHORS = ").concat(options.headingAnchors === true, "\n\nfunction buildBlogPost(record, options) {\n if (!record || typeof record !== 'object') return record\n options = options || {}\n var currentLang = options.currentLanguage || null\n var mainLang = options.mainLanguage || null\n var assetMap = options.assetMap || {}\n\n var id = record.id !== undefined && record.id !== null ? record.id : null\n\n // i18n-resolved text fields\n var title = resolveI18nField(record, 'title', 'title', currentLang, mainLang) || ''\n var slug = resolveI18nField(record, 'slug', 'slug', currentLang, mainLang) || ''\n var content = resolveI18nField(record, 'content', 'content', currentLang, mainLang) || ''\n if (BLOG_HEADING_ANCHORS) content = addHeadingAnchors(content)\n var excerpt = resolveI18nField(record, 'excerpt', 'excerpt', currentLang, mainLang) || ''\n var category = resolveI18nField(record, 'category', 'category', currentLang, mainLang) || null\n\n // Assigned category ids -> resolved {id,name,slug} objects for the post-details\n // BREADCRUMBS (and anything else mapping over them). The taxonomy itself is not\n // in the DB (categories are authored in the GUI and live only in\n // blogSettings.categories); resolved against BLOG_CATEGORIES_BY_ID, baked in at\n // export time. Unknown/stale ids are silently dropped. `category` above stays\n // the denormalized PRIMARY name.\n var categories = resolveAssignedCategories(\n record.category_ids,\n BLOG_CATEGORIES_BY_ID,\n currentLang,\n mainLang,\n category\n )\n var metaTitle = resolveI18nField(record, 'meta_title', 'metaTitle', currentLang, mainLang) || null\n var metaDescription = resolveI18nField(record, 'meta_description', 'metaDescription', currentLang, mainLang) || null\n var featuredImageAlt = resolveI18nField(record, 'featured_image_alt', 'featuredImageAlt', currentLang, mainLang) || null\n var authorBio = resolveI18nField(record, 'author_bio', 'authorBio', currentLang, mainLang) || null\n\n // Status\n var status = record.status || 'draft'\n\n // Asset fields - resolve IDs to URLs\n var rawFeaturedImage = pickFirst(record.featured_image_url, record.featuredImageUrl)\n var TELEPORT_DEFAULT_FEATURED_IMG = 'https://play.teleporthq.io/static/svg/default-img.svg'\n var featuredImageUrl = resolveAssetUrl(rawFeaturedImage, assetMap)\n if (\n !featuredImageUrl ||\n rawFeaturedImage === TELEPORT_DEFAULT_FEATURED_IMG ||\n featuredImageUrl === TELEPORT_DEFAULT_FEATURED_IMG\n ) {\n featuredImageUrl =\n 'data:image/svg+xml;charset=utf-8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"400\" height=\"240\" viewBox=\"0 0 400 240\"><rect fill=\"#e5e7eb\" width=\"400\" height=\"240\"/><text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" fill=\"#9ca3af\" font-family=\"system-ui,sans-serif\" font-size=\"13\">No image</text></svg>'\n )\n }\n\n var rawAuthorAvatar = pickFirst(record.author_avatar_url, record.authorAvatarUrl)\n var authorAvatarUrl = resolveAssetUrl(rawAuthorAvatar, assetMap)\n\n // Simple pass-through fields\n var authorName = pickFirst(record.author_name, record.authorName)\n var authorInitials = blogAuthorInitials(authorName)\n var authorEmail = pickFirst(record.author_email, record.authorEmail)\n var readingTimeMinutes = safeNumber(pickFirst(record.reading_time_minutes, record.readingTimeMinutes), null)\n\n // Tags - i18n-resolved then parsed as JSON array\n var rawTags = resolveI18nField(record, 'tags', 'tags', currentLang, mainLang)\n var tags = parseJsonArray(rawTags)\n\n // Gallery images - parse JSON array then resolve each asset URL\n var rawGalleryImages = pickFirst(record.gallery_images, record.galleryImages)\n var parsedGalleryImages = parseJsonArray(rawGalleryImages)\n var galleryImages = resolveAssetUrls(parsedGalleryImages, assetMap)\n\n // Computed: allImages = [featuredImageUrl, ...galleryImages] (skip null featured)\n var allImages = []\n if (featuredImageUrl) allImages.push(featuredImageUrl)\n allImages = allImages.concat(galleryImages)\n\n // Boolean fields\n var isFeatured = coerceBoolean(pickFirst(record.is_featured, record.isFeatured), false)\n var allowComments = record.allow_comments !== undefined\n ? coerceBoolean(record.allow_comments, true)\n : record.allowComments !== undefined\n ? coerceBoolean(record.allowComments, true)\n : true\n\n // Per-post SEO overrides. The transform is the single normalization point \u2014\n // rows can also be written by the raw admin CRUD form, so whitespace and\n // unknown redirect types are neutralized here. Absent columns (a table\n // provisioned before the feature) read as undefined and normalize to null.\n // robotsContent is null \u2014 never '' or false \u2014 for unset rows, so the\n // page-level fallback (the `??` in the generated Head) can take over.\n var noIndex = coerceBoolean(pickFirst(record.no_index, record.noIndex), false)\n var canonicalUrl = normalizeSeoUrlField(pickFirst(record.canonical_url, record.canonicalUrl))\n var redirectUrl = normalizeSeoUrlField(pickFirst(record.redirect_url, record.redirectUrl))\n var rawRedirectType = pickFirst(record.redirect_type, record.redirectType)\n var redirectType =\n redirectUrl && (rawRedirectType === '301' || rawRedirectType === '302')\n ? rawRedirectType\n : null\n var robotsContent = noIndex ? 'noindex' : null\n\n // The author's related-post picks. `relatedPosts` carries the TRANSFORMED\n // rows, not ids, so the details page's related-posts rail can map over it and\n // draw an article card per entry; `relatedPostIds` keeps the raw selection.\n // The rows arrive from ONE batched query (getRelatedPostsMap) that\n // transformRecords runs, keyed by id in options.relatedPostsById.\n //\n // MUST mirror buildRelatedBlogPosts in packages/renderer/src/utils/blog-posts.ts\n // (the canvas-preview SSOT): the author's order, UNPUBLISHED posts dropped,\n // self dropped, and the nested build deliberately WITHOUT the map \u2014 two posts\n // pointing at each other is ordinary and would otherwise recurse forever.\n var relatedPostIds = parseRelatedIds(record.related_post_ids)\n var relatedPostsById = options.relatedPostsById\n var relatedPosts = []\n // The nested builds of the related and adjacent posts get NO maps: each is a\n // card, not a page, and two posts that point at each other would recurse.\n var relatedNestedOptions = {\n assetMap: assetMap,\n currentLanguage: currentLang,\n mainLanguage: mainLang,\n }\n if (relatedPostsById && relatedPostIds.length > 0) {\n for (var rp = 0; rp < relatedPostIds.length; rp++) {\n var relatedId = relatedPostIds[rp]\n if (id != null && relatedId === String(id)) continue\n var relatedRecord = relatedPostsById[relatedId]\n if (!relatedRecord) continue\n // A draft must not reach the storefront through another post's rail.\n // Missing status reads as 'draft', the same default as above.\n if ((relatedRecord.status || 'draft') !== 'published') continue\n relatedPosts.push(buildBlogPost(relatedRecord, relatedNestedOptions))\n }\n }\n\n // The previous (older) and next (newer) published post, as 0-or-1-item\n // lists: the post navigation maps over them like the related rail does, so an\n // end of the blog simply renders no card on that side.\n var adjacent = options.adjacentPostsById && id != null ? options.adjacentPostsById[String(id)] : null\n var previousPosts = adjacent && adjacent.previous ? [buildBlogPost(adjacent.previous, relatedNestedOptions)] : []\n var nextPosts = adjacent && adjacent.next ? [buildBlogPost(adjacent.next, relatedNestedOptions)] : []\n\n // The approved comments \u2014 the newest top-level ones, each with its replies \u2014\n // present only on a details fetch; see blog-comments.ts.\n var commentsEntry = options.commentsByPostId && id != null ? options.commentsByPostId[String(id)] : null\n var comments = commentsEntry ? buildBlogComments(commentsEntry.rows) : []\n var commentsCount = commentsEntry ? commentsEntry.count : 0\n\n // Timestamps\n var rawPublishedAt = pickFirst(record.published_at, record.publishedAt)\n var publishedAt = rawPublishedAt != null ? normalizeTimestamp(rawPublishedAt) : null\n\n var rawCreatedAt = pickFirst(record.created_at, record.createdAt, record.created)\n var createdAt = normalizeTimestamp(rawCreatedAt)\n\n var rawUpdatedAt = pickFirst(record.updated_at, record.updatedAt, record.updated)\n var updatedAt = rawUpdatedAt != null ? normalizeTimestamp(rawUpdatedAt) : createdAt\n\n // Computed: created = Unix seconds from createdAt milliseconds\n var created = Math.floor(createdAt / 1000)\n\n return {\n id: id,\n title: title,\n slug: slug,\n content: content,\n excerpt: excerpt,\n status: status,\n category: category,\n categories: categories,\n tags: tags,\n relatedPostIds: relatedPostIds,\n relatedPosts: relatedPosts,\n featuredImageUrl: featuredImageUrl,\n featuredImageAlt: featuredImageAlt,\n galleryImages: galleryImages,\n allImages: allImages,\n authorName: authorName,\n authorEmail: authorEmail,\n author_name: authorName,\n author_email: authorEmail,\n authorAvatarUrl: authorAvatarUrl,\n authorBio: authorBio,\n authorInitials: authorInitials,\n metaTitle: metaTitle,\n metaDescription: metaDescription,\n readingTimeMinutes: readingTimeMinutes,\n isFeatured: isFeatured,\n allowComments: allowComments,\n comments: comments,\n commentsCount: commentsCount,\n previousPosts: previousPosts,\n nextPosts: nextPosts,\n noIndex: noIndex,\n canonicalUrl: canonicalUrl,\n redirectUrl: redirectUrl,\n redirectType: redirectType,\n robotsContent: robotsContent,\n publishedAt: publishedAt,\n createdAt: createdAt,\n updatedAt: updatedAt,\n created: created,\n }\n}\n\nfunction transformBlogPosts(records, options) {\n if (!Array.isArray(records)) return []\n return records.map(function(record) { return buildBlogPost(record, options) })\n}\n\n// Batched fetch of the post rows a set of posts reference as \"related\", keyed by\n// id. Best-effort in the same way as the product side: a table provisioned\n// before the column yields no ids (the read is of an absent property, not of a\n// column \u2014 the SQL never names it), the map stays empty, and the rail stays\n// hidden behind its is_not_empty gate.\nasync function getRelatedPostsMap(getClientFn, records) {\n var map = {}\n if (!Array.isArray(records) || records.length === 0) return map\n\n var wantedIds = []\n for (var i = 0; i < records.length; i++) {\n var ids = parseRelatedIds(records[i] && records[i].related_post_ids)\n for (var j = 0; j < ids.length; j++) {\n if (wantedIds.indexOf(ids[j]) === -1) wantedIds.push(ids[j])\n }\n }\n if (wantedIds.length === 0) return map\n\n var client\n try {\n client = getClientFn()\n await client.connect()\n var result = await client.query('SELECT * FROM teleport_blog_posts WHERE id = ANY($1)', [\n wantedIds,\n ])\n if (result && result.rows) {\n for (var r = 0; r < result.rows.length; r++) {\n var row = result.rows[r]\n if (row && row.id != null) map[String(row.id)] = row\n }\n }\n } catch (e) {\n // Leaves relatedPosts empty rather than failing the page.\n } finally {\n if (client) {\n try { await client.end() } catch (e) { /* ignore */ }\n }\n }\n return map\n}\n");
|
|
14
|
+
var tables = (_a = options.tables) !== null && _a !== void 0 ? _a : ContentTables.contentTablesByKey('blog');
|
|
15
|
+
return "\n// ============================================================\n// Blog Post Transformation\n// ============================================================\n".concat(generateCategoryTaxonomyCode('BLOG_CATEGORIES_BY_ID', options.categories), "\n").concat(generateBlogCommentsCode((_b = tables.comments) !== null && _b !== void 0 ? _b : "".concat(tables.posts, "_comments")), "\n").concat(generateAdjacentPostsCode(tables.posts, options.arranged === true), "\n").concat(generateHeadingAnchorsCode(), "\n").concat(RichTextContentCodegen.generateLegacyRichTextNormalizerCode(), "\nvar BLOG_HEADING_ANCHORS = ").concat(options.headingAnchors === true, "\nvar BLOG_CONTENTS = ").concat(options.contents === true, "\nvar BLOG_PICTURE_STAND_IN = ").concat(tables.pictureStandIn !== false, "\n\n// A post's reading time from its body, for one that stores none: its words at\n// about 200 a minute, at least one \u2014 what the editor's post form computes. A\n// card or post page otherwise printed \"min read\" with no number before it.\n// MUST mirror readingTimeOf in teleport-gui packages/renderer/src/utils/blog-posts.ts.\nfunction blogReadingTimeOf(html) {\n var text = String(html || '').replace(/<[^>]*>/g, ' ').replace(/\\s+/g, ' ').trim()\n return text ? Math.max(1, Math.ceil(text.split(' ').length / 200)) : null\n}\n\nfunction buildBlogPost(record, options) {\n if (!record || typeof record !== 'object') return record\n options = options || {}\n var currentLang = options.currentLanguage || null\n var mainLang = options.mainLanguage || null\n var assetMap = options.assetMap || {}\n\n var id = record.id !== undefined && record.id !== null ? record.id : null\n\n // i18n-resolved text fields\n var title = resolveI18nField(record, 'title', 'title', currentLang, mainLang) || ''\n var slug = resolveI18nField(record, 'slug', 'slug', currentLang, mainLang) || ''\n // A body stored before the rich-text contract (the studio's flat list lines,\n // the admin panel's no-break spaces) reads as stored HTML from here on.\n var content = normalizeLegacyRichTextHtml(\n resolveI18nField(record, 'content', 'content', currentLang, mainLang) || ''\n )\n // Counted before the heading anchors add their marks.\n var bodyReadingTime = blogReadingTimeOf(content)\n // The Contents list links to the headings, so they get their ids for it too\n // \u2014 the # links only with the heading anchors on. Its sections ride on a\n // post page's own fetch only (options.details): a listing draws no list, and\n // every card of it would otherwise carry one.\n var contentsHeadings = BLOG_CONTENTS && options.details === true ? [] : null\n if (BLOG_HEADING_ANCHORS || BLOG_CONTENTS) {\n content = addHeadingAnchors(content, { links: BLOG_HEADING_ANCHORS, sections: contentsHeadings })\n }\n var excerpt = resolveI18nField(record, 'excerpt', 'excerpt', currentLang, mainLang) || ''\n var category = resolveI18nField(record, 'category', 'category', currentLang, mainLang) || null\n\n // Assigned category ids -> resolved {id,name,slug} objects for the post-details\n // BREADCRUMBS (and anything else mapping over them). The taxonomy itself is not\n // in the DB (categories are authored in the GUI and live only in\n // blogSettings.categories); resolved against BLOG_CATEGORIES_BY_ID, baked in at\n // export time. Unknown/stale ids are silently dropped. `category` above stays\n // the denormalized PRIMARY name.\n var categories = resolveAssignedCategories(\n record.category_ids,\n BLOG_CATEGORIES_BY_ID,\n currentLang,\n mainLang,\n category\n )\n var metaTitle = resolveI18nField(record, 'meta_title', 'metaTitle', currentLang, mainLang) || null\n var metaDescription = resolveI18nField(record, 'meta_description', 'metaDescription', currentLang, mainLang) || null\n var featuredImageAlt = resolveI18nField(record, 'featured_image_alt', 'featuredImageAlt', currentLang, mainLang) || null\n var authorBio = resolveI18nField(record, 'author_bio', 'authorBio', currentLang, mainLang) || null\n\n // Status\n var status = record.status || 'draft'\n\n // Asset fields - resolve IDs to URLs\n var rawFeaturedImage = pickFirst(record.featured_image_url, record.featuredImageUrl)\n var TELEPORT_DEFAULT_FEATURED_IMG = 'https://play.teleporthq.io/static/svg/default-img.svg'\n var featuredImageUrl = resolveAssetUrl(rawFeaturedImage, assetMap)\n if (\n !featuredImageUrl ||\n rawFeaturedImage === TELEPORT_DEFAULT_FEATURED_IMG ||\n featuredImageUrl === TELEPORT_DEFAULT_FEATURED_IMG\n ) {\n // No picture of its own: the grey \"No image\" stand-in, or none at all for a\n // preset whose posts are text (ContentTables.pictureStandIn) \u2014 its card and\n // post page show the picture only when there is one.\n featuredImageUrl = BLOG_PICTURE_STAND_IN\n ? 'data:image/svg+xml;charset=utf-8,' +\n encodeURIComponent(\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"400\" height=\"240\" viewBox=\"0 0 400 240\"><rect fill=\"#e5e7eb\" width=\"400\" height=\"240\"/><text x=\"50%\" y=\"50%\" dominant-baseline=\"middle\" text-anchor=\"middle\" fill=\"#9ca3af\" font-family=\"system-ui,sans-serif\" font-size=\"13\">No image</text></svg>'\n )\n : null\n }\n\n var rawAuthorAvatar = pickFirst(record.author_avatar_url, record.authorAvatarUrl)\n var authorAvatarUrl = resolveAssetUrl(rawAuthorAvatar, assetMap)\n\n // Simple pass-through fields\n var authorName = pickFirst(record.author_name, record.authorName)\n var authorInitials = blogAuthorInitials(authorName)\n // The author's email never leaves the server: a visitor's API read hides it\n // (browser-row-policy.ts), and the page data a post or listing page ships\n // is built here, so it is not part of the post a page sees either.\n var readingTimeMinutes = safeNumber(pickFirst(record.reading_time_minutes, record.readingTimeMinutes), null)\n if (!(readingTimeMinutes > 0)) readingTimeMinutes = bodyReadingTime\n\n // Tags - i18n-resolved then parsed as JSON array\n var rawTags = resolveI18nField(record, 'tags', 'tags', currentLang, mainLang)\n var tags = parseJsonArray(rawTags)\n\n // Gallery images - parse JSON array then resolve each asset URL\n var rawGalleryImages = pickFirst(record.gallery_images, record.galleryImages)\n var parsedGalleryImages = parseJsonArray(rawGalleryImages)\n var galleryImages = resolveAssetUrls(parsedGalleryImages, assetMap)\n\n // Computed: allImages = [featuredImageUrl, ...galleryImages] (skip null featured)\n var allImages = []\n if (featuredImageUrl) allImages.push(featuredImageUrl)\n allImages = allImages.concat(galleryImages)\n\n // Boolean fields\n var isFeatured = coerceBoolean(pickFirst(record.is_featured, record.isFeatured), false)\n var allowComments = record.allow_comments !== undefined\n ? coerceBoolean(record.allow_comments, true)\n : record.allowComments !== undefined\n ? coerceBoolean(record.allowComments, true)\n : true\n\n // Per-post SEO overrides. The transform is the single normalization point \u2014\n // rows can also be written by the raw admin CRUD form, so whitespace and\n // unknown redirect types are neutralized here. Absent columns (a table\n // provisioned before the feature) read as undefined and normalize to null.\n // robotsContent is null \u2014 never '' or false \u2014 for unset rows, so the\n // page-level fallback (the `??` in the generated Head) can take over.\n var noIndex = coerceBoolean(pickFirst(record.no_index, record.noIndex), false)\n var canonicalUrl = normalizeSeoUrlField(pickFirst(record.canonical_url, record.canonicalUrl))\n var redirectUrl = normalizeSeoUrlField(pickFirst(record.redirect_url, record.redirectUrl))\n var rawRedirectType = pickFirst(record.redirect_type, record.redirectType)\n var redirectType =\n redirectUrl && (rawRedirectType === '301' || rawRedirectType === '302')\n ? rawRedirectType\n : null\n var robotsContent = noIndex ? 'noindex' : null\n\n // The author's related-post picks. `relatedPosts` carries the TRANSFORMED\n // rows, not ids, so the details page's related-posts rail can map over it and\n // draw an article card per entry; `relatedPostIds` keeps the raw selection.\n // The rows arrive from ONE batched query (getRelatedPostsMap) that\n // transformRecords runs, keyed by id in options.relatedPostsById.\n //\n // MUST mirror buildRelatedBlogPosts in packages/renderer/src/utils/blog-posts.ts\n // (the canvas-preview SSOT): the author's order, UNPUBLISHED posts dropped,\n // self dropped, and the nested build deliberately WITHOUT the map \u2014 two posts\n // pointing at each other is ordinary and would otherwise recurse forever.\n var relatedPostIds = parseRelatedIds(record.related_post_ids)\n var relatedPostsById = options.relatedPostsById\n var relatedPosts = []\n // The nested builds of the related and adjacent posts get NO maps: each is a\n // card, not a page, and two posts that point at each other would recurse.\n var relatedNestedOptions = {\n assetMap: assetMap,\n currentLanguage: currentLang,\n mainLanguage: mainLang,\n }\n if (relatedPostsById && relatedPostIds.length > 0) {\n for (var rp = 0; rp < relatedPostIds.length; rp++) {\n var relatedId = relatedPostIds[rp]\n if (id != null && relatedId === String(id)) continue\n var relatedRecord = relatedPostsById[relatedId]\n if (!relatedRecord) continue\n // A draft must not reach the storefront through another post's rail.\n // Missing status reads as 'draft', the same default as above.\n if ((relatedRecord.status || 'draft') !== 'published') continue\n relatedPosts.push(buildBlogPost(relatedRecord, relatedNestedOptions))\n }\n }\n\n // The previous (older) and next (newer) published post, as 0-or-1-item\n // lists: the post navigation maps over them like the related rail does, so an\n // end of the blog simply renders no card on that side.\n var adjacent = options.adjacentPostsById && id != null ? options.adjacentPostsById[String(id)] : null\n var previousPosts = adjacent && adjacent.previous ? [buildBlogPost(adjacent.previous, relatedNestedOptions)] : []\n var nextPosts = adjacent && adjacent.next ? [buildBlogPost(adjacent.next, relatedNestedOptions)] : []\n\n // The approved comments \u2014 the newest top-level ones, each with its replies \u2014\n // present only on a details fetch; see blog-comments.ts.\n var commentsEntry = options.commentsByPostId && id != null ? options.commentsByPostId[String(id)] : null\n var comments = commentsEntry ? buildBlogComments(commentsEntry.rows) : []\n var commentsCount = commentsEntry ? commentsEntry.count : 0\n\n // Timestamps\n var rawPublishedAt = pickFirst(record.published_at, record.publishedAt)\n var publishedAt = rawPublishedAt != null ? normalizeTimestamp(rawPublishedAt) : null\n\n var rawCreatedAt = pickFirst(record.created_at, record.createdAt, record.created)\n var createdAt = normalizeTimestamp(rawCreatedAt)\n\n var rawUpdatedAt = pickFirst(record.updated_at, record.updatedAt, record.updated)\n var updatedAt = rawUpdatedAt != null ? normalizeTimestamp(rawUpdatedAt) : createdAt\n\n // Computed: created = Unix seconds from createdAt milliseconds\n var created = Math.floor(createdAt / 1000)\n\n return {\n id: id,\n title: title,\n slug: slug,\n content: content,\n excerpt: excerpt,\n status: status,\n category: category,\n categories: categories,\n tags: tags,\n relatedPostIds: relatedPostIds,\n relatedPosts: relatedPosts,\n featuredImageUrl: featuredImageUrl,\n featuredImageAlt: featuredImageAlt,\n galleryImages: galleryImages,\n allImages: allImages,\n authorName: authorName,\n author_name: authorName,\n authorAvatarUrl: authorAvatarUrl,\n authorBio: authorBio,\n authorInitials: authorInitials,\n metaTitle: metaTitle,\n metaDescription: metaDescription,\n readingTimeMinutes: readingTimeMinutes,\n // The post's sections, what its page's Contents list links to \u2014 see\n // blogContentsSectionsOf; empty off a post page or under three sections.\n sections: contentsHeadings ? blogContentsSectionsOf(contentsHeadings) : [],\n isFeatured: isFeatured,\n allowComments: allowComments,\n comments: comments,\n commentsCount: commentsCount,\n previousPosts: previousPosts,\n nextPosts: nextPosts,\n noIndex: noIndex,\n canonicalUrl: canonicalUrl,\n redirectUrl: redirectUrl,\n redirectType: redirectType,\n robotsContent: robotsContent,\n publishedAt: publishedAt,\n createdAt: createdAt,\n updatedAt: updatedAt,\n created: created,\n // The post's place among its primary category's posts (Manual Order), or\n // null: what the category pages order by.\n sortOrder: safeNumber(pickFirst(record.sort_order, record.sortOrder), null),\n }\n}\n\nfunction transformBlogPosts(records, options) {\n if (!Array.isArray(records)) return []\n return records.map(function(record) { return buildBlogPost(record, options) })\n}\n\n// Batched fetch of the post rows a set of posts reference as \"related\", keyed by\n// id. Best-effort in the same way as the product side: a table provisioned\n// before the column yields no ids (the read is of an absent property, not of a\n// column \u2014 the SQL never names it), the map stays empty, and the rail stays\n// hidden behind its is_not_empty gate.\nasync function getRelatedPostsMap(getClientFn, records) {\n var map = {}\n if (!Array.isArray(records) || records.length === 0) return map\n\n var wantedIds = []\n for (var i = 0; i < records.length; i++) {\n var ids = parseRelatedIds(records[i] && records[i].related_post_ids)\n for (var j = 0; j < ids.length; j++) {\n if (wantedIds.indexOf(ids[j]) === -1) wantedIds.push(ids[j])\n }\n }\n if (wantedIds.length === 0) return map\n\n var client\n try {\n client = getClientFn()\n await client.connect()\n var result = await client.query('SELECT * FROM ").concat(tables.posts, " WHERE id = ANY($1)', [\n wantedIds,\n ])\n if (result && result.rows) {\n for (var r = 0; r < result.rows.length; r++) {\n var row = result.rows[r]\n if (row && row.id != null) map[String(row.id)] = row\n }\n }\n } catch (e) {\n // Leaves relatedPosts empty rather than failing the page.\n } finally {\n if (client) {\n try { await client.end() } catch (e) { /* ignore */ }\n }\n }\n return map\n}\n");
|
|
13
16
|
};
|
|
14
17
|
//# sourceMappingURL=blog-post.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"blog-post.js","sourceRoot":"","sources":["../../../src/transformations/blog-post.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"blog-post.js","sourceRoot":"","sources":["../../../src/transformations/blog-post.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AACnF,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAClE,OAAO,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAA;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAuB9D;;;;GAIG;AACH,MAAM,CAAC,IAAM,kCAAkC,GAAG,UAChD,OAAsC;;IAAtC,wBAAA,EAAA,YAAsC;IAEtC,IAAM,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,mCAAI,aAAa,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;IACzE,OAAO,2KAIP,4BAA4B,CAAC,uBAAuB,EAAE,OAAO,CAAC,UAAU,CAAC,eACzE,wBAAwB,CAAC,MAAA,MAAM,CAAC,QAAQ,mCAAI,UAAG,MAAM,CAAC,KAAK,cAAW,CAAC,eACvE,yBAAyB,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,eAClE,0BAA0B,EAAE,eAC5B,sBAAsB,CAAC,oCAAoC,EAAE,0CAClC,OAAO,CAAC,cAAc,KAAK,IAAI,mCACtC,OAAO,CAAC,QAAQ,KAAK,IAAI,2CACjB,MAAM,CAAC,cAAc,KAAK,KAAK,49ZA0QR,MAAM,CAAC,KAAK,6cAkBhE,CAAA;AACD,CAAC,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { UIDLEcommerceCategory } from '@teleporthq/teleport-types';
|
|
2
|
+
export interface BookingItemTransformOptions {
|
|
3
|
+
/** The booking items' category taxonomy — see `bookingSettings.categories`. */
|
|
4
|
+
categories?: UIDLEcommerceCategory[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Generates JavaScript code for the `teleport_booking_items` row
|
|
8
|
+
* transformation — the things a Bookings site lets people book.
|
|
9
|
+
*
|
|
10
|
+
* The row is kept whole (every column, snake_case: the booking pages bind
|
|
11
|
+
* them as stored) and its translatable texts — `name`, `description` (rich
|
|
12
|
+
* text) and `location` — are the page's language when the row has them there
|
|
13
|
+
* (`es_name`, …), the main language otherwise. Its `category` is the name its
|
|
14
|
+
* first category has in the page's language, read off the taxonomy baked in
|
|
15
|
+
* here (the row's stored main name while none of its ids is a category). That
|
|
16
|
+
* is all a booking page needs to show an item in the visitor's language; the
|
|
17
|
+
* booking statements localise what they read on their own.
|
|
18
|
+
*
|
|
19
|
+
* MUST mirror `localizeBookingItem` in the editor
|
|
20
|
+
* (teleport-gui features/bookings/utils/localize-booking-item.ts), which is
|
|
21
|
+
* what the canvas renders from.
|
|
22
|
+
*/
|
|
23
|
+
export declare const generateBookingItemTransformationCode: (options?: BookingItemTransformOptions) => string;
|
|
24
|
+
//# sourceMappingURL=booking-item.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-item.d.ts","sourceRoot":"","sources":["../../../src/transformations/booking-item.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAA;AAGvE,MAAM,WAAW,2BAA2B;IAC1C,+EAA+E;IAC/E,UAAU,CAAC,EAAE,qBAAqB,EAAE,CAAA;CACrC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,qCAAqC,aACvC,2BAA2B,KACnC,MA2CF,CAAA"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { generateCategoryTaxonomyCode } from './category-taxonomy';
|
|
2
|
+
/**
|
|
3
|
+
* Generates JavaScript code for the `teleport_booking_items` row
|
|
4
|
+
* transformation — the things a Bookings site lets people book.
|
|
5
|
+
*
|
|
6
|
+
* The row is kept whole (every column, snake_case: the booking pages bind
|
|
7
|
+
* them as stored) and its translatable texts — `name`, `description` (rich
|
|
8
|
+
* text) and `location` — are the page's language when the row has them there
|
|
9
|
+
* (`es_name`, …), the main language otherwise. Its `category` is the name its
|
|
10
|
+
* first category has in the page's language, read off the taxonomy baked in
|
|
11
|
+
* here (the row's stored main name while none of its ids is a category). That
|
|
12
|
+
* is all a booking page needs to show an item in the visitor's language; the
|
|
13
|
+
* booking statements localise what they read on their own.
|
|
14
|
+
*
|
|
15
|
+
* MUST mirror `localizeBookingItem` in the editor
|
|
16
|
+
* (teleport-gui features/bookings/utils/localize-booking-item.ts), which is
|
|
17
|
+
* what the canvas renders from.
|
|
18
|
+
*/
|
|
19
|
+
export var generateBookingItemTransformationCode = function (options) {
|
|
20
|
+
if (options === void 0) { options = {}; }
|
|
21
|
+
return "\n// ============================================================\n// Booking Item Transformation\n// ============================================================\n\nvar BOOKING_ITEM_TRANSLATABLE_COLUMNS = ['name', 'description', 'location']\n".concat(generateCategoryTaxonomyCode('BOOKING_CATEGORIES_BY_ID', options.categories), "\n\nfunction buildBookingItem(record, options) {\n if (!record || typeof record !== 'object') return record\n options = options || {}\n var currentLang = options.currentLanguage || null\n var mainLang = options.mainLanguage || null\n\n var out = {}\n for (var key in record) {\n if (Object.prototype.hasOwnProperty.call(record, key)) out[key] = record[key]\n }\n for (var i = 0; i < BOOKING_ITEM_TRANSLATABLE_COLUMNS.length; i++) {\n var column = BOOKING_ITEM_TRANSLATABLE_COLUMNS[i]\n var value = resolveI18nField(record, column, column, currentLang, mainLang)\n out[column] = value === null || value === undefined ? record[column] : value\n }\n if ('category' in record || 'category_ids' in record) {\n var stored = typeof record.category === 'string' ? record.category : ''\n var assigned = resolveAssignedCategories(\n record.category_ids,\n BOOKING_CATEGORIES_BY_ID,\n currentLang,\n mainLang,\n stored\n )\n out.category = assigned.length > 0 ? assigned[0].name : stored\n }\n return out\n}\n\nfunction transformBookingItems(records, options) {\n if (!Array.isArray(records)) return []\n return records.map(function(record) { return buildBookingItem(record, options) })\n}\n");
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=booking-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"booking-item.js","sourceRoot":"","sources":["../../../src/transformations/booking-item.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAA;AAOlE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,IAAM,qCAAqC,GAAG,UACnD,OAAyC;IAAzC,wBAAA,EAAA,YAAyC;IAEzC,OAAO,6PAMP,4BAA4B,CAAC,0BAA0B,EAAE,OAAO,CAAC,UAAU,CAAC,guCAmC7E,CAAA;AACD,CAAC,CAAA"}
|
|
@@ -8,15 +8,39 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export declare const BLOG_HEADING_ANCHOR_CLASS = "tq-heading-anchor";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* gets an `id` (kept when it already has one, otherwise a slug of its text,
|
|
13
|
-
* unique within the post) and a trailing `#` link to itself, so a section can
|
|
14
|
-
* be linked to (`/blog/post#setup`) and the link works on the very first load —
|
|
15
|
-
* the ids are in the server-rendered HTML.
|
|
11
|
+
* The class of the link a post's content heading's own text becomes.
|
|
16
12
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
13
|
+
* ⛔ PAIRED with `BLOG_HEADING_LINK_CLASS` in teleport-gui
|
|
14
|
+
* `features/blog/utils/elements/heading-anchor-styles.ts`, whose stylesheet
|
|
15
|
+
* keeps the heading looking like a heading rather than like a link.
|
|
16
|
+
*/
|
|
17
|
+
export declare const BLOG_HEADING_LINK_CLASS = "tq-heading-link";
|
|
18
|
+
/**
|
|
19
|
+
* The fewest sections a post's Contents list is drawn for: a shorter post is
|
|
20
|
+
* taken in at a glance.
|
|
21
|
+
*
|
|
22
|
+
* ⛔ PAIRED with `CONTENTS_MIN_SECTIONS` in teleport-gui
|
|
23
|
+
* `packages/renderer/src/utils/blog-posts.ts`, the canvas's copy.
|
|
24
|
+
*/
|
|
25
|
+
export declare const CONTENTS_MIN_SECTIONS = 3;
|
|
26
|
+
/**
|
|
27
|
+
* Generates `addHeadingAnchors(html, options)`: every `<h2>`–`<h6>` of a post's
|
|
28
|
+
* content gets an `id` (kept when it already has one, otherwise a slug of its
|
|
29
|
+
* text, unique within the post), its text becomes a link to itself and a `#`
|
|
30
|
+
* follows it, shown on hover, so a section can be linked to
|
|
31
|
+
* (`/blog/post#setup`) by clicking its heading, and the link works on the very
|
|
32
|
+
* first load — the ids are in the server-rendered HTML. A heading that holds a
|
|
33
|
+
* link of its own keeps its text as it is (a link cannot hold another) and
|
|
34
|
+
* links through the `#` alone.
|
|
35
|
+
*
|
|
36
|
+
* `options.links: false` gives the headings their ids without the links —
|
|
37
|
+
* what a post page's Contents list needs when the heading anchors are off.
|
|
38
|
+
* `options.sections`, an array, collects every heading as `{ level, id, text }`
|
|
39
|
+
* in reading order, and `blogContentsSectionsOf` turns those into the list.
|
|
40
|
+
*
|
|
41
|
+
* The heading's text is the link a screen reader announces and the keyboard
|
|
42
|
+
* reaches; the `#` repeats it, so it is hidden from assistive technology and
|
|
43
|
+
* left out of the tab order.
|
|
20
44
|
*
|
|
21
45
|
* Idempotent: a heading that already carries the link is left alone. `h1` is
|
|
22
46
|
* the post title's level and is never touched.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading-anchors.d.ts","sourceRoot":"","sources":["../../../src/transformations/heading-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAE5D
|
|
1
|
+
{"version":3,"file":"heading-anchors.d.ts","sourceRoot":"","sources":["../../../src/transformations/heading-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,sBAAsB,CAAA;AAE5D;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,oBAAoB,CAAA;AAExD;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,0BAA0B,QAAO,MAiG7C,CAAA"}
|
|
@@ -8,18 +8,42 @@
|
|
|
8
8
|
*/
|
|
9
9
|
export var BLOG_HEADING_ANCHOR_CLASS = 'tq-heading-anchor';
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* gets an `id` (kept when it already has one, otherwise a slug of its text,
|
|
13
|
-
* unique within the post) and a trailing `#` link to itself, so a section can
|
|
14
|
-
* be linked to (`/blog/post#setup`) and the link works on the very first load —
|
|
15
|
-
* the ids are in the server-rendered HTML.
|
|
11
|
+
* The class of the link a post's content heading's own text becomes.
|
|
16
12
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
13
|
+
* ⛔ PAIRED with `BLOG_HEADING_LINK_CLASS` in teleport-gui
|
|
14
|
+
* `features/blog/utils/elements/heading-anchor-styles.ts`, whose stylesheet
|
|
15
|
+
* keeps the heading looking like a heading rather than like a link.
|
|
16
|
+
*/
|
|
17
|
+
export var BLOG_HEADING_LINK_CLASS = 'tq-heading-link';
|
|
18
|
+
/**
|
|
19
|
+
* The fewest sections a post's Contents list is drawn for: a shorter post is
|
|
20
|
+
* taken in at a glance.
|
|
21
|
+
*
|
|
22
|
+
* ⛔ PAIRED with `CONTENTS_MIN_SECTIONS` in teleport-gui
|
|
23
|
+
* `packages/renderer/src/utils/blog-posts.ts`, the canvas's copy.
|
|
24
|
+
*/
|
|
25
|
+
export var CONTENTS_MIN_SECTIONS = 3;
|
|
26
|
+
/**
|
|
27
|
+
* Generates `addHeadingAnchors(html, options)`: every `<h2>`–`<h6>` of a post's
|
|
28
|
+
* content gets an `id` (kept when it already has one, otherwise a slug of its
|
|
29
|
+
* text, unique within the post), its text becomes a link to itself and a `#`
|
|
30
|
+
* follows it, shown on hover, so a section can be linked to
|
|
31
|
+
* (`/blog/post#setup`) by clicking its heading, and the link works on the very
|
|
32
|
+
* first load — the ids are in the server-rendered HTML. A heading that holds a
|
|
33
|
+
* link of its own keeps its text as it is (a link cannot hold another) and
|
|
34
|
+
* links through the `#` alone.
|
|
35
|
+
*
|
|
36
|
+
* `options.links: false` gives the headings their ids without the links —
|
|
37
|
+
* what a post page's Contents list needs when the heading anchors are off.
|
|
38
|
+
* `options.sections`, an array, collects every heading as `{ level, id, text }`
|
|
39
|
+
* in reading order, and `blogContentsSectionsOf` turns those into the list.
|
|
40
|
+
*
|
|
41
|
+
* The heading's text is the link a screen reader announces and the keyboard
|
|
42
|
+
* reaches; the `#` repeats it, so it is hidden from assistive technology and
|
|
43
|
+
* left out of the tab order.
|
|
20
44
|
*
|
|
21
45
|
* Idempotent: a heading that already carries the link is left alone. `h1` is
|
|
22
46
|
* the post title's level and is never touched.
|
|
23
47
|
*/
|
|
24
|
-
export var generateHeadingAnchorsCode = function () { return "\nvar BLOG_HEADING_ANCHOR_CLASS = '".concat(BLOG_HEADING_ANCHOR_CLASS, "'\nvar BLOG_HEADING_ID_PATTERN = /\\sid\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/i\n\nfunction escapeHeadingAttribute(value) {\n return String(value)\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n}\n\nfunction blogHeadingSlug(text, used) {\n var base = String(text || '')\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, '-')\n .replace(/^-+|-+$/g, '')\n if (!base) base = 'section'\n var slug = base\n var suffix = 2\n while (used[slug]) {\n slug = base + '-' + suffix\n suffix++\n }\n used[slug] = true\n return slug\n}\n\nfunction addHeadingAnchors(html) {\n if (typeof html !== 'string' || !/<h[2-6][\\s>]/i.test(html)) return html\n // Every id the content already uses is taken, so a generated one never\n // duplicates it.\n var used =
|
|
48
|
+
export var generateHeadingAnchorsCode = function () { return "\nvar BLOG_HEADING_ANCHOR_CLASS = '".concat(BLOG_HEADING_ANCHOR_CLASS, "'\nvar BLOG_HEADING_LINK_CLASS = '").concat(BLOG_HEADING_LINK_CLASS, "'\nvar BLOG_HEADING_ID_PATTERN = /\\sid\\s*=\\s*(\"([^\"]*)\"|'([^']*)')/i\nvar BLOG_HEADING_ANCHOR_LINK_PATTERN = /<a\\s[^>]*class=\"").concat(BLOG_HEADING_ANCHOR_CLASS, "\"[^>]*>[\\s\\S]*?<\\/a>/gi\nvar BLOG_CONTENTS_MIN_SECTIONS = ").concat(CONTENTS_MIN_SECTIONS, "\n\nfunction escapeHeadingAttribute(value) {\n return String(value)\n .replace(/&/g, '&')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n}\n\nfunction blogHeadingSlug(text, used) {\n var base = String(text || '')\n .normalize('NFKD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .toLowerCase()\n .replace(/[^\\p{L}\\p{N}]+/gu, '-')\n .replace(/^-+|-+$/g, '')\n if (!base) base = 'section'\n var slug = base\n var suffix = 2\n while (used[slug]) {\n slug = base + '-' + suffix\n suffix++\n }\n used[slug] = true\n return slug\n}\n\nfunction addHeadingAnchors(html, options) {\n options = options || {}\n var withLinks = options.links !== false\n var sections = Array.isArray(options.sections) ? options.sections : null\n if (typeof html !== 'string' || !/<h[2-6][\\s>]/i.test(html)) return html\n // Every id the content already uses is taken, so a generated one never\n // duplicates it. No prototype: a heading titled \"Constructor\" is free to be\n // #constructor.\n var used = Object.create(null)\n var existingIds = new RegExp(BLOG_HEADING_ID_PATTERN.source, 'gi')\n var existing\n while ((existing = existingIds.exec(html)) !== null) {\n used[decodeHtmlEntities(existing[2] || existing[3] || '')] = true\n }\n\n return html.replace(/<h([2-6])(\\s[^>]*)?>([\\s\\S]*?)<\\/h\\1>/gi, function(match, level, rawAttrs, inner) {\n var attrs = rawAttrs || ''\n var idMatch = attrs.match(BLOG_HEADING_ID_PATTERN)\n var id = idMatch ? decodeHtmlEntities(idMatch[2] || idMatch[3] || '') : ''\n if (inner.indexOf(BLOG_HEADING_ANCHOR_CLASS) !== -1) {\n if (sections && id) {\n var anchoredText = stripHtmlTags(inner.replace(BLOG_HEADING_ANCHOR_LINK_PATTERN, ''))\n if (anchoredText) sections.push({ level: Number(level), id: id, text: anchoredText })\n }\n return match\n }\n var text = stripHtmlTags(inner)\n if (!text) return match\n if (!id) {\n id = blogHeadingSlug(text, used)\n attrs = ' id=\"' + escapeHeadingAttribute(id) + '\"' + attrs\n }\n if (sections) sections.push({ level: Number(level), id: id, text: text })\n if (!withLinks) return '<h' + level + attrs + '>' + inner + '</h' + level + '>'\n var href = '#' + escapeHeadingAttribute(id)\n var ownText = /<a[\\s>]/i.test(inner)\n ? inner\n : '<a class=\"' + BLOG_HEADING_LINK_CLASS + '\" href=\"' + href + '\">' + inner + '</a>'\n return (\n '<h' + level + attrs + '>' + ownText +\n '<a class=\"' + BLOG_HEADING_ANCHOR_CLASS + '\" href=\"' + href +\n '\" aria-hidden=\"true\" tabindex=\"-1\">#</a>' +\n '</h' + level + '>'\n )\n })\n}\n\n// A post page's Contents list: the post's sections, i.e. its headings of the\n// topmost level it uses, each with the address that jumps to it; none for a\n// post of fewer than BLOG_CONTENTS_MIN_SECTIONS sections.\n// MUST mirror contentsSectionsOf in teleport-gui packages/renderer/src/utils/blog-posts.ts.\nfunction blogContentsSectionsOf(headings) {\n if (!Array.isArray(headings) || headings.length === 0) return []\n var top = 6\n for (var i = 0; i < headings.length; i++) {\n if (headings[i].level < top) top = headings[i].level\n }\n var sections = []\n for (var j = 0; j < headings.length; j++) {\n if (headings[j].level !== top) continue\n sections.push({ id: headings[j].id, title: headings[j].text, href: '#' + headings[j].id })\n }\n return sections.length >= BLOG_CONTENTS_MIN_SECTIONS ? sections : []\n}\n"); };
|
|
25
49
|
//# sourceMappingURL=heading-anchors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heading-anchors.js","sourceRoot":"","sources":["../../../src/transformations/heading-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,IAAM,yBAAyB,GAAG,mBAAmB,CAAA;AAE5D
|
|
1
|
+
{"version":3,"file":"heading-anchors.js","sourceRoot":"","sources":["../../../src/transformations/heading-anchors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,IAAM,yBAAyB,GAAG,mBAAmB,CAAA;AAE5D;;;;;;GAMG;AACH,MAAM,CAAC,IAAM,uBAAuB,GAAG,iBAAiB,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,IAAM,qBAAqB,GAAG,CAAC,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,IAAM,0BAA0B,GAAG,cAAc,OAAA,6CACrB,yBAAyB,+CAC3B,uBAAuB,mJAEG,yBAAyB,2EACjD,qBAAqB,s9GA4FvD,EAjGuD,CAiGvD,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GeneratorOptions, UIDLAuthentication, UIDLEcommerceCategory } from '@teleporthq/teleport-types';
|
|
2
|
+
import { ContentTables } from '@teleporthq/teleport-shared';
|
|
2
3
|
import { type EcommerceProductTransformOptions } from './ecommerce-product';
|
|
3
4
|
import { type ContentLocalization, type LocalizedProjectOptions } from '../content-localization';
|
|
4
5
|
export type { EcommerceProductTransformOptions };
|
|
@@ -8,9 +9,25 @@ export type { EcommerceProductTransformOptions };
|
|
|
8
9
|
* to serve whichever transform that resolves to — the product fields are ignored
|
|
9
10
|
* for a blog table and vice versa.
|
|
10
11
|
*/
|
|
12
|
+
/** What a content preset bakes into its post transform — see `UIDLBlogSettings`. */
|
|
13
|
+
export interface ContentPresetTransformSettings {
|
|
14
|
+
categories?: UIDLEcommerceCategory[];
|
|
15
|
+
headingAnchors?: boolean;
|
|
16
|
+
contents?: boolean;
|
|
17
|
+
comments?: boolean;
|
|
18
|
+
order?: 'manual';
|
|
19
|
+
}
|
|
11
20
|
export interface EntityTransformOptions extends EcommerceProductTransformOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The settings of every content preset, by preset key — the post transform
|
|
23
|
+
* of a table reads its own preset's (`contentSettingsFor`). The `blog*`
|
|
24
|
+
* fields below are the Blog's, kept for the callers that name them.
|
|
25
|
+
*/
|
|
26
|
+
contentSettings?: Partial<Record<ContentTables.ContentPresetKey, ContentPresetTransformSettings>>;
|
|
12
27
|
/** Blog post-category taxonomy — see `blogSettings.categories`. */
|
|
13
28
|
blogCategories?: UIDLEcommerceCategory[];
|
|
29
|
+
/** The booking items' category taxonomy — see `bookingSettings.categories`. */
|
|
30
|
+
bookingCategories?: UIDLEcommerceCategory[];
|
|
14
31
|
/** Post content headings get ids and `#` links — see `blogSettings.headingAnchors`. */
|
|
15
32
|
blogHeadingAnchors?: boolean;
|
|
16
33
|
/**
|
|
@@ -34,15 +51,12 @@ export interface EntityTransformOptions extends EcommerceProductTransformOptions
|
|
|
34
51
|
trustedReaderRoles?: string[];
|
|
35
52
|
}
|
|
36
53
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* `storefrontTaxRate` is what turns a NET catalogue price into the price the
|
|
41
|
-
* shopper is quoted; `resolveStorefrontTaxRate` returns 0 (a no-op) for
|
|
42
|
-
* tax-inclusive or untaxed stores. `allowBackorders` is the effective
|
|
43
|
-
* "stock never blocks a purchase" flag — see `resolveAllowBackorders`.
|
|
54
|
+
* The settings the transform of `tableName` bakes in: its preset's entry in
|
|
55
|
+
* `contentSettings`, or — for the Blog, and for a caller that only set the
|
|
56
|
+
* `blog*` fields — those fields. Empty for a table no preset owns.
|
|
44
57
|
*/
|
|
45
|
-
export declare const
|
|
58
|
+
export declare const contentSettingsFor: (options: Pick<EntityTransformOptions, 'contentSettings' | 'blogCategories' | 'blogHeadingAnchors' | 'blogComments'>, tableName: string) => ContentPresetTransformSettings;
|
|
59
|
+
export declare const buildProductTransformOptions: (options: Pick<GeneratorOptions, 'ecommerceSettings' | 'invoiceSettings' | 'blogSettings' | 'bookingSettings' | 'helpCenterSettings' | 'auth'> & LocalizedProjectOptions & {
|
|
46
60
|
/**
|
|
47
61
|
* The SAME project authentication under the name a `ProjectUIDL` gives
|
|
48
62
|
* it — the project plugins call this with the UIDL itself, where the
|
|
@@ -54,14 +68,14 @@ export declare const buildProductTransformOptions: (options: Pick<GeneratorOptio
|
|
|
54
68
|
*/
|
|
55
69
|
authentication?: UIDLAuthentication;
|
|
56
70
|
}) => EntityTransformOptions;
|
|
57
|
-
export type TransformationType = 'blog-post' | 'ecommerce-product' | 'custom-page' | null;
|
|
71
|
+
export type TransformationType = 'blog-post' | 'ecommerce-product' | 'custom-page' | 'booking-item' | null;
|
|
58
72
|
/**
|
|
59
73
|
* Detects which transformation type to apply based on the table name.
|
|
60
74
|
* Returns null if no transformation is needed.
|
|
61
75
|
*
|
|
62
|
-
* IMPORTANT: Only the real platform-managed tables (`teleport_products`,
|
|
63
|
-
*
|
|
64
|
-
* transforms. A previous loose substring match (`lower.includes('products')`)
|
|
76
|
+
* IMPORTANT: Only the real platform-managed tables (`teleport_products`, the
|
|
77
|
+
* content presets' posts tables) are routed through the e-commerce/blog
|
|
78
|
+
* view-model transforms. A previous loose substring match (`lower.includes('products')`)
|
|
65
79
|
* incorrectly routed CUSTOM tables such as `products`, `store_products` or
|
|
66
80
|
* `wholesale_products` through `buildEcommerceProduct`, which emits a fixed set
|
|
67
81
|
* of platform product fields and silently drops all custom columns. Matching the
|
|
@@ -119,5 +133,5 @@ export declare const REVIEWS_PER_PRODUCT = 5;
|
|
|
119
133
|
* asked of every caller. Without a localization every row reads as before —
|
|
120
134
|
* the base columns.
|
|
121
135
|
*/
|
|
122
|
-
export declare const getTransformWrapperCode: (tableName: string, options?: Pick<EntityTransformOptions, 'localization' | 'blogComments'>) => string;
|
|
136
|
+
export declare const getTransformWrapperCode: (tableName: string, options?: Pick<EntityTransformOptions, 'localization' | 'blogComments' | 'contentSettings'>) => string;
|
|
123
137
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transformations/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/transformations/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAEhB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,aAAa,EAA8B,MAAM,6BAA6B,CAAA;AAKvF,OAAO,EAEL,KAAK,gCAAgC,EACtC,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAA;AAEhC,YAAY,EAAE,gCAAgC,EAAE,CAAA;AAEhD;;;;;GAKG;AACH,oFAAoF;AACpF,MAAM,WAAW,8BAA8B;IAC7C,UAAU,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACpC,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,KAAK,CAAC,EAAE,QAAQ,CAAA;CACjB;AAED,MAAM,WAAW,sBAAuB,SAAQ,gCAAgC;IAC9E;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,gBAAgB,EAAE,8BAA8B,CAAC,CAAC,CAAA;IACjG,mEAAmE;IACnE,cAAc,CAAC,EAAE,qBAAqB,EAAE,CAAA;IACxC,+EAA+E;IAC/E,iBAAiB,CAAC,EAAE,qBAAqB,EAAE,CAAA;IAC3C,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAA;IAClC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;CAC9B;AAqCD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,YACpB,KACP,sBAAsB,EACtB,iBAAiB,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,cAAc,CAC7E,aACU,MAAM,KAChB,8BAiBF,CAAA;AAED,eAAO,MAAM,4BAA4B,YAC9B,KACP,gBAAgB,EACd,mBAAmB,GACnB,iBAAiB,GACjB,cAAc,GACd,iBAAiB,GACjB,oBAAoB,GACpB,MAAM,CACT,GACC,uBAAuB,GAAG;IACxB;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAA;CACpC,KACF,sBAeD,CAAA;AAEF,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,mBAAmB,GACnB,aAAa,GACb,cAAc,GACd,IAAI,CAAA;AAeR;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,wBAAwB,cAAe,MAAM,KAAG,kBAkB5D,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,cACrB,MAAM,YACR,sBAAsB,KAC9B,MAkCF,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc,YAAY,CAAA;AAEvC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,cAAe,MAAM,KAAG,MAAM,GAAG,IAKnE,CAAA;AA+DD;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAA;AAEpC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,uBAAuB,cACvB,MAAM,YACR,KAAK,sBAAsB,EAAE,cAAc,GAAG,cAAc,GAAG,iBAAiB,CAAC,KACzF,MAqKF,CAAA"}
|
|
@@ -1,7 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { ContentTables, StorefrontTax, TableAccess } from '@teleporthq/teleport-shared';
|
|
2
13
|
import { generateSharedTransformationCode } from './shared-utils';
|
|
3
14
|
import { generateBlogPostTransformationCode } from './blog-post';
|
|
4
15
|
import { generateCustomPageTransformationCode } from './custom-page';
|
|
16
|
+
import { generateBookingItemTransformationCode } from './booking-item';
|
|
5
17
|
import { generateEcommerceProductTransformationCode, } from './ecommerce-product';
|
|
6
18
|
import { REQUEST_LOCALE_PARAM } from '../request-locale';
|
|
7
19
|
import { resolveContentLocalization, } from '../content-localization';
|
|
@@ -28,16 +40,46 @@ var resolveAllowBackorders = function (settings) {
|
|
|
28
40
|
* tax-inclusive or untaxed stores. `allowBackorders` is the effective
|
|
29
41
|
* "stock never blocks a purchase" flag — see `resolveAllowBackorders`.
|
|
30
42
|
*/
|
|
43
|
+
var contentPresetTransformSettings = function (settings) { return (__assign(__assign(__assign({ categories: settings === null || settings === void 0 ? void 0 : settings.categories, headingAnchors: (settings === null || settings === void 0 ? void 0 : settings.headingAnchors) === true }, ((settings === null || settings === void 0 ? void 0 : settings.contents) === true && { contents: true })), { comments: (settings === null || settings === void 0 ? void 0 : settings.comments) === true }), ((settings === null || settings === void 0 ? void 0 : settings.order) === 'manual' && { order: 'manual' }))); };
|
|
44
|
+
/**
|
|
45
|
+
* The settings the transform of `tableName` bakes in: its preset's entry in
|
|
46
|
+
* `contentSettings`, or — for the Blog, and for a caller that only set the
|
|
47
|
+
* `blog*` fields — those fields. Empty for a table no preset owns.
|
|
48
|
+
*/
|
|
49
|
+
export var contentSettingsFor = function (options, tableName) {
|
|
50
|
+
var _a;
|
|
51
|
+
var role = ContentTables.contentTableRole(stripSchemaQualifier(tableName));
|
|
52
|
+
if (!role) {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
55
|
+
var own = (_a = options.contentSettings) === null || _a === void 0 ? void 0 : _a[role.key];
|
|
56
|
+
if (own) {
|
|
57
|
+
return own;
|
|
58
|
+
}
|
|
59
|
+
if (role.key === 'blog') {
|
|
60
|
+
return {
|
|
61
|
+
categories: options.blogCategories,
|
|
62
|
+
headingAnchors: options.blogHeadingAnchors,
|
|
63
|
+
comments: options.blogComments,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
return {};
|
|
67
|
+
};
|
|
31
68
|
export var buildProductTransformOptions = function (options) {
|
|
32
|
-
var _a, _b, _c, _d, _e;
|
|
69
|
+
var _a, _b, _c, _d, _e, _f;
|
|
33
70
|
return ({
|
|
34
71
|
categories: (_a = options.ecommerceSettings) === null || _a === void 0 ? void 0 : _a.categories,
|
|
72
|
+
contentSettings: {
|
|
73
|
+
blog: contentPresetTransformSettings(options.blogSettings),
|
|
74
|
+
help: contentPresetTransformSettings(options.helpCenterSettings),
|
|
75
|
+
},
|
|
35
76
|
blogCategories: (_b = options.blogSettings) === null || _b === void 0 ? void 0 : _b.categories,
|
|
36
|
-
|
|
37
|
-
|
|
77
|
+
bookingCategories: (_c = options.bookingSettings) === null || _c === void 0 ? void 0 : _c.categories,
|
|
78
|
+
blogHeadingAnchors: ((_d = options.blogSettings) === null || _d === void 0 ? void 0 : _d.headingAnchors) === true,
|
|
79
|
+
blogComments: ((_e = options.blogSettings) === null || _e === void 0 ? void 0 : _e.comments) === true,
|
|
38
80
|
storefrontTaxRate: StorefrontTax.resolveStorefrontTaxRate(options.invoiceSettings),
|
|
39
81
|
allowBackorders: resolveAllowBackorders(options.ecommerceSettings),
|
|
40
|
-
productPages: (
|
|
82
|
+
productPages: (_f = options.ecommerceSettings) === null || _f === void 0 ? void 0 : _f.productPages,
|
|
41
83
|
localization: resolveContentLocalization(options),
|
|
42
84
|
trustedReaderRoles: TableAccess.resolveTrustedReaderRoles(options.auth || options.authentication),
|
|
43
85
|
});
|
|
@@ -58,9 +100,9 @@ var stripSchemaQualifier = function (tableName) {
|
|
|
58
100
|
* Detects which transformation type to apply based on the table name.
|
|
59
101
|
* Returns null if no transformation is needed.
|
|
60
102
|
*
|
|
61
|
-
* IMPORTANT: Only the real platform-managed tables (`teleport_products`,
|
|
62
|
-
*
|
|
63
|
-
* transforms. A previous loose substring match (`lower.includes('products')`)
|
|
103
|
+
* IMPORTANT: Only the real platform-managed tables (`teleport_products`, the
|
|
104
|
+
* content presets' posts tables) are routed through the e-commerce/blog
|
|
105
|
+
* view-model transforms. A previous loose substring match (`lower.includes('products')`)
|
|
64
106
|
* incorrectly routed CUSTOM tables such as `products`, `store_products` or
|
|
65
107
|
* `wholesale_products` through `buildEcommerceProduct`, which emits a fixed set
|
|
66
108
|
* of platform product fields and silently drops all custom columns. Matching the
|
|
@@ -71,7 +113,7 @@ export var detectTransformationType = function (tableName) {
|
|
|
71
113
|
return null;
|
|
72
114
|
}
|
|
73
115
|
var bare = stripSchemaQualifier(tableName);
|
|
74
|
-
if (bare
|
|
116
|
+
if (ContentTables.isContentPostsTable(bare)) {
|
|
75
117
|
return 'blog-post';
|
|
76
118
|
}
|
|
77
119
|
if (bare === 'teleport_products') {
|
|
@@ -80,6 +122,9 @@ export var detectTransformationType = function (tableName) {
|
|
|
80
122
|
if (bare === 'teleport_pages') {
|
|
81
123
|
return 'custom-page';
|
|
82
124
|
}
|
|
125
|
+
if (bare === 'teleport_booking_items') {
|
|
126
|
+
return 'booking-item';
|
|
127
|
+
}
|
|
83
128
|
return null;
|
|
84
129
|
};
|
|
85
130
|
/**
|
|
@@ -95,16 +140,24 @@ export var getTransformationCode = function (tableName, options) {
|
|
|
95
140
|
}
|
|
96
141
|
var shared = generateSharedTransformationCode();
|
|
97
142
|
switch (type) {
|
|
98
|
-
case 'blog-post':
|
|
143
|
+
case 'blog-post': {
|
|
144
|
+
var role = ContentTables.contentTableRole(stripSchemaQualifier(tableName));
|
|
145
|
+
var settings = contentSettingsFor(options, tableName);
|
|
99
146
|
return (shared +
|
|
100
147
|
generateBlogPostTransformationCode({
|
|
101
|
-
|
|
102
|
-
|
|
148
|
+
tables: role ? ContentTables.contentTablesByKey(role.key) : undefined,
|
|
149
|
+
categories: settings.categories,
|
|
150
|
+
headingAnchors: settings.headingAnchors,
|
|
151
|
+
contents: settings.contents === true,
|
|
152
|
+
arranged: settings.order === 'manual',
|
|
103
153
|
}));
|
|
154
|
+
}
|
|
104
155
|
case 'ecommerce-product':
|
|
105
156
|
return shared + generateEcommerceProductTransformationCode(options);
|
|
106
157
|
case 'custom-page':
|
|
107
158
|
return shared + generateCustomPageTransformationCode();
|
|
159
|
+
case 'booking-item':
|
|
160
|
+
return (shared + generateBookingItemTransformationCode({ categories: options.bookingCategories }));
|
|
108
161
|
default:
|
|
109
162
|
return '';
|
|
110
163
|
}
|
|
@@ -180,7 +233,9 @@ export var getTransformWrapperCode = function (tableName, options) {
|
|
|
180
233
|
? 'transformBlogPosts'
|
|
181
234
|
: type === 'custom-page'
|
|
182
235
|
? 'transformCustomPages'
|
|
183
|
-
: '
|
|
236
|
+
: type === 'booking-item'
|
|
237
|
+
? 'transformBookingItems'
|
|
238
|
+
: 'transformEcommerceProducts';
|
|
184
239
|
// Products additionally get their purchasable variant combinations attached in
|
|
185
240
|
// ONE batched query (keyed by product id). Blog posts have no such enrichment.
|
|
186
241
|
//
|
|
@@ -223,14 +278,15 @@ export var getTransformWrapperCode = function (tableName, options) {
|
|
|
223
278
|
var relatedOption = hasRelatedItems ? ", ".concat(relatedMapVar, ": ").concat(relatedMapVar) : '';
|
|
224
279
|
// A post page's neighbours and comments, on the same single-record heuristic
|
|
225
280
|
// as the related rail. The comments are only asked for when the blog takes
|
|
226
|
-
// them — see `EntityTransformOptions.blogComments`.
|
|
281
|
+
// them — see `EntityTransformOptions.blogComments`. `details` tells the
|
|
282
|
+
// transform the same thing: what only a post page draws (its Contents list).
|
|
227
283
|
var blogPageEnrichment = type === 'blog-post'
|
|
228
|
-
? "\n var adjacentPostsById = null\n var commentsByPostId = null\n if (Array.isArray(records) && records.length === 1) {\n try {\n adjacentPostsById = await getAdjacentPostsMap(getClientFn, records)\n } catch (e) {\n // Best-effort; the post navigation stays hidden.\n }".concat(options.
|
|
284
|
+
? "\n var adjacentPostsById = null\n var commentsByPostId = null\n if (Array.isArray(records) && records.length === 1) {\n try {\n adjacentPostsById = await getAdjacentPostsMap(getClientFn, records)\n } catch (e) {\n // Best-effort; the post navigation stays hidden.\n }".concat(contentSettingsFor(options, tableName).comments === true
|
|
229
285
|
? "\n try {\n commentsByPostId = await getBlogCommentsMap(getClientFn, records)\n } catch (e) {\n // Best-effort; the post renders without comments.\n }"
|
|
230
286
|
: '', "\n }")
|
|
231
287
|
: '';
|
|
232
288
|
var blogPageOption = type === 'blog-post'
|
|
233
|
-
? ', adjacentPostsById: adjacentPostsById, commentsByPostId: commentsByPostId'
|
|
289
|
+
? ', adjacentPostsById: adjacentPostsById, commentsByPostId: commentsByPostId, details: Array.isArray(records) && records.length === 1'
|
|
234
290
|
: '';
|
|
235
291
|
return "".concat(RAW_ROWS_CODE, "\nasync function transformRecords(records, getClientFn, reqQuery) {\n var assetMap = {}\n try {\n assetMap = await getAssetMap(getClientFn)\n } catch (e) {\n // Asset resolution is best-effort; continue without it\n }").concat(relatedEnrichment).concat(blogPageEnrichment).concat(variantEnrichment, "\n var currentLanguage = reqQuery && typeof reqQuery.").concat(REQUEST_LOCALE_PARAM, " === 'string' && reqQuery.").concat(REQUEST_LOCALE_PARAM, " ? reqQuery.").concat(REQUEST_LOCALE_PARAM, " : null\n var options = { assetMap: assetMap, currentLanguage: currentLanguage, mainLanguage: ").concat(mainLanguageLiteral).concat(variantOption).concat(relatedOption).concat(blogPageOption, " }\n return ").concat(transformFn, "(records, options)\n}\n");
|
|
236
292
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transformations/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transformations/index.ts"],"names":[],"mappings":"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"}
|