@timardex/cluemart-shared 1.5.591 → 1.5.595

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.
@@ -29,6 +29,7 @@ __export(sharing_exports, {
29
29
  RESOURCE_SHARE_TYPES: () => RESOURCE_SHARE_TYPES,
30
30
  RESOURCE_SHARE_TYPES_FOR_URL: () => RESOURCE_SHARE_TYPES_FOR_URL,
31
31
  SHARE_COMPACT_SECTION_SEPARATOR: () => SHARE_COMPACT_SECTION_SEPARATOR,
32
+ SHARE_DESCRIPTION_SECTION_BREAK: () => SHARE_DESCRIPTION_SECTION_BREAK,
32
33
  SHARE_DESCRIPTION_SECTION_SEPARATOR: () => SHARE_DESCRIPTION_SECTION_SEPARATOR,
33
34
  SHARE_RESOURCE_LABEL: () => SHARE_RESOURCE_LABEL,
34
35
  SHARE_SITE_URL: () => SHARE_SITE_URL,
@@ -41,6 +42,7 @@ __export(sharing_exports, {
41
42
  buildShareUrl: () => buildShareUrl,
42
43
  formatCategoryLabel: () => formatCategoryLabel,
43
44
  formatShareSectionsForCompactDisplay: () => formatShareSectionsForCompactDisplay,
45
+ formatShareSectionsForMultilineDisplay: () => formatShareSectionsForMultilineDisplay,
44
46
  isPostShareResourceType: () => isPostShareResourceType,
45
47
  isRelationShareResourceType: () => isRelationShareResourceType,
46
48
  joinShareDescriptionSections: () => joinShareDescriptionSections,
@@ -60,9 +62,10 @@ function formatCategoryLabel(category) {
60
62
 
61
63
  // src/sharing/joinShareDescriptionSections.ts
62
64
  var SHARE_DESCRIPTION_SECTION_SEPARATOR = " \xB7 ";
65
+ var SHARE_DESCRIPTION_SECTION_BREAK = "\n\n";
63
66
  var SHARE_COMPACT_SECTION_SEPARATOR = SHARE_DESCRIPTION_SECTION_SEPARATOR;
64
67
  function joinShareDescriptionSections(sections) {
65
- return sections.filter((section) => Boolean(section)).join(SHARE_DESCRIPTION_SECTION_SEPARATOR);
68
+ return sections.filter((section) => Boolean(section)).join(SHARE_DESCRIPTION_SECTION_BREAK);
66
69
  }
67
70
 
68
71
  // src/sharing/buildRelationShareDescription.ts
@@ -179,49 +182,63 @@ function buildShareUrl(type, id) {
179
182
  }
180
183
 
181
184
  // src/sharing/normalizeShareDescription.ts
185
+ var LEGACY_BULLET_PREFIX = "\u2022 ";
182
186
  function normalizeShareSection(value) {
183
187
  if (value == null) {
184
188
  return "";
185
189
  }
186
190
  return value.trim().split("\n").map((line) => line.trim().replace(/[ \t]+/g, " ")).join("\n").replace(/\n{3,}/g, "\n\n");
187
191
  }
188
- function normalizeShareOgDescription(value) {
192
+ function stripLegacyBulletPrefix(section) {
193
+ return section.startsWith(LEGACY_BULLET_PREFIX) ? section.slice(LEGACY_BULLET_PREFIX.length) : section;
194
+ }
195
+ function splitShareDescriptionSections(value) {
189
196
  const trimmed = value.trim();
190
197
  if (!trimmed) {
191
- return "";
198
+ return [];
199
+ }
200
+ if (trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {
201
+ return trimmed.split(SHARE_DESCRIPTION_SECTION_SEPARATOR).map((section) => stripLegacyBulletPrefix(normalizeShareSection(section))).filter((section) => section.length > 0);
192
202
  }
193
203
  if (/\n\n/.test(trimmed)) {
194
- return trimmed.split(/\n\n+/).map((section) => section.replace(/\s+/g, " ").trim()).filter(Boolean).join(SHARE_DESCRIPTION_SECTION_SEPARATOR);
204
+ return trimmed.split(/\n\n+/).map((section) => stripLegacyBulletPrefix(normalizeShareSection(section))).filter((section) => section.length > 0);
195
205
  }
196
- return trimmed.replace(/\s+/g, " ").trim();
206
+ if (/\n/.test(trimmed)) {
207
+ return trimmed.split(/\n+/).map((section) => stripLegacyBulletPrefix(normalizeShareSection(section))).filter((section) => section.length > 0);
208
+ }
209
+ return [stripLegacyBulletPrefix(normalizeShareSection(trimmed))];
210
+ }
211
+ function collapseExcessiveBlankLines(value) {
212
+ return value.replace(/\n{4,}/g, "\n\n\n").trim();
213
+ }
214
+ function formatShareSectionsForMultilineDisplay(value) {
215
+ return collapseExcessiveBlankLines(
216
+ splitShareDescriptionSections(value).join(SHARE_DESCRIPTION_SECTION_BREAK)
217
+ );
197
218
  }
198
219
  function formatShareSectionsForCompactDisplay(value) {
220
+ return splitShareDescriptionSections(value).join(
221
+ SHARE_DESCRIPTION_SECTION_SEPARATOR
222
+ );
223
+ }
224
+ function normalizeShareOgDescription(value) {
199
225
  const trimmed = value.trim();
200
226
  if (!trimmed) {
201
227
  return "";
202
228
  }
203
- if (trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {
204
- return normalizeShareSection(trimmed);
205
- }
206
- if (/\n\n/.test(trimmed)) {
207
- return trimmed.split(/\n\n+/).map((section) => normalizeShareSection(section)).filter((section) => section.length > 0).join(SHARE_DESCRIPTION_SECTION_SEPARATOR);
229
+ if (/\n\n/.test(trimmed) || trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {
230
+ return formatShareSectionsForCompactDisplay(trimmed);
208
231
  }
209
- if (/\n/.test(trimmed)) {
210
- return trimmed.split(/\n+/).map((section) => normalizeShareSection(section)).filter((section) => section.length > 0).join(SHARE_DESCRIPTION_SECTION_SEPARATOR);
211
- }
212
- return normalizeShareSection(trimmed);
232
+ return trimmed.replace(/\s+/g, " ").trim();
213
233
  }
214
- function buildFacebookShareQuote(title, description) {
215
- const titlePart = normalizeShareSection(title);
216
- const descriptionPart = normalizeShareSection(description);
217
- const bodyPart = descriptionPart ? formatShareSectionsForCompactDisplay(descriptionPart) : "";
218
- const parts = [titlePart, bodyPart].filter((part) => part.length > 0);
219
- return parts.length > 0 ? parts.join(SHARE_DESCRIPTION_SECTION_SEPARATOR) : void 0;
234
+ function buildFacebookShareQuote(_title, description) {
235
+ const body = formatShareSectionsForMultilineDisplay(description);
236
+ return body.length > 0 ? body : void 0;
220
237
  }
221
- function buildShareOgDescription(title, description) {
222
- const quote = buildFacebookShareQuote(title, description);
223
- if (quote) {
224
- return quote;
238
+ function buildShareOgDescription(_title, description) {
239
+ const multiline = formatShareSectionsForMultilineDisplay(description);
240
+ if (multiline) {
241
+ return multiline;
225
242
  }
226
243
  return normalizeShareOgDescription(description);
227
244
  }
@@ -248,6 +265,7 @@ function buildSharePagePath(resourceType, rawId) {
248
265
  RESOURCE_SHARE_TYPES,
249
266
  RESOURCE_SHARE_TYPES_FOR_URL,
250
267
  SHARE_COMPACT_SECTION_SEPARATOR,
268
+ SHARE_DESCRIPTION_SECTION_BREAK,
251
269
  SHARE_DESCRIPTION_SECTION_SEPARATOR,
252
270
  SHARE_RESOURCE_LABEL,
253
271
  SHARE_SITE_URL,
@@ -260,6 +278,7 @@ function buildSharePagePath(resourceType, rawId) {
260
278
  buildShareUrl,
261
279
  formatCategoryLabel,
262
280
  formatShareSectionsForCompactDisplay,
281
+ formatShareSectionsForMultilineDisplay,
263
282
  isPostShareResourceType,
264
283
  isRelationShareResourceType,
265
284
  joinShareDescriptionSections,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/sharing/index.ts","../../src/sharing/formatCategoryLabel.ts","../../src/sharing/joinShareDescriptionSections.ts","../../src/sharing/buildRelationShareDescription.ts","../../src/sharing/relationShareTypes.ts","../../src/sharing/constants.ts","../../src/sharing/buildShareUrl.ts","../../src/sharing/normalizeShareDescription.ts","../../src/sharing/normalizeShareRouteId.ts"],"sourcesContent":["export * from \"./buildRelationShareDescription\";\nexport * from \"./shareRelationTypes\";\nexport * from \"./buildShareUrl\";\nexport * from \"./constants\";\nexport * from \"./formatCategoryLabel\";\nexport * from \"./joinShareDescriptionSections\";\nexport * from \"./normalizeShareDescription\";\nexport * from \"./normalizeShareRouteId\";\nexport * from \"./relationShareTypes\";\n","import type { ShareVendorCategory } from \"./shareRelationTypes\";\n\nexport function formatCategoryLabel(category: ShareVendorCategory): string {\n const subcategoryNames = category.subcategories\n .map((subcategory) => subcategory.name)\n .filter(Boolean);\n\n if (subcategoryNames.length === 0) {\n return category.name;\n }\n\n return `${category.name} (${subcategoryNames.join(\", \")})`;\n}\n","/** Visible separator for multi-block share text (OG, Facebook quote, crawlers collapse newlines). */\nexport const SHARE_DESCRIPTION_SECTION_SEPARATOR = \" · \";\n\n/** @deprecated Use {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}. */\nexport const SHARE_COMPACT_SECTION_SEPARATOR =\n SHARE_DESCRIPTION_SECTION_SEPARATOR;\n\nexport function joinShareDescriptionSections(\n sections: ReadonlyArray<string | false | null | undefined>,\n): string {\n return sections\n .filter((section): section is string => Boolean(section))\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n}\n","import { formatCategoryLabel } from \"./formatCategoryLabel\";\nimport { joinShareDescriptionSections } from \"./joinShareDescriptionSections\";\nimport type {\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nexport type {\n ShareEventDateTime,\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareStallType,\n ShareVendorCategory,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nfunction formatShareDate(isoDate: string): string {\n try {\n return new Intl.DateTimeFormat(\"en-NZ\", {\n day: \"numeric\",\n month: \"short\",\n year: \"numeric\",\n }).format(new Date(isoDate));\n } catch {\n return isoDate;\n }\n}\n\nexport function buildInvitationShareDescription(\n event: ShareEventForInvitation,\n eventInfo: ShareEventInfoForInvitation | null | undefined,\n): string {\n const stallTypes =\n eventInfo?.dateTime?.flatMap((date) => date.stallTypes) ?? [];\n\n if (!eventInfo || stallTypes.length === 0) {\n return event.description?.trim() || \"\";\n }\n\n const requirementLabels = (eventInfo.requirements ?? [])\n .filter((item) => item.value)\n .map((item) => item.label);\n\n const sections = [\n event.location.fullAddress,\n ...event.dateTime.map((date) => {\n const start = formatShareDate(date.startDate);\n const end = date.endDate ? ` – ${formatShareDate(date.endDate)}` : \"\";\n return `Market date: ${start}${end}`;\n }),\n `Application deadline: vendors must apply at least ${eventInfo.applicationDeadlineHours} hours before each market date.`,\n ...stallTypes.map(\n (stall) =>\n `Stall: ${stall.label} — $${stall.price} (${stall.stallCapacity} spaces)`,\n ),\n requirementLabels.length > 0 &&\n `Requirements: ${requirementLabels.join(\", \")}`,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n\nexport function buildApplicationShareDescription(\n vendor: ShareVendorForApplication,\n vendorInfo: ShareVendorInfoForApplication | null | undefined,\n): string {\n const categoryLabels = vendor.categories.map((category) =>\n formatCategoryLabel(category),\n );\n\n if (!vendorInfo) {\n return vendor.description?.trim() || \"\";\n }\n\n const compliance = vendorInfo.compliance;\n const complianceLabels = [\n compliance?.liabilityInsurance && \"Liability insurance\",\n compliance?.foodBeverageLicense && \"Food & beverage licence\",\n ].filter(Boolean);\n\n const profileDescription = vendor.description?.trim();\n\n const sections = [\n categoryLabels.length > 0 && `Categories: ${categoryLabels.join(\", \")}`,\n `Stall size: ${vendorInfo.stallInfo.size.width}m × ${vendorInfo.stallInfo.size.depth}m`,\n `Compliance: ${complianceLabels.length > 0 ? complianceLabels.join(\", \") : \"Not specified\"}`,\n `Price range: $${vendorInfo.product.priceRange.min} – $${vendorInfo.product.priceRange.max}`,\n profileDescription,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n","/** Path segments for relation share URLs — must match mobile `RelationTitle` values. */\nexport const RELATION_SHARE_INVITATION = \"invitation\" as const;\nexport const RELATION_SHARE_APPLICATION = \"application\" as const;\n\nexport const RELATION_SHARE_RESOURCE_TYPES = [\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_APPLICATION,\n] as const;\n\nexport type RelationShareResourceType =\n (typeof RELATION_SHARE_RESOURCE_TYPES)[number];\n\nexport function isRelationShareResourceType(\n resourceType: string,\n): resourceType is RelationShareResourceType {\n return (RELATION_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_RESOURCE_TYPES,\n isRelationShareResourceType,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport const SHARE_SITE_URL = \"https://cluemart.co.nz\";\n\nexport const DEFAULT_SHARE_OG_IMAGE = `${SHARE_SITE_URL}/assets/logo.webp`;\n\nexport const RESOURCE_SHARE_TYPES = [\n \"market\",\n \"stallholder\",\n \"partner\",\n] as const;\n\nexport type ResourceShareType = (typeof RESOURCE_SHARE_TYPES)[number];\n\nexport const POST_SHARE_RESOURCE_TYPES = [\n \"daily_meets\",\n \"daily_tips\",\n \"daily_games\",\n] as const;\n\nexport type PostShareResourceType = (typeof POST_SHARE_RESOURCE_TYPES)[number];\n\nexport type ShareResourceType =\n | ResourceShareType\n | PostShareResourceType\n | RelationShareResourceType;\n\nexport const SHARE_RESOURCE_LABEL: Record<ShareResourceType, string> = {\n [RELATION_SHARE_APPLICATION]: \"Application\",\n [RELATION_SHARE_INVITATION]: \"Invitation\",\n daily_games: \"Daily Game\",\n daily_meets: \"Daily Meet\",\n daily_tips: \"Daily Tip\",\n market: \"Market\",\n partner: \"Partner\",\n stallholder: \"Stallholder\",\n};\n\nexport function isPostShareResourceType(\n resourceType: ShareResourceType,\n): resourceType is PostShareResourceType {\n return (POST_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n POST_SHARE_RESOURCE_TYPES,\n RESOURCE_SHARE_TYPES,\n SHARE_SITE_URL,\n} from \"./constants\";\nimport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n} from \"./relationShareTypes\";\n\n/** Path segments for public resource share URLs (markets, posts, etc.). */\nexport const PUBLIC_SHARE_PATH_TYPES = [\n ...RESOURCE_SHARE_TYPES,\n ...POST_SHARE_RESOURCE_TYPES,\n] as const;\n\nexport type PublicSharePathType = (typeof PUBLIC_SHARE_PATH_TYPES)[number];\n\n/** @deprecated Use {@link PUBLIC_SHARE_PATH_TYPES} — kept for mobile deep-link helpers. */\nexport const RESOURCE_SHARE_TYPES_FOR_URL = PUBLIC_SHARE_PATH_TYPES;\n\nexport type RelationSharePathType =\n | typeof RELATION_SHARE_INVITATION\n | typeof RELATION_SHARE_APPLICATION;\n\nexport type ShareType = PublicSharePathType | RelationSharePathType;\n\n/** Alternation for deep-link regexes — keep in sync with {@link ShareType}. */\nexport const SHARE_TYPE_PATH_REGEX = [\n ...PUBLIC_SHARE_PATH_TYPES,\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n].join(\"|\");\n\nexport function buildShareUrl(type: ShareType, id: string): string {\n return `${SHARE_SITE_URL}/share/${type}/${encodeURIComponent(id)}`;\n}\n","import { SHARE_DESCRIPTION_SECTION_SEPARATOR } from \"./joinShareDescriptionSections\";\n\n/** Trims a share section and collapses spaces per line; preserves line breaks. */\nfunction normalizeShareSection(value: string | null | undefined): string {\n if (value == null) {\n return \"\";\n }\n return value\n .trim()\n .split(\"\\n\")\n .map((line) => line.trim().replace(/[ \\t]+/g, \" \"))\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\");\n}\n\n/**\n * Formats share descriptions for Open Graph / Twitter meta tags.\n * Legacy `\\n\\n` sections are joined with {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}\n * because Facebook and others collapse line breaks into spaces.\n */\nexport function normalizeShareOgDescription(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (/\\n\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n\\n+/)\n .map((section) => section.replace(/\\s+/g, \" \").trim())\n .filter(Boolean)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n return trimmed.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Formats multiline share copy for UIs that strip line breaks (Facebook SDK quote).\n */\nexport function formatShareSectionsForCompactDisplay(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {\n return normalizeShareSection(trimmed);\n }\n\n if (/\\n\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n\\n+/)\n .map((section) => normalizeShareSection(section))\n .filter((section) => section.length > 0)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n if (/\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n+/)\n .map((section) => normalizeShareSection(section))\n .filter((section) => section.length > 0)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n return normalizeShareSection(trimmed);\n}\n\n/**\n * Quote text for Facebook ShareDialog — avoids `\\n\\n` which Meta renders as a single space.\n */\nexport function buildFacebookShareQuote(\n title: string,\n description: string,\n): string | undefined {\n const titlePart = normalizeShareSection(title);\n const descriptionPart = normalizeShareSection(description);\n const bodyPart = descriptionPart\n ? formatShareSectionsForCompactDisplay(descriptionPart)\n : \"\";\n\n const parts = [titlePart, bodyPart].filter((part) => part.length > 0);\n return parts.length > 0\n ? parts.join(SHARE_DESCRIPTION_SECTION_SEPARATOR)\n : undefined;\n}\n\n/**\n * Open Graph / Twitter description — same compact section layout as\n * {@link buildFacebookShareQuote} so link previews match mobile Facebook share text.\n */\nexport function buildShareOgDescription(\n title: string,\n description: string,\n): string {\n const quote = buildFacebookShareQuote(title, description);\n if (quote) {\n return quote;\n }\n return normalizeShareOgDescription(description);\n}\n","import type { ShareResourceType } from \"./constants\";\n\nexport function normalizeShareRouteId(id: string): string {\n try {\n return decodeURIComponent(id);\n } catch {\n return id;\n }\n}\n\nexport function buildSharePagePath(\n resourceType: ShareResourceType,\n rawId: string,\n): string {\n return `/share/${resourceType}/${encodeURIComponent(normalizeShareRouteId(rawId))}`;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/sharing/index.ts","../../src/sharing/formatCategoryLabel.ts","../../src/sharing/joinShareDescriptionSections.ts","../../src/sharing/buildRelationShareDescription.ts","../../src/sharing/relationShareTypes.ts","../../src/sharing/constants.ts","../../src/sharing/buildShareUrl.ts","../../src/sharing/normalizeShareDescription.ts","../../src/sharing/normalizeShareRouteId.ts"],"sourcesContent":["export * from \"./buildRelationShareDescription\";\nexport * from \"./shareRelationTypes\";\nexport * from \"./buildShareUrl\";\nexport * from \"./constants\";\nexport * from \"./formatCategoryLabel\";\nexport * from \"./joinShareDescriptionSections\";\nexport * from \"./normalizeShareDescription\";\nexport * from \"./normalizeShareRouteId\";\nexport * from \"./relationShareTypes\";\n","import type { ShareVendorCategory } from \"./shareRelationTypes\";\n\nexport function formatCategoryLabel(category: ShareVendorCategory): string {\n const subcategoryNames = category.subcategories\n .map((subcategory) => subcategory.name)\n .filter(Boolean);\n\n if (subcategoryNames.length === 0) {\n return category.name;\n }\n\n return `${category.name} (${subcategoryNames.join(\", \")})`;\n}\n","/** Visible separator for multi-block share text when line breaks are stripped (legacy OG). */\nexport const SHARE_DESCRIPTION_SECTION_SEPARATOR = \" · \";\n\n/** Blank line between share sections — title, address, dates, URL, etc. */\nexport const SHARE_DESCRIPTION_SECTION_BREAK = \"\\n\\n\";\n\n/** @deprecated Use {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}. */\nexport const SHARE_COMPACT_SECTION_SEPARATOR =\n SHARE_DESCRIPTION_SECTION_SEPARATOR;\n\nexport function joinShareDescriptionSections(\n sections: ReadonlyArray<string | false | null | undefined>,\n): string {\n return sections\n .filter((section): section is string => Boolean(section))\n .join(SHARE_DESCRIPTION_SECTION_BREAK);\n}\n","import { formatCategoryLabel } from \"./formatCategoryLabel\";\nimport { joinShareDescriptionSections } from \"./joinShareDescriptionSections\";\nimport type {\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nexport type {\n ShareEventDateTime,\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareStallType,\n ShareVendorCategory,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nfunction formatShareDate(isoDate: string): string {\n try {\n return new Intl.DateTimeFormat(\"en-NZ\", {\n day: \"numeric\",\n month: \"short\",\n year: \"numeric\",\n }).format(new Date(isoDate));\n } catch {\n return isoDate;\n }\n}\n\nexport function buildInvitationShareDescription(\n event: ShareEventForInvitation,\n eventInfo: ShareEventInfoForInvitation | null | undefined,\n): string {\n const stallTypes =\n eventInfo?.dateTime?.flatMap((date) => date.stallTypes) ?? [];\n\n if (!eventInfo || stallTypes.length === 0) {\n return event.description?.trim() || \"\";\n }\n\n const requirementLabels = (eventInfo.requirements ?? [])\n .filter((item) => item.value)\n .map((item) => item.label);\n\n const sections = [\n event.location.fullAddress,\n ...event.dateTime.map((date) => {\n const start = formatShareDate(date.startDate);\n const end = date.endDate ? ` – ${formatShareDate(date.endDate)}` : \"\";\n return `Market date: ${start}${end}`;\n }),\n `Application deadline: vendors must apply at least ${eventInfo.applicationDeadlineHours} hours before each market date.`,\n ...stallTypes.map(\n (stall) =>\n `Stall: ${stall.label} — $${stall.price} (${stall.stallCapacity} spaces)`,\n ),\n requirementLabels.length > 0 &&\n `Requirements: ${requirementLabels.join(\", \")}`,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n\nexport function buildApplicationShareDescription(\n vendor: ShareVendorForApplication,\n vendorInfo: ShareVendorInfoForApplication | null | undefined,\n): string {\n const categoryLabels = vendor.categories.map((category) =>\n formatCategoryLabel(category),\n );\n\n if (!vendorInfo) {\n return vendor.description?.trim() || \"\";\n }\n\n const compliance = vendorInfo.compliance;\n const complianceLabels = [\n compliance?.liabilityInsurance && \"Liability insurance\",\n compliance?.foodBeverageLicense && \"Food & beverage licence\",\n ].filter(Boolean);\n\n const profileDescription = vendor.description?.trim();\n\n const sections = [\n categoryLabels.length > 0 && `Categories: ${categoryLabels.join(\", \")}`,\n `Stall size: ${vendorInfo.stallInfo.size.width}m × ${vendorInfo.stallInfo.size.depth}m`,\n `Compliance: ${complianceLabels.length > 0 ? complianceLabels.join(\", \") : \"Not specified\"}`,\n `Price range: $${vendorInfo.product.priceRange.min} – $${vendorInfo.product.priceRange.max}`,\n profileDescription,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n","/** Path segments for relation share URLs — must match mobile `RelationTitle` values. */\nexport const RELATION_SHARE_INVITATION = \"invitation\" as const;\nexport const RELATION_SHARE_APPLICATION = \"application\" as const;\n\nexport const RELATION_SHARE_RESOURCE_TYPES = [\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_APPLICATION,\n] as const;\n\nexport type RelationShareResourceType =\n (typeof RELATION_SHARE_RESOURCE_TYPES)[number];\n\nexport function isRelationShareResourceType(\n resourceType: string,\n): resourceType is RelationShareResourceType {\n return (RELATION_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_RESOURCE_TYPES,\n isRelationShareResourceType,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport const SHARE_SITE_URL = \"https://cluemart.co.nz\";\n\nexport const DEFAULT_SHARE_OG_IMAGE = `${SHARE_SITE_URL}/assets/logo.webp`;\n\nexport const RESOURCE_SHARE_TYPES = [\n \"market\",\n \"stallholder\",\n \"partner\",\n] as const;\n\nexport type ResourceShareType = (typeof RESOURCE_SHARE_TYPES)[number];\n\nexport const POST_SHARE_RESOURCE_TYPES = [\n \"daily_meets\",\n \"daily_tips\",\n \"daily_games\",\n] as const;\n\nexport type PostShareResourceType = (typeof POST_SHARE_RESOURCE_TYPES)[number];\n\nexport type ShareResourceType =\n | ResourceShareType\n | PostShareResourceType\n | RelationShareResourceType;\n\nexport const SHARE_RESOURCE_LABEL: Record<ShareResourceType, string> = {\n [RELATION_SHARE_APPLICATION]: \"Application\",\n [RELATION_SHARE_INVITATION]: \"Invitation\",\n daily_games: \"Daily Game\",\n daily_meets: \"Daily Meet\",\n daily_tips: \"Daily Tip\",\n market: \"Market\",\n partner: \"Partner\",\n stallholder: \"Stallholder\",\n};\n\nexport function isPostShareResourceType(\n resourceType: ShareResourceType,\n): resourceType is PostShareResourceType {\n return (POST_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n POST_SHARE_RESOURCE_TYPES,\n RESOURCE_SHARE_TYPES,\n SHARE_SITE_URL,\n} from \"./constants\";\nimport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n} from \"./relationShareTypes\";\n\n/** Path segments for public resource share URLs (markets, posts, etc.). */\nexport const PUBLIC_SHARE_PATH_TYPES = [\n ...RESOURCE_SHARE_TYPES,\n ...POST_SHARE_RESOURCE_TYPES,\n] as const;\n\nexport type PublicSharePathType = (typeof PUBLIC_SHARE_PATH_TYPES)[number];\n\n/** @deprecated Use {@link PUBLIC_SHARE_PATH_TYPES} — kept for mobile deep-link helpers. */\nexport const RESOURCE_SHARE_TYPES_FOR_URL = PUBLIC_SHARE_PATH_TYPES;\n\nexport type RelationSharePathType =\n | typeof RELATION_SHARE_INVITATION\n | typeof RELATION_SHARE_APPLICATION;\n\nexport type ShareType = PublicSharePathType | RelationSharePathType;\n\n/** Alternation for deep-link regexes — keep in sync with {@link ShareType}. */\nexport const SHARE_TYPE_PATH_REGEX = [\n ...PUBLIC_SHARE_PATH_TYPES,\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n].join(\"|\");\n\nexport function buildShareUrl(type: ShareType, id: string): string {\n return `${SHARE_SITE_URL}/share/${type}/${encodeURIComponent(id)}`;\n}\n","import {\n SHARE_DESCRIPTION_SECTION_BREAK,\n SHARE_DESCRIPTION_SECTION_SEPARATOR,\n} from \"./joinShareDescriptionSections\";\n\nconst LEGACY_BULLET_PREFIX = \"• \";\n\n/** Trims a share section and collapses spaces per line; preserves line breaks. */\nfunction normalizeShareSection(value: string | null | undefined): string {\n if (value == null) {\n return \"\";\n }\n return value\n .trim()\n .split(\"\\n\")\n .map((line) => line.trim().replace(/[ \\t]+/g, \" \"))\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\");\n}\n\nfunction stripLegacyBulletPrefix(section: string): string {\n return section.startsWith(LEGACY_BULLET_PREFIX)\n ? section.slice(LEGACY_BULLET_PREFIX.length)\n : section;\n}\n\nfunction splitShareDescriptionSections(value: string): string[] {\n const trimmed = value.trim();\n if (!trimmed) {\n return [];\n }\n\n if (trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {\n return trimmed\n .split(SHARE_DESCRIPTION_SECTION_SEPARATOR)\n .map((section) => stripLegacyBulletPrefix(normalizeShareSection(section)))\n .filter((section) => section.length > 0);\n }\n\n if (/\\n\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n\\n+/)\n .map((section) => stripLegacyBulletPrefix(normalizeShareSection(section)))\n .filter((section) => section.length > 0);\n }\n\n if (/\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n+/)\n .map((section) => stripLegacyBulletPrefix(normalizeShareSection(section)))\n .filter((section) => section.length > 0);\n }\n\n return [stripLegacyBulletPrefix(normalizeShareSection(trimmed))];\n}\n\nfunction collapseExcessiveBlankLines(value: string): string {\n return value.replace(/\\n{4,}/g, \"\\n\\n\\n\").trim();\n}\n\n/**\n * Share copy with a blank line between each section (all apps, Facebook quote, OG body).\n */\nexport function formatShareSectionsForMultilineDisplay(value: string): string {\n return collapseExcessiveBlankLines(\n splitShareDescriptionSections(value).join(SHARE_DESCRIPTION_SECTION_BREAK),\n );\n}\n\n/**\n * Formats multiline share copy for UIs that strip line breaks (legacy OG one-liners).\n */\nexport function formatShareSectionsForCompactDisplay(value: string): string {\n return splitShareDescriptionSections(value).join(\n SHARE_DESCRIPTION_SECTION_SEPARATOR,\n );\n}\n\n/**\n * Formats share descriptions for Open Graph / Twitter meta tags when crawlers\n * collapse line breaks.\n */\nexport function normalizeShareOgDescription(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (/\\n\\n/.test(trimmed) || trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {\n return formatShareSectionsForCompactDisplay(trimmed);\n }\n\n return trimmed.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Quote text for Facebook ShareDialog. Body only — the link card shows the title.\n */\nexport function buildFacebookShareQuote(\n _title: string,\n description: string,\n): string | undefined {\n const body = formatShareSectionsForMultilineDisplay(description);\n return body.length > 0 ? body : undefined;\n}\n\n/**\n * Open Graph / Twitter description — multiline body without repeating `og:title`.\n */\nexport function buildShareOgDescription(\n _title: string,\n description: string,\n): string {\n const multiline = formatShareSectionsForMultilineDisplay(description);\n if (multiline) {\n return multiline;\n }\n return normalizeShareOgDescription(description);\n}\n","import type { ShareResourceType } from \"./constants\";\n\nexport function normalizeShareRouteId(id: string): string {\n try {\n return decodeURIComponent(id);\n } catch {\n return id;\n }\n}\n\nexport function buildSharePagePath(\n resourceType: ShareResourceType,\n rawId: string,\n): string {\n return `/share/${resourceType}/${encodeURIComponent(normalizeShareRouteId(rawId))}`;\n}\n"],"mappings":"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","names":[]}
@@ -90,33 +90,37 @@ declare function isPostShareResourceType(resourceType: ShareResourceType): resou
90
90
 
91
91
  declare function formatCategoryLabel(category: ShareVendorCategory): string;
92
92
 
93
- /** Visible separator for multi-block share text (OG, Facebook quote, crawlers collapse newlines). */
93
+ /** Visible separator for multi-block share text when line breaks are stripped (legacy OG). */
94
94
  declare const SHARE_DESCRIPTION_SECTION_SEPARATOR = " \u00B7 ";
95
+ /** Blank line between share sections — title, address, dates, URL, etc. */
96
+ declare const SHARE_DESCRIPTION_SECTION_BREAK = "\n\n";
95
97
  /** @deprecated Use {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}. */
96
98
  declare const SHARE_COMPACT_SECTION_SEPARATOR = " \u00B7 ";
97
99
  declare function joinShareDescriptionSections(sections: ReadonlyArray<string | false | null | undefined>): string;
98
100
 
99
101
  /**
100
- * Formats share descriptions for Open Graph / Twitter meta tags.
101
- * Legacy `\n\n` sections are joined with {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}
102
- * because Facebook and others collapse line breaks into spaces.
102
+ * Share copy with a blank line between each section (all apps, Facebook quote, OG body).
103
103
  */
104
- declare function normalizeShareOgDescription(value: string): string;
104
+ declare function formatShareSectionsForMultilineDisplay(value: string): string;
105
105
  /**
106
- * Formats multiline share copy for UIs that strip line breaks (Facebook SDK quote).
106
+ * Formats multiline share copy for UIs that strip line breaks (legacy OG one-liners).
107
107
  */
108
108
  declare function formatShareSectionsForCompactDisplay(value: string): string;
109
109
  /**
110
- * Quote text for Facebook ShareDialog avoids `\n\n` which Meta renders as a single space.
110
+ * Formats share descriptions for Open Graph / Twitter meta tags when crawlers
111
+ * collapse line breaks.
112
+ */
113
+ declare function normalizeShareOgDescription(value: string): string;
114
+ /**
115
+ * Quote text for Facebook ShareDialog. Body only — the link card shows the title.
111
116
  */
112
- declare function buildFacebookShareQuote(title: string, description: string): string | undefined;
117
+ declare function buildFacebookShareQuote(_title: string, description: string): string | undefined;
113
118
  /**
114
- * Open Graph / Twitter description — same compact section layout as
115
- * {@link buildFacebookShareQuote} so link previews match mobile Facebook share text.
119
+ * Open Graph / Twitter description — multiline body without repeating `og:title`.
116
120
  */
117
- declare function buildShareOgDescription(title: string, description: string): string;
121
+ declare function buildShareOgDescription(_title: string, description: string): string;
118
122
 
119
123
  declare function normalizeShareRouteId(id: string): string;
120
124
  declare function buildSharePagePath(resourceType: ShareResourceType, rawId: string): string;
121
125
 
122
- export { DEFAULT_SHARE_OG_IMAGE, POST_SHARE_RESOURCE_TYPES, PUBLIC_SHARE_PATH_TYPES, type PostShareResourceType, type PublicSharePathType, RELATION_SHARE_APPLICATION, RELATION_SHARE_INVITATION, RELATION_SHARE_RESOURCE_TYPES, RESOURCE_SHARE_TYPES, RESOURCE_SHARE_TYPES_FOR_URL, type RelationSharePathType, type RelationShareResourceType, type ResourceShareType, SHARE_COMPACT_SECTION_SEPARATOR, SHARE_DESCRIPTION_SECTION_SEPARATOR, SHARE_RESOURCE_LABEL, SHARE_SITE_URL, SHARE_TYPE_PATH_REGEX, type ShareEventDateTime, type ShareEventForInvitation, type ShareEventInfoForInvitation, type ShareResourceType, type ShareStallType, type ShareType, type ShareVendorCategory, type ShareVendorForApplication, type ShareVendorInfoForApplication, buildApplicationShareDescription, buildFacebookShareQuote, buildInvitationShareDescription, buildShareOgDescription, buildSharePagePath, buildShareUrl, formatCategoryLabel, formatShareSectionsForCompactDisplay, isPostShareResourceType, isRelationShareResourceType, joinShareDescriptionSections, normalizeShareOgDescription, normalizeShareRouteId };
126
+ export { DEFAULT_SHARE_OG_IMAGE, POST_SHARE_RESOURCE_TYPES, PUBLIC_SHARE_PATH_TYPES, type PostShareResourceType, type PublicSharePathType, RELATION_SHARE_APPLICATION, RELATION_SHARE_INVITATION, RELATION_SHARE_RESOURCE_TYPES, RESOURCE_SHARE_TYPES, RESOURCE_SHARE_TYPES_FOR_URL, type RelationSharePathType, type RelationShareResourceType, type ResourceShareType, SHARE_COMPACT_SECTION_SEPARATOR, SHARE_DESCRIPTION_SECTION_BREAK, SHARE_DESCRIPTION_SECTION_SEPARATOR, SHARE_RESOURCE_LABEL, SHARE_SITE_URL, SHARE_TYPE_PATH_REGEX, type ShareEventDateTime, type ShareEventForInvitation, type ShareEventInfoForInvitation, type ShareResourceType, type ShareStallType, type ShareType, type ShareVendorCategory, type ShareVendorForApplication, type ShareVendorInfoForApplication, buildApplicationShareDescription, buildFacebookShareQuote, buildInvitationShareDescription, buildShareOgDescription, buildSharePagePath, buildShareUrl, formatCategoryLabel, formatShareSectionsForCompactDisplay, formatShareSectionsForMultilineDisplay, isPostShareResourceType, isRelationShareResourceType, joinShareDescriptionSections, normalizeShareOgDescription, normalizeShareRouteId };
@@ -90,33 +90,37 @@ declare function isPostShareResourceType(resourceType: ShareResourceType): resou
90
90
 
91
91
  declare function formatCategoryLabel(category: ShareVendorCategory): string;
92
92
 
93
- /** Visible separator for multi-block share text (OG, Facebook quote, crawlers collapse newlines). */
93
+ /** Visible separator for multi-block share text when line breaks are stripped (legacy OG). */
94
94
  declare const SHARE_DESCRIPTION_SECTION_SEPARATOR = " \u00B7 ";
95
+ /** Blank line between share sections — title, address, dates, URL, etc. */
96
+ declare const SHARE_DESCRIPTION_SECTION_BREAK = "\n\n";
95
97
  /** @deprecated Use {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}. */
96
98
  declare const SHARE_COMPACT_SECTION_SEPARATOR = " \u00B7 ";
97
99
  declare function joinShareDescriptionSections(sections: ReadonlyArray<string | false | null | undefined>): string;
98
100
 
99
101
  /**
100
- * Formats share descriptions for Open Graph / Twitter meta tags.
101
- * Legacy `\n\n` sections are joined with {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}
102
- * because Facebook and others collapse line breaks into spaces.
102
+ * Share copy with a blank line between each section (all apps, Facebook quote, OG body).
103
103
  */
104
- declare function normalizeShareOgDescription(value: string): string;
104
+ declare function formatShareSectionsForMultilineDisplay(value: string): string;
105
105
  /**
106
- * Formats multiline share copy for UIs that strip line breaks (Facebook SDK quote).
106
+ * Formats multiline share copy for UIs that strip line breaks (legacy OG one-liners).
107
107
  */
108
108
  declare function formatShareSectionsForCompactDisplay(value: string): string;
109
109
  /**
110
- * Quote text for Facebook ShareDialog avoids `\n\n` which Meta renders as a single space.
110
+ * Formats share descriptions for Open Graph / Twitter meta tags when crawlers
111
+ * collapse line breaks.
112
+ */
113
+ declare function normalizeShareOgDescription(value: string): string;
114
+ /**
115
+ * Quote text for Facebook ShareDialog. Body only — the link card shows the title.
111
116
  */
112
- declare function buildFacebookShareQuote(title: string, description: string): string | undefined;
117
+ declare function buildFacebookShareQuote(_title: string, description: string): string | undefined;
113
118
  /**
114
- * Open Graph / Twitter description — same compact section layout as
115
- * {@link buildFacebookShareQuote} so link previews match mobile Facebook share text.
119
+ * Open Graph / Twitter description — multiline body without repeating `og:title`.
116
120
  */
117
- declare function buildShareOgDescription(title: string, description: string): string;
121
+ declare function buildShareOgDescription(_title: string, description: string): string;
118
122
 
119
123
  declare function normalizeShareRouteId(id: string): string;
120
124
  declare function buildSharePagePath(resourceType: ShareResourceType, rawId: string): string;
121
125
 
122
- export { DEFAULT_SHARE_OG_IMAGE, POST_SHARE_RESOURCE_TYPES, PUBLIC_SHARE_PATH_TYPES, type PostShareResourceType, type PublicSharePathType, RELATION_SHARE_APPLICATION, RELATION_SHARE_INVITATION, RELATION_SHARE_RESOURCE_TYPES, RESOURCE_SHARE_TYPES, RESOURCE_SHARE_TYPES_FOR_URL, type RelationSharePathType, type RelationShareResourceType, type ResourceShareType, SHARE_COMPACT_SECTION_SEPARATOR, SHARE_DESCRIPTION_SECTION_SEPARATOR, SHARE_RESOURCE_LABEL, SHARE_SITE_URL, SHARE_TYPE_PATH_REGEX, type ShareEventDateTime, type ShareEventForInvitation, type ShareEventInfoForInvitation, type ShareResourceType, type ShareStallType, type ShareType, type ShareVendorCategory, type ShareVendorForApplication, type ShareVendorInfoForApplication, buildApplicationShareDescription, buildFacebookShareQuote, buildInvitationShareDescription, buildShareOgDescription, buildSharePagePath, buildShareUrl, formatCategoryLabel, formatShareSectionsForCompactDisplay, isPostShareResourceType, isRelationShareResourceType, joinShareDescriptionSections, normalizeShareOgDescription, normalizeShareRouteId };
126
+ export { DEFAULT_SHARE_OG_IMAGE, POST_SHARE_RESOURCE_TYPES, PUBLIC_SHARE_PATH_TYPES, type PostShareResourceType, type PublicSharePathType, RELATION_SHARE_APPLICATION, RELATION_SHARE_INVITATION, RELATION_SHARE_RESOURCE_TYPES, RESOURCE_SHARE_TYPES, RESOURCE_SHARE_TYPES_FOR_URL, type RelationSharePathType, type RelationShareResourceType, type ResourceShareType, SHARE_COMPACT_SECTION_SEPARATOR, SHARE_DESCRIPTION_SECTION_BREAK, SHARE_DESCRIPTION_SECTION_SEPARATOR, SHARE_RESOURCE_LABEL, SHARE_SITE_URL, SHARE_TYPE_PATH_REGEX, type ShareEventDateTime, type ShareEventForInvitation, type ShareEventInfoForInvitation, type ShareResourceType, type ShareStallType, type ShareType, type ShareVendorCategory, type ShareVendorForApplication, type ShareVendorInfoForApplication, buildApplicationShareDescription, buildFacebookShareQuote, buildInvitationShareDescription, buildShareOgDescription, buildSharePagePath, buildShareUrl, formatCategoryLabel, formatShareSectionsForCompactDisplay, formatShareSectionsForMultilineDisplay, isPostShareResourceType, isRelationShareResourceType, joinShareDescriptionSections, normalizeShareOgDescription, normalizeShareRouteId };
@@ -8,6 +8,7 @@ import {
8
8
  RESOURCE_SHARE_TYPES,
9
9
  RESOURCE_SHARE_TYPES_FOR_URL,
10
10
  SHARE_COMPACT_SECTION_SEPARATOR,
11
+ SHARE_DESCRIPTION_SECTION_BREAK,
11
12
  SHARE_DESCRIPTION_SECTION_SEPARATOR,
12
13
  SHARE_RESOURCE_LABEL,
13
14
  SHARE_SITE_URL,
@@ -20,12 +21,13 @@ import {
20
21
  buildShareUrl,
21
22
  formatCategoryLabel,
22
23
  formatShareSectionsForCompactDisplay,
24
+ formatShareSectionsForMultilineDisplay,
23
25
  isPostShareResourceType,
24
26
  isRelationShareResourceType,
25
27
  joinShareDescriptionSections,
26
28
  normalizeShareOgDescription,
27
29
  normalizeShareRouteId
28
- } from "../chunk-EHSQWIQV.mjs";
30
+ } from "../chunk-S7M7375H.mjs";
29
31
  export {
30
32
  DEFAULT_SHARE_OG_IMAGE,
31
33
  POST_SHARE_RESOURCE_TYPES,
@@ -36,6 +38,7 @@ export {
36
38
  RESOURCE_SHARE_TYPES,
37
39
  RESOURCE_SHARE_TYPES_FOR_URL,
38
40
  SHARE_COMPACT_SECTION_SEPARATOR,
41
+ SHARE_DESCRIPTION_SECTION_BREAK,
39
42
  SHARE_DESCRIPTION_SECTION_SEPARATOR,
40
43
  SHARE_RESOURCE_LABEL,
41
44
  SHARE_SITE_URL,
@@ -48,6 +51,7 @@ export {
48
51
  buildShareUrl,
49
52
  formatCategoryLabel,
50
53
  formatShareSectionsForCompactDisplay,
54
+ formatShareSectionsForMultilineDisplay,
51
55
  isPostShareResourceType,
52
56
  isRelationShareResourceType,
53
57
  joinShareDescriptionSections,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timardex/cluemart-shared",
3
- "version": "1.5.591",
3
+ "version": "1.5.595",
4
4
  "description": "",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/sharing/formatCategoryLabel.ts","../src/sharing/joinShareDescriptionSections.ts","../src/sharing/buildRelationShareDescription.ts","../src/sharing/relationShareTypes.ts","../src/sharing/constants.ts","../src/sharing/buildShareUrl.ts","../src/sharing/normalizeShareDescription.ts","../src/sharing/normalizeShareRouteId.ts"],"sourcesContent":["import type { ShareVendorCategory } from \"./shareRelationTypes\";\n\nexport function formatCategoryLabel(category: ShareVendorCategory): string {\n const subcategoryNames = category.subcategories\n .map((subcategory) => subcategory.name)\n .filter(Boolean);\n\n if (subcategoryNames.length === 0) {\n return category.name;\n }\n\n return `${category.name} (${subcategoryNames.join(\", \")})`;\n}\n","/** Visible separator for multi-block share text (OG, Facebook quote, crawlers collapse newlines). */\nexport const SHARE_DESCRIPTION_SECTION_SEPARATOR = \" · \";\n\n/** @deprecated Use {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}. */\nexport const SHARE_COMPACT_SECTION_SEPARATOR =\n SHARE_DESCRIPTION_SECTION_SEPARATOR;\n\nexport function joinShareDescriptionSections(\n sections: ReadonlyArray<string | false | null | undefined>,\n): string {\n return sections\n .filter((section): section is string => Boolean(section))\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n}\n","import { formatCategoryLabel } from \"./formatCategoryLabel\";\nimport { joinShareDescriptionSections } from \"./joinShareDescriptionSections\";\nimport type {\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nexport type {\n ShareEventDateTime,\n ShareEventForInvitation,\n ShareEventInfoForInvitation,\n ShareStallType,\n ShareVendorCategory,\n ShareVendorForApplication,\n ShareVendorInfoForApplication,\n} from \"./shareRelationTypes\";\n\nfunction formatShareDate(isoDate: string): string {\n try {\n return new Intl.DateTimeFormat(\"en-NZ\", {\n day: \"numeric\",\n month: \"short\",\n year: \"numeric\",\n }).format(new Date(isoDate));\n } catch {\n return isoDate;\n }\n}\n\nexport function buildInvitationShareDescription(\n event: ShareEventForInvitation,\n eventInfo: ShareEventInfoForInvitation | null | undefined,\n): string {\n const stallTypes =\n eventInfo?.dateTime?.flatMap((date) => date.stallTypes) ?? [];\n\n if (!eventInfo || stallTypes.length === 0) {\n return event.description?.trim() || \"\";\n }\n\n const requirementLabels = (eventInfo.requirements ?? [])\n .filter((item) => item.value)\n .map((item) => item.label);\n\n const sections = [\n event.location.fullAddress,\n ...event.dateTime.map((date) => {\n const start = formatShareDate(date.startDate);\n const end = date.endDate ? ` – ${formatShareDate(date.endDate)}` : \"\";\n return `Market date: ${start}${end}`;\n }),\n `Application deadline: vendors must apply at least ${eventInfo.applicationDeadlineHours} hours before each market date.`,\n ...stallTypes.map(\n (stall) =>\n `Stall: ${stall.label} — $${stall.price} (${stall.stallCapacity} spaces)`,\n ),\n requirementLabels.length > 0 &&\n `Requirements: ${requirementLabels.join(\", \")}`,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n\nexport function buildApplicationShareDescription(\n vendor: ShareVendorForApplication,\n vendorInfo: ShareVendorInfoForApplication | null | undefined,\n): string {\n const categoryLabels = vendor.categories.map((category) =>\n formatCategoryLabel(category),\n );\n\n if (!vendorInfo) {\n return vendor.description?.trim() || \"\";\n }\n\n const compliance = vendorInfo.compliance;\n const complianceLabels = [\n compliance?.liabilityInsurance && \"Liability insurance\",\n compliance?.foodBeverageLicense && \"Food & beverage licence\",\n ].filter(Boolean);\n\n const profileDescription = vendor.description?.trim();\n\n const sections = [\n categoryLabels.length > 0 && `Categories: ${categoryLabels.join(\", \")}`,\n `Stall size: ${vendorInfo.stallInfo.size.width}m × ${vendorInfo.stallInfo.size.depth}m`,\n `Compliance: ${complianceLabels.length > 0 ? complianceLabels.join(\", \") : \"Not specified\"}`,\n `Price range: $${vendorInfo.product.priceRange.min} – $${vendorInfo.product.priceRange.max}`,\n profileDescription,\n ];\n\n return joinShareDescriptionSections(sections);\n}\n","/** Path segments for relation share URLs — must match mobile `RelationTitle` values. */\nexport const RELATION_SHARE_INVITATION = \"invitation\" as const;\nexport const RELATION_SHARE_APPLICATION = \"application\" as const;\n\nexport const RELATION_SHARE_RESOURCE_TYPES = [\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_APPLICATION,\n] as const;\n\nexport type RelationShareResourceType =\n (typeof RELATION_SHARE_RESOURCE_TYPES)[number];\n\nexport function isRelationShareResourceType(\n resourceType: string,\n): resourceType is RelationShareResourceType {\n return (RELATION_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n RELATION_SHARE_RESOURCE_TYPES,\n isRelationShareResourceType,\n type RelationShareResourceType,\n} from \"./relationShareTypes\";\n\nexport const SHARE_SITE_URL = \"https://cluemart.co.nz\";\n\nexport const DEFAULT_SHARE_OG_IMAGE = `${SHARE_SITE_URL}/assets/logo.webp`;\n\nexport const RESOURCE_SHARE_TYPES = [\n \"market\",\n \"stallholder\",\n \"partner\",\n] as const;\n\nexport type ResourceShareType = (typeof RESOURCE_SHARE_TYPES)[number];\n\nexport const POST_SHARE_RESOURCE_TYPES = [\n \"daily_meets\",\n \"daily_tips\",\n \"daily_games\",\n] as const;\n\nexport type PostShareResourceType = (typeof POST_SHARE_RESOURCE_TYPES)[number];\n\nexport type ShareResourceType =\n | ResourceShareType\n | PostShareResourceType\n | RelationShareResourceType;\n\nexport const SHARE_RESOURCE_LABEL: Record<ShareResourceType, string> = {\n [RELATION_SHARE_APPLICATION]: \"Application\",\n [RELATION_SHARE_INVITATION]: \"Invitation\",\n daily_games: \"Daily Game\",\n daily_meets: \"Daily Meet\",\n daily_tips: \"Daily Tip\",\n market: \"Market\",\n partner: \"Partner\",\n stallholder: \"Stallholder\",\n};\n\nexport function isPostShareResourceType(\n resourceType: ShareResourceType,\n): resourceType is PostShareResourceType {\n return (POST_SHARE_RESOURCE_TYPES as readonly string[]).includes(\n resourceType,\n );\n}\n","import {\n POST_SHARE_RESOURCE_TYPES,\n RESOURCE_SHARE_TYPES,\n SHARE_SITE_URL,\n} from \"./constants\";\nimport {\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n} from \"./relationShareTypes\";\n\n/** Path segments for public resource share URLs (markets, posts, etc.). */\nexport const PUBLIC_SHARE_PATH_TYPES = [\n ...RESOURCE_SHARE_TYPES,\n ...POST_SHARE_RESOURCE_TYPES,\n] as const;\n\nexport type PublicSharePathType = (typeof PUBLIC_SHARE_PATH_TYPES)[number];\n\n/** @deprecated Use {@link PUBLIC_SHARE_PATH_TYPES} — kept for mobile deep-link helpers. */\nexport const RESOURCE_SHARE_TYPES_FOR_URL = PUBLIC_SHARE_PATH_TYPES;\n\nexport type RelationSharePathType =\n | typeof RELATION_SHARE_INVITATION\n | typeof RELATION_SHARE_APPLICATION;\n\nexport type ShareType = PublicSharePathType | RelationSharePathType;\n\n/** Alternation for deep-link regexes — keep in sync with {@link ShareType}. */\nexport const SHARE_TYPE_PATH_REGEX = [\n ...PUBLIC_SHARE_PATH_TYPES,\n RELATION_SHARE_APPLICATION,\n RELATION_SHARE_INVITATION,\n].join(\"|\");\n\nexport function buildShareUrl(type: ShareType, id: string): string {\n return `${SHARE_SITE_URL}/share/${type}/${encodeURIComponent(id)}`;\n}\n","import { SHARE_DESCRIPTION_SECTION_SEPARATOR } from \"./joinShareDescriptionSections\";\n\n/** Trims a share section and collapses spaces per line; preserves line breaks. */\nfunction normalizeShareSection(value: string | null | undefined): string {\n if (value == null) {\n return \"\";\n }\n return value\n .trim()\n .split(\"\\n\")\n .map((line) => line.trim().replace(/[ \\t]+/g, \" \"))\n .join(\"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\");\n}\n\n/**\n * Formats share descriptions for Open Graph / Twitter meta tags.\n * Legacy `\\n\\n` sections are joined with {@link SHARE_DESCRIPTION_SECTION_SEPARATOR}\n * because Facebook and others collapse line breaks into spaces.\n */\nexport function normalizeShareOgDescription(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (/\\n\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n\\n+/)\n .map((section) => section.replace(/\\s+/g, \" \").trim())\n .filter(Boolean)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n return trimmed.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Formats multiline share copy for UIs that strip line breaks (Facebook SDK quote).\n */\nexport function formatShareSectionsForCompactDisplay(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n return \"\";\n }\n\n if (trimmed.includes(SHARE_DESCRIPTION_SECTION_SEPARATOR)) {\n return normalizeShareSection(trimmed);\n }\n\n if (/\\n\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n\\n+/)\n .map((section) => normalizeShareSection(section))\n .filter((section) => section.length > 0)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n if (/\\n/.test(trimmed)) {\n return trimmed\n .split(/\\n+/)\n .map((section) => normalizeShareSection(section))\n .filter((section) => section.length > 0)\n .join(SHARE_DESCRIPTION_SECTION_SEPARATOR);\n }\n\n return normalizeShareSection(trimmed);\n}\n\n/**\n * Quote text for Facebook ShareDialog — avoids `\\n\\n` which Meta renders as a single space.\n */\nexport function buildFacebookShareQuote(\n title: string,\n description: string,\n): string | undefined {\n const titlePart = normalizeShareSection(title);\n const descriptionPart = normalizeShareSection(description);\n const bodyPart = descriptionPart\n ? formatShareSectionsForCompactDisplay(descriptionPart)\n : \"\";\n\n const parts = [titlePart, bodyPart].filter((part) => part.length > 0);\n return parts.length > 0\n ? parts.join(SHARE_DESCRIPTION_SECTION_SEPARATOR)\n : undefined;\n}\n\n/**\n * Open Graph / Twitter description — same compact section layout as\n * {@link buildFacebookShareQuote} so link previews match mobile Facebook share text.\n */\nexport function buildShareOgDescription(\n title: string,\n description: string,\n): string {\n const quote = buildFacebookShareQuote(title, description);\n if (quote) {\n return quote;\n }\n return normalizeShareOgDescription(description);\n}\n","import type { ShareResourceType } from \"./constants\";\n\nexport function normalizeShareRouteId(id: string): string {\n try {\n return decodeURIComponent(id);\n } catch {\n return id;\n }\n}\n\nexport function buildSharePagePath(\n resourceType: ShareResourceType,\n rawId: string,\n): string {\n return `/share/${resourceType}/${encodeURIComponent(normalizeShareRouteId(rawId))}`;\n}\n"],"mappings":"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","names":[]}