Skip to content

Commit 32e5bff

Browse files
committed
feat: generate lexicons on postinstall & log out marshalling to standard site
1 parent 398ad36 commit 32e5bff

6 files changed

Lines changed: 152 additions & 1 deletion

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,6 @@ test-results/
3636

3737
# Lighthouse
3838
.lighthouseci
39+
40+
# Generated lexicon types
41+
shared/types/lexicons/

lexicons.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": 1,
3+
"lexicons": ["site.standard.document"],
4+
"resolutions": {
5+
"com.atproto.repo.strongRef": {
6+
"uri": "at://did:plc:6msi3pj7krzih5qxqtryxlzw/com.atproto.lexicon.schema/com.atproto.repo.strongRef",
7+
"cid": "bafyreifrkdbnkvfjujntdaeigolnrjj3srrs53tfixjhmacclps72qlov4"
8+
},
9+
"site.standard.document": {
10+
"uri": "at://did:plc:re3ebnp5v7ffagz6rb6xfei4/com.atproto.lexicon.schema/site.standard.document",
11+
"cid": "bafyreigdukg62hmel4jbdvghdsoaphslhrdktmahzdyokomuka6yejetwa"
12+
}
13+
}
14+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"id": "com.atproto.repo.strongRef",
3+
"defs": {
4+
"main": {
5+
"type": "object",
6+
"required": ["uri", "cid"],
7+
"properties": {
8+
"cid": {
9+
"type": "string",
10+
"format": "cid"
11+
},
12+
"uri": {
13+
"type": "string",
14+
"format": "at-uri"
15+
}
16+
}
17+
}
18+
},
19+
"$type": "com.atproto.lexicon.schema",
20+
"lexicon": 1,
21+
"description": "A URI with a content-hash fingerprint."
22+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"id": "site.standard.document",
3+
"defs": {
4+
"main": {
5+
"key": "tid",
6+
"type": "record",
7+
"record": {
8+
"type": "object",
9+
"required": ["site", "title", "publishedAt"],
10+
"properties": {
11+
"path": {
12+
"type": "string",
13+
"description": "Combine with site or publication url to construct a canonical URL to the document. Prepend with a leading slash."
14+
},
15+
"site": {
16+
"type": "string",
17+
"format": "uri",
18+
"description": "Points to a publication record (at://) or a publication url (https://) for loose documents. Avoid trailing slashes."
19+
},
20+
"tags": {
21+
"type": "array",
22+
"items": {
23+
"type": "string"
24+
},
25+
"maxLength": 1280,
26+
"description": "Array of strings used to tag or categorize the document. Avoid prepending tags with hashtags.",
27+
"maxGraphemes": 128
28+
},
29+
"title": {
30+
"type": "string",
31+
"maxLength": 5000,
32+
"description": "Title of the document.",
33+
"maxGraphemes": 500
34+
},
35+
"content": {
36+
"refs": [],
37+
"type": "union",
38+
"closed": false,
39+
"description": "Open union used to define the record's content. Each entry must specify a $type and may be extended with other lexicons to support additional content formats."
40+
},
41+
"updatedAt": {
42+
"type": "string",
43+
"format": "datetime",
44+
"description": "Timestamp of the documents last edit."
45+
},
46+
"coverImage": {
47+
"type": "blob",
48+
"accept": ["image/*"],
49+
"maxSize": 1000000,
50+
"description": "Image to used for thumbnail or cover image. Less than 1MB is size."
51+
},
52+
"bskyPostRef": {
53+
"ref": "com.atproto.repo.strongRef",
54+
"type": "ref",
55+
"description": "Strong reference to a Bluesky post. Useful to keep track of comments off-platform."
56+
},
57+
"description": {
58+
"type": "string",
59+
"maxLength": 30000,
60+
"description": "A brief description or excerpt from the document.",
61+
"maxGraphemes": 3000
62+
},
63+
"publishedAt": {
64+
"type": "string",
65+
"format": "datetime",
66+
"description": "Timestamp of the documents publish time."
67+
},
68+
"textContent": {
69+
"type": "string",
70+
"description": "Plaintext representation of the documents contents. Should not contain markdown or other formatting."
71+
}
72+
}
73+
},
74+
"description": "A document record representing a published article, blog post, or other content. Documents can belong to a publication or exist independently."
75+
}
76+
},
77+
"$type": "com.atproto.lexicon.schema",
78+
"lexicon": 1
79+
}

modules/standard-site-sync.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { defineNuxtModule, useNuxt } from 'nuxt/kit'
2+
import * as site from '../shared/types/lexicons/site'
3+
4+
const PUBLICATION_SITE = 'https://npmx.dev'
5+
6+
export default defineNuxtModule({
7+
meta: {
8+
name: 'standard-site-sync',
9+
},
10+
setup() {
11+
const nuxt = useNuxt()
12+
if (nuxt.options._prepare) {
13+
return
14+
}
15+
nuxt.hook('content:file:afterParse', ctx => {
16+
const { content } = ctx
17+
18+
// Marshal content into site.standard.document using generated $build
19+
const document = site.standard.document.$build({
20+
site: PUBLICATION_SITE,
21+
path: content.path as string,
22+
title: content.title as string,
23+
description: (content.excerpt || content.description) as string | undefined,
24+
tags: content.tags as string[] | undefined,
25+
publishedAt: new Date(content.date as string).toISOString(),
26+
})
27+
28+
// Mock PDS push
29+
console.log('[standard-site-sync] Would push:', JSON.stringify(document, null, 2))
30+
})
31+
},
32+
})

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
"generate": "nuxt generate",
2020
"npmx-connector": "pnpm --filter npmx-connector dev",
2121
"preview": "nuxt preview",
22-
"postinstall": "nuxt prepare && simple-git-hooks",
22+
"generate:lexicons": "lex build --lexicons lexicons --out shared/types/lexicons --clear",
23+
"postinstall": "pnpm generate:lexicons && nuxt prepare && simple-git-hooks",
2324
"test": "vite test",
2425
"test:browser": "playwright test",
2526
"test:browser:ui": "playwright test --ui",

0 commit comments

Comments
 (0)