@pradip1995/framework-runtime 0.2.1 → 0.2.4

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.1",
3
+ "version": "0.2.4",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -0,0 +1,37 @@
1
+ export type BuilderSegmentDataFile = {
2
+ version: string
3
+ updatedAt: string
4
+ data: Record<string, Record<string, unknown>>
5
+ }
6
+
7
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value)
9
+ }
10
+
11
+ /** Deep-merge builder CMS values over workflow output (builder wins on conflicts). */
12
+ export function mergeBuilderSegmentData(
13
+ workflowData: Record<string, unknown>,
14
+ builderData: BuilderSegmentDataFile | null | undefined
15
+ ): Record<string, unknown> {
16
+ if (!builderData?.data || Object.keys(builderData.data).length === 0) {
17
+ return workflowData
18
+ }
19
+
20
+ const merged = { ...workflowData }
21
+
22
+ for (const [key, overlay] of Object.entries(builderData.data)) {
23
+ if (!isPlainObject(overlay)) {
24
+ merged[key] = overlay
25
+ continue
26
+ }
27
+
28
+ const existing = merged[key]
29
+ if (isPlainObject(existing)) {
30
+ merged[key] = { ...existing, ...overlay }
31
+ } else {
32
+ merged[key] = { ...overlay }
33
+ }
34
+ }
35
+
36
+ return merged
37
+ }
package/src/index.ts CHANGED
@@ -1,4 +1,11 @@
1
1
  export { renderPage, registerServices, resolveServices, getSegmentProps } from "./render-page"
2
2
  export { renderConfiguredPage } from "./render-configured-page"
3
+ export {
4
+ applyBuilderDataToWorkflow,
5
+ getSegmentDataKey,
6
+ SEGMENT_DATA_KEYS,
7
+ } from "./segment-props"
8
+ export { mergeBuilderSegmentData } from "./builder-data"
3
9
  export type { RenderPageInput } from "./render-page"
4
10
  export type { ConfiguredPage, RenderConfiguredPageInput, SegmentEntry } from "./render-configured-page"
11
+ export type { BuilderSegmentDataFile } from "./builder-data"
@@ -1,6 +1,7 @@
1
1
  import { buildRouteContext } from "@pradip1995/framework-core"
2
2
  import { resolveServices } from "./register-services"
3
- import { getSegmentProps } from "./segment-props"
3
+ import { applyBuilderDataToWorkflow, getSegmentProps } from "./segment-props"
4
+ import type { BuilderSegmentDataFile } from "./builder-data"
4
5
  import type { ComponentType, ReactNode } from "react"
5
6
 
6
7
  export type SegmentEntry = {
@@ -24,6 +25,8 @@ export type RenderConfiguredPageInput = {
24
25
  countryCode: string
25
26
  slug: string[]
26
27
  searchParams: Record<string, string | string[] | undefined>
28
+ /** CMS overrides from storefront/builder/segment-data.json */
29
+ builderSegmentData?: BuilderSegmentDataFile | null
27
30
  }
28
31
 
29
32
  function NotFoundPanel({ message }: { message: string }) {
@@ -42,7 +45,8 @@ export async function renderConfiguredPage(input: RenderConfiguredPageInput): Pr
42
45
  try {
43
46
  const route = buildRouteContext(input.countryCode, input.slug, input.searchParams)
44
47
  const services = await resolveServices()
45
- const data = await input.page.workflow.execute({ route, services })
48
+ const workflowData = await input.page.workflow.execute({ route, services })
49
+ const data = applyBuilderDataToWorkflow(workflowData, input.builderSegmentData)
46
50
  const Layout = input.page.layout
47
51
 
48
52
  if (data.notFound) {
@@ -1,6 +1,7 @@
1
1
  import { matchRoute, buildRouteContext } from "@pradip1995/framework-core"
2
2
  import { resolveServices } from "./register-services"
3
- import { getSegmentProps } from "./segment-props"
3
+ import { applyBuilderDataToWorkflow, getSegmentProps } from "./segment-props"
4
+ import type { BuilderSegmentDataFile } from "./builder-data"
4
5
  import type { ComponentType, ReactNode } from "react"
5
6
  import type { PageConfigEntry } from "@pradip1995/plugin-sdk"
6
7
 
@@ -12,6 +13,8 @@ export type RenderPageInput = {
12
13
  searchParams: Record<string, string | string[] | undefined>
13
14
  routeManifest: PageConfigEntry[]
14
15
  importMap: ImportMap
16
+ /** CMS overrides from storefront/builder/segment-data.json */
17
+ builderSegmentData?: BuilderSegmentDataFile | null
15
18
  }
16
19
 
17
20
  async function resolvePlugin(importMap: ImportMap, pkg: string) {
@@ -42,7 +45,8 @@ export async function renderPage(input: RenderPageInput): Promise<ReactNode> {
42
45
  }
43
46
  }
44
47
 
45
- const data = await workflowMod.default.execute({ route, services })
48
+ const workflowData = await workflowMod.default.execute({ route, services })
49
+ const data = applyBuilderDataToWorkflow(workflowData, input.builderSegmentData)
46
50
 
47
51
  const layoutMod = (await resolvePlugin(input.importMap, page!.layout)) as {
48
52
  default: ComponentType<{ data: Record<string, unknown>; children: ReactNode }>
@@ -1,5 +1,7 @@
1
+ import { mergeBuilderSegmentData, type BuilderSegmentDataFile } from "./builder-data"
2
+
1
3
  /** Maps segment package name → workflow output key(s) */
2
- const SEGMENT_DATA_KEYS: Record<string, string> = {
4
+ export const SEGMENT_DATA_KEYS: Record<string, string> = {
3
5
  "@pradip1995/segment-hero": "hero",
4
6
  "@pradip1995/segment-shop-by-age": "shopByAge",
5
7
  "@pradip1995/segment-shop-by-category": "shopByCategory",
@@ -36,6 +38,10 @@ const SEGMENT_DATA_KEYS: Record<string, string> = {
36
38
  "@pradip1995/segment-help": "helpPage",
37
39
  }
38
40
 
41
+ export function getSegmentDataKey(segmentPkg: string): string | undefined {
42
+ return SEGMENT_DATA_KEYS[segmentPkg]
43
+ }
44
+
39
45
  export function getSegmentProps(
40
46
  segmentPkg: string,
41
47
  data: Record<string, unknown>
@@ -48,3 +54,10 @@ export function getSegmentProps(
48
54
  }
49
55
  return { [key]: value }
50
56
  }
57
+
58
+ export function applyBuilderDataToWorkflow(
59
+ workflowData: Record<string, unknown>,
60
+ builderData: BuilderSegmentDataFile | null | undefined
61
+ ): Record<string, unknown> {
62
+ return mergeBuilderSegmentData(workflowData, builderData)
63
+ }