1.0.36
This commit is contained in:
63 files changed
+1324
-281
No files matched your search
@@ -20,6 +20,47 @@ export interface TemplateItem {
|
||||
stars?: number;
|
||||
pulls?: number;
|
||||
network?: string;
|
||||
/** Free-form maintainer / install notes from the upstream catalog. */
|
||||
note?: string;
|
||||
/** Project / homepage URL the user can click to learn more or report issues (#1211). */
|
||||
projectUrl?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort first-URL extraction from a template's description or note.
|
||||
* Order matters: markdown link first, then HTML href, then a bare URL.
|
||||
*/
|
||||
function extractFirstUrl(text: string | undefined | null): string | null {
|
||||
if (!text) return null;
|
||||
const md = text.match(/\[[^\]]+\]\((https?:\/\/[^)]+)\)/);
|
||||
if (md) return md[1];
|
||||
const html = text.match(/<a\s+[^>]*href=["']([^"']+)["']/i);
|
||||
if (html) return html[1];
|
||||
const plain = text.match(/(https?:\/\/[^\s<>"')]+)/);
|
||||
if (plain) return plain[1];
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the "Project" URL surfaced on the card.
|
||||
* Priority:
|
||||
* 1. URL embedded in `description` — LSIO-style templates have a markdown
|
||||
* link to the actual project repo here, which is what users want most.
|
||||
* 2. URL embedded in `note` — Portainer v3 catalogs often put a homepage
|
||||
* link in the install notes.
|
||||
* 3. `maintainer` field — Lissy93's templates carry a per-template
|
||||
* maintainer URL; not always the project itself but usually close.
|
||||
* 4. `repository.url` — only for stack-type templates, points to the repo
|
||||
* hosting the compose file (closest thing we have).
|
||||
*/
|
||||
function resolveProjectUrl(entry: any, description: string, note: string): string | undefined {
|
||||
return (
|
||||
extractFirstUrl(description) ||
|
||||
extractFirstUrl(note) ||
|
||||
(typeof entry.maintainer === 'string' ? entry.maintainer.trim() : null) ||
|
||||
(entry.repository && typeof entry.repository.url === 'string' ? entry.repository.url : null) ||
|
||||
undefined
|
||||
);
|
||||
}
|
||||
|
||||
// Server-side cache: url → { data, fetchedAt }
|
||||
@@ -43,14 +84,18 @@ function normalizePortainerTemplate(entry: any, sourceName: string): TemplateIte
|
||||
if (entry.type === 2) return null;
|
||||
|
||||
const title = entry.title || entry.name || '';
|
||||
const description = entry.description || '';
|
||||
const note = typeof entry.note === 'string' ? entry.note : '';
|
||||
const template: TemplateItem = {
|
||||
id: hashId(sourceName, title),
|
||||
type: entry.type === 3 ? 'stack' : 'container',
|
||||
title,
|
||||
description: entry.description || '',
|
||||
description,
|
||||
logo: entry.logo || '',
|
||||
categories: Array.isArray(entry.categories) ? entry.categories : [],
|
||||
source: sourceName,
|
||||
note: note || undefined,
|
||||
projectUrl: resolveProjectUrl(entry, description, note)
|
||||
};
|
||||
|
||||
if (entry.type === 3 && entry.repository) {
|
||||
@@ -77,11 +122,18 @@ function normalizePortainerTemplate(entry: any, sourceName: string): TemplateIte
|
||||
function normalizeLinuxServerTemplate(entry: any): TemplateItem | null {
|
||||
if (!entry.name || entry.deprecated) return null;
|
||||
|
||||
const description = entry.description || '';
|
||||
// LSIO fleet entries sometimes carry a project_url; prefer it over regex sniffing.
|
||||
const projectUrl =
|
||||
(typeof entry.project_url === 'string' && entry.project_url) ||
|
||||
extractFirstUrl(description) ||
|
||||
`https://github.com/linuxserver/docker-${entry.name}`;
|
||||
|
||||
return {
|
||||
id: hashId('LinuxServer.io', entry.name),
|
||||
type: 'container',
|
||||
title: entry.name,
|
||||
description: entry.description || '',
|
||||
description,
|
||||
logo: entry.project_logo || '',
|
||||
categories: entry.category ? entry.category.split(',').map((c: string) => c.trim()).filter(Boolean) : [],
|
||||
source: 'LinuxServer.io',
|
||||
@@ -94,6 +146,7 @@ function normalizeLinuxServerTemplate(entry: any): TemplateItem | null {
|
||||
restartPolicy: 'unless-stopped',
|
||||
stars: entry.stars,
|
||||
pulls: entry.monthly_pulls,
|
||||
projectUrl
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user