From bf3aa32bdf7544ea0d141aeaac76b3f2db8ffc51 Mon Sep 17 00:00:00 2001 From: Alex Patterson Date: Thu, 8 Oct 2026 16:54:10 +0100 Subject: [PATCH] feat(sanity): implement youtube transcript intelligence and nightly dataset sync (#696) - Add transcript document schema with cues, chapters, stats, and metadata - Add transcript reference to content partial inherited by posts, podcasts, pages, lessons, and courses - Implement sync-youtube-transcript Sanity function with YouTube Data API v3 and InnerTube caption fetching - Restrict transcript sync execution to production dataset and enforce YOUTUBE_API_KEY - Implement sync-nightly-dataset scheduled function copying production -> dev nightly at 04:00 UTC - Update sanity.blueprint.ts registering both functions - Update search and shared queries to index and project transcripts --- apps/sanity/extract.json | 7041 +++++++++-------- .../functions/sync-nightly-dataset/index.ts | 86 + .../sync-youtube-transcript/index.ts | 402 + apps/sanity/sanity.blueprint.ts | 28 +- apps/sanity/sanity.config.ts | 2 + apps/sanity/schemas/documents/podcast.ts | 7 - apps/sanity/schemas/documents/transcript.ts | 249 + apps/sanity/schemas/partials/content.ts | 9 + apps/site/src/lib/sanity/queries/search.ts | 18 +- apps/site/src/lib/sanity/queries/shared.ts | 13 +- 10 files changed, 4532 insertions(+), 3323 deletions(-) create mode 100644 apps/sanity/functions/sync-nightly-dataset/index.ts create mode 100644 apps/sanity/functions/sync-youtube-transcript/index.ts create mode 100644 apps/sanity/schemas/documents/transcript.ts diff --git a/apps/sanity/extract.json b/apps/sanity/extract.json index 71fddaddc..197953c4f 100644 --- a/apps/sanity/extract.json +++ b/apps/sanity/extract.json @@ -704,7 +704,7 @@ }, { "type": "type", - "name": "page.reference", + "name": "category.reference", "value": { "type": "object", "attributes": { @@ -729,101 +729,279 @@ "optional": true } }, - "dereferencesTo": "page" + "dereferencesTo": "category" + } + }, + { + "name": "short", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "short" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "title": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "slug": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "slug" + }, + "optional": true + }, + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "thumbnail": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageAsset.reference" + }, + "optional": true + }, + "media": { + "type": "objectAttribute", + "value": { + "type": "unknown" + }, + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" + }, + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" + } + } + } + }, + "optional": true + }, + "parentEpisode": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "podcast.reference" + }, + "optional": true + }, + "publishedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "duration": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "categories": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "category.reference" + } + } + }, + "optional": true + } } }, { + "name": "sanity.imageCrop", "type": "type", - "name": "author.reference", "value": { "type": "object", "attributes": { - "_ref": { + "_type": { "type": "objectAttribute", "value": { - "type": "string" + "type": "string", + "value": "sanity.imageCrop" } }, - "_type": { + "top": { "type": "objectAttribute", "value": { - "type": "string", - "value": "reference" - } + "type": "number" + }, + "optional": true }, - "_weak": { + "bottom": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "number" + }, + "optional": true + }, + "left": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "right": { + "type": "objectAttribute", + "value": { + "type": "number" }, "optional": true } - }, - "dereferencesTo": "author" + } } }, { + "name": "sanity.imageHotspot", "type": "type", - "name": "sponsor.reference", "value": { "type": "object", "attributes": { - "_ref": { + "_type": { "type": "objectAttribute", "value": { - "type": "string" + "type": "string", + "value": "sanity.imageHotspot" } }, - "_type": { + "x": { "type": "objectAttribute", "value": { - "type": "string", - "value": "reference" - } + "type": "number" + }, + "optional": true }, - "_weak": { + "y": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "number" + }, + "optional": true + }, + "height": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "width": { + "type": "objectAttribute", + "value": { + "type": "number" }, "optional": true } - }, - "dereferencesTo": "sponsor" + } } }, { + "name": "slug", "type": "type", - "name": "lesson.reference", "value": { "type": "object", "attributes": { - "_ref": { + "_type": { "type": "objectAttribute", "value": { - "type": "string" + "type": "string", + "value": "slug" } }, - "_type": { + "current": { "type": "objectAttribute", "value": { - "type": "string", - "value": "reference" - } + "type": "string" + }, + "optional": true }, - "_weak": { + "source": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "string" }, "optional": true } - }, - "dereferencesTo": "lesson" + } } }, { - "name": "course", + "name": "category", "type": "document", "attributes": { "_id": { @@ -836,7 +1014,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "course" + "value": "category" } }, "_createdAt": { @@ -857,2371 +1035,132 @@ "type": "string" } }, - "coverImage": { + "title": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "coverImage" + "type": "string" }, "optional": true }, - "date": { + "slug": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "slug" + }, + "optional": true + }, + "description": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "title": { + "color": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true + } + } + }, + { + "name": "sponsorPool", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } }, - "slug": { + "_type": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "slug" + "type": "string", + "value": "sponsorPool" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "companyName": { + "type": "objectAttribute", + "value": { + "type": "string" }, "optional": true }, - "excerpt": { + "contactName": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "featured": { + "contactEmail": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "website": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "category": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "source": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "curated" + }, + { + "type": "string", + "value": "enriched" + } + ] + }, + "optional": true + }, + "relevanceScore": { "type": "objectAttribute", "value": { "type": "number" }, "optional": true }, - "content": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "children": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "marks": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "text": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "span" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "style": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "normal" - }, - { - "type": "string", - "value": "h1" - }, - { - "type": "string", - "value": "h2" - }, - { - "type": "string", - "value": "h3" - }, - { - "type": "string", - "value": "h4" - }, - { - "type": "string", - "value": "h5" - }, - { - "type": "string", - "value": "h6" - }, - { - "type": "string", - "value": "blockquote" - } - ] - }, - "optional": true - }, - "listItem": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "bullet" - }, - { - "type": "string", - "value": "number" - } - ] - }, - "optional": true - }, - "markDefs": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "href": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "blank": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "link" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "reference": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "inline", - "name": "post.reference" - }, - { - "type": "inline", - "name": "podcast.reference" - }, - { - "type": "inline", - "name": "page.reference" - } - ] - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "internalLink" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - ] - } - }, - "optional": true - }, - "level": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "block" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "asset": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageAsset.reference" - }, - "optional": true - }, - "media": { - "type": "objectAttribute", - "value": { - "type": "unknown" - }, - "optional": true - }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" - }, - "optional": true - }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "code" - } - }, - { - "type": "object", - "attributes": { - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "youtube" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "shorts": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "youtubeShorts" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "codepen" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "codesandbox" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "id": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "twitter" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "html": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "htmlBlock" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "content": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "children": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "marks": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "text": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "span" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "style": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "normal" - }, - { - "type": "string", - "value": "h1" - }, - { - "type": "string", - "value": "h2" - }, - { - "type": "string", - "value": "h3" - }, - { - "type": "string", - "value": "h4" - }, - { - "type": "string", - "value": "h5" - }, - { - "type": "string", - "value": "h6" - }, - { - "type": "string", - "value": "blockquote" - } - ] - }, - "optional": true - }, - "listItem": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "bullet" - }, - { - "type": "string", - "value": "number" - } - ] - }, - "optional": true - }, - "markDefs": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "href": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "blank": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "link" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "reference": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "inline", - "name": "post.reference" - }, - { - "type": "inline", - "name": "podcast.reference" - }, - { - "type": "inline", - "name": "page.reference" - } - ] - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "internalLink" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - ] - } - }, - "optional": true - }, - "level": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "block" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "quote" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "table" - } - } - ] - } - }, - "optional": true - }, - "videoCloudinary": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "videoCloudinary" - }, - "optional": true - }, - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "author": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "author.reference" - } - } - }, - "optional": true - }, - "sponsor": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "sponsor.reference" - } - } - }, - "optional": true - }, - "devto": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "hashnode": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "statistics": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "statistics" - }, - "optional": true - }, - "stripeProduct": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "sections": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "lesson": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "lesson.reference" - } - } - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "section" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - } - } - }, - { - "name": "lesson", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "lesson" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "coverImage": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "coverImage" - }, - "optional": true - }, - "date": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "slug": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "slug" - }, - "optional": true - }, - "excerpt": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "featured": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "content": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "children": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "marks": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "text": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "span" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "style": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "normal" - }, - { - "type": "string", - "value": "h1" - }, - { - "type": "string", - "value": "h2" - }, - { - "type": "string", - "value": "h3" - }, - { - "type": "string", - "value": "h4" - }, - { - "type": "string", - "value": "h5" - }, - { - "type": "string", - "value": "h6" - }, - { - "type": "string", - "value": "blockquote" - } - ] - }, - "optional": true - }, - "listItem": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "bullet" - }, - { - "type": "string", - "value": "number" - } - ] - }, - "optional": true - }, - "markDefs": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "href": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "blank": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "link" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "reference": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "inline", - "name": "post.reference" - }, - { - "type": "inline", - "name": "podcast.reference" - }, - { - "type": "inline", - "name": "page.reference" - } - ] - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "internalLink" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - ] - } - }, - "optional": true - }, - "level": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "block" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "asset": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageAsset.reference" - }, - "optional": true - }, - "media": { - "type": "objectAttribute", - "value": { - "type": "unknown" - }, - "optional": true - }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" - }, - "optional": true - }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "code" - } - }, - { - "type": "object", - "attributes": { - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "youtube" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "shorts": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "youtubeShorts" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "codepen" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "codesandbox" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "id": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "twitter" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "html": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "htmlBlock" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "content": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "children": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "marks": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "text": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "span" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "style": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "normal" - }, - { - "type": "string", - "value": "h1" - }, - { - "type": "string", - "value": "h2" - }, - { - "type": "string", - "value": "h3" - }, - { - "type": "string", - "value": "h4" - }, - { - "type": "string", - "value": "h5" - }, - { - "type": "string", - "value": "h6" - }, - { - "type": "string", - "value": "blockquote" - } - ] - }, - "optional": true - }, - "listItem": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "bullet" - }, - { - "type": "string", - "value": "number" - } - ] - }, - "optional": true - }, - "markDefs": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "union", - "of": [ - { - "type": "object", - "attributes": { - "href": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "blank": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "link" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "reference": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "inline", - "name": "post.reference" - }, - { - "type": "inline", - "name": "podcast.reference" - }, - { - "type": "inline", - "name": "page.reference" - } - ] - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "internalLink" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - ] - } - }, - "optional": true - }, - "level": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "block" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } - }, - "optional": true - }, - "url": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "quote" - } - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "table" - } - } - ] - } - }, - "optional": true - }, - "videoCloudinary": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "videoCloudinary" - }, - "optional": true - }, - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "author": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "author.reference" - } - } - }, - "optional": true - }, - "sponsor": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "sponsor.reference" - } - } - }, - "optional": true - }, - "devto": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "hashnode": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "statistics": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "statistics" - }, - "optional": true - }, - "locked": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - } - } - }, - { - "type": "type", - "name": "category.reference", - "value": { - "type": "object", - "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "reference" - } - }, - "_weak": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - } - }, - "dereferencesTo": "category" - } - }, - { - "name": "short", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "short" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "slug": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "slug" - }, - "optional": true - }, - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "thumbnail": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "asset": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageAsset.reference" - }, - "optional": true - }, - "media": { - "type": "objectAttribute", - "value": { - "type": "unknown" - }, - "optional": true - }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" - }, - "optional": true - }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } - } - } - }, - "optional": true - }, - "parentEpisode": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "podcast.reference" - }, - "optional": true - }, - "publishedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "duration": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "categories": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "category.reference" - } - } - }, - "optional": true - } - } - }, - { - "name": "sanity.imageCrop", - "type": "type", - "value": { - "type": "object", - "attributes": { - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "sanity.imageCrop" - } - }, - "top": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "bottom": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "left": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "right": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - } - } - } - }, - { - "name": "sanity.imageHotspot", - "type": "type", - "value": { - "type": "object", - "attributes": { - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "sanity.imageHotspot" - } - }, - "x": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "y": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "height": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "width": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - } - } - } - }, - { - "name": "slug", - "type": "type", - "value": { - "type": "object", - "attributes": { - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "slug" - } - }, - "current": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "source": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - } - } - } - }, - { - "name": "category", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "category" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "slug": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "slug" - }, - "optional": true - }, - "description": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "color": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - } - } - }, - { - "name": "sponsorPool", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "sponsorPool" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "companyName": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "contactName": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "contactEmail": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "website": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "category": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "source": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "curated" - }, - { - "type": "string", - "value": "enriched" - } - ] - }, - "optional": true - }, - "relevanceScore": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "lastContactedAt": { + "lastContactedAt": { "type": "objectAttribute", "value": { "type": "string" @@ -5014,6 +2953,36 @@ } } }, + { + "type": "type", + "name": "sponsor.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "sponsor" + } + }, { "name": "sponsorLead", "type": "document", @@ -5291,123 +3260,1059 @@ "type": "objectAttribute", "value": { "type": "string" - } + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "sponsorshipRequest" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "fullName": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "email": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "companyName": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "sponsorshipTier": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "message": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + } + } + }, + { + "name": "previewSession", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "previewSession" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "token": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "documentId": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "expiresAt": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + } + } + }, + { + "type": "type", + "name": "page.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "page" + } + }, + { + "name": "sponsor", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "sponsor" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "coverImage": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "coverImage" + }, + "optional": true + }, + "date": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true }, - "_type": { + "title": { "type": "objectAttribute", "value": { - "type": "string", - "value": "sponsorshipRequest" - } + "type": "string" + }, + "optional": true }, - "_createdAt": { + "slug": { "type": "objectAttribute", "value": { - "type": "string" - } + "type": "inline", + "name": "slug" + }, + "optional": true }, - "_updatedAt": { + "excerpt": { "type": "objectAttribute", "value": { "type": "string" - } + }, + "optional": true }, - "_rev": { + "featured": { "type": "objectAttribute", "value": { - "type": "string" - } + "type": "number" + }, + "optional": true }, - "fullName": { + "content": { "type": "objectAttribute", "value": { - "type": "string" + "type": "array", + "of": { + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "children": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "marks": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "span" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true + }, + "style": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "normal" + }, + { + "type": "string", + "value": "h1" + }, + { + "type": "string", + "value": "h2" + }, + { + "type": "string", + "value": "h3" + }, + { + "type": "string", + "value": "h4" + }, + { + "type": "string", + "value": "h5" + }, + { + "type": "string", + "value": "h6" + }, + { + "type": "string", + "value": "blockquote" + } + ] + }, + "optional": true + }, + "listItem": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "bullet" + }, + { + "type": "string", + "value": "number" + } + ] + }, + "optional": true + }, + "markDefs": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "href": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "blank": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "link" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "reference": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "post.reference" + }, + { + "type": "inline", + "name": "podcast.reference" + }, + { + "type": "inline", + "name": "page.reference" + } + ] + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "internalLink" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + ] + } + }, + "optional": true + }, + "level": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "block" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageAsset.reference" + }, + "optional": true + }, + "media": { + "type": "objectAttribute", + "value": { + "type": "unknown" + }, + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" + }, + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "code" + } + }, + { + "type": "object", + "attributes": { + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "youtube" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "shorts": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "youtubeShorts" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "codepen" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "codesandbox" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "id": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "twitter" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "html": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "htmlBlock" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "content": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "children": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "marks": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "span" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true + }, + "style": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "normal" + }, + { + "type": "string", + "value": "h1" + }, + { + "type": "string", + "value": "h2" + }, + { + "type": "string", + "value": "h3" + }, + { + "type": "string", + "value": "h4" + }, + { + "type": "string", + "value": "h5" + }, + { + "type": "string", + "value": "h6" + }, + { + "type": "string", + "value": "blockquote" + } + ] + }, + "optional": true + }, + "listItem": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "bullet" + }, + { + "type": "string", + "value": "number" + } + ] + }, + "optional": true + }, + "markDefs": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "href": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "blank": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "link" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "reference": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "post.reference" + }, + { + "type": "inline", + "name": "podcast.reference" + }, + { + "type": "inline", + "name": "page.reference" + } + ] + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "internalLink" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + ] + } + }, + "optional": true + }, + "level": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "block" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true + }, + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "quote" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "table" + } + } + ] + } }, "optional": true }, - "email": { + "ogTitle": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "companyName": { + "ogDescription": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "sponsorshipTier": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "string" - } - }, - "optional": true - }, - "message": { + "ogImage": { "type": "objectAttribute", "value": { - "type": "string" + "type": "inline", + "name": "ogImage" }, "optional": true - } - } - }, - { - "name": "previewSession", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "previewSession" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } }, - "token": { + "twitterCardType": { "type": "objectAttribute", "value": { - "type": "string" + "type": "union", + "of": [ + { + "type": "string", + "value": "summary_large_image" + }, + { + "type": "string", + "value": "summary" + } + ] }, "optional": true }, - "documentId": { + "noIndex": { "type": "objectAttribute", "value": { - "type": "string" + "type": "boolean" }, "optional": true }, - "expiresAt": { + "url": { "type": "objectAttribute", "value": { "type": "string" @@ -5417,7 +4322,7 @@ } }, { - "name": "sponsor", + "name": "author", "type": "document", "attributes": { "_id": { @@ -5430,7 +4335,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "sponsor" + "value": "author" } }, "_createdAt": { @@ -6267,63 +5172,123 @@ }, "optional": true }, - "ogTitle": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "ogDescription": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "ogImage": { + "socials": { "type": "objectAttribute", "value": { "type": "inline", - "name": "ogImage" + "name": "socials" }, "optional": true }, - "twitterCardType": { + "websites": { "type": "objectAttribute", "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "summary_large_image" + "type": "array", + "of": { + "type": "object", + "attributes": { + "site": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "link": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "link" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "site" + } + } }, - { - "type": "string", - "value": "summary" + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } } - ] + } }, "optional": true - }, - "noIndex": { - "type": "objectAttribute", - "value": { - "type": "boolean" + } + } + }, + { + "type": "type", + "name": "transcript.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } }, - "optional": true + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } }, - "url": { - "type": "objectAttribute", - "value": { - "type": "string" + "dereferencesTo": "transcript" + } + }, + { + "type": "type", + "name": "author.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } }, - "optional": true - } + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "author" } }, { - "name": "author", + "name": "post", "type": "document", "attributes": { "_id": { @@ -6336,7 +5301,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "author" + "value": "post" } }, "_createdAt": { @@ -7173,63 +6138,287 @@ }, "optional": true }, - "socials": { + "videoCloudinary": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "videoCloudinary" + }, + "optional": true + }, + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "transcript": { "type": "objectAttribute", "value": { "type": "inline", - "name": "socials" + "name": "transcript.reference" }, "optional": true }, - "websites": { + "author": { "type": "objectAttribute", "value": { "type": "array", "of": { "type": "object", "attributes": { - "site": { + "_key": { "type": "objectAttribute", "value": { "type": "string" - }, - "optional": true - }, - "link": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "link" - }, - "optional": true - }, - "_type": { + } + } + }, + "rest": { + "type": "inline", + "name": "author.reference" + } + } + }, + "optional": true + }, + "sponsor": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { "type": "objectAttribute", "value": { - "type": "string", - "value": "site" + "type": "string" } } }, "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } + "type": "inline", + "name": "sponsor.reference" + } + } + }, + "optional": true + }, + "devto": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "hashnode": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "statistics": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "statistics" + }, + "optional": true + }, + "ogTitle": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogDescription": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogImage": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "ogImage" + }, + "optional": true + }, + "twitterCardType": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "summary_large_image" + }, + { + "type": "string", + "value": "summary" + } + ] + }, + "optional": true + }, + "noIndex": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "categories": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" } } + }, + "rest": { + "type": "inline", + "name": "category.reference" } } }, - "optional": true - } + "optional": true + } + } + }, + { + "type": "type", + "name": "podcastType.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "podcastType" + } + }, + { + "type": "type", + "name": "guest.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "guest" + } + }, + { + "type": "type", + "name": "podcastSeries.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "podcastSeries" + } + }, + { + "type": "type", + "name": "short.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "short" } }, { - "name": "post", + "name": "podcast", "type": "document", "attributes": { "_id": { @@ -7242,7 +6431,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "post" + "value": "podcast" } }, "_createdAt": { @@ -8068,55 +7257,459 @@ "type": "string" } } - }, - "rest": { - "type": "inline", - "name": "table" + }, + "rest": { + "type": "inline", + "name": "table" + } + } + ] + } + }, + "optional": true + }, + "videoCloudinary": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "videoCloudinary" + }, + "optional": true + }, + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "transcript": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "transcript.reference" + }, + "optional": true + }, + "author": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "author.reference" + } + } + }, + "optional": true + }, + "sponsor": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "sponsor.reference" + } + } + }, + "optional": true + }, + "devto": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "hashnode": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "statistics": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "statistics" + }, + "optional": true + }, + "ogTitle": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogDescription": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogImage": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "ogImage" + }, + "optional": true + }, + "twitterCardType": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "summary_large_image" + }, + { + "type": "string", + "value": "summary" + } + ] + }, + "optional": true + }, + "noIndex": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "podcastType": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "podcastType.reference" + }, + "optional": true + }, + "season": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "episode": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "recordingDate": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "guest": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "guest.reference" + } + } + }, + "optional": true + }, + "pick": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "user": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "guest.reference" + }, + { + "type": "inline", + "name": "author.reference" + } + ] + }, + "optional": true + }, + "name": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "site": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } } } - ] + } } }, "optional": true }, - "videoCloudinary": { + "spotify": { "type": "objectAttribute", "value": { "type": "inline", - "name": "videoCloudinary" + "name": "podcastRssEpisode" }, "optional": true }, - "youtube": { + "thumbnail": { "type": "objectAttribute", "value": { - "type": "string" + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageAsset.reference" + }, + "optional": true + }, + "media": { + "type": "objectAttribute", + "value": { + "type": "unknown" + }, + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" + }, + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" + } + } + } }, "optional": true }, - "author": { + "duration": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "chapters": { "type": "objectAttribute", "value": { "type": "array", "of": { "type": "object", "attributes": { - "_key": { + "title": { "type": "objectAttribute", "value": { "type": "string" - } + }, + "optional": true + }, + "timestamp": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "seconds": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true } }, "rest": { - "type": "inline", - "name": "author.reference" + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } } } }, "optional": true }, - "sponsor": { + "series": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "podcastSeries.reference" + }, + "optional": true + }, + "seriesOrder": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "listenLinks": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "spotify": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "apple": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "overcast": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "pocketCasts": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "rss": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + } + } + }, + "optional": true + }, + "contentType": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "interview" + }, + { + "type": "string", + "value": "solo" + }, + { + "type": "string", + "value": "tutorial" + }, + { + "type": "string", + "value": "news" + }, + { + "type": "string", + "value": "review" + } + ] + }, + "optional": true + }, + "relatedShorts": { "type": "objectAttribute", "value": { "type": "array", @@ -8132,226 +7725,255 @@ }, "rest": { "type": "inline", - "name": "sponsor.reference" + "name": "short.reference" } } }, "optional": true }, - "devto": { + "relatedBlogPost": { "type": "objectAttribute", "value": { - "type": "string" + "type": "inline", + "name": "post.reference" }, "optional": true + } + } + }, + { + "name": "podcastSeries", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } }, - "hashnode": { + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "podcastSeries" + } + }, + "_createdAt": { "type": "objectAttribute", "value": { "type": "string" - }, - "optional": true + } }, - "statistics": { + "_updatedAt": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "statistics" - }, - "optional": true + "type": "string" + } }, - "ogTitle": { + "_rev": { "type": "objectAttribute", "value": { "type": "string" - }, - "optional": true + } }, - "ogDescription": { + "title": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "ogImage": { + "slug": { "type": "objectAttribute", "value": { "type": "inline", - "name": "ogImage" + "name": "slug" }, "optional": true }, - "twitterCardType": { + "description": { "type": "objectAttribute", "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "summary_large_image" + "type": "string" + }, + "optional": true + }, + "coverImage": { + "type": "objectAttribute", + "value": { + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageAsset.reference" + }, + "optional": true }, - { - "type": "string", - "value": "summary" + "media": { + "type": "objectAttribute", + "value": { + "type": "unknown" + }, + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" + }, + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" + } } - ] + } }, "optional": true }, - "noIndex": { + "youtubePlaylistId": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "string" }, "optional": true }, - "categories": { + "isActive": { "type": "objectAttribute", "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "category.reference" - } - } + "type": "boolean" }, "optional": true } } }, { + "name": "podcastRssEpisode", "type": "type", - "name": "podcastType.reference", "value": { "type": "object", "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, "_type": { "type": "objectAttribute", "value": { "type": "string", - "value": "reference" + "value": "podcastRssEpisode" } }, - "_weak": { + "title": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "string" }, "optional": true - } - }, - "dereferencesTo": "podcastType" - } - }, - { - "type": "type", - "name": "guest.reference", - "value": { - "type": "object", - "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "reference" - } }, - "_weak": { + "description": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "string" }, "optional": true - } - }, - "dereferencesTo": "guest" - } - }, - { - "type": "type", - "name": "podcastSeries.reference", - "value": { - "type": "object", - "attributes": { - "_ref": { - "type": "objectAttribute", - "value": { - "type": "string" - } }, - "_type": { + "link": { "type": "objectAttribute", "value": { - "type": "string", - "value": "reference" - } + "type": "string" + }, + "optional": true }, - "_weak": { + "guid": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "inline", + "name": "guid" }, "optional": true - } - }, - "dereferencesTo": "podcastSeries" - } - }, - { - "type": "type", - "name": "short.reference", - "value": { - "type": "object", - "attributes": { - "_ref": { + }, + "pubDate": { "type": "objectAttribute", "value": { "type": "string" - } + }, + "optional": true }, - "_type": { + "enclosures": { "type": "objectAttribute", "value": { - "type": "string", - "value": "reference" - } + "type": "array", + "of": { + "type": "object", + "attributes": { + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "length": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "type": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "enclosure" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true }, - "_weak": { + "itunes": { "type": "objectAttribute", "value": { - "type": "boolean" + "type": "inline", + "name": "itunes" }, "optional": true } - }, - "dereferencesTo": "short" + } } }, { - "name": "podcast", + "name": "guest", "type": "document", "attributes": { "_id": { @@ -8364,7 +7986,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "podcast" + "value": "guest" } }, "_createdAt": { @@ -9192,693 +8814,916 @@ } }, "rest": { - "type": "inline", - "name": "table" - } - } - ] - } - }, - "optional": true - }, - "videoCloudinary": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "videoCloudinary" - }, - "optional": true - }, - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "author": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" + "type": "inline", + "name": "table" } } - }, - "rest": { - "type": "inline", - "name": "author.reference" - } + ] } }, "optional": true }, - "sponsor": { + "socials": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "socials" + }, + "optional": true + }, + "websites": { "type": "objectAttribute", "value": { "type": "array", "of": { "type": "object", "attributes": { - "_key": { + "site": { "type": "objectAttribute", "value": { "type": "string" + }, + "optional": true + }, + "link": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "link" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "site" } } }, "rest": { - "type": "inline", - "name": "sponsor.reference" + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } } } }, "optional": true }, - "devto": { + "company": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "hashnode": { + "role": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true - }, - "statistics": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "statistics" - }, - "optional": true - }, - "ogTitle": { + } + } + }, + { + "name": "podcastType", + "type": "document", + "attributes": { + "_id": { "type": "objectAttribute", "value": { "type": "string" - }, - "optional": true + } }, - "ogDescription": { + "_type": { "type": "objectAttribute", "value": { - "type": "string" - }, - "optional": true + "type": "string", + "value": "podcastType" + } }, - "ogImage": { + "_createdAt": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "ogImage" - }, - "optional": true + "type": "string" + } }, - "twitterCardType": { + "_updatedAt": { "type": "objectAttribute", "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "summary_large_image" - }, - { - "type": "string", - "value": "summary" - } - ] - }, - "optional": true + "type": "string" + } }, - "noIndex": { + "_rev": { "type": "objectAttribute", "value": { - "type": "boolean" - }, - "optional": true + "type": "string" + } }, - "podcastType": { + "coverImage": { "type": "objectAttribute", "value": { "type": "inline", - "name": "podcastType.reference" - }, - "optional": true - }, - "season": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "episode": { - "type": "objectAttribute", - "value": { - "type": "number" + "name": "coverImage" }, "optional": true }, - "recordingDate": { + "date": { "type": "objectAttribute", "value": { "type": "string" }, "optional": true }, - "guest": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "guest.reference" - } - } - }, - "optional": true - }, - "pick": { + "title": { "type": "objectAttribute", "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "user": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "inline", - "name": "guest.reference" - }, - { - "type": "inline", - "name": "author.reference" - } - ] - }, - "optional": true - }, - "name": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "site": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - } - } - } + "type": "string" }, "optional": true }, - "spotify": { + "slug": { "type": "objectAttribute", "value": { "type": "inline", - "name": "podcastRssEpisode" - }, - "optional": true - }, - "thumbnail": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "asset": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageAsset.reference" - }, - "optional": true - }, - "media": { - "type": "objectAttribute", - "value": { - "type": "unknown" - }, - "optional": true - }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" - }, - "optional": true - }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" - }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } - } - } + "name": "slug" }, "optional": true }, - "duration": { + "excerpt": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "featured": { "type": "objectAttribute", "value": { "type": "number" }, "optional": true }, - "chapters": { + "content": { "type": "objectAttribute", "value": { "type": "array", "of": { - "type": "object", - "attributes": { - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "timestamp": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "seconds": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - } - }, - "rest": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "children": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "marks": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "span" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true + }, + "style": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "normal" + }, + { + "type": "string", + "value": "h1" + }, + { + "type": "string", + "value": "h2" + }, + { + "type": "string", + "value": "h3" + }, + { + "type": "string", + "value": "h4" + }, + { + "type": "string", + "value": "h5" + }, + { + "type": "string", + "value": "h6" + }, + { + "type": "string", + "value": "blockquote" + } + ] + }, + "optional": true + }, + "listItem": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "bullet" + }, + { + "type": "string", + "value": "number" + } + ] + }, + "optional": true + }, + "markDefs": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "href": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "blank": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "link" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "reference": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "post.reference" + }, + { + "type": "inline", + "name": "podcast.reference" + }, + { + "type": "inline", + "name": "page.reference" + } + ] + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "internalLink" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + ] + } + }, + "optional": true + }, + "level": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "block" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } } } - } - } - } - }, - "optional": true - }, - "series": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "podcastSeries.reference" - }, - "optional": true - }, - "seriesOrder": { - "type": "objectAttribute", - "value": { - "type": "number" - }, - "optional": true - }, - "listenLinks": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "youtube": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "spotify": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "apple": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "overcast": { - "type": "objectAttribute", - "value": { - "type": "string" }, - "optional": true - }, - "pocketCasts": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "rss": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - } - } - }, - "optional": true - }, - "transcript": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "contentType": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "interview" - }, - { - "type": "string", - "value": "solo" - }, - { - "type": "string", - "value": "tutorial" - }, - { - "type": "string", - "value": "news" - }, - { - "type": "string", - "value": "review" - } - ] - }, - "optional": true - }, - "relatedShorts": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "_key": { - "type": "objectAttribute", - "value": { - "type": "string" - } - } - }, - "rest": { - "type": "inline", - "name": "short.reference" - } - } - }, - "optional": true - }, - "relatedBlogPost": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "post.reference" - }, - "optional": true - } - } - }, - { - "name": "podcastSeries", - "type": "document", - "attributes": { - "_id": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "podcastSeries" - } - }, - "_createdAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_updatedAt": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "_rev": { - "type": "objectAttribute", - "value": { - "type": "string" - } - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "slug": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "slug" - }, - "optional": true - }, - "description": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "coverImage": { - "type": "objectAttribute", - "value": { - "type": "object", - "attributes": { - "asset": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageAsset.reference" + { + "type": "object", + "attributes": { + "asset": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageAsset.reference" + }, + "optional": true + }, + "media": { + "type": "objectAttribute", + "value": { + "type": "unknown" + }, + "optional": true + }, + "hotspot": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageHotspot" + }, + "optional": true + }, + "crop": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "sanity.imageCrop" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "image" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } }, - "optional": true - }, - "media": { - "type": "objectAttribute", - "value": { - "type": "unknown" + { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "code" + } }, - "optional": true - }, - "hotspot": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageHotspot" + { + "type": "object", + "attributes": { + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "youtube" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } }, - "optional": true - }, - "crop": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "sanity.imageCrop" + { + "type": "object", + "attributes": { + "shorts": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "youtubeShorts" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } }, - "optional": true - }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "image" - } - } - } - }, - "optional": true - }, - "youtubePlaylistId": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "isActive": { - "type": "objectAttribute", - "value": { - "type": "boolean" - }, - "optional": true - } - } - }, - { - "name": "podcastRssEpisode", - "type": "type", - "value": { - "type": "object", - "attributes": { - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "podcastRssEpisode" - } - }, - "title": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "description": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "link": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "guid": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "guid" - }, - "optional": true - }, - "pubDate": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "enclosures": { - "type": "objectAttribute", - "value": { - "type": "array", - "of": { - "type": "object", - "attributes": { - "url": { - "type": "objectAttribute", - "value": { - "type": "string" + { + "type": "object", + "attributes": { + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "codepen" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "codesandbox" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "id": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true }, - "optional": true + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "twitter" + } + } }, - "length": { - "type": "objectAttribute", - "value": { - "type": "number" + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "html": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "htmlBlock" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "content": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "children": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "marks": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "span" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true + }, + "style": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "normal" + }, + { + "type": "string", + "value": "h1" + }, + { + "type": "string", + "value": "h2" + }, + { + "type": "string", + "value": "h3" + }, + { + "type": "string", + "value": "h4" + }, + { + "type": "string", + "value": "h5" + }, + { + "type": "string", + "value": "h6" + }, + { + "type": "string", + "value": "blockquote" + } + ] + }, + "optional": true + }, + "listItem": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "bullet" + }, + { + "type": "string", + "value": "number" + } + ] + }, + "optional": true + }, + "markDefs": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "union", + "of": [ + { + "type": "object", + "attributes": { + "href": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "blank": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "link" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "attributes": { + "reference": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "post.reference" + }, + { + "type": "inline", + "name": "podcast.reference" + }, + { + "type": "inline", + "name": "page.reference" + } + ] + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "internalLink" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + ] + } + }, + "optional": true + }, + "level": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "block" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true }, - "optional": true - }, - "type": { - "type": "objectAttribute", - "value": { - "type": "string" + "url": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true }, - "optional": true + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "quote" + } + } }, - "_type": { - "type": "objectAttribute", - "value": { - "type": "string", - "value": "enclosure" + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } } } }, - "rest": { + { "type": "object", "attributes": { "_key": { @@ -9887,25 +9732,21 @@ "type": "string" } } + }, + "rest": { + "type": "inline", + "name": "table" } } - } - }, - "optional": true + ] + } }, - "itunes": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "itunes" - }, - "optional": true - } + "optional": true } } }, { - "name": "guest", + "name": "page", "type": "document", "attributes": { "_id": { @@ -9918,7 +9759,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "guest" + "value": "page" } }, "_createdAt": { @@ -10755,33 +10596,461 @@ }, "optional": true }, - "socials": { + "videoCloudinary": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "videoCloudinary" + }, + "optional": true + }, + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "transcript": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "transcript.reference" + }, + "optional": true + }, + "author": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "author.reference" + } + } + }, + "optional": true + }, + "sponsor": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "sponsor.reference" + } + } + }, + "optional": true + }, + "devto": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "hashnode": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "statistics": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "statistics" + }, + "optional": true + }, + "ogTitle": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogDescription": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "ogImage": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "ogImage" + }, + "optional": true + }, + "twitterCardType": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "summary_large_image" + }, + { + "type": "string", + "value": "summary" + } + ] + }, + "optional": true + }, + "noIndex": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + } + }, + { + "type": "type", + "name": "lesson.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "lesson" + } + }, + { + "type": "type", + "name": "course.reference", + "value": { + "type": "object", + "attributes": { + "_ref": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "reference" + } + }, + "_weak": { + "type": "objectAttribute", + "value": { + "type": "boolean" + }, + "optional": true + } + }, + "dereferencesTo": "course" + } + }, + { + "name": "transcript", + "type": "document", + "attributes": { + "_id": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "transcript" + } + }, + "_createdAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_updatedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "_rev": { + "type": "objectAttribute", + "value": { + "type": "string" + } + }, + "title": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "youtubeId": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "socials" + "type": "string" + }, + "optional": true + }, + "youtubeUrl": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "contentRef": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "inline", + "name": "post.reference" + }, + { + "type": "inline", + "name": "podcast.reference" + }, + { + "type": "inline", + "name": "page.reference" + }, + { + "type": "inline", + "name": "lesson.reference" + }, + { + "type": "inline", + "name": "course.reference" + } + ] + }, + "optional": true + }, + "channelTitle": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "channelId": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "publishedAt": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "duration": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "durationSeconds": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "description": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "tags": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "topicCategories": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "string" + } + }, + "optional": true + }, + "status": { + "type": "objectAttribute", + "value": { + "type": "union", + "of": [ + { + "type": "string", + "value": "completed" + }, + { + "type": "string", + "value": "no_caption_available" + }, + { + "type": "string", + "value": "error" + } + ] + }, + "optional": true + }, + "fullText": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "summary": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "chapters": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "title": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "start": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "timestamp": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "chapter" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } }, "optional": true }, - "websites": { + "cues": { "type": "objectAttribute", "value": { "type": "array", "of": { "type": "object", "attributes": { - "site": { + "start": { "type": "objectAttribute", "value": { - "type": "string" + "type": "number" }, "optional": true }, - "link": { + "duration": { "type": "objectAttribute", "value": { - "type": "inline", - "name": "link" + "type": "number" + }, + "optional": true + }, + "text": { + "type": "objectAttribute", + "value": { + "type": "string" }, "optional": true }, @@ -10789,7 +11058,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "site" + "value": "cue" } } }, @@ -10808,14 +11077,44 @@ }, "optional": true }, - "company": { + "statistics": { "type": "objectAttribute", "value": { - "type": "string" + "type": "object", + "attributes": { + "viewCount": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "likeCount": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "commentCount": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + }, + "favoriteCount": { + "type": "objectAttribute", + "value": { + "type": "number" + }, + "optional": true + } + } }, "optional": true }, - "role": { + "lastFetchedAt": { "type": "objectAttribute", "value": { "type": "string" @@ -10825,7 +11124,7 @@ } }, { - "name": "podcastType", + "name": "course", "type": "document", "attributes": { "_id": { @@ -10838,7 +11137,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "podcastType" + "value": "course" } }, "_createdAt": { @@ -11674,11 +11973,166 @@ } }, "optional": true + }, + "videoCloudinary": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "videoCloudinary" + }, + "optional": true + }, + "youtube": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "transcript": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "transcript.reference" + }, + "optional": true + }, + "author": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "author.reference" + } + } + }, + "optional": true + }, + "sponsor": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "sponsor.reference" + } + } + }, + "optional": true + }, + "devto": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "hashnode": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "statistics": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "statistics" + }, + "optional": true + }, + "stripeProduct": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "sections": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "title": { + "type": "objectAttribute", + "value": { + "type": "string" + }, + "optional": true + }, + "lesson": { + "type": "objectAttribute", + "value": { + "type": "array", + "of": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + }, + "rest": { + "type": "inline", + "name": "lesson.reference" + } + } + }, + "optional": true + }, + "_type": { + "type": "objectAttribute", + "value": { + "type": "string", + "value": "section" + } + } + }, + "rest": { + "type": "object", + "attributes": { + "_key": { + "type": "objectAttribute", + "value": { + "type": "string" + } + } + } + } + } + }, + "optional": true } } }, { - "name": "page", + "name": "lesson", "type": "document", "attributes": { "_id": { @@ -11691,7 +12145,7 @@ "type": "objectAttribute", "value": { "type": "string", - "value": "page" + "value": "lesson" } }, "_createdAt": { @@ -12543,6 +12997,14 @@ }, "optional": true }, + "transcript": { + "type": "objectAttribute", + "value": { + "type": "inline", + "name": "transcript.reference" + }, + "optional": true + }, "author": { "type": "objectAttribute", "value": { @@ -12609,46 +13071,7 @@ }, "optional": true }, - "ogTitle": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "ogDescription": { - "type": "objectAttribute", - "value": { - "type": "string" - }, - "optional": true - }, - "ogImage": { - "type": "objectAttribute", - "value": { - "type": "inline", - "name": "ogImage" - }, - "optional": true - }, - "twitterCardType": { - "type": "objectAttribute", - "value": { - "type": "union", - "of": [ - { - "type": "string", - "value": "summary_large_image" - }, - { - "type": "string", - "value": "summary" - } - ] - }, - "optional": true - }, - "noIndex": { + "locked": { "type": "objectAttribute", "value": { "type": "boolean" diff --git a/apps/sanity/functions/sync-nightly-dataset/index.ts b/apps/sanity/functions/sync-nightly-dataset/index.ts new file mode 100644 index 000000000..7095957dc --- /dev/null +++ b/apps/sanity/functions/sync-nightly-dataset/index.ts @@ -0,0 +1,86 @@ +import { scheduledEventHandler } from "@sanity/functions"; + +export const handler = scheduledEventHandler(async ({ context }) => { + console.log("[Sync Nightly Dataset] Starting scheduled dataset sync..."); + + const projectId = + context.clientOptions?.projectId || + process.env.SANITY_STUDIO_PROJECT_ID || + "hfh83o0w"; + const token = + context.clientOptions?.token || process.env.SANITY_AUTH_TOKEN; + + if (!token) { + throw new Error( + "[Sync Nightly Dataset] Missing Sanity API token (neither context.clientOptions.token nor SANITY_AUTH_TOKEN is present).", + ); + } + + const apiHost = + context.clientOptions?.apiHost || "https://api.sanity.io"; + const apiVersion = "v2025-09-30"; + + const targetDataset = "dev"; + const sourceDataset = "production"; + + console.log( + `[Sync Nightly Dataset] Resetting dataset "${targetDataset}" from source "${sourceDataset}" for project ${projectId}...`, + ); + + // 1. Delete existing target dataset (dev) if it exists + const deleteUrl = `${apiHost}/${apiVersion}/projects/${projectId}/datasets/${targetDataset}`; + console.log(`[Sync Nightly Dataset] Deleting existing dataset "${targetDataset}": ${deleteUrl}`); + + const deleteResp = await fetch(deleteUrl, { + method: "DELETE", + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + if (deleteResp.ok) { + console.log( + `[Sync Nightly Dataset] Target dataset "${targetDataset}" deleted successfully (HTTP ${deleteResp.status}).`, + ); + } else if (deleteResp.status === 404) { + console.log( + `[Sync Nightly Dataset] Target dataset "${targetDataset}" does not exist yet (HTTP 404). Proceeding to clone.`, + ); + } else { + const deleteError = await deleteResp.text(); + console.warn( + `[Sync Nightly Dataset] Notice when deleting dataset "${targetDataset}": HTTP ${deleteResp.status} — ${deleteError}`, + ); + } + + // 2. Clone source dataset (production) to target (dev) via Sanity Enterprise Copy API + const copyUrl = `${apiHost}/${apiVersion}/projects/${projectId}/datasets/${sourceDataset}/copy`; + console.log( + `[Sync Nightly Dataset] Copying "${sourceDataset}" -> "${targetDataset}": ${copyUrl}`, + ); + + const copyResp = await fetch(copyUrl, { + method: "PUT", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + targetDataset, + skipHistory: true, + }), + }); + + if (!copyResp.ok) { + const errorText = await copyResp.text(); + throw new Error( + `[Sync Nightly Dataset] Failed to initiate dataset copy from "${sourceDataset}" to "${targetDataset}": HTTP ${copyResp.status} — ${errorText}`, + ); + } + + const copyResult = await copyResp.json().catch(() => ({})); + console.log( + `[Sync Nightly Dataset] Successfully initiated dataset copy from "${sourceDataset}" to "${targetDataset}":`, + copyResult, + ); +}); diff --git a/apps/sanity/functions/sync-youtube-transcript/index.ts b/apps/sanity/functions/sync-youtube-transcript/index.ts new file mode 100644 index 000000000..b6cee292f --- /dev/null +++ b/apps/sanity/functions/sync-youtube-transcript/index.ts @@ -0,0 +1,402 @@ +import { documentEventHandler } from "@sanity/functions"; +import { createClient } from "@sanity/client"; +import { youtubeParser } from "../../lib/utils"; + +interface TargetContentDocument { + _id: string; + _type: string; + title?: string; + youtube?: string; + transcript?: { + _type: "reference"; + _ref: string; + }; +} + +interface Chapter { + title: string; + start: number; + timestamp: string; +} + +interface Cue { + start: number; + duration: number; + text: string; +} + +function parseIsoDuration(duration?: string): number { + if (!duration) return 0; + const match = duration.match(/PT(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?/); + if (!match) return 0; + const hours = parseInt(match[1] || "0", 10); + const minutes = parseInt(match[2] || "0", 10); + const seconds = parseInt(match[3] || "0", 10); + return hours * 3600 + minutes * 60 + seconds; +} + +function extractChaptersFromDescription(description?: string): Chapter[] { + if (!description) return []; + const lines = description.split("\n"); + const chapters: Chapter[] = []; + const chapterRegex = + /(?:^|\s)(?:(\d{1,2}):)?(\d{1,2}):(\d{2})(?:\s+[-–—:]\s*|\s+)(.+)$/; + + for (const line of lines) { + const match = line.trim().match(chapterRegex); + if (match) { + const hours = match[1] ? parseInt(match[1], 10) : 0; + const minutes = parseInt(match[2], 10); + const seconds = parseInt(match[3], 10); + const totalSeconds = hours * 3600 + minutes * 60 + seconds; + const title = match[4].trim(); + const timestamp = match[1] + ? `${match[1]}:${match[2].padStart(2, "0")}:${match[3].padStart(2, "0")}` + : `${match[2]}:${match[3].padStart(2, "0")}`; + chapters.push({ title, start: totalSeconds, timestamp }); + } + } + return chapters; +} + +function decodeHtmlEntities(text: string): string { + return text + .replace(/&/g, "&") + .replace(/</g, "<") + .replace(/>/g, ">") + .replace(/"/g, '"') + .replace(/'/g, "'") + .replace(/'/g, "'") + .replace(/&#x([0-9a-fA-F]+);/g, (_, hex) => + String.fromCodePoint(parseInt(hex, 16)), + ) + .replace(/&#(\d+);/g, (_, dec) => String.fromCodePoint(parseInt(dec, 10))) + .replace(/\s+/g, " ") + .trim(); +} + +async function fetchYouTubeCaptions(videoId: string): Promise<{ + cues: Cue[]; + fullText: string; + status: "completed" | "no_caption_available"; +}> { + const INNERTUBE_API_URL = + "https://www.youtube.com/youtubei/v1/player?prettyPrint=false"; + const INNERTUBE_CLIENT_VERSION = "20.10.38"; + + try { + const response = await fetch(INNERTUBE_API_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + "User-Agent": `com.google.android.youtube/${INNERTUBE_CLIENT_VERSION} (Linux; U; Android 14)`, + }, + body: JSON.stringify({ + context: { + client: { + clientName: "ANDROID", + clientVersion: INNERTUBE_CLIENT_VERSION, + }, + }, + videoId, + }), + }); + + if (!response.ok) { + console.warn( + `[Sync YouTube Transcript] Innertube API returned HTTP ${response.status}`, + ); + return { cues: [], fullText: "", status: "no_caption_available" }; + } + + const data = await response.json(); + const captionTracks = + data?.captions?.playerCaptionsTracklistRenderer?.captionTracks; + + if (!Array.isArray(captionTracks) || captionTracks.length === 0) { + console.log( + `[Sync YouTube Transcript] No caption tracks found for video: ${videoId}`, + ); + return { cues: [], fullText: "", status: "no_caption_available" }; + } + + // Prefer English track or default to first + const track = + captionTracks.find( + (t: any) => + t?.languageCode?.toLowerCase().startsWith("en") || + t?.name?.runs?.[0]?.text?.toLowerCase().includes("english"), + ) || captionTracks[0]; + + if (!track?.baseUrl) { + return { cues: [], fullText: "", status: "no_caption_available" }; + } + + const captionResp = await fetch(track.baseUrl); + if (!captionResp.ok) { + console.warn( + `[Sync YouTube Transcript] Failed to fetch caption track XML: HTTP ${captionResp.status}`, + ); + return { cues: [], fullText: "", status: "no_caption_available" }; + } + + const xml = await captionResp.text(); + const cues: Cue[] = []; + + // Try srv3 format (

text

) + const pRegex = /]*>([\s\S]*?)<\/p>/g; + let match: RegExpExecArray | null; + + while ((match = pRegex.exec(xml)) !== null) { + const startMs = parseInt(match[1], 10); + const durMs = parseInt(match[2], 10); + const inner = match[3]; + + let text = ""; + const sRegex = /]*>([^<]*)<\/s>/g; + let sMatch: RegExpExecArray | null; + while ((sMatch = sRegex.exec(inner)) !== null) { + text += sMatch[1]; + } + if (!text) { + text = inner.replace(/<[^>]+>/g, ""); + } + + text = decodeHtmlEntities(text); + if (text) { + cues.push({ + start: Math.round((startMs / 1000) * 100) / 100, + duration: Math.round((durMs / 1000) * 100) / 100, + text, + }); + } + } + + // Fallback to classic format (text) + if (cues.length === 0) { + const textRegex = /]*>([\s\S]*?)<\/text>/g; + while ((match = textRegex.exec(xml)) !== null) { + const start = parseFloat(match[1]); + const dur = parseFloat(match[2]); + const text = decodeHtmlEntities(match[3]); + if (text) { + cues.push({ + start: Math.round(start * 100) / 100, + duration: Math.round(dur * 100) / 100, + text, + }); + } + } + } + + const fullText = cues.map((c) => c.text).join(" "); + return { + cues, + fullText, + status: cues.length > 0 ? "completed" : "no_caption_available", + }; + } catch (error) { + console.warn( + `[Sync YouTube Transcript] Error fetching captions for ${videoId}:`, + error, + ); + return { cues: [], fullText: "", status: "no_caption_available" }; + } +} + +function generateSummary( + title: string, + description: string, + fullText: string, +): string { + const descSnippet = description ? description.slice(0, 300).trim() : ""; + if (fullText && fullText.length > 50) { + const transcriptSnippet = fullText.slice(0, 400).trim(); + return `${title}: ${descSnippet ? descSnippet + " — " : ""}${transcriptSnippet}...`; + } + return `${title}: ${descSnippet}`; +} + +export const handler = documentEventHandler( + async ({ context, event }) => { + const rawData = event.data; + if (!rawData?._id || !rawData?._type) { + console.log("[Sync YouTube Transcript] No valid document data in event, skipping."); + return; + } + + // Skip drafts + if (rawData._id.startsWith("drafts.")) { + console.log("[Sync YouTube Transcript] Skipping draft document:", rawData._id); + return; + } + + // Production dataset enforcement + const dataset = context.clientOptions?.dataset || "dev"; + if (dataset !== "production") { + console.log( + `[Sync YouTube Transcript] Skipping execution: dataset is "${dataset}", execution restricted to "production".`, + ); + return; + } + + // Extract YouTube ID + if (!rawData.youtube) { + console.log( + `[Sync YouTube Transcript] Document ${rawData._id} has no youtube field, skipping.`, + ); + return; + } + + const youtubeId = youtubeParser(rawData.youtube); + if (!youtubeId) { + console.log( + `[Sync YouTube Transcript] Could not parse YouTube video ID from "${rawData.youtube}" for document ${rawData._id}.`, + ); + return; + } + + // YouTube API Key validation: strictly required per project specification + const apiKey = process.env.YOUTUBE_API_KEY; + if (!apiKey) { + throw new Error( + "[Sync YouTube Transcript] YOUTUBE_API_KEY environment variable is missing. Full access to video intelligence is required.", + ); + } + + const client = createClient({ + ...context.clientOptions, + apiVersion: "2025-09-30", + }); + + const transcriptId = `transcript-yt-${youtubeId}`; + + // Recursion guard and recent fetch check: + // If document already links to this transcript and the transcript was fetched within the last 24 hours, skip. + const existingTranscript = await client + .getDocument<{ _id: string; lastFetchedAt?: string }>(transcriptId) + .catch(() => null); + + const isLinked = rawData.transcript?._ref === transcriptId; + + if (existingTranscript && isLinked && existingTranscript.lastFetchedAt) { + const lastFetched = new Date(existingTranscript.lastFetchedAt).getTime(); + const now = Date.now(); + const oneDayMs = 24 * 60 * 60 * 1000; + if (now - lastFetched < oneDayMs) { + console.log( + `[Sync YouTube Transcript] Transcript ${transcriptId} already up to date and linked to ${rawData._id}. Skipping.`, + ); + return; + } + } + + console.log( + `[Sync YouTube Transcript] Fetching YouTube Data API v3 for video ID: ${youtubeId}`, + ); + + // Fetch video metadata via YouTube Data API v3 + const ytApiUrl = `https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails,statistics,topicDetails&id=${youtubeId}&key=${apiKey}`; + const ytResp = await fetch(ytApiUrl); + + if (!ytResp.ok) { + const errorText = await ytResp.text(); + throw new Error( + `[Sync YouTube Transcript] YouTube Data API returned HTTP ${ytResp.status}: ${errorText}`, + ); + } + + const ytData = await ytResp.json(); + const videoItem = ytData?.items?.[0]; + + if (!videoItem) { + throw new Error( + `[Sync YouTube Transcript] Video not found on YouTube for ID: ${youtubeId}`, + ); + } + + const snippet = videoItem.snippet || {}; + const contentDetails = videoItem.contentDetails || {}; + const statistics = videoItem.statistics || {}; + const topicDetails = videoItem.topicDetails || {}; + + const duration = contentDetails.duration || ""; + const durationSeconds = parseIsoDuration(duration); + const chapters = extractChaptersFromDescription(snippet.description); + + console.log( + `[Sync YouTube Transcript] Fetching timed captions for video ID: ${youtubeId}`, + ); + const captionResult = await fetchYouTubeCaptions(youtubeId); + + const summary = generateSummary( + snippet.title || rawData.title || "Video", + snippet.description || "", + captionResult.fullText, + ); + + // 1. Create or replace the published transcript document + await client.createOrReplace({ + _id: transcriptId, + _type: "transcript", + title: snippet.title || rawData.title || `YouTube: ${youtubeId}`, + youtubeId, + youtubeUrl: `https://www.youtube.com/watch?v=${youtubeId}`, + contentRef: { + _type: "reference", + _ref: rawData._id, + }, + channelTitle: snippet.channelTitle, + channelId: snippet.channelId, + publishedAt: snippet.publishedAt, + duration, + durationSeconds, + description: snippet.description || "", + tags: snippet.tags || [], + topicCategories: topicDetails.topicCategories || [], + status: captionResult.status, + fullText: captionResult.fullText, + summary, + chapters, + cues: captionResult.cues, + statistics: { + viewCount: statistics.viewCount + ? parseInt(statistics.viewCount, 10) + : undefined, + likeCount: statistics.likeCount + ? parseInt(statistics.likeCount, 10) + : undefined, + commentCount: statistics.commentCount + ? parseInt(statistics.commentCount, 10) + : undefined, + favoriteCount: statistics.favoriteCount + ? parseInt(statistics.favoriteCount, 10) + : undefined, + }, + lastFetchedAt: new Date().toISOString(), + }); + + console.log( + `[Sync YouTube Transcript] Successfully created/updated published transcript ${transcriptId} (cues: ${captionResult.cues.length}, status: ${captionResult.status}).`, + ); + + // 2. Link reference in parent document if not already linked + if (!isLinked) { + console.log( + `[Sync YouTube Transcript] Linking transcript ${transcriptId} to source document ${rawData._id}.`, + ); + await client + .patch(rawData._id) + .set({ + transcript: { + _type: "reference", + _ref: transcriptId, + }, + }) + .commit(); + console.log( + `[Sync YouTube Transcript] Parent document ${rawData._id} patched with transcript reference.`, + ); + } + }, +); diff --git a/apps/sanity/sanity.blueprint.ts b/apps/sanity/sanity.blueprint.ts index e00fd3390..7c5f54828 100644 --- a/apps/sanity/sanity.blueprint.ts +++ b/apps/sanity/sanity.blueprint.ts @@ -1,4 +1,8 @@ -import { defineBlueprint, defineDocumentFunction } from "@sanity/blueprints"; +import { + defineBlueprint, + defineDocumentFunction, + defineScheduledFunction, +} from "@sanity/blueprints"; export default defineBlueprint({ resources: [ @@ -12,5 +16,27 @@ export default defineBlueprint({ runtime: "nodejs22.x", timeout: 30, }), + defineDocumentFunction({ + name: "sync-youtube-transcript", + displayName: "Sync YouTube Transcripts & Video Intelligence", + event: { + on: ["create", "update"], + filter: 'defined(youtube) && !(_id in path("drafts.**"))', + }, + runtime: "nodejs22.x", + timeout: 60, + env: { + YOUTUBE_API_KEY: process.env.YOUTUBE_API_KEY || "", + }, + }), + defineScheduledFunction({ + name: "sync-nightly-dataset", + displayName: "Nightly Dataset Sync (production -> dev)", + event: { + expression: "0 4 * * *", + }, + runtime: "nodejs22.x", + timeout: 300, + }), ], }); diff --git a/apps/sanity/sanity.config.ts b/apps/sanity/sanity.config.ts index c8ca15cdb..1b712b1d5 100644 --- a/apps/sanity/sanity.config.ts +++ b/apps/sanity/sanity.config.ts @@ -53,6 +53,7 @@ import short from "./schemas/documents/short"; import lesson from "./schemas/documents/lesson"; import course from "./schemas/documents/course"; import syndication from "./schemas/documents/syndication"; +import transcript from "./schemas/documents/transcript"; // ── Shared constants ───────────────────────────────────────────────── const projectId = process.env.SANITY_STUDIO_PROJECT_ID || "hfh83o0w"; @@ -118,6 +119,7 @@ const schemaTypes = [ lesson, course, syndication, + transcript, ]; // ── Shared document actions ────────────────────────────────────────── diff --git a/apps/sanity/schemas/documents/podcast.ts b/apps/sanity/schemas/documents/podcast.ts index f8b18a698..24739d6fa 100644 --- a/apps/sanity/schemas/documents/podcast.ts +++ b/apps/sanity/schemas/documents/podcast.ts @@ -246,13 +246,6 @@ export default defineType({ }), ], }), - defineField({ - name: "transcript", - title: "Transcript", - type: "text", - group: "podcast", - description: "Full episode transcript", - }), defineField({ name: "contentType", title: "Content Type", diff --git a/apps/sanity/schemas/documents/transcript.ts b/apps/sanity/schemas/documents/transcript.ts new file mode 100644 index 000000000..49875b506 --- /dev/null +++ b/apps/sanity/schemas/documents/transcript.ts @@ -0,0 +1,249 @@ +import { defineField, defineType } from "sanity"; +import { HiOutlineDocumentText } from "react-icons/hi"; + +export default defineType({ + name: "transcript", + title: "Transcript & Video Intelligence", + type: "document", + icon: HiOutlineDocumentText, + groups: [ + { name: "transcript", title: "Transcript & Cues", default: true }, + { name: "video", title: "Video Metadata" }, + { name: "stats", title: "Statistics" }, + ], + fields: [ + defineField({ + name: "title", + title: "Video Title", + type: "string", + group: "video", + validation: (Rule) => Rule.required(), + }), + defineField({ + name: "youtubeId", + title: "YouTube Video ID", + type: "string", + group: "video", + description: "11-character YouTube video ID", + validation: (Rule) => Rule.required(), + }), + defineField({ + name: "youtubeUrl", + title: "YouTube URL", + type: "url", + group: "video", + }), + defineField({ + name: "contentRef", + title: "Source Document", + type: "reference", + to: [ + { type: "post" }, + { type: "podcast" }, + { type: "page" }, + { type: "lesson" }, + { type: "course" }, + ], + group: "video", + description: "The source content document referencing this transcript", + }), + defineField({ + name: "channelTitle", + title: "Channel Title", + type: "string", + group: "video", + }), + defineField({ + name: "channelId", + title: "Channel ID", + type: "string", + group: "video", + }), + defineField({ + name: "publishedAt", + title: "Video Published At", + type: "datetime", + group: "video", + }), + defineField({ + name: "duration", + title: "Duration (ISO 8601)", + type: "string", + group: "video", + description: "ISO 8601 duration e.g. PT15M33S", + }), + defineField({ + name: "durationSeconds", + title: "Duration (Seconds)", + type: "number", + group: "video", + }), + defineField({ + name: "description", + title: "Video Description", + type: "text", + rows: 6, + group: "video", + }), + defineField({ + name: "tags", + title: "Video Tags", + type: "array", + of: [{ type: "string" }], + options: { layout: "tags" }, + group: "video", + }), + defineField({ + name: "topicCategories", + title: "Topic Entities (Wikipedia)", + type: "array", + of: [{ type: "url" }], + group: "video", + }), + defineField({ + name: "status", + title: "Transcript Status", + type: "string", + options: { + list: [ + { title: "Completed", value: "completed" }, + { title: "No Captions Available", value: "no_caption_available" }, + { title: "Error", value: "error" }, + ], + }, + group: "transcript", + initialValue: "completed", + }), + defineField({ + name: "fullText", + title: "Full Transcript Text", + type: "text", + rows: 14, + group: "transcript", + description: + "Continuous plain-text transcript indexed for search and retrieval.", + }), + defineField({ + name: "summary", + title: "Transcript Summary & Key Concepts", + type: "text", + rows: 5, + group: "transcript", + description: + "High-density topical summary for semantic similarity search and knowledgebase indexing.", + }), + defineField({ + name: "chapters", + title: "Chapters & Timestamps", + type: "array", + group: "transcript", + of: [ + { + type: "object", + name: "chapter", + fields: [ + defineField({ name: "title", title: "Title", type: "string" }), + defineField({ + name: "start", + title: "Start (Seconds)", + type: "number", + }), + defineField({ + name: "timestamp", + title: "Display Timestamp", + type: "string", + }), + ], + preview: { + select: { + title: "title", + subtitle: "timestamp", + }, + }, + }, + ], + }), + defineField({ + name: "cues", + title: "Timed Transcript Cues", + type: "array", + group: "transcript", + of: [ + { + type: "object", + name: "cue", + fields: [ + defineField({ + name: "start", + title: "Start Offset (s)", + type: "number", + }), + defineField({ + name: "duration", + title: "Duration (s)", + type: "number", + }), + defineField({ name: "text", title: "Spoken Text", type: "string" }), + ], + preview: { + select: { + title: "text", + subtitle: "start", + }, + prepare({ title, subtitle }) { + const mins = Math.floor((subtitle || 0) / 60); + const secs = Math.floor((subtitle || 0) % 60); + const timeStr = `${mins}:${secs.toString().padStart(2, "0")}`; + return { + title: title || "(no text)", + subtitle: timeStr, + }; + }, + }, + }, + ], + }), + defineField({ + name: "statistics", + title: "YouTube Statistics", + type: "object", + group: "stats", + fields: [ + defineField({ name: "viewCount", title: "Views", type: "number" }), + defineField({ name: "likeCount", title: "Likes", type: "number" }), + defineField({ + name: "commentCount", + title: "Comments", + type: "number", + }), + defineField({ + name: "favoriteCount", + title: "Favorites", + type: "number", + }), + ], + }), + defineField({ + name: "lastFetchedAt", + title: "Last Fetched At", + type: "datetime", + group: "video", + readOnly: true, + }), + ], + preview: { + select: { + title: "title", + youtubeId: "youtubeId", + status: "status", + duration: "duration", + }, + prepare({ title, youtubeId, status, duration }) { + return { + title: title || `YouTube: ${youtubeId}`, + subtitle: `${status || "completed"} · ${duration || ""}`, + media: HiOutlineDocumentText, + }; + }, + }, +}); diff --git a/apps/sanity/schemas/partials/content.ts b/apps/sanity/schemas/partials/content.ts index 99854ee4e..d72d99a27 100644 --- a/apps/sanity/schemas/partials/content.ts +++ b/apps/sanity/schemas/partials/content.ts @@ -31,6 +31,15 @@ const content = defineType({ input, }, }), + defineField({ + name: "transcript", + title: "Transcript & Video Intelligence", + type: "reference", + to: [{ type: "transcript" }], + group: "data", + description: + "Automated YouTube transcript, metadata, and video intelligence", + }), defineField({ name: "author", title: "Author", diff --git a/apps/site/src/lib/sanity/queries/search.ts b/apps/site/src/lib/sanity/queries/search.ts index 43274ca95..7ff5c0c14 100644 --- a/apps/site/src/lib/sanity/queries/search.ts +++ b/apps/site/src/lib/sanity/queries/search.ts @@ -2,13 +2,15 @@ import { defineQuery } from "groq"; /** * Hybrid semantic search utilizing Sanity dataset embeddings (text::semanticSimilarity) - * combined with boost() scoring on title and excerpt. + * combined with boost() scoring on title, excerpt, and transcript content. */ export const semanticSearchQuery = defineQuery(` *[_type in ["post", "podcast", "author", "guest"] && defined(slug.current) && ($type == null || $type == "all" || _type == $type)] | score( boost(title match $searchTerm + "*", 5), boost(excerpt match $searchTerm + "*", 2), + boost(transcript->summary match $searchTerm + "*", 3), + boost(transcript->fullText match $searchTerm + "*", 1), text::semanticSimilarity($searchTerm) ) | order(_score desc)[0...24] { @@ -16,7 +18,8 @@ export const semanticSearchQuery = defineQuery(` _type, title, "slug": slug.current, - excerpt, + "excerpt": coalesce(excerpt, transcript->summary), + "transcriptSummary": transcript->summary, coverImage, date, _score @@ -29,18 +32,23 @@ export const semanticSearchQuery = defineQuery(` export const textSearchFallbackQuery = defineQuery(` *[_type in ["post", "podcast", "author", "guest"] && defined(slug.current) && ($type == null || $type == "all" || _type == $type) && ( title match $searchTerm + "*" || - excerpt match $searchTerm + "*" + excerpt match $searchTerm + "*" || + transcript->summary match $searchTerm + "*" || + transcript->fullText match $searchTerm + "*" )] | score( boost(title match $searchTerm + "*", 5), - boost(excerpt match $searchTerm + "*", 2) + boost(excerpt match $searchTerm + "*", 2), + boost(transcript->summary match $searchTerm + "*", 3), + boost(transcript->fullText match $searchTerm + "*", 1) ) | order(_score desc)[0...24] { _id, _type, title, "slug": slug.current, - excerpt, + "excerpt": coalesce(excerpt, transcript->summary), + "transcriptSummary": transcript->summary, coverImage, date, _score diff --git a/apps/site/src/lib/sanity/queries/shared.ts b/apps/site/src/lib/sanity/queries/shared.ts index e03fc5717..08a5ec1ec 100644 --- a/apps/site/src/lib/sanity/queries/shared.ts +++ b/apps/site/src/lib/sanity/queries/shared.ts @@ -48,7 +48,18 @@ export const contentFields = ` }, tags, videoCloudinary, - youtube + youtube, + transcript->{ + _id, + title, + duration, + durationSeconds, + status, + summary, + chapters, + cues, + statistics + } `; export const podcastFields = `