Skip to content

Commit

Permalink
add contentful fix
Browse files Browse the repository at this point in the history
  • Loading branch information
claytercek committed Nov 26, 2024
1 parent 8647c02 commit 6d9ae5f
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .changeset/flat-poems-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bluecadet/launchpad-content": patch
---

Improve contentful source compatibility with mediaDownloader
9 changes: 1 addition & 8 deletions docs/src/reference/content/sources/contentful-source.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,6 @@ Set to true to use the Preview API instead of the Content Delivery API. Requires

Optionally limit queries to specific content types. This will also apply to linked assets. Types that link to other types will include up to 10 levels of child content.

### `locale`

- **Type:** `string`
- **Default:** `'en-US'`

Used to pull localized content.

### `filename`

- **Type:** `string`
Expand All @@ -88,7 +81,7 @@ The filename where content (entries and assets metadata) will be stored.
- **Type:** `string`
- **Default:** `'https'`

The protocol to use for API requests.
This updates the asset urls for better compatibility with the mediaDownloader plugin. By default, asset urls have no protocol.

### `host`

Expand Down
2 changes: 1 addition & 1 deletion packages/content/src/plugins/media-downloader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import ResultAsyncQueue from "../utils/result-async-queue.js";
import { safeKy } from "../utils/safe-ky.js";
import { CacheProgressLogger, parsePluginConfig, queryOrUpdate } from "./contentPluginHelpers.js";

const DEFAULT_MEDIA_PATTERN = /\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i;
const DEFAULT_MEDIA_PATTERN = /https?.*\.(jpe?g|png|webp|avi|mov|mp4|mpg|mpeg|webm)$/i;

declare module "../content-plugin-driver.js" {
interface ContentHookArgs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ describe("contentfulSource", () => {
{
"fields": {
"file": {
"url": "//test.com/preview.jpg",
"url": "https://test.com/preview.jpg",
},
"title": "Preview Asset",
},
Expand Down
20 changes: 13 additions & 7 deletions packages/content/src/sources/contentful-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,14 @@ const contentfulSourceSchema = z
.describe("Required field to identify this source. Will be used as download path."),
/** Required field to identify this source. Will be used as download path. */
space: z.string().describe("Your Contentful space ID."),
/** Used to pull localized images. */
locale: z.string().default("en-US").describe("Used to pull localized images."),
/** The filename you want to use for where all content (entries and assets metadata) will be stored. Defaults to 'content.json' */
filename: z
.string()
.default("content.json")
.describe(
"The filename you want to use for where all content (entries and assets metadata) will be stored.",
),
/** Optional. Defaults to 'https' */
/** Optional. Defaults to 'https'. This updates the asset urls for better compatibility with the mediaDownloader plugin. By default, asset urls have no protocol. */
protocol: z.string().default("https").describe("Optional. Defaults to 'https'"),
/** Optional. Defaults to 'cdn.contentful.com', or 'preview.contentful.com' if `usePreviewApi` is true */
host: z
Expand Down Expand Up @@ -123,7 +121,7 @@ export default async function contentfulSource(options: z.input<typeof contentfu

const page = rawPage.toPlainObject();
const entries = parseEntries(page);
const assets = parseAssets(page);
const assets = parseAssets(page, assembled.protocol);

if (!entries.length) {
return null; // No more pages left
Expand Down Expand Up @@ -171,13 +169,20 @@ function parseEntries(responseObj: any): Array<Entry<unknown>> {
* Returns all entries from a sync() or getEntries() response object.
*/
// biome-ignore lint/suspicious/noExplicitAny: unknown type from CMS
function parseAssets(responseObj: any): Array<Asset> {
function parseAssets(responseObj: any, protocol: string): Array<Asset> {
const assets = responseObj.assets || [];
if (responseObj.includes) {
// 'includes' is an object where the key = type, and the value = list of items
for (const [key, items] of Object.entries(responseObj.includes)) {
if (key === "Asset") {
assets.push(...(items as Array<Asset>));
const withMediaProtocols = (items as Array<Asset>).map((asset) => {
if (asset.fields.file.url.startsWith("//")) {
asset.fields.file.url = `${protocol}:${asset.fields.file.url}`;
}
return asset;
});

assets.push(...withMediaProtocols);
}
}
}
Expand All @@ -186,7 +191,8 @@ function parseAssets(responseObj: any): Array<Asset> {

async function tryImportContentful() {
try {
return await import("contentful");
const contentful = await import("contentful");
return contentful.default;
} catch (error) {
throw new Error('Could not find module "contentful". Make sure you have installed it.', {
cause: error,
Expand Down

0 comments on commit 6d9ae5f

Please sign in to comment.