Skip to content

Commit

Permalink
fix: Fallback to GitHub API for listing templates when ungh is down (#…
Browse files Browse the repository at this point in the history
…944)

Co-authored-by: Aaron <[email protected]>
  • Loading branch information
1natsu172 and aklinker1 authored Aug 29, 2024
1 parent 68183b6 commit aebbbb0
Showing 1 changed file with 56 additions and 33 deletions.
89 changes: 56 additions & 33 deletions packages/wxt/src/core/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,53 +99,74 @@ interface Template {
}

async function listTemplates(): Promise<Template[]> {
try {
const res = await fetch('https://ungh.cc/repos/wxt-dev/wxt/files/main');
if (res.status >= 300)
throw Error(`Request failed with status ${res.status} ${res.statusText}`);

const data = (await res.json()) as {
meta: {
sha: string;
};
files: Array<{
path: string;
mode: string;
sha: string;
size: number;
}>;
const templates = await listTemplatesUngh().catch((err) => {
consola.debug('Failed to load templates via ungh:', err);
return listTemplatesGithub();
});
return templates.sort((l, r) => {
const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
const diff = lWeight - rWeight;
if (diff !== 0) return diff;
return l.name.localeCompare(r.name);
});
}

async function listTemplatesUngh(): Promise<Template[]> {
const res = await fetch('https://ungh.cc/repos/wxt-dev/wxt/files/main');
if (res.status !== 200)
throw Error(
`Request failed with status ${res.status} ${res.statusText}: ${await res.text()}`,
);

const data = (await res.json()) as {
meta: {
sha: string;
};
return data.files
.map((item) => item.path.match(/templates\/(.+)\/package\.json/)?.[1])
.filter((name) => name != null)
.map((name) => ({ name: name!, path: `templates/${name}` }))
.sort((l, r) => {
const lWeight = TEMPLATE_SORT_WEIGHT[l.name] ?? Number.MAX_SAFE_INTEGER;
const rWeight = TEMPLATE_SORT_WEIGHT[r.name] ?? Number.MAX_SAFE_INTEGER;
const diff = lWeight - rWeight;
if (diff !== 0) return diff;
return l.name.localeCompare(r.name);
});
} catch (err) {
consola.error(err);
throw Error(`Failed to load templates`);
}
files: Array<{
path: string;
mode: string;
sha: string;
size: number;
}>;
};
return data.files
.map((item) => item.path.match(/templates\/(.+)\/package\.json/)?.[1])
.filter((name) => name != null)
.map((name) => ({ name: name!, path: `templates/${name}` }));
}

async function listTemplatesGithub(): Promise<Template[]> {
const res = await fetch(
`https://api.github.com/repos/${REPO}/contents/templates`,
{ headers: { Accept: 'application/vnd.github+json' } },
);
if (res.status !== 200)
throw Error(
`Request failed with status ${res.status} ${res.statusText}: ${await res.text()}`,
);

// Schema is Example4 of https://docs.github.com/en/rest/repos/contents?apiVersion=2022-11-28#get-repository-content
return (await res.json()) as Array<{
name: string;
path: string;
sha: string;
size: number;
}>;
}

async function cloneProject({
directory,
template,
packageManager,
}: {
directory: string;
template: Template;
packageManager: string;
}) {
const { default: ora } = await import('ora');
const spinner = ora('Downloading template').start();
try {
// 1. Clone repo
await downloadTemplate(`gh:wxt-dev/wxt/${template.path}`, {
await downloadTemplate(`gh:${REPO}/${template.path}`, {
dir: directory,
force: true,
});
Expand Down Expand Up @@ -180,3 +201,5 @@ const TEMPLATE_SORT_WEIGHT: Record<string, number> = {
vue: 1,
react: 2,
};

const REPO = 'wxt-dev/wxt';

0 comments on commit aebbbb0

Please sign in to comment.