@contentful/experiences-client 0.3.10 → 0.3.11
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 +10 -0
- package/dist/errors.d.ts +26 -0
- package/dist/errors.js +16 -0
- package/dist/errors.js.map +1 -0
- package/dist/fetch-experience.js +15 -1
- package/dist/fetch-experience.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 0.3.11 (2026-08-28)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- error handling and sensible fallbacks for non-happy-path rendering [AIS-364] ([#156](https://github.com/contentful/experiences/pull/156))
|
|
6
|
+
|
|
7
|
+
### 🧱 Updated Dependencies
|
|
8
|
+
|
|
9
|
+
- Updated core to 0.7.11
|
|
10
|
+
|
|
1
11
|
## 0.3.10 (2026-08-27)
|
|
2
12
|
|
|
3
13
|
### 🧱 Updated Dependencies
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Thrown by `fetchExperience` for a fetch failure that is not "experience not
|
|
3
|
+
* found" — network failure, an invalid/expired token, a 5xx from the
|
|
4
|
+
* delivery API, etc. This failure mode is "surface clearly to the host app,"
|
|
5
|
+
* unlike the diagnostics `resolveExperience` collects for resolve/render-time
|
|
6
|
+
* issues — there's no partial payload to render around a fetch that never
|
|
7
|
+
* returned one, so a real thrown class is the right shape.
|
|
8
|
+
*
|
|
9
|
+
* `NotFoundError` (the delivery client's class, re-exported from this
|
|
10
|
+
* package) is the one exception: it passes through undisturbed so callers
|
|
11
|
+
* can route it to their framework's 404 idiom, per the existing
|
|
12
|
+
* distinguishable-404 contract.
|
|
13
|
+
*/
|
|
14
|
+
declare class ExperienceFetchError extends Error {
|
|
15
|
+
readonly spaceId: string;
|
|
16
|
+
readonly environmentId: string;
|
|
17
|
+
readonly experienceId: string;
|
|
18
|
+
constructor(message: string, options: {
|
|
19
|
+
spaceId: string;
|
|
20
|
+
environmentId: string;
|
|
21
|
+
experienceId: string;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { ExperienceFetchError };
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class ExperienceFetchError extends Error {
|
|
2
|
+
spaceId;
|
|
3
|
+
environmentId;
|
|
4
|
+
experienceId;
|
|
5
|
+
constructor(message, options) {
|
|
6
|
+
super(message, options.cause !== void 0 ? { cause: options.cause } : void 0);
|
|
7
|
+
this.name = "ExperienceFetchError";
|
|
8
|
+
this.spaceId = options.spaceId;
|
|
9
|
+
this.environmentId = options.environmentId;
|
|
10
|
+
this.experienceId = options.experienceId;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export {
|
|
14
|
+
ExperienceFetchError
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Thrown by `fetchExperience` for a fetch failure that is not \"experience not\n * found\" — network failure, an invalid/expired token, a 5xx from the\n * delivery API, etc. This failure mode is \"surface clearly to the host app,\"\n * unlike the diagnostics `resolveExperience` collects for resolve/render-time\n * issues — there's no partial payload to render around a fetch that never\n * returned one, so a real thrown class is the right shape.\n *\n * `NotFoundError` (the delivery client's class, re-exported from this\n * package) is the one exception: it passes through undisturbed so callers\n * can route it to their framework's 404 idiom, per the existing\n * distinguishable-404 contract.\n */\nexport class ExperienceFetchError extends Error {\n readonly spaceId: string;\n readonly environmentId: string;\n readonly experienceId: string;\n\n constructor(\n message: string,\n options: {\n spaceId: string;\n environmentId: string;\n experienceId: string;\n cause?: unknown;\n }\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = 'ExperienceFetchError';\n this.spaceId = options.spaceId;\n this.environmentId = options.environmentId;\n this.experienceId = options.experienceId;\n }\n}\n"],"mappings":"AAaO,MAAM,6BAA6B,MAAM;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,SACA,SAMA;AACA,UAAM,SAAS,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,MAAS;AACjF,SAAK,OAAO;AACZ,SAAK,UAAU,QAAQ;AACvB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,eAAe,QAAQ;AAAA,EAC9B;AACF;","names":[]}
|
package/dist/fetch-experience.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { ContentfulViewDelivery } from "@contentful/experience-delivery";
|
|
1
2
|
import { createDebugLogger, resolveExperience } from "@contentful/experiences-sdk-core";
|
|
2
3
|
import { createClient } from "./create-client.js";
|
|
4
|
+
import { ExperienceFetchError } from "./errors.js";
|
|
3
5
|
import { PREVIEW_HOST } from "./hosts.js";
|
|
4
6
|
async function fetchExperience(experienceOptions, clientOptions, resolveOptions) {
|
|
5
7
|
const { spaceId, environmentId, experienceId, locale } = experienceOptions;
|
|
@@ -24,7 +26,19 @@ async function fetchExperience(experienceOptions, clientOptions, resolveOptions)
|
|
|
24
26
|
log.log("created delivery client", { preview: Boolean(preview), host: resolvedHost });
|
|
25
27
|
}
|
|
26
28
|
log.log("fetching experience", { spaceId, environmentId, experienceId, locale });
|
|
27
|
-
|
|
29
|
+
let response;
|
|
30
|
+
try {
|
|
31
|
+
response = await client.experience.get(spaceId, environmentId, experienceId, { locale });
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (err instanceof ContentfulViewDelivery.NotFoundError) {
|
|
34
|
+
throw err;
|
|
35
|
+
}
|
|
36
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
37
|
+
throw new ExperienceFetchError(
|
|
38
|
+
`Failed to fetch Experience "${experienceId}" (space "${spaceId}", environment "${environmentId}"): ${reason}. Check network connectivity, the access token, and that the space/environment/experience ids are correct.`,
|
|
39
|
+
{ spaceId, environmentId, experienceId, cause: err }
|
|
40
|
+
);
|
|
41
|
+
}
|
|
28
42
|
const payload = response;
|
|
29
43
|
log.lazy("received raw payload", () => payload);
|
|
30
44
|
return resolveExperience(payload, config, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fetch-experience.ts"],"sourcesContent":["import type {
|
|
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 {\n ExperiencePayload,\n PortableRenderPlan,\n ResolverConfig,\n} from '@contentful/experiences-sdk-core';\nimport { createClient } from './create-client.js';\nimport { ExperienceFetchError } from './errors.js';\nimport { PREVIEW_HOST } from './hosts.js';\n\nexport type ExperienceOptions = {\n spaceId: string;\n environmentId: string;\n experienceId: string;\n locale?: 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\nexport async function fetchExperience(\n experienceOptions: ExperienceOptions,\n clientOptions: ClientOptions,\n resolveOptions: ResolveOptions\n): Promise<PortableRenderPlan> {\n const { spaceId, environmentId, experienceId, locale } = experienceOptions;\n const { config, metadata, debug, initialViewportId } = resolveOptions;\n const log = createDebugLogger(debug, 'client');\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 log.log('fetching experience', { spaceId, environmentId, experienceId, locale });\n\n let response: ContentfulViewDelivery.GetExperienceResponse;\n try {\n response = await client.experience.get(spaceId, environmentId, experienceId, { locale });\n } catch (err) {\n // `NotFoundError` is a distinguishable, expected outcome (draft/unpublished/\n // wrong id) — callers already route it to their framework's 404 idiom, so\n // it passes through as-is. Everything else (network failure, bad/expired\n // token, a 5xx) is unexpected and gets wrapped in an actionable error\n // instead of leaking whatever shape the delivery client happened to throw.\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 // The delivery API gates the ExO entity shapes this SDK reads (`component` /\n // `experienceTemplate` links) behind an alpha-feature header. Since\n // `@contentful/experience-delivery@1.0.0-dev.7` the client sends it on every\n // request itself, so a caller-supplied `{ client }` is covered too and we no\n // longer set it here.\n //\n // The client still types `GetExperienceResponse` as a union of every shape the\n // endpoint can return, so the narrowing stays manual. `HydratedExperienceView`\n // is a structural superset of `ExperiencePayload`.\n const payload = response as ContentfulViewDelivery.HydratedExperienceView as ExperiencePayload;\n\n log.lazy('received raw payload', () => payload);\n\n return resolveExperience(payload, config, {\n metadata,\n debug,\n initialViewportId,\n });\n}\n"],"mappings":"AACA,SAAS,8BAA8B;AACvC,SAAS,mBAAmB,yBAAyB;AAMrD,SAAS,oBAAoB;AAC7B,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAwD7B,eAAsB,gBACpB,mBACA,eACA,gBAC6B;AAC7B,QAAM,EAAE,SAAS,eAAe,cAAc,OAAO,IAAI;AACzD,QAAM,EAAE,QAAQ,UAAU,OAAO,kBAAkB,IAAI;AACvD,QAAM,MAAM,kBAAkB,OAAO,QAAQ;AAE7C,MAAI;AACJ,MAAI,YAAY,eAAe;AAC7B,aAAS,cAAc;AACvB,QAAI,IAAI,uCAAuC;AAAA,EACjD,OAAO;AACL,UAAM,EAAE,aAAa,cAAc,SAAS,KAAK,IAAI;AACrD,QAAI,WAAW,CAAC,cAAc;AAC5B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,UAAM,eAAe,SAAS,UAAU,eAAe;AACvD,aAAS,aAAa;AAAA,MACpB,aAAa,UAAW,eAA0B;AAAA,MAClD,MAAM;AAAA,IACR,CAAC;AACD,QAAI,IAAI,2BAA2B,EAAE,SAAS,QAAQ,OAAO,GAAG,MAAM,aAAa,CAAC;AAAA,EACtF;AAEA,MAAI,IAAI,uBAAuB,EAAE,SAAS,eAAe,cAAc,OAAO,CAAC;AAE/E,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,OAAO,WAAW,IAAI,SAAS,eAAe,cAAc,EAAE,OAAO,CAAC;AAAA,EACzF,SAAS,KAAK;AAMZ,QAAI,eAAe,uBAAuB,eAAe;AACvD,YAAM;AAAA,IACR;AACA,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,UAAM,IAAI;AAAA,MACR,+BAA+B,YAAY,aAAa,OAAO,mBACzD,aAAa,OAAO,MAAM;AAAA,MAEhC,EAAE,SAAS,eAAe,cAAc,OAAO,IAAI;AAAA,IACrD;AAAA,EACF;AAWA,QAAM,UAAU;AAEhB,MAAI,KAAK,wBAAwB,MAAM,OAAO;AAE9C,SAAO,kBAAkB,SAAS,QAAQ;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;","names":[]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ContentfulViewDelivery } from '@contentful/experience-delivery';
|
|
2
2
|
export { ContentfulViewDelivery, ContentfulViewDeliveryClient } from '@contentful/experience-delivery';
|
|
3
|
+
export { ExperienceFetchError } from './errors.js';
|
|
3
4
|
export { CreateClientOptions, createClient } from './create-client.js';
|
|
4
5
|
export { ClientOptions, ExperienceOptions, ResolveOptions, fetchExperience } from './fetch-experience.js';
|
|
5
6
|
export { DELIVERY_HOST, PREVIEW_HOST } from './hosts.js';
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
ContentfulViewDeliveryClient
|
|
5
5
|
} from "@contentful/experience-delivery";
|
|
6
6
|
const NotFoundError = ContentfulViewDelivery.NotFoundError;
|
|
7
|
+
import { ExperienceFetchError } from "./errors.js";
|
|
7
8
|
import { createClient } from "./create-client.js";
|
|
8
9
|
import { fetchExperience } from "./fetch-experience.js";
|
|
9
10
|
import { DELIVERY_HOST, PREVIEW_HOST } from "./hosts.js";
|
|
@@ -11,6 +12,7 @@ export {
|
|
|
11
12
|
ContentfulViewDelivery2 as ContentfulViewDelivery,
|
|
12
13
|
ContentfulViewDeliveryClient,
|
|
13
14
|
DELIVERY_HOST,
|
|
15
|
+
ExperienceFetchError,
|
|
14
16
|
NotFoundError,
|
|
15
17
|
PREVIEW_HOST,
|
|
16
18
|
createClient,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { ContentfulViewDelivery } from '@contentful/experience-delivery';\n\nexport {\n ContentfulViewDelivery,\n ContentfulViewDeliveryClient,\n} from '@contentful/experience-delivery';\nexport const NotFoundError = ContentfulViewDelivery.NotFoundError;\nexport type NotFoundError = InstanceType<typeof ContentfulViewDelivery.NotFoundError>;\nexport { createClient } from './create-client.js';\nexport type { CreateClientOptions } from './create-client.js';\nexport { fetchExperience } from './fetch-experience.js';\nexport type { ExperienceOptions, ClientOptions, ResolveOptions } from './fetch-experience.js';\nexport { DELIVERY_HOST, PREVIEW_HOST } from './hosts.js';\n"],"mappings":"AAAA,SAAS,8BAA8B;AAEvC;AAAA,EACE,0BAAAA;AAAA,EACA;AAAA,OACK;AACA,MAAM,gBAAgB,uBAAuB;AAEpD,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,SAAS,eAAe,oBAAoB;","names":["ContentfulViewDelivery"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { ContentfulViewDelivery } from '@contentful/experience-delivery';\n\nexport {\n ContentfulViewDelivery,\n ContentfulViewDeliveryClient,\n} from '@contentful/experience-delivery';\nexport const NotFoundError = ContentfulViewDelivery.NotFoundError;\nexport type NotFoundError = InstanceType<typeof ContentfulViewDelivery.NotFoundError>;\nexport { ExperienceFetchError } from './errors.js';\nexport { createClient } from './create-client.js';\nexport type { CreateClientOptions } from './create-client.js';\nexport { fetchExperience } from './fetch-experience.js';\nexport type { ExperienceOptions, ClientOptions, ResolveOptions } from './fetch-experience.js';\nexport { DELIVERY_HOST, PREVIEW_HOST } from './hosts.js';\n"],"mappings":"AAAA,SAAS,8BAA8B;AAEvC;AAAA,EACE,0BAAAA;AAAA,EACA;AAAA,OACK;AACA,MAAM,gBAAgB,uBAAuB;AAEpD,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAE7B,SAAS,uBAAuB;AAEhC,SAAS,eAAe,oBAAoB;","names":["ContentfulViewDelivery"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/experiences-client",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Delivery client + fetchExperience for Contentful Experiences",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,6 @@
|
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@contentful/experience-delivery": "1.0.0-dev.7",
|
|
34
|
-
"@contentful/experiences-sdk-core": "0.7.
|
|
34
|
+
"@contentful/experiences-sdk-core": "0.7.11"
|
|
35
35
|
}
|
|
36
36
|
}
|