UNPKG

gitly

Version:

An API to download and/or extract git repositories

1 lines 23.4 kB
{"version":3,"sources":["../src/main.ts","../src/utils/clone.ts","../src/utils/archive.ts","../src/utils/error.ts","../src/utils/execute.ts","../src/utils/exists.ts","../src/utils/parse.ts","../src/utils/offline.ts","../src/utils/download.ts","../src/utils/fetch.ts","../src/utils/write.ts","../src/utils/extract.ts","../src/utils/gitly.ts"],"sourcesContent":["export { default } from './utils/gitly'\nexport { default as download } from './utils/download'\nexport { default as extract } from './utils/extract'\nexport { default as parse } from './utils/parse'\nexport { default as clone } from './utils/clone'\n","import spawn from 'cross-spawn'\nimport { rm } from 'node:fs/promises'\nimport path from 'node:path'\nimport * as tar from 'tar'\nimport type GitlyOptions from '../interfaces/options'\nimport { getArchivePath } from './archive'\nimport { GitlyCloneError } from './error'\nimport execute from './execute'\nimport exists from './exists'\nimport { isOffline } from './offline'\nimport parse from './parse'\n/**\n * Uses local git installation to clone a repository to the destination.\n * @param repository The repository to clone\n * @param options The options to use\n * @returns The path to the cloned repository\n * @throws {GitlyCloneError} When the repository fails to clone\n * @note This method requires a local git installation\n * @note This method caches the repository by default\n * @example\n * ```js\n * // ...\n * const path = await clone('iwatakeshi/git-copy')\n * // ...\n * ```\n */\nexport default async function clone(\n repository: string,\n options: GitlyOptions = {}\n): Promise<string> {\n const info = parse(repository, options)\n const archivePath = getArchivePath(info, options)\n const directory = archivePath.replace(/\\.tar\\.gz$/, '')\n let order: (() => Promise<boolean | string>)[] = []\n\n const local = async () => exists(`${archivePath}.tar.gz`)\n const remote = async () => {\n // If the repository is cached, remove the old cache\n if (await exists(archivePath)) {\n /* istanbul ignore next */\n await rm(archivePath)\n }\n\n // Prevent second order command injection\n\n const depth = options?.git?.depth || 1\n\n if (\n repository.includes('--upload-pack') ||\n directory.includes('--upload-pack')\n ) {\n throw new GitlyCloneError('Invalid argument')\n }\n\n /* istanbul ignore if */\n if (typeof depth !== 'number') {\n throw new GitlyCloneError('Invalid depth option')\n }\n\n /* istanbul ignore if */\n if (info.href.includes('--upload-pack')) {\n throw new GitlyCloneError('Invalid argument')\n }\n\n const child = spawn('git', [\n 'clone',\n '--depth',\n depth.toString(),\n info.href,\n directory,\n ])\n\n await new Promise((resolve, reject) => {\n child.on('error', (reason) => reject(new GitlyCloneError(reason.message)))\n child.on('close', (code) => {\n /* istanbul ignore next */\n if (code === 0) {\n // delete the .git directory to make the archive smaller\n rm(path.resolve(directory, '.git'), { recursive: true })\n .then(() =>\n // Create the archive after cloning\n tar.create(\n {\n gzip: true,\n file: archivePath,\n // Go one level up to include the repository name in the archive\n cwd: path.resolve(archivePath, '..'),\n portable: true,\n },\n [info.type]\n )\n )\n .then(() =>\n rm(path.resolve(directory), {\n recursive: true,\n })\n )\n .then(resolve)\n .catch((error) => reject(new GitlyCloneError(error.message)))\n } /* istanbul ignore next */ else {\n reject(new GitlyCloneError('Failed to clone the repository'))\n }\n })\n })\n return archivePath\n }\n /* istanbul ignore next */\n if ((await isOffline()) || options.cache) {\n order = [local]\n } else if (options.force || ['master', 'main'].includes(info.type)) {\n order = [remote, local]\n }\n\n try {\n const result = await execute(order)\n if (typeof result === 'boolean') {\n return archivePath\n }\n return result\n } catch (error) {\n if (options.throw) {\n throw error\n }\n }\n return ''\n}\n","import os from 'node:os'\nimport { join } from 'node:path'\nimport * as tar from 'tar'\n\nimport type GitlyOptions from '../interfaces/options'\nimport type URLInfo from '../interfaces/url'\n\nexport function getArchiveUrl(\n info: URLInfo,\n options: GitlyOptions = {}\n): string {\n const { path: repo, type } = info\n\n if (options.url?.filter) {\n return options.url.filter(info)\n }\n\n switch (info.hostname) {\n case 'bitbucket':\n return `https://bitbucket.org${repo}/get/${type}.tar.gz`\n case 'gitlab':\n return `https://gitlab.com${repo}/-/archive/${type}/${\n repo.split('/')[2]\n }-${type}.tar.gz`\n default:\n return `https://github.com${repo}/archive/${type}.tar.gz`\n }\n}\n\nexport function getArchivePath(\n info: URLInfo,\n options: GitlyOptions = {}\n): string {\n const { path, type, hostname: site } = info\n\n return join(\n options.temp || join(os.homedir(), '.gitly'),\n site,\n path,\n `${type}.tar.gz`\n )\n}\n\nexport const extract = tar.extract\n","export enum GitlyErrorType {\n Fetch = 'fetch',\n Clone = 'clone',\n Extract = 'extract',\n Download = 'download',\n Unknown = 'unknown',\n}\n\nexport default abstract class GitlyAbstractError extends Error {\n static type: GitlyErrorType\n type: GitlyErrorType\n rawMessage: string\n constructor(\n readonly message: string,\n readonly code: number = -1\n ) {\n super(message)\n this.rawMessage = message\n // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>\n const type = (this.type = this.ctor.type)\n this.message = `[${type ? `gitly:${type}` : 'gitly'}]: ${message}`\n Object.setPrototypeOf(this, new.target.prototype)\n }\n\n get ctor(): typeof GitlyAbstractError {\n return this.constructor as typeof GitlyAbstractError\n }\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>\nexport const GitlyUknownError = class extends GitlyAbstractError {\n static type = GitlyErrorType.Unknown\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>\nexport const GitlyFetchError = class extends GitlyAbstractError {\n static type = GitlyErrorType.Fetch\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>\nexport const GitlyExtractError = class extends GitlyAbstractError {\n static type = GitlyErrorType.Extract\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>\nexport const GitlyDownloadError = class extends GitlyAbstractError {\n static type = GitlyErrorType.Download\n}\n\n// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>\nexport const GitlyCloneError = class extends GitlyAbstractError {\n static type = GitlyErrorType.Clone\n}\n","export type Task = () => Promise<string | boolean>\n\nexport default async function execute(\n tasks: Task[]\n): Promise<string | boolean> {\n return new Promise((resolve, reject) => {\n const next = () => execute(tasks.slice(1)).then(resolve)\n return tasks[0]()\n .then((t) => (t ? resolve(t) : next()))\n .catch(reject)\n })\n}\n","import { constants, promises as fs } from 'node:fs'\nimport { isAbsolute } from 'node:path'\n\nimport type GitlyOptions from '../interfaces/options'\n\nimport parse from './parse'\nimport { getArchivePath } from './archive'\n\nexport default async function exists(\n path: string,\n options: GitlyOptions = {}\n): Promise<boolean> {\n let _path = path\n if (!isAbsolute(path)) {\n _path = getArchivePath(parse(path), options)\n }\n try {\n await fs.access(_path, constants.F_OK)\n return true\n // eslint-disable-next-line no-empty\n } catch (_) {}\n return false\n}\n","import { URL } from 'node:url'\n\nimport type GitlyOptions from '../interfaces/options'\nimport type URLInfo from '../interfaces/url'\n\n/**\n * Parses a url and returns the metadata\n *\n * @example\n * ```markdown\n * 1. owner/repo\n * 2. owner/repo#tag\n * 3. https://host.com/owner/repo\n * 4. host.com/owner/repo\n * 5. host.com/owner/repo#tag\n * 6. host:owner/repo\n * 7. host:owner/repo#tag\n * ```\n */\nexport default function parse(\n url: string,\n options: GitlyOptions = {}\n): URLInfo {\n const { url: normalized, host } = normalizeURL(url, options)\n const result = new URL(normalized)\n const paths = (result.pathname || '').split('/').filter(Boolean)\n const owner = paths.shift() || ''\n const repository = paths.shift() || ''\n return {\n protocol: (result.protocol || 'https').replace(/:/g, ''),\n host: result.host || host || 'github.com',\n hostname: (result.hostname || host || 'github').replace(/\\.(\\S+)/, ''),\n hash: result.hash || '',\n href: result.href || '',\n path: result.pathname || '',\n repository,\n owner,\n type: (result.hash || '#master').substring(1),\n }\n}\n\nfunction normalizeURL(url: string, options: GitlyOptions) {\n const { host } = options\n\n /* istanbul ignore if */\n if (url.includes('0') && Array.from(url.matchAll(/0/g)).length > 25) {\n throw new Error('Invalid argument')\n }\n /* istanbul ignore if */\n if (host?.includes('0') && Array.from(host.matchAll(/0/g)).length > 25) {\n throw new Error('Invalid argument')\n }\n\n const isNotProtocol = !/http(s)?:\\/\\//.test(url)\n const hasHost = /([\\S]+):.+/.test(url)\n const hasTLD = /[\\S]+\\.([\\D]+)/.test(url)\n\n let normalizedURL = url.replace('www.', '').replace('.git', '')\n let updatedHost = host || ''\n\n if (isNotProtocol && hasHost) {\n // Matches host:owner/repo\n const hostMatch = url.match(/([\\S]+):.+/)\n updatedHost = hostMatch ? hostMatch[1] : ''\n normalizedURL = `https://${updatedHost}.com/${normalizedURL.replace(`${updatedHost}:`, '')}`\n } else if (isNotProtocol && hasTLD) {\n // Matches host.com/...\n normalizedURL = `https://${normalizedURL}`\n } else if (isNotProtocol) {\n // Matches owner/repo\n const tldMatch = (host || '').match(/[\\S]+\\.([\\D]+)/)\n const domain = (host || 'github').replace(\n `.${tldMatch ? tldMatch[1] : 'com'}`,\n ''\n )\n const tld = tldMatch ? tldMatch[1] : 'com'\n normalizedURL = `https://${domain}.${tld}/${normalizedURL}`\n }\n\n return { url: normalizedURL, host: updatedHost }\n}\n","import { promises as dns } from 'node:dns'\nconst { lookup } = dns\nexport async function isOffline(): Promise<boolean> {\n try {\n await lookup('google.com')\n return false\n // eslint-disable-next-line no-empty\n } catch (_) {}\n return true\n}\n","import type GitlyOptions from '../interfaces/options'\n\nimport { rm } from 'shelljs'\nimport { getArchivePath, getArchiveUrl } from './archive'\nimport execute from './execute'\nimport exists from './exists'\nimport fetch from './fetch'\nimport { isOffline } from './offline'\nimport parse from './parse'\n\n/**\n * Download the tar file from the repository\n * and store it in a temporary directory\n * @param repository The repository to download\n *\n * @example\n * ```js\n * // ..\n * const path = await download('iwatakeshi/git-copy')\n * // ...\n * ```\n */\nexport default async function download(\n repository: string,\n options: GitlyOptions = {}\n): Promise<string> {\n const info = parse(repository, options)\n const archivePath = getArchivePath(info, options)\n const url = getArchiveUrl(info, options)\n const local = async () => exists(archivePath)\n const remote = async () => {\n // If the repository is cached, remove the old cache\n if (await exists(archivePath)) {\n /* istanbul ignore next */\n rm(archivePath)\n }\n\n return fetch(url, archivePath, options)\n }\n let order = [local, remote]\n if ((await isOffline()) || options.cache) {\n order = [local]\n } else if (options.force || ['master', 'main'].includes(info.type)) {\n order = [remote, local]\n }\n\n try {\n const result = await execute(order)\n if (typeof result === 'boolean') {\n return archivePath\n }\n return result\n } catch (error) {\n if (options.throw) {\n throw error\n }\n }\n return ''\n}\n","import axios from 'axios'\nimport * as stream from 'node:stream'\nimport { promisify } from 'node:util'\n\nimport { GitlyDownloadError } from './error'\nimport write from './write'\nimport type GitlyOptions from '../interfaces/options'\n\nconst pipeline = promisify(stream.pipeline)\n\nexport default async function fetch(\n url: string,\n file: string,\n options: GitlyOptions = {}\n): Promise<string> {\n const response = await axios.get(url, {\n headers: options.headers,\n responseType: 'stream',\n validateStatus: (status) => status >= 200 && status < 500,\n })\n\n const { statusText: message, status: code } = response\n if (code >= 400) throw new GitlyDownloadError(message, code)\n if (code >= 300 && code < 400 && response.headers.location) {\n return fetch(response.headers.location, file)\n }\n await pipeline(response.data, await write(file))\n return file\n}\n","import type { WriteStream } from 'node:fs'\nimport { createWriteStream, promises as fs } from 'node:fs'\nimport { dirname, normalize } from 'node:path'\n\nconst { mkdir } = fs\n/**\n * Create a folder and return a writable stream.\n * @param path The path to write a file\n */\nexport default async function write(path: string): Promise<WriteStream> {\n const _path = normalize(path)\n await mkdir(dirname(_path), { recursive: true })\n return createWriteStream(_path)\n}\n","import { promises as fs } from 'node:fs'\nimport { resolve } from 'node:path'\n\nimport type GitlyOptions from '../interfaces/options'\n\nimport exists from './exists'\nimport { extract } from './archive'\n\nconst { mkdir } = fs\n\n/**\n * Extract a zipped file to the specified destination\n * @param source The source zipped file\n * @param destination The path to extract the zipped file\n * @param options\n *\n */\nexport default async (\n source: string,\n destination: string,\n options: GitlyOptions = {}\n): Promise<string> => {\n const _destination = resolve(destination)\n if (await exists(source, options)) {\n try {\n const filter = options.extract?.filter\n ? options.extract.filter\n : () => true\n await mkdir(destination, { recursive: true })\n await extract({ strip: 1, filter, file: source, cwd: _destination })\n return _destination\n // eslint-disable-next-line no-empty\n } catch (_) {}\n }\n return ''\n}\n","import type GitlyOptions from '../interfaces/options'\nimport clone from './clone'\nimport download from './download'\nimport extract from './extract'\n\n/**\n * Downloads and extracts the repository\n * @param repository The repository to download\n * @param destination The destination to extract\n * @returns A tuple with the source and destination respectively\n */\nexport default async function gitly(\n repository: string,\n destination: string,\n options: GitlyOptions\n): Promise<[string, string]> {\n let source = ''\n switch (options?.backend) {\n case 'git':\n source = await clone(repository, options)\n break\n default:\n source = await download(repository, options)\n break\n }\n\n return [source, await extract(source, destination, options)]\n}\n"],"mappings":"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","names":["import_node_path","tar","_a","path","os","extract","_a","resolve","import_node_path","path","fs","dns","_a","spawn","resolve","path","import_node_fs","import_node_path","fs","path","pipeline","axios","import_node_fs","import_node_path","mkdir","fs","_a","extract"]}