import generated leaflet types

nulfrost 7061283f 7d8fd04a

+15
lexicons/com/atproto/repo/strongRef.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "com.atproto.repo.strongRef", 4 + "description": "A URI with a content-hash fingerprint.", 5 + "defs": { 6 + "main": { 7 + "type": "object", 8 + "required": ["uri", "cid"], 9 + "properties": { 10 + "uri": { "type": "string", "format": "at-uri" }, 11 + "cid": { "type": "string", "format": "cid" } 12 + } 13 + } 14 + } 15 + }
+21
lexicons/pub/leaflet/blocks/code.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.code", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["plaintext"], 8 + "properties": { 9 + "plaintext": { 10 + "type": "string" 11 + }, 12 + "language": { 13 + "type": "string" 14 + }, 15 + "syntaxHighlightingTheme": { 16 + "type": "string" 17 + } 18 + } 19 + } 20 + } 21 + }
+27
lexicons/pub/leaflet/blocks/header.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.header", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["plaintext"], 8 + "properties": { 9 + "level": { 10 + "type": "integer", 11 + "minimum": 1, 12 + "maximum": 6 13 + }, 14 + "plaintext": { 15 + "type": "string" 16 + }, 17 + "facets": { 18 + "type": "array", 19 + "items": { 20 + "type": "ref", 21 + "ref": "pub.leaflet.richtext.facet" 22 + } 23 + } 24 + } 25 + } 26 + } 27 + }
+37
lexicons/pub/leaflet/blocks/image.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.image", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["image", "aspectRatio"], 8 + "properties": { 9 + "image": { 10 + "type": "blob", 11 + "accept": ["image/*"], 12 + "maxSize": 1000000 13 + }, 14 + "alt": { 15 + "type": "string", 16 + "description": "Alt text description of the image, for accessibility." 17 + }, 18 + "aspectRatio": { 19 + "type": "ref", 20 + "ref": "#aspectRatio" 21 + } 22 + } 23 + }, 24 + "aspectRatio": { 25 + "type": "object", 26 + "required": ["width", "height"], 27 + "properties": { 28 + "width": { 29 + "type": "integer" 30 + }, 31 + "height": { 32 + "type": "integer" 33 + } 34 + } 35 + } 36 + } 37 + }
+15
lexicons/pub/leaflet/blocks/math.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.math", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["tex"], 8 + "properties": { 9 + "tex": { 10 + "type": "string" 11 + } 12 + } 13 + } 14 + } 15 + }
+22
lexicons/pub/leaflet/blocks/text.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.text", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["plaintext"], 8 + "properties": { 9 + "plaintext": { 10 + "type": "string" 11 + }, 12 + "facets": { 13 + "type": "array", 14 + "items": { 15 + "type": "ref", 16 + "ref": "pub.leaflet.richtext.facet" 17 + } 18 + } 19 + } 20 + } 21 + } 22 + }
+40
lexicons/pub/leaflet/blocks/unorderedList.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.unorderedList", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["children"], 8 + "properties": { 9 + "children": { 10 + "type": "array", 11 + "items": { 12 + "type": "ref", 13 + "ref": "#listItem" 14 + } 15 + } 16 + } 17 + }, 18 + "listItem": { 19 + "type": "object", 20 + "required": ["content"], 21 + "properties": { 22 + "content": { 23 + "type": "union", 24 + "refs": [ 25 + "pub.leaflet.blocks.text", 26 + "pub.leaflet.blocks.header", 27 + "pub.leaflet.blocks.image" 28 + ] 29 + }, 30 + "children": { 31 + "type": "array", 32 + "items": { 33 + "type": "ref", 34 + "ref": "#listItem" 35 + } 36 + } 37 + } 38 + } 39 + } 40 + }
+27
lexicons/pub/leaflet/blocks/website.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.blocks.website", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "required": ["src"], 8 + "properties": { 9 + "previewImage": { 10 + "type": "blob", 11 + "accept": ["image/*"], 12 + "maxSize": 1000000 13 + }, 14 + "title": { 15 + "type": "string" 16 + }, 17 + "description": { 18 + "type": "string" 19 + }, 20 + "src": { 21 + "type": "string", 22 + "format": "uri" 23 + } 24 + } 25 + } 26 + } 27 + }
+52
lexicons/pub/leaflet/document.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.document", 4 + "revision": 1, 5 + "description": "A lexicon for long form rich media documents", 6 + "defs": { 7 + "main": { 8 + "type": "record", 9 + "key": "tid", 10 + "description": "Record containing a document", 11 + "record": { 12 + "type": "object", 13 + "required": ["pages", "author", "title", "publication"], 14 + "properties": { 15 + "title": { 16 + "type": "string", 17 + "maxLength": 1280, 18 + "maxGraphemes": 128 19 + }, 20 + "postRef": { 21 + "type": "ref", 22 + "ref": "com.atproto.repo.strongRef" 23 + }, 24 + "description": { 25 + "type": "string", 26 + "maxLength": 3000, 27 + "maxGraphemes": 300 28 + }, 29 + "publishedAt": { 30 + "type": "string", 31 + "format": "datetime" 32 + }, 33 + "publication": { 34 + "type": "string", 35 + "format": "at-uri" 36 + }, 37 + "author": { 38 + "type": "string", 39 + "format": "at-identifier" 40 + }, 41 + "pages": { 42 + "type": "array", 43 + "items": { 44 + "type": "union", 45 + "refs": ["pub.leaflet.pages.linearDocument"] 46 + } 47 + } 48 + } 49 + } 50 + } 51 + } 52 + }
+53
lexicons/pub/leaflet/pages/linearDocument.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.pages.linearDocument", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "properties": { 8 + "blocks": { 9 + "type": "array", 10 + "items": { 11 + "type": "ref", 12 + "ref": "#block" 13 + } 14 + } 15 + } 16 + }, 17 + "block": { 18 + "type": "object", 19 + "required": ["block"], 20 + "properties": { 21 + "block": { 22 + "type": "union", 23 + "refs": [ 24 + "pub.leaflet.blocks.text", 25 + "pub.leaflet.blocks.header", 26 + "pub.leaflet.blocks.image", 27 + "pub.leaflet.blocks.unorderedList", 28 + "pub.leaflet.blocks.website", 29 + "pub.leaflet.blocks.math", 30 + "pub.leaflet.blocks.code" 31 + ] 32 + }, 33 + "alignment": { 34 + "type": "string", 35 + "knownValues": [ 36 + "#textAlignLeft", 37 + "#textAlignCenter", 38 + "#textAlignRight" 39 + ] 40 + } 41 + } 42 + }, 43 + "textAlignLeft": { 44 + "type": "token" 45 + }, 46 + "textAlignCenter": { 47 + "type": "token" 48 + }, 49 + "textAlignRight": { 50 + "type": "token" 51 + } 52 + } 53 + }
+105
lexicons/pub/leaflet/richtext/facet.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "pub.leaflet.richtext.facet", 4 + "defs": { 5 + "main": { 6 + "type": "object", 7 + "description": "Annotation of a sub-string within rich text.", 8 + "required": ["index", "features"], 9 + "properties": { 10 + "index": { 11 + "type": "ref", 12 + "ref": "#byteSlice" 13 + }, 14 + "features": { 15 + "type": "array", 16 + "items": { 17 + "type": "union", 18 + "refs": [ 19 + "#link", 20 + "#code", 21 + "#highlight", 22 + "#underline", 23 + "#strikethrough", 24 + "#id", 25 + "#bold", 26 + "#italic" 27 + ] 28 + } 29 + } 30 + } 31 + }, 32 + "byteSlice": { 33 + "type": "object", 34 + "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.", 35 + "required": ["byteStart", "byteEnd"], 36 + "properties": { 37 + "byteStart": { 38 + "type": "integer", 39 + "minimum": 0 40 + }, 41 + "byteEnd": { 42 + "type": "integer", 43 + "minimum": 0 44 + } 45 + } 46 + }, 47 + "link": { 48 + "type": "object", 49 + "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", 50 + "required": ["uri"], 51 + "properties": { 52 + "uri": { 53 + "type": "string", 54 + "format": "uri" 55 + } 56 + } 57 + }, 58 + "code": { 59 + "type": "object", 60 + "description": "Facet feature for inline code.", 61 + "required": [], 62 + "properties": {} 63 + }, 64 + "highlight": { 65 + "type": "object", 66 + "description": "Facet feature for highlighted text.", 67 + "required": [], 68 + "properties": {} 69 + }, 70 + "underline": { 71 + "type": "object", 72 + "description": "Facet feature for underline markup", 73 + "required": [], 74 + "properties": {} 75 + }, 76 + "strikethrough": { 77 + "type": "object", 78 + "description": "Facet feature for strikethrough markup", 79 + "required": [], 80 + "properties": {} 81 + }, 82 + "id": { 83 + "type": "object", 84 + "description": "Facet feature for an identifier. Used for linking to a segment", 85 + "required": [], 86 + "properties": { 87 + "id": { 88 + "type": "string" 89 + } 90 + } 91 + }, 92 + "bold": { 93 + "type": "object", 94 + "description": "Facet feature for bold text", 95 + "required": [], 96 + "properties": {} 97 + }, 98 + "italic": { 99 + "type": "object", 100 + "description": "Facet feature for italic text", 101 + "required": [], 102 + "properties": {} 103 + } 104 + } 105 + }
+6 -1
package.json
··· 18 18 "url": "git+https://github.com/nulfrost/leaflet-loader-astro.git" 19 19 }, 20 20 "scripts": { 21 + "lex-gen": "lex gen-api ./src/__generated__/lexicons ./lexicons/pub/leaflet/* ./lexicons/pub/leaflet/*/* ./lexicons/com/atproto/*/* --yes", 22 + "typecheck": "tsc --noEmit", 21 23 "build": "tsc" 22 24 }, 23 25 "license": "MIT", ··· 27 29 "type": "module", 28 30 "main": "dist/index.js", 29 31 "devDependencies": { 32 + "@atproto/lex-cli": "^0.9.1", 33 + "@types/sanitize-html": "^2.16.0", 30 34 "astro": "^5.12.8", 31 35 "tsup": "^8.5.0", 32 36 "typescript": "^5.9.2", ··· 35 39 "dependencies": { 36 40 "@atproto/api": "^0.16.1", 37 41 "@atproto/did": "^0.1.5", 38 - "@atproto/syntax": "^0.4.0" 42 + "@atproto/syntax": "^0.4.0", 43 + "sanitize-html": "^2.17.0" 39 44 } 40 45 }
+182
pnpm-lock.yaml
··· 17 17 '@atproto/syntax': 18 18 specifier: ^0.4.0 19 19 version: 0.4.0 20 + sanitize-html: 21 + specifier: ^2.17.0 22 + version: 2.17.0 20 23 devDependencies: 24 + '@atproto/lex-cli': 25 + specifier: ^0.9.1 26 + version: 0.9.1 27 + '@types/sanitize-html': 28 + specifier: ^2.16.0 29 + version: 2.16.0 21 30 astro: 22 31 specifier: ^5.12.8 23 32 version: 5.12.8(@types/node@24.2.0)(rollup@4.46.2)(typescript@5.9.2) ··· 58 67 59 68 '@atproto/did@0.1.5': 60 69 resolution: {integrity: sha512-8+1D08QdGE5TF0bB0vV8HLVrVZJeLNITpRTUVEoABNMRaUS7CoYSVb0+JNQDeJIVmqMjOL8dOjvCUDkp3gEaGQ==} 70 + 71 + '@atproto/lex-cli@0.9.1': 72 + resolution: {integrity: sha512-ftcUZd8rElHeUJq6pTcQkURnTEe7woCF4I1NK3j5GpT/itacEZtcppabjy5o2aUsbktZsALj3ch3xm7ZZ+Zp0w==} 73 + engines: {node: '>=18.7.0'} 74 + hasBin: true 61 75 62 76 '@atproto/lexicon@0.4.12': 63 77 resolution: {integrity: sha512-fcEvEQ1GpQYF5igZ4IZjPWEoWVpsEF22L9RexxLS3ptfySXLflEyH384e7HITzO/73McDeaJx3lqHIuqn9ulnw==} ··· 509 523 '@swc/helpers@0.5.17': 510 524 resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} 511 525 526 + '@ts-morph/common@0.25.0': 527 + resolution: {integrity: sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==} 528 + 512 529 '@types/chai@5.2.2': 513 530 resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==} 514 531 ··· 538 555 539 556 '@types/node@24.2.0': 540 557 resolution: {integrity: sha512-3xyG3pMCq3oYCNg7/ZP+E1ooTaGB4cG8JWRsqqOYQdbWNY4zbaV0Ennrd7stjiJEFZCaybcIgpTjJWHRfBSIDw==} 558 + 559 + '@types/sanitize-html@2.16.0': 560 + resolution: {integrity: sha512-l6rX1MUXje5ztPT0cAFtUayXF06DqPhRyfVXareEN5gGCFaP/iwsxIyKODr9XDhfxPpN6vXUFNfo5kZMXCxBtw==} 541 561 542 562 '@types/unist@3.0.3': 543 563 resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} ··· 677 697 resolution: {integrity: sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==} 678 698 engines: {node: '>=18'} 679 699 700 + chalk@4.1.2: 701 + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 702 + engines: {node: '>=10'} 703 + 680 704 chalk@5.5.0: 681 705 resolution: {integrity: sha512-1tm8DTaJhPBG3bIkVeZt1iZM9GfSX2lzOeDVZH9R9ffRHpmHvxZ/QhgQH/aDTkswQVt+YHdXAdS/In/30OjCbg==} 682 706 engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} ··· 714 738 resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} 715 739 engines: {node: '>=6'} 716 740 741 + code-block-writer@13.0.3: 742 + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} 743 + 717 744 color-convert@2.0.1: 718 745 resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 719 746 engines: {node: '>=7.0.0'} ··· 735 762 resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 736 763 engines: {node: '>= 6'} 737 764 765 + commander@9.5.0: 766 + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} 767 + engines: {node: ^12.20.0 || >=14} 768 + 738 769 common-ancestor-path@1.0.1: 739 770 resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} 740 771 ··· 787 818 resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} 788 819 engines: {node: '>=6'} 789 820 821 + deepmerge@4.3.1: 822 + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} 823 + engines: {node: '>=0.10.0'} 824 + 790 825 defu@6.1.4: 791 826 resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} 792 827 ··· 821 856 dlv@1.1.3: 822 857 resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} 823 858 859 + dom-serializer@2.0.0: 860 + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} 861 + 862 + domelementtype@2.3.0: 863 + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} 864 + 865 + domhandler@5.0.3: 866 + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} 867 + engines: {node: '>= 4'} 868 + 869 + domutils@3.2.2: 870 + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} 871 + 824 872 dset@3.1.4: 825 873 resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} 826 874 engines: {node: '>=4'} ··· 837 885 emoji-regex@9.2.2: 838 886 resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 839 887 888 + entities@4.5.0: 889 + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} 890 + engines: {node: '>=0.12'} 891 + 840 892 entities@6.0.1: 841 893 resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} 842 894 engines: {node: '>=0.12'} ··· 848 900 resolution: {integrity: sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q==} 849 901 engines: {node: '>=18'} 850 902 hasBin: true 903 + 904 + escape-string-regexp@4.0.0: 905 + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 906 + engines: {node: '>=10'} 851 907 852 908 escape-string-regexp@5.0.0: 853 909 resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} ··· 919 975 h3@1.15.4: 920 976 resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} 921 977 978 + has-flag@4.0.0: 979 + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 980 + engines: {node: '>=8'} 981 + 922 982 hast-util-from-html@2.0.3: 923 983 resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} 924 984 ··· 955 1015 html-void-elements@3.0.0: 956 1016 resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} 957 1017 1018 + htmlparser2@8.0.2: 1019 + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} 1020 + 958 1021 http-cache-semantics@4.2.0: 959 1022 resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} 960 1023 ··· 984 1047 is-plain-obj@4.1.0: 985 1048 resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} 986 1049 engines: {node: '>=12'} 1050 + 1051 + is-plain-object@5.0.0: 1052 + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} 1053 + engines: {node: '>=0.10.0'} 987 1054 988 1055 is-wsl@3.1.0: 989 1056 resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} ··· 1270 1337 parse-latin@7.0.0: 1271 1338 resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} 1272 1339 1340 + parse-srcset@1.0.2: 1341 + resolution: {integrity: sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==} 1342 + 1273 1343 parse5@7.3.0: 1274 1344 resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} 1345 + 1346 + path-browserify@1.0.1: 1347 + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} 1275 1348 1276 1349 path-key@3.1.1: 1277 1350 resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} ··· 1327 1400 postcss@8.5.6: 1328 1401 resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} 1329 1402 engines: {node: ^10 || ^12 || >=14} 1403 + 1404 + prettier@3.6.2: 1405 + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} 1406 + engines: {node: '>=14'} 1407 + hasBin: true 1330 1408 1331 1409 prismjs@1.30.0: 1332 1410 resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} ··· 1414 1492 engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1415 1493 hasBin: true 1416 1494 1495 + sanitize-html@2.17.0: 1496 + resolution: {integrity: sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==} 1497 + 1417 1498 semver@7.7.2: 1418 1499 resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} 1419 1500 engines: {node: '>=10'} ··· 1500 1581 engines: {node: '>=16 || 14 >=14.17'} 1501 1582 hasBin: true 1502 1583 1584 + supports-color@7.2.0: 1585 + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1586 + engines: {node: '>=8'} 1587 + 1503 1588 thenify-all@1.6.0: 1504 1589 resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1505 1590 engines: {node: '>=0.8'} ··· 1554 1639 1555 1640 ts-interface-checker@0.1.13: 1556 1641 resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 1642 + 1643 + ts-morph@24.0.0: 1644 + resolution: {integrity: sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==} 1557 1645 1558 1646 tsconfck@3.1.6: 1559 1647 resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} ··· 1890 1978 yargs-parser@21.1.1: 1891 1979 resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 1892 1980 engines: {node: '>=12'} 1981 + 1982 + yesno@0.4.0: 1983 + resolution: {integrity: sha512-tdBxmHvbXPBKYIg81bMCB7bVeDmHkRzk5rVJyYYXurwKkHq/MCd8rz4HSJUP7hW0H2NlXiq8IFiWvYKEHhlotA==} 1893 1984 1894 1985 yocto-queue@1.2.1: 1895 1986 resolution: {integrity: sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==} ··· 1990 2081 dependencies: 1991 2082 zod: 3.25.76 1992 2083 2084 + '@atproto/lex-cli@0.9.1': 2085 + dependencies: 2086 + '@atproto/lexicon': 0.4.12 2087 + '@atproto/syntax': 0.4.0 2088 + chalk: 4.1.2 2089 + commander: 9.5.0 2090 + prettier: 3.6.2 2091 + ts-morph: 24.0.0 2092 + yesno: 0.4.0 2093 + zod: 3.25.76 2094 + 1993 2095 '@atproto/lexicon@0.4.12': 1994 2096 dependencies: 1995 2097 '@atproto/common-web': 0.4.2 ··· 2317 2419 dependencies: 2318 2420 tslib: 2.8.1 2319 2421 2422 + '@ts-morph/common@0.25.0': 2423 + dependencies: 2424 + minimatch: 9.0.5 2425 + path-browserify: 1.0.1 2426 + tinyglobby: 0.2.14 2427 + 2320 2428 '@types/chai@5.2.2': 2321 2429 dependencies: 2322 2430 '@types/deep-eql': 4.0.2 ··· 2350 2458 '@types/node@24.2.0': 2351 2459 dependencies: 2352 2460 undici-types: 7.10.0 2461 + 2462 + '@types/sanitize-html@2.16.0': 2463 + dependencies: 2464 + htmlparser2: 8.0.2 2353 2465 2354 2466 '@types/unist@3.0.3': {} 2355 2467 ··· 2581 2693 loupe: 3.2.0 2582 2694 pathval: 2.0.1 2583 2695 2696 + chalk@4.1.2: 2697 + dependencies: 2698 + ansi-styles: 4.3.0 2699 + supports-color: 7.2.0 2700 + 2584 2701 chalk@5.5.0: {} 2585 2702 2586 2703 character-entities-html4@2.1.0: {} ··· 2603 2720 2604 2721 clsx@2.1.1: {} 2605 2722 2723 + code-block-writer@13.0.3: {} 2724 + 2606 2725 color-convert@2.0.1: 2607 2726 dependencies: 2608 2727 color-name: 1.1.4 ··· 2625 2744 2626 2745 commander@4.1.1: {} 2627 2746 2747 + commander@9.5.0: {} 2748 + 2628 2749 common-ancestor-path@1.0.1: {} 2629 2750 2630 2751 confbox@0.1.8: {} ··· 2668 2789 2669 2790 deep-eql@5.0.2: {} 2670 2791 2792 + deepmerge@4.3.1: {} 2793 + 2671 2794 defu@6.1.4: {} 2672 2795 2673 2796 dequal@2.0.3: {} ··· 2693 2816 2694 2817 dlv@1.1.3: {} 2695 2818 2819 + dom-serializer@2.0.0: 2820 + dependencies: 2821 + domelementtype: 2.3.0 2822 + domhandler: 5.0.3 2823 + entities: 4.5.0 2824 + 2825 + domelementtype@2.3.0: {} 2826 + 2827 + domhandler@5.0.3: 2828 + dependencies: 2829 + domelementtype: 2.3.0 2830 + 2831 + domutils@3.2.2: 2832 + dependencies: 2833 + dom-serializer: 2.0.0 2834 + domelementtype: 2.3.0 2835 + domhandler: 5.0.3 2836 + 2696 2837 dset@3.1.4: {} 2697 2838 2698 2839 eastasianwidth@0.2.0: {} ··· 2702 2843 emoji-regex@8.0.0: {} 2703 2844 2704 2845 emoji-regex@9.2.2: {} 2846 + 2847 + entities@4.5.0: {} 2705 2848 2706 2849 entities@6.0.1: {} 2707 2850 ··· 2735 2878 '@esbuild/win32-arm64': 0.25.8 2736 2879 '@esbuild/win32-ia32': 0.25.8 2737 2880 '@esbuild/win32-x64': 0.25.8 2881 + 2882 + escape-string-regexp@4.0.0: {} 2738 2883 2739 2884 escape-string-regexp@5.0.0: {} 2740 2885 ··· 2815 2960 radix3: 1.1.2 2816 2961 ufo: 1.6.1 2817 2962 uncrypto: 0.1.3 2963 + 2964 + has-flag@4.0.0: {} 2818 2965 2819 2966 hast-util-from-html@2.0.3: 2820 2967 dependencies: ··· 2907 3054 2908 3055 html-void-elements@3.0.0: {} 2909 3056 3057 + htmlparser2@8.0.2: 3058 + dependencies: 3059 + domelementtype: 2.3.0 3060 + domhandler: 5.0.3 3061 + domutils: 3.2.2 3062 + entities: 4.5.0 3063 + 2910 3064 http-cache-semantics@4.2.0: {} 2911 3065 2912 3066 import-meta-resolve@4.1.0: {} ··· 2925 3079 is-docker: 3.0.0 2926 3080 2927 3081 is-plain-obj@4.1.0: {} 3082 + 3083 + is-plain-object@5.0.0: {} 2928 3084 2929 3085 is-wsl@3.1.0: 2930 3086 dependencies: ··· 3378 3534 unist-util-visit-children: 3.0.0 3379 3535 vfile: 6.0.3 3380 3536 3537 + parse-srcset@1.0.2: {} 3538 + 3381 3539 parse5@7.3.0: 3382 3540 dependencies: 3383 3541 entities: 6.0.1 3542 + 3543 + path-browserify@1.0.1: {} 3384 3544 3385 3545 path-key@3.1.1: {} 3386 3546 ··· 3419 3579 picocolors: 1.1.1 3420 3580 source-map-js: 1.2.1 3421 3581 3582 + prettier@3.6.2: {} 3583 + 3422 3584 prismjs@1.30.0: {} 3423 3585 3424 3586 prompts@2.4.2: ··· 3566 3728 '@rollup/rollup-win32-ia32-msvc': 4.46.2 3567 3729 '@rollup/rollup-win32-x64-msvc': 4.46.2 3568 3730 fsevents: 2.3.3 3731 + 3732 + sanitize-html@2.17.0: 3733 + dependencies: 3734 + deepmerge: 4.3.1 3735 + escape-string-regexp: 4.0.0 3736 + htmlparser2: 8.0.2 3737 + is-plain-object: 5.0.0 3738 + parse-srcset: 1.0.2 3739 + postcss: 8.5.6 3569 3740 3570 3741 semver@7.7.2: {} 3571 3742 ··· 3683 3854 pirates: 4.0.7 3684 3855 ts-interface-checker: 0.1.13 3685 3856 3857 + supports-color@7.2.0: 3858 + dependencies: 3859 + has-flag: 4.0.0 3860 + 3686 3861 thenify-all@1.6.0: 3687 3862 dependencies: 3688 3863 thenify: 3.3.1 ··· 3723 3898 trough@2.2.0: {} 3724 3899 3725 3900 ts-interface-checker@0.1.13: {} 3901 + 3902 + ts-morph@24.0.0: 3903 + dependencies: 3904 + '@ts-morph/common': 0.25.0 3905 + code-block-writer: 13.0.3 3726 3906 3727 3907 tsconfck@3.1.6(typescript@5.9.2): 3728 3908 optionalDependencies: ··· 4012 4192 xxhash-wasm@1.1.0: {} 4013 4193 4014 4194 yargs-parser@21.1.1: {} 4195 + 4196 + yesno@0.4.0: {} 4015 4197 4016 4198 yocto-queue@1.2.1: {} 4017 4199
+215
src/__generated__/lexicons/index.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + XrpcClient, 6 + type FetchHandler, 7 + type FetchHandlerOptions, 8 + } from '@atproto/xrpc' 9 + import { schemas } from './lexicons.js' 10 + import { CID } from 'multiformats/cid' 11 + import { type OmitKey, type Un$Typed } from './util.js' 12 + import * as PubLeafletDocument from './types/pub/leaflet/document.js' 13 + import * as PubLeafletBlocksCode from './types/pub/leaflet/blocks/code.js' 14 + import * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header.js' 15 + import * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image.js' 16 + import * as PubLeafletBlocksMath from './types/pub/leaflet/blocks/math.js' 17 + import * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text.js' 18 + import * as PubLeafletBlocksUnorderedList from './types/pub/leaflet/blocks/unorderedList.js' 19 + import * as PubLeafletBlocksWebsite from './types/pub/leaflet/blocks/website.js' 20 + import * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument.js' 21 + import * as PubLeafletRichtextFacet from './types/pub/leaflet/richtext/facet.js' 22 + import * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js' 23 + 24 + export * as PubLeafletDocument from './types/pub/leaflet/document.js' 25 + export * as PubLeafletBlocksCode from './types/pub/leaflet/blocks/code.js' 26 + export * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header.js' 27 + export * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image.js' 28 + export * as PubLeafletBlocksMath from './types/pub/leaflet/blocks/math.js' 29 + export * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text.js' 30 + export * as PubLeafletBlocksUnorderedList from './types/pub/leaflet/blocks/unorderedList.js' 31 + export * as PubLeafletBlocksWebsite from './types/pub/leaflet/blocks/website.js' 32 + export * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument.js' 33 + export * as PubLeafletRichtextFacet from './types/pub/leaflet/richtext/facet.js' 34 + export * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js' 35 + 36 + export const PUB_LEAFLET_PAGES = { 37 + LinearDocumentTextAlignLeft: 'pub.leaflet.pages.linearDocument#textAlignLeft', 38 + LinearDocumentTextAlignCenter: 39 + 'pub.leaflet.pages.linearDocument#textAlignCenter', 40 + LinearDocumentTextAlignRight: 41 + 'pub.leaflet.pages.linearDocument#textAlignRight', 42 + } 43 + 44 + export class AtpBaseClient extends XrpcClient { 45 + pub: PubNS 46 + com: ComNS 47 + 48 + constructor(options: FetchHandler | FetchHandlerOptions) { 49 + super(options, schemas) 50 + this.pub = new PubNS(this) 51 + this.com = new ComNS(this) 52 + } 53 + 54 + /** @deprecated use `this` instead */ 55 + get xrpc(): XrpcClient { 56 + return this 57 + } 58 + } 59 + 60 + export class PubNS { 61 + _client: XrpcClient 62 + leaflet: PubLeafletNS 63 + 64 + constructor(client: XrpcClient) { 65 + this._client = client 66 + this.leaflet = new PubLeafletNS(client) 67 + } 68 + } 69 + 70 + export class PubLeafletNS { 71 + _client: XrpcClient 72 + document: PubLeafletDocumentRecord 73 + blocks: PubLeafletBlocksNS 74 + pages: PubLeafletPagesNS 75 + richtext: PubLeafletRichtextNS 76 + 77 + constructor(client: XrpcClient) { 78 + this._client = client 79 + this.blocks = new PubLeafletBlocksNS(client) 80 + this.pages = new PubLeafletPagesNS(client) 81 + this.richtext = new PubLeafletRichtextNS(client) 82 + this.document = new PubLeafletDocumentRecord(client) 83 + } 84 + } 85 + 86 + export class PubLeafletBlocksNS { 87 + _client: XrpcClient 88 + 89 + constructor(client: XrpcClient) { 90 + this._client = client 91 + } 92 + } 93 + 94 + export class PubLeafletPagesNS { 95 + _client: XrpcClient 96 + 97 + constructor(client: XrpcClient) { 98 + this._client = client 99 + } 100 + } 101 + 102 + export class PubLeafletRichtextNS { 103 + _client: XrpcClient 104 + 105 + constructor(client: XrpcClient) { 106 + this._client = client 107 + } 108 + } 109 + 110 + export class PubLeafletDocumentRecord { 111 + _client: XrpcClient 112 + 113 + constructor(client: XrpcClient) { 114 + this._client = client 115 + } 116 + 117 + async list( 118 + params: OmitKey<ComAtprotoRepoListRecords.QueryParams, 'collection'>, 119 + ): Promise<{ 120 + cursor?: string 121 + records: { uri: string; value: PubLeafletDocument.Record }[] 122 + }> { 123 + const res = await this._client.call('com.atproto.repo.listRecords', { 124 + collection: 'pub.leaflet.document', 125 + ...params, 126 + }) 127 + return res.data 128 + } 129 + 130 + async get( 131 + params: OmitKey<ComAtprotoRepoGetRecord.QueryParams, 'collection'>, 132 + ): Promise<{ uri: string; cid: string; value: PubLeafletDocument.Record }> { 133 + const res = await this._client.call('com.atproto.repo.getRecord', { 134 + collection: 'pub.leaflet.document', 135 + ...params, 136 + }) 137 + return res.data 138 + } 139 + 140 + async create( 141 + params: OmitKey< 142 + ComAtprotoRepoCreateRecord.InputSchema, 143 + 'collection' | 'record' 144 + >, 145 + record: Un$Typed<PubLeafletDocument.Record>, 146 + headers?: Record<string, string>, 147 + ): Promise<{ uri: string; cid: string }> { 148 + const collection = 'pub.leaflet.document' 149 + const res = await this._client.call( 150 + 'com.atproto.repo.createRecord', 151 + undefined, 152 + { collection, ...params, record: { ...record, $type: collection } }, 153 + { encoding: 'application/json', headers }, 154 + ) 155 + return res.data 156 + } 157 + 158 + async put( 159 + params: OmitKey< 160 + ComAtprotoRepoPutRecord.InputSchema, 161 + 'collection' | 'record' 162 + >, 163 + record: Un$Typed<PubLeafletDocument.Record>, 164 + headers?: Record<string, string>, 165 + ): Promise<{ uri: string; cid: string }> { 166 + const collection = 'pub.leaflet.document' 167 + const res = await this._client.call( 168 + 'com.atproto.repo.putRecord', 169 + undefined, 170 + { collection, ...params, record: { ...record, $type: collection } }, 171 + { encoding: 'application/json', headers }, 172 + ) 173 + return res.data 174 + } 175 + 176 + async delete( 177 + params: OmitKey<ComAtprotoRepoDeleteRecord.InputSchema, 'collection'>, 178 + headers?: Record<string, string>, 179 + ): Promise<void> { 180 + await this._client.call( 181 + 'com.atproto.repo.deleteRecord', 182 + undefined, 183 + { collection: 'pub.leaflet.document', ...params }, 184 + { headers }, 185 + ) 186 + } 187 + } 188 + 189 + export class ComNS { 190 + _client: XrpcClient 191 + atproto: ComAtprotoNS 192 + 193 + constructor(client: XrpcClient) { 194 + this._client = client 195 + this.atproto = new ComAtprotoNS(client) 196 + } 197 + } 198 + 199 + export class ComAtprotoNS { 200 + _client: XrpcClient 201 + repo: ComAtprotoRepoNS 202 + 203 + constructor(client: XrpcClient) { 204 + this._client = client 205 + this.repo = new ComAtprotoRepoNS(client) 206 + } 207 + } 208 + 209 + export class ComAtprotoRepoNS { 210 + _client: XrpcClient 211 + 212 + constructor(client: XrpcClient) { 213 + this._client = client 214 + } 215 + }
+481
src/__generated__/lexicons/lexicons.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { 5 + type LexiconDoc, 6 + Lexicons, 7 + ValidationError, 8 + type ValidationResult, 9 + } from '@atproto/lexicon' 10 + import { type $Typed, is$typed, maybe$typed } from './util.js' 11 + 12 + export const schemaDict = { 13 + PubLeafletDocument: { 14 + lexicon: 1, 15 + id: 'pub.leaflet.document', 16 + revision: 1, 17 + description: 'A lexicon for long form rich media documents', 18 + defs: { 19 + main: { 20 + type: 'record', 21 + key: 'tid', 22 + description: 'Record containing a document', 23 + record: { 24 + type: 'object', 25 + required: ['pages', 'author', 'title', 'publication'], 26 + properties: { 27 + title: { 28 + type: 'string', 29 + maxLength: 1280, 30 + maxGraphemes: 128, 31 + }, 32 + postRef: { 33 + type: 'ref', 34 + ref: 'lex:com.atproto.repo.strongRef', 35 + }, 36 + description: { 37 + type: 'string', 38 + maxLength: 3000, 39 + maxGraphemes: 300, 40 + }, 41 + publishedAt: { 42 + type: 'string', 43 + format: 'datetime', 44 + }, 45 + publication: { 46 + type: 'string', 47 + format: 'at-uri', 48 + }, 49 + author: { 50 + type: 'string', 51 + format: 'at-identifier', 52 + }, 53 + pages: { 54 + type: 'array', 55 + items: { 56 + type: 'union', 57 + refs: ['lex:pub.leaflet.pages.linearDocument'], 58 + }, 59 + }, 60 + }, 61 + }, 62 + }, 63 + }, 64 + }, 65 + PubLeafletBlocksCode: { 66 + lexicon: 1, 67 + id: 'pub.leaflet.blocks.code', 68 + defs: { 69 + main: { 70 + type: 'object', 71 + required: ['plaintext'], 72 + properties: { 73 + plaintext: { 74 + type: 'string', 75 + }, 76 + language: { 77 + type: 'string', 78 + }, 79 + syntaxHighlightingTheme: { 80 + type: 'string', 81 + }, 82 + }, 83 + }, 84 + }, 85 + }, 86 + PubLeafletBlocksHeader: { 87 + lexicon: 1, 88 + id: 'pub.leaflet.blocks.header', 89 + defs: { 90 + main: { 91 + type: 'object', 92 + required: ['plaintext'], 93 + properties: { 94 + level: { 95 + type: 'integer', 96 + minimum: 1, 97 + maximum: 6, 98 + }, 99 + plaintext: { 100 + type: 'string', 101 + }, 102 + facets: { 103 + type: 'array', 104 + items: { 105 + type: 'ref', 106 + ref: 'lex:pub.leaflet.richtext.facet', 107 + }, 108 + }, 109 + }, 110 + }, 111 + }, 112 + }, 113 + PubLeafletBlocksImage: { 114 + lexicon: 1, 115 + id: 'pub.leaflet.blocks.image', 116 + defs: { 117 + main: { 118 + type: 'object', 119 + required: ['image', 'aspectRatio'], 120 + properties: { 121 + image: { 122 + type: 'blob', 123 + accept: ['image/*'], 124 + maxSize: 1000000, 125 + }, 126 + alt: { 127 + type: 'string', 128 + description: 129 + 'Alt text description of the image, for accessibility.', 130 + }, 131 + aspectRatio: { 132 + type: 'ref', 133 + ref: 'lex:pub.leaflet.blocks.image#aspectRatio', 134 + }, 135 + }, 136 + }, 137 + aspectRatio: { 138 + type: 'object', 139 + required: ['width', 'height'], 140 + properties: { 141 + width: { 142 + type: 'integer', 143 + }, 144 + height: { 145 + type: 'integer', 146 + }, 147 + }, 148 + }, 149 + }, 150 + }, 151 + PubLeafletBlocksMath: { 152 + lexicon: 1, 153 + id: 'pub.leaflet.blocks.math', 154 + defs: { 155 + main: { 156 + type: 'object', 157 + required: ['tex'], 158 + properties: { 159 + tex: { 160 + type: 'string', 161 + }, 162 + }, 163 + }, 164 + }, 165 + }, 166 + PubLeafletBlocksText: { 167 + lexicon: 1, 168 + id: 'pub.leaflet.blocks.text', 169 + defs: { 170 + main: { 171 + type: 'object', 172 + required: ['plaintext'], 173 + properties: { 174 + plaintext: { 175 + type: 'string', 176 + }, 177 + facets: { 178 + type: 'array', 179 + items: { 180 + type: 'ref', 181 + ref: 'lex:pub.leaflet.richtext.facet', 182 + }, 183 + }, 184 + }, 185 + }, 186 + }, 187 + }, 188 + PubLeafletBlocksUnorderedList: { 189 + lexicon: 1, 190 + id: 'pub.leaflet.blocks.unorderedList', 191 + defs: { 192 + main: { 193 + type: 'object', 194 + required: ['children'], 195 + properties: { 196 + children: { 197 + type: 'array', 198 + items: { 199 + type: 'ref', 200 + ref: 'lex:pub.leaflet.blocks.unorderedList#listItem', 201 + }, 202 + }, 203 + }, 204 + }, 205 + listItem: { 206 + type: 'object', 207 + required: ['content'], 208 + properties: { 209 + content: { 210 + type: 'union', 211 + refs: [ 212 + 'lex:pub.leaflet.blocks.text', 213 + 'lex:pub.leaflet.blocks.header', 214 + 'lex:pub.leaflet.blocks.image', 215 + ], 216 + }, 217 + children: { 218 + type: 'array', 219 + items: { 220 + type: 'ref', 221 + ref: 'lex:pub.leaflet.blocks.unorderedList#listItem', 222 + }, 223 + }, 224 + }, 225 + }, 226 + }, 227 + }, 228 + PubLeafletBlocksWebsite: { 229 + lexicon: 1, 230 + id: 'pub.leaflet.blocks.website', 231 + defs: { 232 + main: { 233 + type: 'object', 234 + required: ['src'], 235 + properties: { 236 + previewImage: { 237 + type: 'blob', 238 + accept: ['image/*'], 239 + maxSize: 1000000, 240 + }, 241 + title: { 242 + type: 'string', 243 + }, 244 + description: { 245 + type: 'string', 246 + }, 247 + src: { 248 + type: 'string', 249 + format: 'uri', 250 + }, 251 + }, 252 + }, 253 + }, 254 + }, 255 + PubLeafletPagesLinearDocument: { 256 + lexicon: 1, 257 + id: 'pub.leaflet.pages.linearDocument', 258 + defs: { 259 + main: { 260 + type: 'object', 261 + properties: { 262 + blocks: { 263 + type: 'array', 264 + items: { 265 + type: 'ref', 266 + ref: 'lex:pub.leaflet.pages.linearDocument#block', 267 + }, 268 + }, 269 + }, 270 + }, 271 + block: { 272 + type: 'object', 273 + required: ['block'], 274 + properties: { 275 + block: { 276 + type: 'union', 277 + refs: [ 278 + 'lex:pub.leaflet.blocks.text', 279 + 'lex:pub.leaflet.blocks.header', 280 + 'lex:pub.leaflet.blocks.image', 281 + 'lex:pub.leaflet.blocks.unorderedList', 282 + 'lex:pub.leaflet.blocks.website', 283 + 'lex:pub.leaflet.blocks.math', 284 + 'lex:pub.leaflet.blocks.code', 285 + ], 286 + }, 287 + alignment: { 288 + type: 'string', 289 + knownValues: [ 290 + 'lex:pub.leaflet.pages.linearDocument#textAlignLeft', 291 + 'lex:pub.leaflet.pages.linearDocument#textAlignCenter', 292 + 'lex:pub.leaflet.pages.linearDocument#textAlignRight', 293 + ], 294 + }, 295 + }, 296 + }, 297 + textAlignLeft: { 298 + type: 'token', 299 + }, 300 + textAlignCenter: { 301 + type: 'token', 302 + }, 303 + textAlignRight: { 304 + type: 'token', 305 + }, 306 + }, 307 + }, 308 + PubLeafletRichtextFacet: { 309 + lexicon: 1, 310 + id: 'pub.leaflet.richtext.facet', 311 + defs: { 312 + main: { 313 + type: 'object', 314 + description: 'Annotation of a sub-string within rich text.', 315 + required: ['index', 'features'], 316 + properties: { 317 + index: { 318 + type: 'ref', 319 + ref: 'lex:pub.leaflet.richtext.facet#byteSlice', 320 + }, 321 + features: { 322 + type: 'array', 323 + items: { 324 + type: 'union', 325 + refs: [ 326 + 'lex:pub.leaflet.richtext.facet#link', 327 + 'lex:pub.leaflet.richtext.facet#code', 328 + 'lex:pub.leaflet.richtext.facet#highlight', 329 + 'lex:pub.leaflet.richtext.facet#underline', 330 + 'lex:pub.leaflet.richtext.facet#strikethrough', 331 + 'lex:pub.leaflet.richtext.facet#id', 332 + 'lex:pub.leaflet.richtext.facet#bold', 333 + 'lex:pub.leaflet.richtext.facet#italic', 334 + ], 335 + }, 336 + }, 337 + }, 338 + }, 339 + byteSlice: { 340 + type: 'object', 341 + description: 342 + '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.', 343 + required: ['byteStart', 'byteEnd'], 344 + properties: { 345 + byteStart: { 346 + type: 'integer', 347 + minimum: 0, 348 + }, 349 + byteEnd: { 350 + type: 'integer', 351 + minimum: 0, 352 + }, 353 + }, 354 + }, 355 + link: { 356 + type: 'object', 357 + description: 358 + 'Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.', 359 + required: ['uri'], 360 + properties: { 361 + uri: { 362 + type: 'string', 363 + format: 'uri', 364 + }, 365 + }, 366 + }, 367 + code: { 368 + type: 'object', 369 + description: 'Facet feature for inline code.', 370 + required: [], 371 + properties: {}, 372 + }, 373 + highlight: { 374 + type: 'object', 375 + description: 'Facet feature for highlighted text.', 376 + required: [], 377 + properties: {}, 378 + }, 379 + underline: { 380 + type: 'object', 381 + description: 'Facet feature for underline markup', 382 + required: [], 383 + properties: {}, 384 + }, 385 + strikethrough: { 386 + type: 'object', 387 + description: 'Facet feature for strikethrough markup', 388 + required: [], 389 + properties: {}, 390 + }, 391 + id: { 392 + type: 'object', 393 + description: 394 + 'Facet feature for an identifier. Used for linking to a segment', 395 + required: [], 396 + properties: { 397 + id: { 398 + type: 'string', 399 + }, 400 + }, 401 + }, 402 + bold: { 403 + type: 'object', 404 + description: 'Facet feature for bold text', 405 + required: [], 406 + properties: {}, 407 + }, 408 + italic: { 409 + type: 'object', 410 + description: 'Facet feature for italic text', 411 + required: [], 412 + properties: {}, 413 + }, 414 + }, 415 + }, 416 + ComAtprotoRepoStrongRef: { 417 + lexicon: 1, 418 + id: 'com.atproto.repo.strongRef', 419 + description: 'A URI with a content-hash fingerprint.', 420 + defs: { 421 + main: { 422 + type: 'object', 423 + required: ['uri', 'cid'], 424 + properties: { 425 + uri: { 426 + type: 'string', 427 + format: 'at-uri', 428 + }, 429 + cid: { 430 + type: 'string', 431 + format: 'cid', 432 + }, 433 + }, 434 + }, 435 + }, 436 + }, 437 + } as const satisfies Record<string, LexiconDoc> 438 + export const schemas = Object.values(schemaDict) satisfies LexiconDoc[] 439 + export const lexicons: Lexicons = new Lexicons(schemas) 440 + 441 + export function validate<T extends { $type: string }>( 442 + v: unknown, 443 + id: string, 444 + hash: string, 445 + requiredType: true, 446 + ): ValidationResult<T> 447 + export function validate<T extends { $type?: string }>( 448 + v: unknown, 449 + id: string, 450 + hash: string, 451 + requiredType?: false, 452 + ): ValidationResult<T> 453 + export function validate( 454 + v: unknown, 455 + id: string, 456 + hash: string, 457 + requiredType?: boolean, 458 + ): ValidationResult { 459 + return (requiredType ? is$typed : maybe$typed)(v, id, hash) 460 + ? lexicons.validate(`${id}#${hash}`, v) 461 + : { 462 + success: false, 463 + error: new ValidationError( 464 + `Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`, 465 + ), 466 + } 467 + } 468 + 469 + export const ids = { 470 + PubLeafletDocument: 'pub.leaflet.document', 471 + PubLeafletBlocksCode: 'pub.leaflet.blocks.code', 472 + PubLeafletBlocksHeader: 'pub.leaflet.blocks.header', 473 + PubLeafletBlocksImage: 'pub.leaflet.blocks.image', 474 + PubLeafletBlocksMath: 'pub.leaflet.blocks.math', 475 + PubLeafletBlocksText: 'pub.leaflet.blocks.text', 476 + PubLeafletBlocksUnorderedList: 'pub.leaflet.blocks.unorderedList', 477 + PubLeafletBlocksWebsite: 'pub.leaflet.blocks.website', 478 + PubLeafletPagesLinearDocument: 'pub.leaflet.pages.linearDocument', 479 + PubLeafletRichtextFacet: 'pub.leaflet.richtext.facet', 480 + ComAtprotoRepoStrongRef: 'com.atproto.repo.strongRef', 481 + } as const
+31
src/__generated__/lexicons/types/com/atproto/repo/strongRef.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'com.atproto.repo.strongRef' 16 + 17 + export interface Main { 18 + $type?: 'com.atproto.repo.strongRef' 19 + uri: string 20 + cid: string 21 + } 22 + 23 + const hashMain = 'main' 24 + 25 + export function isMain<V>(v: V) { 26 + return is$typed(v, id, hashMain) 27 + } 28 + 29 + export function validateMain<V>(v: V) { 30 + return validate<Main & V>(v, id, hashMain) 31 + }
+32
src/__generated__/lexicons/types/pub/leaflet/blocks/code.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'pub.leaflet.blocks.code' 16 + 17 + export interface Main { 18 + $type?: 'pub.leaflet.blocks.code' 19 + plaintext: string 20 + language?: string 21 + syntaxHighlightingTheme?: string 22 + } 23 + 24 + const hashMain = 'main' 25 + 26 + export function isMain<V>(v: V) { 27 + return is$typed(v, id, hashMain) 28 + } 29 + 30 + export function validateMain<V>(v: V) { 31 + return validate<Main & V>(v, id, hashMain) 32 + }
+33
src/__generated__/lexicons/types/pub/leaflet/blocks/header.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + import type * as PubLeafletRichtextFacet from '../richtext/facet.js' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'pub.leaflet.blocks.header' 17 + 18 + export interface Main { 19 + $type?: 'pub.leaflet.blocks.header' 20 + level?: number 21 + plaintext: string 22 + facets?: PubLeafletRichtextFacet.Main[] 23 + } 24 + 25 + const hashMain = 'main' 26 + 27 + export function isMain<V>(v: V) { 28 + return is$typed(v, id, hashMain) 29 + } 30 + 31 + export function validateMain<V>(v: V) { 32 + return validate<Main & V>(v, id, hashMain) 33 + }
+49
src/__generated__/lexicons/types/pub/leaflet/blocks/image.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'pub.leaflet.blocks.image' 16 + 17 + export interface Main { 18 + $type?: 'pub.leaflet.blocks.image' 19 + image: BlobRef 20 + /** Alt text description of the image, for accessibility. */ 21 + alt?: string 22 + aspectRatio: AspectRatio 23 + } 24 + 25 + const hashMain = 'main' 26 + 27 + export function isMain<V>(v: V) { 28 + return is$typed(v, id, hashMain) 29 + } 30 + 31 + export function validateMain<V>(v: V) { 32 + return validate<Main & V>(v, id, hashMain) 33 + } 34 + 35 + export interface AspectRatio { 36 + $type?: 'pub.leaflet.blocks.image#aspectRatio' 37 + width: number 38 + height: number 39 + } 40 + 41 + const hashAspectRatio = 'aspectRatio' 42 + 43 + export function isAspectRatio<V>(v: V) { 44 + return is$typed(v, id, hashAspectRatio) 45 + } 46 + 47 + export function validateAspectRatio<V>(v: V) { 48 + return validate<AspectRatio & V>(v, id, hashAspectRatio) 49 + }
+30
src/__generated__/lexicons/types/pub/leaflet/blocks/math.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'pub.leaflet.blocks.math' 16 + 17 + export interface Main { 18 + $type?: 'pub.leaflet.blocks.math' 19 + tex: string 20 + } 21 + 22 + const hashMain = 'main' 23 + 24 + export function isMain<V>(v: V) { 25 + return is$typed(v, id, hashMain) 26 + } 27 + 28 + export function validateMain<V>(v: V) { 29 + return validate<Main & V>(v, id, hashMain) 30 + }
+32
src/__generated__/lexicons/types/pub/leaflet/blocks/text.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + import type * as PubLeafletRichtextFacet from '../richtext/facet.js' 13 + 14 + const is$typed = _is$typed, 15 + validate = _validate 16 + const id = 'pub.leaflet.blocks.text' 17 + 18 + export interface Main { 19 + $type?: 'pub.leaflet.blocks.text' 20 + plaintext: string 21 + facets?: PubLeafletRichtextFacet.Main[] 22 + } 23 + 24 + const hashMain = 'main' 25 + 26 + export function isMain<V>(v: V) { 27 + return is$typed(v, id, hashMain) 28 + } 29 + 30 + export function validateMain<V>(v: V) { 31 + return validate<Main & V>(v, id, hashMain) 32 + }
+53
src/__generated__/lexicons/types/pub/leaflet/blocks/unorderedList.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + import type * as PubLeafletBlocksText from './text.js' 13 + import type * as PubLeafletBlocksHeader from './header.js' 14 + import type * as PubLeafletBlocksImage from './image.js' 15 + 16 + const is$typed = _is$typed, 17 + validate = _validate 18 + const id = 'pub.leaflet.blocks.unorderedList' 19 + 20 + export interface Main { 21 + $type?: 'pub.leaflet.blocks.unorderedList' 22 + children: ListItem[] 23 + } 24 + 25 + const hashMain = 'main' 26 + 27 + export function isMain<V>(v: V) { 28 + return is$typed(v, id, hashMain) 29 + } 30 + 31 + export function validateMain<V>(v: V) { 32 + return validate<Main & V>(v, id, hashMain) 33 + } 34 + 35 + export interface ListItem { 36 + $type?: 'pub.leaflet.blocks.unorderedList#listItem' 37 + content: 38 + | $Typed<PubLeafletBlocksText.Main> 39 + | $Typed<PubLeafletBlocksHeader.Main> 40 + | $Typed<PubLeafletBlocksImage.Main> 41 + | { $type: string } 42 + children?: ListItem[] 43 + } 44 + 45 + const hashListItem = 'listItem' 46 + 47 + export function isListItem<V>(v: V) { 48 + return is$typed(v, id, hashListItem) 49 + } 50 + 51 + export function validateListItem<V>(v: V) { 52 + return validate<ListItem & V>(v, id, hashListItem) 53 + }
+33
src/__generated__/lexicons/types/pub/leaflet/blocks/website.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'pub.leaflet.blocks.website' 16 + 17 + export interface Main { 18 + $type?: 'pub.leaflet.blocks.website' 19 + previewImage?: BlobRef 20 + title?: string 21 + description?: string 22 + src: string 23 + } 24 + 25 + const hashMain = 'main' 26 + 27 + export function isMain<V>(v: V) { 28 + return is$typed(v, id, hashMain) 29 + } 30 + 31 + export function validateMain<V>(v: V) { 32 + return validate<Main & V>(v, id, hashMain) 33 + }
+35
src/__generated__/lexicons/types/pub/leaflet/document.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../lexicons' 7 + import { type $Typed, is$typed as _is$typed, type OmitKey } from '../../../util' 8 + import type * as ComAtprotoRepoStrongRef from '../../com/atproto/repo/strongRef.js' 9 + import type * as PubLeafletPagesLinearDocument from './pages/linearDocument.js' 10 + 11 + const is$typed = _is$typed, 12 + validate = _validate 13 + const id = 'pub.leaflet.document' 14 + 15 + export interface Record { 16 + $type: 'pub.leaflet.document' 17 + title: string 18 + postRef?: ComAtprotoRepoStrongRef.Main 19 + description?: string 20 + publishedAt?: string 21 + publication: string 22 + author: string 23 + pages: ($Typed<PubLeafletPagesLinearDocument.Main> | { $type: string })[] 24 + [k: string]: unknown 25 + } 26 + 27 + const hashRecord = 'main' 28 + 29 + export function isRecord<V>(v: V) { 30 + return is$typed(v, id, hashRecord) 31 + } 32 + 33 + export function validateRecord<V>(v: V) { 34 + return validate<Record & V>(v, id, hashRecord, true) 35 + }
+69
src/__generated__/lexicons/types/pub/leaflet/pages/linearDocument.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + import type * as PubLeafletBlocksText from '../blocks/text.js' 13 + import type * as PubLeafletBlocksHeader from '../blocks/header.js' 14 + import type * as PubLeafletBlocksImage from '../blocks/image.js' 15 + import type * as PubLeafletBlocksUnorderedList from '../blocks/unorderedList.js' 16 + import type * as PubLeafletBlocksWebsite from '../blocks/website.js' 17 + import type * as PubLeafletBlocksMath from '../blocks/math.js' 18 + import type * as PubLeafletBlocksCode from '../blocks/code.js' 19 + 20 + const is$typed = _is$typed, 21 + validate = _validate 22 + const id = 'pub.leaflet.pages.linearDocument' 23 + 24 + export interface Main { 25 + $type?: 'pub.leaflet.pages.linearDocument' 26 + blocks?: Block[] 27 + } 28 + 29 + const hashMain = 'main' 30 + 31 + export function isMain<V>(v: V) { 32 + return is$typed(v, id, hashMain) 33 + } 34 + 35 + export function validateMain<V>(v: V) { 36 + return validate<Main & V>(v, id, hashMain) 37 + } 38 + 39 + export interface Block { 40 + $type?: 'pub.leaflet.pages.linearDocument#block' 41 + block: 42 + | $Typed<PubLeafletBlocksText.Main> 43 + | $Typed<PubLeafletBlocksHeader.Main> 44 + | $Typed<PubLeafletBlocksImage.Main> 45 + | $Typed<PubLeafletBlocksUnorderedList.Main> 46 + | $Typed<PubLeafletBlocksWebsite.Main> 47 + | $Typed<PubLeafletBlocksMath.Main> 48 + | $Typed<PubLeafletBlocksCode.Main> 49 + | { $type: string } 50 + alignment?: 51 + | 'lex:pub.leaflet.pages.linearDocument#textAlignLeft' 52 + | 'lex:pub.leaflet.pages.linearDocument#textAlignCenter' 53 + | 'lex:pub.leaflet.pages.linearDocument#textAlignRight' 54 + | (string & {}) 55 + } 56 + 57 + const hashBlock = 'block' 58 + 59 + export function isBlock<V>(v: V) { 60 + return is$typed(v, id, hashBlock) 61 + } 62 + 63 + export function validateBlock<V>(v: V) { 64 + return validate<Block & V>(v, id, hashBlock) 65 + } 66 + 67 + export const TEXTALIGNLEFT = `${id}#textAlignLeft` 68 + export const TEXTALIGNCENTER = `${id}#textAlignCenter` 69 + export const TEXTALIGNRIGHT = `${id}#textAlignRight`
+181
src/__generated__/lexicons/types/pub/leaflet/richtext/facet.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + import { type ValidationResult, BlobRef } from '@atproto/lexicon' 5 + import { CID } from 'multiformats/cid' 6 + import { validate as _validate } from '../../../../lexicons' 7 + import { 8 + type $Typed, 9 + is$typed as _is$typed, 10 + type OmitKey, 11 + } from '../../../../util' 12 + 13 + const is$typed = _is$typed, 14 + validate = _validate 15 + const id = 'pub.leaflet.richtext.facet' 16 + 17 + /** Annotation of a sub-string within rich text. */ 18 + export interface Main { 19 + $type?: 'pub.leaflet.richtext.facet' 20 + index: ByteSlice 21 + features: ( 22 + | $Typed<Link> 23 + | $Typed<Code> 24 + | $Typed<Highlight> 25 + | $Typed<Underline> 26 + | $Typed<Strikethrough> 27 + | $Typed<Id> 28 + | $Typed<Bold> 29 + | $Typed<Italic> 30 + | { $type: string } 31 + )[] 32 + } 33 + 34 + const hashMain = 'main' 35 + 36 + export function isMain<V>(v: V) { 37 + return is$typed(v, id, hashMain) 38 + } 39 + 40 + export function validateMain<V>(v: V) { 41 + return validate<Main & V>(v, id, hashMain) 42 + } 43 + 44 + /** 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. */ 45 + export interface ByteSlice { 46 + $type?: 'pub.leaflet.richtext.facet#byteSlice' 47 + byteStart: number 48 + byteEnd: number 49 + } 50 + 51 + const hashByteSlice = 'byteSlice' 52 + 53 + export function isByteSlice<V>(v: V) { 54 + return is$typed(v, id, hashByteSlice) 55 + } 56 + 57 + export function validateByteSlice<V>(v: V) { 58 + return validate<ByteSlice & V>(v, id, hashByteSlice) 59 + } 60 + 61 + /** Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. */ 62 + export interface Link { 63 + $type?: 'pub.leaflet.richtext.facet#link' 64 + uri: string 65 + } 66 + 67 + const hashLink = 'link' 68 + 69 + export function isLink<V>(v: V) { 70 + return is$typed(v, id, hashLink) 71 + } 72 + 73 + export function validateLink<V>(v: V) { 74 + return validate<Link & V>(v, id, hashLink) 75 + } 76 + 77 + /** Facet feature for inline code. */ 78 + export interface Code { 79 + $type?: 'pub.leaflet.richtext.facet#code' 80 + } 81 + 82 + const hashCode = 'code' 83 + 84 + export function isCode<V>(v: V) { 85 + return is$typed(v, id, hashCode) 86 + } 87 + 88 + export function validateCode<V>(v: V) { 89 + return validate<Code & V>(v, id, hashCode) 90 + } 91 + 92 + /** Facet feature for highlighted text. */ 93 + export interface Highlight { 94 + $type?: 'pub.leaflet.richtext.facet#highlight' 95 + } 96 + 97 + const hashHighlight = 'highlight' 98 + 99 + export function isHighlight<V>(v: V) { 100 + return is$typed(v, id, hashHighlight) 101 + } 102 + 103 + export function validateHighlight<V>(v: V) { 104 + return validate<Highlight & V>(v, id, hashHighlight) 105 + } 106 + 107 + /** Facet feature for underline markup */ 108 + export interface Underline { 109 + $type?: 'pub.leaflet.richtext.facet#underline' 110 + } 111 + 112 + const hashUnderline = 'underline' 113 + 114 + export function isUnderline<V>(v: V) { 115 + return is$typed(v, id, hashUnderline) 116 + } 117 + 118 + export function validateUnderline<V>(v: V) { 119 + return validate<Underline & V>(v, id, hashUnderline) 120 + } 121 + 122 + /** Facet feature for strikethrough markup */ 123 + export interface Strikethrough { 124 + $type?: 'pub.leaflet.richtext.facet#strikethrough' 125 + } 126 + 127 + const hashStrikethrough = 'strikethrough' 128 + 129 + export function isStrikethrough<V>(v: V) { 130 + return is$typed(v, id, hashStrikethrough) 131 + } 132 + 133 + export function validateStrikethrough<V>(v: V) { 134 + return validate<Strikethrough & V>(v, id, hashStrikethrough) 135 + } 136 + 137 + /** Facet feature for an identifier. Used for linking to a segment */ 138 + export interface Id { 139 + $type?: 'pub.leaflet.richtext.facet#id' 140 + id?: string 141 + } 142 + 143 + const hashId = 'id' 144 + 145 + export function isId<V>(v: V) { 146 + return is$typed(v, id, hashId) 147 + } 148 + 149 + export function validateId<V>(v: V) { 150 + return validate<Id & V>(v, id, hashId) 151 + } 152 + 153 + /** Facet feature for bold text */ 154 + export interface Bold { 155 + $type?: 'pub.leaflet.richtext.facet#bold' 156 + } 157 + 158 + const hashBold = 'bold' 159 + 160 + export function isBold<V>(v: V) { 161 + return is$typed(v, id, hashBold) 162 + } 163 + 164 + export function validateBold<V>(v: V) { 165 + return validate<Bold & V>(v, id, hashBold) 166 + } 167 + 168 + /** Facet feature for italic text */ 169 + export interface Italic { 170 + $type?: 'pub.leaflet.richtext.facet#italic' 171 + } 172 + 173 + const hashItalic = 'italic' 174 + 175 + export function isItalic<V>(v: V) { 176 + return is$typed(v, id, hashItalic) 177 + } 178 + 179 + export function validateItalic<V>(v: V) { 180 + return validate<Italic & V>(v, id, hashItalic) 181 + }
+82
src/__generated__/lexicons/util.ts
··· 1 + /** 2 + * GENERATED CODE - DO NOT MODIFY 3 + */ 4 + 5 + import { type ValidationResult } from '@atproto/lexicon' 6 + 7 + export type OmitKey<T, K extends keyof T> = { 8 + [K2 in keyof T as K2 extends K ? never : K2]: T[K2] 9 + } 10 + 11 + export type $Typed<V, T extends string = string> = V & { $type: T } 12 + export type Un$Typed<V extends { $type?: string }> = OmitKey<V, '$type'> 13 + 14 + export type $Type<Id extends string, Hash extends string> = Hash extends 'main' 15 + ? Id 16 + : `${Id}#${Hash}` 17 + 18 + function isObject<V>(v: V): v is V & object { 19 + return v != null && typeof v === 'object' 20 + } 21 + 22 + function is$type<Id extends string, Hash extends string>( 23 + $type: unknown, 24 + id: Id, 25 + hash: Hash, 26 + ): $type is $Type<Id, Hash> { 27 + return hash === 'main' 28 + ? $type === id 29 + : // $type === `${id}#${hash}` 30 + typeof $type === 'string' && 31 + $type.length === id.length + 1 + hash.length && 32 + $type.charCodeAt(id.length) === 35 /* '#' */ && 33 + $type.startsWith(id) && 34 + $type.endsWith(hash) 35 + } 36 + 37 + export type $TypedObject< 38 + V, 39 + Id extends string, 40 + Hash extends string, 41 + > = V extends { 42 + $type: $Type<Id, Hash> 43 + } 44 + ? V 45 + : V extends { $type?: string } 46 + ? V extends { $type?: infer T extends $Type<Id, Hash> } 47 + ? V & { $type: T } 48 + : never 49 + : V & { $type: $Type<Id, Hash> } 50 + 51 + export function is$typed<V, Id extends string, Hash extends string>( 52 + v: V, 53 + id: Id, 54 + hash: Hash, 55 + ): v is $TypedObject<V, Id, Hash> { 56 + return isObject(v) && '$type' in v && is$type(v.$type, id, hash) 57 + } 58 + 59 + export function maybe$typed<V, Id extends string, Hash extends string>( 60 + v: V, 61 + id: Id, 62 + hash: Hash, 63 + ): v is V & object & { $type?: $Type<Id, Hash> } { 64 + return ( 65 + isObject(v) && 66 + ('$type' in v ? v.$type === undefined || is$type(v.$type, id, hash) : true) 67 + ) 68 + } 69 + 70 + export type Validator<R = unknown> = (v: unknown) => ValidationResult<R> 71 + export type ValidatorParam<V extends Validator> = 72 + V extends Validator<infer R> ? R : never 73 + 74 + /** 75 + * Utility function that allows to convert a "validate*" utility function into a 76 + * type predicate. 77 + */ 78 + export function asPredicate<V extends Validator>(validate: V) { 79 + return function <T>(v: T): v is T & ValidatorParam<V> { 80 + return validate(v).success 81 + } 82 + }
-8
src/leaflet-live-loader.ts
··· 27 27 } 28 28 } 29 29 30 - /** 31 - * Flow: 32 - * - Check for valid handle or did [done] 33 - * - Resolve PDS url from handle or did [done, thanks Phil!] 34 - * - Fetch leaflet documents [done] 35 - * - Find out how to use leaflet types here 36 - */ 37 - 38 30 export function leafletLiveLoader( 39 31 options: LeafletLoaderOptions, 40 32 ): LiveLoader<
+7
src/types.ts
··· 1 1 import type { Agent } from "@atproto/api"; 2 + import type { PubLeafletRichtextFacet } from "./__generated__/lexicons/index.js"; 2 3 3 4 export interface LeafletLoaderOptions { 4 5 /** ··· 58 59 agent: Agent; 59 60 id: string; 60 61 } 62 + 63 + export interface Facet extends PubLeafletRichtextFacet.Main {} 64 + export interface RichTextSegment { 65 + text: string; 66 + facet?: Exclude<Facet["features"], { $type: string }>; 67 + }
+159
src/utils.ts
··· 1 1 import type { 2 + Facet, 2 3 GetLeafletDocumentsParams, 3 4 GetSingleLeafletDocumentParams, 4 5 LeafletDocumentRecord, 5 6 LeafletDocumentView, 6 7 MiniDoc, 8 + RichTextSegment, 7 9 } from "./types.js"; 8 10 import { LiveLoaderError } from "./leaflet-live-loader.js"; 11 + import { UnicodeString } from "@atproto/api"; 12 + import sanitizeHTML from "sanitize-html"; 13 + import { 14 + PubLeafletBlocksHeader, 15 + PubLeafletBlocksText, 16 + type PubLeafletDocument, 17 + PubLeafletPagesLinearDocument, 18 + PubLeafletRichtextFacet, 19 + } from "./__generated__/lexicons/index.js"; 9 20 10 21 export function uriToRkey(uri: string): string { 11 22 const rkey = uri.split("/").pop(); ··· 100 111 publishedAt: value.publishedAt, 101 112 }; 102 113 } 114 + 115 + export function leafletBlocksToHTML(record: { 116 + id: string; 117 + uri: string; 118 + cid: string; 119 + value: PubLeafletDocument.Record; 120 + }) { 121 + let html = ""; 122 + const firstPage = record.value.pages[0]; 123 + let blocks: PubLeafletPagesLinearDocument.Block[] = []; 124 + if (PubLeafletPagesLinearDocument.isMain(firstPage)) { 125 + blocks = firstPage.blocks || []; 126 + } 127 + 128 + for (const block of blocks) { 129 + if (PubLeafletBlocksText.isMain(block.block)) { 130 + const rt = new RichText({ 131 + text: block.block.plaintext, 132 + facets: block.block.facets || [], 133 + }); 134 + const children = []; 135 + for (const segment of rt.segments()) { 136 + const link = segment.facet?.find(PubLeafletRichtextFacet.isLink); 137 + const isBold = segment.facet?.find(PubLeafletRichtextFacet.isBold); 138 + const isCode = segment.facet?.find(PubLeafletRichtextFacet.isCode); 139 + const isStrikethrough = segment.facet?.find( 140 + PubLeafletRichtextFacet.isStrikethrough, 141 + ); 142 + const isUnderline = segment.facet?.find( 143 + PubLeafletRichtextFacet.isUnderline, 144 + ); 145 + const isItalic = segment.facet?.find(PubLeafletRichtextFacet.isItalic); 146 + if (isCode) { 147 + children.push(` <code> 148 + ${segment.text} 149 + </code>`); 150 + } else if (link) { 151 + children.push( 152 + ` <a 153 + href="${link.uri}" 154 + target="_blank" 155 + > 156 + ${segment.text} 157 + </a>`, 158 + ); 159 + } else if (isBold) { 160 + children.push(`<b>${segment.text}</b>`); 161 + } else if (isStrikethrough) { 162 + children.push(`<s>${segment.text}</s>`); 163 + } else if (isUnderline) { 164 + children.push( 165 + `<span style="text-decoration:underline;">${segment.text}</span>`, 166 + ); 167 + } else if (isItalic) { 168 + children.push(`<i>${segment.text}</i>`); 169 + } else { 170 + children.push( 171 + ` 172 + ${segment.text} 173 + `, 174 + ); 175 + } 176 + } 177 + html += `<p>${children.join("\n")}</p>`; 178 + } 179 + 180 + if (PubLeafletBlocksHeader.isMain(block.block)) { 181 + if (block.block.level === 1) { 182 + html += `<h2>${block.block.plaintext}</h2>`; 183 + } 184 + } 185 + if (PubLeafletBlocksHeader.isMain(block.block)) { 186 + if (block.block.level === 2) { 187 + html += `<h3>${block.block.plaintext}</h3>`; 188 + } 189 + } 190 + if (PubLeafletBlocksHeader.isMain(block.block)) { 191 + if (block.block.level === 3) { 192 + html += `<h4>${block.block.plaintext}</h4>`; 193 + } 194 + } 195 + if (PubLeafletBlocksHeader.isMain(block.block)) { 196 + if (!block.block.level) { 197 + html += `<h6>${block.block.plaintext}</h6>`; 198 + } 199 + } 200 + } 201 + 202 + return sanitizeHTML(html); 203 + } 204 + 205 + export class RichText { 206 + unicodeText: UnicodeString; 207 + facets?: Facet[]; 208 + 209 + constructor(props: { text: string; facets: Facet[] }) { 210 + this.unicodeText = new UnicodeString(props.text); 211 + this.facets = props.facets; 212 + if (this.facets) { 213 + this.facets = this.facets 214 + .filter((facet) => facet.index.byteStart <= facet.index.byteEnd) 215 + .sort((a, b) => a.index.byteStart - b.index.byteStart); 216 + } 217 + } 218 + 219 + *segments(): Generator<RichTextSegment, void, void> { 220 + const facets = this.facets || []; 221 + if (!facets.length) { 222 + yield { text: this.unicodeText.utf16 }; 223 + return; 224 + } 225 + 226 + let textCursor = 0; 227 + let facetCursor = 0; 228 + do { 229 + const currFacet = facets[facetCursor]; 230 + if (currFacet) { 231 + if (textCursor < currFacet.index.byteStart) { 232 + yield { 233 + text: this.unicodeText.slice(textCursor, currFacet.index.byteStart), 234 + }; 235 + } else if (textCursor > currFacet.index.byteStart) { 236 + facetCursor++; 237 + continue; 238 + } 239 + if (currFacet.index.byteStart < currFacet.index.byteEnd) { 240 + const subtext = this.unicodeText.slice( 241 + currFacet.index.byteStart, 242 + currFacet.index.byteEnd, 243 + ); 244 + if (!subtext.trim()) { 245 + // dont empty string entities 246 + yield { text: subtext }; 247 + } else { 248 + yield { text: subtext, facet: currFacet.features }; 249 + } 250 + } 251 + textCursor = currFacet.index.byteEnd; 252 + facetCursor++; 253 + } 254 + } while (facetCursor < facets.length); 255 + if (textCursor < this.unicodeText.length) { 256 + yield { 257 + text: this.unicodeText.slice(textCursor, this.unicodeText.length), 258 + }; 259 + } 260 + } 261 + }