create-strapi-app
Version:
Generate a new Strapi application.
1 lines • 12.4 kB
Source Map (JSON)
{"version":3,"file":"template.mjs","sources":["../../src/utils/template.ts"],"sourcesContent":["import path from 'node:path';\nimport url from 'node:url';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport * as tar from 'tar';\nimport retry from 'async-retry';\n\nimport fse from 'fs-extra';\nimport type { Scope } from '../types';\n\nconst stripTrailingSlash = (str: string) => {\n return str.endsWith('/') ? str.slice(0, -1) : str;\n};\n\n// Merge template with new project being created\nexport async function copyTemplate(scope: Scope, rootPath: string) {\n const { template } = scope;\n\n if (!template) {\n throw new Error('Missing template or example app option');\n }\n\n if (await isOfficialTemplate(template, scope.templateBranch)) {\n await retry(\n () =>\n downloadGithubRepo(rootPath, {\n owner: 'strapi',\n repo: 'strapi',\n branch: scope.templateBranch,\n subPath: `templates/${template}`,\n }),\n {\n retries: 3,\n onRetry(err, attempt) {\n console.log(`Retrying to download the template. Attempt ${attempt}. Error: ${err}`);\n },\n }\n );\n\n return;\n }\n\n if (isLocalTemplate(template)) {\n const filePath = template.startsWith('file://') ? url.fileURLToPath(template) : template;\n\n await fse.copy(filePath, rootPath);\n }\n\n if (isGithubShorthand(template)) {\n const [owner, repo, ...pathSegments] = template.split('/');\n const subPath = pathSegments.length ? pathSegments.join('/') : scope.templatePath;\n\n await retry(\n () => downloadGithubRepo(rootPath, { owner, repo, branch: scope.templateBranch, subPath }),\n {\n retries: 3,\n onRetry(err, attempt) {\n console.log(`Retrying to download the template. Attempt ${attempt}. Error: ${err}`);\n },\n }\n );\n\n return;\n }\n\n if (isGithubRepo(template)) {\n const url = new URL(template);\n\n const [owner, repo, t, branch, ...pathSegments] = stripTrailingSlash(\n url.pathname.slice(1)\n ).split('/');\n\n if (t !== undefined && t !== 'tree') {\n throw new Error(`Invalid GitHub template URL: ${template}`);\n }\n\n if (scope.templateBranch) {\n await retry(\n () =>\n downloadGithubRepo(rootPath, {\n owner,\n repo,\n branch: scope.templateBranch,\n subPath: scope.templatePath,\n }),\n {\n retries: 3,\n onRetry(err, attempt) {\n console.log(`Retrying to download the template. Attempt ${attempt}. Error: ${err}`);\n },\n }\n );\n\n return;\n }\n\n await retry(\n () =>\n downloadGithubRepo(rootPath, {\n owner,\n repo,\n branch: decodeURIComponent(branch) ?? scope.templateBranch,\n subPath: pathSegments.length\n ? decodeURIComponent(pathSegments.join('/'))\n : scope.templatePath,\n }),\n {\n retries: 3,\n onRetry(err, attempt) {\n console.log(`Retrying to download the template. Attempt ${attempt}. Error: ${err}`);\n },\n }\n );\n\n throw new Error(`Invalid GitHub template URL: ${template}`);\n }\n}\n\ntype RepoInfo = {\n owner: string;\n repo: string;\n branch?: string;\n subPath?: string | null;\n};\n\nasync function downloadGithubRepo(rootPath: string, { owner, repo, branch, subPath }: RepoInfo) {\n const filePath = subPath ? subPath.split('/').join(path.posix.sep) : null;\n\n let checkContentUrl = `https://api.github.com/repos/${owner}/${repo}/contents`;\n if (filePath) {\n checkContentUrl = `${checkContentUrl}/${filePath}`;\n }\n\n if (branch) {\n checkContentUrl = `${checkContentUrl}?ref=${branch}`;\n }\n\n const checkRes = await fetch(checkContentUrl, {\n method: 'HEAD',\n });\n\n if (checkRes.status !== 200) {\n throw new Error(\n `Could not find a template at https://github.com/${owner}/${repo}${branch ? ` on branch ${branch}` : ''}${filePath ? ` at path ${filePath}` : ''}`\n );\n }\n\n let url = `https://api.github.com/repos/${owner}/${repo}/tarball`;\n\n if (branch) {\n url = `${url}/${branch}`;\n }\n\n const res = await fetch(url);\n\n if (!res.body) {\n throw new Error(`Failed to download ${url}`);\n }\n\n await pipeline(\n // @ts-expect-error - Readable is not a valid source\n Readable.fromWeb(res.body),\n tar.x({\n cwd: rootPath,\n strip: filePath ? filePath.split('/').length + 1 : 1,\n filter(path) {\n if (filePath) {\n return path.split('/').slice(1).join('/').startsWith(filePath);\n }\n\n return true;\n },\n })\n );\n}\n\nfunction isLocalTemplate(template: string) {\n return (\n template.startsWith('file://') ||\n fse.existsSync(path.isAbsolute(template) ? template : path.resolve(process.cwd(), template))\n );\n}\n\nfunction isGithubShorthand(value: string) {\n if (isValidUrl(value)) {\n return false;\n }\n\n return /^[\\w-]+\\/[\\w-.]+(\\/[\\w-.]+)*$/.test(value);\n}\n\nfunction isGithubRepo(value: string) {\n try {\n const url = new URL(value);\n\n return url.origin === 'https://github.com';\n } catch {\n return false;\n }\n}\n\nfunction isValidUrl(value: string) {\n try {\n // eslint-disable-next-line no-new\n new URL(value);\n return true;\n } catch {\n return false;\n }\n}\n\nconst OFFICIAL_NAME_REGEX = /^[a-zA-Z]*$/;\n\nasync function isOfficialTemplate(template: string, branch: string | undefined) {\n if (isValidUrl(template) || !OFFICIAL_NAME_REGEX.test(template)) {\n return false;\n }\n\n const res = await fetch(\n `https://api.github.com/repos/strapi/strapi/contents/templates/${template}?${branch ? `ref=${branch}` : ''}`,\n { method: 'HEAD' }\n );\n\n return res.status === 200;\n}\n"],"names":["stripTrailingSlash","str","endsWith","slice","copyTemplate","scope","rootPath","template","Error","isOfficialTemplate","templateBranch","retry","downloadGithubRepo","owner","repo","branch","subPath","retries","onRetry","err","attempt","console","log","isLocalTemplate","filePath","startsWith","url","fileURLToPath","fse","copy","isGithubShorthand","pathSegments","split","length","join","templatePath","isGithubRepo","URL","t","pathname","undefined","decodeURIComponent","path","posix","sep","checkContentUrl","checkRes","fetch","method","status","res","body","pipeline","Readable","fromWeb","tar","x","cwd","strip","filter","existsSync","isAbsolute","resolve","process","value","isValidUrl","test","origin","OFFICIAL_NAME_REGEX"],"mappings":"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"}