WIP Hello world
This commit is contained in:
commit
b618c6a1a1
12
deno.json
Normal file
12
deno.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"tasks": {
|
||||||
|
"dev": "deno run --allow-net --deny-env --watch main.ts"
|
||||||
|
},
|
||||||
|
"imports": {
|
||||||
|
"@deno/gfm": "jsr:@deno/gfm@^0.9.0",
|
||||||
|
"@nostr/tools": "jsr:@nostr/tools@^2.3.1",
|
||||||
|
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.36.1",
|
||||||
|
"@oak/oak": "jsr:@oak/oak@^17.1.0",
|
||||||
|
"@std/assert": "jsr:@std/assert@1"
|
||||||
|
}
|
||||||
|
}
|
387
deno.lock
generated
Normal file
387
deno.lock
generated
Normal file
@ -0,0 +1,387 @@
|
|||||||
|
{
|
||||||
|
"version": "4",
|
||||||
|
"specifiers": {
|
||||||
|
"jsr:@deno/gfm@0.9": "0.9.0",
|
||||||
|
"jsr:@denosaurs/emoji@0.3": "0.3.1",
|
||||||
|
"jsr:@nostr/tools@^2.3.1": "2.3.1",
|
||||||
|
"jsr:@nostrify/nostrify@~0.36.1": "0.36.1",
|
||||||
|
"jsr:@nostrify/types@0.35": "0.35.0",
|
||||||
|
"jsr:@oak/commons@1": "1.0.0",
|
||||||
|
"jsr:@oak/oak@^17.1.0": "17.1.0",
|
||||||
|
"jsr:@std/assert@1": "1.0.6",
|
||||||
|
"jsr:@std/bytes@1": "1.0.2",
|
||||||
|
"jsr:@std/bytes@^1.0.2": "1.0.2",
|
||||||
|
"jsr:@std/crypto@1": "1.0.3",
|
||||||
|
"jsr:@std/encoding@1": "1.0.5",
|
||||||
|
"jsr:@std/encoding@^1.0.5": "1.0.5",
|
||||||
|
"jsr:@std/encoding@~0.224.1": "0.224.3",
|
||||||
|
"jsr:@std/http@1": "1.0.8",
|
||||||
|
"jsr:@std/internal@^1.0.4": "1.0.4",
|
||||||
|
"jsr:@std/io@0.224": "0.224.9",
|
||||||
|
"jsr:@std/media-types@1": "1.0.3",
|
||||||
|
"jsr:@std/path@1": "1.0.6",
|
||||||
|
"npm:@noble/ciphers@~0.5.1": "0.5.3",
|
||||||
|
"npm:@noble/curves@1.2.0": "1.2.0",
|
||||||
|
"npm:@noble/hashes@1.3.1": "1.3.1",
|
||||||
|
"npm:@scure/base@1.1.1": "1.1.1",
|
||||||
|
"npm:@scure/bip32@^1.4.0": "1.4.0",
|
||||||
|
"npm:@scure/bip39@^1.3.0": "1.3.0",
|
||||||
|
"npm:github-slugger@2": "2.0.0",
|
||||||
|
"npm:he@^1.2.0": "1.2.0",
|
||||||
|
"npm:katex@0.16": "0.16.11",
|
||||||
|
"npm:lru-cache@^10.2.0": "10.2.2",
|
||||||
|
"npm:marked-alert@2": "2.1.0_marked@12.0.2",
|
||||||
|
"npm:marked-footnote@^1.2.0": "1.2.4_marked@12.0.2",
|
||||||
|
"npm:marked-gfm-heading-id@^3.1.0": "3.2.0_marked@12.0.2",
|
||||||
|
"npm:marked@12": "12.0.2",
|
||||||
|
"npm:nostr-tools@^2.7.0": "2.7.0",
|
||||||
|
"npm:path-to-regexp@*": "6.2.1",
|
||||||
|
"npm:path-to-regexp@6.2.1": "6.2.1",
|
||||||
|
"npm:prismjs@^1.29.0": "1.29.0",
|
||||||
|
"npm:sanitize-html@^2.11.0": "2.13.1",
|
||||||
|
"npm:websocket-ts@^2.1.5": "2.1.5",
|
||||||
|
"npm:zod@^3.23.8": "3.23.8"
|
||||||
|
},
|
||||||
|
"jsr": {
|
||||||
|
"@deno/gfm@0.9.0": {
|
||||||
|
"integrity": "9002dbdb6e382e247509edfeae3afdb9232f5ca98a8210ef186d42084e9ded30",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@denosaurs/emoji",
|
||||||
|
"npm:github-slugger",
|
||||||
|
"npm:he",
|
||||||
|
"npm:katex",
|
||||||
|
"npm:marked",
|
||||||
|
"npm:marked-alert",
|
||||||
|
"npm:marked-footnote",
|
||||||
|
"npm:marked-gfm-heading-id",
|
||||||
|
"npm:prismjs",
|
||||||
|
"npm:sanitize-html"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@denosaurs/emoji@0.3.1": {
|
||||||
|
"integrity": "b0aed5f55dec99e83da7c9637fe0a36d1d6252b7c99deaaa3fc5dea3fcf3da8b"
|
||||||
|
},
|
||||||
|
"@nostr/tools@2.3.1": {
|
||||||
|
"integrity": "af01dc45cb28784c584d7a0699707196f397bcc53946efa582a01b11ddde4d61",
|
||||||
|
"dependencies": [
|
||||||
|
"npm:@noble/ciphers",
|
||||||
|
"npm:@noble/curves",
|
||||||
|
"npm:@noble/hashes",
|
||||||
|
"npm:@scure/base"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@nostrify/nostrify@0.36.1": {
|
||||||
|
"integrity": "f76c803c0bda5df1c172f25d2313980344b0431df2a973ab3e1dd61e9e7b4b1a",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@nostrify/types",
|
||||||
|
"jsr:@std/encoding@~0.224.1",
|
||||||
|
"npm:@scure/bip32",
|
||||||
|
"npm:@scure/bip39",
|
||||||
|
"npm:lru-cache",
|
||||||
|
"npm:nostr-tools",
|
||||||
|
"npm:websocket-ts",
|
||||||
|
"npm:zod"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@nostrify/types@0.35.0": {
|
||||||
|
"integrity": "b8d515563d467072694557d5626fa1600f74e83197eef45dd86a9a99c64f7fe6"
|
||||||
|
},
|
||||||
|
"@oak/commons@1.0.0": {
|
||||||
|
"integrity": "49805b55603c3627a9d6235c0655aa2b6222d3036b3a13ff0380c16368f607ac",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/assert",
|
||||||
|
"jsr:@std/bytes@1",
|
||||||
|
"jsr:@std/crypto",
|
||||||
|
"jsr:@std/encoding@1",
|
||||||
|
"jsr:@std/http",
|
||||||
|
"jsr:@std/media-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@oak/oak@17.1.0": {
|
||||||
|
"integrity": "14ffb400c3c268bdc7b3a838664fab782b4ed35bb0dfe7669013c95bb12a9503",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@oak/commons",
|
||||||
|
"jsr:@std/assert",
|
||||||
|
"jsr:@std/bytes@1",
|
||||||
|
"jsr:@std/crypto",
|
||||||
|
"jsr:@std/http",
|
||||||
|
"jsr:@std/io",
|
||||||
|
"jsr:@std/media-types",
|
||||||
|
"jsr:@std/path",
|
||||||
|
"npm:path-to-regexp@6.2.1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/assert@1.0.6": {
|
||||||
|
"integrity": "1904c05806a25d94fe791d6d883b685c9e2dcd60e4f9fc30f4fc5cf010c72207",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/internal"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/bytes@1.0.2": {
|
||||||
|
"integrity": "fbdee322bbd8c599a6af186a1603b3355e59a5fb1baa139f8f4c3c9a1b3e3d57"
|
||||||
|
},
|
||||||
|
"@std/crypto@1.0.3": {
|
||||||
|
"integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f"
|
||||||
|
},
|
||||||
|
"@std/encoding@0.224.3": {
|
||||||
|
"integrity": "5e861b6d81be5359fad4155e591acf17c0207b595112d1840998bb9f476dbdaf"
|
||||||
|
},
|
||||||
|
"@std/encoding@1.0.5": {
|
||||||
|
"integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04"
|
||||||
|
},
|
||||||
|
"@std/http@1.0.8": {
|
||||||
|
"integrity": "6ea1b2e8d33929967754a3b6d6c6f399ad6647d7bbb5a466c1eaf9b294a6ebcd",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/encoding@^1.0.5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/internal@1.0.4": {
|
||||||
|
"integrity": "62e8e4911527e5e4f307741a795c0b0a9e6958d0b3790716ae71ce085f755422"
|
||||||
|
},
|
||||||
|
"@std/io@0.224.9": {
|
||||||
|
"integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3",
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@std/bytes@^1.0.2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@std/media-types@1.0.3": {
|
||||||
|
"integrity": "b12d30a7852f7578f4d210622df713bbfd1cbdd9b4ec2eaf5c1845ab70bab159"
|
||||||
|
},
|
||||||
|
"@std/path@1.0.6": {
|
||||||
|
"integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"@noble/ciphers@0.5.3": {
|
||||||
|
"integrity": "sha512-B0+6IIHiqEs3BPMT0hcRmHvEj2QHOLu+uwt+tqDDeVd0oyVzh7BPrDcPjRnV1PV/5LaknXJJQvOuRGR0zQJz+w=="
|
||||||
|
},
|
||||||
|
"@noble/curves@1.1.0": {
|
||||||
|
"integrity": "sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/hashes@1.3.1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@noble/curves@1.2.0": {
|
||||||
|
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/hashes@1.3.2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@noble/curves@1.4.0": {
|
||||||
|
"integrity": "sha512-p+4cb332SFCrReJkCYe8Xzm0OWi4Jji5jVdIZRL/PmacmDkFNw6MrrV+gGpiPxLHbV+zKFRywUWbaseT+tZRXg==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/hashes@1.4.0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@noble/hashes@1.3.1": {
|
||||||
|
"integrity": "sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA=="
|
||||||
|
},
|
||||||
|
"@noble/hashes@1.3.2": {
|
||||||
|
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="
|
||||||
|
},
|
||||||
|
"@noble/hashes@1.4.0": {
|
||||||
|
"integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg=="
|
||||||
|
},
|
||||||
|
"@scure/base@1.1.1": {
|
||||||
|
"integrity": "sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA=="
|
||||||
|
},
|
||||||
|
"@scure/base@1.1.7": {
|
||||||
|
"integrity": "sha512-PPNYBslrLNNUQ/Yad37MHYsNQtK67EhWb6WtSvNLLPo7SdVZgkUjD6Dg+5On7zNwmskf8OX7I7Nx5oN+MIWE0g=="
|
||||||
|
},
|
||||||
|
"@scure/bip32@1.3.1": {
|
||||||
|
"integrity": "sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/curves@1.1.0",
|
||||||
|
"@noble/hashes@1.3.2",
|
||||||
|
"@scure/base@1.1.7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@scure/bip32@1.4.0": {
|
||||||
|
"integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/curves@1.4.0",
|
||||||
|
"@noble/hashes@1.4.0",
|
||||||
|
"@scure/base@1.1.7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@scure/bip39@1.2.1": {
|
||||||
|
"integrity": "sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/hashes@1.3.2",
|
||||||
|
"@scure/base@1.1.7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"@scure/bip39@1.3.0": {
|
||||||
|
"integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/hashes@1.4.0",
|
||||||
|
"@scure/base@1.1.7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"commander@8.3.0": {
|
||||||
|
"integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="
|
||||||
|
},
|
||||||
|
"deepmerge@4.3.1": {
|
||||||
|
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="
|
||||||
|
},
|
||||||
|
"dom-serializer@2.0.0": {
|
||||||
|
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||||
|
"dependencies": [
|
||||||
|
"domelementtype",
|
||||||
|
"domhandler",
|
||||||
|
"entities"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"domelementtype@2.3.0": {
|
||||||
|
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
|
||||||
|
},
|
||||||
|
"domhandler@5.0.3": {
|
||||||
|
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||||
|
"dependencies": [
|
||||||
|
"domelementtype"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"domutils@3.1.0": {
|
||||||
|
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
|
||||||
|
"dependencies": [
|
||||||
|
"dom-serializer",
|
||||||
|
"domelementtype",
|
||||||
|
"domhandler"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"entities@4.5.0": {
|
||||||
|
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
|
||||||
|
},
|
||||||
|
"escape-string-regexp@4.0.0": {
|
||||||
|
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||||
|
},
|
||||||
|
"github-slugger@2.0.0": {
|
||||||
|
"integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
|
||||||
|
},
|
||||||
|
"he@1.2.0": {
|
||||||
|
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="
|
||||||
|
},
|
||||||
|
"htmlparser2@8.0.2": {
|
||||||
|
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
||||||
|
"dependencies": [
|
||||||
|
"domelementtype",
|
||||||
|
"domhandler",
|
||||||
|
"domutils",
|
||||||
|
"entities"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"is-plain-object@5.0.0": {
|
||||||
|
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
|
||||||
|
},
|
||||||
|
"katex@0.16.11": {
|
||||||
|
"integrity": "sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"commander"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lru-cache@10.2.2": {
|
||||||
|
"integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ=="
|
||||||
|
},
|
||||||
|
"marked-alert@2.1.0_marked@12.0.2": {
|
||||||
|
"integrity": "sha512-X95Z8PCDgWa0bBfM70GxZG3LD/leUrhXc3cx3w1eFExBhswd1oXn/S4S+9H8ypPdCY7okREb4dItUOc+VJq4jQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"marked"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"marked-footnote@1.2.4_marked@12.0.2": {
|
||||||
|
"integrity": "sha512-DB2Kl+wFh6YwZd70qABMY6WUkG1UuyqoNTFoDfGyG79Pz24neYtLBkB+45a7o72V7gkfvbC3CGzIYFobxfMT1Q==",
|
||||||
|
"dependencies": [
|
||||||
|
"marked"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"marked-gfm-heading-id@3.2.0_marked@12.0.2": {
|
||||||
|
"integrity": "sha512-Xfxpr5lXLDLY10XqzSCA9l2dDaiabQUgtYM9hw8yunyVsB/xYBRpiic6BOiY/EAJw1ik1eWr1ET1HKOAPZBhXg==",
|
||||||
|
"dependencies": [
|
||||||
|
"github-slugger",
|
||||||
|
"marked"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"marked@12.0.2": {
|
||||||
|
"integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="
|
||||||
|
},
|
||||||
|
"nanoid@3.3.7": {
|
||||||
|
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
|
||||||
|
},
|
||||||
|
"nostr-tools@2.7.0": {
|
||||||
|
"integrity": "sha512-jJoL2J1CBiKDxaXZww27nY/Wsuxzx7AULxmGKFce4sskDu1tohNyfnzYQ8BvDyvkstU8kNZUAXPL32tre33uig==",
|
||||||
|
"dependencies": [
|
||||||
|
"@noble/ciphers",
|
||||||
|
"@noble/curves@1.2.0",
|
||||||
|
"@noble/hashes@1.3.1",
|
||||||
|
"@scure/base@1.1.1",
|
||||||
|
"@scure/bip32@1.3.1",
|
||||||
|
"@scure/bip39@1.2.1",
|
||||||
|
"nostr-wasm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"nostr-wasm@0.1.0": {
|
||||||
|
"integrity": "sha512-78BTryCLcLYv96ONU8Ws3Q1JzjlAt+43pWQhIl86xZmWeegYCNLPml7yQ+gG3vR6V5h4XGj+TxO+SS5dsThQIA=="
|
||||||
|
},
|
||||||
|
"parse-srcset@1.0.2": {
|
||||||
|
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
|
||||||
|
},
|
||||||
|
"path-to-regexp@6.2.1": {
|
||||||
|
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
|
},
|
||||||
|
"picocolors@1.1.1": {
|
||||||
|
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||||
|
},
|
||||||
|
"postcss@8.4.47": {
|
||||||
|
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||||
|
"dependencies": [
|
||||||
|
"nanoid",
|
||||||
|
"picocolors",
|
||||||
|
"source-map-js"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"prismjs@1.29.0": {
|
||||||
|
"integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q=="
|
||||||
|
},
|
||||||
|
"sanitize-html@2.13.1": {
|
||||||
|
"integrity": "sha512-ZXtKq89oue4RP7abL9wp/9URJcqQNABB5GGJ2acW1sdO8JTVl92f4ygD7Yc9Ze09VAZhnt2zegeU0tbNsdcLYg==",
|
||||||
|
"dependencies": [
|
||||||
|
"deepmerge",
|
||||||
|
"escape-string-regexp",
|
||||||
|
"htmlparser2",
|
||||||
|
"is-plain-object",
|
||||||
|
"parse-srcset",
|
||||||
|
"postcss"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"source-map-js@1.2.1": {
|
||||||
|
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="
|
||||||
|
},
|
||||||
|
"websocket-ts@2.1.5": {
|
||||||
|
"integrity": "sha512-rCNl9w6Hsir1azFm/pbjBEFzLD/gi7Th5ZgOxMifB6STUfTSovYAzryWw0TRvSZ1+Qu1Z5Plw4z42UfTNA9idA=="
|
||||||
|
},
|
||||||
|
"zod@3.23.8": {
|
||||||
|
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"redirects": {
|
||||||
|
"https://esm.sh/preact/jsx-runtime": "https://esm.sh/preact@10.24.3/jsx-runtime"
|
||||||
|
},
|
||||||
|
"remote": {
|
||||||
|
"https://esm.sh/preact-render-to-string@5.2.6": "7de74b492ac57386231a0934edc459940ebeec07ee71ac4bf9b89b91ca6d1c0d",
|
||||||
|
"https://esm.sh/preact@10.24.3/jsx-runtime": "b9e4a84f55cb84ddb400600787de5b6a0ee66d879d8cf920dc0cdc94d00ae847",
|
||||||
|
"https://esm.sh/stable/preact@10.19.2/denonext/preact.mjs": "dc999b6432dc04d74ad7b692a8801f346294d815266dff915d0f222c120fd0b0",
|
||||||
|
"https://esm.sh/stable/preact@10.20.2/denonext/preact.mjs": "f418bc70c24b785703afb9d4dea8cdc1e315e43c8df620a0c52fd27ad9bd70eb",
|
||||||
|
"https://esm.sh/stable/preact@10.24.3/denonext/jsx-runtime.js": "562a3adc7f89394c5fc430323f2875e9ec954bf138572227e5a26f9b42a8d179",
|
||||||
|
"https://esm.sh/stable/preact@10.24.3/denonext/preact.mjs": "adda7b905b40f0bab844d3ee900378e59da2b16f0f8e716ba9a8d67c15b78c87",
|
||||||
|
"https://esm.sh/v135/preact-render-to-string@5.2.6/denonext/preact-render-to-string.mjs": "571ed1a39a0a503606419614ab6533e068891be3fa1c5397f44266e3104d59f2"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"dependencies": [
|
||||||
|
"jsr:@deno/gfm@0.9",
|
||||||
|
"jsr:@nostr/tools@^2.3.1",
|
||||||
|
"jsr:@nostrify/nostrify@~0.36.1",
|
||||||
|
"jsr:@oak/oak@^17.1.0",
|
||||||
|
"jsr:@std/assert@1"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
36
handlers/naddr.ts
Normal file
36
handlers/naddr.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { ctx } from "@oak/oak";
|
||||||
|
import { nip19 } from "@nostr/tools";
|
||||||
|
import { log } from "../log.ts";
|
||||||
|
import { articleHtml } from "../html.ts"
|
||||||
|
import {
|
||||||
|
fetchReplaceableEvent,
|
||||||
|
fetchProfileEvent
|
||||||
|
} from "../nostr.ts";
|
||||||
|
|
||||||
|
const naddrHandler = async function (ctx: ctx) {
|
||||||
|
const { request } = ctx;
|
||||||
|
const { path } = ctx.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const r = nip19.decode(path);
|
||||||
|
const articleEvent = await fetchReplaceableEvent(r.data.pubkey, r.data.identifier);
|
||||||
|
const profileEvent = await fetchProfileEvent(r.data.pubkey);
|
||||||
|
let profile;
|
||||||
|
|
||||||
|
if (articleEvent && profileEvent) {
|
||||||
|
const profile = JSON.parse(profileEvent.content);
|
||||||
|
const html = articleHtml(articleEvent, profile);
|
||||||
|
|
||||||
|
ctx.response.body = html;
|
||||||
|
} else {
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log(e, "yellow");
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default naddrHandler;
|
10
handlers/nprofile.ts
Normal file
10
handlers/nprofile.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { Context } from "@oak/oak";
|
||||||
|
|
||||||
|
const nprofileHandler = function (context: Context) {
|
||||||
|
const { request, response } = context;
|
||||||
|
const fullPath = request.url.pathname;
|
||||||
|
|
||||||
|
response.body = `You are viewing an nprofile with address: ${fullPath}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default nprofileHandler;
|
145
html.ts
Normal file
145
html.ts
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import { render as renderMarkdown } from "@deno/gfm";
|
||||||
|
import { log } from "./log.ts";
|
||||||
|
|
||||||
|
export function htmlLayout(title: string, body: string) {
|
||||||
|
return `
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>${title}</title>
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,400;0,700;0,900;1,400;1,700&display=swap" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: #f5f2eb;
|
||||||
|
color: #3b3a38;
|
||||||
|
font-size: 18px;
|
||||||
|
font-family: "Merriweather", serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.avatar {
|
||||||
|
height: 48px;
|
||||||
|
width: 48px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.anchor {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 2em 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2, h3, h4 {
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4 {
|
||||||
|
color: #191818;
|
||||||
|
}
|
||||||
|
|
||||||
|
p, pre, ul, ol, blockquote {
|
||||||
|
line-height: 1.6em;
|
||||||
|
margin-bottom: 1.6em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #023b77
|
||||||
|
}
|
||||||
|
|
||||||
|
a:visited {
|
||||||
|
color: #3b0277
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
font-size: 1rem;
|
||||||
|
background-color: #e8e3da;
|
||||||
|
color: #027739;
|
||||||
|
padding: 0.1em 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 0.6rem 1rem;
|
||||||
|
background-color: #333;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: block;
|
||||||
|
max-width: 728px;
|
||||||
|
margin: 12rem auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
main header {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main header h1 {
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.meta {
|
||||||
|
display: flex;
|
||||||
|
column-gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.meta .content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.meta .date {
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
${body}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function articleHtml(articleEvent: object, profile: object) {
|
||||||
|
const titleTag = articleEvent.tags.find(t => t[0] === "title");
|
||||||
|
const title = titleTag ? titleTag[1] : "Untitled";
|
||||||
|
const content = renderMarkdown(articleEvent.content);
|
||||||
|
const date = new Date(articleEvent.created_at * 1000);
|
||||||
|
const formattedDate = date.toLocaleDateString("en-US", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "long",
|
||||||
|
day: "numeric",
|
||||||
|
});
|
||||||
|
|
||||||
|
const body = `
|
||||||
|
<main>
|
||||||
|
<header>
|
||||||
|
<h1>${title}</h1>
|
||||||
|
<p class="meta">
|
||||||
|
<img class="avatar" src="${profile.picture}" alt="User Avatar" />
|
||||||
|
<span class="content">
|
||||||
|
<span class="name">${profile.name}</span>
|
||||||
|
<span class="date">${formattedDate}</span>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
${content}
|
||||||
|
</main>
|
||||||
|
`;
|
||||||
|
|
||||||
|
return htmlLayout(title, body);
|
||||||
|
}
|
7
log.ts
Normal file
7
log.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export function log(msg: string, color?: string) {
|
||||||
|
if (typeof color !== "undefined") {
|
||||||
|
console.debug(`%c${msg}`, `color: ${color}`);
|
||||||
|
} else {
|
||||||
|
console.debug(msg);
|
||||||
|
}
|
||||||
|
}
|
30
main.ts
Normal file
30
main.ts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import { Application, Router } from "@oak/oak";
|
||||||
|
import { log } from "./log.ts";
|
||||||
|
import naddrHandler from "./handlers/naddr.ts";
|
||||||
|
import nprofileHandler from "./handlers/nprofile.ts";
|
||||||
|
|
||||||
|
const router = new Router();
|
||||||
|
|
||||||
|
router.get("/:path", async (ctx: ctx) => {
|
||||||
|
const { path } = ctx.params;
|
||||||
|
|
||||||
|
if (path && path.startsWith("naddr")) {
|
||||||
|
await naddrHandler(ctx);
|
||||||
|
} else if (prefix && prefix.startsWith("nprofile")) {
|
||||||
|
await nprofileHandler(ctx);
|
||||||
|
} else {
|
||||||
|
ctx.response.status = 404;
|
||||||
|
ctx.response.body = "Not Found";
|
||||||
|
}
|
||||||
|
|
||||||
|
log(`${ctx.request.method} ${ctx.request.url} - ${ctx.response.status}`, "gray");
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = new Application();
|
||||||
|
app.use(router.routes());
|
||||||
|
app.use(router.allowedMethods());
|
||||||
|
|
||||||
|
const PORT = 8000;
|
||||||
|
app.listen({ port: PORT });
|
||||||
|
|
||||||
|
console.log(`App listening on http://localhost:${PORT}`)
|
6
main_test.ts
Normal file
6
main_test.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { assertEquals } from "@std/assert";
|
||||||
|
// import { add } from "./main.ts";
|
||||||
|
|
||||||
|
// Deno.test(function addTest() {
|
||||||
|
// assertEquals(add(2, 3), 5);
|
||||||
|
// });
|
24
nostr.ts
Normal file
24
nostr.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { NRelay1 } from "@nostrify/nostrify";
|
||||||
|
|
||||||
|
export const relay = new NRelay1("wss://nostr.kosmos.org");
|
||||||
|
|
||||||
|
export async function fetchReplaceableEvent(pubkey: string, identifier: string) {
|
||||||
|
const events = await relay.query([{
|
||||||
|
authors: [pubkey],
|
||||||
|
kinds: [30023],
|
||||||
|
"#d": [identifier],
|
||||||
|
limit: 1,
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return events.length > 0 ? events[0] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchProfileEvent(pubkey: string) {
|
||||||
|
const events = await relay.query([{
|
||||||
|
authors: [pubkey],
|
||||||
|
kinds: [0],
|
||||||
|
limit: 1,
|
||||||
|
}]);
|
||||||
|
|
||||||
|
return events.length > 0 ? events[0] : null;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user