From fcbdd2d770377862b5405ae41eb2bac3f014e4c8 Mon Sep 17 00:00:00 2001 From: Chris Arter Date: Fri, 8 May 2026 11:44:17 -0400 Subject: [PATCH] feat(import): tag collection + upsert helper --- scripts/import/tags.ts | 32 +++++++++++++++++++++++++++++++ tests/int/import-tags.int.spec.ts | 16 ++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 scripts/import/tags.ts create mode 100644 tests/int/import-tags.int.spec.ts diff --git a/scripts/import/tags.ts b/scripts/import/tags.ts new file mode 100644 index 0000000..5c0d607 --- /dev/null +++ b/scripts/import/tags.ts @@ -0,0 +1,32 @@ +import type { Payload } from 'payload' +import { slugify } from '@/lib/slugify' + +export function collectUniqueTags(posts: { tags: string[] }[]) { + const map = new Map() + for (const p of posts) { + for (const name of p.tags ?? []) { + const slug = slugify(name) + if (!slug) continue + if (!map.has(slug)) map.set(slug, { name, slug }) + } + } + return [...map.values()] +} + +export async function upsertTags(payload: Payload, tags: { name: string; slug: string }[]) { + const idBySlug = new Map() + for (const tag of tags) { + const existing = await payload.find({ + collection: 'tags', + where: { slug: { equals: tag.slug } }, + limit: 1, + }) + if (existing.docs[0]) { + idBySlug.set(tag.slug, existing.docs[0].id) + continue + } + const created = await payload.create({ collection: 'tags', data: tag }) + idBySlug.set(tag.slug, created.id) + } + return idBySlug +} diff --git a/tests/int/import-tags.int.spec.ts b/tests/int/import-tags.int.spec.ts new file mode 100644 index 0000000..94c4a8a --- /dev/null +++ b/tests/int/import-tags.int.spec.ts @@ -0,0 +1,16 @@ +import { describe, expect, it } from 'vitest' +import { collectUniqueTags } from '../../scripts/import/tags' + +describe('collectUniqueTags', () => { + it('flattens and dedupes by slug', () => { + const r = collectUniqueTags([ + { tags: ['Laravel', 'PHP'] }, + { tags: ['laravel', 'Docker'] }, + ]) + expect(r.map((t) => t.slug).sort()).toEqual(['docker', 'laravel', 'php']) + }) + it('preserves first-seen display name', () => { + const r = collectUniqueTags([{ tags: ['Laravel'] }, { tags: ['laravel'] }]) + expect(r[0].name).toBe('Laravel') + }) +}) -- 2.51.2