import type { PublishPlatformId, PublishPlatformProfile } from './types.js'; const RETRIEVED_AT = '2026-08-20T00:00:00.000Z'; const PROFILES: PublishPlatformProfile[] = [ { platform: 'youtube-shorts', displayName: 'YouTube Shorts', profileVersion: '2026-08-20.youtube-shorts.v1', retrievedAt: RETRIEVED_AT, sources: [ { url: 'https://support.google.com/youtube/answer/15424877', title: 'YouTube Shorts creation eligibility', retrievedAt: RETRIEVED_AT, fields: ['maxDurationSeconds', 'aspectRatios'], }, { url: 'https://support.google.com/youtube/answer/57407', title: 'YouTube upload details', retrievedAt: RETRIEVED_AT, fields: ['maxTitleCharacters', 'maxDescriptionCharacters'], }, { url: 'https://support.google.com/youtube/answer/1722171', title: 'Recommended upload encoding settings', retrievedAt: RETRIEVED_AT, fields: ['containers', 'videoCodecs', 'audioCodecs', 'progressiveRequired'], }, { url: 'https://developers.google.com/youtube/v3/docs/videos', title: 'YouTube Data API videos resource', retrievedAt: RETRIEVED_AT, fields: ['syntheticDisclosureRequired'], }, ], media: { containers: ['mp4'], videoCodecs: ['h264'], audioCodecs: ['aac'], audioRequired: false, progressiveRequired: true, maxDurationSeconds: 180, aspectRatios: [ { label: 'vertical', ratio: 9 / 16, tolerance: 0.03 }, { label: 'square', ratio: 1, tolerance: 0.03 }, ], recommendedAspectRatio: '9:16', }, metadata: { maxTitleCharacters: 100, maxDescriptionCharacters: 5000, syntheticDisclosureRequired: true, supportedVisibility: ['private', 'unlisted', 'public'], captionsOptional: true, captionFormats: ['srt', 'vtt'], thumbnailOptional: true, thumbnailFormats: ['jpg', 'jpeg', 'png'], }, }, { platform: 'tiktok', displayName: 'TikTok', profileVersion: '2026-08-20.tiktok.v1', retrievedAt: RETRIEVED_AT, sources: [ { url: 'https://developers.tiktok.com/doc/content-posting-api-media-transfer-guide', title: 'TikTok Content Posting API media transfer guide', retrievedAt: RETRIEVED_AT, fields: ['containers', 'videoCodecs', 'frameRate', 'dimensions', 'maxDurationSeconds', 'maxSizeBytes'], }, { url: 'https://developers.tiktok.com/doc/content-posting-api-reference-direct-post', title: 'TikTok Direct Post API reference', retrievedAt: RETRIEVED_AT, fields: ['maxTitleCharacters', 'syntheticDisclosureRequired'], }, { url: 'https://developers.tiktok.com/doc/content-posting-api-reference-query-creator-info', title: 'TikTok creator info reference', retrievedAt: RETRIEVED_AT, fields: ['maxDurationSeconds'], }, ], media: { containers: ['mp4', 'mov', 'webm'], videoCodecs: ['h264', 'h265', 'vp8', 'vp9'], audioCodecs: ['aac'], audioRequired: false, maxDurationSeconds: 600, maxSizeBytes: 4_000_000_000, minWidth: 360, maxWidth: 4096, minHeight: 360, maxHeight: 4096, minFrameRate: 23, maxFrameRate: 60, recommendedAspectRatio: '9:16', }, metadata: { maxTitleCharacters: 2200, syntheticDisclosureRequired: true, supportedVisibility: ['private', 'public'], captionsOptional: true, captionFormats: ['srt', 'vtt'], thumbnailOptional: true, thumbnailFormats: ['jpg', 'jpeg', 'png'], }, }, { platform: 'instagram-reels', displayName: 'Instagram Reels', profileVersion: '2026-08-20.instagram-reels.v1', retrievedAt: RETRIEVED_AT, sources: [ { url: 'https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/media/', title: 'Instagram Graph API IG User media reference', retrievedAt: RETRIEVED_AT, fields: ['containers', 'videoCodecs', 'audioCodecs', 'duration', 'size', 'width', 'frameRate', 'bitrate', 'aspectRatio', 'maxTitleCharacters', 'maxHashtags', 'thumbnailFormats'], }, { url: 'https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/content-publishing/', title: 'Instagram Platform content publishing', retrievedAt: RETRIEVED_AT, fields: ['mediaType', 'publishingQuota'], }, ], media: { containers: ['mp4', 'mov'], videoCodecs: ['h264', 'hevc'], audioCodecs: ['aac'], audioRequired: false, progressiveRequired: true, minDurationSeconds: 3, maxDurationSeconds: 900, maxSizeBytes: 300_000_000, maxWidth: 1920, minFrameRate: 23, maxFrameRate: 60, minAspectRatio: 0.01, maxAspectRatio: 10, maxVideoBitrateMbps: 25, maxAudioSampleRateHz: 48_000, maxAudioChannels: 2, recommendedAspectRatio: '9:16', }, metadata: { maxTitleCharacters: 2200, maxHashtags: 30, syntheticDisclosureRequired: true, supportedVisibility: ['private', 'public'], captionsOptional: true, captionFormats: ['srt', 'vtt'], thumbnailOptional: true, thumbnailFormats: ['jpg', 'jpeg'], }, }, ]; export function listPublishProfiles(): PublishPlatformProfile[] { return PROFILES.map((profile) => structuredClone(profile)); } export function getPublishProfile(platform: PublishPlatformId): PublishPlatformProfile { const profile = PROFILES.find((candidate) => candidate.platform === platform); if (!profile) { throw new Error(`Unknown publish platform: ${platform}`); } return structuredClone(profile); } export function isPublishPlatformId(value: string): value is PublishPlatformId { return PROFILES.some((profile) => profile.platform === value); }