Skip to content

Commit 87da20e

Browse files
committed
feat: shorten install URL by dropping /install suffix, make packages clickable to official pages
1 parent aa8809c commit 87da20e

File tree

5 files changed

+54
-8
lines changed

5 files changed

+54
-8
lines changed

src/hooks.server.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,36 @@ export const handle: Handle = async ({ event, resolve }) => {
3333
}
3434
}
3535

36+
const twoSegMatch = path.match(/^\/([a-z0-9_-]+)\/([a-z0-9_-]+)$/i);
37+
if (twoSegMatch) {
38+
const ua = event.request.headers.get('user-agent') || '';
39+
const isCurl = /^(curl|wget)\//i.test(ua);
40+
if (isCurl) {
41+
const env = event.platform?.env;
42+
if (env) {
43+
const username = twoSegMatch[1];
44+
const slug = twoSegMatch[2];
45+
46+
const user = await env.DB.prepare('SELECT id FROM users WHERE username = ?').bind(username).first<{ id: string }>();
47+
if (user) {
48+
const config = await env.DB.prepare('SELECT custom_script, is_public, dotfiles_repo FROM configs WHERE user_id = ? AND slug = ?')
49+
.bind(user.id, slug)
50+
.first<{ custom_script: string; is_public: number; dotfiles_repo: string }>();
51+
52+
if (config && config.is_public) {
53+
const script = generateInstallScript(username, slug, config.custom_script, config.dotfiles_repo || '');
54+
55+
return new Response(script, {
56+
headers: {
57+
'Content-Type': 'text/plain; charset=utf-8',
58+
'Cache-Control': 'no-cache'
59+
}
60+
});
61+
}
62+
}
63+
}
64+
}
65+
}
66+
3667
return resolve(event);
3768
};

src/routes/[username]/[slug]/+page.svelte

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
let copied = $state(false);
99
1010
function getInstallCommand() {
11-
return `curl -fsSL https://openboot.dev/${data.configUser.username}/${data.config.slug}/install | bash`;
11+
return `curl -fsSL https://openboot.dev/${data.configUser.username}/${data.config.slug} | bash`;
1212
}
1313
1414
function copyCommand() {
@@ -17,6 +17,12 @@
1717
setTimeout(() => (copied = false), 2000);
1818
}
1919
20+
function getPackageUrl(name: string, type: 'formula' | 'cask' | 'npm'): string {
21+
if (type === 'npm') return `https://www.npmjs.com/package/${name}`;
22+
if (type === 'cask') return `https://formulae.brew.sh/cask/${name}`;
23+
return `https://formulae.brew.sh/formula/${name}`;
24+
}
25+
2026
const snapshot = data.config.snapshot || {};
2127
const snapshotPkgs = snapshot.packages || {};
2228
const macosPrefs = snapshot.macos_prefs || [];
@@ -209,7 +215,7 @@
209215
{:else}
210216
<div class="package-grid">
211217
{#each formulae as pkg}
212-
<div class="package-item">{pkg}</div>
218+
<a href={getPackageUrl(pkg, 'formula')} target="_blank" rel="noopener noreferrer" class="package-item">{pkg}</a>
213219
{/each}
214220
</div>
215221
{/if}
@@ -220,7 +226,7 @@
220226
{:else}
221227
<div class="package-grid">
222228
{#each casks as pkg}
223-
<div class="package-item">{pkg}</div>
229+
<a href={getPackageUrl(pkg, 'cask')} target="_blank" rel="noopener noreferrer" class="package-item">{pkg}</a>
224230
{/each}
225231
</div>
226232
{/if}
@@ -231,7 +237,7 @@
231237
{:else}
232238
<div class="package-grid">
233239
{#each configNpm as pkg}
234-
<div class="package-item">{pkg.name}</div>
240+
<a href={getPackageUrl(pkg.name, 'npm')} target="_blank" rel="noopener noreferrer" class="package-item">{pkg.name}</a>
235241
{/each}
236242
</div>
237243
{/if}
@@ -619,12 +625,21 @@
619625
}
620626
621627
.package-item {
628+
display: block;
622629
background: var(--bg-secondary);
623630
border: 1px solid var(--border);
624631
border-radius: 6px;
625632
padding: 10px 14px;
626633
font-family: 'JetBrains Mono', monospace;
627634
font-size: 0.85rem;
635+
color: var(--text-primary);
636+
text-decoration: none;
637+
transition: border-color 0.2s, background 0.2s;
638+
}
639+
640+
.package-item:hover {
641+
border-color: var(--accent);
642+
background: var(--bg-tertiary);
628643
}
629644
630645
.prefs-list {

src/routes/api/configs/+server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export const POST: RequestHandler = async ({ platform, cookies, request }) => {
7979
return json({ error: 'Database error: ' + (e as Error).message }, { status: 500 });
8080
}
8181

82-
const installUrl = cleanAlias ? `${env.APP_URL}/${cleanAlias}` : `${env.APP_URL}/${user.username}/${slug}/install`;
82+
const installUrl = cleanAlias ? `${env.APP_URL}/${cleanAlias}` : `${env.APP_URL}/${user.username}/${slug}`;
8383

8484
return json({ id, slug, alias: cleanAlias, install_url: installUrl }, { status: 201 });
8585
};

src/routes/api/configs/[slug]/+server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const GET: RequestHandler = async ({ platform, cookies, params, request }
1212
const config = await env.DB.prepare('SELECT * FROM configs WHERE user_id = ? AND slug = ?').bind(user.id, params.slug).first();
1313
if (!config) return json({ error: 'Config not found' }, { status: 404 });
1414

15-
const installUrl = config.alias ? `${env.APP_URL}/${config.alias}` : `${env.APP_URL}/${user.username}/${params.slug}/install`;
15+
const installUrl = config.alias ? `${env.APP_URL}/${config.alias}` : `${env.APP_URL}/${user.username}/${params.slug}`;
1616

1717
const rawPkgs = JSON.parse((config.packages as string) || '[]');
1818
const needsTypeInference = rawPkgs.length > 0 && typeof rawPkgs[0] === 'string';
@@ -132,7 +132,7 @@ export const PUT: RequestHandler = async ({ platform, cookies, params, request }
132132
return json({ error: 'Database error: ' + (e as Error).message }, { status: 500 });
133133
}
134134

135-
const installUrl = newAlias ? `${env.APP_URL}/${newAlias}` : `${env.APP_URL}/${user.username}/${newSlug}/install`;
135+
const installUrl = newAlias ? `${env.APP_URL}/${newAlias}` : `${env.APP_URL}/${user.username}/${newSlug}`;
136136

137137
return json({ success: true, slug: newSlug, alias: newAlias, install_url: installUrl });
138138
};

src/routes/dashboard/+page.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@
392392
if (config.alias) {
393393
return `openboot.dev/${config.alias}`;
394394
}
395-
return `openboot.dev/${$auth.user?.username}/${config.slug}/install`;
395+
return `openboot.dev/${$auth.user?.username}/${config.slug}`;
396396
}
397397
398398
async function importBrewfile() {

0 commit comments

Comments
 (0)