My personal site hosted @ https://indexx.dev

feat: re-route /api/status to public.api.bsky.app

Index ff2bcd93 6065b1d8

+1
.env.example
···
···
+
PUBLIC_ACTOR_DID=""
+5 -1
astro.config.mjs
···
// @ts-check
import { defineConfig } from "astro/config";
// https://astro.build/config
-
export default defineConfig({});
···
// @ts-check
import { defineConfig } from "astro/config";
+
import react from "@astrojs/react";
+
// https://astro.build/config
+
export default defineConfig({
+
integrations: [react()],
+
});
+573 -7
package-lock.json
···
"name": "static",
"version": "0.0.1",
"dependencies": {
"@atproto/api": "^0.15.6",
"astro": "^5.7.11",
"fs": "^0.0.1-security",
"marked": "^15.0.11",
"node-cache": "^5.1.2",
"ts-node": "^10.9.2"
},
"devDependencies": {
"@types/node": "^22.15.14",
"tsx": "^4.19.4"
}
},
"node_modules/@astrojs/compiler": {
···
"node": "^18.17.1 || ^20.3.0 || >=22.0.0"
}
},
"node_modules/@astrojs/telemetry": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.2.1.tgz",
···
"zod": "^3.23.8"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
···
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
-
"version": "7.27.2",
-
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz",
-
"integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==",
"dependencies": {
-
"@babel/types": "^7.27.1"
},
"bin": {
"parser": "bin/babel-parser.js"
···
"node": ">=6.0.0"
}
},
"node_modules/@babel/types": {
-
"version": "7.27.1",
-
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz",
-
"integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
···
"url": "https://opencollective.com/libvips"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"engines": {
"node": ">=6.0.0"
}
···
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz",
"integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.4",
···
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
···
"undici-types": "~6.21.0"
}
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
···
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="
},
"node_modules/acorn": {
"version": "8.14.1",
···
"base64-js": "^1.1.2"
}
},
"node_modules/camelcase": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
···
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ccount": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
···
"resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz",
"integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="
},
"node_modules/cookie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
···
"engines": {
"node": ">=4"
}
},
"node_modules/debug": {
"version": "4.4.0",
···
"node": ">=4"
}
},
"node_modules/emoji-regex": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
···
"@esbuild/win32-arm64": "0.25.4",
"@esbuild/win32-ia32": "0.25.4",
"@esbuild/win32-x64": "0.25.4"
}
},
"node_modules/escape-string-regexp": {
···
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/get-east-asian-width": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
···
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
"integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
},
"node_modules/graphemer": {
"version": "1.4.0",
···
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
···
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
···
"resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.0.tgz",
"integrity": "sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ=="
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
···
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="
},
"node_modules/readdirp": {
"version": "4.1.2",
···
"fsevents": "~2.3.2"
}
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
···
}
}
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
···
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
"integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="
},
"node_modules/yargs-parser": {
"version": "21.1.1",
···
"name": "static",
"version": "0.0.1",
"dependencies": {
+
"@astrojs/react": "^4.3.0",
"@atproto/api": "^0.15.6",
+
"@types/react": "^19.1.6",
+
"@types/react-dom": "^19.1.6",
"astro": "^5.7.11",
"fs": "^0.0.1-security",
"marked": "^15.0.11",
"node-cache": "^5.1.2",
+
"react": "^19.1.0",
+
"react-dom": "^19.1.0",
"ts-node": "^10.9.2"
},
"devDependencies": {
"@types/node": "^22.15.14",
"tsx": "^4.19.4"
+
}
+
},
+
"node_modules/@ampproject/remapping": {
+
"version": "2.3.0",
+
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+
"dependencies": {
+
"@jridgewell/gen-mapping": "^0.3.5",
+
"@jridgewell/trace-mapping": "^0.3.24"
+
},
+
"engines": {
+
"node": ">=6.0.0"
+
}
+
},
+
"node_modules/@ampproject/remapping/node_modules/@jridgewell/trace-mapping": {
+
"version": "0.3.25",
+
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+
"dependencies": {
+
"@jridgewell/resolve-uri": "^3.1.0",
+
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@astrojs/compiler": {
···
"node": "^18.17.1 || ^20.3.0 || >=22.0.0"
}
},
+
"node_modules/@astrojs/react": {
+
"version": "4.3.0",
+
"resolved": "https://registry.npmjs.org/@astrojs/react/-/react-4.3.0.tgz",
+
"integrity": "sha512-N02aj52Iezn69qHyx5+XvPqgsPMEnel9mI5JMbGiRMTzzLMuNaxRVoQTaq2024Dpr7BLsxCjqMkNvelqMDhaHA==",
+
"dependencies": {
+
"@vitejs/plugin-react": "^4.4.1",
+
"ultrahtml": "^1.6.0",
+
"vite": "^6.3.5"
+
},
+
"engines": {
+
"node": "18.20.8 || ^20.3.0 || >=22.0.0"
+
},
+
"peerDependencies": {
+
"@types/react": "^17.0.50 || ^18.0.21 || ^19.0.0",
+
"@types/react-dom": "^17.0.17 || ^18.0.6 || ^19.0.0",
+
"react": "^17.0.2 || ^18.0.0 || ^19.0.0",
+
"react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0"
+
}
+
},
"node_modules/@astrojs/telemetry": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.2.1.tgz",
···
"zod": "^3.23.8"
}
},
+
"node_modules/@babel/code-frame": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
+
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
+
"dependencies": {
+
"@babel/helper-validator-identifier": "^7.27.1",
+
"js-tokens": "^4.0.0",
+
"picocolors": "^1.1.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/compat-data": {
+
"version": "7.27.5",
+
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.27.5.tgz",
+
"integrity": "sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==",
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/core": {
+
"version": "7.27.4",
+
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz",
+
"integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==",
+
"dependencies": {
+
"@ampproject/remapping": "^2.2.0",
+
"@babel/code-frame": "^7.27.1",
+
"@babel/generator": "^7.27.3",
+
"@babel/helper-compilation-targets": "^7.27.2",
+
"@babel/helper-module-transforms": "^7.27.3",
+
"@babel/helpers": "^7.27.4",
+
"@babel/parser": "^7.27.4",
+
"@babel/template": "^7.27.2",
+
"@babel/traverse": "^7.27.4",
+
"@babel/types": "^7.27.3",
+
"convert-source-map": "^2.0.0",
+
"debug": "^4.1.0",
+
"gensync": "^1.0.0-beta.2",
+
"json5": "^2.2.3",
+
"semver": "^6.3.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
},
+
"funding": {
+
"type": "opencollective",
+
"url": "https://opencollective.com/babel"
+
}
+
},
+
"node_modules/@babel/core/node_modules/semver": {
+
"version": "6.3.1",
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+
"bin": {
+
"semver": "bin/semver.js"
+
}
+
},
+
"node_modules/@babel/generator": {
+
"version": "7.27.5",
+
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.5.tgz",
+
"integrity": "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==",
+
"dependencies": {
+
"@babel/parser": "^7.27.5",
+
"@babel/types": "^7.27.3",
+
"@jridgewell/gen-mapping": "^0.3.5",
+
"@jridgewell/trace-mapping": "^0.3.25",
+
"jsesc": "^3.0.2"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/generator/node_modules/@jridgewell/trace-mapping": {
+
"version": "0.3.25",
+
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+
"dependencies": {
+
"@jridgewell/resolve-uri": "^3.1.0",
+
"@jridgewell/sourcemap-codec": "^1.4.14"
+
}
+
},
+
"node_modules/@babel/helper-compilation-targets": {
+
"version": "7.27.2",
+
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
+
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
+
"dependencies": {
+
"@babel/compat-data": "^7.27.2",
+
"@babel/helper-validator-option": "^7.27.1",
+
"browserslist": "^4.24.0",
+
"lru-cache": "^5.1.1",
+
"semver": "^6.3.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+
"version": "5.1.1",
+
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+
"dependencies": {
+
"yallist": "^3.0.2"
+
}
+
},
+
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
+
"version": "6.3.1",
+
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+
"bin": {
+
"semver": "bin/semver.js"
+
}
+
},
+
"node_modules/@babel/helper-module-imports": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+
"dependencies": {
+
"@babel/traverse": "^7.27.1",
+
"@babel/types": "^7.27.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/helper-module-transforms": {
+
"version": "7.27.3",
+
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz",
+
"integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==",
+
"dependencies": {
+
"@babel/helper-module-imports": "^7.27.1",
+
"@babel/helper-validator-identifier": "^7.27.1",
+
"@babel/traverse": "^7.27.3"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
},
+
"peerDependencies": {
+
"@babel/core": "^7.0.0"
+
}
+
},
+
"node_modules/@babel/helper-plugin-utils": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
+
"integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
···
"node": ">=6.9.0"
}
},
+
"node_modules/@babel/helper-validator-option": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
+
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/helpers": {
+
"version": "7.27.4",
+
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.4.tgz",
+
"integrity": "sha512-Y+bO6U+I7ZKaM5G5rDUZiYfUvQPUibYmAFe7EnKdnKBbVXDZxvp+MWOH5gYciY0EPk4EScsuFMQBbEfpdRKSCQ==",
+
"dependencies": {
+
"@babel/template": "^7.27.2",
+
"@babel/types": "^7.27.3"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
"node_modules/@babel/parser": {
+
"version": "7.27.5",
+
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.5.tgz",
+
"integrity": "sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==",
"dependencies": {
+
"@babel/types": "^7.27.3"
},
"bin": {
"parser": "bin/babel-parser.js"
···
"node": ">=6.0.0"
}
},
+
"node_modules/@babel/plugin-transform-react-jsx-self": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz",
+
"integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==",
+
"dependencies": {
+
"@babel/helper-plugin-utils": "^7.27.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
},
+
"peerDependencies": {
+
"@babel/core": "^7.0.0-0"
+
}
+
},
+
"node_modules/@babel/plugin-transform-react-jsx-source": {
+
"version": "7.27.1",
+
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz",
+
"integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==",
+
"dependencies": {
+
"@babel/helper-plugin-utils": "^7.27.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
},
+
"peerDependencies": {
+
"@babel/core": "^7.0.0-0"
+
}
+
},
+
"node_modules/@babel/template": {
+
"version": "7.27.2",
+
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+
"dependencies": {
+
"@babel/code-frame": "^7.27.1",
+
"@babel/parser": "^7.27.2",
+
"@babel/types": "^7.27.1"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
+
"node_modules/@babel/traverse": {
+
"version": "7.27.4",
+
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.4.tgz",
+
"integrity": "sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==",
+
"dependencies": {
+
"@babel/code-frame": "^7.27.1",
+
"@babel/generator": "^7.27.3",
+
"@babel/parser": "^7.27.4",
+
"@babel/template": "^7.27.2",
+
"@babel/types": "^7.27.3",
+
"debug": "^4.3.1",
+
"globals": "^11.1.0"
+
},
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
"node_modules/@babel/types": {
+
"version": "7.27.3",
+
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.3.tgz",
+
"integrity": "sha512-Y1GkI4ktrtvmawoSq+4FCVHNryea6uR+qUQy0AGxLSsjCX0nVmkYQMBLHDkXZuo5hGx7eYdnIaslsdBFm7zbUw==",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
···
"url": "https://opencollective.com/libvips"
}
},
+
"node_modules/@jridgewell/gen-mapping": {
+
"version": "0.3.8",
+
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
+
"dependencies": {
+
"@jridgewell/set-array": "^1.2.1",
+
"@jridgewell/sourcemap-codec": "^1.4.10",
+
"@jridgewell/trace-mapping": "^0.3.24"
+
},
+
"engines": {
+
"node": ">=6.0.0"
+
}
+
},
+
"node_modules/@jridgewell/gen-mapping/node_modules/@jridgewell/trace-mapping": {
+
"version": "0.3.25",
+
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+
"dependencies": {
+
"@jridgewell/resolve-uri": "^3.1.0",
+
"@jridgewell/sourcemap-codec": "^1.4.14"
+
}
+
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+
"engines": {
+
"node": ">=6.0.0"
+
}
+
},
+
"node_modules/@jridgewell/set-array": {
+
"version": "1.2.1",
+
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"engines": {
"node": ">=6.0.0"
}
···
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz",
"integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ=="
+
},
+
"node_modules/@rolldown/pluginutils": {
+
"version": "1.0.0-beta.9",
+
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.9.tgz",
+
"integrity": "sha512-e9MeMtVWo186sgvFFJOPGy7/d2j2mZhLJIdVW0C/xDluuOvymEATqz6zKsP0ZmXGzQtqlyjz5sC1sYQUoJG98w=="
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.4",
···
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA=="
},
+
"node_modules/@types/babel__core": {
+
"version": "7.20.5",
+
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+
"integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+
"dependencies": {
+
"@babel/parser": "^7.20.7",
+
"@babel/types": "^7.20.7",
+
"@types/babel__generator": "*",
+
"@types/babel__template": "*",
+
"@types/babel__traverse": "*"
+
}
+
},
+
"node_modules/@types/babel__generator": {
+
"version": "7.27.0",
+
"resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+
"integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+
"dependencies": {
+
"@babel/types": "^7.0.0"
+
}
+
},
+
"node_modules/@types/babel__template": {
+
"version": "7.4.4",
+
"resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+
"integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+
"dependencies": {
+
"@babel/parser": "^7.1.0",
+
"@babel/types": "^7.0.0"
+
}
+
},
+
"node_modules/@types/babel__traverse": {
+
"version": "7.20.7",
+
"resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz",
+
"integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==",
+
"dependencies": {
+
"@babel/types": "^7.20.7"
+
}
+
},
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
···
"undici-types": "~6.21.0"
}
},
+
"node_modules/@types/react": {
+
"version": "19.1.6",
+
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz",
+
"integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==",
+
"dependencies": {
+
"csstype": "^3.0.2"
+
}
+
},
+
"node_modules/@types/react-dom": {
+
"version": "19.1.6",
+
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
+
"integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
+
"peerDependencies": {
+
"@types/react": "^19.0.0"
+
}
+
},
"node_modules/@types/unist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
···
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
"integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="
+
},
+
"node_modules/@vitejs/plugin-react": {
+
"version": "4.5.1",
+
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.5.1.tgz",
+
"integrity": "sha512-uPZBqSI0YD4lpkIru6M35sIfylLGTyhGHvDZbNLuMA73lMlwJKz5xweH7FajfcCAc2HnINciejA9qTz0dr0M7A==",
+
"dependencies": {
+
"@babel/core": "^7.26.10",
+
"@babel/plugin-transform-react-jsx-self": "^7.25.9",
+
"@babel/plugin-transform-react-jsx-source": "^7.25.9",
+
"@rolldown/pluginutils": "1.0.0-beta.9",
+
"@types/babel__core": "^7.20.5",
+
"react-refresh": "^0.17.0"
+
},
+
"engines": {
+
"node": "^14.18.0 || >=16.0.0"
+
},
+
"peerDependencies": {
+
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0"
+
}
},
"node_modules/acorn": {
"version": "8.14.1",
···
"base64-js": "^1.1.2"
}
},
+
"node_modules/browserslist": {
+
"version": "4.25.0",
+
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.0.tgz",
+
"integrity": "sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==",
+
"funding": [
+
{
+
"type": "opencollective",
+
"url": "https://opencollective.com/browserslist"
+
},
+
{
+
"type": "tidelift",
+
"url": "https://tidelift.com/funding/github/npm/browserslist"
+
},
+
{
+
"type": "github",
+
"url": "https://github.com/sponsors/ai"
+
}
+
],
+
"dependencies": {
+
"caniuse-lite": "^1.0.30001718",
+
"electron-to-chromium": "^1.5.160",
+
"node-releases": "^2.0.19",
+
"update-browserslist-db": "^1.1.3"
+
},
+
"bin": {
+
"browserslist": "cli.js"
+
},
+
"engines": {
+
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+
}
+
},
"node_modules/camelcase": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
···
"url": "https://github.com/sponsors/sindresorhus"
}
},
+
"node_modules/caniuse-lite": {
+
"version": "1.0.30001721",
+
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001721.tgz",
+
"integrity": "sha512-cOuvmUVtKrtEaoKiO0rSc29jcjwMwX5tOHDy4MgVFEWiUXj4uBMJkwI8MDySkgXidpMiHUcviogAvFi4pA2hDQ==",
+
"funding": [
+
{
+
"type": "opencollective",
+
"url": "https://opencollective.com/browserslist"
+
},
+
{
+
"type": "tidelift",
+
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+
},
+
{
+
"type": "github",
+
"url": "https://github.com/sponsors/ai"
+
}
+
]
+
},
"node_modules/ccount": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz",
···
"resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz",
"integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="
},
+
"node_modules/convert-source-map": {
+
"version": "2.0.0",
+
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+
},
"node_modules/cookie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
···
"engines": {
"node": ">=4"
}
+
},
+
"node_modules/csstype": {
+
"version": "3.1.3",
+
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/debug": {
"version": "4.4.0",
···
"node": ">=4"
}
},
+
"node_modules/electron-to-chromium": {
+
"version": "1.5.165",
+
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.165.tgz",
+
"integrity": "sha512-naiMx1Z6Nb2TxPU6fiFrUrDTjyPMLdTtaOd2oLmG8zVSg2hCWGkhPyxwk+qRmZ1ytwVqUv0u7ZcDA5+ALhaUtw=="
+
},
"node_modules/emoji-regex": {
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
···
"@esbuild/win32-arm64": "0.25.4",
"@esbuild/win32-ia32": "0.25.4",
"@esbuild/win32-x64": "0.25.4"
+
}
+
},
+
"node_modules/escalade": {
+
"version": "3.2.0",
+
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+
"engines": {
+
"node": ">=6"
}
},
"node_modules/escape-string-regexp": {
···
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+
"node_modules/gensync": {
+
"version": "1.0.0-beta.2",
+
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+
"engines": {
+
"node": ">=6.9.0"
+
}
+
},
"node_modules/get-east-asian-width": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
···
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
"integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw=="
+
},
+
"node_modules/globals": {
+
"version": "11.12.0",
+
"resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+
"integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+
"engines": {
+
"node": ">=4"
+
}
},
"node_modules/graphemer": {
"version": "1.4.0",
···
"resolved": "https://registry.npmjs.org/iso-datestring-validator/-/iso-datestring-validator-2.2.2.tgz",
"integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA=="
},
+
"node_modules/js-tokens": {
+
"version": "4.0.0",
+
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+
},
"node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
···
"js-yaml": "bin/js-yaml.js"
}
},
+
"node_modules/jsesc": {
+
"version": "3.1.0",
+
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+
"bin": {
+
"jsesc": "bin/jsesc"
+
},
+
"engines": {
+
"node": ">=6"
+
}
+
},
+
"node_modules/json5": {
+
"version": "2.2.3",
+
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+
"bin": {
+
"json5": "lib/cli.js"
+
},
+
"engines": {
+
"node": ">=6"
+
}
+
},
"node_modules/kleur": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
···
"resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.0.tgz",
"integrity": "sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ=="
},
+
"node_modules/node-releases": {
+
"version": "2.0.19",
+
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="
+
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
···
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz",
"integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA=="
+
},
+
"node_modules/react": {
+
"version": "19.1.0",
+
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
+
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
+
"engines": {
+
"node": ">=0.10.0"
+
}
+
},
+
"node_modules/react-dom": {
+
"version": "19.1.0",
+
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
+
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
+
"dependencies": {
+
"scheduler": "^0.26.0"
+
},
+
"peerDependencies": {
+
"react": "^19.1.0"
+
}
+
},
+
"node_modules/react-refresh": {
+
"version": "0.17.0",
+
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
+
"integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==",
+
"engines": {
+
"node": ">=0.10.0"
+
}
},
"node_modules/readdirp": {
"version": "4.1.2",
···
"fsevents": "~2.3.2"
}
},
+
"node_modules/scheduler": {
+
"version": "0.26.0",
+
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+
"integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="
+
},
"node_modules/semver": {
"version": "7.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
···
}
}
},
+
"node_modules/update-browserslist-db": {
+
"version": "1.1.3",
+
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
+
"funding": [
+
{
+
"type": "opencollective",
+
"url": "https://opencollective.com/browserslist"
+
},
+
{
+
"type": "tidelift",
+
"url": "https://tidelift.com/funding/github/npm/browserslist"
+
},
+
{
+
"type": "github",
+
"url": "https://github.com/sponsors/ai"
+
}
+
],
+
"dependencies": {
+
"escalade": "^3.2.0",
+
"picocolors": "^1.1.1"
+
},
+
"bin": {
+
"update-browserslist-db": "cli.js"
+
},
+
"peerDependencies": {
+
"browserslist": ">= 4.21.0"
+
}
+
},
"node_modules/v8-compile-cache-lib": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
···
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz",
"integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA=="
+
},
+
"node_modules/yallist": {
+
"version": "3.1.1",
+
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/yargs-parser": {
"version": "21.1.1",
+5
package.json
···
"astro": "astro"
},
"dependencies": {
"@atproto/api": "^0.15.6",
"astro": "^5.7.11",
"fs": "^0.0.1-security",
"marked": "^15.0.11",
"node-cache": "^5.1.2",
"ts-node": "^10.9.2"
},
"devDependencies": {
···
"astro": "astro"
},
"dependencies": {
+
"@astrojs/react": "^4.3.0",
"@atproto/api": "^0.15.6",
+
"@types/react": "^19.1.6",
+
"@types/react-dom": "^19.1.6",
"astro": "^5.7.11",
"fs": "^0.0.1-security",
"marked": "^15.0.11",
"node-cache": "^5.1.2",
+
"react": "^19.1.0",
+
"react-dom": "^19.1.0",
"ts-node": "^10.9.2"
},
"devDependencies": {
-37
src/components/Status.astro
···
-
---
-
type StatusRes = {
-
text: string,
-
createdAt: string,
-
link: string
-
}
-
-
const url = new URL("/api/status", Astro.request.url);
-
const data = await fetch(url);
-
const { text, createdAt, link } = await data.json() as StatusRes;
-
-
function getRelativeTime(dateStr: string) {
-
const date = new Date(dateStr);
-
const now = new Date();
-
const diff = now.getTime() - date.getTime();
-
-
const minutes = Math.floor(diff / 60000);
-
const hours = Math.floor(minutes / 60);
-
const days = Math.floor(hours / 24);
-
-
if (days > 0) return `${days} days ago`;
-
if (hours > 0) return `${hours} hours ago`;
-
if (minutes > 0) return `${minutes} minutes ago`;
-
return 'just now';
-
}
-
-
const timeAgo = getRelativeTime(createdAt);
-
-
const date = new Date(createdAt);
-
const now = new Date();
-
const diff = now.getTime() - date.getTime();
-
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
-
-
const oldStatusClasses = days > 3 ? 'opacity-75 text-decoration-line-through' : '';
-
---
-
-
<a href={link} target="_blank" class={`badge bg-white ${oldStatusClasses}`}>Index is.. "{text}", {timeAgo}</a>
···
+76
src/components/Status.jsx
···
···
+
import { useEffect, useState } from "react";
+
const actorDid = import.meta.env.PUBLIC_ACTOR_DID;
+
+
if (!actorDid) {
+
console.error(
+
"PUBLIC_ACTOR_DID is not defined. Please check your .env file.",
+
);
+
}
+
+
export default function Status() {
+
const [data, setData] = useState(null);
+
const [error, setError] = useState(null);
+
+
useEffect(() => {
+
console.log("gettin dat damn sattus directly from bsky");
+
const fetchStatus = async () => {
+
if (!actorDid) {
+
setError("Configuration error: Actor DID is missing.");
+
return;
+
}
+
try {
+
const res = await fetch(
+
`https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${actorDid}&limit=1&filter=posts_no_replies`,
+
);
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
+
+
const json = await res.json();
+
const latestPost = json.feed[0].post;
+
+
const status = {
+
text: latestPost.record.text,
+
createdAt: latestPost.record.createdAt,
+
link: `https://bsky.app/profile/${actorDid}/post/${
+
latestPost.uri.split("/")[4]
+
}`,
+
};
+
setData(status);
+
} catch (err) {
+
console.error("Fetch failed:", err);
+
setError(err.message);
+
}
+
};
+
+
fetchStatus();
+
}, [actorDid]);
+
+
if (error) return <span>Error: {error}</span>;
+
if (!data) return <span>Loading status...</span>;
+
+
const date = new Date(data.createdAt);
+
const now = new Date();
+
const diff = now.getTime() - date.getTime();
+
+
const minutes = Math.floor(diff / 60000);
+
const hours = Math.floor(minutes / 60);
+
const days = Math.floor(hours / 24);
+
+
let timeAgo = "just now";
+
if (days > 0) timeAgo = `${days} days ago`;
+
else if (hours > 0) timeAgo = `${hours} hours ago`;
+
else if (minutes > 0) timeAgo = `${minutes} minutes ago`;
+
+
const oldStatusClasses = days > 3
+
? "opacity-75 text-decoration-line-through"
+
: "";
+
+
return (
+
<a
+
href={data.link}
+
target="_blank"
+
className={`badge bg-white ${oldStatusClasses}`}
+
>
+
Index is.. "{data.text}", {timeAgo}
+
</a>
+
);
+
}
-75
src/pages/api/status.ts
···
-
import type { APIRoute } from "astro";
-
import NodeCache from "node-cache";
-
-
const cache = new NodeCache({ stdTTL: 300 }); // cache for 5 minutes
-
const actorDid = "did:plc:zl4ugdpxfgrzlr5uz2nm7kcq";
-
-
type FeedResponse = {
-
feed: {
-
post: {
-
uri: string;
-
cid: string;
-
author: {
-
did: string;
-
handle: string;
-
displayName: string;
-
avatar: string;
-
labels: any[];
-
createdAt: string;
-
};
-
record: {
-
$type: string;
-
createdAt: string;
-
text: string;
-
};
-
replyCount: number;
-
repostCount: number;
-
likeCount: number;
-
quoteCount: number;
-
indexedAt: string;
-
labels: any[];
-
};
-
}[];
-
cursor: string;
-
};
-
-
export const GET: APIRoute = async () => {
-
let status = cache.get("status");
-
-
if (status) {
-
return new Response(JSON.stringify(status), {
-
headers: { "Content-Type": "application/json", "X-Cache": "HIT" },
-
});
-
}
-
-
try {
-
const res = await fetch(
-
`https://public.api.bsky.app/xrpc/app.bsky.feed.getAuthorFeed?actor=${actorDid}&limit=1&filter=posts_no_replies`,
-
);
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
-
-
const json: FeedResponse = await res.json();
-
const latestPost = json.feed[0].post;
-
status = {
-
text: latestPost.record.text,
-
createdAt: latestPost.record.createdAt,
-
link: `https://bsky.app/profile/${actorDid}/post/${
-
latestPost.uri.split("/")[4]
-
}`,
-
};
-
-
cache.set("status", status);
-
-
return new Response(JSON.stringify(status), {
-
headers: { "Content-Type": "application/json", "X-Cache": "MISS" },
-
});
-
} catch (err) {
-
return new Response(
-
JSON.stringify({ error: "Failed to fetch status" }),
-
{
-
status: 500,
-
headers: { "Content-Type": "application/json" },
-
},
-
);
-
}
-
};
···
+2 -2
src/pages/index.astro
···
import Header from "../components/Header.astro";
import SocialLinks from "../components/SocialLinks.astro";
-
import Status from "../components/Status.astro";
import ProjectsPane from "../components/ProjectsPane.astro";
---
<Layout title="hello" description="insert wave emoji">
<main id="page" class="text-center">
<Header />
-
<Status />
<SocialLinks />
<a
id="projects-button"
···
import Header from "../components/Header.astro";
import SocialLinks from "../components/SocialLinks.astro";
+
import Status from '../components/Status.jsx';
import ProjectsPane from "../components/ProjectsPane.astro";
---
<Layout title="hello" description="insert wave emoji">
<main id="page" class="text-center">
<Header />
+
<Status client:load />
<SocialLinks />
<a
id="projects-button"
+12 -3
tsconfig.json
···
{
"extends": "astro/tsconfigs/strict",
-
"include": [".astro/types.d.ts", "**/*"],
-
"exclude": ["dist"]
-
}
···
{
"extends": "astro/tsconfigs/strict",
+
"include": [
+
".astro/types.d.ts",
+
"**/*"
+
],
+
"exclude": [
+
"dist"
+
],
+
"compilerOptions": {
+
"jsx": "react-jsx",
+
"jsxImportSource": "react"
+
}
+
}