Skip to content
← Public packages

@kentcdodds/linkedin

Headless helpers for LinkedIn identity, requests, and guarded posting using the saved linkedin OAuth integration.

src/create-text-post-input.ts

73 lines · 1.7 KB · TypeScript
import {
	ValidationError,
	boolean,
	object,
	optional,
	parse,
	string,
} from 'remix/data-schema'
import { formatSchemaValidationError } from './schema-input-errors.ts'
import type { CreateTextPostInput, LinkedInVisibility } from './types.ts'

const KNOWN_KEYS = [
	'text',
	'commentary',
	'message',
	'body',
	'author',
	'visibility',
	'isReshareDisabledByAuthor',
	'dryRun',
	'confirm',
] as const

const HINT =
	`Pass text (aliases: commentary, message, body) plus optional author/visibility. Unknown keys are rejected.`

const Schema = object(
	{
		text: optional(string()),
		commentary: optional(string()),
		message: optional(string()),
		body: optional(string()),
		author: optional(string()),
		visibility: optional(string()),
		isReshareDisabledByAuthor: optional(boolean()),
		dryRun: optional(boolean()),
		confirm: optional(boolean()),
	},
	{ unknownKeys: 'error' },
).transform((raw): CreateTextPostInput => {
	const text =
		[raw.text, raw.commentary, raw.message, raw.body]
			.find((v) => typeof v === 'string' && v.trim().length > 0)
			?.trim()
	return {
		text,
		author: raw.author,
		visibility: raw.visibility as LinkedInVisibility | undefined,
		isReshareDisabledByAuthor: raw.isReshareDisabledByAuthor,
		dryRun: raw.dryRun,
		confirm: raw.confirm,
	}
})

export function parseCreateTextPostInput(input: unknown): CreateTextPostInput {
	try {
		const normalized = parse(Schema, input ?? {})
		if (!normalized.text?.trim()) {
			throw new Error('create-text-post requires text (aliases: commentary, message, body).')
		}
		return normalized
	} catch (error) {
		if (error instanceof ValidationError) {
			throw formatSchemaValidationError(error, {
				surface: 'create-text-post',
				knownKeys: KNOWN_KEYS,
				hint: HINT,
				input,
			})
		}
		throw error
	}
}