diff --git a/app/components/workbench/Preview.tsx b/app/components/workbench/Preview.tsx
index 63348b9a..aaf2b9d4 100644
--- a/app/components/workbench/Preview.tsx
+++ b/app/components/workbench/Preview.tsx
@@ -773,14 +773,14 @@ export const Preview = memo(() => {
Device Options
-
Show Device Frame
diff --git a/app/routes/api.github-template.ts b/app/routes/api.github-template.ts
index e930bb7f..7a7fa8ec 100644
--- a/app/routes/api.github-template.ts
+++ b/app/routes/api.github-template.ts
@@ -4,90 +4,93 @@ import JSZip from 'jszip';
export async function loader({ request }: { request: Request }) {
const url = new URL(request.url);
const repo = url.searchParams.get('repo');
-
+
if (!repo) {
return json({ error: 'Repository name is required' }, { status: 400 });
}
-
+
try {
const baseUrl = 'https://api.github.com';
-
+
// Get the latest release
const releaseResponse = await fetch(`${baseUrl}/repos/${repo}/releases/latest`, {
headers: {
- 'Accept': 'application/vnd.github.v3+json',
+ Accept: 'application/vnd.github.v3+json',
+
// Add GitHub token if available in environment variables
- ...(process.env.GITHUB_TOKEN ? { 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}` } : {})
- }
+ ...(process.env.GITHUB_TOKEN ? { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } : {}),
+ },
});
-
+
if (!releaseResponse.ok) {
throw new Error(`GitHub API error: ${releaseResponse.status}`);
}
-
- const releaseData = await releaseResponse.json() as any;
+
+ const releaseData = (await releaseResponse.json()) as any;
const zipballUrl = releaseData.zipball_url;
-
+
// Fetch the zipball
const zipResponse = await fetch(zipballUrl, {
headers: {
- ...(process.env.GITHUB_TOKEN ? { 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}` } : {})
- }
+ ...(process.env.GITHUB_TOKEN ? { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } : {}),
+ },
});
-
+
if (!zipResponse.ok) {
throw new Error(`Failed to fetch release zipball: ${zipResponse.status}`);
}
-
+
// Get the zip content as ArrayBuffer
const zipArrayBuffer = await zipResponse.arrayBuffer();
-
+
// Use JSZip to extract the contents
const zip = await JSZip.loadAsync(zipArrayBuffer);
-
- // Process the zip contents
- const files: { name: string; path: string; content: string }[] = [];
-
+
// Find the root folder name
let rootFolderName = '';
- zip.forEach((relativePath, zipEntry) => {
+ zip.forEach((relativePath) => {
if (!rootFolderName && relativePath.includes('/')) {
rootFolderName = relativePath.split('/')[0];
}
});
-
+
// Extract all files
const promises = Object.keys(zip.files).map(async (filename) => {
const zipEntry = zip.files[filename];
-
+
// Skip directories
- if (zipEntry.dir) return null;
-
+ if (zipEntry.dir) {
+ return null;
+ }
+
// Skip the root folder itself
- if (filename === rootFolderName) return null;
-
+ if (filename === rootFolderName) {
+ return null;
+ }
+
// Remove the root folder from the path
let normalizedPath = filename;
+
if (rootFolderName && filename.startsWith(rootFolderName + '/')) {
normalizedPath = filename.substring(rootFolderName.length + 1);
}
-
+
// Get the file content
const content = await zipEntry.async('string');
-
+
return {
name: normalizedPath.split('/').pop() || '',
path: normalizedPath,
content,
};
});
-
+
const results = await Promise.all(promises);
const fileList = results.filter(Boolean) as { name: string; path: string; content: string }[];
-
+
return json(fileList);
} catch (error) {
console.error('Error processing GitHub template:', error);
return json({ error: 'Failed to fetch template files' }, { status: 500 });
}
-}
\ No newline at end of file
+}
diff --git a/app/routes/webcontainer.connect.$id.tsx b/app/routes/webcontainer.connect.$id.tsx
index ec464291..7d44b328 100644
--- a/app/routes/webcontainer.connect.$id.tsx
+++ b/app/routes/webcontainer.connect.$id.tsx
@@ -29,4 +29,4 @@ export const loader: LoaderFunction = async ({ request }) => {
return new Response(htmlContent, {
headers: { 'Content-Type': 'text/html' },
});
-};
\ No newline at end of file
+};
diff --git a/app/utils/selectStarterTemplate.ts b/app/utils/selectStarterTemplate.ts
index 293e5d61..7d26c846 100644
--- a/app/utils/selectStarterTemplate.ts
+++ b/app/utils/selectStarterTemplate.ts
@@ -2,7 +2,6 @@ import ignore from 'ignore';
import type { ProviderInfo } from '~/types/model';
import type { Template } from '~/types/template';
import { STARTER_TEMPLATES } from './constants';
-import Cookies from 'js-cookie';
const starterTemplateSelectionPrompt = (templates: Template[]) => `
You are an experienced developer who helps people choose the best starter template for their projects.
@@ -111,20 +110,18 @@ export const selectStarterTemplate = async (options: { message: string; model: s
}
};
-const getGitHubRepoContent = async (
- repoName: string,
- path: string = '',
-): Promise<{ name: string; path: string; content: string }[]> => {
+const getGitHubRepoContent = async (repoName: string): Promise<{ name: string; path: string; content: string }[]> => {
try {
// Instead of directly fetching from GitHub, use our own API endpoint as a proxy
const response = await fetch(`/api/github-template?repo=${encodeURIComponent(repoName)}`);
-
+
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
-
+
// Our API will return the files in the format we need
- const files = await response.json() as any;
+ const files = (await response.json()) as any;
+
return files;
} catch (error) {
console.error('Error fetching release contents:', error);
@@ -150,10 +147,16 @@ export async function getTemplates(templateName: string, title?: string) {
*/
filteredFiles = filteredFiles.filter((x) => x.path.startsWith('.git') == false);
- // exclude lock files
- // WE NOW INCLUDE LOCK FILES FOR IMPROVED INSTALL TIMES
- {/*const comminLockFiles = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'];
- filteredFiles = filteredFiles.filter((x) => comminLockFiles.includes(x.name) == false);*/}
+ /*
+ * exclude lock files
+ * WE NOW INCLUDE LOCK FILES FOR IMPROVED INSTALL TIMES
+ */
+ {
+ /*
+ *const comminLockFiles = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml'];
+ *filteredFiles = filteredFiles.filter((x) => comminLockFiles.includes(x.name) == false);
+ */
+ }
// exclude .bolt
filteredFiles = filteredFiles.filter((x) => x.path.startsWith('.bolt') == false);