A web app for writing and sharing 301+ character Bluesky posts.
1import fs from 'fs';
2import path from 'path';
3
4export const generateClientMetadata = (appOrigin: string) => {
5 const callbackPath = '/callback';
6 return {
7 "client_id": `${appOrigin}/client-metadata.json`,
8 "client_name": "SkeetLonger",
9 "client_uri": appOrigin,
10 "logo_uri": `${appOrigin}/logo192.png`,
11 "tos_uri": `${appOrigin}/terms-of-service`,
12 "policy_uri": `${appOrigin}/privacy-policy`,
13 "redirect_uris": [`${appOrigin}${callbackPath}`] as [string, ...string[]],
14 "scope": "atproto transition:generic",
15 "grant_types": ["authorization_code", "refresh_token"] as ["authorization_code", "refresh_token"],
16 "response_types": ["code"] as ["code"],
17 "token_endpoint_auth_method": "none" as "none",
18 "application_type": "web" as "web",
19 "dpop_bound_access_tokens": true
20 };
21}
22
23export function generateMetadataPlugin({prod, dev}:{prod: string, dev: string}) {
24 return {
25 name: 'vite-plugin-generate-metadata',
26 configResolved(config: any) {
27 let appOrigin;
28 if (config.mode === 'production') {
29 appOrigin = prod
30 if (!appOrigin || !appOrigin.startsWith('https://')) {
31 throw new Error('VITE_APP_ORIGIN environment variable must be set to a valid HTTPS URL for production build.');
32 }
33 } else {
34 appOrigin = dev;
35 }
36
37 const metadata = generateClientMetadata(appOrigin);
38 const outputPath = path.resolve(process.cwd(), 'public', 'client-metadata.json');
39
40 // Ensure public directory exists
41 const publicDir = path.resolve(process.cwd(), 'public');
42 if (!fs.existsSync(publicDir)) {
43 fs.mkdirSync(publicDir, { recursive: true });
44 }
45
46 fs.writeFileSync(outputPath, JSON.stringify(metadata, null, 2));
47 console.log(`✅ Generated client-metadata.json for ${appOrigin}`);
48 },
49 };
50}