Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,12 +340,13 @@ When initialising a client, you will receive an instance of the [`ContentfulClie

#### Entries

| Chain | Modifier |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| _none (default)_ | Returns entries in a single locale. Resolvable linked entries will be inlined while unresolvable links will be kept as link objects. [Read more on link resolution](ADVANCED.md#link-resolution) |
| `withAllLocales` | Returns entries in all locales. |
| `withoutLinkResolution` | All linked entries will be rendered as link objects. [Read more on link resolution](ADVANCED.md#link-resolution) |
| `withoutUnresolvableLinks` | If linked entries are not resolvable, the corresponding link objects are removed from the response. |
| Chain | Modifier |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| _none (default)_ | Returns entries in a single locale. Resolvable linked entries will be inlined while unresolvable links will be kept as link objects. [Read more on link resolution](ADVANCED.md#link-resolution) |
| `withAllLocales` | Returns entries in all locales. |
| `withoutLinkResolution` | All linked entries will be rendered as link objects. [Read more on link resolution](ADVANCED.md#link-resolution) |
| `withoutUnresolvableLinks` | If linked entries are not resolvable, the corresponding link objects are removed from the response. |
| `withLocaleBasedPublishing` | Fetched entries & assets will be returned with only content from published locales. |

##### Example

Expand Down
64 changes: 54 additions & 10 deletions lib/create-contentful-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import { getTimelinePreviewParams } from './utils/timeline-preview-helpers.js'
import { normalizeCursorPaginationParameters } from './utils/normalize-cursor-pagination-parameters.js'
import { normalizeCursorPaginationResponse } from './utils/normalize-cursor-pagination-response.js'
import type { AxiosRequestConfig } from 'axios'

const ASSET_KEY_MAX_LIFETIME = 48 * 60 * 60

Expand All @@ -60,7 +61,7 @@

class NotFoundError extends Error {
public readonly sys: { id: string; type: string }
public readonly details: { environment: string; id: string; type: string; space: any }

Check warning on line 64 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 64 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type

constructor(id: string, environment: string, space: string) {
super('The resource could not be found.')
Expand Down Expand Up @@ -90,11 +91,11 @@
interface GetConfig {
context: Context
path: string
config?: any

Check warning on line 94 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 94 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type
}

interface PostConfig extends GetConfig {
data?: any

Check warning on line 98 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 98 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type
}

const getBaseUrl = (context: Context) => {
Expand All @@ -112,7 +113,7 @@
return baseUrl
}

function maybeEnableSourceMaps(query: Record<string, any> = {}): Record<string, any> {

Check warning on line 116 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 116 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 116 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type

Check warning on line 116 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type
const params = http.httpClientParams as CreateClientParams
const includeContentSourceMaps =
params?.includeContentSourceMaps ?? params?.alphaFeatures?.includeContentSourceMaps
Expand Down Expand Up @@ -142,7 +143,7 @@
return enabled ? `timeline/${path}` : path
}

function maybeAddTimelinePreviewConfigToQuery(query: Record<string, any>) {

Check warning on line 146 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 146 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type
const { enabled, timelinePreview } = getTimelinePreviewParams(
http.httpClientParams as CreateClientParams,
)
Expand All @@ -158,7 +159,7 @@
return query
}

function maybeEncodeCPAResponse(data: any, config: Record<string, any>): any {

Check warning on line 162 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 162 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / lint

Unexpected any. Specify a different type

Check warning on line 162 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type

Check warning on line 162 in lib/create-contentful-api.ts

View workflow job for this annotation

GitHub Actions / check / test

Unexpected any. Specify a different type
const includeContentSourceMaps = config?.params?.includeContentSourceMaps as boolean

if (includeContentSourceMaps) {
Expand Down Expand Up @@ -230,6 +231,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
const { withAllLocales } = options
Expand Down Expand Up @@ -280,6 +282,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
const { withAllLocales } = options
Expand Down Expand Up @@ -318,14 +321,22 @@
): Promise<
CollectionForQuery<Entry<EntrySkeleton, ModifiersFromOptions<Options>, Locales>, Query>
> {
const { withoutLinkResolution, withoutUnresolvableLinks } = options
const { withoutLinkResolution, withoutUnresolvableLinks, withLocaleBasedPublishing } = options
try {
const baseConfig = createRequestConfig({
query: prepareQuery(query),
})
const config: AxiosRequestConfig = baseConfig
if (withLocaleBasedPublishing) {
config.headers = {
...config.headers,
'X-Contentful-Locale-Based-Publishing': true,
}
}
const entries = await get({
context: 'environment',
path: maybeEnableTimelinePreview('entries'),
config: createRequestConfig({
query: prepareQuery(query),
}),
config,
})

return resolveCircular(entries, {
Expand Down Expand Up @@ -358,6 +369,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
const { withAllLocales } = options
Expand All @@ -367,18 +379,33 @@

const localeSpecificQuery = withAllLocales ? { ...query, locale: '*' } : query

return internalGetAssets<any, Extract<ChainOptions, typeof options>, Query>(localeSpecificQuery)
return internalGetAssets<any, Extract<ChainOptions, typeof options>, Query>(
localeSpecificQuery,
options,
)
}

async function internalGetAsset<Locales extends LocaleCode, Options extends ChainOptions>(
id: string,
query: Record<string, any>,
options: Options,
): Promise<Asset<ModifiersFromOptions<Options>, Locales>> {
const { withLocaleBasedPublishing } = options
try {
const baseConfig = createRequestConfig({
query: prepareQuery(query),
})
const config: AxiosRequestConfig = baseConfig
if (withLocaleBasedPublishing) {
config.headers = {
...config.headers,
'X-Contentful-Locale-Based-Publishing': true,
}
}
return get({
context: 'environment',
path: maybeEnableTimelinePreview(`assets/${id}`),
config: createRequestConfig({ query: prepareQuery(query) }),
config,
})
} catch (error) {
errorHandler(error)
Expand All @@ -392,6 +419,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
const { withAllLocales } = options
Expand All @@ -401,7 +429,11 @@

const localeSpecificQuery = withAllLocales ? { ...query, locale: '*' } : query

return internalGetAsset<any, Extract<ChainOptions, typeof options>>(id, localeSpecificQuery)
return internalGetAsset<any, Extract<ChainOptions, typeof options>>(
id,
localeSpecificQuery,
options,
)
}

async function internalGetAssets<
Expand All @@ -410,14 +442,24 @@
Query extends Record<string, any>,
>(
query: Query,
options: Options,
): Promise<CollectionForQuery<Asset<ModifiersFromOptions<Options>, Locales>, Query>> {
const { withLocaleBasedPublishing } = options
try {
const baseConfig = createRequestConfig({
query: prepareQuery(query),
})
const config: AxiosRequestConfig = baseConfig
if (withLocaleBasedPublishing) {
config.headers = {
...config.headers,
'X-Contentful-Locale-Based-Publishing': true,
}
}
return get({
context: 'environment',
path: maybeEnableTimelinePreview('assets'),
config: createRequestConfig({
query: prepareQuery(query),
}),
config,
})
} catch (error) {
errorHandler(error)
Expand Down Expand Up @@ -481,6 +523,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
validateResolveLinksParam(query)
Expand Down Expand Up @@ -508,6 +551,7 @@
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
) {
return internalParseEntries<EntrySkeleton, any, Extract<ChainOptions, typeof options>>(
Expand Down
15 changes: 15 additions & 0 deletions lib/make-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ function create<OptionsType extends ChainOptions>(
Object.defineProperty(response, 'withoutUnresolvableLinks', {
get: () => makeInnerClient({ ...options, withoutUnresolvableLinks: true }),
})
Object.defineProperty(response, 'withLocaleBasedPublishing', {
get: () => makeInnerClient({ ...options, withLocaleBasedPublishing: true }),
})
return Object.create(response) as ContentfulClientApi<ModifiersFromOptions<OptionsType>>
}

Expand All @@ -50,6 +53,7 @@ export const makeClient = ({
withoutLinkResolution: false,
withAllLocales: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
},
)

Expand All @@ -60,20 +64,31 @@ export const makeClient = ({
withAllLocales: true,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
})
},
get withoutLinkResolution() {
return makeInnerClient<ChainOption<'WITHOUT_LINK_RESOLUTION'>>({
withAllLocales: false,
withoutLinkResolution: true,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
})
},
get withoutUnresolvableLinks() {
return makeInnerClient<ChainOption<'WITHOUT_UNRESOLVABLE_LINKS'>>({
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: true,
withLocaleBasedPublishing: false,
})
},
get withLocaleBasedPublishing() {
return makeInnerClient<ChainOption<'WITH_LOCALE_BASED_PUBLISHING'>>({
withAllLocales: false,
withoutLinkResolution: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: true,
})
},
}
Expand Down
5 changes: 5 additions & 0 deletions lib/types/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export type ChainModifiers =
| 'WITH_ALL_LOCALES'
| 'WITHOUT_LINK_RESOLUTION'
| 'WITHOUT_UNRESOLVABLE_LINKS'
| 'WITH_LOCALE_BASED_PUBLISHING'
| undefined

/**
Expand Down Expand Up @@ -581,6 +582,10 @@ export interface ContentfulClientApi<Modifiers extends ChainModifiers> {
? never
: ContentfulClientApi<AddChainModifier<Modifiers, 'WITHOUT_UNRESOLVABLE_LINKS'>>

withLocaleBasedPublishing: 'WITH_LOCALE_BASED_PUBLISHING' extends Modifiers
? never
: ContentfulClientApi<AddChainModifier<Modifiers, 'WITH_LOCALE_BASED_PUBLISHING'>>

/**
* The current Contentful.js version
*/
Expand Down
5 changes: 5 additions & 0 deletions lib/utils/client-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ export type ChainOption<Modifiers extends ChainModifiers = ChainModifiers> = {
: 'WITHOUT_UNRESOLVABLE_LINKS' extends Modifiers
? true
: false
withLocaleBasedPublishing: ChainModifiers extends Modifiers
? boolean
: 'WITH_LOCALE_BASED_PUBLISHING' extends Modifiers
? true
: false
}

export type DefaultChainOption = ChainOption<undefined>
Expand Down
36 changes: 36 additions & 0 deletions test/types/chain-options.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,47 @@ expectAssignable<ChainOptions>({
withoutLinkResolution: true as boolean,
withAllLocales: true as boolean,
withoutUnresolvableLinks: true as boolean,
withLocaleBasedPublishing: true as boolean,
})

expectType<ChainOption<undefined>>({
withoutLinkResolution: false,
withAllLocales: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
})

expectType<ChainOption<'WITHOUT_UNRESOLVABLE_LINKS'>>({
withoutLinkResolution: false,
withAllLocales: false,
withLocaleBasedPublishing: false,
withoutUnresolvableLinks: true,
})

expectType<ChainOption<'WITHOUT_LINK_RESOLUTION'>>({
withoutLinkResolution: true,
withAllLocales: false,
withLocaleBasedPublishing: false,
withoutUnresolvableLinks: false,
})

expectType<ChainOption<'WITH_ALL_LOCALES'>>({
withoutLinkResolution: false,
withAllLocales: true,
withLocaleBasedPublishing: false,
withoutUnresolvableLinks: false,
})

expectType<ChainOption<'WITH_ALL_LOCALES' | 'WITHOUT_UNRESOLVABLE_LINKS'>>({
withoutLinkResolution: false,
withLocaleBasedPublishing: false,
withAllLocales: true,
withoutUnresolvableLinks: true,
})

expectNotType<ChainOption<'WITH_ALL_LOCALES' | 'WITHOUT_UNRESOLVABLE_LINKS'>>({
withoutLinkResolution: false,
withLocaleBasedPublishing: false,
withAllLocales: true,
withoutUnresolvableLinks: false,
})
Expand All @@ -50,4 +57,33 @@ expectType<ChainOption<'WITH_ALL_LOCALES' | 'WITHOUT_LINK_RESOLUTION'>>({
withoutLinkResolution: true,
withAllLocales: true,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: false,
})

expectType<ChainOption<'WITH_LOCALE_BASED_PUBLISHING'>>({
withoutLinkResolution: false,
withAllLocales: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: true,
})

expectType<ChainOption<'WITH_LOCALE_BASED_PUBLISHING' | 'WITH_ALL_LOCALES'>>({
withoutLinkResolution: false,
withAllLocales: true,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: true,
})

expectType<ChainOption<'WITH_LOCALE_BASED_PUBLISHING' | 'WITHOUT_LINK_RESOLUTION'>>({
withoutLinkResolution: true,
withAllLocales: false,
withoutUnresolvableLinks: false,
withLocaleBasedPublishing: true,
})

expectType<ChainOption<'WITH_LOCALE_BASED_PUBLISHING' | 'WITHOUT_UNRESOLVABLE_LINKS'>>({
withoutLinkResolution: false,
withAllLocales: false,
withoutUnresolvableLinks: true,
withLocaleBasedPublishing: true,
})
26 changes: 26 additions & 0 deletions test/types/client/createClient.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,29 @@ expectType<ContentfulClientApi<'WITH_ALL_LOCALES' | 'WITHOUT_LINK_RESOLUTION'>>(
expectType<ContentfulClientApi<'WITH_ALL_LOCALES' | 'WITHOUT_UNRESOLVABLE_LINKS'>>(
createClient(CLIENT_OPTIONS).withAllLocales.withoutUnresolvableLinks,
)
expectType<ContentfulClientApi<'WITH_LOCALE_BASED_PUBLISHING'>>(
createClient(CLIENT_OPTIONS).withLocaleBasedPublishing,
)
expectType<never>(createClient(CLIENT_OPTIONS).withLocaleBasedPublishing.withLocaleBasedPublishing)

expectType<ContentfulClientApi<'WITH_LOCALE_BASED_PUBLISHING' | 'WITH_ALL_LOCALES'>>(
createClient(CLIENT_OPTIONS).withLocaleBasedPublishing.withAllLocales,
)

expectType<ContentfulClientApi<'WITH_LOCALE_BASED_PUBLISHING' | 'WITHOUT_LINK_RESOLUTION'>>(
createClient(CLIENT_OPTIONS).withLocaleBasedPublishing.withoutLinkResolution,
)

expectType<ContentfulClientApi<'WITH_LOCALE_BASED_PUBLISHING' | 'WITHOUT_UNRESOLVABLE_LINKS'>>(
createClient(CLIENT_OPTIONS).withLocaleBasedPublishing.withoutUnresolvableLinks,
)

expectType<
ContentfulClientApi<
'WITH_LOCALE_BASED_PUBLISHING' | 'WITH_ALL_LOCALES' | 'WITHOUT_LINK_RESOLUTION'
>
>(createClient(CLIENT_OPTIONS).withLocaleBasedPublishing.withAllLocales.withoutLinkResolution)

expectType<ContentfulClientApi<'WITH_ALL_LOCALES' | 'WITH_LOCALE_BASED_PUBLISHING'>>(
createClient(CLIENT_OPTIONS).withAllLocales.withLocaleBasedPublishing,
)
Loading
Loading