Add option to download another nsite as a homepage

Replace homepage with simple welcome page
This commit is contained in:
hzrd149 2025-01-22 12:09:06 -06:00
parent c4eae33451
commit c84396ed62
19 changed files with 677 additions and 1399 deletions

View File

@ -0,0 +1,5 @@
---
"nsite-ts": minor
---
Replace homepage with simple welcome page

View File

@ -0,0 +1,5 @@
---
"nsite-ts": minor
---
Add option to download another nsite as a homepage

View File

@ -17,6 +17,13 @@ MAX_FILE_SIZE='2 MB'
# The cache folder for nginx
NGINX_CACHE_DIR='/var/nginx/cache'
# A nprofile pointer for an nsite to use as the default homepage
# Setting this will override anything in the ./public folder
NSITE_HOMEPAGE=""
# a local directory to download the homepage to
NSITE_HOMEPAGE_DIR="public"
# Screenshots require Puppeteer to be setup https://pptr.dev/troubleshooting#setting-up-chrome-linux-sandbox
ENABLE_SCREENSHOTS="false"
SCREENSHOTS_DIR="./screenshots"

View File

@ -33,6 +33,7 @@
"koa-static": "^5.0.0",
"mime": "^4.0.6",
"nostr-tools": "^2.10.4",
"nsite-cli": "^0.1.14",
"pac-proxy-agent": "^7.1.0",
"proxy-agent": "^6.5.0",
"puppeteer": "^23.11.1",

553
pnpm-lock.yaml generated
View File

@ -53,6 +53,9 @@ importers:
nostr-tools:
specifier: ^2.10.4
version: 2.10.4(typescript@5.7.3)
nsite-cli:
specifier: ^0.1.14
version: 0.1.14(@types/node@20.17.14)(typescript@5.7.3)
pac-proxy-agent:
specifier: ^7.1.0
version: 7.1.0
@ -214,6 +217,94 @@ packages:
'@gar/promisify@1.1.3':
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
'@inquirer/checkbox@4.0.6':
resolution: {integrity: sha512-PgP35JfmGjHU0LSXOyRew0zHuA9N6OJwOlos1fZ20b7j8ISeAdib3L+n0jIxBtX958UeEpte6xhG/gxJ5iUqMw==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/confirm@5.1.3':
resolution: {integrity: sha512-fuF9laMmHoOgWapF9h9hv6opA5WvmGFHsTYGCmuFxcghIhEhb3dN0CdQR4BUMqa2H506NCj8cGX4jwMsE4t6dA==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/core@10.1.4':
resolution: {integrity: sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w==}
engines: {node: '>=18'}
'@inquirer/core@3.1.2':
resolution: {integrity: sha512-lR2GaqBkp42Ew9BOAOqf2pSp+ymVES1qN8OC90WWh45yeoYLl0Ty1GyCxmkKqBJtq/+Ea1MF12AdFcZcpRNFsw==}
engines: {node: '>=14.18.0'}
'@inquirer/editor@4.2.3':
resolution: {integrity: sha512-S9KnIOJuTZpb9upeRSBBhoDZv7aSV3pG9TECrBj0f+ZsFwccz886hzKBrChGrXMJwd4NKY+pOA9Vy72uqnd6Eg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/expand@4.0.6':
resolution: {integrity: sha512-TRTfi1mv1GeIZGyi9PQmvAaH65ZlG4/FACq6wSzs7Vvf1z5dnNWsAAXBjWMHt76l+1hUY8teIqJFrWBk5N6gsg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/figures@1.0.9':
resolution: {integrity: sha512-BXvGj0ehzrngHTPTDqUoDT3NXL8U0RxUk2zJm2A66RhCEIWdtU1v6GuUqNAgArW4PQ9CinqIWyHdQgdwOj06zQ==}
engines: {node: '>=18'}
'@inquirer/input@4.1.3':
resolution: {integrity: sha512-zeo++6f7hxaEe7OjtMzdGZPHiawsfmCZxWB9X1NpmYgbeoyerIbWemvlBxxl+sQIlHC0WuSAG19ibMq3gbhaqQ==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/number@3.0.6':
resolution: {integrity: sha512-xO07lftUHk1rs1gR0KbqB+LJPhkUNkyzV/KhH+937hdkMazmAYHLm1OIrNKpPelppeV1FgWrgFDjdUD8mM+XUg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/password@4.0.6':
resolution: {integrity: sha512-QLF0HmMpHZPPMp10WGXh6F+ZPvzWE7LX6rNoccdktv/Rov0B+0f+eyXkAcgqy5cH9V+WSpbLxu2lo3ysEVK91w==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/prompts@7.2.3':
resolution: {integrity: sha512-hzfnm3uOoDySDXfDNOm9usOuYIaQvTgKp/13l1uJoe6UNY+Zpcn2RYt0jXz3yA+yemGHvDOxVzqWl3S5sQq53Q==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/rawlist@4.0.6':
resolution: {integrity: sha512-QoE4s1SsIPx27FO4L1b1mUjVcoHm1pWE/oCmm4z/Hl+V1Aw5IXl8FYYzGmfXaBT0l/sWr49XmNSiq7kg3Kd/Lg==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/search@3.0.6':
resolution: {integrity: sha512-eFZ2hiAq0bZcFPuFFBmZEtXU1EarHLigE+ENCtpO+37NHCl4+Yokq1P/d09kUblObaikwfo97w+0FtG/EXl5Ng==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/select@4.0.6':
resolution: {integrity: sha512-yANzIiNZ8fhMm4NORm+a74+KFYHmf7BZphSOBovIzYPVLquseTGEkU5l2UTnBOf5k0VLmTgPighNDLE9QtbViQ==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@inquirer/type@1.5.5':
resolution: {integrity: sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==}
engines: {node: '>=18'}
'@inquirer/type@3.0.2':
resolution: {integrity: sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
'@ioredis/commands@1.2.0':
resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==}
@ -266,6 +357,9 @@ packages:
resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==}
engines: {node: ^14.21.3 || >=16}
'@noble/secp256k1@2.2.3':
resolution: {integrity: sha512-l7r5oEQym9Us7EAigzg30/PQAvynhMt2uoYtT3t26eGDVm9Yii5mZ5jWSWmZ/oSIR2Et0xfc6DXrG0bZ787V3w==}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@ -278,6 +372,10 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@nostr-dev-kit/ndk@2.11.0':
resolution: {integrity: sha512-FKIMtcVsVcquzrC+yir9lOXHCIHmQ3IKEVCMohqEB7N96HjP2qrI9s5utbjI3lkavFNF5tXg1Gp9ODEo7XCfLA==}
engines: {node: '>=16'}
'@npmcli/fs@1.1.1':
resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==}
@ -534,6 +632,9 @@ packages:
'@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
'@types/mute-stream@0.0.1':
resolution: {integrity: sha512-0yQLzYhCqGz7CQPE3iDmYjhb7KMBFOP+tBkyw+/Y2YyDI5wpS7itXXxneN1zSsUwWx3Ji6YiVYrhAnpQGS/vkw==}
'@types/node@12.20.55':
resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==}
@ -555,6 +656,9 @@ packages:
'@types/serve-static@1.15.7':
resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==}
'@types/wrap-ansi@3.0.0':
resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==}
'@types/ws@8.5.13':
resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==}
@ -588,6 +692,10 @@ packages:
resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
engines: {node: '>=6'}
ansi-escapes@4.3.2:
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
engines: {node: '>=8'}
ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'}
@ -622,6 +730,12 @@ packages:
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
engines: {node: '>=4'}
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
axios@1.7.9:
resolution: {integrity: sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==}
b4a@1.6.7:
resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==}
@ -721,6 +835,10 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
chalk@4.1.2:
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
engines: {node: '>=10'}
chardet@0.7.0:
resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==}
@ -748,6 +866,14 @@ packages:
resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
engines: {node: '>=6'}
cli-spinners@2.9.2:
resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
engines: {node: '>=6'}
cli-width@4.1.0:
resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==}
engines: {node: '>= 12'}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@ -774,6 +900,14 @@ packages:
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
commander@12.1.0:
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
engines: {node: '>=18'}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@ -805,6 +939,10 @@ packages:
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
engines: {node: '>= 8'}
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
data-uri-to-buffer@6.0.2:
resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==}
engines: {node: '>= 14'}
@ -849,6 +987,10 @@ packages:
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
engines: {node: '>= 14'}
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
@ -940,6 +1082,14 @@ packages:
escape-html@1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
escape-string-regexp@1.0.5:
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
engines: {node: '>=0.8.0'}
escape-string-regexp@5.0.0:
resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
engines: {node: '>=12'}
escodegen@2.1.0:
resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
engines: {node: '>=6.0'}
@ -987,6 +1137,18 @@ packages:
fd-slicer@1.1.0:
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
fetch-blob@3.2.0:
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
engines: {node: ^12.20 || >= 14.13}
figures@3.2.0:
resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==}
engines: {node: '>=8'}
figures@5.0.0:
resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==}
engines: {node: '>=14'}
file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
@ -1007,6 +1169,14 @@ packages:
debug:
optional: true
form-data@4.0.1:
resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==}
engines: {node: '>= 6'}
formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'}
fresh@0.5.2:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
@ -1088,6 +1258,10 @@ packages:
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
engines: {node: '>=4'}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
has-symbols@1.1.0:
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
engines: {node: '>= 0.4'}
@ -1189,6 +1363,16 @@ packages:
ini@1.3.8:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
inquirer-autocomplete-standalone@0.8.1:
resolution: {integrity: sha512-mlzwCTiXDX1Cw4yJL5PCq32k23XYLTK8K6BDFoL1a76iJeFB5ul6IoMU9spgdDagl2SM7P6ZaCNjj8VNXRDPOQ==}
engines: {node: '>=16'}
inquirer@12.3.2:
resolution: {integrity: sha512-YjQCIcDd3yyDuQrbII0FBtm/ZqNoWtvaC71yeCnd5Vbg4EgzsAGaemzfpzmqfvIZEp2roSwuZZKdM0C65hA43g==}
engines: {node: '>=18'}
peerDependencies:
'@types/node': '>=18'
ioredis@5.4.2:
resolution: {integrity: sha512-0SZXGNGZ+WzISQ67QDyZ2x0+wVxjjUndtD8oSeik/4ajifeiRufed8fCb8QW8VMyi4MXcS+UO1k/0NGhvq1PAg==}
engines: {node: '>=12.22.0'}
@ -1235,6 +1419,10 @@ packages:
resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==}
engines: {node: '>=4'}
is-unicode-supported@1.3.0:
resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
engines: {node: '>=12'}
is-windows@1.0.2:
resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
engines: {node: '>=0.10.0'}
@ -1291,6 +1479,9 @@ packages:
resolution: {integrity: sha512-j/8tY9j5t+GVMLeioLaxweJiKUayFhlGqNTzf2ZGwL0ZCQijd2RLHK0SLW5Tsko8YyyqCZC2cojIb0/s62qTAg==}
engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4}
light-bolt11-decoder@3.2.0:
resolution: {integrity: sha512-3QEofgiBOP4Ehs9BI+RkZdXZNtSys0nsJ6fyGeSiAGCBsMwHGUDS/JQlY/sTnWs91A2Nh0S9XXfA8Sy9g6QpuQ==}
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
@ -1415,6 +1606,14 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
mute-stream@1.0.0:
resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
mute-stream@2.0.0:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0}
napi-build-utils@2.0.0:
resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==}
@ -1437,6 +1636,14 @@ packages:
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
node-fetch@3.3.2:
resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
node-gyp@8.4.1:
resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==}
engines: {node: '>= 10.12.0'}
@ -1472,6 +1679,11 @@ packages:
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
deprecated: This package is no longer supported.
nsite-cli@0.1.14:
resolution: {integrity: sha512-ZPIIrft//YJJpKINrVDOiTxA1ut1vK5YocrY/Dwf2dSM0xzER2ipF6QL5hfVHbT84wC5R3Ea9O1IoH17nuFHoQ==}
engines: {node: '>=20.0.0', npm: '>=8.0.0 '}
hasBin: true
on-finished@2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
@ -1696,9 +1908,16 @@ packages:
deprecated: Rimraf versions prior to v4 are no longer supported
hasBin: true
run-async@3.0.0:
resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==}
engines: {node: '>=0.12.0'}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
rxjs@7.8.1:
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
safe-buffer@5.1.2:
resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
@ -1827,6 +2046,10 @@ packages:
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
engines: {node: '>=4'}
supports-color@7.2.0:
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
engines: {node: '>=8'}
tar-fs@2.1.2:
resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==}
@ -1870,6 +2093,9 @@ packages:
resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
hasBin: true
tseep@1.3.1:
resolution: {integrity: sha512-ZPtfk1tQnZVyr7BPtbJ93qaAh2lZuIOpTMjhrYa4XctT8xe7t4SAW9LIxrySDuYMsfNNayE51E/WNGrNVgVicQ==}
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@ -1883,6 +2109,10 @@ packages:
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
type-is@1.6.18:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
@ -1890,6 +2120,9 @@ packages:
typed-query-selector@2.12.0:
resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==}
typescript-lru-cache@2.0.0:
resolution: {integrity: sha512-Jp57Qyy8wXeMkdNuZiglE6v2Cypg13eDA1chHwDG6kq51X7gk4K7P7HaDdzZKCxkegXkVHNcPD0n5aW6OZH3aA==}
typescript@5.7.3:
resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==}
engines: {node: '>=14.17'}
@ -1914,6 +2147,10 @@ packages:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
utf8-buffer@1.0.0:
resolution: {integrity: sha512-ueuhzvWnp5JU5CiGSY4WdKbiN/PO2AZ/lpeLiz2l38qwdLy/cW40XobgyuIWucNyum0B33bVB0owjFCeGBSLqg==}
engines: {node: '>=8'}
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -1921,6 +2158,10 @@ packages:
resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
web-streams-polyfill@3.3.3:
resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==}
engines: {node: '>= 8'}
websocket-polyfill@1.0.0:
resolution: {integrity: sha512-QwfEy8jcOOCVO9su9UP+msEmhZa4a9WSJfePIdCT8GxwVl2Z9toM7nCqFfDDxA/sRmxgf1KNiwL6PXvjJ9qRxw==}
@ -1932,6 +2173,10 @@ packages:
wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
@ -1977,6 +2222,10 @@ packages:
resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==}
engines: {node: '>= 4.0.0'}
yoctocolors-cjs@2.1.2:
resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==}
engines: {node: '>=18'}
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
@ -2171,6 +2420,132 @@ snapshots:
'@gar/promisify@1.1.3':
optional: true
'@inquirer/checkbox@4.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/figures': 1.0.9
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
ansi-escapes: 4.3.2
yoctocolors-cjs: 2.1.2
'@inquirer/confirm@5.1.3(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
'@inquirer/core@10.1.4(@types/node@20.17.14)':
dependencies:
'@inquirer/figures': 1.0.9
'@inquirer/type': 3.0.2(@types/node@20.17.14)
ansi-escapes: 4.3.2
cli-width: 4.1.0
mute-stream: 2.0.0
signal-exit: 4.1.0
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
yoctocolors-cjs: 2.1.2
transitivePeerDependencies:
- '@types/node'
'@inquirer/core@3.1.2':
dependencies:
'@inquirer/type': 1.5.5
'@types/mute-stream': 0.0.1
'@types/node': 20.17.14
'@types/wrap-ansi': 3.0.0
ansi-escapes: 4.3.2
chalk: 4.1.2
cli-spinners: 2.9.2
cli-width: 4.1.0
figures: 3.2.0
mute-stream: 1.0.0
run-async: 3.0.0
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
'@inquirer/editor@4.2.3(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
external-editor: 3.1.0
'@inquirer/expand@4.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
yoctocolors-cjs: 2.1.2
'@inquirer/figures@1.0.9': {}
'@inquirer/input@4.1.3(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
'@inquirer/number@3.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
'@inquirer/password@4.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
ansi-escapes: 4.3.2
'@inquirer/prompts@7.2.3(@types/node@20.17.14)':
dependencies:
'@inquirer/checkbox': 4.0.6(@types/node@20.17.14)
'@inquirer/confirm': 5.1.3(@types/node@20.17.14)
'@inquirer/editor': 4.2.3(@types/node@20.17.14)
'@inquirer/expand': 4.0.6(@types/node@20.17.14)
'@inquirer/input': 4.1.3(@types/node@20.17.14)
'@inquirer/number': 3.0.6(@types/node@20.17.14)
'@inquirer/password': 4.0.6(@types/node@20.17.14)
'@inquirer/rawlist': 4.0.6(@types/node@20.17.14)
'@inquirer/search': 3.0.6(@types/node@20.17.14)
'@inquirer/select': 4.0.6(@types/node@20.17.14)
'@types/node': 20.17.14
'@inquirer/rawlist@4.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
yoctocolors-cjs: 2.1.2
'@inquirer/search@3.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/figures': 1.0.9
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
yoctocolors-cjs: 2.1.2
'@inquirer/select@4.0.6(@types/node@20.17.14)':
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/figures': 1.0.9
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
ansi-escapes: 4.3.2
yoctocolors-cjs: 2.1.2
'@inquirer/type@1.5.5':
dependencies:
mute-stream: 1.0.0
'@inquirer/type@3.0.2(@types/node@20.17.14)':
dependencies:
'@types/node': 20.17.14
'@ioredis/commands@1.2.0': {}
'@keyv/redis@3.0.1':
@ -2237,6 +2612,8 @@ snapshots:
'@noble/hashes@1.7.1': {}
'@noble/secp256k1@2.2.3': {}
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@ -2249,6 +2626,25 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.18.0
'@nostr-dev-kit/ndk@2.11.0(typescript@5.7.3)':
dependencies:
'@noble/curves': 1.8.1
'@noble/hashes': 1.7.1
'@noble/secp256k1': 2.2.3
'@scure/base': 1.2.4
debug: 4.4.0(supports-color@5.5.0)
light-bolt11-decoder: 3.2.0
nostr-tools: 2.10.4(typescript@5.7.3)
tseep: 1.3.1
typescript-lru-cache: 2.0.0
utf8-buffer: 1.0.0
websocket-polyfill: 1.0.0
transitivePeerDependencies:
- bufferutil
- supports-color
- typescript
- utf-8-validate
'@npmcli/fs@1.1.1':
dependencies:
'@gar/promisify': 1.1.3
@ -2522,6 +2918,10 @@ snapshots:
'@types/ms@2.1.0': {}
'@types/mute-stream@0.0.1':
dependencies:
'@types/node': 20.17.14
'@types/node@12.20.55': {}
'@types/node@20.17.14':
@ -2547,6 +2947,8 @@ snapshots:
'@types/node': 20.17.14
'@types/send': 0.17.4
'@types/wrap-ansi@3.0.0': {}
'@types/ws@8.5.13':
dependencies:
'@types/node': 20.17.14
@ -2586,6 +2988,10 @@ snapshots:
ansi-colors@4.1.3: {}
ansi-escapes@4.3.2:
dependencies:
type-fest: 0.21.3
ansi-regex@5.0.1: {}
ansi-styles@4.3.0:
@ -2618,6 +3024,16 @@ snapshots:
dependencies:
tslib: 2.8.1
asynckit@0.4.0: {}
axios@1.7.9(debug@4.4.0):
dependencies:
follow-redirects: 1.15.9(debug@4.4.0)
form-data: 4.0.1
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
b4a@1.6.7: {}
balanced-match@1.0.2: {}
@ -2742,6 +3158,11 @@ snapshots:
callsites@3.1.0: {}
chalk@4.1.2:
dependencies:
ansi-styles: 4.3.0
supports-color: 7.2.0
chardet@0.7.0: {}
chokidar@3.6.0:
@ -2771,6 +3192,10 @@ snapshots:
clean-stack@2.2.0:
optional: true
cli-spinners@2.9.2: {}
cli-width@4.1.0: {}
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@ -2792,6 +3217,12 @@ snapshots:
colorette@2.0.20: {}
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
commander@12.1.0: {}
concat-map@0.0.1: {}
console-control-strings@1.1.0:
@ -2823,6 +3254,8 @@ snapshots:
shebang-command: 2.0.0
which: 2.0.2
data-uri-to-buffer@4.0.1: {}
data-uri-to-buffer@6.0.2: {}
debug@2.6.9:
@ -2853,6 +3286,8 @@ snapshots:
escodegen: 2.1.0
esprima: 4.0.1
delayed-stream@1.0.0: {}
delegates@1.0.0: {}
denque@2.1.0: {}
@ -2922,6 +3357,10 @@ snapshots:
escape-html@1.0.3: {}
escape-string-regexp@1.0.5: {}
escape-string-regexp@5.0.0: {}
escodegen@2.1.0:
dependencies:
esprima: 4.0.1
@ -2974,6 +3413,20 @@ snapshots:
dependencies:
pend: 1.2.0
fetch-blob@3.2.0:
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 3.3.3
figures@3.2.0:
dependencies:
escape-string-regexp: 1.0.5
figures@5.0.0:
dependencies:
escape-string-regexp: 5.0.0
is-unicode-supported: 1.3.0
file-uri-to-path@1.0.0: {}
fill-range@7.1.1:
@ -2989,6 +3442,16 @@ snapshots:
optionalDependencies:
debug: 4.4.0(supports-color@5.5.0)
form-data@4.0.1:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
formdata-polyfill@4.0.10:
dependencies:
fetch-blob: 3.2.0
fresh@0.5.2: {}
fs-constants@1.0.0: {}
@ -3092,6 +3555,8 @@ snapshots:
has-flag@3.0.0: {}
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
has-tostringtag@1.0.2:
@ -3209,6 +3674,24 @@ snapshots:
ini@1.3.8: {}
inquirer-autocomplete-standalone@0.8.1:
dependencies:
'@inquirer/core': 3.1.2
'@inquirer/type': 1.5.5
figures: 5.0.0
picocolors: 1.1.1
inquirer@12.3.2(@types/node@20.17.14):
dependencies:
'@inquirer/core': 10.1.4(@types/node@20.17.14)
'@inquirer/prompts': 7.2.3(@types/node@20.17.14)
'@inquirer/type': 3.0.2(@types/node@20.17.14)
'@types/node': 20.17.14
ansi-escapes: 4.3.2
mute-stream: 2.0.0
run-async: 3.0.0
rxjs: 7.8.1
ioredis@5.4.2:
dependencies:
'@ioredis/commands': 1.2.0
@ -3265,6 +3748,8 @@ snapshots:
dependencies:
better-path-resolve: 1.0.0
is-unicode-supported@1.3.0: {}
is-windows@1.0.2: {}
isexe@2.0.0: {}
@ -3352,6 +3837,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
light-bolt11-decoder@3.2.0:
dependencies:
'@scure/base': 1.1.1
lines-and-columns@1.2.4: {}
locate-path@5.0.0:
@ -3483,6 +3972,10 @@ snapshots:
ms@2.1.3: {}
mute-stream@1.0.0: {}
mute-stream@2.0.0: {}
napi-build-utils@2.0.0: {}
negotiator@0.6.3: {}
@ -3498,6 +3991,14 @@ snapshots:
node-addon-api@7.1.1: {}
node-domexception@1.0.0: {}
node-fetch@3.3.2:
dependencies:
data-uri-to-buffer: 4.0.1
fetch-blob: 3.2.0
formdata-polyfill: 4.0.10
node-gyp@8.4.1:
dependencies:
env-paths: 2.2.1
@ -3558,6 +4059,30 @@ snapshots:
set-blocking: 2.0.0
optional: true
nsite-cli@0.1.14(@types/node@20.17.14)(typescript@5.7.3):
dependencies:
'@noble/hashes': 1.7.1
'@nostr-dev-kit/ndk': 2.11.0(typescript@5.7.3)
axios: 1.7.9(debug@4.4.0)
blossom-client-sdk: 2.1.1
commander: 12.1.0
debug: 4.4.0(supports-color@5.5.0)
dotenv: 16.4.7
inquirer: 12.3.2(@types/node@20.17.14)
inquirer-autocomplete-standalone: 0.8.1
mime-types: 2.1.35
node-fetch: 3.3.2
nostr-tools: 2.10.4(typescript@5.7.3)
proxy-agent: 6.5.0
websocket-polyfill: 1.0.0
ws: 8.18.0
transitivePeerDependencies:
- '@types/node'
- bufferutil
- supports-color
- typescript
- utf-8-validate
on-finished@2.3.0:
dependencies:
ee-first: 1.1.1
@ -3802,10 +4327,16 @@ snapshots:
glob: 7.2.3
optional: true
run-async@3.0.0: {}
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
rxjs@7.8.1:
dependencies:
tslib: 2.8.1
safe-buffer@5.1.2: {}
safe-buffer@5.2.1: {}
@ -3943,6 +4474,10 @@ snapshots:
dependencies:
has-flag: 3.0.0
supports-color@7.2.0:
dependencies:
has-flag: 4.0.0
tar-fs@2.1.2:
dependencies:
chownr: 1.1.4
@ -4003,6 +4538,8 @@ snapshots:
touch@3.1.1: {}
tseep@1.3.1: {}
tslib@2.8.1: {}
tsscmp@1.0.6: {}
@ -4013,6 +4550,8 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
type-fest@0.21.3: {}
type-is@1.6.18:
dependencies:
media-typer: 0.3.0
@ -4020,6 +4559,8 @@ snapshots:
typed-query-selector@2.12.0: {}
typescript-lru-cache@2.0.0: {}
typescript@5.7.3: {}
unbzip2-stream@1.4.3:
@ -4043,10 +4584,14 @@ snapshots:
universalify@0.1.2: {}
utf8-buffer@1.0.0: {}
util-deprecate@1.0.2: {}
vary@1.1.2: {}
web-streams-polyfill@3.3.3: {}
websocket-polyfill@1.0.0:
dependencies:
import2: 1.0.3
@ -4065,6 +4610,12 @@ snapshots:
string-width: 4.2.3
optional: true
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
@ -4100,4 +4651,6 @@ snapshots:
ylru@1.4.0: {}
yoctocolors-cjs@2.1.2: {}
zod@3.23.8: {}

View File

@ -1,110 +0,0 @@
import { html, css, LitElement } from "lit";
import { nip19 } from "nostr-tools";
import { pool, relays } from "../pool.js";
export class NsiteCard extends LitElement {
static styles = css`
:host {
min-width: 3in;
max-width: 4in;
border: 1px solid lightslategray;
display: flex;
flex-direction: column;
padding: 0.5em;
gap: 0.3em;
border-radius: 0.5em;
}
.title {
display: flex;
gap: 0.5em;
align-items: center;
color: initial;
text-decoration: none;
}
.title h3 {
margin: 0;
}
.avatar {
width: 3rem;
height: 3rem;
border: none;
outline: none;
border-radius: 50%;
}
.thumb {
display: flex;
overflow: hidden;
}
.thumb > img {
width: 100%;
border-radius: 0.5em;
}
.about {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
time {
margin-top: auto;
}
`;
static properties = {
nsite: { type: Object },
profile: { state: true, type: Object },
hasThumb: { state: true, type: Boolean },
};
constructor() {
super();
this.hasThumb = true;
}
connectedCallback() {
super.connectedCallback();
pool.get(relays, { kinds: [0], authors: [this.nsite.pubkey] }).then((event) => {
if (event) this.profile = JSON.parse(event.content);
});
}
handleError() {
this.hasThumb = false;
}
render() {
const npub = nip19.npubEncode(this.nsite.pubkey);
const url = new URL("/", `${location.protocol}//${npub}.${location.host}`);
return html`
${this.hasThumb
? html`
<a class="thumb" href="${url}" target="_blank">
<img src="/screenshot/${this.nsite.pubkey}.png" @error=${this.handleError} />
</a>
`
: undefined}
<a class="title" href="${url}" target="_blank">
${this.profile && html`<img src="${this.profile.image || this.profile.picture}" class="avatar" />`}
<div>
${this.profile
? html`
<h3>${this.profile.display_name || this.profile.name}</h3>
<small>${this.profile.nip05}</small>
`
: html`<h3>${npub.slice(0, 8)}</h3>`}
</div>
</a>
${this.profile && html`<p class="about">${this.profile.about}</p>`}
<time>${new Date(this.nsite.created_at * 1000).toDateString()}</time>
`;
}
}
customElements.define("nsite-card", NsiteCard);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@ -3,27 +3,65 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>nsite</title>
<script type="importmap">
{
"imports": {
"blossom-client-sdk": "https://esm.run/blossom-client-sdk",
"nostr-tools": "https://esm.run/nostr-tools",
"lit": "https://esm.run/lit",
"lit/directives/repeat.js": "https://esm.run/lit/directives/repeat.js"
}
}
</script>
<title>Welcome to nsite-ts</title>
<style>
nostr-picture > img {
width: 100%;
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.6;
color: #333;
max-width: 800px;
margin: 40px auto;
padding: 0 20px;
background-color: #f5f5f5;
}
.container {
background-color: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
h1 {
color: #2c3e50;
margin-bottom: 20px;
}
.info {
background-color: #f8f9fa;
border-left: 4px solid #007bff;
padding: 15px;
margin: 20px 0;
}
code {
background-color: #f1f1f1;
padding: 2px 6px;
border-radius: 3px;
font-family: Monaco, monospace;
user-select: all;
word-break: break-all;
}
</style>
<script type="module" src="./main.js"></script>
</head>
<body>
<nsite-app></nsite-app>
<div class="container">
<h1>Welcome to nsite-ts</h1>
<p>If you're seeing this page, nsite-ts has been successfully installed and is working.</p>
<div class="info">
<p>
To set a custom homepage, set the <code>NSITE_HOMEPAGE</code> environment variable to your desired nprofile
</p>
<p>
Example:
<br />
<code
>NSITE_HOMEPAGE=nprofile1qqspspfsrjnurtf0jdyswm8jstustv7pu4qw3pn4u99etptvgzm4uvcpz9mhxue69uhkummnw3e82efwvdhk6qg5waehxw309aex2mrp0yhxgctdw4eju6t04mzfem</code
>
</p>
</div>
<p>
For more information about configuring nsite-ts, please refer to the
<a href="https://github.com/hzrd149/nsite-ts">documentation</a>
</p>
</div>
</body>
</html>

29
public/lib/lit.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -1,635 +0,0 @@
/*!
* Milligram v1.4.1
* https://milligram.io
*
* Copyright (c) 2020 CJ Patoilo
* Licensed under the MIT license
*/
*,
*:after,
*:before {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: 62.5%;
}
body {
color: #606c76;
font-family: 'Roboto', 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
font-size: 1.6em;
font-weight: 300;
letter-spacing: .01em;
line-height: 1.6;
}
blockquote {
border-left: 0.3rem solid #d1d1d1;
margin-left: 0;
margin-right: 0;
padding: 1rem 1.5rem;
}
blockquote *:last-child {
margin-bottom: 0;
}
.button,
button,
input[type='button'],
input[type='reset'],
input[type='submit'] {
background-color: #9b4dca;
border: 0.1rem solid #9b4dca;
border-radius: .4rem;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: 1.1rem;
font-weight: 700;
height: 3.8rem;
letter-spacing: .1rem;
line-height: 3.8rem;
padding: 0 3.0rem;
text-align: center;
text-decoration: none;
text-transform: uppercase;
white-space: nowrap;
}
.button:focus, .button:hover,
button:focus,
button:hover,
input[type='button']:focus,
input[type='button']:hover,
input[type='reset']:focus,
input[type='reset']:hover,
input[type='submit']:focus,
input[type='submit']:hover {
background-color: #606c76;
border-color: #606c76;
color: #fff;
outline: 0;
}
.button[disabled],
button[disabled],
input[type='button'][disabled],
input[type='reset'][disabled],
input[type='submit'][disabled] {
cursor: default;
opacity: .5;
}
.button[disabled]:focus, .button[disabled]:hover,
button[disabled]:focus,
button[disabled]:hover,
input[type='button'][disabled]:focus,
input[type='button'][disabled]:hover,
input[type='reset'][disabled]:focus,
input[type='reset'][disabled]:hover,
input[type='submit'][disabled]:focus,
input[type='submit'][disabled]:hover {
background-color: #9b4dca;
border-color: #9b4dca;
}
.button.button-outline,
button.button-outline,
input[type='button'].button-outline,
input[type='reset'].button-outline,
input[type='submit'].button-outline {
background-color: transparent;
color: #9b4dca;
}
.button.button-outline:focus, .button.button-outline:hover,
button.button-outline:focus,
button.button-outline:hover,
input[type='button'].button-outline:focus,
input[type='button'].button-outline:hover,
input[type='reset'].button-outline:focus,
input[type='reset'].button-outline:hover,
input[type='submit'].button-outline:focus,
input[type='submit'].button-outline:hover {
background-color: transparent;
border-color: #606c76;
color: #606c76;
}
.button.button-outline[disabled]:focus, .button.button-outline[disabled]:hover,
button.button-outline[disabled]:focus,
button.button-outline[disabled]:hover,
input[type='button'].button-outline[disabled]:focus,
input[type='button'].button-outline[disabled]:hover,
input[type='reset'].button-outline[disabled]:focus,
input[type='reset'].button-outline[disabled]:hover,
input[type='submit'].button-outline[disabled]:focus,
input[type='submit'].button-outline[disabled]:hover {
border-color: inherit;
color: #9b4dca;
}
.button.button-clear,
button.button-clear,
input[type='button'].button-clear,
input[type='reset'].button-clear,
input[type='submit'].button-clear {
background-color: transparent;
border-color: transparent;
color: #9b4dca;
}
.button.button-clear:focus, .button.button-clear:hover,
button.button-clear:focus,
button.button-clear:hover,
input[type='button'].button-clear:focus,
input[type='button'].button-clear:hover,
input[type='reset'].button-clear:focus,
input[type='reset'].button-clear:hover,
input[type='submit'].button-clear:focus,
input[type='submit'].button-clear:hover {
background-color: transparent;
border-color: transparent;
color: #606c76;
}
.button.button-clear[disabled]:focus, .button.button-clear[disabled]:hover,
button.button-clear[disabled]:focus,
button.button-clear[disabled]:hover,
input[type='button'].button-clear[disabled]:focus,
input[type='button'].button-clear[disabled]:hover,
input[type='reset'].button-clear[disabled]:focus,
input[type='reset'].button-clear[disabled]:hover,
input[type='submit'].button-clear[disabled]:focus,
input[type='submit'].button-clear[disabled]:hover {
color: #9b4dca;
}
code {
background: #f4f5f6;
border-radius: .4rem;
font-size: 86%;
margin: 0 .2rem;
padding: .2rem .5rem;
white-space: nowrap;
}
pre {
background: #f4f5f6;
border-left: 0.3rem solid #9b4dca;
overflow-y: hidden;
}
pre > code {
border-radius: 0;
display: block;
padding: 1rem 1.5rem;
white-space: pre;
}
hr {
border: 0;
border-top: 0.1rem solid #f4f5f6;
margin: 3.0rem 0;
}
input[type='color'],
input[type='date'],
input[type='datetime'],
input[type='datetime-local'],
input[type='email'],
input[type='month'],
input[type='number'],
input[type='password'],
input[type='search'],
input[type='tel'],
input[type='text'],
input[type='url'],
input[type='week'],
input:not([type]),
textarea,
select {
-webkit-appearance: none;
background-color: transparent;
border: 0.1rem solid #d1d1d1;
border-radius: .4rem;
box-shadow: none;
box-sizing: inherit;
height: 3.8rem;
padding: .6rem 1.0rem .7rem;
width: 100%;
}
input[type='color']:focus,
input[type='date']:focus,
input[type='datetime']:focus,
input[type='datetime-local']:focus,
input[type='email']:focus,
input[type='month']:focus,
input[type='number']:focus,
input[type='password']:focus,
input[type='search']:focus,
input[type='tel']:focus,
input[type='text']:focus,
input[type='url']:focus,
input[type='week']:focus,
input:not([type]):focus,
textarea:focus,
select:focus {
border-color: #9b4dca;
outline: 0;
}
select {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 8" width="30"><path fill="%23d1d1d1" d="M0,0l6,8l6-8"/></svg>') center right no-repeat;
padding-right: 3.0rem;
}
select:focus {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 8" width="30"><path fill="%239b4dca" d="M0,0l6,8l6-8"/></svg>');
}
select[multiple] {
background: none;
height: auto;
}
textarea {
min-height: 6.5rem;
}
label,
legend {
display: block;
font-size: 1.6rem;
font-weight: 700;
margin-bottom: .5rem;
}
fieldset {
border-width: 0;
padding: 0;
}
input[type='checkbox'],
input[type='radio'] {
display: inline;
}
.label-inline {
display: inline-block;
font-weight: normal;
margin-left: .5rem;
}
.container {
margin: 0 auto;
max-width: 112.0rem;
padding: 0 2.0rem;
position: relative;
width: 100%;
}
.row {
display: flex;
flex-direction: column;
padding: 0;
width: 100%;
}
.row.row-no-padding {
padding: 0;
}
.row.row-no-padding > .column {
padding: 0;
}
.row.row-wrap {
flex-wrap: wrap;
}
.row.row-top {
align-items: flex-start;
}
.row.row-bottom {
align-items: flex-end;
}
.row.row-center {
align-items: center;
}
.row.row-stretch {
align-items: stretch;
}
.row.row-baseline {
align-items: baseline;
}
.row .column {
display: block;
flex: 1 1 auto;
margin-left: 0;
max-width: 100%;
width: 100%;
}
.row .column.column-offset-10 {
margin-left: 10%;
}
.row .column.column-offset-20 {
margin-left: 20%;
}
.row .column.column-offset-25 {
margin-left: 25%;
}
.row .column.column-offset-33, .row .column.column-offset-34 {
margin-left: 33.3333%;
}
.row .column.column-offset-40 {
margin-left: 40%;
}
.row .column.column-offset-50 {
margin-left: 50%;
}
.row .column.column-offset-60 {
margin-left: 60%;
}
.row .column.column-offset-66, .row .column.column-offset-67 {
margin-left: 66.6666%;
}
.row .column.column-offset-75 {
margin-left: 75%;
}
.row .column.column-offset-80 {
margin-left: 80%;
}
.row .column.column-offset-90 {
margin-left: 90%;
}
.row .column.column-10 {
flex: 0 0 10%;
max-width: 10%;
}
.row .column.column-20 {
flex: 0 0 20%;
max-width: 20%;
}
.row .column.column-25 {
flex: 0 0 25%;
max-width: 25%;
}
.row .column.column-33, .row .column.column-34 {
flex: 0 0 33.3333%;
max-width: 33.3333%;
}
.row .column.column-40 {
flex: 0 0 40%;
max-width: 40%;
}
.row .column.column-50 {
flex: 0 0 50%;
max-width: 50%;
}
.row .column.column-60 {
flex: 0 0 60%;
max-width: 60%;
}
.row .column.column-66, .row .column.column-67 {
flex: 0 0 66.6666%;
max-width: 66.6666%;
}
.row .column.column-75 {
flex: 0 0 75%;
max-width: 75%;
}
.row .column.column-80 {
flex: 0 0 80%;
max-width: 80%;
}
.row .column.column-90 {
flex: 0 0 90%;
max-width: 90%;
}
.row .column .column-top {
align-self: flex-start;
}
.row .column .column-bottom {
align-self: flex-end;
}
.row .column .column-center {
align-self: center;
}
@media (min-width: 40rem) {
.row {
flex-direction: row;
margin-left: -1.0rem;
width: calc(100% + 2.0rem);
}
.row .column {
margin-bottom: inherit;
padding: 0 1.0rem;
}
}
a {
color: #9b4dca;
text-decoration: none;
}
a:focus, a:hover {
color: #606c76;
}
dl,
ol,
ul {
list-style: none;
margin-top: 0;
padding-left: 0;
}
dl dl,
dl ol,
dl ul,
ol dl,
ol ol,
ol ul,
ul dl,
ul ol,
ul ul {
font-size: 90%;
margin: 1.5rem 0 1.5rem 3.0rem;
}
ol {
list-style: decimal inside;
}
ul {
list-style: circle inside;
}
.button,
button,
dd,
dt,
li {
margin-bottom: 1.0rem;
}
fieldset,
input,
select,
textarea {
margin-bottom: 1.5rem;
}
blockquote,
dl,
figure,
form,
ol,
p,
pre,
table,
ul {
margin-bottom: 2.5rem;
}
table {
border-spacing: 0;
display: block;
overflow-x: auto;
text-align: left;
width: 100%;
}
td,
th {
border-bottom: 0.1rem solid #e1e1e1;
padding: 1.2rem 1.5rem;
}
td:first-child,
th:first-child {
padding-left: 0;
}
td:last-child,
th:last-child {
padding-right: 0;
}
@media (min-width: 40rem) {
table {
display: table;
overflow-x: initial;
}
}
b,
strong {
font-weight: bold;
}
p {
margin-top: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: 300;
letter-spacing: -.1rem;
margin-bottom: 2.0rem;
margin-top: 0;
}
h1 {
font-size: 4.6rem;
line-height: 1.2;
}
h2 {
font-size: 3.6rem;
line-height: 1.25;
}
h3 {
font-size: 2.8rem;
line-height: 1.3;
}
h4 {
font-size: 2.2rem;
letter-spacing: -.08rem;
line-height: 1.35;
}
h5 {
font-size: 1.8rem;
letter-spacing: -.05rem;
line-height: 1.5;
}
h6 {
font-size: 1.6rem;
letter-spacing: 0;
line-height: 1.4;
}
img {
max-width: 100%;
}
.clearfix:after {
clear: both;
content: ' ';
display: table;
}
.float-left {
float: left;
}
.float-right {
float: right;
}
/*# sourceMappingURL=milligram.css.map */

View File

@ -1,349 +0,0 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@ -1,58 +0,0 @@
import { LitElement, html, css } from "lit";
import { repeat } from "lit/directives/repeat.js";
import "./components/nsite-card.js";
import { pool, relays } from "./pool.js";
export class NsiteApp extends LitElement {
static properties = {
selected: { state: true },
status: { state: true, type: String },
sites: { state: true, type: Array },
};
static styles = css`
.sites {
display: flex;
gap: 0.5em;
flex-wrap: wrap;
}
`;
seen = new Set();
constructor() {
super();
this.sites = [];
}
connectedCallback() {
super.connectedCallback();
pool.subscribeMany(relays, [{ kinds: [34128], "#d": ["/index.html"] }], {
onevent: (event) => {
if (this.seen.has(event.pubkey)) return;
this.seen.add(event.pubkey);
this.sites = [...this.sites, event].sort((a, b) => b.created_at - a.created_at);
},
});
}
render() {
return html`<div class="container">
<img src="/logo.jpg" style="max-height: 2in" />
<h1>nsite</h1>
<a class="navbar-item" href="https://github.com/hzrd149/nsite-ts" target="_blank">Source Code</a>
<h2 class="subtitle is-2">Latest nsites:</h2>
<div class="sites">
${repeat(
this.sites,
(nsite) => nsite.pubkey,
(nsite) => html`<nsite-card .nsite="${nsite}"></nsite-card>`,
)}
</div>
</div>`;
}
}
customElements.define("nsite-app", NsiteApp);

View File

@ -1,4 +0,0 @@
import { SimplePool } from "nostr-tools";
export const relays = ["wss://relay.damus.io", "wss://nos.lol", "wss://nostr.wine"];
export const pool = new SimplePool();

View File

@ -1,46 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>nsite</title>
<script type="importmap">
{
"imports": {
"blossom-client-sdk": "https://esm.run/blossom-client-sdk",
"nostr-tools": "https://esm.run/nostr-tools"
}
}
</script>
</head>
<body>
<label>relays</label>
<br />
<textarea type="text" id="relays" cols="50" rows="4"></textarea>
<br />
<br />
<label>blossom servers</label>
<br />
<textarea type="text" id="servers" cols="50" rows="4"></textarea>
<br />
<br />
<input type="file" id="files" webkitdirectory directory multiple />
<button id="upload-button">Upload nsite</button>
<div
id="log"
style="
max-height: 50em;
max-width: 80em;
width: 100%;
border: 1px solid gray;
min-height: 8em;
margin: 0.5em 0;
overflow: auto;
font-size: 0.8em;
gap: 0.1em;
white-space: pre;
"
></div>
<script type="module" src="/upload/upload.js"></script>
</body>
</html>

View File

@ -1,142 +0,0 @@
import { multiServerUpload, BlossomClient } from "blossom-client-sdk";
import { SimplePool } from "nostr-tools";
const logContainer = document.getElementById("log");
function log(...args) {
const el = document.createElement("div");
el.innerText = args.join(" ");
logContainer.appendChild(el);
}
const uploadButton = document.getElementById("upload-button");
/** @type {HTMLInputElement} */
const filesInput = document.getElementById("files");
/**
* @param {FileSystemFileEntry} fileEntry
* @returns {File}
*/
export function readFileSystemFile(fileEntry) {
return new Promise((res, rej) => {
fileEntry.file(
(file) => res(file),
(err) => rej(err),
);
});
}
/**
* @param {FileSystemDirectoryEntry} directory
* @returns {FileSystemEntry[]}
*/
export function readFileSystemDirectory(directory) {
return new Promise((res, rej) => {
directory.createReader().readEntries(
(entries) => res(entries),
(err) => rej(err),
);
});
}
/**
* uploads a file system entry to blossom servers
* @param {FileSystemEntry} entry
* @returns {{file: File, path: string, sha256: string}[]}
*/
async function readFileSystemEntry(entry) {
const files = [];
if (entry instanceof FileSystemFileEntry && entry.isFile) {
try {
const file = await readFileSystemFile(entry);
const sha256 = await BlossomClient.getFileSha256(file);
const path = entry.fullPath;
files.push({ file, path, sha256 });
} catch (e) {
log("Failed to add" + entry.fullPath);
log(e.message);
}
} else if (entry instanceof FileSystemDirectoryEntry && entry.isDirectory) {
const entries = await readFileSystemDirectory(entry);
for (const e of entries) files.push(...(await readFileSystemEntry(e)));
}
return files;
}
/**
* uploads a file system entry to blossom servers
* @param {FileList} list
* @returns {{file: File, path: string, sha256: string}[]}
*/
async function readFileList(list) {
const files = [];
for (const file of list) {
const path = file.webkitRelativePath ? file.webkitRelativePath : file.name;
const sha256 = await BlossomClient.getFileSha256(file);
files.push({ file, path, sha256 });
}
return files;
}
const pool = new SimplePool();
/**
* uploads a file system entry to blossom servers
* @param {{file:File, path:string}} files
* @param {import("blossom-client-sdk").Signer} signer
* @param {*} auth
* @param {string[]} servers
* @param {string[]} relays
*/
async function uploadFiles(files, signer, auth, servers, relays) {
for (const { file, path, sha256 } of files) {
try {
const upload = multiServerUpload(servers, file, signer, auth);
let published = false;
for await (let { blob } of upload) {
if (!published) {
const signed = await signer({
kind: 34128,
content: "",
created_at: Math.round(Date.now() / 1000),
tags: [
["d", path],
["x", sha256],
],
});
await pool.publish(relays, signed);
log("Published", path, sha256, signed.id);
}
}
} catch (error) {
log(`Failed to upload ${path}`, error);
}
}
}
uploadButton.addEventListener("click", async () => {
if (!window.nostr) return alert("Missing NIP-07 signer");
const signer = (draft) => window.nostr.signEvent(draft);
const relays = document.getElementById("relays").value.split(/\n|,/);
const servers = document.getElementById("servers").value.split(/\n|,/);
try {
if (filesInput.files) {
const files = await readFileList(filesInput.files);
// strip leading dir
for (const file of files) file.path = file.path.replace(/^[^\/]+\//, "/");
log(`Found ${files.length} files`);
await uploadFiles(files, signer, undefined, servers, relays);
}
} catch (error) {
alert(`Failed to upload files: ${error.message}`);
}
});

View File

@ -1,6 +1,9 @@
import "dotenv/config";
import xbytes from "xbytes";
const NSITE_HOMEPAGE = process.env.NSITE_HOMEPAGE;
const NSITE_HOMEPAGE_DIR = process.env.NSITE_HOMEPAGE_DIR || "public";
const LOOKUP_RELAYS = process.env.LOOKUP_RELAYS?.split(",").map((u) => u.trim()) ?? [
"wss://user.kindpag.es/",
"wss://purplepag.es/",
@ -30,6 +33,8 @@ const SCREENSHOTS_DIR = process.env.SCREENSHOTS_DIR || "./screenshots";
const ONION_HOST = process.env.ONION_HOST;
export {
NSITE_HOMEPAGE,
NSITE_HOMEPAGE_DIR,
SUBSCRIPTION_RELAYS,
LOOKUP_RELAYS,
BLOSSOM_SERVERS,

View File

@ -10,6 +10,8 @@ import mime from "mime";
import morgan from "koa-morgan";
import send from "koa-send";
import { npubEncode } from "nostr-tools/nip19";
import { spawn } from "node:child_process";
import { nip19 } from "nostr-tools";
import { resolveNpubFromHostname } from "./helpers/dns.js";
import { getNsiteBlobs, parseNsiteEvent } from "./events.js";
@ -19,6 +21,8 @@ import {
ENABLE_SCREENSHOTS,
HOST,
NGINX_CACHE_DIR,
NSITE_HOMEPAGE,
NSITE_HOMEPAGE_DIR,
NSITE_HOST,
NSITE_PORT,
ONION_HOST,
@ -64,12 +68,12 @@ app.use(async (ctx, next) => {
// resolve pubkey if not in cache
if (pubkey === undefined) {
console.log(`${ctx.hostname}: Resolving`);
logger(`${ctx.hostname}: Resolving`);
pubkey = await resolveNpubFromHostname(ctx.hostname);
if (pubkey) {
await userDomains.set(ctx.hostname, pubkey);
console.log(`${ctx.hostname}: Found ${pubkey}`);
logger(`${ctx.hostname}: Found ${pubkey}`);
} else {
await userDomains.set(ctx.hostname, "");
}
@ -194,14 +198,48 @@ if (ENABLE_SCREENSHOTS) {
});
}
// download homepage
if (NSITE_HOMEPAGE) {
try {
const log = logger.extend("homepage");
// create the public dir
try {
fs.mkdirSync(NSITE_HOMEPAGE_DIR);
} catch (error) {}
const bin = (await import.meta.resolve("nsite-cli")).replace("file://", "");
const decode = nip19.decode(NSITE_HOMEPAGE);
if (decode.type !== "nprofile") throw new Error("NSITE_HOMEPAGE must be a valid nprofile");
// use nsite-cli to download the homepage
const args = [bin, "download", NSITE_HOMEPAGE_DIR, nip19.npubEncode(decode.data.pubkey)];
if (decode.data.relays) args.push("--relays", decode.data.relays?.join(","));
const child = spawn("node", args, { stdio: "pipe" });
child.on("spawn", () => log("Downloading..."));
child.stdout.on("data", (line) => log(line.toString("utf-8")));
child.on("error", (e) => log("Failed", e));
child.on("close", (code) => {
if (code === 0) log("Finished");
else log("Failed");
});
} catch (error) {
console.log(`Failed to download homepage`);
console.log(error);
}
}
// serve static files from public
const serveOptions: serve.Options = {
hidden: true,
maxAge: 60 * 60 * 1000,
index: "index.html",
};
try {
const www = path.resolve(process.cwd(), "public");
const www = NSITE_HOMEPAGE_DIR;
fs.statSync(www);
app.use(serve(www, serveOptions));
} catch (error) {
@ -210,19 +248,19 @@ try {
}
app.listen({ host: NSITE_HOST, port: NSITE_PORT }, () => {
console.log("Started on port", HOST);
logger("Started on port", HOST);
});
// invalidate nginx cache and screenshots on new events
if (SUBSCRIPTION_RELAYS.length > 0) {
console.log(`Listening for new nsite events on: ${SUBSCRIPTION_RELAYS.join(", ")}`);
logger(`Listening for new nsite events on: ${SUBSCRIPTION_RELAYS.join(", ")}`);
subscribeForEvents(SUBSCRIPTION_RELAYS, async (event) => {
try {
const nsite = parseNsiteEvent(event);
if (nsite) {
if (NGINX_CACHE_DIR) {
console.log(`${nsite.pubkey}: Invalidating ${nsite.path}`);
logger(`${nsite.pubkey}: Invalidating ${nsite.path}`);
await invalidatePubkeyPath(nsite.pubkey, nsite.path);
}
@ -243,7 +281,7 @@ process.on("unhandledRejection", (reason, promise) => {
});
async function shutdown() {
console.log("Shutting down...");
logger("Shutting down...");
pool.destroy();
process.exit(0);
}

View File

@ -1,8 +1,7 @@
import debug from "debug";
// enable default logging
if (!debug.enabled("nsite")) debug.enable("nsite");
if (!debug.enabled("nsite:*")) debug.enable("nsite:*");
if (!debug.enabled("nsite")) debug.enable("nsite,nsite:*");
const logger = debug("nsite");