@contentful/experiences-client 0.8.0 → 0.9.0
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/CHANGELOG.md +138 -0
- package/dist/contentful-experiences.d.ts +0 -1
- package/dist/contentful-experiences.js +1 -2
- package/dist/contentful-experiences.js.map +1 -1
- package/dist/fetch-experience.d.ts +0 -6
- package/dist/fetch-experience.js +5 -7
- package/dist/fetch-experience.js.map +1 -1
- package/dist/sdk-info.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,141 @@
|
|
|
1
|
+
## 0.9.0 (2026-10-08)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- ⚠️ remove sdk viewport surface [SPA-5275] ([#220](https://github.com/contentful/experiences/pull/220))
|
|
6
|
+
|
|
7
|
+
### ⚠️ Breaking Changes
|
|
8
|
+
|
|
9
|
+
- remove sdk viewport surface [SPA-5275] ([#220](https://github.com/contentful/experiences/pull/220))
|
|
10
|
+
The SDK no longer exposes viewport definitions, viewport-aware design-value resolution, or active-viewport hooks. Use CSS media queries or application-owned matchMedia integration for responsive behavior. Delivered design property values are now flat and require no migration."
|
|
11
|
+
M AGENTS.md
|
|
12
|
+
M ARCHITECTURE.md
|
|
13
|
+
M CONTRIBUTING.md
|
|
14
|
+
M README.md
|
|
15
|
+
M catalog-info.yaml
|
|
16
|
+
M examples/angular/README.md
|
|
17
|
+
M examples/angular/src/app/components/heading.component.ts
|
|
18
|
+
D examples/angular/src/app/lib/detect-viewport.ts
|
|
19
|
+
M examples/angular/src/app/lib/experience-config.ts
|
|
20
|
+
M examples/angular/src/app/lib/experience-route-data.ts
|
|
21
|
+
M examples/angular/src/app/pages/experience-page.component.ts
|
|
22
|
+
M examples/angular/src/server.ts
|
|
23
|
+
M examples/nextjs/README.md
|
|
24
|
+
M examples/nextjs/app/[slug]/page.tsx
|
|
25
|
+
M examples/nextjs/components/Heading.tsx
|
|
26
|
+
M examples/nextjs/components/LivePreviewExperience.tsx
|
|
27
|
+
M examples/nextjs/components/Section.tsx
|
|
28
|
+
D examples/nextjs/lib/detect-viewport.ts
|
|
29
|
+
M examples/nextjs/lib/experience-config.tsx
|
|
30
|
+
M examples/scripts/bootstrap-example.ts
|
|
31
|
+
M examples/scripts/fixture/experience.ts
|
|
32
|
+
M examples/scripts/fixture/types.ts
|
|
33
|
+
M examples/sveltekit/README.md
|
|
34
|
+
M examples/sveltekit/src/lib/components/Heading.svelte
|
|
35
|
+
D examples/sveltekit/src/lib/detect-viewport.ts
|
|
36
|
+
M examples/sveltekit/src/lib/experience-config.ts
|
|
37
|
+
M examples/sveltekit/src/routes/[slug]/+page.server.ts
|
|
38
|
+
M examples/sveltekit/src/routes/[slug]/+page.svelte
|
|
39
|
+
M examples/sveltekit/vite.config.ts
|
|
40
|
+
M package-lock.json
|
|
41
|
+
M packages/adapter-angular/README.md
|
|
42
|
+
M packages/adapter-angular/src/client-experience-renderer.component.ts
|
|
43
|
+
M packages/adapter-angular/src/context.ts
|
|
44
|
+
M packages/adapter-angular/src/debug-experience.test.ts
|
|
45
|
+
M packages/adapter-angular/src/debug-panel-coverage.ssr.test.ts
|
|
46
|
+
M packages/adapter-angular/src/debug-panel-coverage.test.ts
|
|
47
|
+
M packages/adapter-angular/src/dom-parity.test.ts
|
|
48
|
+
M packages/adapter-angular/src/experience-defaults.ts
|
|
49
|
+
M packages/adapter-angular/src/experience-scope.ts
|
|
50
|
+
M packages/adapter-angular/src/index.ts
|
|
51
|
+
D packages/adapter-angular/src/inject-active-viewport.ts
|
|
52
|
+
M packages/adapter-angular/src/inject-design-values.ts
|
|
53
|
+
M packages/adapter-angular/src/inject-experience-plan.ts
|
|
54
|
+
M packages/adapter-angular/src/live-preview-experience.ssr.test.ts
|
|
55
|
+
M packages/adapter-angular/src/live-preview-experience.test.ts
|
|
56
|
+
M packages/adapter-angular/src/node-render-engine.test.ts
|
|
57
|
+
M packages/adapter-angular/src/node-render-engine.ts
|
|
58
|
+
M packages/adapter-angular/src/node-scopes.ts
|
|
59
|
+
M packages/adapter-angular/src/nodes-renderer.ssr.test.ts
|
|
60
|
+
M packages/adapter-angular/src/server-experience-renderer.component.ts
|
|
61
|
+
M packages/adapter-angular/src/server-renderer.test.ts
|
|
62
|
+
M packages/adapter-angular/src/test-fixtures/render-harness.ts
|
|
63
|
+
M packages/adapter-angular/src/types.ts
|
|
64
|
+
M packages/adapter-react/README.md
|
|
65
|
+
M packages/adapter-react/src/client-renderer.tsx
|
|
66
|
+
M packages/adapter-react/src/context.tsx
|
|
67
|
+
M packages/adapter-react/src/debug-experience.test.tsx
|
|
68
|
+
M packages/adapter-react/src/debug-experience.tsx
|
|
69
|
+
M packages/adapter-react/src/debug-panel-coverage.test.tsx
|
|
70
|
+
M packages/adapter-react/src/index.ts
|
|
71
|
+
M packages/adapter-react/src/nodes-renderer.ssr.test.tsx
|
|
72
|
+
M packages/adapter-react/src/nodes-renderer.test.tsx
|
|
73
|
+
M packages/adapter-react/src/nodes-renderer.tsx
|
|
74
|
+
M packages/adapter-react/src/server-renderer.test.tsx
|
|
75
|
+
M packages/adapter-react/src/server-renderer.tsx
|
|
76
|
+
M packages/adapter-react/src/types.ts
|
|
77
|
+
D packages/adapter-react/src/use-active-viewport.ts
|
|
78
|
+
M packages/adapter-react/src/use-design-values.tsx
|
|
79
|
+
M packages/adapter-react/src/use-experience-plan.test.tsx
|
|
80
|
+
M packages/adapter-react/src/use-experience-plan.ts
|
|
81
|
+
M packages/adapter-react/src/use-live-preview-experience.test.tsx
|
|
82
|
+
M packages/adapter-react/src/use-live-preview.test.tsx
|
|
83
|
+
M packages/adapter-svelte/README.md
|
|
84
|
+
M packages/adapter-svelte/src/ClientExperienceRenderer.svelte
|
|
85
|
+
M packages/adapter-svelte/src/DebugExperience.svelte
|
|
86
|
+
M packages/adapter-svelte/src/DebugExperience.test.ts
|
|
87
|
+
M packages/adapter-svelte/src/NodeRenderer.svelte
|
|
88
|
+
M packages/adapter-svelte/src/NodeRenderer.test.ts
|
|
89
|
+
M packages/adapter-svelte/src/NodesRenderer.svelte
|
|
90
|
+
M packages/adapter-svelte/src/ServerExperienceRenderer.svelte
|
|
91
|
+
M packages/adapter-svelte/src/component-props.ts
|
|
92
|
+
M packages/adapter-svelte/src/context.ts
|
|
93
|
+
M packages/adapter-svelte/src/debug-panel-coverage.ssr.test.ts
|
|
94
|
+
M packages/adapter-svelte/src/debug-panel-coverage.test.ts
|
|
95
|
+
M packages/adapter-svelte/src/get-design-values.ts
|
|
96
|
+
M packages/adapter-svelte/src/index.ts
|
|
97
|
+
M packages/adapter-svelte/src/nodes-renderer.ssr.test.ts
|
|
98
|
+
M packages/adapter-svelte/src/server-renderer.test.ts
|
|
99
|
+
M packages/adapter-svelte/src/types.ts
|
|
100
|
+
D packages/adapter-svelte/src/use-active-viewport.svelte.ts
|
|
101
|
+
M packages/adapter-svelte/src/use-experience-plan.test.ts
|
|
102
|
+
M packages/adapter-svelte/src/use-live-preview-experience.test.ts
|
|
103
|
+
M packages/adapter-svelte/src/use-live-preview.test.ts
|
|
104
|
+
M packages/client/src/contentful-experiences.test.ts
|
|
105
|
+
M packages/client/src/contentful-experiences.ts
|
|
106
|
+
M packages/client/src/fetch-experience.test.ts
|
|
107
|
+
M packages/client/src/fetch-experience.ts
|
|
108
|
+
M packages/core/README.md
|
|
109
|
+
A packages/core/src/design-properties.test.ts
|
|
110
|
+
A packages/core/src/design-properties.ts
|
|
111
|
+
M packages/core/src/index.ts
|
|
112
|
+
M packages/core/src/resolve-experience.test.ts
|
|
113
|
+
M packages/core/src/resolve-experience.ts
|
|
114
|
+
M packages/core/src/types.ts
|
|
115
|
+
D packages/core/src/viewport.test.ts
|
|
116
|
+
D packages/core/src/viewport.ts
|
|
117
|
+
M packages/design/README.md
|
|
118
|
+
M packages/design/package.json
|
|
119
|
+
M packages/design/src/index.ts
|
|
120
|
+
D packages/design/src/media-query-matchers.ts
|
|
121
|
+
D packages/design/src/select-resolved-design.ts
|
|
122
|
+
D packages/design/src/viewport.test.ts
|
|
123
|
+
D packages/design/src/viewport.ts
|
|
124
|
+
M packages/live-preview/README.md
|
|
125
|
+
M packages/live-preview/src/experience-payload.ts
|
|
126
|
+
M packages/live-preview/src/fetch-preview-session.test.ts
|
|
127
|
+
M packages/live-preview/src/fetch-preview-session.ts
|
|
128
|
+
M packages/live-preview/src/live-preview-client.test.ts
|
|
129
|
+
M packages/node/README.md
|
|
130
|
+
M packages/node/src/contentful-experiences.test.ts
|
|
131
|
+
M packages/node/src/contentful-experiences.ts
|
|
132
|
+
M packages/web/README.md
|
|
133
|
+
M packages/web/src/contentful-experiences.test.ts
|
|
134
|
+
|
|
135
|
+
### 🧱 Updated Dependencies
|
|
136
|
+
|
|
137
|
+
- Updated core to 0.12.0
|
|
138
|
+
|
|
1
139
|
## 0.8.0 (2026-10-06)
|
|
2
140
|
|
|
3
141
|
### 🧱 Updated Dependencies
|
|
@@ -12,7 +12,6 @@ import '@contentful/optimization-api-client';
|
|
|
12
12
|
type RuntimeResolveOptions = {
|
|
13
13
|
metadata?: Record<string, unknown>;
|
|
14
14
|
debug?: boolean;
|
|
15
|
-
initialViewportId?: string;
|
|
16
15
|
};
|
|
17
16
|
type RuntimeEventBuilderConfig = Omit<EventBuilderConfig, 'channel' | 'library'> & {
|
|
18
17
|
channel: EventBuilderConfig['channel'];
|
|
@@ -94,8 +94,7 @@ class ContentfulExperiences {
|
|
|
94
94
|
#mergeResolveOptions(options) {
|
|
95
95
|
return {
|
|
96
96
|
metadata: { ...this.#resolveDefaults.metadata, ...options?.metadata },
|
|
97
|
-
debug: options?.debug ?? this.#resolveDefaults.debug
|
|
98
|
-
initialViewportId: options?.initialViewportId
|
|
97
|
+
debug: options?.debug ?? this.#resolveDefaults.debug
|
|
99
98
|
};
|
|
100
99
|
}
|
|
101
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contentful-experiences.ts"],"sourcesContent":["import type { ContentfulViewDeliveryClient } from '@contentful/experience-delivery';\nimport { resolveExperience as resolveCoreExperience } from '@contentful/experiences-sdk-core';\nimport type {\n ExperiencePayload,\n PortableRenderPlan,\n ResolverConfig,\n} from '@contentful/experiences-sdk-core';\nimport EventBuilder from './event-builder.js';\nimport type { EventBuilderConfig } from './event-builder.js';\nimport {\n createRuntimeDeliveryClient,\n type RuntimeDeliveryClientOptions,\n} from './create-delivery-client.js';\nimport {\n fetchExperience,\n type DestinationRedirectResult,\n type ExperienceRequestExtensions,\n type PersonalizationOptions,\n} from './fetch-experience.js';\nimport {\n createRuntimeOptimizationClient,\n type RuntimeOptimizationConfig,\n} from './create-optimization-client.js';\nimport { PREVIEW_HOST } from './hosts.js';\nimport { DEFAULT_EVENT_CONTEXT_LIBRARY } from './sdk-info.js';\nimport {\n createRuntimeEventMethods,\n type RuntimeEventBindings,\n type RuntimeEventDispatch,\n type RuntimeEventMethods,\n type RuntimeOptimizationApiClient,\n} from './runtime-event-methods.js';\n\nexport type RuntimeResolveOptions = {\n metadata?: Record<string, unknown>;\n debug?: boolean;\n
|
|
1
|
+
{"version":3,"sources":["../src/contentful-experiences.ts"],"sourcesContent":["import type { ContentfulViewDeliveryClient } from '@contentful/experience-delivery';\nimport { resolveExperience as resolveCoreExperience } from '@contentful/experiences-sdk-core';\nimport type {\n ExperiencePayload,\n PortableRenderPlan,\n ResolverConfig,\n} from '@contentful/experiences-sdk-core';\nimport EventBuilder from './event-builder.js';\nimport type { EventBuilderConfig } from './event-builder.js';\nimport {\n createRuntimeDeliveryClient,\n type RuntimeDeliveryClientOptions,\n} from './create-delivery-client.js';\nimport {\n fetchExperience,\n type DestinationRedirectResult,\n type ExperienceRequestExtensions,\n type PersonalizationOptions,\n} from './fetch-experience.js';\nimport {\n createRuntimeOptimizationClient,\n type RuntimeOptimizationConfig,\n} from './create-optimization-client.js';\nimport { PREVIEW_HOST } from './hosts.js';\nimport { DEFAULT_EVENT_CONTEXT_LIBRARY } from './sdk-info.js';\nimport {\n createRuntimeEventMethods,\n type RuntimeEventBindings,\n type RuntimeEventDispatch,\n type RuntimeEventMethods,\n type RuntimeOptimizationApiClient,\n} from './runtime-event-methods.js';\n\nexport type RuntimeResolveOptions = {\n metadata?: Record<string, unknown>;\n debug?: boolean;\n};\n\nexport type RuntimeEventBuilderConfig = Omit<EventBuilderConfig, 'channel' | 'library'> & {\n channel: EventBuilderConfig['channel'];\n library?: Partial<EventBuilderConfig['library']>;\n};\n\nexport type RuntimeFetchExperienceOptions = {\n experienceId: string;\n locale?: string;\n personalization?: PersonalizationOptions;\n extensions?: ExperienceRequestExtensions;\n preview?: boolean;\n};\n\nexport type RuntimeFetchByDestinationNodeOptions = {\n destinationId: string;\n nodeId: string;\n};\n\nexport type RuntimeFetchByDestinationPathOptions = {\n destinationId: string;\n path: string;\n};\n\n/** Structural contract implemented by the Client runtime. */\nexport interface ExperienceRuntime {\n readonly spaceId: string;\n readonly environmentId: string;\n readonly locale: string | undefined;\n readonly eventBuilder: EventBuilder;\n resolveExperience(\n payload: ExperiencePayload,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan>;\n fetchExperience(\n options: RuntimeFetchExperienceOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan>;\n fetchByDestinationNode(\n options: RuntimeFetchByDestinationNodeOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan | DestinationRedirectResult>;\n fetchByDestinationPath(\n options: RuntimeFetchByDestinationPathOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan | DestinationRedirectResult>;\n}\n\nexport type ContentfulExperiencesConfig = {\n spaceId: string;\n environmentId: string;\n locale?: string;\n resolverConfig: ResolverConfig;\n /** Configuration for the runtime-owned Content Delivery API client. */\n delivery: RuntimeDeliveryClientOptions;\n /** Optional configuration for the runtime-owned Content Preview API client. */\n preview?: RuntimeDeliveryClientOptions;\n /** Overrides for the runtime-owned Personalization and Analytics event transport. */\n optimization?: RuntimeOptimizationConfig;\n resolveDefaults?: Pick<RuntimeResolveOptions, 'metadata' | 'debug'>;\n eventBuilder: RuntimeEventBuilderConfig;\n};\n\nexport class ContentfulExperiences implements ExperienceRuntime {\n readonly spaceId: string;\n readonly environmentId: string;\n readonly eventBuilder: EventBuilder;\n\n readonly #locale: string | undefined;\n readonly #resolverConfig: ResolverConfig;\n readonly #deliveryClient: ContentfulViewDeliveryClient;\n readonly #previewClient: ContentfulViewDeliveryClient | undefined;\n protected readonly optimizationApi: RuntimeOptimizationApiClient;\n readonly #resolveDefaults: Pick<RuntimeResolveOptions, 'metadata' | 'debug'>;\n\n constructor(config: ContentfulExperiencesConfig) {\n this.spaceId = config.spaceId;\n this.environmentId = config.environmentId;\n this.#locale = config.locale;\n this.#resolverConfig = config.resolverConfig;\n this.#deliveryClient = createRuntimeDeliveryClient(config.delivery);\n this.#previewClient =\n config.preview === undefined\n ? undefined\n : createRuntimeDeliveryClient(config.preview, PREVIEW_HOST);\n this.optimizationApi = createRuntimeOptimizationClient({\n spaceId: config.spaceId,\n environmentId: config.environmentId,\n ...config.optimization,\n });\n this.#resolveDefaults = config.resolveDefaults ?? {};\n\n this.eventBuilder = new EventBuilder({\n ...config.eventBuilder,\n library: { ...DEFAULT_EVENT_CONTEXT_LIBRARY, ...config.eventBuilder.library },\n getLocale: config.eventBuilder.getLocale ?? (() => this.locale),\n });\n }\n\n get locale(): string | undefined {\n return this.#locale;\n }\n\n protected createEventMethods(\n bindings: RuntimeEventBindings,\n dispatch?: RuntimeEventDispatch\n ): RuntimeEventMethods {\n return createRuntimeEventMethods(this.optimizationApi, this.eventBuilder, bindings, dispatch);\n }\n\n resolveExperience(\n payload: ExperiencePayload,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan> {\n return resolveCoreExperience(\n payload,\n this.#resolverConfig,\n this.#mergeResolveOptions(resolveOptions)\n );\n }\n\n fetchExperience(\n options: RuntimeFetchExperienceOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan> {\n if (options.preview === true && this.#previewClient === undefined) {\n throw new Error(\n 'fetchExperience() called with preview: true but this runtime has no preview client'\n );\n }\n return fetchExperience(\n {\n spaceId: this.spaceId,\n environmentId: this.environmentId,\n experienceId: options.experienceId,\n locale: options.locale ?? this.locale,\n personalization: options.personalization,\n extensions: options.extensions,\n },\n {\n client: options.preview\n ? (this.#previewClient as ContentfulViewDeliveryClient)\n : this.#deliveryClient,\n },\n { config: this.#resolverConfig, ...this.#mergeResolveOptions(resolveOptions) }\n );\n }\n\n fetchByDestinationNode(\n options: RuntimeFetchByDestinationNodeOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan | DestinationRedirectResult> {\n return fetchExperience(\n { spaceId: this.spaceId, destinationId: options.destinationId, nodeId: options.nodeId },\n { client: this.#deliveryClient },\n { config: this.#resolverConfig, ...this.#mergeResolveOptions(resolveOptions) }\n );\n }\n\n fetchByDestinationPath(\n options: RuntimeFetchByDestinationPathOptions,\n resolveOptions?: RuntimeResolveOptions\n ): Promise<PortableRenderPlan | DestinationRedirectResult> {\n return fetchExperience(\n { spaceId: this.spaceId, destinationId: options.destinationId, path: options.path },\n { client: this.#deliveryClient },\n { config: this.#resolverConfig, ...this.#mergeResolveOptions(resolveOptions) }\n );\n }\n\n #mergeResolveOptions(options: RuntimeResolveOptions | undefined): RuntimeResolveOptions {\n return {\n metadata: { ...this.#resolveDefaults.metadata, ...options?.metadata },\n debug: options?.debug ?? this.#resolveDefaults.debug,\n };\n }\n}\n"],"mappings":"AACA,SAAS,qBAAqB,6BAA6B;AAM3D,OAAO,kBAAkB;AAEzB;AAAA,EACE;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAIK;AACP;AAAA,EACE;AAAA,OAEK;AACP,SAAS,oBAAoB;AAC7B,SAAS,qCAAqC;AAC9C;AAAA,EACE;AAAA,OAKK;AAqEA,MAAM,sBAAmD;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACU;AAAA,EACV;AAAA,EAET,YAAY,QAAqC;AAC/C,SAAK,UAAU,OAAO;AACtB,SAAK,gBAAgB,OAAO;AAC5B,SAAK,UAAU,OAAO;AACtB,SAAK,kBAAkB,OAAO;AAC9B,SAAK,kBAAkB,4BAA4B,OAAO,QAAQ;AAClE,SAAK,iBACH,OAAO,YAAY,SACf,SACA,4BAA4B,OAAO,SAAS,YAAY;AAC9D,SAAK,kBAAkB,gCAAgC;AAAA,MACrD,SAAS,OAAO;AAAA,MAChB,eAAe,OAAO;AAAA,MACtB,GAAG,OAAO;AAAA,IACZ,CAAC;AACD,SAAK,mBAAmB,OAAO,mBAAmB,CAAC;AAEnD,SAAK,eAAe,IAAI,aAAa;AAAA,MACnC,GAAG,OAAO;AAAA,MACV,SAAS,EAAE,GAAG,+BAA+B,GAAG,OAAO,aAAa,QAAQ;AAAA,MAC5E,WAAW,OAAO,aAAa,cAAc,MAAM,KAAK;AAAA,IAC1D,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,SAA6B;AAC/B,WAAO,KAAK;AAAA,EACd;AAAA,EAEU,mBACR,UACA,UACqB;AACrB,WAAO,0BAA0B,KAAK,iBAAiB,KAAK,cAAc,UAAU,QAAQ;AAAA,EAC9F;AAAA,EAEA,kBACE,SACA,gBAC6B;AAC7B,WAAO;AAAA,MACL;AAAA,MACA,KAAK;AAAA,MACL,KAAK,qBAAqB,cAAc;AAAA,IAC1C;AAAA,EACF;AAAA,EAEA,gBACE,SACA,gBAC6B;AAC7B,QAAI,QAAQ,YAAY,QAAQ,KAAK,mBAAmB,QAAW;AACjE,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL;AAAA,QACE,SAAS,KAAK;AAAA,QACd,eAAe,KAAK;AAAA,QACpB,cAAc,QAAQ;AAAA,QACtB,QAAQ,QAAQ,UAAU,KAAK;AAAA,QAC/B,iBAAiB,QAAQ;AAAA,QACzB,YAAY,QAAQ;AAAA,MACtB;AAAA,MACA;AAAA,QACE,QAAQ,QAAQ,UACX,KAAK,iBACN,KAAK;AAAA,MACX;AAAA,MACA,EAAE,QAAQ,KAAK,iBAAiB,GAAG,KAAK,qBAAqB,cAAc,EAAE;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,uBACE,SACA,gBACyD;AACzD,WAAO;AAAA,MACL,EAAE,SAAS,KAAK,SAAS,eAAe,QAAQ,eAAe,QAAQ,QAAQ,OAAO;AAAA,MACtF,EAAE,QAAQ,KAAK,gBAAgB;AAAA,MAC/B,EAAE,QAAQ,KAAK,iBAAiB,GAAG,KAAK,qBAAqB,cAAc,EAAE;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,uBACE,SACA,gBACyD;AACzD,WAAO;AAAA,MACL,EAAE,SAAS,KAAK,SAAS,eAAe,QAAQ,eAAe,MAAM,QAAQ,KAAK;AAAA,MAClF,EAAE,QAAQ,KAAK,gBAAgB;AAAA,MAC/B,EAAE,QAAQ,KAAK,iBAAiB,GAAG,KAAK,qBAAqB,cAAc,EAAE;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,qBAAqB,SAAmE;AACtF,WAAO;AAAA,MACL,UAAU,EAAE,GAAG,KAAK,iBAAiB,UAAU,GAAG,SAAS,SAAS;AAAA,MACpE,OAAO,SAAS,SAAS,KAAK,iBAAiB;AAAA,IACjD;AAAA,EACF;AACF;","names":[]}
|
|
@@ -90,12 +90,6 @@ type ResolveOptions = {
|
|
|
90
90
|
* debug fallback). A single boolean across fetch + resolve + render.
|
|
91
91
|
*/
|
|
92
92
|
debug?: boolean;
|
|
93
|
-
/**
|
|
94
|
-
* Per-request fallback viewport for server-side design pre-resolution. Pass
|
|
95
|
-
* the same id you seed the renderer's `initialViewportId` with (e.g. a
|
|
96
|
-
* User-Agent-derived viewport) so SSR paints correct design on first render.
|
|
97
|
-
*/
|
|
98
|
-
initialViewportId?: string;
|
|
99
93
|
};
|
|
100
94
|
declare function fetchExperience(experienceOptions: ByIdExperienceOptions, clientOptions: ClientOptions, resolveOptions: ResolveOptions): Promise<PortableRenderPlan>;
|
|
101
95
|
declare function fetchExperience(experienceOptions: ByDestinationNodeIdExperienceOptions, clientOptions: ClientOptions, resolveOptions: ResolveOptions): Promise<PortableRenderPlan | DestinationRedirectResult>;
|
package/dist/fetch-experience.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
toExperiencePayloadFromDestination
|
|
10
10
|
} from "./to-experience-payload.js";
|
|
11
11
|
async function fetchExperience(experienceOptions, clientOptions, resolveOptions) {
|
|
12
|
-
const { config, metadata, debug
|
|
12
|
+
const { config, metadata, debug } = resolveOptions;
|
|
13
13
|
const log = createDebugLogger(debug, "client");
|
|
14
14
|
if (!("client" in clientOptions) && clientOptions.preview && "destinationId" in experienceOptions) {
|
|
15
15
|
const { spaceId: spaceId2, destinationId } = experienceOptions;
|
|
@@ -43,7 +43,7 @@ async function fetchExperience(experienceOptions, clientOptions, resolveOptions)
|
|
|
43
43
|
{ spaceId: spaceId2, destinationId, locator: nodeId },
|
|
44
44
|
() => client.destination.resolveByNodeId(spaceId2, destinationId, nodeId),
|
|
45
45
|
log,
|
|
46
|
-
{ config, metadata, debug
|
|
46
|
+
{ config, metadata, debug }
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
if ("path" in experienceOptions) {
|
|
@@ -52,7 +52,7 @@ async function fetchExperience(experienceOptions, clientOptions, resolveOptions)
|
|
|
52
52
|
{ spaceId: spaceId2, destinationId, locator: path },
|
|
53
53
|
() => client.destination.resolveByPath(spaceId2, destinationId, { path }),
|
|
54
54
|
log,
|
|
55
|
-
{ config, metadata, debug
|
|
55
|
+
{ config, metadata, debug }
|
|
56
56
|
);
|
|
57
57
|
}
|
|
58
58
|
const { spaceId, environmentId, experienceId, locale, personalization, extensions } = experienceOptions;
|
|
@@ -72,7 +72,6 @@ async function fetchExperience(experienceOptions, clientOptions, resolveOptions)
|
|
|
72
72
|
return resolveExperience(payload, config, {
|
|
73
73
|
metadata,
|
|
74
74
|
debug,
|
|
75
|
-
initialViewportId,
|
|
76
75
|
sourceMap
|
|
77
76
|
});
|
|
78
77
|
}
|
|
@@ -103,7 +102,7 @@ async function fetchByExperienceId(client, options) {
|
|
|
103
102
|
}
|
|
104
103
|
async function fetchByDestination(identity, resolve, log, resolveOptions) {
|
|
105
104
|
const { spaceId, destinationId, locator } = identity;
|
|
106
|
-
const { config, metadata, debug
|
|
105
|
+
const { config, metadata, debug } = resolveOptions;
|
|
107
106
|
log.log("resolving destination experience", { spaceId, destinationId, locator });
|
|
108
107
|
let response;
|
|
109
108
|
try {
|
|
@@ -133,8 +132,7 @@ async function fetchByDestination(identity, resolve, log, resolveOptions) {
|
|
|
133
132
|
log.lazy("received raw payload", () => payload);
|
|
134
133
|
return resolveExperience(payload, config, {
|
|
135
134
|
metadata,
|
|
136
|
-
debug
|
|
137
|
-
initialViewportId
|
|
135
|
+
debug
|
|
138
136
|
});
|
|
139
137
|
}
|
|
140
138
|
function hasRequestExtensions(extensions) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fetch-experience.ts"],"sourcesContent":["import type { ContentfulViewDeliveryClient } from '@contentful/experience-delivery';\nimport { ContentfulViewDelivery } from '@contentful/experience-delivery';\nimport { createDebugLogger, resolveExperience } from '@contentful/experiences-sdk-core';\nimport type { PortableRenderPlan, ResolverConfig } from '@contentful/experiences-sdk-core';\nimport { createClient } from './create-delivery-client.js';\nimport { DestinationPreviewNotSupportedError, ExperienceFetchError } from './errors.js';\nimport { PREVIEW_HOST } from './hosts.js';\nimport {\n readSourceMap,\n toExperiencePayload,\n toExperiencePayloadFromDestination,\n type ExperienceResponse,\n} from './to-experience-payload.js';\n\ntype DeliveryExperienceRequestExtensions =\n ContentfulViewDelivery.GetWithOverridesExperienceRequestExtensions;\n\nexport type PersonalizationOptions = NonNullable<\n DeliveryExperienceRequestExtensions['personalization']\n>;\n\nexport type ExperienceRequestExtensions = Omit<\n DeliveryExperienceRequestExtensions,\n 'personalization'\n>;\n\nexport type ByIdExperienceOptions = {\n spaceId: string;\n environmentId: string;\n experienceId: string;\n locale?: string;\n /**\n * Profile and events used by XDA to personalize the resolved Experience.\n */\n personalization?: PersonalizationOptions;\n /**\n * Additional XDA request extensions such as source maps. Supplying a defined\n * extension switches the request to POST.\n */\n extensions?: ExperienceRequestExtensions;\n};\n\n/**\n * Resolve an Experience by the Destination Node instead of `experienceId`\n * The destinations delivery endpoints are space-scoped only and have no locale\n * param, unlike the by-id path.\n */\nexport type ByDestinationNodeIdExperienceOptions = {\n spaceId: string;\n destinationId: string;\n nodeId: string;\n};\n\n/**\n * Resolve an Experience by the absolute path wired up to a\n * Destination Node, instead of a node id directly. Same scoping as\n * `ByDestinationNodeIdExperienceOptions` — no `environmentId` or `locale`.\n */\nexport type ByDestinationPathExperienceOptions = {\n spaceId: string;\n destinationId: string;\n /** Absolute path to resolve. Must start with `/`. */\n path: string;\n};\n\nexport type ExperienceOptions =\n ByIdExperienceOptions | ByDestinationNodeIdExperienceOptions | ByDestinationPathExperienceOptions;\n\n/**\n * A Destination resolution that the app must act on as control flow — honor\n * it by navigating or re-resolving at the new path — rather than a hydrated\n * Experience to render. Modeled as a normal return value, not a thrown error,\n * per the Destinations delivery API's own framing of a redirect response.\n */\nexport interface DestinationRedirectResult {\n redirect: { path: string };\n}\n\nexport type ClientOptions =\n | {\n accessToken: string;\n /**\n * Preview access token. Required when calling with `preview: true`.\n */\n previewToken?: string;\n /**\n * Flip between delivery (default) and preview at request time. When\n * `true`, `fetchExperience` uses `previewToken` and the preview host;\n * when `false` or unset, it uses `accessToken` and the delivery host.\n * Ignored when a pre-made `client` is passed instead of inline creds.\n */\n preview?: boolean;\n /**\n * Custom base URL for the delivery client (staging, proxy, per-region).\n * Wins over the `preview`-derived default host — combine `host` with\n * `preview: true` to point preview mode at a non-prod endpoint.\n * Omit for the standard delivery / preview hosts.\n */\n host?: string;\n }\n | { client: ContentfulViewDeliveryClient };\n\nexport type ResolveOptions = {\n config: ResolverConfig;\n /**\n * Arbitrary per-render metadata exposed to every resolver as\n * `ctx.experience.metadata` and readable at render time via the framework\n * adapter's `useExperience()` / `getExperience()`.\n */\n metadata?: Record<string, unknown>;\n /**\n * Observability switch. When on: logs the fetch (host, ids) and the raw\n * payload here, and threads through to `resolveExperience` (resolution steps\n * + `resolveData` timings) and the renderer (visible missing-component box,\n * debug fallback). A single boolean across fetch + resolve + render.\n */\n debug?: boolean;\n /**\n * Per-request fallback viewport for server-side design pre-resolution. Pass\n * the same id you seed the renderer's `initialViewportId` with (e.g. a\n * User-Agent-derived viewport) so SSR paints correct design on first render.\n */\n initialViewportId?: string;\n};\n\n// TS overload signatures, not real redeclarations — base ESLint's no-redeclare doesn't know the\n// overload form (@typescript-eslint's own version does), so each repeated signature needs a\n// disable comment.\nexport async function fetchExperience(\n experienceOptions: ByIdExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ByDestinationNodeIdExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ByDestinationPathExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult> {\n const { config, metadata, debug, initialViewportId } = resolveOptions;\n const log = createDebugLogger(debug, 'client');\n\n if (\n !('client' in clientOptions) &&\n clientOptions.preview &&\n 'destinationId' in experienceOptions\n ) {\n const { spaceId, destinationId } = experienceOptions;\n const locator =\n 'nodeId' in experienceOptions\n ? { nodeId: experienceOptions.nodeId }\n : { path: experienceOptions.path };\n throw new DestinationPreviewNotSupportedError(\n `fetchExperience() called with preview: true and a destination-shaped experienceOptions ` +\n `(destinationId \"${destinationId}\"). The Destinations Delivery API does not support ` +\n `preview mode yet — pass preview: false (or omit it) for destination-based fetches.`,\n { spaceId, destinationId, ...locator }\n );\n }\n\n let client: ContentfulViewDeliveryClient;\n if ('client' in clientOptions) {\n client = clientOptions.client;\n log.log('using caller-supplied delivery client');\n } else {\n const { accessToken, previewToken, preview, host } = clientOptions;\n if (preview && !previewToken) {\n throw new Error(\n 'fetchExperience() called with preview: true but no previewToken was provided'\n );\n }\n const resolvedHost = host ?? (preview ? PREVIEW_HOST : undefined);\n client = createClient({\n accessToken: preview ? (previewToken as string) : accessToken,\n host: resolvedHost,\n });\n log.log('created delivery client', { preview: Boolean(preview), host: resolvedHost });\n }\n\n if ('nodeId' in experienceOptions) {\n const { spaceId, destinationId, nodeId } = experienceOptions;\n return fetchByDestination(\n { spaceId, destinationId, locator: nodeId },\n () => client.destination.resolveByNodeId(spaceId, destinationId, nodeId),\n log,\n { config, metadata, debug, initialViewportId }\n );\n }\n\n if ('path' in experienceOptions) {\n const { spaceId, destinationId, path } = experienceOptions;\n return fetchByDestination(\n { spaceId, destinationId, locator: path },\n () => client.destination.resolveByPath(spaceId, destinationId, { path }),\n log,\n { config, metadata, debug, initialViewportId }\n );\n }\n\n const { spaceId, environmentId, experienceId, locale, personalization, extensions } =\n experienceOptions;\n\n log.log('fetching experience', {\n spaceId,\n environmentId,\n experienceId,\n locale,\n // avoiding log any personalization sensitive data\n personalization: personalization !== undefined,\n extensions,\n });\n\n const response = await fetchByExperienceId(client, experienceOptions);\n\n const payload = toExperiencePayload(response);\n const sourceMap = extensions?.sourceMap !== undefined ? readSourceMap(response) : undefined;\n\n log.lazy('received raw payload', () => payload);\n\n return resolveExperience(payload, config, {\n metadata,\n debug,\n initialViewportId,\n sourceMap,\n });\n}\n\nasync function fetchByExperienceId(\n client: ContentfulViewDeliveryClient,\n options: ByIdExperienceOptions\n): Promise<ExperienceResponse> {\n const { spaceId, environmentId, experienceId, locale, personalization, extensions } = options;\n const requestExtensions: DeliveryExperienceRequestExtensions = {\n ...extensions,\n ...(personalization === undefined ? {} : { personalization }),\n };\n\n try {\n // Both methods hit the same endpoint, but only the POST operation accepts\n // extensions in its request body. Keep the cacheable GET when there are no\n // extensions to evaluate.\n // The generated delivery client owns the alpha-feature header on both\n // paths, including when the caller supplied the client instance.\n //\n // Await inside the try so rejected requests are normalized below.\n if (hasRequestExtensions(requestExtensions)) {\n return await client.experience.getWithOverrides(spaceId, environmentId, experienceId, {\n locale,\n extensions: requestExtensions,\n });\n }\n\n return await client.experience.get(spaceId, environmentId, experienceId, { locale });\n } catch (err) {\n // Preserve expected 404 control flow for framework routers. Other failures\n // are wrapped with stable SDK context instead of exposing transport-specific\n // error shapes.\n if (err instanceof ContentfulViewDelivery.NotFoundError) {\n throw err;\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new ExperienceFetchError(\n `Failed to fetch Experience \"${experienceId}\" (space \"${spaceId}\", environment ` +\n `\"${environmentId}\"): ${reason}. Check network connectivity, the access token, and ` +\n `that the space/environment/experience ids are correct.`,\n { spaceId, environmentId, experienceId, cause: err }\n );\n }\n}\n\n/**\n * Shared response-handling for both destination-shaped `fetchExperience`\n * branches (by node id, by path).\n */\nasync function fetchByDestination(\n identity: { spaceId: string; destinationId: string; locator: string },\n resolve: () => Promise<ContentfulViewDelivery.DestinationExperienceResolutionResponse>,\n log: ReturnType<typeof createDebugLogger>,\n resolveOptions: {\n config: ResolverConfig;\n metadata: Record<string, unknown> | undefined;\n debug: boolean | undefined;\n initialViewportId: string | undefined;\n }\n): Promise<PortableRenderPlan | DestinationRedirectResult> {\n const { spaceId, destinationId, locator } = identity;\n const { config, metadata, debug, initialViewportId } = resolveOptions;\n\n log.log('resolving destination experience', { spaceId, destinationId, locator });\n\n let response: ContentfulViewDelivery.DestinationExperienceResolutionResponse;\n try {\n response = await resolve();\n } catch (err) {\n if (err instanceof ContentfulViewDelivery.NotFoundError) {\n throw err;\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new ExperienceFetchError(\n `Failed to resolve Destination \"${destinationId}\" at \"${locator}\" (space \"${spaceId}\"): ` +\n `${reason}. Check network connectivity, the access token, and that the space/` +\n `destination/node-or-path values are correct.`,\n { spaceId, experienceId: locator, cause: err }\n );\n }\n\n if ('redirect' in response) {\n log.log('destination resolved to a redirect', response.redirect);\n return { redirect: response.redirect };\n }\n\n const [firstExperience] = response.experiences;\n if (!firstExperience) {\n throw new ExperienceFetchError(\n `Destination \"${destinationId}\" resolved \"${locator}\" to zero Experiences ` +\n `(space \"${spaceId}\"). Expected exactly one hydrated Experience or a redirect.`,\n { spaceId, experienceId: locator }\n );\n }\n\n const payload = toExperiencePayloadFromDestination(firstExperience.experience);\n log.lazy('received raw payload', () => payload);\n\n return resolveExperience(payload, config, {\n metadata,\n debug,\n initialViewportId,\n });\n}\n\nfunction hasRequestExtensions(\n extensions: DeliveryExperienceRequestExtensions | undefined\n): extensions is DeliveryExperienceRequestExtensions {\n return (\n extensions !== undefined &&\n Object.values(extensions).some((extension) => extension !== undefined)\n );\n}\n"],"mappings":"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","names":["spaceId"]}
|
|
1
|
+
{"version":3,"sources":["../src/fetch-experience.ts"],"sourcesContent":["import type { ContentfulViewDeliveryClient } from '@contentful/experience-delivery';\nimport { ContentfulViewDelivery } from '@contentful/experience-delivery';\nimport { createDebugLogger, resolveExperience } from '@contentful/experiences-sdk-core';\nimport type { PortableRenderPlan, ResolverConfig } from '@contentful/experiences-sdk-core';\nimport { createClient } from './create-delivery-client.js';\nimport { DestinationPreviewNotSupportedError, ExperienceFetchError } from './errors.js';\nimport { PREVIEW_HOST } from './hosts.js';\nimport {\n readSourceMap,\n toExperiencePayload,\n toExperiencePayloadFromDestination,\n type ExperienceResponse,\n} from './to-experience-payload.js';\n\ntype DeliveryExperienceRequestExtensions =\n ContentfulViewDelivery.GetWithOverridesExperienceRequestExtensions;\n\nexport type PersonalizationOptions = NonNullable<\n DeliveryExperienceRequestExtensions['personalization']\n>;\n\nexport type ExperienceRequestExtensions = Omit<\n DeliveryExperienceRequestExtensions,\n 'personalization'\n>;\n\nexport type ByIdExperienceOptions = {\n spaceId: string;\n environmentId: string;\n experienceId: string;\n locale?: string;\n /**\n * Profile and events used by XDA to personalize the resolved Experience.\n */\n personalization?: PersonalizationOptions;\n /**\n * Additional XDA request extensions such as source maps. Supplying a defined\n * extension switches the request to POST.\n */\n extensions?: ExperienceRequestExtensions;\n};\n\n/**\n * Resolve an Experience by the Destination Node instead of `experienceId`\n * The destinations delivery endpoints are space-scoped only and have no locale\n * param, unlike the by-id path.\n */\nexport type ByDestinationNodeIdExperienceOptions = {\n spaceId: string;\n destinationId: string;\n nodeId: string;\n};\n\n/**\n * Resolve an Experience by the absolute path wired up to a\n * Destination Node, instead of a node id directly. Same scoping as\n * `ByDestinationNodeIdExperienceOptions` — no `environmentId` or `locale`.\n */\nexport type ByDestinationPathExperienceOptions = {\n spaceId: string;\n destinationId: string;\n /** Absolute path to resolve. Must start with `/`. */\n path: string;\n};\n\nexport type ExperienceOptions =\n ByIdExperienceOptions | ByDestinationNodeIdExperienceOptions | ByDestinationPathExperienceOptions;\n\n/**\n * A Destination resolution that the app must act on as control flow — honor\n * it by navigating or re-resolving at the new path — rather than a hydrated\n * Experience to render. Modeled as a normal return value, not a thrown error,\n * per the Destinations delivery API's own framing of a redirect response.\n */\nexport interface DestinationRedirectResult {\n redirect: { path: string };\n}\n\nexport type ClientOptions =\n | {\n accessToken: string;\n /**\n * Preview access token. Required when calling with `preview: true`.\n */\n previewToken?: string;\n /**\n * Flip between delivery (default) and preview at request time. When\n * `true`, `fetchExperience` uses `previewToken` and the preview host;\n * when `false` or unset, it uses `accessToken` and the delivery host.\n * Ignored when a pre-made `client` is passed instead of inline creds.\n */\n preview?: boolean;\n /**\n * Custom base URL for the delivery client (staging, proxy, per-region).\n * Wins over the `preview`-derived default host — combine `host` with\n * `preview: true` to point preview mode at a non-prod endpoint.\n * Omit for the standard delivery / preview hosts.\n */\n host?: string;\n }\n | { client: ContentfulViewDeliveryClient };\n\nexport type ResolveOptions = {\n config: ResolverConfig;\n /**\n * Arbitrary per-render metadata exposed to every resolver as\n * `ctx.experience.metadata` and readable at render time via the framework\n * adapter's `useExperience()` / `getExperience()`.\n */\n metadata?: Record<string, unknown>;\n /**\n * Observability switch. When on: logs the fetch (host, ids) and the raw\n * payload here, and threads through to `resolveExperience` (resolution steps\n * + `resolveData` timings) and the renderer (visible missing-component box,\n * debug fallback). A single boolean across fetch + resolve + render.\n */\n debug?: boolean;\n};\n\n// TS overload signatures, not real redeclarations — base ESLint's no-redeclare doesn't know the\n// overload form (@typescript-eslint's own version does), so each repeated signature needs a\n// disable comment.\nexport async function fetchExperience(\n experienceOptions: ByIdExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ByDestinationNodeIdExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ByDestinationPathExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult>;\n// eslint-disable-next-line no-redeclare -- see above\nexport async function fetchExperience(\n experienceOptions: ExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan | DestinationRedirectResult> {\n const { config, metadata, debug } = resolveOptions;\n const log = createDebugLogger(debug, 'client');\n\n if (\n !('client' in clientOptions) &&\n clientOptions.preview &&\n 'destinationId' in experienceOptions\n ) {\n const { spaceId, destinationId } = experienceOptions;\n const locator =\n 'nodeId' in experienceOptions\n ? { nodeId: experienceOptions.nodeId }\n : { path: experienceOptions.path };\n throw new DestinationPreviewNotSupportedError(\n `fetchExperience() called with preview: true and a destination-shaped experienceOptions ` +\n `(destinationId \"${destinationId}\"). The Destinations Delivery API does not support ` +\n `preview mode yet — pass preview: false (or omit it) for destination-based fetches.`,\n { spaceId, destinationId, ...locator }\n );\n }\n\n let client: ContentfulViewDeliveryClient;\n if ('client' in clientOptions) {\n client = clientOptions.client;\n log.log('using caller-supplied delivery client');\n } else {\n const { accessToken, previewToken, preview, host } = clientOptions;\n if (preview && !previewToken) {\n throw new Error(\n 'fetchExperience() called with preview: true but no previewToken was provided'\n );\n }\n const resolvedHost = host ?? (preview ? PREVIEW_HOST : undefined);\n client = createClient({\n accessToken: preview ? (previewToken as string) : accessToken,\n host: resolvedHost,\n });\n log.log('created delivery client', { preview: Boolean(preview), host: resolvedHost });\n }\n\n if ('nodeId' in experienceOptions) {\n const { spaceId, destinationId, nodeId } = experienceOptions;\n return fetchByDestination(\n { spaceId, destinationId, locator: nodeId },\n () => client.destination.resolveByNodeId(spaceId, destinationId, nodeId),\n log,\n { config, metadata, debug }\n );\n }\n\n if ('path' in experienceOptions) {\n const { spaceId, destinationId, path } = experienceOptions;\n return fetchByDestination(\n { spaceId, destinationId, locator: path },\n () => client.destination.resolveByPath(spaceId, destinationId, { path }),\n log,\n { config, metadata, debug }\n );\n }\n\n const { spaceId, environmentId, experienceId, locale, personalization, extensions } =\n experienceOptions;\n\n log.log('fetching experience', {\n spaceId,\n environmentId,\n experienceId,\n locale,\n // avoiding log any personalization sensitive data\n personalization: personalization !== undefined,\n extensions,\n });\n\n const response = await fetchByExperienceId(client, experienceOptions);\n\n const payload = toExperiencePayload(response);\n const sourceMap = extensions?.sourceMap !== undefined ? readSourceMap(response) : undefined;\n\n log.lazy('received raw payload', () => payload);\n\n return resolveExperience(payload, config, {\n metadata,\n debug,\n sourceMap,\n });\n}\n\nasync function fetchByExperienceId(\n client: ContentfulViewDeliveryClient,\n options: ByIdExperienceOptions\n): Promise<ExperienceResponse> {\n const { spaceId, environmentId, experienceId, locale, personalization, extensions } = options;\n const requestExtensions: DeliveryExperienceRequestExtensions = {\n ...extensions,\n ...(personalization === undefined ? {} : { personalization }),\n };\n\n try {\n // Both methods hit the same endpoint, but only the POST operation accepts\n // extensions in its request body. Keep the cacheable GET when there are no\n // extensions to evaluate.\n // The generated delivery client owns the alpha-feature header on both\n // paths, including when the caller supplied the client instance.\n //\n // Await inside the try so rejected requests are normalized below.\n if (hasRequestExtensions(requestExtensions)) {\n return await client.experience.getWithOverrides(spaceId, environmentId, experienceId, {\n locale,\n extensions: requestExtensions,\n });\n }\n\n return await client.experience.get(spaceId, environmentId, experienceId, { locale });\n } catch (err) {\n // Preserve expected 404 control flow for framework routers. Other failures\n // are wrapped with stable SDK context instead of exposing transport-specific\n // error shapes.\n if (err instanceof ContentfulViewDelivery.NotFoundError) {\n throw err;\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new ExperienceFetchError(\n `Failed to fetch Experience \"${experienceId}\" (space \"${spaceId}\", environment ` +\n `\"${environmentId}\"): ${reason}. Check network connectivity, the access token, and ` +\n `that the space/environment/experience ids are correct.`,\n { spaceId, environmentId, experienceId, cause: err }\n );\n }\n}\n\n/**\n * Shared response-handling for both destination-shaped `fetchExperience`\n * branches (by node id, by path).\n */\nasync function fetchByDestination(\n identity: { spaceId: string; destinationId: string; locator: string },\n resolve: () => Promise<ContentfulViewDelivery.DestinationExperienceResolutionResponse>,\n log: ReturnType<typeof createDebugLogger>,\n resolveOptions: {\n config: ResolverConfig;\n metadata: Record<string, unknown> | undefined;\n debug: boolean | undefined;\n }\n): Promise<PortableRenderPlan | DestinationRedirectResult> {\n const { spaceId, destinationId, locator } = identity;\n const { config, metadata, debug } = resolveOptions;\n\n log.log('resolving destination experience', { spaceId, destinationId, locator });\n\n let response: ContentfulViewDelivery.DestinationExperienceResolutionResponse;\n try {\n response = await resolve();\n } catch (err) {\n if (err instanceof ContentfulViewDelivery.NotFoundError) {\n throw err;\n }\n const reason = err instanceof Error ? err.message : String(err);\n throw new ExperienceFetchError(\n `Failed to resolve Destination \"${destinationId}\" at \"${locator}\" (space \"${spaceId}\"): ` +\n `${reason}. Check network connectivity, the access token, and that the space/` +\n `destination/node-or-path values are correct.`,\n { spaceId, experienceId: locator, cause: err }\n );\n }\n\n if ('redirect' in response) {\n log.log('destination resolved to a redirect', response.redirect);\n return { redirect: response.redirect };\n }\n\n const [firstExperience] = response.experiences;\n if (!firstExperience) {\n throw new ExperienceFetchError(\n `Destination \"${destinationId}\" resolved \"${locator}\" to zero Experiences ` +\n `(space \"${spaceId}\"). Expected exactly one hydrated Experience or a redirect.`,\n { spaceId, experienceId: locator }\n );\n }\n\n const payload = toExperiencePayloadFromDestination(firstExperience.experience);\n log.lazy('received raw payload', () => payload);\n\n return resolveExperience(payload, config, {\n metadata,\n debug,\n });\n}\n\nfunction hasRequestExtensions(\n extensions: DeliveryExperienceRequestExtensions | undefined\n): extensions is DeliveryExperienceRequestExtensions {\n return (\n extensions !== undefined &&\n Object.values(extensions).some((extension) => extension !== undefined)\n );\n}\n"],"mappings":"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","names":["spaceId"]}
|
package/dist/sdk-info.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experiences-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Delivery client + fetchExperience for Contentful Experiences",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@contentful/experience-delivery": "1.0.0-dev.9",
|
|
34
|
-
"@contentful/experiences-sdk-core": "0.
|
|
34
|
+
"@contentful/experiences-sdk-core": "0.12.0",
|
|
35
35
|
"@contentful/optimization-api-client": "^2.0.1",
|
|
36
36
|
"es-toolkit": "^1.46.0",
|
|
37
37
|
"zod": "^4.3.6"
|