platform-types 1.10.687 → 1.10.689

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/dist/cjs/index.js CHANGED
@@ -103,6 +103,8 @@ __exportStar(require("./storefrontTheme.js"), exports);
103
103
  __exportStar(require("./storeNetwork.js"), exports);
104
104
  __exportStar(require("./storefrontAssets.js"), exports);
105
105
  __exportStar(require("./storefrontEvent.js"), exports);
106
+ __exportStar(require("./storefrontSeo.js"), exports);
107
+ __exportStar(require("./storefrontWebLiteralKeys.js"), exports);
106
108
  __exportStar(require("./subscription.js"), exports);
107
109
  __exportStar(require("./support.js"), exports);
108
110
  __exportStar(require("./terminal.js"), exports);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MAX_STOREFRONT_ASSETS = exports.STOREFRONT_ASSET_VARIANTS = void 0;
3
+ exports.MAX_STOREFRONT_ASSETS = exports.STOREFRONT_ASSET_VARIANT_FIT = exports.STOREFRONT_ASSET_VARIANTS = void 0;
4
4
  const storefrontDesign_ts_1 = require("./storefrontDesign.js");
5
5
  exports.STOREFRONT_ASSET_VARIANTS = [
6
6
  'original',
@@ -9,6 +9,31 @@ exports.STOREFRONT_ASSET_VARIANTS = [
9
9
  '800x800',
10
10
  '1200x1200',
11
11
  '1600x1600',
12
+ '1200x630',
13
+ '192x192',
14
+ '512x512',
12
15
  ];
16
+ /**
17
+ * How each variant is rendered from the stored original. `original` is the
18
+ * stored image unchanged in size. `inside` is a thumbnail: it fits inside the
19
+ * box keeping its aspect and never enlarges, so a small original comes back at
20
+ * its own size. `1200x630` is `cover`: an EXACT-size crop for share images
21
+ * (`og:image`), enlarged when the original is smaller. `192x192` and `512x512`
22
+ * are `contain`: EXACT-size icons (favicon, PWA manifest), not thumbnails —
23
+ * the whole original is scaled to fit and the rest of the square is padded
24
+ * transparent, so nothing is cropped; they are always PNG, or WebP when the
25
+ * client accepts it, because a JPEG cannot carry the transparent padding.
26
+ */
27
+ exports.STOREFRONT_ASSET_VARIANT_FIT = {
28
+ original: 'original',
29
+ '200x200': 'inside',
30
+ '400x400': 'inside',
31
+ '800x800': 'inside',
32
+ '1200x1200': 'inside',
33
+ '1600x1600': 'inside',
34
+ '1200x630': 'cover',
35
+ '192x192': 'contain',
36
+ '512x512': 'contain',
37
+ };
13
38
  /** The active-asset cap, the same value as `STOREFRONT_DESIGN_LIMITS.activeImages` by construction. */
14
39
  exports.MAX_STOREFRONT_ASSETS = storefrontDesign_ts_1.STOREFRONT_DESIGN_LIMITS.activeImages;
@@ -1,12 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.STOREFRONT_PREVIEW_PROTOCOL_ERRORS = exports.STOREFRONT_PREVIEW_READ_OPERATIONS = exports.STOREFRONT_SOCIAL_HOSTS = exports.STOREFRONT_BENEFIT_ICONS = exports.STOREFRONT_RESERVED_SLUGS = exports.STOREFRONT_CONTACT_FIELDS = exports.STOREFRONT_PROTECTED_BUILTIN_DESTINATIONS = exports.STOREFRONT_BUILTIN_DESTINATIONS = exports.STOREFRONT_SECTION_TYPES = exports.STOREFRONT_DESIGN_LIMITS = void 0;
3
+ exports.STOREFRONT_PREVIEW_PROTOCOL_ERRORS = exports.STOREFRONT_PREVIEW_READ_OPERATIONS = exports.STOREFRONT_BENEFIT_ICONS = exports.STOREFRONT_RESERVED_SLUGS = exports.STOREFRONT_CONTACT_FIELDS = exports.STOREFRONT_PROTECTED_BUILTIN_DESTINATIONS = exports.STOREFRONT_BUILTIN_DESTINATIONS = exports.STOREFRONT_SECTION_TYPES = exports.isStorefrontPageSlug = exports.STOREFRONT_PAGE_SLUG_RE = exports.STOREFRONT_DESIGN_LIMITS = exports.STOREFRONT_SOCIAL_HOSTS = void 0;
4
4
  exports.createStorefrontDesignV1 = createStorefrontDesignV1;
5
5
  exports.parseStorefrontPreviewDocument = parseStorefrontPreviewDocument;
6
6
  exports.parseStorefrontPreviewMessage = parseStorefrontPreviewMessage;
7
7
  exports.acceptStorefrontPreviewMessage = acceptStorefrontPreviewMessage;
8
+ /** The social kinds a contact may link, each to its own hosts; a contact links at most one per kind. */
9
+ exports.STOREFRONT_SOCIAL_HOSTS = {
10
+ instagram: ['instagram.com', 'www.instagram.com'],
11
+ facebook: ['facebook.com', 'www.facebook.com'],
12
+ youtube: ['youtube.com', 'www.youtube.com', 'youtu.be', 'www.youtu.be'],
13
+ tiktok: ['tiktok.com', 'www.tiktok.com'],
14
+ linkedin: ['linkedin.com', 'www.linkedin.com'],
15
+ x: ['x.com', 'www.x.com'],
16
+ };
8
17
  exports.STOREFRONT_DESIGN_LIMITS = {
9
18
  customPages: 20,
19
+ pageAliases: 20,
20
+ pageAliasMetadataBytes: 64 * 1024,
10
21
  sectionsPerPage: 10,
11
22
  productCountMin: 4,
12
23
  productCountMax: 24,
@@ -41,9 +52,18 @@ exports.STOREFRONT_DESIGN_LIMITS = {
41
52
  contactAddress: 500,
42
53
  contactNote: 200,
43
54
  contactHours: 14,
44
- contactSocials: 8,
55
+ /** One link per social kind, so the cap is the number of kinds. */
56
+ contactSocials: Object.keys(exports.STOREFRONT_SOCIAL_HOSTS).length,
45
57
  contactEmail: 254,
46
58
  };
59
+ /**
60
+ * A custom page's slug: lowercase ASCII letters, digits and inner hyphens, 1 to
61
+ * `STOREFRONT_DESIGN_LIMITS.slug` characters, starting and ending alphanumeric. The one
62
+ * definition: the api's validators, its page renderer and the edge viewer request read it.
63
+ */
64
+ exports.STOREFRONT_PAGE_SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,78}[a-z0-9])?$/;
65
+ const isStorefrontPageSlug = (value) => typeof value === 'string' && exports.STOREFRONT_PAGE_SLUG_RE.test(value);
66
+ exports.isStorefrontPageSlug = isStorefrontPageSlug;
47
67
  exports.STOREFRONT_SECTION_TYPES = [
48
68
  'banner',
49
69
  'imageText',
@@ -122,14 +142,6 @@ exports.STOREFRONT_RESERVED_SLUGS = [
122
142
  'mantenimiento',
123
143
  ];
124
144
  exports.STOREFRONT_BENEFIT_ICONS = ['truck', 'shield', 'credit-card', 'store', 'heart', 'check'];
125
- exports.STOREFRONT_SOCIAL_HOSTS = {
126
- instagram: ['instagram.com', 'www.instagram.com'],
127
- facebook: ['facebook.com', 'www.facebook.com'],
128
- youtube: ['youtube.com', 'www.youtube.com', 'youtu.be', 'www.youtu.be'],
129
- tiktok: ['tiktok.com', 'www.tiktok.com'],
130
- linkedin: ['linkedin.com', 'www.linkedin.com'],
131
- x: ['x.com', 'www.x.com'],
132
- };
133
145
  function createStorefrontDesignV1() {
134
146
  return {
135
147
  schemaVersion: 1,
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * Information-page paths and the storefront's SEO inheritance chain — one
4
+ * definition for the server that renders a shared link's head and the editor
5
+ * that previews it.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.storefrontDefaultSeoDescription = exports.storefrontPagePath = exports.STOREFRONT_PAGE_PATH_PREFIX = void 0;
9
+ exports.resolveStorefrontSeo = resolveStorefrontSeo;
10
+ /** Path prefix of a published information page: `/pagina/<slug>`. */
11
+ exports.STOREFRONT_PAGE_PATH_PREFIX = '/pagina/';
12
+ /** The path an information page with `slug` is served at. The slug is neither validated nor encoded here. */
13
+ const storefrontPagePath = (slug) => `${exports.STOREFRONT_PAGE_PATH_PREFIX}${slug}`;
14
+ exports.storefrontPagePath = storefrontPagePath;
15
+ /** The description a shop is shared with when neither the page nor the shop sets one. */
16
+ const storefrontDefaultSeoDescription = (storeName) => `Comprá online en ${storeName}: catálogo, precios y stock actualizados.`;
17
+ exports.storefrontDefaultSeoDescription = storefrontDefaultSeoDescription;
18
+ const shopImage = (document) => {
19
+ if (document.seo.image)
20
+ return { image: document.seo.image, source: 'shop' };
21
+ if (document.branding.logo)
22
+ return { image: document.branding.logo, source: 'logo' };
23
+ return { image: null, source: 'default' };
24
+ };
25
+ /** Home's SEO — and the default every information page inherits field by field. */
26
+ const shopSeo = (document, storeName) => {
27
+ const { seo } = document;
28
+ const image = shopImage(document);
29
+ return {
30
+ title: seo.title || storeName,
31
+ description: seo.description || (0, exports.storefrontDefaultSeoDescription)(storeName),
32
+ image: image.image,
33
+ noindex: seo.noindex === true,
34
+ source: {
35
+ title: seo.title ? 'shop' : 'default',
36
+ description: seo.description ? 'shop' : 'default',
37
+ image: image.source,
38
+ noindex: typeof seo.noindex === 'boolean' ? 'shop' : 'default',
39
+ },
40
+ };
41
+ };
42
+ function resolveStorefrontSeo(document, target, storeName) {
43
+ const shop = shopSeo(document, storeName);
44
+ if (target === 'home')
45
+ return shop;
46
+ const page = document.pages.find(({ id }) => id === target);
47
+ if (!page)
48
+ return undefined;
49
+ const own = page.seo;
50
+ const pageTitle = own?.title || page.title;
51
+ const pageNoindex = own?.noindex;
52
+ return {
53
+ title: pageTitle || shop.title,
54
+ description: own?.description || shop.description,
55
+ image: own?.image || shop.image,
56
+ noindex: typeof pageNoindex === 'boolean' ? pageNoindex : shop.noindex,
57
+ source: {
58
+ title: pageTitle ? 'page' : shop.source.title,
59
+ description: own?.description ? 'page' : shop.source.description,
60
+ image: own?.image ? 'page' : shop.source.image,
61
+ noindex: typeof pageNoindex === 'boolean' ? 'page' : shop.source.noindex,
62
+ },
63
+ };
64
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveStorefrontTheme = exports.storefrontContrastRatio = void 0;
3
+ exports.resolveStorefrontTheme = exports.resolveStorefrontEffectiveSettings = exports.storefrontGlobalSettingsLayer = exports.storefrontContrastRatio = void 0;
4
4
  const storefrontDesignRegistry_ts_1 = require("./storefrontDesignRegistry.js");
5
5
  const channels = (color) => [
6
6
  Number.parseInt(color.slice(1, 3), 16),
@@ -66,14 +66,38 @@ const surfaceTokens = (background, settings, mode, surface, warnings) => {
66
66
  };
67
67
  };
68
68
  /**
69
- * The storefront theme for a design's settings overrides.
70
- *
71
- * Settings resolve from the registry defaults plus the store's own design
72
- * overrides ONLY — no GLOBAL or WEB layer takes part — so a consumer uses this
73
- * as shipped rather than merging layers of its own first.
69
+ * The GLOBAL design-settings layer of the platform globals row as `getPlatformGlobalsRow`
70
+ * returns it (`{ [key]: { value, ... } }`): each entry's `value`, kept only when it is a
71
+ * valid design setting, so a non-design global or a malformed value never reaches a theme.
74
72
  */
75
- const resolveStorefrontTheme = (overrides = {}) => {
76
- const settings = (0, storefrontDesignRegistry_ts_1.resolveStorefrontDesignSettings)(overrides);
73
+ const storefrontGlobalSettingsLayer = (globalsRow) => ({
74
+ layer: 'GLOBAL',
75
+ values: Object.fromEntries(Object.entries(globalsRow ?? {}).flatMap(([key, entry]) => {
76
+ const value = entry !== null && typeof entry === 'object' ? entry.value : undefined;
77
+ return (0, storefrontDesignRegistry_ts_1.validateStorefrontDesignSetting)(key, value) ? [[key, value]] : [];
78
+ })),
79
+ });
80
+ exports.storefrontGlobalSettingsLayer = storefrontGlobalSettingsLayer;
81
+ /**
82
+ * The settings a storefront is served with: registry defaults, then the platform GLOBAL
83
+ * layer, then the design's own overrides. The one resolver behind the public envelope's
84
+ * `effectiveSettings`, the draft's `effectiveSettings` and the publish contrast report —
85
+ * a caller passes the globals row it read, never a layer stack of its own. The edge
86
+ * renderer's `theme-color` is design-only: its role reads no GLOBALS row.
87
+ */
88
+ const resolveStorefrontEffectiveSettings = (overrides = {}, globalsRow) => (0, storefrontDesignRegistry_ts_1.resolveStorefrontDesignSettings)(overrides, [(0, exports.storefrontGlobalSettingsLayer)(globalsRow)]);
89
+ exports.resolveStorefrontEffectiveSettings = resolveStorefrontEffectiveSettings;
90
+ /**
91
+ * The storefront theme for a design's settings overrides, resolved through
92
+ * `resolveStorefrontEffectiveSettings`: the GLOBAL layer of `globalsRow` sits under the
93
+ * design, exactly as in the public envelope's `effectiveSettings`. Omitting `globalsRow`
94
+ * resolves defaults plus the design only — correct solely while no GLOBAL design setting
95
+ * is set, so a caller serving or reporting on a storefront passes the row (the edge
96
+ * renderer's `theme-color` is the one exception, design-only by its read grant). Passing
97
+ * already-effective settings as `overrides` rebuilds the same theme.
98
+ */
99
+ const resolveStorefrontTheme = (overrides = {}, globalsRow) => {
100
+ const settings = (0, exports.resolveStorefrontEffectiveSettings)(overrides, globalsRow);
77
101
  const warnings = [];
78
102
  const makeMode = (mode) => {
79
103
  const background = (requested) => mode === 'light' ? requested.toUpperCase() : mix(requested, '#000000', 0.9);