Skip to content

Commit 9f1a236

Browse files
authored
Add support for content metadata (#358)
1 parent 803d7da commit 9f1a236

File tree

7 files changed

+155
-69
lines changed

7 files changed

+155
-69
lines changed

package-lock.json

Lines changed: 51 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
"dependencies": {
4444
"@croct/content": "^1.1.0",
4545
"@croct/json": "^2.1.0",
46-
"@croct/sdk": "^0.19.1",
46+
"@croct/sdk": "^0.20.0",
4747
"tslib": "^2.7.0"
4848
},
4949
"devDependencies": {

src/api/fetchContent.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import {
22
ContentFetcher,
33
DynamicContentOptions as BaseDynamicOptions,
4+
FetchResponseOptions,
45
StaticContentOptions as BaseStaticOptions,
6+
FetchOptions as BaseFetchOptions,
57
} from '@croct/sdk/contentFetcher';
68
import type {ApiKey} from '@croct/sdk/apiKey';
79
import type {Logger} from '@croct/sdk/logging';
@@ -39,10 +41,14 @@ export type StaticContentOptions<T extends JsonObject = JsonObject> =
3941

4042
export type FetchOptions<T extends JsonObject = SlotContent> = DynamicContentOptions<T> | StaticContentOptions<T>;
4143

42-
export function fetchContent<I extends VersionedSlotId, C extends JsonObject>(
44+
export function fetchContent<
45+
I extends VersionedSlotId,
46+
C extends JsonObject,
47+
O extends FetchResponseOptions = FetchResponseOptions
48+
>(
4349
slotId: I,
44-
options?: FetchOptions<SlotContent<I, C>>,
45-
): Promise<Omit<FetchResponse<I, C>, 'payload'>> {
50+
options?: O & FetchOptions<SlotContent<I, C>>,
51+
): Promise<FetchResponse<I, C, never, O>> {
4652
const {
4753
apiKey,
4854
appId,
@@ -57,12 +63,14 @@ export function fetchContent<I extends VersionedSlotId, C extends JsonObject>(
5763
const [id, version = 'latest'] = slotId.split('@') as [I, `${number}` | 'latest' | undefined];
5864
const normalizedLocale = preferredLocale === '' ? undefined : preferredLocale;
5965

66+
const resolvedOptions: BaseFetchOptions = {
67+
...fetchOptions,
68+
...(normalizedLocale !== undefined ? {preferredLocale: normalizedLocale} : {}),
69+
...(version !== 'latest' ? {version: version} : {}),
70+
};
71+
6072
const promise = (new ContentFetcher({...auth, baseEndpointUrl: baseEndpointUrl}))
61-
.fetch<SlotContent<I, C>>(id, {
62-
...fetchOptions,
63-
...(normalizedLocale !== undefined ? {preferredLocale: normalizedLocale} : {}),
64-
...(version !== 'latest' ? {version: version} : {}),
65-
});
73+
.fetch<SlotContent<I, C>, O>(id, resolvedOptions);
6674

6775
return promise.catch(
6876
async error => {

src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import {Configuration, Plug, GlobalPlug} from './plug';
1+
import {Configuration, Plug, GlobalPlug, FetchResponse} from './plug';
22

3-
export type {Configuration, Plug};
3+
export type {Configuration, Plug, FetchResponse};
44

55
/* eslint-disable-next-line import/no-default-export -- Should be default export */
66
export default GlobalPlug.GLOBAL;

src/plug.ts

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
} from '@croct/sdk/trackingEvents';
1616
import {VERSION} from '@croct/sdk';
1717
import {FetchOptions as BaseFetchOptions} from '@croct/sdk/facade/contentFetcherFacade';
18+
import {FetchResponseOptions, FetchResponse as BaseFetchResponse} from '@croct/sdk/contentFetcher';
1819
import {loadSlotContent} from '@croct/content';
1920
import {Plugin, PluginArguments, PluginFactory} from './plugin';
2021
import {CDN_URL} from './constants';
@@ -36,9 +37,12 @@ export type FetchOptions<T> = Omit<BaseFetchOptions, 'version'> & {
3637
fallback?: T,
3738
};
3839

39-
export type FetchResponse<I extends VersionedSlotId, C extends JsonObject = JsonObject, F = never> = {
40-
content: SlotContent<I, C>|F,
41-
};
40+
export type FetchResponse<
41+
I extends VersionedSlotId,
42+
C extends JsonObject = JsonObject,
43+
F = never,
44+
O extends FetchResponseOptions = FetchResponseOptions
45+
> = Optional<BaseFetchResponse<SlotContent<I, C>|F, O>, 'metadata'>;
4246

4347
export interface Plug {
4448
readonly tracker: TrackerFacade;
@@ -66,12 +70,15 @@ export interface Plug {
6670

6771
evaluate<T extends JsonValue>(expression: string, options?: EvaluationOptions): Promise<T>;
6872

69-
fetch<I extends VersionedSlotId>(slotId: I, options?: FetchOptions<SlotContent<I>>): Promise<FetchResponse<I>>;
73+
fetch<I extends VersionedSlotId, O extends FetchResponseOptions>(
74+
slotId: I,
75+
options?: O & FetchOptions<SlotContent<I>>
76+
): Promise<FetchResponse<I, JsonObject, never, O>>;
7077

71-
fetch<F, I extends VersionedSlotId>(
78+
fetch<F, I extends VersionedSlotId, O extends FetchResponseOptions>(
7279
slotId: I,
73-
options?: FetchOptions<SlotContent<I>|F>
74-
): Promise<FetchResponse<I, JsonObject, F>>;
80+
options?: O & FetchOptions<SlotContent<I>|F>
81+
): Promise<FetchResponse<I, JsonObject, F, O>>;
7582

7683
unplug(): Promise<void>;
7784
}
@@ -376,15 +383,15 @@ export class GlobalPlug implements Plug {
376383
.then(result => result === true);
377384
}
378385

379-
public fetch<I extends VersionedSlotId>(
386+
public fetch<I extends VersionedSlotId, O extends FetchResponseOptions>(
380387
slotId: I,
381-
options?: FetchOptions<SlotContent<I>>
382-
): Promise<FetchResponse<I>>;
388+
options?: O & FetchOptions<SlotContent<I>>
389+
): Promise<FetchResponse<I, JsonObject, never, O>>;
383390

384-
public fetch<F, I extends VersionedSlotId>(
391+
public fetch<F, I extends VersionedSlotId, O extends FetchResponseOptions>(
385392
slotId: I,
386-
options?: FetchOptions<SlotContent<I>|F>
387-
): Promise<FetchResponse<I, JsonObject, F>>;
393+
options?: O & FetchOptions<SlotContent<I>|F>
394+
): Promise<FetchResponse<I, JsonObject, F, O>>;
388395

389396
public fetch<I extends VersionedSlotId = VersionedSlotId>(
390397
slotId: I,
@@ -396,7 +403,7 @@ export class GlobalPlug implements Plug {
396403

397404
return this.sdk
398405
.contentFetcher
399-
.fetch<SlotContent<I>>(id, {
406+
.fetch<SlotContent<I>, FetchResponseOptions>(id, {
400407
...options,
401408
...(normalizedLocale !== undefined ? {preferredLocale: normalizedLocale} : {}),
402409
...(version !== 'latest' ? {version: version} : {}),
@@ -412,7 +419,9 @@ export class GlobalPlug implements Plug {
412419
throw error;
413420
}
414421

415-
return {content: resolvedFallback};
422+
return {
423+
content: resolvedFallback,
424+
};
416425
});
417426
}
418427

test/api/fetchContent.test.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import {Logger} from '@croct/sdk/logging';
33
import {JsonObject} from '@croct/json';
44
import {loadSlotContent} from '@croct/content';
55
import {FetchResponse} from '../../src/plug';
6-
import {SlotContent} from '../../src/slot';
6+
import {DynamicSlotId, SlotContent} from '../../src/slot';
77
import {fetchContent, FetchOptions} from '../../src/api';
88

99
const mockFetch: ContentFetcher['fetch'] = jest.fn();
@@ -50,12 +50,15 @@ describe('fetchContent', () => {
5050
},
5151
};
5252

53-
const result: FetchResponse<typeof slotId> = {
53+
const result = {
54+
metadata: {
55+
version: '1.0',
56+
},
5457
content: {
5558
_component: 'component',
5659
id: 'test',
5760
},
58-
};
61+
} satisfies FetchResponse<DynamicSlotId>;
5962

6063
jest.mocked(mockFetch).mockResolvedValue(result);
6164

@@ -82,12 +85,15 @@ describe('fetchContent', () => {
8285
},
8386
};
8487

85-
const result: FetchResponse<typeof slotId> = {
88+
const result = {
89+
metadata: {
90+
version: '1.0',
91+
},
8692
content: {
8793
_component: 'component',
8894
id: 'test',
8995
},
90-
};
96+
} satisfies FetchResponse<DynamicSlotId>;
9197

9298
jest.mocked(mockFetch).mockResolvedValue(result);
9399

@@ -113,12 +119,15 @@ describe('fetchContent', () => {
113119
},
114120
};
115121

116-
const result: FetchResponse<typeof slotId> = {
122+
const result = {
123+
metadata: {
124+
version: '1.0',
125+
},
117126
content: {
118127
_component: 'component',
119128
id: 'test',
120129
},
121-
};
130+
} satisfies FetchResponse<DynamicSlotId>;
122131

123132
jest.mocked(mockFetch).mockResolvedValue(result);
124133

@@ -143,12 +152,15 @@ describe('fetchContent', () => {
143152
timeout: 100,
144153
};
145154

146-
const result: FetchResponse<typeof slotId> = {
155+
const result = {
156+
metadata: {
157+
version: '1.0',
158+
},
147159
content: {
148160
_component: 'component',
149161
id: 'test',
150162
},
151-
};
163+
} satisfies FetchResponse<DynamicSlotId>;
152164

153165
jest.mocked(mockFetch).mockResolvedValue(result);
154166

@@ -174,12 +186,15 @@ describe('fetchContent', () => {
174186
timeout: 100,
175187
};
176188

177-
const result: FetchResponse<typeof slotId> = {
189+
const result = {
190+
metadata: {
191+
version: '1.0',
192+
},
178193
content: {
179194
_component: 'component',
180195
id: 'test',
181196
},
182-
};
197+
} satisfies FetchResponse<DynamicSlotId>;
183198

184199
jest.mocked(mockFetch).mockResolvedValue(result);
185200

0 commit comments

Comments
 (0)