a tool for shared writing and social publishing
1import type { AppBskyFeedGetPostThread } from "@atproto/api";
2import type { DeepAsReadonlyJSONValue } from "./utils";
3
4const RootAttributes = {
5 "root/page": {
6 type: "ordered-reference",
7 cardinality: "many",
8 },
9} as const;
10const PageAttributes = {
11 "card/block": {
12 type: "ordered-reference",
13 cardinality: "many",
14 },
15 "page/type": {
16 type: "page-type-union",
17 cardinality: "one",
18 },
19 "canvas/block": {
20 type: "spatial-reference",
21 cardinality: "many",
22 },
23 "canvas/block/width": {
24 type: "number",
25 cardinality: "one",
26 },
27 "canvas/block/rotation": {
28 type: "number",
29 cardinality: "one",
30 },
31 "canvas/narrow-width": {
32 type: "boolean",
33 cardinality: "one",
34 },
35 "canvas/background-pattern": {
36 type: "canvas-pattern-union",
37 cardinality: "one",
38 },
39} as const;
40
41const BlockAttributes = {
42 "block/type": {
43 type: "block-type-union",
44 cardinality: "one",
45 },
46 "block/is-list": {
47 type: "boolean",
48 cardinality: "one",
49 },
50 "block/is-locked": {
51 type: "boolean",
52 cardinality: "one",
53 },
54 "block/check-list": {
55 type: "boolean",
56 cardinality: "one",
57 },
58 "block/text-alignment": {
59 type: "text-alignment-type-union",
60 cardinality: "one",
61 },
62 "block/date-time": {
63 type: "date-time",
64 cardinality: "one",
65 },
66 "block/text": {
67 type: "text",
68 cardinality: "one",
69 },
70 "block/heading-level": {
71 type: "number",
72 cardinality: "one",
73 },
74 "block/text-size": {
75 type: "text-size-union",
76 cardinality: "one",
77 },
78 "block/image": {
79 type: "image",
80 cardinality: "one",
81 },
82 "block/card": {
83 type: "reference",
84 cardinality: "one",
85 },
86 "block/bluesky-post": {
87 type: "bluesky-post",
88 cardinality: "one",
89 },
90 "block/math": {
91 type: "string",
92 cardinality: "one",
93 },
94 "block/code": {
95 type: "string",
96 cardinality: "one",
97 },
98 "block/code-language": {
99 type: "string",
100 cardinality: "one",
101 },
102 "block/list-style": {
103 type: "list-style-union",
104 cardinality: "one",
105 },
106 "block/list-number": {
107 type: "number",
108 cardinality: "one",
109 },
110 "block/footnote": {
111 type: "ordered-reference",
112 cardinality: "many",
113 },
114} as const;
115
116const MailboxAttributes = {
117 "mailbox/draft": {
118 type: "reference",
119 cardinality: "one",
120 },
121 "mailbox/archive": {
122 type: "reference",
123 cardinality: "one",
124 },
125 "mailbox/subscriber-count": {
126 type: "number",
127 cardinality: "one",
128 },
129} as const;
130
131const LinkBlockAttributes = {
132 "link/preview": {
133 type: "image",
134 cardinality: "one",
135 },
136 "link/url": {
137 type: "string",
138 cardinality: "one",
139 },
140 "link/description": {
141 type: "string",
142 cardinality: "one",
143 },
144 "link/title": {
145 type: "string",
146 cardinality: "one",
147 },
148} as const;
149
150const EmbedBlockAttributes = {
151 "embed/url": {
152 type: "string",
153 cardinality: "one",
154 },
155 "embed/height": {
156 type: "number",
157 cardinality: "one",
158 },
159 "embed/aspect-ratio": {
160 type: "string",
161 cardinality: "one",
162 },
163} as const;
164
165const BlueskyPostBlockAttributes = {
166 "bluesky-post/url": {
167 type: "string",
168 cardinality: "one",
169 },
170 "bluesky-post/host": {
171 type: "string",
172 cardinality: "one",
173 },
174} as const;
175
176const ButtonBlockAttributes = {
177 "button/text": {
178 type: "string",
179 cardinality: "one",
180 },
181 "button/url": {
182 type: "string",
183 cardinality: "one",
184 },
185} as const;
186
187const ImageBlockAttributes = {
188 "image/full-bleed": {
189 type: "boolean",
190 cardinality: "one",
191 },
192 "image/alt": {
193 type: "string",
194 cardinality: "one",
195 },
196} as const;
197
198const PollBlockAttributes = {
199 "poll/options": {
200 type: "ordered-reference",
201 cardinality: "many",
202 },
203 "poll-option/name": {
204 type: "string",
205 cardinality: "one",
206 },
207} as const;
208
209export const ThemeAttributes = {
210 "theme/heading-font": {
211 type: "string",
212 cardinality: "one",
213 },
214 "theme/body-font": {
215 type: "string",
216 cardinality: "one",
217 },
218 "theme/page-leaflet-watermark": {
219 type: "boolean",
220 cardinality: "one",
221 },
222 "theme/page-width": {
223 type: "number",
224 cardinality: "one",
225 },
226 "theme/page-background": {
227 type: "color",
228 cardinality: "one",
229 },
230 "theme/background-image": {
231 type: "image",
232 cardinality: "one",
233 },
234 "theme/background-image-repeat": {
235 type: "number",
236 cardinality: "one",
237 },
238 "theme/card-background": {
239 type: "color",
240 cardinality: "one",
241 },
242 "theme/card-background-image": {
243 type: "image",
244 cardinality: "one",
245 },
246 "theme/card-background-image-repeat": {
247 type: "number",
248 cardinality: "one",
249 },
250 "theme/card-background-image-opacity": {
251 type: "number",
252 cardinality: "one",
253 },
254 "theme/card-border-hidden": {
255 type: "boolean",
256 cardinality: "one",
257 },
258 "theme/primary": {
259 type: "color",
260 cardinality: "one",
261 },
262 "theme/accent-background": {
263 type: "color",
264 cardinality: "one",
265 },
266 "theme/accent-text": {
267 type: "color",
268 cardinality: "one",
269 },
270 "theme/highlight-1": {
271 type: "color",
272 cardinality: "one",
273 },
274 "theme/highlight-2": {
275 type: "color",
276 cardinality: "one",
277 },
278 "theme/highlight-3": {
279 type: "color",
280 cardinality: "one",
281 },
282 "theme/code-theme": {
283 type: "string",
284 cardinality: "one",
285 },
286} as const;
287
288export const Attributes = {
289 ...RootAttributes,
290 ...PageAttributes,
291 ...BlockAttributes,
292 ...LinkBlockAttributes,
293 ...ThemeAttributes,
294 ...MailboxAttributes,
295 ...EmbedBlockAttributes,
296 ...BlueskyPostBlockAttributes,
297 ...ButtonBlockAttributes,
298 ...ImageBlockAttributes,
299 ...PollBlockAttributes,
300};
301export type Attributes = typeof Attributes;
302export type Attribute = keyof Attributes;
303export type Data<A extends keyof typeof Attributes> = {
304 text: { type: "text"; value: string };
305 string: { type: "string"; value: string };
306 "spatial-reference": {
307 type: "spatial-reference";
308 position: { x: number; y: number };
309 value: string;
310 };
311 "date-time": {
312 type: "date-time";
313 value: string;
314 originalTimezone: string;
315 dateOnly?: boolean;
316 };
317 "ordered-reference": {
318 type: "ordered-reference";
319 position: string;
320 value: string;
321 };
322 "bluesky-post": {
323 type: "bluesky-post";
324 value: DeepAsReadonlyJSONValue<
325 AppBskyFeedGetPostThread.OutputSchema["thread"]
326 >;
327 };
328 image: {
329 type: "image";
330 fallback: string;
331 src: string;
332 height: number;
333 width: number;
334 local?: string;
335 };
336 boolean: {
337 type: "boolean";
338 value: boolean;
339 };
340 number: {
341 type: "number";
342 value: number;
343 };
344 awareness: {
345 type: "awareness";
346 value: string;
347 };
348 reference: { type: "reference"; value: string };
349 "text-alignment-type-union": {
350 type: "text-alignment-type-union";
351 value: "right" | "left" | "center" | "justify";
352 };
353 "text-size-union": {
354 type: "text-size-union";
355 value: "default" | "small" | "large";
356 };
357 "page-type-union": { type: "page-type-union"; value: "doc" | "canvas" };
358 "block-type-union": {
359 type: "block-type-union";
360 value:
361 | "datetime"
362 | "rsvp"
363 | "text"
364 | "image"
365 | "card"
366 | "heading"
367 | "link"
368 | "mailbox"
369 | "embed"
370 | "button"
371 | "poll"
372 | "bluesky-post"
373 | "math"
374 | "code"
375 | "blockquote"
376 | "horizontal-rule";
377 };
378 "canvas-pattern-union": {
379 type: "canvas-pattern-union";
380 value: "dot" | "grid" | "plain";
381 };
382 "list-style-union": {
383 type: "list-style-union";
384 value: "ordered" | "unordered";
385 };
386 color: { type: "color"; value: string };
387}[(typeof Attributes)[A]["type"]];
388export type FilterAttributes<F extends Partial<Attributes[keyof Attributes]>> =
389 {
390 [A in keyof Attributes as Attributes[A] extends F
391 ? A
392 : never]: Attributes[A];
393 };