@shopify/create-app
Version:
A CLI tool to create a new Shopify app.
348 lines (343 loc) • 13.6 kB
JavaScript
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