Skip to content

Commit d7cbe79

Browse files
committed
Merge remote-tracking branch 'origin/feature/cloudinary-to-sanity-migration' into dev
2 parents 60d759b + 7e5c775 commit d7cbe79

30 files changed

+1774
-294
lines changed

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,11 @@ next-env.d.ts
5151
# Firebase debug files
5252
firebase-debug.log
5353
firebase-debug.*.logpackage-lock.json
54+
55+
# Migration tool generated files
56+
scripts/migration/discovered-references.json
57+
scripts/migration/unique-cloudinary-urls.json
58+
scripts/migration/asset-mapping.json
59+
scripts/migration/migration-report.json
60+
scripts/migration/node_modules/
61+
scripts/migration/.env

app/(main)/layout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import * as demo from "@/sanity/lib/demo";
1313
import { sanityFetch } from "@/sanity/lib/live";
1414
import { settingsQuery } from "@/sanity/lib/queries";
1515
import { cn } from "@/lib/utils";
16+
import { resolveOpenGraphImage } from "@/sanity/lib/utils";
1617
import { ThemeProvider } from "@/components/theme-provider";
1718
import Link from "next/link";
1819
import { Button } from "@/components/ui/button";
@@ -56,8 +57,7 @@ export async function generateMetadata(): Promise<Metadata> {
5657
const title = settings?.title || demo.title;
5758
const description = settings?.description || demo.description;
5859

59-
// const ogImage = resolveOpenGraphImage(settings?.ogImage);
60-
const ogImage = settings?.ogImage?.secure_url;
60+
const ogImage = resolveOpenGraphImage(settings?.ogImage);
6161
return {
6262
title: {
6363
template: `%s | ${title}`,

app/api/devto/route.tsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { podcastQuery, postQuery } from "@/sanity/lib/queries";
33
import { isValidSignature, SIGNATURE_HEADER_NAME } from "@sanity/webhook";
44
import toMarkdown from "@sanity/block-content-to-markdown";
55
import { createClient } from "next-sanity";
6+
import { urlForImage } from "@/sanity/lib/utils";
67

78
const secret = process.env.PRIVATE_SYNDICATE_WEBOOK_SECRET;
89
import { apiVersion, dataset, projectId, studioUrl } from "@/sanity/lib/api";
@@ -81,10 +82,7 @@ const formatPodcast = async (_type: string, slug: string) => {
8182
title: podcast.title,
8283
published: true,
8384
tags: ["webdev", "javascript", "beginners"],
84-
main_image: podcast?.coverImage?.secure_url?.replace(
85-
"upload/",
86-
"upload/b_rgb:5e1186,c_pad,w_1000,h_420/",
87-
),
85+
main_image: urlForImage(podcast?.coverImage)?.width(1000).height(420).url() || "",
8886
canonical_url: `https://codingcat.dev/${podcast._type}/${podcast.slug}`,
8987
description: podcast?.excerpt || "",
9088
organization_id: "1009",
@@ -239,7 +237,12 @@ const serializers = {
239237
types: {
240238
code: (props: any) =>
241239
"```" + props?.node?.language + "\n" + props?.node?.code + "\n```",
242-
"cloudinary.asset": (props: any) => `![](${props?.node?.secure_url})`,
240+
image: (props: any) => {
241+
const url = props?.node?.asset?._ref
242+
? urlForImage(props.node)?.url()
243+
: "";
244+
return `![](${url})`;
245+
},
243246
codepen: (props: any) => `{% codepen ${props?.node?.url} %}`,
244247
codesandbox: (props: any) =>
245248
`{% codesandbox ${props?.node?.url?.split("https://codesandbox.io/p/sandbox/")?.at(-1)} %}`,

app/api/hashnode/route.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { podcastQuery, postQuery } from "@/sanity/lib/queries";
33
import { isValidSignature, SIGNATURE_HEADER_NAME } from "@sanity/webhook";
44
import toMarkdown from "@sanity/block-content-to-markdown";
55
import { createClient } from "next-sanity";
6+
import { urlForImage } from "@/sanity/lib/utils";
67
import { apiVersion, dataset, projectId, studioUrl } from "@/sanity/lib/api";
78

89
const secret = process.env.PRIVATE_SYNDICATE_WEBOOK_SECRET;
@@ -110,7 +111,7 @@ const formatPodcast = async (_type: string, slug: string) => {
110111
},
111112
],
112113
coverImageOptions: {
113-
coverImageURL: podcast?.coverImage?.secure_url,
114+
coverImageURL: urlForImage(podcast?.coverImage)?.width(1600).height(840).url() || "",
114115
},
115116
originalArticleURL: `https://codingcat.dev/${podcast._type}/${podcast.slug}`,
116117
contentMarkdown: `
@@ -344,7 +345,12 @@ const serializers = {
344345
types: {
345346
code: (props: any) =>
346347
"```" + props?.node?.language + "\n" + props?.node?.code + "\n```",
347-
"cloudinary.asset": (props: any) => `![](${props?.node?.secure_url})`,
348+
image: (props: any) => {
349+
const url = props?.node?.asset?._ref
350+
? urlForImage(props.node)?.url()
351+
: "";
352+
return `![](${url})`;
353+
},
348354
codepen: (props: any) => `{% codepen ${props?.node?.url} %}`,
349355
codesandbox: (props: any) =>
350356
`{% codesandbox ${props?.node?.url?.split("https://codesandbox.io/p/sandbox/")?.at(-1)} %}`,

components/avatar.tsx

Lines changed: 44 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,55 @@
11
"use client";
22

3-
import { CldImage } from "next-cloudinary";
3+
import Image from "next/image";
44
import type { Author } from "@/sanity/types";
55
import Link from "next/link";
6-
import { stegaClean } from "@sanity/client/stega";
6+
import { urlForImage } from "@/sanity/lib/image";
77

88
interface Props {
9-
name?: string;
10-
href?: string;
11-
coverImage: Exclude<Author["coverImage"], undefined> | undefined;
12-
imgSize?: string;
13-
width?: number;
14-
height?: number;
9+
name?: string;
10+
href?: string;
11+
coverImage: Exclude<Author["coverImage"], undefined> | undefined;
12+
imgSize?: string;
13+
width?: number;
14+
height?: number;
1515
}
1616

1717
export default function Avatar({
18-
name,
19-
href,
20-
coverImage,
21-
imgSize,
22-
width,
23-
height,
18+
name,
19+
href,
20+
coverImage,
21+
imgSize,
22+
width,
23+
height,
2424
}: Props) {
25-
const source = stegaClean(coverImage);
26-
if (!href && source?.public_id) {
27-
return (
28-
<div className={`${imgSize ? imgSize : "w-12 h-12 mr-4"}`}>
29-
<CldImage
30-
className="w-full h-auto aspect-square rounded-md object-cover"
31-
width={width || 48}
32-
height={height || 48}
33-
alt={source?.context?.custom?.alt || ""}
34-
src={source.public_id}
35-
config={{
36-
url: {
37-
secureDistribution: "media.codingcat.dev",
38-
privateCdn: true,
39-
},
40-
}}
41-
/>
42-
</div>
43-
);
44-
}
45-
if (href && source?.public_id) {
46-
return (
47-
<Link className="flex items-center text-xl" href={href}>
48-
{source?.public_id && (
49-
<div className={`${imgSize ? imgSize : "w-12 h-12 mr-4"}`}>
50-
<CldImage
51-
className="w-full h-auto aspect-square rounded-md object-cover"
52-
width={width || 48}
53-
height={height || 48}
54-
alt={source?.context?.custom?.alt || ""}
55-
src={source.public_id}
56-
config={{
57-
url: {
58-
secureDistribution: "media.codingcat.dev",
59-
privateCdn: true,
60-
},
61-
}}
62-
/>
63-
</div>
64-
)}
65-
{name && (
66-
<div className="text-xl font-bold text-pretty hover:underline">
67-
{name}
68-
</div>
69-
)}
70-
</Link>
71-
);
72-
}
73-
return <></>;
25+
const imageUrl = coverImage?.asset?._ref
26+
? urlForImage(coverImage)?.width(width || 48).height(height || 48).url()
27+
: null;
28+
29+
if (!imageUrl) return <></>;
30+
31+
const imageElement = (
32+
<div className={`${imgSize ? imgSize : "w-12 h-12 mr-4"}`}>
33+
<Image
34+
className="w-full h-auto aspect-square rounded-md object-cover"
35+
width={width || 48}
36+
height={height || 48}
37+
alt={coverImage?.alt || ""}
38+
src={imageUrl}
39+
/>
40+
</div>
41+
);
42+
43+
if (!href) return imageElement;
44+
45+
return (
46+
<Link className="flex items-center text-xl" href={href}>
47+
{imageElement}
48+
{name && (
49+
<div className="text-xl font-bold text-pretty hover:underline">
50+
{name}
51+
</div>
52+
)}
53+
</Link>
54+
);
7455
}

components/block-image.tsx

Lines changed: 28 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,35 @@
1-
import type { CloudinaryAsset } from "@/sanity/types";
2-
import CloudinaryImage from "@/components/cloudinary-image";
1+
import Image from "next/image";
2+
import { urlForImage } from "@/sanity/lib/image";
33

4-
import { getCldImageUrl } from "next-cloudinary";
5-
6-
interface CoverImageProps {
7-
image: CloudinaryAsset;
4+
interface BlockImageProps {
5+
image: any;
86
}
97

10-
export default async function BlockImage(props: CoverImageProps) {
11-
const { image: originalImage } = props;
8+
export default function BlockImage(props: BlockImageProps) {
9+
const { image } = props;
1210

13-
let image;
14-
if (originalImage?.public_id) {
15-
const imageUrl = getCldImageUrl({
16-
src: originalImage.public_id,
17-
width: 100,
18-
});
19-
const response = await fetch(imageUrl);
20-
const arrayBuffer = await response.arrayBuffer();
21-
const buffer = Buffer.from(arrayBuffer);
22-
const base64 = buffer.toString("base64");
23-
const dataUrl = `data:${response.type};base64,${base64}`;
11+
const imageUrl = image?.asset?._ref
12+
? urlForImage(image)?.width(1920).height(1080).url()
13+
: null;
2414

25-
image = (
26-
<CloudinaryImage
27-
className="w-full h-auto"
28-
width={1920}
29-
height={1080}
30-
sizes="100vw"
31-
alt={originalImage?.context?.custom?.alt || ""}
32-
src={originalImage?.public_id}
33-
placeholder="blur"
34-
blurDataURL={dataUrl}
35-
config={{
36-
url: {
37-
secureDistribution: "media.codingcat.dev",
38-
privateCdn: true,
39-
},
40-
}}
41-
/>
42-
);
43-
} else {
44-
image = <div className="bg-slate-50" style={{ paddingTop: "50%" }} />;
45-
}
15+
if (!imageUrl) {
16+
return (
17+
<div className="shadow-md transition-shadow duration-200 group-hover:shadow-lg sm:mx-0">
18+
<div className="bg-slate-50" style={{ paddingTop: "50%" }} />
19+
</div>
20+
);
21+
}
4622

47-
return (
48-
<div className="shadow-md transition-shadow duration-200 group-hover:shadow-lg sm:mx-0">
49-
{image}
50-
</div>
51-
);
23+
return (
24+
<div className="shadow-md transition-shadow duration-200 group-hover:shadow-lg sm:mx-0">
25+
<Image
26+
className="w-full h-auto"
27+
width={1920}
28+
height={1080}
29+
sizes="100vw"
30+
alt={image?.alt || ""}
31+
src={imageUrl}
32+
/>
33+
</div>
34+
);
5235
}

components/cloudinary-image.tsx

Lines changed: 0 additions & 25 deletions
This file was deleted.

components/cloudinary-video.tsx

Lines changed: 0 additions & 13 deletions
This file was deleted.

0 commit comments

Comments
 (0)