You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

92 lines
2.6 KiB

import {
applyImwaldAttributionTags,
collectUploadImetaTagsForContentUrls,
mergeUploadImetaTagsInto
} from '@/lib/draft-event'
import type { TDraftEvent } from '@/types'
export type AdvancedEventLabSlice = {
kind: number
content: string
tags: string[][]
}
/**
* JSON shaped like the draft passed to publish: merges `imeta` from content URLs,
* then applies Imwald `client` (and strips duplicate client/attribution tags) like {@link applyImwaldAttributionTags}.
*/
export function serializePublishPreviewLabJson(
slice: AdvancedEventLabSlice,
options?: { addClientTag?: boolean }
): string {
const tags = slice.tags.map((row) => [...row])
mergeUploadImetaTagsInto(tags, collectUploadImetaTagsForContentUrls(slice.content))
const draft: TDraftEvent = {
kind: slice.kind,
content: slice.content,
created_at: Math.floor(Date.now() / 1000),
tags
}
const withAttribution = applyImwaldAttributionTags(draft, {
addClientTag: options?.addClientTag
})
return JSON.stringify(
{
kind: withAttribution.kind,
content: withAttribution.content,
created_at: withAttribution.created_at,
tags: withAttribution.tags
},
null,
2
)
}
export function serializeLabSlice(slice: AdvancedEventLabSlice): string {
return JSON.stringify(
{
kind: slice.kind,
content: slice.content,
tags: slice.tags
},
null,
2
)
}
/**
* Accepts lab slice JSON or a fuller draft/event object; ignores unknown top-level fields
* (`created_at`, `pubkey`, `id`, etc.).
*/
export function parseLabSlice(
raw: string
): { ok: true; value: AdvancedEventLabSlice } | { ok: false; error: string } {
let o: unknown
try {
o = JSON.parse(raw)
} catch {
return { ok: false, error: 'Invalid JSON' }
}
if (!o || typeof o !== 'object' || Array.isArray(o)) {
return { ok: false, error: 'Root must be an object' }
}
const rec = o as Record<string, unknown>
if (typeof rec.kind !== 'number' || !Number.isFinite(rec.kind) || !Number.isInteger(rec.kind)) {
return { ok: false, error: '`kind` must be an integer' }
}
if (typeof rec.content !== 'string') {
return { ok: false, error: '`content` must be a string' }
}
if (!Array.isArray(rec.tags)) {
return { ok: false, error: '`tags` must be an array' }
}
const tags: string[][] = []
for (let i = 0; i < rec.tags.length; i++) {
const row = rec.tags[i]
if (!Array.isArray(row) || !row.every((c) => typeof c === 'string')) {
return { ok: false, error: `tags[${i}] must be an array of strings` }
}
tags.push([...row])
}
return { ok: true, value: { kind: rec.kind, content: rec.content, tags } }
}