diff --git a/README.md b/README.md
index 3dde686..a326687 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# GitHub Folder Tree 🌲
-**github-folder-tree** is a React custom hook that allows you to fetch and process the contents of a GitHub folder. It retrieves information about the files and subfolders in the specified folder, including their names, file types, download URLs, SHA hashes, sizes, and paths.
+**github-folder-tree** is a React custom hook that allows you to fetch and process the contents of a GitHub folder. It retrieves information about the files and subfolders in the specified folder, including their names, file types, download URLs, SHA hashes, sizes, and paths. In addition, it provides the functionality to download the contents of the folder as a ZIP file and access repository information.
## Installation ⬇️
@@ -25,29 +25,39 @@ import {useGitHubFolderTree} from 'github-folder-tree';
**repositoryUrl** is the URL of the GitHub repository, and **apiKey** is an optional GitHub API key for authentication.
```jsx
-const { repoFiles, error, log, fetchRepositoryContents } = useGitHubFolderTree(repositoryUrl, apiKey);
+const { repoFiles, error, log, fetchRepositoryContents, useGitHubFolderDownload, repoInfo } = useGitHubFolderTree(folderUrl, apiKey);
```
### Example
```javascript
-import { useState } from 'react';
-import {useGitHubFolderTree} from 'github-folder-tree';
+import React, { FC, useState } from 'react';
+import { useGitHubFolderTree } from 'github-folder-tree';
const MyComponent = () => {
- const [repositoryUrl, setRepositoryUrl] = useState('');
+ const [folderUrl, setFolderUrl] = useState('');
const [apiKey, setApiKey] = useState('');
- const { repoFiles, error, log, fetchRepositoryContents } = useGitHubFolderTree(repositoryUrl, apiKey);
+ const { repoFiles, error, log, fetchRepositoryContents, useGitHubFolderDownload, repoInfo } = useGitHubFolderTree(folderUrl, apiKey);
const handleFetchClick = () => {
fetchRepositoryContents();
};
+ const handleDownloadClick = () => {
+ useGitHubFolderDownload();
+ };
+
+ if (repoFiles.length > 0) {
+ console.log(repoFiles);
+ console.log(repoInfo);
+ }
+
return (
-
setRepositoryUrl(e.target.value)} placeholder="Enter GitHub repository URL" />
+
setFolderUrl(e.target.value)} placeholder="Enter GitHub folder URL" />
setApiKey(e.target.value)} placeholder="Enter GitHub API key (optional)" />
Fetch Folder Contents
+
Download Folder as ZIP
{error &&
Error: {error}
}
{log &&
Log: {log}
}
@@ -77,7 +87,11 @@ const MyComponent = () => {
export default MyComponent;
```
-In the above example, **repositoryUrl** is the URL of the GitHub repository, and **apiKey** is an optional GitHub API key for authentication.
+In the above example, **folderUrl** is the URL of the GitHub folder, and **apiKey** is an optional GitHub API key for authentication.
+
+To fetch the contents of a GitHub folder, enter the folder URL in the input field and click **Fetch Folder Contents**. The files and their details will be displayed in a table. Any errors or log messages will be shown accordingly.
+
+To download the folder as a ZIP file, click the **Download Folder as ZIP** button. The ZIP file will be generated and downloaded.
To fetch the contents of the root folder of a repository, use the repository URL in the following format:
@@ -109,14 +123,14 @@ Note: Make sure to handle any errors and display them appropriately in your Reac
#### X-Ratelimit-Limit: 60
-
+
#### API rate limit exceeded
-
+
#### Using Github API Key(Personal access tokens) - X-Ratelimit-Limit: 5000
-
+
## Hook Reference 📚
@@ -128,6 +142,9 @@ The **useGitHubFolderTree** hook returns the following values:
| **error** | **string** | An error message if an error occurred during the fetch. |
| **log** | **string** | Log messages for tracking progress and debugging. |
| **fetchRepositoryContents** | **function** | A function that fetches the contents of the specified GitHub folder. |
+| **useGitHubFolderDownload** | **function** | A function that downloads the contents of the specified GitHub folder as a ZIP file. |
+| **repoInfo** | **RepoInfo** | An object containing information about the GitHub repository. |
+
## Contributing 🤝
diff --git a/dist/cjs/hooks/useGitHubFolderTree.d.ts b/dist/cjs/hooks/useGitHubFolderTree.d.ts
index 0e246dc..6524888 100644
--- a/dist/cjs/hooks/useGitHubFolderTree.d.ts
+++ b/dist/cjs/hooks/useGitHubFolderTree.d.ts
@@ -1,17 +1,9 @@
-interface RepoFile {
- url: string;
- name: string;
- file_type: string;
- download_url: string;
- sha: string;
- size: string;
- path: string;
- type?: string;
-}
+import { RepoFile, RepoInfo } from '../types';
export declare const useGitHubFolderTree: (folderUrl: string, apiKey?: string) => {
repoFiles: RepoFile[];
+ fetchRepositoryContents: () => Promise;
+ useGitHubFolderDownload: () => Promise;
error: string;
log: string;
- fetchRepositoryContents: () => Promise;
+ repoInfo: RepoInfo;
};
-export {};
diff --git a/dist/cjs/hooks/useGitHubFolderTree.js b/dist/cjs/hooks/useGitHubFolderTree.js
index ed875fb..6b96ab0 100644
--- a/dist/cjs/hooks/useGitHubFolderTree.js
+++ b/dist/cjs/hooks/useGitHubFolderTree.js
@@ -14,63 +14,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true });
exports.useGitHubFolderTree = void 0;
const react_1 = require("react");
-const axios_1 = __importDefault(require("axios"));
+const jszip_1 = __importDefault(require("jszip"));
+const file_saver_1 = __importDefault(require("file-saver"));
+const apiUtils_1 = require("../utils/apiUtils");
+const zipUtils_1 = require("../utils/zipUtils");
const useGitHubFolderTree = (folderUrl, apiKey) => {
const [repoFiles, setRepoFiles] = (0, react_1.useState)([]);
+ const [repoInfo, setRepoInfo] = (0, react_1.useState)({
+ user: '',
+ repo: '',
+ branch: '',
+ dir: '',
+ });
+ const { repo, branch, dir } = repoInfo;
const [error, setError] = (0, react_1.useState)('');
const [log, setLog] = (0, react_1.useState)('');
- const fetchFolderData = (folderUrl) => __awaiter(void 0, void 0, void 0, function* () {
- const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length;
- const decodedUrl = decodeURIComponent(contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl);
- setLog(`Fetching data from ${decodedUrl}`);
- const options = {};
- if (apiKey) {
- options.headers = {
- Authorization: `Bearer ${apiKey}`,
- };
- }
- const { data: response } = yield axios_1.default.get(folderUrl, options);
- setLog(`Data fetched from ${decodedUrl}`);
- return response;
- });
- const processFolderContents = (folder) => __awaiter(void 0, void 0, void 0, function* () {
- const filePromises = folder.map((item) => __awaiter(void 0, void 0, void 0, function* () {
- if (item.type === 'file') {
- setLog(`Processing ${item.name}`);
- const extension = item.name.split('.').pop() || 'unknown';
- const sizeInKB = Math.round(parseInt(item.size) / 1024);
- let size;
- if (sizeInKB >= 1024) {
- const sizeInMB = (sizeInKB / 1024).toFixed(2);
- size = sizeInMB + ' MB';
- }
- else {
- size = sizeInKB + ' KB';
- }
- return {
- name: item.name,
- file_type: extension,
- download_url: item.download_url,
- sha: item.sha,
- size: size,
- path: item.path,
- };
- }
- else if (item.type === 'dir') {
- setLog(`Processing ${item.name}`);
- const subFolder = yield fetchFolderData(item.url);
- setLog(`Subfolder data fetched from ${item.url}`);
- const subFolderFiles = yield processFolderContents(subFolder);
- setLog(`Processed ${item.name}`);
- return subFolderFiles;
- }
- return null;
- }));
- const files = yield Promise.all(filePromises);
- const flattenedFiles = files.flat();
- setLog('Processing complete');
- return flattenedFiles.filter(Boolean);
- });
const fetchRepositoryContents = () => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
try {
@@ -87,24 +45,44 @@ const useGitHubFolderTree = (folderUrl, apiKey) => {
const user = matches[1];
const repo = matches[2];
const branch = matches[3];
- const dir = matches[4];
+ const dir = matches[4] || '';
+ setRepoInfo({ user, repo, branch, dir });
setLog(`Extracted user: ${user}, repo: ${repo}, branch: ${branch}, dir: ${dir}`);
const apiUrl = `https://api.github.com/repos/${user}/${repo}/contents/${dir}?ref=${branch}`;
setLog(`Fetching repository contents from ${apiUrl}`);
- const folderData = yield fetchFolderData(apiUrl);
+ const folderData = yield (0, apiUtils_1.fetchFolderData)(apiUrl, setError, setLog, apiKey);
setLog('Folder data fetched');
- const processedFiles = yield processFolderContents(folderData);
+ const processedFiles = yield (0, apiUtils_1.processFolderContents)(folderData, setError, setLog, dir, apiKey);
setRepoFiles(prevFiles => [...prevFiles, ...processedFiles].filter(Boolean));
}
catch (error) {
- setError(((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || 'An error occurred');
+ setError((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message);
+ }
+ });
+ const useGitHubFolderDownload = () => __awaiter(void 0, void 0, void 0, function* () {
+ if (repoFiles.length === 0) {
+ setError('No repository files available');
+ return;
+ }
+ try {
+ const zip = new jszip_1.default();
+ yield (0, zipUtils_1.generateZip)(zip, repoFiles, setError, setLog);
+ const zipBlob = yield zip.generateAsync({ type: 'blob' });
+ const fileName = dir ? dir.split('/').pop() : `${repo}-${branch}`;
+ console.log(fileName);
+ file_saver_1.default.saveAs(zipBlob, fileName);
+ }
+ catch (error) {
+ setError('An error occurred while creating the ZIP file');
}
});
return {
repoFiles,
+ fetchRepositoryContents,
+ useGitHubFolderDownload,
error,
log,
- fetchRepositoryContents,
+ repoInfo,
};
};
exports.useGitHubFolderTree = useGitHubFolderTree;
diff --git a/dist/cjs/hooks/useGitHubFolderTree.js.map b/dist/cjs/hooks/useGitHubFolderTree.js.map
index 1a836bb..0ea1697 100644
--- a/dist/cjs/hooks/useGitHubFolderTree.js.map
+++ b/dist/cjs/hooks/useGitHubFolderTree.js.map
@@ -1 +1 @@
-{"version":3,"file":"useGitHubFolderTree.js","sourceRoot":"","sources":["../../../src/hooks/useGitHubFolderTree.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"useGitHubFolderTree.js","sourceRoot":"","sources":["../../../src/hooks/useGitHubFolderTree.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/cjs/index.d.ts b/dist/cjs/index.d.ts
index 4cc90d0..a31e240 100644
--- a/dist/cjs/index.d.ts
+++ b/dist/cjs/index.d.ts
@@ -1 +1,3 @@
export * from './hooks';
+export * from './types';
+export * from './utils';
diff --git a/dist/cjs/index.js b/dist/cjs/index.js
index 8bd911e..545c646 100644
--- a/dist/cjs/index.js
+++ b/dist/cjs/index.js
@@ -15,4 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./hooks"), exports);
+__exportStar(require("./types"), exports);
+__exportStar(require("./utils"), exports);
//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/cjs/index.js.map b/dist/cjs/index.js.map
index 4453a63..ccdf1cc 100644
--- a/dist/cjs/index.js.map
+++ b/dist/cjs/index.js.map
@@ -1 +1 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB"}
\ No newline at end of file
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAuB;AACvB,0CAAuB;AACvB,0CAAuB"}
\ No newline at end of file
diff --git a/dist/cjs/types/RepoFile.d.ts b/dist/cjs/types/RepoFile.d.ts
new file mode 100644
index 0000000..ad641bf
--- /dev/null
+++ b/dist/cjs/types/RepoFile.d.ts
@@ -0,0 +1,10 @@
+export interface RepoFile {
+ url: string;
+ name: string;
+ file_type: string;
+ download_url: string;
+ sha: string;
+ size: string;
+ path: string;
+ type?: string;
+}
diff --git a/dist/cjs/types/RepoFile.js b/dist/cjs/types/RepoFile.js
new file mode 100644
index 0000000..4ece3e8
--- /dev/null
+++ b/dist/cjs/types/RepoFile.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=RepoFile.js.map
\ No newline at end of file
diff --git a/dist/cjs/types/RepoFile.js.map b/dist/cjs/types/RepoFile.js.map
new file mode 100644
index 0000000..78dec42
--- /dev/null
+++ b/dist/cjs/types/RepoFile.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"RepoFile.js","sourceRoot":"","sources":["../../../src/types/RepoFile.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/cjs/types/RepoInfo.d.ts b/dist/cjs/types/RepoInfo.d.ts
new file mode 100644
index 0000000..185d25d
--- /dev/null
+++ b/dist/cjs/types/RepoInfo.d.ts
@@ -0,0 +1,6 @@
+export interface RepoInfo {
+ user: string;
+ repo: string;
+ branch: string;
+ dir: string;
+}
diff --git a/dist/cjs/types/RepoInfo.js b/dist/cjs/types/RepoInfo.js
new file mode 100644
index 0000000..513b858
--- /dev/null
+++ b/dist/cjs/types/RepoInfo.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=RepoInfo.js.map
\ No newline at end of file
diff --git a/dist/cjs/types/RepoInfo.js.map b/dist/cjs/types/RepoInfo.js.map
new file mode 100644
index 0000000..626f394
--- /dev/null
+++ b/dist/cjs/types/RepoInfo.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"RepoInfo.js","sourceRoot":"","sources":["../../../src/types/RepoInfo.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/cjs/types/index.d.ts b/dist/cjs/types/index.d.ts
new file mode 100644
index 0000000..e95d26f
--- /dev/null
+++ b/dist/cjs/types/index.d.ts
@@ -0,0 +1,2 @@
+export * from './RepoFile';
+export * from './RepoInfo';
diff --git a/dist/cjs/types/index.js b/dist/cjs/types/index.js
new file mode 100644
index 0000000..cc0771f
--- /dev/null
+++ b/dist/cjs/types/index.js
@@ -0,0 +1,19 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./RepoFile"), exports);
+__exportStar(require("./RepoInfo"), exports);
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/cjs/types/index.js.map b/dist/cjs/types/index.js.map
new file mode 100644
index 0000000..33fcfeb
--- /dev/null
+++ b/dist/cjs/types/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA0B;AAC1B,6CAA0B"}
\ No newline at end of file
diff --git a/dist/cjs/utils/apiUtils.d.ts b/dist/cjs/utils/apiUtils.d.ts
new file mode 100644
index 0000000..21474d7
--- /dev/null
+++ b/dist/cjs/utils/apiUtils.d.ts
@@ -0,0 +1,3 @@
+import { RepoFile } from '../types';
+export declare const fetchFolderData: (folderUrl: string, setError: (error: string) => void, setLog: (log: string) => void, apiKey?: string) => Promise;
+export declare const processFolderContents: (folder: any[], setError: (error: string) => void, setLog: (log: string) => void, path?: string, apiKey?: string) => Promise;
diff --git a/dist/cjs/utils/apiUtils.js b/dist/cjs/utils/apiUtils.js
new file mode 100644
index 0000000..38c3514
--- /dev/null
+++ b/dist/cjs/utils/apiUtils.js
@@ -0,0 +1,82 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+var __importDefault = (this && this.__importDefault) || function (mod) {
+ return (mod && mod.__esModule) ? mod : { "default": mod };
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.processFolderContents = exports.fetchFolderData = void 0;
+const axios_1 = __importDefault(require("axios"));
+const fetchFolderData = (folderUrl, setError, setLog, apiKey) => __awaiter(void 0, void 0, void 0, function* () {
+ const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length;
+ const decodedUrl = decodeURIComponent(contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl);
+ setLog(`Fetching data from ${decodedUrl}`);
+ const options = {};
+ if (apiKey) {
+ options.headers = {
+ Authorization: `Bearer ${apiKey}`,
+ };
+ }
+ const { data: response } = yield axios_1.default.get(folderUrl, options);
+ setLog(`Data fetched from ${decodedUrl}`);
+ return response;
+});
+exports.fetchFolderData = fetchFolderData;
+const processFolderContents = (folder, setError, setLog, path, apiKey) => __awaiter(void 0, void 0, void 0, function* () {
+ const filePromises = folder.map((item) => __awaiter(void 0, void 0, void 0, function* () {
+ try {
+ if (item.type === 'file') {
+ setLog(`Processing ${item.name}`);
+ const extension = item.name.split('.').pop() || 'unknown';
+ const sizeInKB = Math.round(parseInt(item.size) / 1024);
+ let size;
+ if (sizeInKB >= 1024) {
+ const sizeInMB = (sizeInKB / 1024).toFixed(2);
+ size = sizeInMB + ' MB';
+ }
+ else {
+ size = sizeInKB + ' KB';
+ }
+ return {
+ name: item.name,
+ file_type: extension,
+ download_url: item.download_url,
+ sha: item.sha,
+ size: size,
+ path: item.path,
+ };
+ }
+ else if (item.type === 'dir') {
+ setLog(`Processing ${item.name}`);
+ const subFolder = yield (0, exports.fetchFolderData)(item.url, setError, setLog, apiKey);
+ if (subFolder !== null) {
+ setLog(`Processing ${item.name}`);
+ const subFolderFiles = yield (0, exports.processFolderContents)(subFolder, setError, setLog, item.path, apiKey);
+ setLog(`Processed ${item.name}`);
+ return subFolderFiles;
+ }
+ else {
+ setLog(`Skipping ${item.name} due to error in fetching subfolder data`);
+ return null;
+ }
+ }
+ }
+ catch (error) {
+ setError(`Error processing ${item.name}: ${error.message}`);
+ return null;
+ }
+ }));
+ const files = yield Promise.all(filePromises);
+ const flattenedFiles = files.flat();
+ setLog('Processing complete');
+ return flattenedFiles.filter((file) => file !== null);
+});
+exports.processFolderContents = processFolderContents;
+//# sourceMappingURL=apiUtils.js.map
\ No newline at end of file
diff --git a/dist/cjs/utils/apiUtils.js.map b/dist/cjs/utils/apiUtils.js.map
new file mode 100644
index 0000000..d817dc7
--- /dev/null
+++ b/dist/cjs/utils/apiUtils.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"apiUtils.js","sourceRoot":"","sources":["../../../src/utils/apiUtils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/cjs/utils/index.d.ts b/dist/cjs/utils/index.d.ts
new file mode 100644
index 0000000..8b801ad
--- /dev/null
+++ b/dist/cjs/utils/index.d.ts
@@ -0,0 +1,2 @@
+export * from './apiUtils';
+export * from './zipUtils';
diff --git a/dist/cjs/utils/index.js b/dist/cjs/utils/index.js
new file mode 100644
index 0000000..42bd4fe
--- /dev/null
+++ b/dist/cjs/utils/index.js
@@ -0,0 +1,19 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./apiUtils"), exports);
+__exportStar(require("./zipUtils"), exports);
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/cjs/utils/index.js.map b/dist/cjs/utils/index.js.map
new file mode 100644
index 0000000..6a6cc94
--- /dev/null
+++ b/dist/cjs/utils/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA0B;AAC1B,6CAA0B"}
\ No newline at end of file
diff --git a/dist/cjs/utils/zipUtils.d.ts b/dist/cjs/utils/zipUtils.d.ts
new file mode 100644
index 0000000..44800bb
--- /dev/null
+++ b/dist/cjs/utils/zipUtils.d.ts
@@ -0,0 +1,3 @@
+import JSZip from 'jszip';
+import { RepoFile } from '../types';
+export declare const generateZip: (zip: JSZip, repoFiles: RepoFile[], setError: (error: string) => void, setLog: (log: string) => void) => Promise;
diff --git a/dist/cjs/utils/zipUtils.js b/dist/cjs/utils/zipUtils.js
new file mode 100644
index 0000000..7019e10
--- /dev/null
+++ b/dist/cjs/utils/zipUtils.js
@@ -0,0 +1,69 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.generateZip = void 0;
+const generateZip = (zip, repoFiles, setError, setLog) => __awaiter(void 0, void 0, void 0, function* () {
+ const totalFiles = repoFiles.length;
+ let completedFiles = 0;
+ const filePromises = repoFiles.map((file) => __awaiter(void 0, void 0, void 0, function* () {
+ const filePath = file.path;
+ try {
+ const response = yield fetch(file.download_url);
+ if (!response.ok) {
+ throw new Error(`Failed to fetch ${file.name}`);
+ }
+ const contentLength = response.headers.get('content-length');
+ const totalSize = contentLength ? parseInt(contentLength, 10) : 0;
+ let downloadedSize = 0;
+ const fileContent = yield response.blob();
+ const downloadProgress = (event) => {
+ if (event.lengthComputable) {
+ downloadedSize = event.loaded;
+ const progress = Math.min(Math.round((downloadedSize / totalSize) * 100), 100);
+ setLog(`Downloading ${file.name}: ${progress}%`);
+ }
+ };
+ const reader = new FileReader();
+ reader.onload = () => {
+ if (filePath) {
+ const pathSegments = filePath.split('/');
+ let folder = zip.folder(pathSegments[0]);
+ const nestedFolders = pathSegments.slice(1, -1);
+ nestedFolders.forEach(folderName => {
+ folder = folder.folder(folderName);
+ });
+ folder.file(file.name, reader.result);
+ }
+ else {
+ zip.file(file.name, reader.result);
+ }
+ completedFiles++;
+ };
+ reader.onerror = error => {
+ setError(`Error reading file content: ${error}`);
+ throw error;
+ };
+ reader.onprogress = downloadProgress;
+ reader.readAsArrayBuffer(fileContent);
+ yield new Promise(resolve => {
+ reader.onloadend = () => resolve(null);
+ });
+ }
+ catch (error) {
+ setError(`Error fetching file content: ${error.message}`);
+ throw error;
+ }
+ }));
+ yield Promise.all(filePromises);
+ setLog(`Downloaded and added ${completedFiles} out of ${totalFiles} files to the zip.`);
+});
+exports.generateZip = generateZip;
+//# sourceMappingURL=zipUtils.js.map
\ No newline at end of file
diff --git a/dist/cjs/utils/zipUtils.js.map b/dist/cjs/utils/zipUtils.js.map
new file mode 100644
index 0000000..4701fa0
--- /dev/null
+++ b/dist/cjs/utils/zipUtils.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"zipUtils.js","sourceRoot":"","sources":["../../../src/utils/zipUtils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/esm/hooks/useGitHubFolderTree.d.ts b/dist/esm/hooks/useGitHubFolderTree.d.ts
index 0e246dc..6524888 100644
--- a/dist/esm/hooks/useGitHubFolderTree.d.ts
+++ b/dist/esm/hooks/useGitHubFolderTree.d.ts
@@ -1,17 +1,9 @@
-interface RepoFile {
- url: string;
- name: string;
- file_type: string;
- download_url: string;
- sha: string;
- size: string;
- path: string;
- type?: string;
-}
+import { RepoFile, RepoInfo } from '../types';
export declare const useGitHubFolderTree: (folderUrl: string, apiKey?: string) => {
repoFiles: RepoFile[];
+ fetchRepositoryContents: () => Promise;
+ useGitHubFolderDownload: () => Promise;
error: string;
log: string;
- fetchRepositoryContents: () => Promise;
+ repoInfo: RepoInfo;
};
-export {};
diff --git a/dist/esm/hooks/useGitHubFolderTree.js b/dist/esm/hooks/useGitHubFolderTree.js
index 79b7d95..74e4f23 100644
--- a/dist/esm/hooks/useGitHubFolderTree.js
+++ b/dist/esm/hooks/useGitHubFolderTree.js
@@ -8,63 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
});
};
import { useState } from 'react';
-import axios from 'axios';
+import JSZip from 'jszip';
+import FileSaver from 'file-saver';
+import { fetchFolderData, processFolderContents } from '../utils/apiUtils';
+import { generateZip } from '../utils/zipUtils';
export const useGitHubFolderTree = (folderUrl, apiKey) => {
const [repoFiles, setRepoFiles] = useState([]);
+ const [repoInfo, setRepoInfo] = useState({
+ user: '',
+ repo: '',
+ branch: '',
+ dir: '',
+ });
+ const { repo, branch, dir } = repoInfo;
const [error, setError] = useState('');
const [log, setLog] = useState('');
- const fetchFolderData = (folderUrl) => __awaiter(void 0, void 0, void 0, function* () {
- const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length;
- const decodedUrl = decodeURIComponent(contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl);
- setLog(`Fetching data from ${decodedUrl}`);
- const options = {};
- if (apiKey) {
- options.headers = {
- Authorization: `Bearer ${apiKey}`,
- };
- }
- const { data: response } = yield axios.get(folderUrl, options);
- setLog(`Data fetched from ${decodedUrl}`);
- return response;
- });
- const processFolderContents = (folder) => __awaiter(void 0, void 0, void 0, function* () {
- const filePromises = folder.map((item) => __awaiter(void 0, void 0, void 0, function* () {
- if (item.type === 'file') {
- setLog(`Processing ${item.name}`);
- const extension = item.name.split('.').pop() || 'unknown';
- const sizeInKB = Math.round(parseInt(item.size) / 1024);
- let size;
- if (sizeInKB >= 1024) {
- const sizeInMB = (sizeInKB / 1024).toFixed(2);
- size = sizeInMB + ' MB';
- }
- else {
- size = sizeInKB + ' KB';
- }
- return {
- name: item.name,
- file_type: extension,
- download_url: item.download_url,
- sha: item.sha,
- size: size,
- path: item.path,
- };
- }
- else if (item.type === 'dir') {
- setLog(`Processing ${item.name}`);
- const subFolder = yield fetchFolderData(item.url);
- setLog(`Subfolder data fetched from ${item.url}`);
- const subFolderFiles = yield processFolderContents(subFolder);
- setLog(`Processed ${item.name}`);
- return subFolderFiles;
- }
- return null;
- }));
- const files = yield Promise.all(filePromises);
- const flattenedFiles = files.flat();
- setLog('Processing complete');
- return flattenedFiles.filter(Boolean);
- });
const fetchRepositoryContents = () => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b;
try {
@@ -81,24 +39,44 @@ export const useGitHubFolderTree = (folderUrl, apiKey) => {
const user = matches[1];
const repo = matches[2];
const branch = matches[3];
- const dir = matches[4];
+ const dir = matches[4] || '';
+ setRepoInfo({ user, repo, branch, dir });
setLog(`Extracted user: ${user}, repo: ${repo}, branch: ${branch}, dir: ${dir}`);
const apiUrl = `https://api.github.com/repos/${user}/${repo}/contents/${dir}?ref=${branch}`;
setLog(`Fetching repository contents from ${apiUrl}`);
- const folderData = yield fetchFolderData(apiUrl);
+ const folderData = yield fetchFolderData(apiUrl, setError, setLog, apiKey);
setLog('Folder data fetched');
- const processedFiles = yield processFolderContents(folderData);
+ const processedFiles = yield processFolderContents(folderData, setError, setLog, dir, apiKey);
setRepoFiles(prevFiles => [...prevFiles, ...processedFiles].filter(Boolean));
}
catch (error) {
- setError(((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message) || 'An error occurred');
+ setError((_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.message);
+ }
+ });
+ const useGitHubFolderDownload = () => __awaiter(void 0, void 0, void 0, function* () {
+ if (repoFiles.length === 0) {
+ setError('No repository files available');
+ return;
+ }
+ try {
+ const zip = new JSZip();
+ yield generateZip(zip, repoFiles, setError, setLog);
+ const zipBlob = yield zip.generateAsync({ type: 'blob' });
+ const fileName = dir ? dir.split('/').pop() : `${repo}-${branch}`;
+ console.log(fileName);
+ FileSaver.saveAs(zipBlob, fileName);
+ }
+ catch (error) {
+ setError('An error occurred while creating the ZIP file');
}
});
return {
repoFiles,
+ fetchRepositoryContents,
+ useGitHubFolderDownload,
error,
log,
- fetchRepositoryContents,
+ repoInfo,
};
};
//# sourceMappingURL=useGitHubFolderTree.js.map
\ No newline at end of file
diff --git a/dist/esm/hooks/useGitHubFolderTree.js.map b/dist/esm/hooks/useGitHubFolderTree.js.map
index a90bd51..5ad5a0a 100644
--- a/dist/esm/hooks/useGitHubFolderTree.js.map
+++ b/dist/esm/hooks/useGitHubFolderTree.js.map
@@ -1 +1 @@
-{"version":3,"file":"useGitHubFolderTree.js","sourceRoot":"","sources":["../../../src/hooks/useGitHubFolderTree.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"useGitHubFolderTree.js","sourceRoot":"","sources":["../../../src/hooks/useGitHubFolderTree.tsx"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/esm/index.d.ts b/dist/esm/index.d.ts
index 4cc90d0..a31e240 100644
--- a/dist/esm/index.d.ts
+++ b/dist/esm/index.d.ts
@@ -1 +1,3 @@
export * from './hooks';
+export * from './types';
+export * from './utils';
diff --git a/dist/esm/index.js b/dist/esm/index.js
index 3f5114f..f0b49fc 100644
--- a/dist/esm/index.js
+++ b/dist/esm/index.js
@@ -1,2 +1,4 @@
export * from './hooks';
+export * from './types';
+export * from './utils';
//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/esm/index.js.map b/dist/esm/index.js.map
index 3e75f06..68014d0 100644
--- a/dist/esm/index.js.map
+++ b/dist/esm/index.js.map
@@ -1 +1 @@
-{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA"}
\ No newline at end of file
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA;AACvB,cAAc,SAAS,CAAA"}
\ No newline at end of file
diff --git a/dist/esm/types/RepoFile.d.ts b/dist/esm/types/RepoFile.d.ts
new file mode 100644
index 0000000..ad641bf
--- /dev/null
+++ b/dist/esm/types/RepoFile.d.ts
@@ -0,0 +1,10 @@
+export interface RepoFile {
+ url: string;
+ name: string;
+ file_type: string;
+ download_url: string;
+ sha: string;
+ size: string;
+ path: string;
+ type?: string;
+}
diff --git a/dist/esm/types/RepoFile.js b/dist/esm/types/RepoFile.js
new file mode 100644
index 0000000..2d1c263
--- /dev/null
+++ b/dist/esm/types/RepoFile.js
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=RepoFile.js.map
\ No newline at end of file
diff --git a/dist/esm/types/RepoFile.js.map b/dist/esm/types/RepoFile.js.map
new file mode 100644
index 0000000..78dec42
--- /dev/null
+++ b/dist/esm/types/RepoFile.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"RepoFile.js","sourceRoot":"","sources":["../../../src/types/RepoFile.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/esm/types/RepoInfo.d.ts b/dist/esm/types/RepoInfo.d.ts
new file mode 100644
index 0000000..185d25d
--- /dev/null
+++ b/dist/esm/types/RepoInfo.d.ts
@@ -0,0 +1,6 @@
+export interface RepoInfo {
+ user: string;
+ repo: string;
+ branch: string;
+ dir: string;
+}
diff --git a/dist/esm/types/RepoInfo.js b/dist/esm/types/RepoInfo.js
new file mode 100644
index 0000000..6fa4694
--- /dev/null
+++ b/dist/esm/types/RepoInfo.js
@@ -0,0 +1,2 @@
+export {};
+//# sourceMappingURL=RepoInfo.js.map
\ No newline at end of file
diff --git a/dist/esm/types/RepoInfo.js.map b/dist/esm/types/RepoInfo.js.map
new file mode 100644
index 0000000..626f394
--- /dev/null
+++ b/dist/esm/types/RepoInfo.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"RepoInfo.js","sourceRoot":"","sources":["../../../src/types/RepoInfo.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/dist/esm/types/index.d.ts b/dist/esm/types/index.d.ts
new file mode 100644
index 0000000..e95d26f
--- /dev/null
+++ b/dist/esm/types/index.d.ts
@@ -0,0 +1,2 @@
+export * from './RepoFile';
+export * from './RepoInfo';
diff --git a/dist/esm/types/index.js b/dist/esm/types/index.js
new file mode 100644
index 0000000..ebaf68e
--- /dev/null
+++ b/dist/esm/types/index.js
@@ -0,0 +1,3 @@
+export * from './RepoFile';
+export * from './RepoInfo';
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/esm/types/index.js.map b/dist/esm/types/index.js.map
new file mode 100644
index 0000000..daaa4a7
--- /dev/null
+++ b/dist/esm/types/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
\ No newline at end of file
diff --git a/dist/esm/utils/apiUtils.d.ts b/dist/esm/utils/apiUtils.d.ts
new file mode 100644
index 0000000..21474d7
--- /dev/null
+++ b/dist/esm/utils/apiUtils.d.ts
@@ -0,0 +1,3 @@
+import { RepoFile } from '../types';
+export declare const fetchFolderData: (folderUrl: string, setError: (error: string) => void, setLog: (log: string) => void, apiKey?: string) => Promise;
+export declare const processFolderContents: (folder: any[], setError: (error: string) => void, setLog: (log: string) => void, path?: string, apiKey?: string) => Promise;
diff --git a/dist/esm/utils/apiUtils.js b/dist/esm/utils/apiUtils.js
new file mode 100644
index 0000000..8c3430a
--- /dev/null
+++ b/dist/esm/utils/apiUtils.js
@@ -0,0 +1,74 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+import axios from 'axios';
+export const fetchFolderData = (folderUrl, setError, setLog, apiKey) => __awaiter(void 0, void 0, void 0, function* () {
+ const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length;
+ const decodedUrl = decodeURIComponent(contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl);
+ setLog(`Fetching data from ${decodedUrl}`);
+ const options = {};
+ if (apiKey) {
+ options.headers = {
+ Authorization: `Bearer ${apiKey}`,
+ };
+ }
+ const { data: response } = yield axios.get(folderUrl, options);
+ setLog(`Data fetched from ${decodedUrl}`);
+ return response;
+});
+export const processFolderContents = (folder, setError, setLog, path, apiKey) => __awaiter(void 0, void 0, void 0, function* () {
+ const filePromises = folder.map((item) => __awaiter(void 0, void 0, void 0, function* () {
+ try {
+ if (item.type === 'file') {
+ setLog(`Processing ${item.name}`);
+ const extension = item.name.split('.').pop() || 'unknown';
+ const sizeInKB = Math.round(parseInt(item.size) / 1024);
+ let size;
+ if (sizeInKB >= 1024) {
+ const sizeInMB = (sizeInKB / 1024).toFixed(2);
+ size = sizeInMB + ' MB';
+ }
+ else {
+ size = sizeInKB + ' KB';
+ }
+ return {
+ name: item.name,
+ file_type: extension,
+ download_url: item.download_url,
+ sha: item.sha,
+ size: size,
+ path: item.path,
+ };
+ }
+ else if (item.type === 'dir') {
+ setLog(`Processing ${item.name}`);
+ const subFolder = yield fetchFolderData(item.url, setError, setLog, apiKey);
+ if (subFolder !== null) {
+ setLog(`Processing ${item.name}`);
+ const subFolderFiles = yield processFolderContents(subFolder, setError, setLog, item.path, apiKey);
+ setLog(`Processed ${item.name}`);
+ return subFolderFiles;
+ }
+ else {
+ setLog(`Skipping ${item.name} due to error in fetching subfolder data`);
+ return null;
+ }
+ }
+ }
+ catch (error) {
+ setError(`Error processing ${item.name}: ${error.message}`);
+ return null;
+ }
+ }));
+ const files = yield Promise.all(filePromises);
+ const flattenedFiles = files.flat();
+ setLog('Processing complete');
+ return flattenedFiles.filter((file) => file !== null);
+});
+//# sourceMappingURL=apiUtils.js.map
\ No newline at end of file
diff --git a/dist/esm/utils/apiUtils.js.map b/dist/esm/utils/apiUtils.js.map
new file mode 100644
index 0000000..1d05254
--- /dev/null
+++ b/dist/esm/utils/apiUtils.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"apiUtils.js","sourceRoot":"","sources":["../../../src/utils/apiUtils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/esm/utils/index.d.ts b/dist/esm/utils/index.d.ts
new file mode 100644
index 0000000..8b801ad
--- /dev/null
+++ b/dist/esm/utils/index.d.ts
@@ -0,0 +1,2 @@
+export * from './apiUtils';
+export * from './zipUtils';
diff --git a/dist/esm/utils/index.js b/dist/esm/utils/index.js
new file mode 100644
index 0000000..938da1c
--- /dev/null
+++ b/dist/esm/utils/index.js
@@ -0,0 +1,3 @@
+export * from './apiUtils';
+export * from './zipUtils';
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/dist/esm/utils/index.js.map b/dist/esm/utils/index.js.map
new file mode 100644
index 0000000..d4a37af
--- /dev/null
+++ b/dist/esm/utils/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
\ No newline at end of file
diff --git a/dist/esm/utils/zipUtils.d.ts b/dist/esm/utils/zipUtils.d.ts
new file mode 100644
index 0000000..44800bb
--- /dev/null
+++ b/dist/esm/utils/zipUtils.d.ts
@@ -0,0 +1,3 @@
+import JSZip from 'jszip';
+import { RepoFile } from '../types';
+export declare const generateZip: (zip: JSZip, repoFiles: RepoFile[], setError: (error: string) => void, setLog: (log: string) => void) => Promise;
diff --git a/dist/esm/utils/zipUtils.js b/dist/esm/utils/zipUtils.js
new file mode 100644
index 0000000..7670251
--- /dev/null
+++ b/dist/esm/utils/zipUtils.js
@@ -0,0 +1,65 @@
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+export const generateZip = (zip, repoFiles, setError, setLog) => __awaiter(void 0, void 0, void 0, function* () {
+ const totalFiles = repoFiles.length;
+ let completedFiles = 0;
+ const filePromises = repoFiles.map((file) => __awaiter(void 0, void 0, void 0, function* () {
+ const filePath = file.path;
+ try {
+ const response = yield fetch(file.download_url);
+ if (!response.ok) {
+ throw new Error(`Failed to fetch ${file.name}`);
+ }
+ const contentLength = response.headers.get('content-length');
+ const totalSize = contentLength ? parseInt(contentLength, 10) : 0;
+ let downloadedSize = 0;
+ const fileContent = yield response.blob();
+ const downloadProgress = (event) => {
+ if (event.lengthComputable) {
+ downloadedSize = event.loaded;
+ const progress = Math.min(Math.round((downloadedSize / totalSize) * 100), 100);
+ setLog(`Downloading ${file.name}: ${progress}%`);
+ }
+ };
+ const reader = new FileReader();
+ reader.onload = () => {
+ if (filePath) {
+ const pathSegments = filePath.split('/');
+ let folder = zip.folder(pathSegments[0]);
+ const nestedFolders = pathSegments.slice(1, -1);
+ nestedFolders.forEach(folderName => {
+ folder = folder.folder(folderName);
+ });
+ folder.file(file.name, reader.result);
+ }
+ else {
+ zip.file(file.name, reader.result);
+ }
+ completedFiles++;
+ };
+ reader.onerror = error => {
+ setError(`Error reading file content: ${error}`);
+ throw error;
+ };
+ reader.onprogress = downloadProgress;
+ reader.readAsArrayBuffer(fileContent);
+ yield new Promise(resolve => {
+ reader.onloadend = () => resolve(null);
+ });
+ }
+ catch (error) {
+ setError(`Error fetching file content: ${error.message}`);
+ throw error;
+ }
+ }));
+ yield Promise.all(filePromises);
+ setLog(`Downloaded and added ${completedFiles} out of ${totalFiles} files to the zip.`);
+});
+//# sourceMappingURL=zipUtils.js.map
\ No newline at end of file
diff --git a/dist/esm/utils/zipUtils.js.map b/dist/esm/utils/zipUtils.js.map
new file mode 100644
index 0000000..df82603
--- /dev/null
+++ b/dist/esm/utils/zipUtils.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"zipUtils.js","sourceRoot":"","sources":["../../../src/utils/zipUtils.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..78e7a0f
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1697 @@
+{
+ "name": "github-folder-tree",
+ "version": "1.2.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "github-folder-tree",
+ "version": "1.2.1",
+ "license": "MIT",
+ "dependencies": {
+ "axios": "^1.4.0",
+ "file-saver": "^2.0.5",
+ "jszip": "^3.10.1"
+ },
+ "devDependencies": {
+ "@types/file-saver": "^2.0.5",
+ "@types/node": "^20.1.4",
+ "@types/react": "^18.2.6",
+ "@types/react-dom": "^18.2.4",
+ "axios": "^1.4.0",
+ "eslint-plugin-react-hooks": "^4.6.0",
+ "prettier": "2.8.8",
+ "typescript": "^5.0.4"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "eslint-visitor-keys": "^3.3.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
+ "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
+ "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.5.2",
+ "globals": "^13.19.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.40.0.tgz",
+ "integrity": "sha512-ElyB54bJIhXQYVKjDSvCkPO1iU1tSAeVQJbllWJq1XQSmmA4dgFk8CbiBGpiOPxleE48vDogxCtmMYku4HSVLA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.11.8",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
+ "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^1.2.1",
+ "debug": "^4.1.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/object-schema": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
+ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@types/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "20.1.4",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz",
+ "integrity": "sha512-At4pvmIOki8yuwLtd7BNHl3CiWNbtclUbNtScGx4OHfBd4/oWoJC8KRCIxXwkdndzhxOsPXihrsOoydxBjlE9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.5",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
+ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.6",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz",
+ "integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.4",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz",
+ "integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.3",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
+ "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/acorn": {
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+ "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0",
+ "peer": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz",
+ "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.0",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "license": "MIT"
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "8.40.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.40.0.tgz",
+ "integrity": "sha512-bvR+TsP9EHL3TqNtj9sCNJVAFK3fBN8Q7g5waghxyRsPLIMwL73XSKnZFK0hk/O2ANC+iAoq6PWMQ+IfBAJIiQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.4.0",
+ "@eslint/eslintrc": "^2.0.3",
+ "@eslint/js": "8.40.0",
+ "@humanwhocodes/config-array": "^0.11.8",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "ajv": "^6.10.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.0",
+ "eslint-visitor-keys": "^3.4.1",
+ "espree": "^9.5.2",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "grapheme-splitter": "^1.0.4",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-sdsl": "^4.1.4",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.1",
+ "strip-ansi": "^6.0.1",
+ "strip-json-comments": "^3.1.0",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-plugin-react-hooks": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
+ "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+ "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+ "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "peer": true,
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree": {
+ "version": "9.5.2",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+ "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "acorn": "^8.8.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
+ "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
+ "license": "MIT"
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+ "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "flatted": "^3.1.0",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
+ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "13.20.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+ "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/js-sdsl": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+ "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/js-sdsl"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/jszip": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+ "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "dependencies": {
+ "lie": "~3.3.0",
+ "pako": "~1.0.2",
+ "readable-stream": "~2.3.6",
+ "setimmediate": "^1.0.5"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.1",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
+ "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.3"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "license": "(MIT AND Zlib)"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
+ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "license": "MIT"
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "license": "MIT"
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
+ "license": "MIT"
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+ "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "peer": true,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "license": "MIT"
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC",
+ "peer": true
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 1877d42..d96fc76 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "github-folder-tree",
- "version": "1.1.0",
+ "version": "1.2.1",
"description": "github-folder-tree is a React custom hook that allows you to fetch and process the contents of a GitHub folder. It retrieves information about the files and subfolders in the specified folder, including their names, file types, download URLs, SHA hashes, sizes, and paths.",
"main": "dist/cjs/index.js",
"module": "dist/esm/index.js",
@@ -36,6 +36,7 @@
},
"homepage": "https://github-folder-tree.vercel.app/",
"devDependencies": {
+ "@types/file-saver": "^2.0.5",
"@types/node": "^20.1.4",
"@types/react": "^18.2.6",
"@types/react-dom": "^18.2.4",
@@ -49,6 +50,8 @@
"react-dom": "^18.2.0"
},
"dependencies": {
- "axios": "^1.4.0"
+ "axios": "^1.4.0",
+ "file-saver": "^2.0.5",
+ "jszip": "^3.10.1"
}
}
diff --git a/src/hooks/useGitHubFolderTree.tsx b/src/hooks/useGitHubFolderTree.tsx
index 5f95bef..63eaded 100644
--- a/src/hooks/useGitHubFolderTree.tsx
+++ b/src/hooks/useGitHubFolderTree.tsx
@@ -1,80 +1,22 @@
import { useState } from 'react'
-import axios from 'axios'
-
-interface RepoFile {
- url: string
- name: string
- file_type: string
- download_url: string
- sha: string
- size: string
- path: string
- type?: string
-}
+import JSZip from 'jszip'
+import FileSaver from 'file-saver'
+import { RepoFile, RepoInfo } from '../types'
+import { fetchFolderData, processFolderContents } from '../utils/apiUtils'
+import { generateZip } from '../utils/zipUtils'
export const useGitHubFolderTree = (folderUrl: string, apiKey?: string) => {
const [repoFiles, setRepoFiles] = useState([])
+ const [repoInfo, setRepoInfo] = useState({
+ user: '',
+ repo: '',
+ branch: '',
+ dir: '',
+ })
+ const { repo, branch, dir } = repoInfo
const [error, setError] = useState('')
const [log, setLog] = useState('')
- const fetchFolderData = async (folderUrl: string): Promise => {
- const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length
- const decodedUrl = decodeURIComponent(
- contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl
- )
- setLog(`Fetching data from ${decodedUrl}`)
- const options: any = {}
- if (apiKey) {
- options.headers = {
- Authorization: `Bearer ${apiKey}`,
- }
- }
- const { data: response } = await axios.get(folderUrl, options)
- setLog(`Data fetched from ${decodedUrl}`)
- return response
- }
-
- const processFolderContents = async (folder: RepoFile[]): Promise<(RepoFile | null)[]> => {
- const filePromises = folder.map(async (item: RepoFile) => {
- if (item.type === 'file') {
- setLog(`Processing ${item.name}`)
- const extension = item.name.split('.').pop() || 'unknown'
- const sizeInKB = Math.round(parseInt(item.size) / 1024)
- let size
- if (sizeInKB >= 1024) {
- const sizeInMB = (sizeInKB / 1024).toFixed(2)
- size = sizeInMB + ' MB'
- } else {
- size = sizeInKB + ' KB'
- }
-
- return {
- name: item.name,
- file_type: extension,
- download_url: item.download_url,
- sha: item.sha,
- size: size,
- path: item.path,
- }
- } else if (item.type === 'dir') {
- setLog(`Processing ${item.name}`)
- const subFolder = await fetchFolderData(item.url)
- setLog(`Subfolder data fetched from ${item.url}`)
- const subFolderFiles = await processFolderContents(subFolder)
- setLog(`Processed ${item.name}`)
- return subFolderFiles
- }
-
- return null
- })
-
- const files = await Promise.all(filePromises)
- const flattenedFiles = files.flat()
-
- setLog('Processing complete')
- return flattenedFiles.filter(Boolean) as (RepoFile | null)[]
- }
-
const fetchRepositoryContents = async () => {
try {
const urlRegex = /https:\/\/github.com\/([^\/]+)\/([^\/]+)\/tree\/([^\/]+)\/?(.*)/
@@ -93,26 +35,48 @@ export const useGitHubFolderTree = (folderUrl: string, apiKey?: string) => {
const user = matches[1]
const repo = matches[2]
const branch = matches[3]
- const dir = matches[4]
+ const dir = matches[4] || ''
+
+ setRepoInfo({ user, repo, branch, dir })
setLog(`Extracted user: ${user}, repo: ${repo}, branch: ${branch}, dir: ${dir}`)
const apiUrl = `https://api.github.com/repos/${user}/${repo}/contents/${dir}?ref=${branch}`
setLog(`Fetching repository contents from ${apiUrl}`)
- const folderData = await fetchFolderData(apiUrl)
+ const folderData = await fetchFolderData(apiUrl, setError, setLog, apiKey)
setLog('Folder data fetched')
- const processedFiles = await processFolderContents(folderData)
+ const processedFiles = await processFolderContents(folderData, setError, setLog, dir, apiKey)
setRepoFiles(prevFiles => [...prevFiles, ...processedFiles].filter(Boolean) as RepoFile[])
} catch (error: any) {
- setError(error.response?.data?.message || 'An error occurred')
+ setError(error.response?.data?.message)
+ }
+ }
+
+ const useGitHubFolderDownload = async () => {
+ if (repoFiles.length === 0) {
+ setError('No repository files available')
+ return
+ }
+
+ try {
+ const zip = new JSZip()
+ await generateZip(zip, repoFiles, setError, setLog)
+ const zipBlob = await zip.generateAsync({ type: 'blob' })
+ const fileName = dir ? dir.split('/').pop() : `${repo}-${branch}`
+ console.log(fileName)
+ FileSaver.saveAs(zipBlob, fileName)
+ } catch (error: any) {
+ setError('An error occurred while creating the ZIP file')
}
}
return {
repoFiles,
+ fetchRepositoryContents,
+ useGitHubFolderDownload,
error,
log,
- fetchRepositoryContents,
+ repoInfo,
}
}
diff --git a/src/index.ts b/src/index.ts
index fc78d35..c64f671 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1 +1,3 @@
export * from './hooks'
+export * from './types'
+export * from './utils'
diff --git a/src/types/RepoFile.ts b/src/types/RepoFile.ts
new file mode 100644
index 0000000..a8c4474
--- /dev/null
+++ b/src/types/RepoFile.ts
@@ -0,0 +1,10 @@
+export interface RepoFile {
+ url: string
+ name: string
+ file_type: string
+ download_url: string
+ sha: string
+ size: string
+ path: string
+ type?: string
+}
diff --git a/src/types/RepoInfo.ts b/src/types/RepoInfo.ts
new file mode 100644
index 0000000..d2c2274
--- /dev/null
+++ b/src/types/RepoInfo.ts
@@ -0,0 +1,6 @@
+export interface RepoInfo {
+ user: string
+ repo: string
+ branch: string
+ dir: string
+}
diff --git a/src/types/index.ts b/src/types/index.ts
new file mode 100644
index 0000000..45582d9
--- /dev/null
+++ b/src/types/index.ts
@@ -0,0 +1,2 @@
+export * from './RepoFile'
+export * from './RepoInfo'
diff --git a/src/utils/apiUtils.ts b/src/utils/apiUtils.ts
new file mode 100644
index 0000000..2558623
--- /dev/null
+++ b/src/utils/apiUtils.ts
@@ -0,0 +1,86 @@
+import axios from 'axios'
+import { RepoFile } from '../types'
+
+export const fetchFolderData = async (
+ folderUrl: string,
+ setError: (error: string) => void,
+ setLog: (log: string) => void,
+ apiKey?: string
+): Promise => {
+ const contentIndex = folderUrl.indexOf('contents/') + 'contents/'.length
+ const decodedUrl = decodeURIComponent(
+ contentIndex > 0 ? folderUrl.substring(contentIndex) : folderUrl
+ )
+ setLog(`Fetching data from ${decodedUrl}`)
+ const options: any = {}
+ if (apiKey) {
+ options.headers = {
+ Authorization: `Bearer ${apiKey}`,
+ }
+ }
+ const { data: response } = await axios.get(folderUrl, options)
+ setLog(`Data fetched from ${decodedUrl}`)
+ return response
+}
+
+export const processFolderContents = async (
+ folder: any[],
+ setError: (error: string) => void,
+ setLog: (log: string) => void,
+ path?: string,
+ apiKey?: string
+): Promise => {
+ const filePromises = folder.map(async (item: RepoFile) => {
+ try {
+ if (item.type === 'file') {
+ setLog(`Processing ${item.name}`)
+ const extension = item.name.split('.').pop() || 'unknown'
+ const sizeInKB = Math.round(parseInt(item.size) / 1024)
+ let size
+ if (sizeInKB >= 1024) {
+ const sizeInMB = (sizeInKB / 1024).toFixed(2)
+ size = sizeInMB + ' MB'
+ } else {
+ size = sizeInKB + ' KB'
+ }
+
+ return {
+ name: item.name,
+ file_type: extension,
+ download_url: item.download_url,
+ sha: item.sha,
+ size: size,
+ path: item.path,
+ } as RepoFile
+ } else if (item.type === 'dir') {
+ setLog(`Processing ${item.name}`)
+ const subFolder = await fetchFolderData(item.url, setError, setLog, apiKey)
+
+ if (subFolder !== null) {
+ setLog(`Processing ${item.name}`)
+ const subFolderFiles = await processFolderContents(
+ subFolder,
+ setError,
+ setLog,
+ item.path,
+ apiKey
+ )
+ setLog(`Processed ${item.name}`)
+ return subFolderFiles
+ } else {
+ setLog(`Skipping ${item.name} due to error in fetching subfolder data`)
+ return null
+ }
+ }
+ } catch (error: any) {
+ setError(`Error processing ${item.name}: ${error.message}`)
+ return null
+ }
+ })
+
+ const files = await Promise.all(filePromises)
+ const flattenedFiles = files.flat()
+
+ setLog('Processing complete')
+ return flattenedFiles.filter((file): file is RepoFile => file !== null)
+}
diff --git a/src/utils/index.ts b/src/utils/index.ts
new file mode 100644
index 0000000..765a03b
--- /dev/null
+++ b/src/utils/index.ts
@@ -0,0 +1,2 @@
+export * from './apiUtils'
+export * from './zipUtils'
diff --git a/src/utils/zipUtils.ts b/src/utils/zipUtils.ts
new file mode 100644
index 0000000..2affd7c
--- /dev/null
+++ b/src/utils/zipUtils.ts
@@ -0,0 +1,75 @@
+import JSZip from 'jszip'
+import { RepoFile } from '../types'
+
+export const generateZip = async (
+ zip: JSZip,
+ repoFiles: RepoFile[],
+ setError: (error: string) => void,
+ setLog: (log: string) => void
+) => {
+ const totalFiles = repoFiles.length
+ let completedFiles = 0
+
+ const filePromises = repoFiles.map(async (file: RepoFile) => {
+ const filePath = file.path
+
+ try {
+ const response = await fetch(file.download_url)
+
+ if (!response.ok) {
+ throw new Error(`Failed to fetch ${file.name}`)
+ }
+
+ const contentLength = response.headers.get('content-length')
+ const totalSize = contentLength ? parseInt(contentLength, 10) : 0
+ let downloadedSize = 0
+
+ const fileContent = await response.blob()
+
+ const downloadProgress = (event: ProgressEvent) => {
+ if (event.lengthComputable) {
+ downloadedSize = event.loaded
+ const progress = Math.min(Math.round((downloadedSize / totalSize) * 100), 100)
+ setLog(`Downloading ${file.name}: ${progress}%`)
+ }
+ }
+
+ const reader = new FileReader()
+
+ reader.onload = () => {
+ if (filePath) {
+ const pathSegments = filePath.split('/')
+ let folder: JSZip | null = zip.folder(pathSegments[0]) as JSZip
+ const nestedFolders = pathSegments.slice(1, -1)
+ nestedFolders.forEach(folderName => {
+ folder = folder!.folder(folderName)
+ })
+ folder!.file(file.name, reader.result as ArrayBuffer)
+ } else {
+ zip.file(file.name, reader.result as ArrayBuffer)
+ }
+ completedFiles++
+ }
+
+ reader.onerror = error => {
+ setError(`Error reading file content: ${error}`)
+ throw error
+ }
+
+ reader.onprogress = downloadProgress as unknown as (event: ProgressEvent) => any
+
+ reader.readAsArrayBuffer(fileContent)
+
+ await new Promise(resolve => {
+ reader.onloadend = () => resolve(null)
+ })
+ } catch (error: any) {
+ setError(`Error fetching file content: ${error.message}`)
+ throw error
+ }
+ })
+
+ await Promise.all(filePromises)
+
+ setLog(`Downloaded and added ${completedFiles} out of ${totalFiles} files to the zip.`)
+}
diff --git a/tsconfig.json b/tsconfig.json
index 31de6f2..08042db 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -16,4 +16,4 @@
"target": "es6"
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
-}
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 6107118..f5cf045 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -74,6 +74,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
+"@types/file-saver@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.5.tgz"
+ integrity sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==
+
"@types/node@^20.1.4":
version "20.1.4"
resolved "https://registry.npmjs.org/@types/node/-/node-20.1.4.tgz"
@@ -206,6 +211,11 @@ concat-map@0.0.1:
resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
cross-spawn@^7.0.2:
version "7.0.3"
resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz"
@@ -375,6 +385,11 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
+file-saver@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz"
+ integrity sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==
+
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz"
@@ -456,6 +471,11 @@ ignore@^5.2.0:
resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz"
integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==
+immediate@~3.0.5:
+ version "3.0.6"
+ resolved "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz"
+ integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
+
import-fresh@^3.0.0, import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
@@ -477,7 +497,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2:
+inherits@~2.0.3, inherits@2:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -499,6 +519,11 @@ is-path-inside@^3.0.3:
resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz"
integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz"
+ integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
@@ -531,6 +556,16 @@ json-stable-stringify-without-jsonify@^1.0.1:
resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
+jszip@^3.10.1:
+ version "3.10.1"
+ resolved "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz"
+ integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
+ dependencies:
+ lie "~3.3.0"
+ pako "~1.0.2"
+ readable-stream "~2.3.6"
+ setimmediate "^1.0.5"
+
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz"
@@ -539,6 +574,13 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
+lie@~3.3.0:
+ version "3.3.0"
+ resolved "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz"
+ integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
+ dependencies:
+ immediate "~3.0.5"
+
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz"
@@ -620,6 +662,11 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
+pako@~1.0.2:
+ version "1.0.11"
+ resolved "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz"
+ integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
@@ -652,6 +699,11 @@ prettier@2.8.8:
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
+process-nextick-args@~2.0.0:
+ version "2.0.1"
+ resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
+ integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
@@ -682,6 +734,19 @@ react@^18.2.0:
dependencies:
loose-envify "^1.1.0"
+readable-stream@~2.3.6:
+ version "2.3.8"
+ resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
@@ -706,6 +771,11 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
+safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+ version "5.1.2"
+ resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
scheduler@^0.23.0:
version "0.23.0"
resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz"
@@ -713,6 +783,11 @@ scheduler@^0.23.0:
dependencies:
loose-envify "^1.1.0"
+setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz"
+ integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
+
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz"
@@ -725,6 +800,13 @@ shebang-regex@^3.0.0:
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz"
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+ dependencies:
+ safe-buffer "~5.1.0"
+
strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
@@ -773,6 +855,11 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
+util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
which@^2.0.1:
version "2.0.2"
resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz"