diff --git a/__tests__/integration/api.spec.ts b/__tests__/integration/api.spec.ts
deleted file mode 100644
index 5d3d989..0000000
--- a/__tests__/integration/api.spec.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-/* eslint-disable no-unused-expressions */
-// eslint-disable-next-line spaced-comment
-///
-import JSZip from 'jszip';
-
-/**
- * repo link: git, zip
- * git: commit id, branch, tag
- * subdirectory: undefined, existing, non-existing
- */
-describe('Test valid fetch', () => {
- beforeEach(() => {
- cy.viewport(1920, 1080);
- cy.visit('http://localhost:3000');
- });
-
- it('zip file', () => {
- const expected = ['test', 'main'];
- const url =
- 'https://code.quarkus.io/d?e=io.quarkus%3Aquarkus-resteasy&e=io.quarkus%3Aquarkus-micrometer&e=io.quarkus%3Aquarkus-smallrye-health&e=io.quarkus%3Aquarkus-openshift&cn=devfile';
- checkForValidZipFetch(url, 'src', expected);
- });
-
- it('git file', () => {
- const expected = ['src', 'README.adoc', 'pom.xml'];
- checkForValidZipFetch(
- 'https://api.github.com/repos/wildfly/quickstart/zipball/',
- 'microprofile-health',
- expected,
- );
- });
-
- it('git repo with tag', () => {
- const expected = ['src', 'README.adoc', 'pom.xml'];
- checkForValidZipFetch(
- 'https://api.github.com/repos/wildfly/quickstart/zipball/23.0.2.Final',
- 'microprofile-health',
- expected,
- );
- });
-
- it('git repo with commit ID', () => {
- const expected = ['src', 'README.adoc', 'pom.xml'];
- checkForValidZipFetch(
- 'https://api.github.com/repos/wildfly/quickstart/zipball/66661cf477f74f60c12de40b9d84ce13576e6f44',
- 'microprofile-opentracing',
- expected,
- );
- });
-});
-
-describe('Test invalid fetch', () => {
- beforeEach(() => {
- cy.viewport(1920, 1080);
- cy.visit('http://localhost:3000');
- });
-
- it('zip file with non-existing subdirectory', () => {
- const data = {
- url: 'https://code.quarkus.io/d?e=io.quarkus%3Aquarkus-resteasy&e=io.quarkus%3Aquarkus-micrometer&e=io.quarkus%3Aquarkus-smallrye-health&e=io.quarkus%3Aquarkus-openshift&cn=devfile',
- subdirectory: 'non-existing',
- };
- cy.request({
- url: '/api/download-subdirectory',
- failOnStatusCode: false,
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }).should(async (response) => {
- expect(response.status).to.eq(404);
- });
- });
-
- it('zip file with non-existing link', () => {
- const data = {
- url: 'https://non-existing.com/',
- subdirectory: 'non-existing',
- };
- cy.request({
- url: '/api/download-subdirectory',
- failOnStatusCode: false,
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }).should(async (response) => {
- expect(response.status).to.eq(500);
- });
- });
-});
-
-/**
- * Compares two arrays for equality
- * @param a - array to compare
- * @param b - array to compare
- * @returns boolean of whether arrays a and b are equal
- */
-function areArraysEqual(a: T, b: T): boolean {
- return (
- Array.isArray(a) &&
- Array.isArray(b) &&
- a.length === b.length &&
- a.every((val, index) => val === b[index])
- );
-}
-
-/**
- * Checks that fetch for extracting the subdirectory returns the right zip by
- * * checking status of response (should be 200)
- * * checking files and folders at first level of zip (should equal @param expectedRootFileAndFolders-)
- * @param url - url to fetch zip from
- * @param subdirectory - subdirectory to extract from zip
- * @param expectedRootFileAndFolders - expected files and folders at first level of zip
- */
-function checkForValidZipFetch(
- url: string,
- subdirectory: string,
- expectedRootFileAndFolders: string[],
-): void {
- const data = {
- url,
- subdirectory,
- };
- const expected = expectedRootFileAndFolders;
- expected.sort((a, b) => a.localeCompare(b));
-
- cy.request({
- url: '/api/download-subdirectory',
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- }).should(async (response) => {
- expect(response.status).to.eq(200);
-
- const array = await response.body;
- const zip = await JSZip.loadAsync(array, { base64: true });
-
- const zipFiles = new Array();
- Object.keys(zip.files).forEach((fileName) => {
- const firstLevelDirectory = fileName.split('/')[0];
- if (!zipFiles.includes(firstLevelDirectory)) {
- zipFiles.push(firstLevelDirectory);
- }
- });
- zipFiles.sort((a, b) => a.localeCompare(b));
-
- expect(areArraysEqual(zipFiles, expected)).to.be.true;
- });
-}
-
-export {};
diff --git a/pages/api/download-subdirectory.ts b/pages/api/download-subdirectory.ts
deleted file mode 100644
index f5f53ae..0000000
--- a/pages/api/download-subdirectory.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-import { NextApiRequest, NextApiResponse } from 'next';
-import JSZip from 'jszip';
-/**
- * request handler for subdirectory download
- * @param req - request body
- * @param res - response body
- */
-export default async function handler(
- req: NextApiRequest,
- res: NextApiResponse,
-): Promise {
- try {
- const data = req.body;
- const response = await fetch(data.url);
- const array = await response.arrayBuffer();
-
- const zip = await JSZip.loadAsync(array, {});
-
- const notFound = Object.keys(zip.files).every((fileName) => {
- const firstLevelDirectory = fileName.split('/')[1];
- return firstLevelDirectory !== data.subdirectory;
- });
- if (notFound) {
- throw TypeError('subdirectory does not exist');
- }
-
- const rootName = Object.keys(zip.files)[0];
- const subdirectoryZip = zip.folder(rootName)?.folder(data.subdirectory);
-
- if (!subdirectoryZip) {
- throw Error('subdirectory zip is null');
- }
- const base64Send = await subdirectoryZip.generateAsync({ type: 'base64' });
-
- res.status(200);
- res.send(base64Send);
- res.end();
- } catch (e) {
- const error = e as Error;
- if (error.toString().includes('subdirectory does not exist')) {
- res.status(404);
- } else {
- res.status(500);
- }
- res.json({ error: error.toString() });
- res.end();
- }
-}
diff --git a/src/components/DevfilePage/DevfilePageProjects/DevfilePageProjects.tsx b/src/components/DevfilePage/DevfilePageProjects/DevfilePageProjects.tsx
index 9b6e764..ffc06bb 100644
--- a/src/components/DevfilePage/DevfilePageProjects/DevfilePageProjects.tsx
+++ b/src/components/DevfilePage/DevfilePageProjects/DevfilePageProjects.tsx
@@ -1,7 +1,7 @@
import styles from './DevfilePageProjects.module.css';
import type { Project, DefaultProps, Devfile } from 'custom-types';
import { DevfilePageProjectDisplay } from '@src/components';
-import { download, UnsupportedLinkError, getUserRegion } from '@src/util/client';
+import { getUserRegion } from '@src/util/client';
import {
Alert,
AlertActionLink,
@@ -72,11 +72,11 @@ export const DevfilePageProjects: React.FC = ({
const router = useRouter();
- async function triggerDownload(project: Project): Promise {
+ async function downloadStarterProject(devfile: Devfile, project: Project): Promise {
setDownloading(true);
try {
- await download(project);
+ window.open(`${devfile.registryLink}/starter-projects/${project.name}`);
if (analytics) {
const region = getUserRegion(router.locale);
@@ -96,22 +96,13 @@ export const DevfilePageProjects: React.FC = ({
);
}
} catch (error) {
- if (error instanceof UnsupportedLinkError) {
- setErrorAlert({
- name: 'Unsupported Link',
- error: error.toString(),
- message: error.message,
- alertType: 'warning',
- });
- } else {
- setErrorAlert({
- name: 'Download Error',
- error: (error as Error).toString(),
- message:
- 'Internal error has occurred during download. Please try again or report as issue. \n',
- alertType: 'danger',
- });
- }
+ setErrorAlert({
+ name: 'Download Error',
+ error: (error as Error).toString(),
+ message:
+ 'Internal error has occurred during download. Please try again or report as issue. \n',
+ alertType: 'danger',
+ });
if (analytics) {
const region = getUserRegion(router.locale);
@@ -179,7 +170,7 @@ export const DevfilePageProjects: React.FC = ({
data-testid="download-button"
className={styles.button}
isLoading={downloading}
- onClick={(): Promise => triggerDownload(selectedProject)}
+ onClick={(): Promise => downloadStarterProject(devfile, selectedProject)}
variant="tertiary"
>
Download
diff --git a/src/util/client/downloadHelperFuncs.ts b/src/util/client/downloadHelperFuncs.ts
deleted file mode 100644
index 266f3a4..0000000
--- a/src/util/client/downloadHelperFuncs.ts
+++ /dev/null
@@ -1,120 +0,0 @@
-import type { Git, Project } from 'custom-types';
-import { apiWrapper } from '@src/util/client';
-import JSZip from 'jszip';
-import { saveAs } from 'file-saver';
-
-/**
- * Error for unsupported links
- */
-export class UnsupportedLinkError extends Error {
- /**
- * Error constructor with message 'Unsupported link: {@link link}'
- *
- * @param link - unsupported link
- */
- public constructor(link: string) {
- super(`Attempted download with unsupported git repo link at ${link}`);
- this.name = 'UnsupportedLinkError ';
- Object.setPrototypeOf(this, UnsupportedLinkError.prototype);
- }
-}
-
-/**
- * Download subdirectory from root folder
- *
- * @param url - zip url
- * @param subdirectory - name of subdirectory to extract from zip
- *
- * @throws {@link Error} - thrown if error in download
- */
-export async function downloadSubdirectory(url: string, subdirectory: string): Promise {
- const data = {
- url,
- subdirectory,
- };
- const res = await fetch(apiWrapper('/api/download-subdirectory'), {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(data),
- });
-
- const status = res.status;
- if (status !== 200) {
- const errorJson = await res.json();
- throw new Error(errorJson.error);
- }
-
- const base64string = await res.text();
- const zip = await JSZip.loadAsync(base64string, { base64: true });
- try {
- const blob = await zip.generateAsync({ type: 'blob' });
- saveAs(blob, `${subdirectory}.zip`);
- } catch (error) {
- throw new Error((error as Error).message);
- }
-}
-
-/**
- * Extract zip url from project git source
- *
- * @param git - git source of project, assumes github url of root directory of project
- *
- * @throws {@link TypeError} - thrown if git remotes isn't configured properly
- * @throws {@link UnsupportedLinkException} - thrown if git repo is supported on an unsupported site
- */
-export function getURLForGit(git: Git): string {
- let url = '';
- const keys = Object.keys(git.remotes);
-
- if (keys.length === 1) {
- url = git.remotes[keys[0]];
- } else if (git.checkoutFrom && git.checkoutFrom.remote) {
- // should always be true if keys.length!=1
- url = git.remotes[git.checkoutFrom.remote];
- } else {
- throw new TypeError('Invalid git remotes');
- }
-
- if (url.match(/[.]git$/)) {
- url = url.slice(0, url.length - 4);
- }
-
- if (url.match(/github[.]com/)) {
- url = `${url.replace('github.com', 'api.github.com/repos')}/zipball/`; // remove '.git' from link and convert to api zip link
- } else {
- throw new UnsupportedLinkError(url);
- }
-
- if (git.checkoutFrom && git.checkoutFrom.revision) {
- url += git.checkoutFrom.revision;
- }
- return url;
-}
-
-/**
- * Download project as a zip file as specified version and subdirectory
- *
- * @param project - project to download
- *
- * @throws {@link TypeError} - thrown if git remotes isn't configured properly or if no url locations are found
- * @throws {@link UnsupportedLinkError} - thrown if git repo is supported on an unsupported site
- * @throws {@link Error} - thrown if git repo is supported on an unsupported site
- */
-export async function download(project: Project): Promise {
- let url: string;
- if (project.git) {
- // for git
- url = getURLForGit(project.git);
- } else if (project.zip && project.zip.location) {
- // for zip
- url = project.zip.location;
- } else {
- throw new TypeError('Invalid project has no zip/git url');
- }
-
- if (project.subDir) {
- await downloadSubdirectory(url, project.subDir);
- } else {
- window.open(url);
- }
-}
diff --git a/src/util/client/index.ts b/src/util/client/index.ts
index 8791d7d..6b051b8 100644
--- a/src/util/client/index.ts
+++ b/src/util/client/index.ts
@@ -3,7 +3,6 @@
* Sort in alphabetical order
*/
export * from './apiWrapper';
-export * from './downloadHelperFuncs';
export * from './filterElemFuncs';
export * from './getCSSStyles';
export * from './getUserRegion';