UNPKG

@shopify/create-app

Version:

A CLI tool to create a new Shopify app.

348 lines (343 loc) • 13.6 kB
import { cacheRetrieve, cacheRetrieveOrRepopulate } from "./chunk-5LLHAM5N.js"; import { AbortController, exec } from "./chunk-TGZSJFOF.js"; import { runWithTimer } from "./chunk-YYJ6EVI6.js"; import { AbortError, BugError } from "./chunk-LEQAULOW.js"; import { require_semver } from "./chunk-OQ3KXXGH.js"; import { fileExists, fileExistsSync, findPathUp, glob, inferPackageManagerForGlobalCLI, outputContent, outputDebug, outputToken, readFile, writeFile } from "./chunk-PK2M5CKS.js"; import { dirname, joinPath } from "./chunk-C3J4HVUN.js"; import { __toESM, init_cjs_shims } from "./chunk-3XNI6LP4.js"; // ../cli-kit/dist/public/node/node-package-manager.js init_cjs_shims(); // ../cli-kit/dist/public/common/json.js init_cjs_shims(); function parseJSON(jsonString, context) { try { return JSON.parse(jsonString); } catch (error) { let errorMessage = error instanceof Error ? error.message : String(error), contextMessage = context ? ` from ${context}` : ""; throw new AbortError(`Failed to parse JSON${contextMessage}. ${errorMessage}`); } } // ../cli-kit/dist/public/node/node-package-manager.js var import_semver = __toESM(require_semver(), 1), yarnLockfile = "yarn.lock", npmLockfile = "package-lock.json", pnpmLockfile = "pnpm-lock.yaml", bunLockfile = "bun.lockb", modernBunLockfile = "bun.lock", pnpmWorkspaceFile = "pnpm-workspace.yaml", lockfiles = [yarnLockfile, pnpmLockfile, npmLockfile, bunLockfile, modernBunLockfile], lockfilesByManager = { yarn: [yarnLockfile], npm: [npmLockfile], pnpm: [pnpmLockfile], bun: [bunLockfile, modernBunLockfile], homebrew: [], unknown: [] }, packageManager = ["yarn", "npm", "pnpm", "bun", "homebrew", "unknown"], UnknownPackageManagerError = class extends AbortError { constructor() { super("Unknown package manager"); } }, PackageJsonNotFoundError = class extends AbortError { constructor(directory) { super(outputContent`The directory ${outputToken.path(directory)} doesn't have a package.json.`); } }, FindUpAndReadPackageJsonNotFoundError = class extends BugError { constructor(directory) { super(outputContent`Couldn't find a a package.json traversing directories from ${outputToken.path(directory)}`); } }; function packageManagerFromUserAgent(env = process.env) { let userAgent = env.npm_config_user_agent; return ["yarn", "pnpm", "bun", "npm"].find((pm) => userAgent?.includes(pm)) ?? "unknown"; } function hasBunLockfileSync(directory) { return fileExistsSync(joinPath(directory, bunLockfile)) || fileExistsSync(joinPath(directory, modernBunLockfile)); } function normalizePackageManagerForProject(packageManager2) { switch (packageManager2) { case "yarn": case "npm": case "pnpm": case "bun": return packageManager2; case "homebrew": case "unknown": return "npm"; } } function packageManagerBinaryCommand(packageManager2, binary, ...binaryArgs) { switch (packageManager2) { case "npm": return { command: "npm", args: ["exec", "--", binary, ...binaryArgs] }; case "pnpm": return { command: "pnpm", args: ["exec", binary, ...binaryArgs] }; case "yarn": return { command: "yarn", args: ["run", binary, ...binaryArgs] }; case "bun": return { command: "bun", args: ["x", binary, ...binaryArgs] }; } } async function getPackageManager(fromDirectory) { let current = fromDirectory; for (outputDebug(outputContent`Looking for a lockfile in ${outputToken.path(current)}...`); ; ) { if (fileExistsSync(joinPath(current, yarnLockfile))) return "yarn"; if (fileExistsSync(joinPath(current, pnpmLockfile)) || fileExistsSync(joinPath(current, pnpmWorkspaceFile))) return "pnpm"; if (hasBunLockfileSync(current)) return "bun"; if (fileExistsSync(joinPath(current, npmLockfile))) return "npm"; let parent = dirname(current); if (parent === current) break; current = parent; } let pm = packageManagerFromUserAgent(); return pm !== "unknown" ? pm : "npm"; } async function packageManagerBinaryCommandForDirectory(fromDirectory, binary, ...binaryArgs) { let packageManager2 = normalizePackageManagerForProject(await getPackageManager(fromDirectory)); return packageManagerBinaryCommand(packageManager2, binary, ...binaryArgs); } async function installNPMDependenciesRecursively(options) { let packageJsons = await glob(joinPath(options.directory, "**/package.json"), { ignore: [joinPath(options.directory, "node_modules/**/package.json")], cwd: options.directory, onlyFiles: !0, deep: options.deep }), abortController = new AbortController(); try { await Promise.all(packageJsons.map(async (packageJsonPath) => { let directory = dirname(packageJsonPath); await installNodeModules({ directory, packageManager: options.packageManager, stdout: void 0, stderr: void 0, signal: abortController.signal, args: [] }); })); } catch (error) { throw abortController.abort(), error; } } async function installNodeModules(options) { let execOptions = { cwd: options.directory, stdin: void 0, stdout: options.stdout, stderr: options.stderr, signal: options.signal }, args = ["install"]; options.args && (args = args.concat(options.args)), await runWithTimer("cmd_all_timing_network_ms")(async () => { await exec(options.packageManager, args, execOptions); }); } async function getPackageName(packageJsonPath) { return (await readAndParsePackageJson(packageJsonPath)).name; } async function getPackageVersion(packageJsonPath) { return (await readAndParsePackageJson(packageJsonPath)).version; } async function getDependencies(packageJsonPath) { let packageJsonContent = await readAndParsePackageJson(packageJsonPath), dependencies = packageJsonContent.dependencies ?? {}, devDependencies = packageJsonContent.devDependencies ?? {}; return { ...dependencies, ...devDependencies }; } async function usesWorkspaces(appDirectory) { let packageJsonPath = joinPath(appDirectory, "package.json"), packageJsonContent = await readAndParsePackageJson(packageJsonPath), pnpmWorkspacePath = joinPath(appDirectory, pnpmWorkspaceFile); return !!packageJsonContent.workspaces || fileExists(pnpmWorkspacePath); } async function checkForNewVersion(dependency, currentVersion, { cacheExpiryInHours = 0 } = {}) { let getLatestVersion = async () => (outputDebug(outputContent`Checking if there's a version of ${dependency} newer than ${currentVersion}`), getLatestNPMPackageVersion(dependency)), cacheKey = `npm-package-${dependency}`, lastVersion; try { lastVersion = await cacheRetrieveOrRepopulate(cacheKey, getLatestVersion, cacheExpiryInHours * 3600 * 1e3); } catch { return; } if (lastVersion && new import_semver.SemVer(currentVersion).compare(lastVersion) < 0) return lastVersion; } function checkForCachedNewVersion(dependency, currentVersion) { let cacheKey = `npm-package-${dependency}`, lastVersion = cacheRetrieve(cacheKey)?.value; if (lastVersion && new import_semver.SemVer(currentVersion).compare(lastVersion) < 0) return lastVersion; } function versionSatisfies(version, requirements) { return (0, import_semver.satisfies)(version, requirements); } async function readAndParsePackageJson(packageJsonPath) { if (!await fileExists(packageJsonPath)) throw new PackageJsonNotFoundError(dirname(packageJsonPath)); return parseJSON(await readFile(packageJsonPath), packageJsonPath); } async function addNPMDependenciesIfNeeded(dependencies, options) { outputDebug(outputContent`Adding the following dependencies if needed: ${outputToken.json(dependencies)} With options: ${outputToken.json(options)} `); let packageJsonPath = joinPath(options.directory, "package.json"); if (!await fileExists(packageJsonPath)) throw new PackageJsonNotFoundError(options.directory); let existingDependencies = Object.keys(await getDependencies(packageJsonPath)), dependenciesToAdd = dependencies.filter((dep) => !existingDependencies.includes(dep.name)); dependenciesToAdd.length !== 0 && await addNPMDependencies(dependenciesToAdd, options); } async function addNPMDependencies(dependencies, options) { let dependenciesWithVersion = dependencies.map((dep) => dep.version ? `${dep.name}@${dep.version}` : dep.name); switch (options.stdout?.write(`Installing ${dependenciesWithVersion.join(" ")} with ${options.packageManager}`), options.packageManager) { case "npm": for (let dep of dependenciesWithVersion) await installDependencies(options, argumentsToAddDependenciesWithNPM(dep, options.type)); break; case "yarn": await installDependencies(options, argumentsToAddDependenciesWithYarn(dependenciesWithVersion, options.type, !!options.addToRootDirectory)); break; case "pnpm": await installDependencies(options, argumentsToAddDependenciesWithPNPM(dependenciesWithVersion, options.type, !!options.addToRootDirectory)); break; case "bun": await installDependencies(options, argumentsToAddDependenciesWithBun(dependenciesWithVersion, options.type)), await installDependencies(options, ["install"]); break; case "homebrew": throw new AbortError("Homebrew can't be used to install project dependencies. Use npm, yarn, pnpm, or bun."); case "unknown": throw new UnknownPackageManagerError(); } } async function installDependencies(options, args) { return runWithTimer("cmd_all_timing_network_ms")(async () => exec(options.packageManager, args, { cwd: options.directory, stdout: options.stdout, stderr: options.stderr, signal: options.signal })); } async function addNPMDependenciesWithoutVersionIfNeeded(dependencies, options) { await addNPMDependenciesIfNeeded(dependencies.map((dependency) => ({ name: dependency, version: void 0 })), options); } function argumentsToAddDependenciesWithNPM(dependency, type) { let command = ["install", dependency, { dev: "--save-dev", peer: "--save-peer", prod: "--save-prod" }[type]]; return dependency.match(/@\d/g) && command.push("--save-exact"), command; } function argumentsToAddDependenciesWithYarn(dependencies, type, addAtRoot = !1) { let typeFlags = { dev: "--dev", peer: "--peer", prod: "--prod" }; return ["add", ...addAtRoot ? ["-W"] : [], ...dependencies, typeFlags[type]]; } function argumentsToAddDependenciesWithPNPM(dependencies, type, addAtRoot = !1) { let typeFlags = { dev: "--save-dev", peer: "--save-peer", prod: "--save-prod" }; return ["add", ...addAtRoot ? ["-w"] : [], ...dependencies, typeFlags[type]]; } function argumentsToAddDependenciesWithBun(dependencies, type) { let flag = { dev: "--development", peer: "--optional" }[type]; return ["add", ...dependencies, ...flag ? [flag] : []]; } async function findUpAndReadPackageJson(fromDirectory) { let packageJsonPath = await findPathUp("package.json", { cwd: fromDirectory, type: "file" }); if (packageJsonPath) { let packageJson = parseJSON(await readFile(packageJsonPath), packageJsonPath); return { path: packageJsonPath, content: packageJson }; } else throw new FindUpAndReadPackageJsonNotFoundError(fromDirectory); } async function addResolutionOrOverride(directory, dependencies) { let packageManager2 = await getPackageManager(directory), packageJsonContent = await readAndParsePackageJson(joinPath(directory, "package.json")), key = packageManager2 === "yarn" ? "resolutions" : "overrides"; packageJsonContent[key] = { ...packageJsonContent[key], ...dependencies }, await writePackageJSON(directory, packageJsonContent); } async function getLatestNPMPackageVersion(name) { return outputDebug(outputContent`Getting the latest version of NPM package: ${outputToken.raw(name)}`), runWithTimer("cmd_all_timing_network_ms")(async () => { let { default: latestVersion } = await import("./latest-version-HW6YILV7.js"); return latestVersion(name); }); } async function writePackageJSON(directory, packageJSON) { outputDebug(outputContent`JSON-encoding and writing content to package.json at ${outputToken.path(directory)}...`); let packagePath = joinPath(directory, "package.json"); await writeFile(packagePath, JSON.stringify(packageJSON, null, 2)); } function inferPackageManager(optionsPackageManager, env = process.env) { if (optionsPackageManager && packageManager.includes(optionsPackageManager)) return optionsPackageManager; let usedPackageManager = packageManagerFromUserAgent(env); if (usedPackageManager !== "unknown") return usedPackageManager; let globalPackageManager = inferPackageManagerForGlobalCLI(); return globalPackageManager !== "unknown" ? globalPackageManager : "npm"; } export { yarnLockfile, npmLockfile, pnpmLockfile, bunLockfile, pnpmWorkspaceFile, lockfiles, lockfilesByManager, packageManager, UnknownPackageManagerError, PackageJsonNotFoundError, FindUpAndReadPackageJsonNotFoundError, packageManagerFromUserAgent, getPackageManager, packageManagerBinaryCommandForDirectory, installNPMDependenciesRecursively, installNodeModules, getPackageName, getPackageVersion, getDependencies, usesWorkspaces, checkForNewVersion, checkForCachedNewVersion, versionSatisfies, readAndParsePackageJson, addNPMDependenciesIfNeeded, addNPMDependencies, addNPMDependenciesWithoutVersionIfNeeded, findUpAndReadPackageJson, addResolutionOrOverride, writePackageJSON, inferPackageManager }; //# sourceMappingURL=chunk-ZPNNBR5Z.js.map