Something went wrong. Try again.
Schedule posts and reposts to Bluesky (and other PDSes) with Cloudflare workers. skyscheduler.work
scheduling social-media cloudflare bsky service cloudflare-workers bsky-tool bluesky
Something went wrong. Try again.
2.8 kB · 77 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677import isEmpty from "just-is-empty";import * as z from "zod/v4";import { EmbedDataType } from "../enums";import { BSKY_VIDEO_LENGTH_LIMIT, MAX_ASSOCIATEDREFS_PER_LINK } from "../limits";import { FileContentSchema } from "./mediaSchema";import { StrongRecordSchema } from "./recordSchema";import { atpRecordURI, domainRegexCheck, httpProtoRecord } from "./regexCases";import { AltTextSchema } from "./sharedSchemas";
export const ImageEmbedSchema = z.object({ ...FileContentSchema.shape, type: z.literal(EmbedDataType.Image), ...AltTextSchema.shape,});
export const VideoEmbedSchema = z.object({ ...FileContentSchema.shape, ...AltTextSchema.shape, type: z.literal(EmbedDataType.Video), width: z.int("media width is not a number") .min(1, "media width value is below 1") .nonoptional("media width is required"), height: z.int("media height is not a number") .min(1, "media height value is below 1") .nonoptional("media height is required"), duration: z.number("media duration is invalid") .min(0, "media must be over 0 seconds long") .max(BSKY_VIDEO_LENGTH_LIMIT, `media must be less than ${BSKY_VIDEO_LENGTH_LIMIT} seconds long`) .nonoptional("media duration is required")});
export const LinkEmbedSchema = z.object({ /* content is the thumbnail */ content: z.string().trim().prefault("").refine((value) => { if (isEmpty(value)) return true; // So the idea here is to try to encode the string into an URL object, and if that fails // then you just fail out the string. try { const urlWrap = new URL(value); return (urlWrap.protocol === "https:" || urlWrap.protocol === "http:"); } catch (_err) { return false; } }, { message: "the link to embed failed to parse, is it accessible?", path: ["content"] }), type: z.literal(EmbedDataType.WebLink), title: z.string().trim().default(""), /* NOTE: uri is the link to the website here, content is used as the thumbnail */ uri: z.url({ normalize: true, protocol: httpProtoRecord, hostname: domainRegexCheck, error: "provided link is not an URL, please check the value and try again" }).trim() .nonoptional("link embeds require a url"), description: z.string().trim().default(""), associatedRefs: z.array(StrongRecordSchema) .max(MAX_ASSOCIATEDREFS_PER_LINK, `too many ref records attached, max of ${MAX_ASSOCIATEDREFS_PER_LINK}`) .optional()});
export const PostRecordSchema = z.object({ content: z.url({ normalize: true, protocol: httpProtoRecord, hostname: domainRegexCheck, error: "post/feed/list record url is invalid" }).trim() .toLowerCase() .regex(atpRecordURI, "url is not a post/feed/list record") .nonoptional("post/feed/list records require a url"), type: z.literal(EmbedDataType.Record),});