@pradip1995/framework-runtime 0.2.4 → 0.2.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pradip1995/framework-runtime",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -14,9 +14,9 @@
14
14
  "./render-page": "./src/render-page.tsx"
15
15
  },
16
16
  "dependencies": {
17
- "@pradip1995/framework-core": "0.2.1",
18
17
  "@pradip1995/plugin-sdk": "0.2.1",
19
- "@pradip1995/medusa-connector": "0.2.1"
18
+ "@pradip1995/framework-core": "0.2.1",
19
+ "@pradip1995/medusa-connector": "0.2.2"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "next": ">=15",
@@ -1,12 +1,19 @@
1
1
  import { buildRouteContext } from "@pradip1995/framework-core"
2
2
  import { resolveServices } from "./register-services"
3
- import { applyBuilderDataToWorkflow, getSegmentProps } from "./segment-props"
3
+ import {
4
+ applyChromeSegmentData,
5
+ applyBuilderDataToWorkflow,
6
+ resolveSegmentProps,
7
+ type ChromeSegmentRef,
8
+ } from "./segment-props"
4
9
  import type { BuilderSegmentDataFile } from "./builder-data"
5
10
  import type { ComponentType, ReactNode } from "react"
6
11
 
7
12
  export type SegmentEntry = {
8
13
  pkg: string
9
14
  Component: ComponentType<Record<string, unknown>>
15
+ /** CMS values from pages.config.json, shaped by segment builder.settings.json */
16
+ data?: Record<string, unknown>
10
17
  }
11
18
 
12
19
  export type ConfiguredPage = {
@@ -25,7 +32,11 @@ export type RenderConfiguredPageInput = {
25
32
  countryCode: string
26
33
  slug: string[]
27
34
  searchParams: Record<string, string | string[] | undefined>
28
- /** CMS overrides from storefront/builder/segment-data.json */
35
+ /** Global layout chrome from pages.config.json chrome[] */
36
+ chrome?: ChromeSegmentRef[] | null
37
+ /** @deprecated legacy global overlay */
38
+ pageSegmentData?: BuilderSegmentDataFile | null
39
+ /** @deprecated use chrome + inline segment data */
29
40
  builderSegmentData?: BuilderSegmentDataFile | null
30
41
  }
31
42
 
@@ -46,7 +57,13 @@ export async function renderConfiguredPage(input: RenderConfiguredPageInput): Pr
46
57
  const route = buildRouteContext(input.countryCode, input.slug, input.searchParams)
47
58
  const services = await resolveServices()
48
59
  const workflowData = await input.page.workflow.execute({ route, services })
49
- const data = applyBuilderDataToWorkflow(workflowData, input.builderSegmentData)
60
+
61
+ const legacyOverlay = input.pageSegmentData ?? input.builderSegmentData
62
+ let data = legacyOverlay
63
+ ? applyBuilderDataToWorkflow(workflowData, legacyOverlay)
64
+ : workflowData
65
+ data = applyChromeSegmentData(data, input.chrome)
66
+
50
67
  const Layout = input.page.layout
51
68
 
52
69
  if (data.notFound) {
@@ -62,8 +79,8 @@ export async function renderConfiguredPage(input: RenderConfiguredPageInput): Pr
62
79
  )
63
80
  }
64
81
 
65
- const segmentElements = input.page.segments.map(({ pkg, Component: Segment }) => {
66
- const props = getSegmentProps(pkg, data)
82
+ const segmentElements = input.page.segments.map(({ pkg, Component: Segment, data: inline }) => {
83
+ const props = resolveSegmentProps(pkg, data, inline)
67
84
  return <Segment key={pkg} {...props} />
68
85
  })
69
86
 
@@ -13,7 +13,9 @@ export type RenderPageInput = {
13
13
  searchParams: Record<string, string | string[] | undefined>
14
14
  routeManifest: PageConfigEntry[]
15
15
  importMap: ImportMap
16
- /** CMS overrides from storefront/builder/segment-data.json */
16
+ /** CMS values from pages.config.json segmentData */
17
+ pageSegmentData?: BuilderSegmentDataFile | null
18
+ /** @deprecated use pageSegmentData */
17
19
  builderSegmentData?: BuilderSegmentDataFile | null
18
20
  }
19
21
 
@@ -46,7 +48,8 @@ export async function renderPage(input: RenderPageInput): Promise<ReactNode> {
46
48
  }
47
49
 
48
50
  const workflowData = await workflowMod.default.execute({ route, services })
49
- const data = applyBuilderDataToWorkflow(workflowData, input.builderSegmentData)
51
+ const pageSegmentData = input.pageSegmentData ?? input.builderSegmentData
52
+ const data = applyBuilderDataToWorkflow(workflowData, pageSegmentData)
50
53
 
51
54
  const layoutMod = (await resolvePlugin(input.importMap, page!.layout)) as {
52
55
  default: ComponentType<{ data: Record<string, unknown>; children: ReactNode }>
@@ -17,7 +17,8 @@ export const SEGMENT_DATA_KEYS: Record<string, string> = {
17
17
  "@pradip1995/segment-nav": "nav",
18
18
  "@pradip1995/segment-footer": "footer",
19
19
  "@pradip1995/segment-promo-bar": "promoBar",
20
- "@pradip1995/segment-product-grid": "store",
20
+ "@pradip1995/segment-product-grid": "store",
21
+ "@pradip1995/segment-beauty-shop-grid": "store",
21
22
  "@pradip1995/segment-refinement-list": "store",
22
23
  "@pradip1995/segment-mobile-filters": "store",
23
24
  "@pradip1995/segment-product-gallery": "product",
@@ -36,6 +37,14 @@ export const SEGMENT_DATA_KEYS: Record<string, string> = {
36
37
  "@pradip1995/segment-order-details": "orderPage",
37
38
  "@pradip1995/segment-wishlist": "wishlistPage",
38
39
  "@pradip1995/segment-help": "helpPage",
40
+ "@pradip1995/segment-shop-by-nav": "shopByNav",
41
+ "@pradip1995/segment-shop-banner": "shopBanner",
42
+ "@pradip1995/segment-newsletter": "newsletter",
43
+ "@pradip1995/segment-store-faqs": "storeFaqs",
44
+ "@pradip1995/segment-beauty-category-tiles": "beautyCategories",
45
+ "@pradip1995/segment-beauty-promise": "beautyPromise",
46
+ "@pradip1995/segment-beauty-reviews": "beautyReviews",
47
+ "@pradip1995/segment-beauty-values": "beautyValues",
39
48
  }
40
49
 
41
50
  export function getSegmentDataKey(segmentPkg: string): string | undefined {
@@ -47,7 +56,7 @@ export function getSegmentProps(
47
56
  data: Record<string, unknown>
48
57
  ): Record<string, unknown> {
49
58
  const key = SEGMENT_DATA_KEYS[segmentPkg]
50
- if (!key) return data
59
+ if (!key) return {}
51
60
  const value = data[key]
52
61
  if (value && typeof value === "object" && !Array.isArray(value)) {
53
62
  return value as Record<string, unknown>
@@ -55,6 +64,89 @@ export function getSegmentProps(
55
64
  return { [key]: value }
56
65
  }
57
66
 
67
+ function mergeSegmentRecords(
68
+ base: Record<string, unknown>,
69
+ overlay: Record<string, unknown>
70
+ ): Record<string, unknown> {
71
+ const result = { ...base }
72
+ for (const [key, value] of Object.entries(overlay)) {
73
+ const existing = result[key]
74
+ if (
75
+ value &&
76
+ typeof value === "object" &&
77
+ !Array.isArray(value) &&
78
+ existing &&
79
+ typeof existing === "object" &&
80
+ !Array.isArray(existing)
81
+ ) {
82
+ result[key] = mergeSegmentRecords(
83
+ existing as Record<string, unknown>,
84
+ value as Record<string, unknown>
85
+ )
86
+ } else {
87
+ result[key] = value
88
+ }
89
+ }
90
+ return result
91
+ }
92
+
93
+ export function resolveSegmentProps(
94
+ segmentPkg: string,
95
+ workflowData: Record<string, unknown>,
96
+ inlineData?: Record<string, unknown> | null
97
+ ): Record<string, unknown> {
98
+ const base = getSegmentProps(segmentPkg, workflowData)
99
+
100
+ const layoutCart = workflowData.cart
101
+ if (
102
+ layoutCart &&
103
+ typeof layoutCart === "object" &&
104
+ (segmentPkg === "@pradip1995/segment-product-actions" ||
105
+ segmentPkg === "@pradip1995/segment-product-info") &&
106
+ !("cart" in base)
107
+ ) {
108
+ base.cart = layoutCart
109
+ }
110
+
111
+ if (!inlineData || Object.keys(inlineData).length === 0) return base
112
+ return mergeSegmentRecords(base, inlineData)
113
+ }
114
+
115
+ export type ChromeSegmentRef = string | { package: string; data?: Record<string, unknown> }
116
+
117
+ function chromePackageName(ref: ChromeSegmentRef): string {
118
+ return typeof ref === "string" ? ref : ref.package
119
+ }
120
+
121
+ function chromeInlineData(ref: ChromeSegmentRef): Record<string, unknown> | undefined {
122
+ return typeof ref === "string" ? undefined : ref.data
123
+ }
124
+
125
+ /** Merge global chrome segment data (nav, footer, promo) into workflow output for layout. */
126
+ export function applyChromeSegmentData(
127
+ workflowData: Record<string, unknown>,
128
+ chrome: ChromeSegmentRef[] | null | undefined
129
+ ): Record<string, unknown> {
130
+ if (!chrome?.length) return workflowData
131
+ const merged = { ...workflowData }
132
+
133
+ for (const ref of chrome) {
134
+ const pkg = chromePackageName(ref)
135
+ const data = chromeInlineData(ref)
136
+ const key = SEGMENT_DATA_KEYS[pkg]
137
+ if (!key || !data || Object.keys(data).length === 0) continue
138
+
139
+ const existing = merged[key]
140
+ if (existing && typeof existing === "object" && !Array.isArray(existing)) {
141
+ merged[key] = mergeSegmentRecords(existing as Record<string, unknown>, data)
142
+ } else {
143
+ merged[key] = { ...data }
144
+ }
145
+ }
146
+
147
+ return merged
148
+ }
149
+
58
150
  export function applyBuilderDataToWorkflow(
59
151
  workflowData: Record<string, unknown>,
60
152
  builderData: BuilderSegmentDataFile | null | undefined