feat: hooked scripts into the blogmark pipeline

This commit is contained in:
2026-02-23 20:10:46 +01:00
parent 77ddacd52a
commit cd394bcacb
13 changed files with 1029 additions and 10 deletions

View File

@@ -0,0 +1,168 @@
import type { PanelOutputEntry, PostData } from '../store';
export interface BlogmarkTransformDebugError {
scriptId: string;
scriptSlug: string;
message: string;
}
export interface BlogmarkTransformDebugInfo {
appliedScriptIds: string[];
errors: BlogmarkTransformDebugError[];
toasts: string[];
}
export interface BlogmarkTransformToastNotification {
kind: 'success' | 'error';
message: string;
}
export interface BlogmarkCreatedEventPayload {
post: PostData;
transform?: BlogmarkTransformDebugInfo;
}
function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function parseTransformDebugInfo(value: unknown): BlogmarkTransformDebugInfo | undefined {
if (!isRecord(value)) {
return undefined;
}
const appliedScriptIds = Array.isArray(value.appliedScriptIds)
? value.appliedScriptIds.filter((item): item is string => typeof item === 'string')
: [];
const errors = Array.isArray(value.errors)
? value.errors
.map((entry) => {
if (!isRecord(entry)) {
return null;
}
const scriptId = typeof entry.scriptId === 'string' ? entry.scriptId : '';
const scriptSlug = typeof entry.scriptSlug === 'string' ? entry.scriptSlug : '';
const message = typeof entry.message === 'string' ? entry.message : '';
if (!scriptId || !scriptSlug || !message) {
return null;
}
return {
scriptId,
scriptSlug,
message,
};
})
.filter((item): item is BlogmarkTransformDebugError => item !== null)
: [];
const toasts = Array.isArray(value.toasts)
? value.toasts
.map((entry) => (typeof entry === 'string' ? entry.trim() : ''))
.filter((entry) => entry.length > 0)
: [];
if (appliedScriptIds.length === 0 && errors.length === 0 && toasts.length === 0) {
return undefined;
}
return {
appliedScriptIds,
errors,
toasts,
};
}
export function parseBlogmarkCreatedEventPayload(payload: unknown): BlogmarkCreatedEventPayload | null {
if (!isRecord(payload)) {
return null;
}
if (isRecord(payload.post)) {
return {
post: payload.post as PostData,
transform: parseTransformDebugInfo(payload.transform),
};
}
return {
post: payload as PostData,
transform: undefined,
};
}
export function buildBlogmarkTransformOutputEntries(
transform: BlogmarkTransformDebugInfo | undefined,
t: (key: string, values?: Record<string, string | number>) => string,
): Array<Omit<PanelOutputEntry, 'id' | 'createdAt'>> {
if (!transform) {
return [];
}
const entries: Array<Omit<PanelOutputEntry, 'id' | 'createdAt'>> = [];
entries.push({
kind: 'result',
message: t('app.blogmark.transforms.summary', {
applied: transform.appliedScriptIds.length,
failed: transform.errors.length,
}),
});
if (transform.appliedScriptIds.length > 0) {
entries.push({
kind: 'result',
message: t('app.blogmark.transforms.appliedList', {
scripts: transform.appliedScriptIds.join(', '),
}),
});
}
for (const toastMessage of transform.toasts) {
entries.push({
kind: 'result',
message: t('app.blogmark.transforms.toast', {
message: toastMessage,
}),
});
}
for (const error of transform.errors) {
entries.push({
kind: 'error',
message: t('app.blogmark.transforms.failed', {
script: error.scriptSlug,
message: error.message,
}),
});
}
return entries;
}
export function buildBlogmarkTransformToastNotifications(
transform: BlogmarkTransformDebugInfo | undefined,
t: (key: string, values?: Record<string, string | number>) => string,
): BlogmarkTransformToastNotification[] {
if (!transform) {
return [];
}
const notifications: BlogmarkTransformToastNotification[] = transform.toasts.map((message) => ({
kind: 'success',
message,
}));
if (transform.errors.length > 0) {
notifications.push({
kind: 'error',
message: t('app.blogmark.transforms.errorToast', {
count: transform.errors.length,
}),
});
}
return notifications;
}