···11# gallery
2233-lexicons for my gallery.
33+lexicons are defined with the [typelex] emitter for typespec and emitted as
44+json in the `lexicons/` directory in the standard lexicon format.
4555-lexicons are defined in `./src/lexicons.ts`, then exported into json files in
66-`./lexicons/`, aaaand then into type declarations in `./src/lexicons/` by
77-`@atcute/lex-cli`.
66+we can then generate typescript types using `@atcute/lex-cli`.
8799-to build the lexicons, run:
1010-1111-```bash
1212-bun lex:export # src/lexicons.ts -> ./lexicons/*.json
1313-bun lex:gen # ./lexicons/*.json -> src/lexicons/#
88+```sh
99+bun run
1010+ gen:lex # compiles typespec to lexicon json
1111+ gen:types # generates typescript types from lexicon json in `lib/`
1212+ gen # runs both commands sequentially
14131515-# or, simply
1616-bun lex:all
1414+bun run
1515+ build # builds the package for publishing
1716```
···11-import { type LexiconDoc, Lexicons } from "@atproto/lexicon";
22-33-export const galleryLex = new Lexicons();
44-55-const imageLex: LexiconDoc = {
66- id: "moe.wlo.gallery.image",
77- lexicon: 1,
88- defs: {
99- main: {
1010- type: "record",
1111- description: "an image with optional alt text.",
1212- record: {
1313- type: "object",
1414- properties: {
1515- // core
1616- blob: {
1717- type: "blob",
1818- description: "the image blob.",
1919- accept: ["image/*"],
2020- },
2121- alt: {
2222- type: "string",
2323- description: "alt text for the image.",
2424- maxLength: 2_000,
2525- },
2626- caption: {
2727- type: "string",
2828- description: "caption for the image.",
2929- maxLength: 2_000,
3030- },
3131-3232- // display
3333- width: { type: "integer", description: "pixel width of the image." },
3434- height: {
3535- type: "integer",
3636- description: "pixel height of the image.",
3737- },
3838- aspectRatio: { type: "integer", description: "width / height." },
3939- size: { type: "integer", description: "file size in bytes." },
4040- checksum: {
4141- type: "string",
4242- description: "sha256 or other checksum of the blob.",
4343- },
4444-4545- // visual helpers
4646- blurhash: {
4747- type: "string",
4848- description: "blurhash for preview placeholders.",
4949- maxLength: 128,
5050- },
5151- dominantColor: {
5252- type: "string",
5353- description: "dominant color as a hex, e.g. '#aabbcc'.",
5454- },
5555- },
5656- required: ["blob", "width", "height"],
5757- },
5858- },
5959- },
6060-};
6161-6262-const groupLex: LexiconDoc = {
6363- id: "moe.wlo.gallery.group",
6464- lexicon: 1,
6565- defs: {
6666- main: {
6767- type: "record",
6868- description: "a named group/collection of images.",
6969- record: {
7070- type: "object",
7171- properties: {
7272- name: {
7373- type: "string",
7474- description: "name of the group.",
7575- maxLength: 256,
7676- },
7777- description: {
7878- type: "string",
7979- description: "optional longer description of the group.",
8080- maxLength: 2000,
8181- },
8282- createdAt: {
8383- type: "string",
8484- description: "iso 8601 timestamp when the group was created.",
8585- },
8686- },
8787- required: ["name", "createdAt"],
8888- },
8989- },
9090- },
9191-};
9292-9393-const groupItemLex: LexiconDoc = {
9494- id: "moe.wlo.gallery.groupitem",
9595- lexicon: 1,
9696- defs: {
9797- main: {
9898- type: "record",
9999- description: "an association between a group and an image.",
100100- record: {
101101- type: "object",
102102- properties: {
103103- group: {
104104- type: "string",
105105- description:
106106- "uri of the group record (eg at://... or your internal uri).",
107107- },
108108- image: {
109109- type: "string",
110110- description:
111111- "uri of the image record (eg at://... or your internal uri).",
112112- },
113113- createdAt: {
114114- type: "string",
115115- description:
116116- "iso 8601 timestamp when the image was added to the group.",
117117- },
118118- note: {
119119- type: "string",
120120- description: "optional note about this item.",
121121- maxLength: 2000,
122122- },
123123- },
124124- required: ["group", "image", "createdAt"],
125125- },
126126- },
127127- },
128128-};
129129-130130-export const lexes: LexiconDoc[] = [imageLex, groupLex, groupItemLex];
131131-for (const lex of lexes) galleryLex.add(lex);
-3
pkgs/gallery/src/lexicons/index.ts
···11-export * as MoeWloGalleryGroup from "./types/moe/wlo/gallery/group.js";
22-export * as MoeWloGalleryGroupitem from "./types/moe/wlo/gallery/groupitem.js";
33-export * as MoeWloGalleryImage from "./types/moe/wlo/gallery/image.js";
···11+import "@typelex/emitter";
22+33+namespace moe.wlo.gallery.image {
44+ /**
55+ * defines an image in the gallery
66+ */
77+ @rec("tid")
88+ model Main {
99+ @required image: Blob<#["image/*"], 32000000>; // 32mb max
1010+ @required createdAt: datetime;
1111+ @maxLength(2000) alt?: string;
1212+ @maxLength(2000) caption?: string;
1313+ width?: numeric;
1414+ height?: numeric;
1515+ aspectRatio?: numeric;
1616+ sizeInBytes?: numeric;
1717+ checksum?: string;
1818+ dominantColour?: string;
1919+2020+ /** provides a blurred preview of the image for use while loading, see github.com/woltapp/blurhash */
2121+ blurhash?: string;
2222+ }
2323+}
2424+2525+namespace moe.wlo.gallery.group {
2626+ /**
2727+ * defines a group of images in the gallery
2828+ */
2929+ @rec("tid")
3030+ model Main {
3131+ @required createdAt: datetime;
3232+ @maxLength(300) title?: string;
3333+ @maxLength(1000) description?: string;
3434+ }
3535+}
3636+3737+namespace moe.wlo.gallery.groupItem {
3838+ /**
3939+ * defines an item in a gallery group
4040+ */
4141+ @rec("tid")
4242+ model Main {
4343+ /** uri of the group that the image belongs to */
4444+ @required group: atUri;
4545+4646+ /** uri of the image that this item represents */
4747+ @required image: atUri;
4848+4949+ @required addedAt: datetime;
5050+ note?: string;
5151+ }
5252+}