Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 9 additions & 15 deletions apps/web/scripts/sync-standard-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import { basename } from 'node:path';
import { pathToFileURL } from 'node:url';
import * as z from 'zod';

import {
serializeStandardSiteManifest,
standardSitePublicationUri,
} from '../src/lib/standard-site.ts';

type PublishedPost = {
portableContent: string;
publishedAt: string;
Expand All @@ -22,7 +27,7 @@ type DocumentRecord = {
description: string;
path: `/posts/${string}`;
publishedAt: string;
site: typeof PUBLICATION_URI;
site: typeof standardSitePublicationUri;
textContent: string;
title: string;
};
Expand Down Expand Up @@ -70,8 +75,6 @@ const POSTS_DIR = new URL('content/posts/', APP_DIR);
const GENERATED_DIR = new URL('src/generated/', APP_DIR);
const MANIFEST_URL = new URL('src/generated/standard-site.json', APP_DIR);
const COLLECTION = 'site.standard.document';
const PUBLICATION_URI =
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.publication/3mnqwgvxn372f';
const DEFAULT_IDENTIFIER = 'lukebennett.dev';

export function extractPortableContent(
Expand Down Expand Up @@ -184,7 +187,7 @@ export function planReconciliation({
for (const record of existingRecords) {
const value = record.value ?? {};
if (
value.site !== PUBLICATION_URI ||
value.site !== standardSitePublicationUri ||
typeof value.path !== 'string' ||
!value.path.startsWith('/posts/')
) {
Expand Down Expand Up @@ -253,7 +256,7 @@ export function buildDocumentRecord(post: PublishedPost): DocumentRecord {
description: truncateDescription(textContent),
path: `/posts/${post.slug}`,
publishedAt: new Date(`${post.publishedAt}T00:00:00.000Z`).toISOString(),
site: PUBLICATION_URI,
site: standardSitePublicationUri,
textContent,
title: post.title,
};
Expand All @@ -269,16 +272,7 @@ async function writeManifest(
await mkdir(GENERATED_DIR, { recursive: true });
await writeFile(
MANIFEST_URL,
`${JSON.stringify(
{
documentsBySlug: Object.fromEntries(
[...documentsBySlug.entries()].sort(([a], [b]) => a.localeCompare(b)),
),
publicationUri: PUBLICATION_URI,
},
null,
2,
)}\n`,
serializeStandardSiteManifest(documentsBySlug),
'utf8',
);
}
Expand Down
55 changes: 55 additions & 0 deletions apps/web/src/lib/standard-site.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import test from 'node:test';
import {
getStandardSiteDocumentUri,
loadStandardSiteManifest,
serializeStandardSiteManifest,
standardSitePublicationUri,
} from './standard-site.ts';

Expand Down Expand Up @@ -92,3 +93,57 @@ test('reads document URIs from valid manifest', async () => {
await rm(dir, { force: true, recursive: true });
}
});

test('serializeStandardSiteManifest round-trips through loadStandardSiteManifest', async () => {
const dir = await mkdtemp(join(tmpdir(), 'standard-site-'));
const manifestPath = join(dir, 'standard-site.json');
const documentsBySlug = new Map([
[
'hello-world',
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.document/hello-world',
],
[
'another-post',
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.document/another-post',
],
]);

try {
await writeFile(
manifestPath,
serializeStandardSiteManifest(documentsBySlug),
'utf8',
);

const manifest = loadStandardSiteManifest({
manifestPath,
requireManifest: false,
});

assert.deepEqual(
manifest.documentsBySlug,
Object.fromEntries(documentsBySlug),
);
assert.equal(manifest.publicationUri, standardSitePublicationUri);
} finally {
await rm(dir, { force: true, recursive: true });
}
});

test('serializeStandardSiteManifest sorts slugs and ends with a trailing newline', () => {
const serialized = serializeStandardSiteManifest(
new Map([
[
'zebra',
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.document/zebra',
],
[
'apple',
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.document/apple',
],
]),
);

assert.ok(serialized.endsWith('\n'));
assert.ok(serialized.indexOf('"apple"') < serialized.indexOf('"zebra"'));
});
16 changes: 14 additions & 2 deletions apps/web/src/lib/standard-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,26 @@ import * as z from 'zod';
export const standardSitePublicationUri =
'at://did:plc:3z5ja7l2rhnmtr2bni5dyfe7/site.standard.publication/3mnqwgvxn372f';

const StandardSiteManifestSchema = z
export const StandardSiteManifestSchema = z
.object({
documentsBySlug: z.record(z.string(), z.string().startsWith('at://')),
publicationUri: z.literal(standardSitePublicationUri),
})
.readonly();

type StandardSiteManifest = z.infer<typeof StandardSiteManifestSchema>;
export type StandardSiteManifest = z.infer<typeof StandardSiteManifestSchema>;

export function serializeStandardSiteManifest(
documentsBySlug: Map<string, string>,
): string {
const manifest = StandardSiteManifestSchema.parse({
documentsBySlug: Object.fromEntries(
[...documentsBySlug.entries()].sort(([a], [b]) => a.localeCompare(b)),
),
publicationUri: standardSitePublicationUri,
});
return `${JSON.stringify(manifest, null, 2)}\n`;
}

type ManifestOptions = {
manifestPath?: string;
Expand Down