@flamingo-stack/openframe-frontend-core 0.0.234 → 0.0.235-snapshot.20260609090033

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/dist/{chunk-Z46NRJWW.js → chunk-265KKBV2.js} +2 -2
  2. package/dist/{chunk-BOF5MSRY.js → chunk-2LEMRJ7Z.js} +3 -3
  3. package/dist/{chunk-EO3RG6II.cjs → chunk-7SOVT7RJ.cjs} +16 -16
  4. package/dist/{chunk-EO3RG6II.cjs.map → chunk-7SOVT7RJ.cjs.map} +1 -1
  5. package/dist/{chunk-YZDUOUMB.js → chunk-AGU44B7B.js} +2 -2
  6. package/dist/{chunk-DHCGJW3G.js → chunk-AZGRKZJ7.js} +10 -6
  7. package/dist/chunk-AZGRKZJ7.js.map +1 -0
  8. package/dist/{chunk-W7P7RH2X.cjs → chunk-BXMMMSIK.cjs} +1278 -1274
  9. package/dist/chunk-BXMMMSIK.cjs.map +1 -0
  10. package/dist/{chunk-IBSZ27Y7.cjs → chunk-E3VQ53IM.cjs} +7 -7
  11. package/dist/{chunk-IBSZ27Y7.cjs.map → chunk-E3VQ53IM.cjs.map} +1 -1
  12. package/dist/chunk-FIG2RKZF.cjs +169 -0
  13. package/dist/chunk-FIG2RKZF.cjs.map +1 -0
  14. package/dist/{chunk-E6B4B7GM.cjs → chunk-GRTZ23GL.cjs} +49 -49
  15. package/dist/{chunk-E6B4B7GM.cjs.map → chunk-GRTZ23GL.cjs.map} +1 -1
  16. package/dist/{chunk-F6F525T7.js → chunk-HGYOMQM3.js} +2 -2
  17. package/dist/{chunk-GSD52WAS.js → chunk-JNXFCV7K.js} +4 -4
  18. package/dist/{chunk-D3S2ODUI.js → chunk-KIGEKMBB.js} +4 -4
  19. package/dist/{chunk-GYRRSOTR.cjs → chunk-LPJPTBRI.cjs} +38 -38
  20. package/dist/{chunk-GYRRSOTR.cjs.map → chunk-LPJPTBRI.cjs.map} +1 -1
  21. package/dist/{chunk-UYWJM2LS.cjs → chunk-NOS6DCYY.cjs} +12 -12
  22. package/dist/{chunk-UYWJM2LS.cjs.map → chunk-NOS6DCYY.cjs.map} +1 -1
  23. package/dist/{chunk-LLTUSEHF.js → chunk-Q3GY66ST.js} +3 -3
  24. package/dist/chunk-XTCBRQN2.js +169 -0
  25. package/dist/chunk-XTCBRQN2.js.map +1 -0
  26. package/dist/{chunk-MWW7LKDN.cjs → chunk-Z4IBEIWD.cjs} +8 -8
  27. package/dist/{chunk-MWW7LKDN.cjs.map → chunk-Z4IBEIWD.cjs.map} +1 -1
  28. package/dist/{chunk-52PRKXK4.cjs → chunk-ZP2DKI5P.cjs} +32 -32
  29. package/dist/{chunk-52PRKXK4.cjs.map → chunk-ZP2DKI5P.cjs.map} +1 -1
  30. package/dist/components/chat/index.cjs +10 -6
  31. package/dist/components/chat/index.cjs.map +1 -1
  32. package/dist/components/chat/index.d.ts +1 -0
  33. package/dist/components/chat/index.d.ts.map +1 -1
  34. package/dist/components/chat/index.js +9 -5
  35. package/dist/components/contact/index.cjs +7 -7
  36. package/dist/components/contact/index.js +6 -6
  37. package/dist/components/features/index.cjs +6 -6
  38. package/dist/components/features/index.js +5 -5
  39. package/dist/components/icons/index.cjs +3 -3
  40. package/dist/components/icons/index.js +2 -2
  41. package/dist/components/index.cjs +241 -238
  42. package/dist/components/index.cjs.map +1 -1
  43. package/dist/components/index.js +13 -10
  44. package/dist/components/index.js.map +1 -1
  45. package/dist/components/navigation/index.cjs +6 -6
  46. package/dist/components/navigation/index.js +5 -5
  47. package/dist/components/onboarding-guides/index.cjs +30 -30
  48. package/dist/components/onboarding-guides/index.js +7 -7
  49. package/dist/components/resizable.d.ts +1 -1
  50. package/dist/components/tickets/index.cjs +89 -89
  51. package/dist/components/tickets/index.js +8 -8
  52. package/dist/components/ui/file-manager/index.cjs +69 -69
  53. package/dist/components/ui/file-manager/index.js +2 -2
  54. package/dist/components/ui/index.cjs +10 -6
  55. package/dist/components/ui/index.cjs.map +1 -1
  56. package/dist/components/ui/index.js +9 -5
  57. package/dist/components/vendor-display-button.d.ts.map +1 -1
  58. package/dist/hooks/index.cjs +4 -4
  59. package/dist/hooks/index.js +3 -3
  60. package/dist/index.cjs +10 -6
  61. package/dist/index.cjs.map +1 -1
  62. package/dist/index.js +9 -5
  63. package/dist/platform-domains.cjs +149 -0
  64. package/dist/platform-domains.cjs.map +1 -0
  65. package/dist/platform-domains.d.ts +106 -0
  66. package/dist/platform-domains.d.ts.map +1 -0
  67. package/dist/platform-domains.js +134 -0
  68. package/dist/platform-domains.js.map +1 -0
  69. package/dist/types/index.cjs +87 -0
  70. package/dist/types/index.cjs.map +1 -1
  71. package/dist/types/index.js +87 -0
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/utils/cn.d.ts +8 -43
  74. package/dist/utils/cn.d.ts.map +1 -1
  75. package/dist/utils/index.cjs +113 -72
  76. package/dist/utils/index.cjs.map +1 -1
  77. package/dist/utils/index.d.ts +3 -2
  78. package/dist/utils/index.d.ts.map +1 -1
  79. package/dist/utils/index.js +113 -72
  80. package/dist/utils/index.js.map +1 -1
  81. package/package.json +7 -1
  82. package/src/__tests__/platform-domains.test.ts +189 -0
  83. package/src/components/chat/index.ts +1 -0
  84. package/src/components/vendor-display-button.tsx +4 -3
  85. package/src/platform-domains.ts +299 -0
  86. package/src/utils/cn.ts +18 -134
  87. package/src/utils/index.ts +7 -2
  88. package/dist/chunk-2TBN53KY.cjs +0 -122
  89. package/dist/chunk-2TBN53KY.cjs.map +0 -1
  90. package/dist/chunk-DHCGJW3G.js.map +0 -1
  91. package/dist/chunk-W7P7RH2X.cjs.map +0 -1
  92. package/dist/chunk-YICWWZ3Z.js +0 -122
  93. package/dist/chunk-YICWWZ3Z.js.map +0 -1
  94. /package/dist/{chunk-Z46NRJWW.js.map → chunk-265KKBV2.js.map} +0 -0
  95. /package/dist/{chunk-BOF5MSRY.js.map → chunk-2LEMRJ7Z.js.map} +0 -0
  96. /package/dist/{chunk-YZDUOUMB.js.map → chunk-AGU44B7B.js.map} +0 -0
  97. /package/dist/{chunk-F6F525T7.js.map → chunk-HGYOMQM3.js.map} +0 -0
  98. /package/dist/{chunk-GSD52WAS.js.map → chunk-JNXFCV7K.js.map} +0 -0
  99. /package/dist/{chunk-D3S2ODUI.js.map → chunk-KIGEKMBB.js.map} +0 -0
  100. /package/dist/{chunk-LLTUSEHF.js.map → chunk-Q3GY66ST.js.map} +0 -0
package/src/utils/cn.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  import { clsx, type ClassValue } from "clsx"
2
2
  import { extendTailwindMerge } from "tailwind-merge"
3
+ // Platform→domain resolution moved to the SSOT module `src/platform-domains.ts`.
4
+ // `getPlatformProductionUrl` / `getAllPlatformBaseDomains` now live there (re-exported
5
+ // via the utils barrel for existing callers); `getBaseUrl` stays here because it owns the
6
+ // dev-localhost + Vercel-self-origin branches, and delegates its platform branch.
7
+ import { getPlatformProductionUrl } from "../platform-domains"
3
8
 
4
9
  const twMerge = extendTailwindMerge<'ods-typography'>({
5
10
  extend: {
@@ -16,110 +21,6 @@ export function cn(...inputs: ClassValue[]) {
16
21
  return twMerge(clsx(inputs))
17
22
  }
18
23
 
19
- /**
20
- * Platform URL mappings for production (with environment variable overrides)
21
- */
22
- export function getPlatformProductionUrl(platform: string): string {
23
- switch (platform) {
24
- // *-hub platforms — env var convention: NEXT_PUBLIC_<NAME>_HUB_URL
25
- case 'marketing-hub':
26
- return process.env.NEXT_PUBLIC_MARKETING_HUB_URL || 'https://marketing-hub.flamingo.so';
27
- case 'company-hub':
28
- return process.env.NEXT_PUBLIC_COMPANY_HUB_URL || 'https://company-hub.flamingo.so';
29
- case 'product-hub':
30
- return process.env.NEXT_PUBLIC_PRODUCT_HUB_URL || 'https://product-hub.flamingo.so';
31
- case 'revenue-hub':
32
- return process.env.NEXT_PUBLIC_REVENUE_HUB_URL || 'https://revenue-hub.flamingo.so';
33
- case 'people-hub':
34
- return process.env.NEXT_PUBLIC_PEOPLE_HUB_URL || 'https://people-hub.flamingo.so';
35
- // Standalone platforms — env var convention: NEXT_PUBLIC_<NAME>_URL
36
- case 'openmsp':
37
- return process.env.NEXT_PUBLIC_OPENMSP_URL || 'https://www.openmsp.ai';
38
- case 'flamingo':
39
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';
40
- case 'tmcg':
41
- return process.env.NEXT_PUBLIC_TMCG_URL || 'https://www.tmcg.miami';
42
- case 'flamingo-teaser':
43
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';
44
- case 'openframe':
45
- return process.env.NEXT_PUBLIC_OPENFRAME_URL || 'https://openframe.ai';
46
- // OpenFrame product / dashboard — the "Start Free Trial" CTA target. DISTINCT from
47
- // the `openframe` content hub above: production overrides that one to
48
- // hub.openframe.ai via NEXT_PUBLIC_OPENFRAME_URL (the knowledge/docs deployment),
49
- // so a product CTA must NOT reuse it. Defaults to the product apex so the CTA is
50
- // correct even when the (optional) dashboard override is unset.
51
- case 'openframe-dashboard':
52
- return process.env.NEXT_PUBLIC_OPENFRAME_DASHBOARD_URL || 'https://openframe.ai';
53
- case 'universal':
54
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';
55
- default:
56
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';
57
- }
58
- }
59
-
60
- /**
61
- * Get ALL unique base domains from getPlatformProductionUrl
62
- *
63
- * Extracts domains by calling getPlatformProductionUrl for each platform identifier.
64
- * Platform identifiers match the switch cases in getPlatformProductionUrl.
65
- *
66
- * Handles 3 cases:
67
- * 1. LOCALHOST DEBUG - No domain (hostname-specific cookies)
68
- * 2. VERCEL PREVIEW (*.vercel.app) - Use vercel.app domain
69
- * 3. PRODUCTION - Extract from ALL platform URLs via getPlatformProductionUrl
70
- *
71
- * @returns Array of all unique base domains (with and without wildcard)
72
- */
73
- export function getAllPlatformBaseDomains(): string[] {
74
- if (typeof window === 'undefined') return []
75
-
76
- const hostname = window.location.hostname
77
-
78
- // Case 1: LOCALHOST DEBUG - no domains needed
79
- if (hostname === 'localhost' ||
80
- hostname === '127.0.0.1' ||
81
- hostname.startsWith('127.')) {
82
- return []
83
- }
84
-
85
- // Case 2: VERCEL PREVIEW - use vercel.app domain
86
- const isVercelPreview = process.env.VERCEL_ENV === 'preview' ||
87
- process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ||
88
- hostname.includes('.vercel.app')
89
-
90
- if (isVercelPreview) {
91
- return ['.vercel.app', 'vercel.app']
92
- }
93
-
94
- // Case 3: PRODUCTION - extract from ALL platforms using getPlatformProductionUrl
95
- // Platform identifiers MUST match switch cases in getPlatformProductionUrl —
96
- // otherwise the corresponding domain is omitted from cookie scope.
97
- const platformIdentifiers = [
98
- 'marketing-hub', 'company-hub', 'product-hub', 'revenue-hub', 'people-hub',
99
- 'openmsp', 'flamingo', 'tmcg', 'flamingo-teaser', 'openframe', 'universal'
100
- ]
101
-
102
- const baseDomains = new Set<string>()
103
-
104
- platformIdentifiers.forEach(platform => {
105
- try {
106
- const url = getPlatformProductionUrl(platform)
107
- const urlHostname = new URL(url).hostname
108
- const parts = urlHostname.split('.')
109
-
110
- if (parts.length >= 2) {
111
- const baseDomain = parts.slice(-2).join('.')
112
- baseDomains.add(`.${baseDomain}`) // Wildcard
113
- baseDomains.add(baseDomain) // Non-wildcard
114
- }
115
- } catch (error) {
116
- console.warn('[Platform Domains] Failed to parse URL for platform:', platform, error)
117
- }
118
- })
119
-
120
- return Array.from(baseDomains)
121
- }
122
-
123
24
  /**
124
25
  * Get the application base URL for the current environment
125
26
  *
@@ -127,35 +28,18 @@ export function getAllPlatformBaseDomains(): string[] {
127
28
  * @returns The base URL with protocol (https:// or http://)
128
29
  *
129
30
  * Priority order:
130
- * 1. Environment variable override (NEXT_PUBLIC_*_URL)
131
- * 2. Platform-specific URL (if platform parameter provided)
31
+ * 1. Development (http://localhost:3000)
32
+ * 2. Platform-specific URL via the SSOT (if `platform` provided) — env override ?? default
132
33
  * 3. VERCEL_PROJECT_PRODUCTION_URL (Vercel production domain)
133
- * 4. Production fallback (current app or openmsp)
134
- * 5. Development (http://localhost:3000)
135
- *
136
- * Environment Variables (optional overrides — only set when production domain
137
- * differs from the hardcoded default):
138
- *
139
- * Hub deployments (NEXT_PUBLIC_<NAME>_HUB_URL):
140
- * - NEXT_PUBLIC_MARKETING_HUB_URL -> marketing-hub.flamingo.so
141
- * - NEXT_PUBLIC_COMPANY_HUB_URL -> company-hub.flamingo.so
142
- * - NEXT_PUBLIC_PRODUCT_HUB_URL -> product-hub.flamingo.so
143
- * - NEXT_PUBLIC_REVENUE_HUB_URL -> revenue-hub.flamingo.so
144
- * - NEXT_PUBLIC_PEOPLE_HUB_URL -> people-hub.flamingo.so
34
+ * 4. Production fallback: the DEPLOYING platform's canonical URL (NEXT_PUBLIC_APP_TYPE),
35
+ * openmsp if unset — sourced from the SSOT, no hardcoded literal.
145
36
  *
146
- * Standalone platforms (NEXT_PUBLIC_<NAME>_URL):
147
- * - NEXT_PUBLIC_OPENMSP_URL -> www.openmsp.ai
148
- * - NEXT_PUBLIC_FLAMINGO_URL -> www.flamingo.run
149
- * - NEXT_PUBLIC_TMCG_URL -> www.tmcg.miami
150
- * - NEXT_PUBLIC_FLAMINGO_TEASER_URL -> www.flamingo.cx
151
- * - NEXT_PUBLIC_OPENFRAME_URL -> openframe.ai
152
- * - NEXT_PUBLIC_OPENFRAME_DASHBOARD_URL -> openframe.ai (product/dashboard CTA target;
153
- * distinct from the openframe content hub, which prod points at hub.openframe.ai)
37
+ * The per-platform canonical URLs + their `NEXT_PUBLIC_*_URL` overrides are the single
38
+ * source of truth in `src/platform-domains.ts` (`PLATFORM_DOMAINS`).
154
39
  *
155
40
  * @example
156
- * getBaseUrl() // Current app URL
157
- * getBaseUrl('flamingo') // https://www.flamingo.run (production) or http://localhost:3000 (dev)
158
- * getBaseUrl('openmsp') // https://www.openmsp.ai (or NEXT_PUBLIC_OPENMSP_URL if set)
41
+ * getBaseUrl() // Current deployment's URL
42
+ * getBaseUrl('flamingo') // https://www.flamingo.run (prod) or http://localhost:3000 (dev)
159
43
  */
160
44
  export function getBaseUrl(platform?: string): string {
161
45
  // In development, always use localhost (regardless of platform)
@@ -163,7 +47,7 @@ export function getBaseUrl(platform?: string): string {
163
47
  return process.env.NEXT_PUBLIC_DEV_URL || 'http://localhost:3000'
164
48
  }
165
49
 
166
- // If platform is specified, return its production URL with env variable override support
50
+ // If platform is specified, return its production URL (env override ?? default)
167
51
  if (platform) {
168
52
  return getPlatformProductionUrl(platform)
169
53
  }
@@ -173,8 +57,8 @@ export function getBaseUrl(platform?: string): string {
173
57
  return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
174
58
  }
175
59
 
176
- // Production fallback: Use canonical www domain to avoid Google "Page with redirect" issue.
177
- // openmsp.ai redirects to www.openmsp.ai, so we set the base URL to the
178
- // final destination to ensure canonical URLs do not require a redirect.
179
- return 'https://www.openmsp.ai'
60
+ // Production fallback: the deploying platform's canonical www domain (avoids Google
61
+ // "Page with redirect"). Derived from the SSOT for the current app type (openmsp when
62
+ // unset → 'https://www.openmsp.ai', byte-identical to the old hardcoded fallback).
63
+ return getPlatformProductionUrl(process.env.NEXT_PUBLIC_APP_TYPE || 'openmsp')
180
64
  }
@@ -1,5 +1,10 @@
1
1
  // Utils exports - client-side only
2
- export { cn, getAllPlatformBaseDomains } from './cn'
2
+ export { cn } from './cn'
3
+ // Platform→domain SSOT lives in `../platform-domains` (single definition). Re-exported
4
+ // here so existing `/utils` callers keep working; the new resolver/helpers
5
+ // (getPlatformByHostname/hostOf/expandWwwApex/…) are exposed via the `/platform-domains`
6
+ // subpath ONLY (one import surface for the new API).
7
+ export { getPlatformProductionUrl, getAllPlatformBaseDomains } from '../platform-domains'
3
8
  // Number / currency / byte / date formatters live in `./format` (single
4
9
  // source of truth). Re-exported here so existing callers that pull from
5
10
  // the barrel keep working without changing imports.
@@ -8,7 +13,7 @@ export { formatDate, formatNumber, formatPrice, formatBytes } from './format'
8
13
  export { PLAY_ICON_PATH } from '../components/icons-v2-generated/media-playback/play-icon'
9
14
  export { getPlatformAccentColor, getCurrentPlatform, type ColorCategory, HEX_PATTERN } from './ods-color-utils'
10
15
  export { delay, generateRandomString, truncateString, deepClone, getSlackCommunityJoinUrl } from './common'
11
- export { getBaseUrl, getPlatformProductionUrl } from '../utils/cn'
16
+ export { getBaseUrl } from '../utils/cn'
12
17
 
13
18
  export * from './platform-config'
14
19
  export * from './os-platforms'
@@ -1,122 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
-
3
-
4
- var _chunkVRHGVLSLcjs = require('./chunk-VRHGVLSL.cjs');
5
-
6
- // src/utils/cn.ts
7
- var _clsx = require('clsx');
8
- var _tailwindmerge = require('tailwind-merge');
9
- function cn(...inputs) {
10
- return twMerge(_clsx.clsx.call(void 0, inputs));
11
- }
12
- function getPlatformProductionUrl(platform) {
13
- switch (platform) {
14
- // *-hub platforms — env var convention: NEXT_PUBLIC_<NAME>_HUB_URL
15
- case "marketing-hub":
16
- return process.env.NEXT_PUBLIC_MARKETING_HUB_URL || "https://marketing-hub.flamingo.so";
17
- case "company-hub":
18
- return process.env.NEXT_PUBLIC_COMPANY_HUB_URL || "https://company-hub.flamingo.so";
19
- case "product-hub":
20
- return process.env.NEXT_PUBLIC_PRODUCT_HUB_URL || "https://product-hub.flamingo.so";
21
- case "revenue-hub":
22
- return process.env.NEXT_PUBLIC_REVENUE_HUB_URL || "https://revenue-hub.flamingo.so";
23
- case "people-hub":
24
- return process.env.NEXT_PUBLIC_PEOPLE_HUB_URL || "https://people-hub.flamingo.so";
25
- // Standalone platforms — env var convention: NEXT_PUBLIC_<NAME>_URL
26
- case "openmsp":
27
- return process.env.NEXT_PUBLIC_OPENMSP_URL || "https://www.openmsp.ai";
28
- case "flamingo":
29
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || "https://www.flamingo.run";
30
- case "tmcg":
31
- return process.env.NEXT_PUBLIC_TMCG_URL || "https://www.tmcg.miami";
32
- case "flamingo-teaser":
33
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || "https://www.flamingo.run";
34
- case "openframe":
35
- return process.env.NEXT_PUBLIC_OPENFRAME_URL || "https://openframe.ai";
36
- // OpenFrame product / dashboard — the "Start Free Trial" CTA target. DISTINCT from
37
- // the `openframe` content hub above: production overrides that one to
38
- // hub.openframe.ai via NEXT_PUBLIC_OPENFRAME_URL (the knowledge/docs deployment),
39
- // so a product CTA must NOT reuse it. Defaults to the product apex so the CTA is
40
- // correct even when the (optional) dashboard override is unset.
41
- case "openframe-dashboard":
42
- return process.env.NEXT_PUBLIC_OPENFRAME_DASHBOARD_URL || "https://openframe.ai";
43
- case "universal":
44
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || "https://www.flamingo.run";
45
- default:
46
- return process.env.NEXT_PUBLIC_FLAMINGO_URL || "https://www.flamingo.run";
47
- }
48
- }
49
- function getAllPlatformBaseDomains() {
50
- if (typeof window === "undefined") return [];
51
- const hostname = window.location.hostname;
52
- if (hostname === "localhost" || hostname === "127.0.0.1" || hostname.startsWith("127.")) {
53
- return [];
54
- }
55
- const isVercelPreview = process.env.VERCEL_ENV === "preview" || process.env.NEXT_PUBLIC_VERCEL_ENV === "preview" || hostname.includes(".vercel.app");
56
- if (isVercelPreview) {
57
- return [".vercel.app", "vercel.app"];
58
- }
59
- const platformIdentifiers = [
60
- "marketing-hub",
61
- "company-hub",
62
- "product-hub",
63
- "revenue-hub",
64
- "people-hub",
65
- "openmsp",
66
- "flamingo",
67
- "tmcg",
68
- "flamingo-teaser",
69
- "openframe",
70
- "universal"
71
- ];
72
- const baseDomains = /* @__PURE__ */ new Set();
73
- platformIdentifiers.forEach((platform) => {
74
- try {
75
- const url = getPlatformProductionUrl(platform);
76
- const urlHostname = new URL(url).hostname;
77
- const parts = urlHostname.split(".");
78
- if (parts.length >= 2) {
79
- const baseDomain = parts.slice(-2).join(".");
80
- baseDomains.add(`.${baseDomain}`);
81
- baseDomains.add(baseDomain);
82
- }
83
- } catch (error) {
84
- console.warn("[Platform Domains] Failed to parse URL for platform:", platform, error);
85
- }
86
- });
87
- return Array.from(baseDomains);
88
- }
89
- function getBaseUrl(platform) {
90
- if (process.env.NODE_ENV !== "production") {
91
- return process.env.NEXT_PUBLIC_DEV_URL || "http://localhost:3000";
92
- }
93
- if (platform) {
94
- return getPlatformProductionUrl(platform);
95
- }
96
- if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
97
- return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;
98
- }
99
- return "https://www.openmsp.ai";
100
- }
101
- var twMerge;
102
- var init_cn = _chunkVRHGVLSLcjs.__esm.call(void 0, {
103
- "src/utils/cn.ts"() {
104
- "use strict";
105
- twMerge = _tailwindmerge.extendTailwindMerge.call(void 0, {
106
- extend: {
107
- classGroups: {
108
- "ods-typography": ["text-h1", "text-h2", "text-h3", "text-h4", "text-h5", "text-h6"]
109
- }
110
- }
111
- });
112
- }
113
- });
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
- exports.cn = cn; exports.getPlatformProductionUrl = getPlatformProductionUrl; exports.getAllPlatformBaseDomains = getAllPlatformBaseDomains; exports.getBaseUrl = getBaseUrl; exports.init_cn = init_cn;
122
- //# sourceMappingURL=chunk-2TBN53KY.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2TBN53KY.cjs","../src/utils/cn.ts"],"names":[],"mappings":"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","file":"/home/runner/work/openframe-oss-lib/openframe-oss-lib/openframe-frontend-core/dist/chunk-2TBN53KY.cjs","sourcesContent":[null,"import { clsx, type ClassValue } from \"clsx\"\nimport { extendTailwindMerge } from \"tailwind-merge\"\n\nconst twMerge = extendTailwindMerge<'ods-typography'>({\n extend: {\n classGroups: {\n 'ods-typography': ['text-h1', 'text-h2', 'text-h3', 'text-h4', 'text-h5', 'text-h6'],\n },\n },\n})\n\n/**\n * Combine class names with Tailwind's merge utility\n */\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\n/**\n * Platform URL mappings for production (with environment variable overrides)\n */\nexport function getPlatformProductionUrl(platform: string): string {\n switch (platform) {\n // *-hub platforms — env var convention: NEXT_PUBLIC_<NAME>_HUB_URL\n case 'marketing-hub':\n return process.env.NEXT_PUBLIC_MARKETING_HUB_URL || 'https://marketing-hub.flamingo.so';\n case 'company-hub':\n return process.env.NEXT_PUBLIC_COMPANY_HUB_URL || 'https://company-hub.flamingo.so';\n case 'product-hub':\n return process.env.NEXT_PUBLIC_PRODUCT_HUB_URL || 'https://product-hub.flamingo.so';\n case 'revenue-hub':\n return process.env.NEXT_PUBLIC_REVENUE_HUB_URL || 'https://revenue-hub.flamingo.so';\n case 'people-hub':\n return process.env.NEXT_PUBLIC_PEOPLE_HUB_URL || 'https://people-hub.flamingo.so';\n // Standalone platforms — env var convention: NEXT_PUBLIC_<NAME>_URL\n case 'openmsp':\n return process.env.NEXT_PUBLIC_OPENMSP_URL || 'https://www.openmsp.ai';\n case 'flamingo':\n return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';\n case 'tmcg':\n return process.env.NEXT_PUBLIC_TMCG_URL || 'https://www.tmcg.miami';\n case 'flamingo-teaser':\n return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';\n case 'openframe':\n return process.env.NEXT_PUBLIC_OPENFRAME_URL || 'https://openframe.ai';\n // OpenFrame product / dashboard — the \"Start Free Trial\" CTA target. DISTINCT from\n // the `openframe` content hub above: production overrides that one to\n // hub.openframe.ai via NEXT_PUBLIC_OPENFRAME_URL (the knowledge/docs deployment),\n // so a product CTA must NOT reuse it. Defaults to the product apex so the CTA is\n // correct even when the (optional) dashboard override is unset.\n case 'openframe-dashboard':\n return process.env.NEXT_PUBLIC_OPENFRAME_DASHBOARD_URL || 'https://openframe.ai';\n case 'universal':\n return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';\n default:\n return process.env.NEXT_PUBLIC_FLAMINGO_URL || 'https://www.flamingo.run';\n }\n}\n\n/**\n * Get ALL unique base domains from getPlatformProductionUrl\n *\n * Extracts domains by calling getPlatformProductionUrl for each platform identifier.\n * Platform identifiers match the switch cases in getPlatformProductionUrl.\n *\n * Handles 3 cases:\n * 1. LOCALHOST DEBUG - No domain (hostname-specific cookies)\n * 2. VERCEL PREVIEW (*.vercel.app) - Use vercel.app domain\n * 3. PRODUCTION - Extract from ALL platform URLs via getPlatformProductionUrl\n *\n * @returns Array of all unique base domains (with and without wildcard)\n */\nexport function getAllPlatformBaseDomains(): string[] {\n if (typeof window === 'undefined') return []\n\n const hostname = window.location.hostname\n\n // Case 1: LOCALHOST DEBUG - no domains needed\n if (hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.startsWith('127.')) {\n return []\n }\n\n // Case 2: VERCEL PREVIEW - use vercel.app domain\n const isVercelPreview = process.env.VERCEL_ENV === 'preview' ||\n process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview' ||\n hostname.includes('.vercel.app')\n\n if (isVercelPreview) {\n return ['.vercel.app', 'vercel.app']\n }\n\n // Case 3: PRODUCTION - extract from ALL platforms using getPlatformProductionUrl\n // Platform identifiers MUST match switch cases in getPlatformProductionUrl —\n // otherwise the corresponding domain is omitted from cookie scope.\n const platformIdentifiers = [\n 'marketing-hub', 'company-hub', 'product-hub', 'revenue-hub', 'people-hub',\n 'openmsp', 'flamingo', 'tmcg', 'flamingo-teaser', 'openframe', 'universal'\n ]\n\n const baseDomains = new Set<string>()\n\n platformIdentifiers.forEach(platform => {\n try {\n const url = getPlatformProductionUrl(platform)\n const urlHostname = new URL(url).hostname\n const parts = urlHostname.split('.')\n\n if (parts.length >= 2) {\n const baseDomain = parts.slice(-2).join('.')\n baseDomains.add(`.${baseDomain}`) // Wildcard\n baseDomains.add(baseDomain) // Non-wildcard\n }\n } catch (error) {\n console.warn('[Platform Domains] Failed to parse URL for platform:', platform, error)\n }\n })\n\n return Array.from(baseDomains)\n}\n\n/**\n * Get the application base URL for the current environment\n *\n * @param platform - Optional platform name (openmsp, flamingo, tmcg, openframe, etc.)\n * @returns The base URL with protocol (https:// or http://)\n *\n * Priority order:\n * 1. Environment variable override (NEXT_PUBLIC_*_URL)\n * 2. Platform-specific URL (if platform parameter provided)\n * 3. VERCEL_PROJECT_PRODUCTION_URL (Vercel production domain)\n * 4. Production fallback (current app or openmsp)\n * 5. Development (http://localhost:3000)\n *\n * Environment Variables (optional overrides — only set when production domain\n * differs from the hardcoded default):\n *\n * Hub deployments (NEXT_PUBLIC_<NAME>_HUB_URL):\n * - NEXT_PUBLIC_MARKETING_HUB_URL -> marketing-hub.flamingo.so\n * - NEXT_PUBLIC_COMPANY_HUB_URL -> company-hub.flamingo.so\n * - NEXT_PUBLIC_PRODUCT_HUB_URL -> product-hub.flamingo.so\n * - NEXT_PUBLIC_REVENUE_HUB_URL -> revenue-hub.flamingo.so\n * - NEXT_PUBLIC_PEOPLE_HUB_URL -> people-hub.flamingo.so\n *\n * Standalone platforms (NEXT_PUBLIC_<NAME>_URL):\n * - NEXT_PUBLIC_OPENMSP_URL -> www.openmsp.ai\n * - NEXT_PUBLIC_FLAMINGO_URL -> www.flamingo.run\n * - NEXT_PUBLIC_TMCG_URL -> www.tmcg.miami\n * - NEXT_PUBLIC_FLAMINGO_TEASER_URL -> www.flamingo.cx\n * - NEXT_PUBLIC_OPENFRAME_URL -> openframe.ai\n * - NEXT_PUBLIC_OPENFRAME_DASHBOARD_URL -> openframe.ai (product/dashboard CTA target;\n * distinct from the openframe content hub, which prod points at hub.openframe.ai)\n *\n * @example\n * getBaseUrl() // Current app URL\n * getBaseUrl('flamingo') // https://www.flamingo.run (production) or http://localhost:3000 (dev)\n * getBaseUrl('openmsp') // https://www.openmsp.ai (or NEXT_PUBLIC_OPENMSP_URL if set)\n */\nexport function getBaseUrl(platform?: string): string {\n // In development, always use localhost (regardless of platform)\n if (process.env.NODE_ENV !== 'production') {\n return process.env.NEXT_PUBLIC_DEV_URL || 'http://localhost:3000'\n }\n\n // If platform is specified, return its production URL with env variable override support\n if (platform) {\n return getPlatformProductionUrl(platform)\n }\n\n // Production: Use Vercel domain if available\n if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {\n return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`\n }\n\n // Production fallback: Use canonical www domain to avoid Google \"Page with redirect\" issue.\n // openmsp.ai redirects to www.openmsp.ai, so we set the base URL to the\n // final destination to ensure canonical URLs do not require a redirect.\n return 'https://www.openmsp.ai'\n}\n"]}