atproto blogging
1{
2 "lexicon": 1,
3 "id": "sh.weaver.notebook.defs",
4 "defs": {
5 "notebookView": {
6 "type": "object",
7 "required": ["uri", "cid", "authors", "record", "indexedAt"],
8
9 "properties": {
10 "title": { "type": "ref", "ref": "#title" },
11 "path": { "type": "ref", "ref": "#path" },
12 "tags": { "type": "ref", "ref": "#tags" },
13 "uri": { "type": "string", "format": "at-uri" },
14 "cid": { "type": "string", "format": "cid" },
15 "authors": {
16 "type": "array",
17 "items": { "type": "ref", "ref": "#authorListView" }
18 },
19 "permissions": {
20 "type": "ref",
21 "ref": "#permissionsState"
22 },
23 "record": { "type": "unknown" },
24 "indexedAt": { "type": "string", "format": "datetime" },
25 "likeCount": { "type": "integer" },
26 "bookmarkCount": { "type": "integer" },
27 "subscriberCount": { "type": "integer" },
28 "entryCount": { "type": "integer" },
29 "viewerLike": { "type": "string", "format": "at-uri" },
30 "viewerBookmark": { "type": "string", "format": "at-uri" },
31 "viewerSubscription": { "type": "string", "format": "at-uri" },
32 "viewerReadingProgress": { "type": "ref", "ref": "#readingProgress" }
33 }
34 },
35 "entryView": {
36 "type": "object",
37 "required": ["uri", "cid", "authors", "record", "indexedAt"],
38
39 "properties": {
40 "title": { "type": "ref", "ref": "#title" },
41 "path": { "type": "ref", "ref": "#path" },
42 "tags": { "type": "ref", "ref": "#tags" },
43 "uri": { "type": "string", "format": "at-uri" },
44 "cid": { "type": "string", "format": "cid" },
45 "authors": {
46 "type": "array",
47 "items": { "type": "ref", "ref": "#authorListView" }
48 },
49 "permissions": {
50 "type": "ref",
51 "ref": "#permissionsState"
52 },
53 "record": { "type": "unknown" },
54 "renderedView": {
55 "type": "ref",
56 "ref": "#renderedView"
57 },
58 "indexedAt": { "type": "string", "format": "datetime" },
59 "likeCount": { "type": "integer" },
60 "bookmarkCount": { "type": "integer" },
61 "viewerLike": { "type": "string", "format": "at-uri" },
62 "viewerBookmark": { "type": "string", "format": "at-uri" },
63 "viewerReadingProgress": { "type": "ref", "ref": "#readingProgress" }
64 }
65 },
66
67 "renderedView": {
68 "type": "object",
69 "required": ["html"],
70 "properties": {
71 "html": {
72 "type": "blob",
73 "accept": ["text/html"],
74 "maxSize": 1000000
75 },
76 "css": {
77 "type": "blob",
78 "accept": ["text/css"],
79 "maxSize": 1000000
80 }
81 },
82 "description": "View of a rendered and cached notebook entry"
83 },
84 "authorListView": {
85 "type": "object",
86 "required": ["record", "index"],
87 "properties": {
88 "uri": { "type": "string", "format": "at-uri" },
89 "record": {
90 "type": "ref",
91 "ref": "sh.weaver.actor.defs#profileDataView"
92 },
93 "index": { "type": "integer" }
94 }
95 },
96
97 "bookEntryView": {
98 "type": "object",
99 "description": "An ordered entry in a Weaver notebook.",
100 "required": ["entry", "index"],
101 "properties": {
102 "entry": {
103 "type": "ref",
104 "ref": "#entryView"
105 },
106 "index": { "type": "integer" },
107 "next": {
108 "type": "ref",
109 "ref": "#bookEntryRef"
110 },
111 "prev": {
112 "type": "ref",
113 "ref": "#bookEntryRef"
114 }
115 }
116 },
117
118 "bookEntryRef": {
119 "type": "object",
120 "required": ["entry"],
121 "properties": {
122 "entry": {
123 "type": "ref",
124 "ref": "#entryView"
125 }
126 }
127 },
128 "title": {
129 "type": "string",
130 "maxLength": 300,
131 "description": "The title of the notebook entry."
132 },
133 "path": {
134 "type": "string",
135 "maxLength": 100,
136 "description": "The path of the notebook."
137 },
138 "tags": {
139 "type": "array",
140 "items": {
141 "type": "string",
142 "maxLength": 64
143 },
144 "maxLength": 10,
145 "description": "An array of tags associated with the notebook entry. Tags can help categorize and organize entries."
146 },
147 "contentFormat": {
148 "type": "object",
149 "description": "The format of the content. This is used to determine how to render the content.",
150 "properties": {
151 "markdown": {
152 "type": "string",
153 "description": "The format of the content. This is used to determine how to render the content.",
154 "enum": ["commonmark", "gfm", "obsidian", "weaver"],
155 "default": "weaver"
156 }
157 }
158 },
159 "permissionsState": {
160 "type": "object",
161 "description": "ACL-style permissions for a resource. Separate from authors (who contributed).",
162 "required": ["editors"],
163 "properties": {
164 "editors": {
165 "type": "array",
166 "description": "DIDs that can edit this resource",
167 "items": { "type": "ref", "ref": "#permissionGrant" }
168 },
169 "viewers": {
170 "type": "array",
171 "description": "DIDs that can view (future use)",
172 "items": { "type": "ref", "ref": "#permissionGrant" }
173 }
174 }
175 },
176 "permissionGrant": {
177 "type": "object",
178 "description": "A single permission grant. For resource authority: source=resource URI, grantedAt=createdAt. For invitees: source=invite URI, grantedAt=accept createdAt.",
179 "required": ["did", "scope", "source", "grantedAt"],
180 "properties": {
181 "did": { "type": "string", "format": "did" },
182 "scope": {
183 "type": "string",
184 "knownValues": ["direct", "inherited"],
185 "description": "direct = this resource (includes authority), inherited = via notebook invite"
186 },
187 "source": {
188 "type": "string",
189 "format": "at-uri",
190 "description": "For authority: resource URI. For invitees: invite URI"
191 },
192 "grantedAt": {
193 "type": "string",
194 "format": "datetime",
195 "description": "For authority: record createdAt. For invitees: accept createdAt"
196 }
197 }
198 },
199 "feedEntryView": {
200 "type": "object",
201 "description": "Entry with feed-specific context (discovery reason, notebook context).",
202 "required": ["entry"],
203 "properties": {
204 "entry": { "type": "ref", "ref": "#entryView" },
205 "reason": { "type": "ref", "ref": "#feedReason" },
206 "notebookContext": { "type": "ref", "ref": "#feedNotebookContext" }
207 }
208 },
209 "feedNotebookContext": {
210 "type": "object",
211 "description": "Minimal notebook context for feed display.",
212 "required": ["uri", "title"],
213 "properties": {
214 "uri": { "type": "string", "format": "at-uri" },
215 "title": { "type": "string" },
216 "path": { "type": "string" }
217 }
218 },
219 "feedReason": {
220 "type": "union",
221 "description": "Why this entry appeared in the feed.",
222 "refs": ["#reasonLike", "#reasonBookmark", "#reasonSubscription"]
223 },
224 "reasonLike": {
225 "type": "object",
226 "required": ["by", "indexedAt"],
227 "properties": {
228 "by": { "type": "ref", "ref": "sh.weaver.actor.defs#profileViewBasic" },
229 "indexedAt": { "type": "string", "format": "datetime" }
230 }
231 },
232 "reasonBookmark": {
233 "type": "object",
234 "required": ["by", "indexedAt"],
235 "properties": {
236 "by": { "type": "ref", "ref": "sh.weaver.actor.defs#profileViewBasic" },
237 "indexedAt": { "type": "string", "format": "datetime" }
238 }
239 },
240 "reasonSubscription": {
241 "type": "object",
242 "required": ["indexedAt"],
243 "properties": {
244 "indexedAt": { "type": "string", "format": "datetime" }
245 }
246 },
247 "publishedVersionView": {
248 "type": "object",
249 "description": "A published version of an entry in a collaborator's repo.",
250 "required": ["uri", "cid", "publisher", "publishedAt"],
251 "properties": {
252 "uri": { "type": "string", "format": "at-uri" },
253 "cid": { "type": "string", "format": "cid" },
254 "publisher": { "type": "ref", "ref": "sh.weaver.actor.defs#profileViewBasic" },
255 "publishedAt": { "type": "string", "format": "datetime" },
256 "updatedAt": { "type": "string", "format": "datetime" },
257 "isCanonical": {
258 "type": "boolean",
259 "description": "True if this is the 'primary' version (owner's repo)"
260 },
261 "divergedFrom": {
262 "type": "ref",
263 "ref": "com.atproto.repo.strongRef",
264 "description": "If content differs, the version it diverged from"
265 }
266 }
267 },
268 "contentWarning": {
269 "type": "string",
270 "description": "Author-applied content warning.",
271 "knownValues": [
272 "violence",
273 "graphic-violence",
274 "death",
275 "major-character-death",
276 "sexual-content",
277 "explicit-sexual-content",
278 "language",
279 "substance-use",
280 "self-harm",
281 "abuse",
282 "disturbing-imagery"
283 ]
284 },
285 "contentWarnings": {
286 "type": "array",
287 "description": "Author-applied content warnings.",
288 "maxLength": 10,
289 "items": { "type": "ref", "ref": "#contentWarning" }
290 },
291 "contentRating": {
292 "type": "string",
293 "description": "Author-applied content rating.",
294 "knownValues": ["general", "teen", "mature", "explicit"]
295 },
296 "chapterView": {
297 "type": "object",
298 "description": "Hydrated view of a chapter.",
299 "required": ["uri", "cid", "notebook", "authors", "record", "indexedAt"],
300 "properties": {
301 "uri": { "type": "string", "format": "at-uri" },
302 "cid": { "type": "string", "format": "cid" },
303 "title": { "type": "ref", "ref": "#title" },
304 "tags": { "type": "ref", "ref": "#tags" },
305 "notebook": { "type": "ref", "ref": "#notebookView" },
306 "authors": {
307 "type": "array",
308 "items": { "type": "ref", "ref": "#authorListView" }
309 },
310 "record": { "type": "unknown" },
311 "entryCount": { "type": "integer" },
312 "indexedAt": { "type": "string", "format": "datetime" }
313 }
314 },
315 "chapterEntryView": {
316 "type": "object",
317 "description": "An entry within a chapter context.",
318 "required": ["entry", "index"],
319 "properties": {
320 "entry": { "type": "ref", "ref": "#entryView" },
321 "index": { "type": "integer" },
322 "next": { "type": "ref", "ref": "#bookEntryRef" },
323 "prev": { "type": "ref", "ref": "#bookEntryRef" }
324 }
325 },
326 "pageView": {
327 "type": "object",
328 "description": "Hydrated view of a page (entries displayed together).",
329 "required": ["uri", "cid", "notebook", "record", "indexedAt"],
330 "properties": {
331 "uri": { "type": "string", "format": "at-uri" },
332 "cid": { "type": "string", "format": "cid" },
333 "title": { "type": "ref", "ref": "#title" },
334 "tags": { "type": "ref", "ref": "#tags" },
335 "notebook": { "type": "ref", "ref": "#notebookView" },
336 "record": { "type": "unknown" },
337 "entryCount": { "type": "integer" },
338 "indexedAt": { "type": "string", "format": "datetime" }
339 }
340 },
341 "readingProgress": {
342 "type": "object",
343 "description": "Viewer's reading progress (appview-side state, not a record).",
344 "properties": {
345 "status": {
346 "type": "string",
347 "knownValues": ["reading", "finished", "abandoned", "want-to-read"]
348 },
349 "currentEntry": {
350 "type": "string",
351 "format": "at-uri",
352 "description": "Last entry the viewer was reading."
353 },
354 "percentComplete": {
355 "type": "integer",
356 "minimum": 0,
357 "maximum": 100
358 },
359 "lastReadAt": { "type": "string", "format": "datetime" },
360 "startedAt": { "type": "string", "format": "datetime" },
361 "finishedAt": { "type": "string", "format": "datetime" }
362 }
363 }
364 }
365}