···11+name = "gpreview"
22+version = "1.0.0"
33+target = "javascript"
44+55+# Fill out these fields if you intend to generate HTML documentation or publish
66+# your project to the Hex package manager.
77+#
88+# description = ""
99+# licences = ["Apache-2.0"]
1010+# repository = { type = "github", user = "", repo = "" }
1111+# links = [{ title = "Website", href = "" }]
1212+#
1313+# For a full reference of all the available options, you can have a look at
1414+# https://gleam.run/writing-gleam/gleam-toml/.
1515+1616+[dependencies]
1717+gleam_stdlib = ">= 0.44.0 and < 2.0.0"
1818+lustre = ">= 5.6.0 and < 6.0.0"
1919+rsvp = ">= 1.2.0 and < 2.0.0"
2020+gleam_json = ">= 3.1.0 and < 4.0.0"
2121+2222+[dev-dependencies]
2323+gleeunit = ">= 1.0.0 and < 2.0.0"
2424+lustre_dev_tools = ">= 2.3.4 and < 3.0.0"
2525+2626+[tools.lustre]
2727+[tools.lustre.bin]
2828+bun = "system"
2929+tailwindcss = "system"
3030+[tools.lustre.html]
3131+title = "GPreview - Bluesky Post Viewer"
···11+{
22+ "lexicon": 1,
33+ "id": "app.bsky.feed.post",
44+ "defs": {
55+ "main": {
66+ "type": "record",
77+ "description": "Record containing a Bluesky post.",
88+ "key": "tid",
99+ "record": {
1010+ "type": "object",
1111+ "required": ["text", "createdAt"],
1212+ "properties": {
1313+ "text": {
1414+ "type": "string",
1515+ "maxLength": 3000,
1616+ "maxGraphemes": 300,
1717+ "description": "The primary post content. May be an empty string, if there are embeds."
1818+ },
1919+ "entities": {
2020+ "type": "array",
2121+ "description": "DEPRECATED: replaced by app.bsky.richtext.facet.",
2222+ "items": { "type": "ref", "ref": "#entity" }
2323+ },
2424+ "facets": {
2525+ "type": "array",
2626+ "description": "Annotations of text (mentions, URLs, hashtags, etc)",
2727+ "items": { "type": "ref", "ref": "app.bsky.richtext.facet" }
2828+ },
2929+ "reply": { "type": "ref", "ref": "#replyRef" },
3030+ "embed": {
3131+ "type": "union",
3232+ "refs": [
3333+ "app.bsky.embed.images",
3434+ "app.bsky.embed.video",
3535+ "app.bsky.embed.external",
3636+ "app.bsky.embed.record",
3737+ "app.bsky.embed.recordWithMedia"
3838+ ]
3939+ },
4040+ "langs": {
4141+ "type": "array",
4242+ "description": "Indicates human language of post primary text content.",
4343+ "maxLength": 3,
4444+ "items": { "type": "string", "format": "language" }
4545+ },
4646+ "labels": {
4747+ "type": "union",
4848+ "description": "Self-label values for this post. Effectively content warnings.",
4949+ "refs": ["com.atproto.label.defs#selfLabels"]
5050+ },
5151+ "tags": {
5252+ "type": "array",
5353+ "description": "Additional hashtags, in addition to any included in post text and facets.",
5454+ "maxLength": 8,
5555+ "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }
5656+ },
5757+ "createdAt": {
5858+ "type": "string",
5959+ "format": "datetime",
6060+ "description": "Client-declared timestamp when this post was originally created."
6161+ }
6262+ }
6363+ }
6464+ },
6565+ "replyRef": {
6666+ "type": "object",
6767+ "required": ["root", "parent"],
6868+ "properties": {
6969+ "root": { "type": "ref", "ref": "com.atproto.repo.strongRef" },
7070+ "parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" }
7171+ }
7272+ },
7373+ "entity": {
7474+ "type": "object",
7575+ "description": "Deprecated: use facets instead.",
7676+ "required": ["index", "type", "value"],
7777+ "properties": {
7878+ "index": { "type": "ref", "ref": "#textSlice" },
7979+ "type": {
8080+ "type": "string",
8181+ "description": "Expected values are 'mention' and 'link'."
8282+ },
8383+ "value": { "type": "string" }
8484+ }
8585+ },
8686+ "textSlice": {
8787+ "type": "object",
8888+ "description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.",
8989+ "required": ["start", "end"],
9090+ "properties": {
9191+ "start": { "type": "integer", "minimum": 0 },
9292+ "end": { "type": "integer", "minimum": 0 }
9393+ }
9494+ }
9595+ }
9696+}
+51
src/lexicons/app/bsky/richtext/facet.json
···11+{
22+ "lexicon": 1,
33+ "id": "app.bsky.richtext.facet",
44+ "defs": {
55+ "main": {
66+ "type": "object",
77+ "description": "Annotation of a sub-string within rich text.",
88+ "required": ["index", "features"],
99+ "properties": {
1010+ "index": { "type": "ref", "ref": "#byteSlice" },
1111+ "features": {
1212+ "type": "array",
1313+ "items": { "type": "union", "refs": ["#mention", "#link", "#tag"] }
1414+ }
1515+ }
1616+ },
1717+ "mention": {
1818+ "type": "object",
1919+ "description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.",
2020+ "required": ["did"],
2121+ "properties": {
2222+ "did": { "type": "string", "format": "did" }
2323+ }
2424+ },
2525+ "link": {
2626+ "type": "object",
2727+ "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.",
2828+ "required": ["uri"],
2929+ "properties": {
3030+ "uri": { "type": "string", "format": "uri" }
3131+ }
3232+ },
3333+ "tag": {
3434+ "type": "object",
3535+ "description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').",
3636+ "required": ["tag"],
3737+ "properties": {
3838+ "tag": { "type": "string", "maxLength": 640, "maxGraphemes": 64 }
3939+ }
4040+ },
4141+ "byteSlice": {
4242+ "type": "object",
4343+ "description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.",
4444+ "required": ["byteStart", "byteEnd"],
4545+ "properties": {
4646+ "byteStart": { "type": "integer", "minimum": 0 },
4747+ "byteEnd": { "type": "integer", "minimum": 0 }
4848+ }
4949+ }
5050+ }
5151+}