@winjs-dev/create-win
Version:
@winjs-dev/create-win
425 lines (422 loc) • 13.6 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
default: () => src_default
});
module.exports = __toCommonJS(src_exports);
var clackPrompts = __toESM(require("@winner-fed/clack-prompts"));
var import_utils = require("@winner-fed/utils");
var import_fs = require("fs");
var import_path = require("path");
var import_template = require("./template");
var devCommands = {
pnpm: "pnpm dev",
yarn: "yarn dev",
npm: "npm run dev",
bun: "bun run dev"
};
function parseStr(str) {
return str.replace(/-(\w)/g, function(_$0, $1) {
return $1.toUpperCase();
});
}
function getUUID() {
return Number(Math.random().toString().substr(2)).toString(36);
}
function generateOnlyContainer(str) {
return `${parseStr(str)}${getUUID()}`;
}
var ETemplate = /* @__PURE__ */ ((ETemplate2) => {
ETemplate2["app"] = "app";
ETemplate2["pc"] = "pc";
ETemplate2["plugin"] = "plugin";
ETemplate2["sample"] = "sample";
return ETemplate2;
})(ETemplate || {});
var pkg = require("../package");
var DEFAULT_DATA = {
pluginName: "winjs-plugin-demo",
projectName: "winjs-template",
email: "i@domain.com",
author: "winjs",
appContainerName: "root",
version: pkg.version,
npmClient: "pnpm" /* pnpm */,
registry: import_template.ERegistry.npm,
withHusky: false,
extraNpmrc: "",
appTemplate: "app" /* app */,
vueVersion: "3" /* vue3 */
};
var src_default = async ({
cwd,
args,
defaultData = DEFAULT_DATA
}) => {
let [name] = args._;
let npmClient = "pnpm" /* pnpm */;
let registry = import_template.ERegistry.npm;
let appTemplate = (defaultData == null ? void 0 : defaultData.appTemplate) || "app" /* app */;
let vueVersion = (defaultData == null ? void 0 : defaultData.vueVersion) || "3" /* vue3 */;
const { username, email } = await (0, import_utils.getGitInfo)();
const author = email && username ? `${username} <${email}>` : "";
let pluginName = `winjs-plugin-${name || "demo"}`;
let projectName = `winjs-template-${name || "demo"}`;
const appContainerName = generateOnlyContainer(projectName);
let target = name ? (0, import_path.join)(cwd, name) : cwd;
const { isCancel, text, select, intro, outro, box, taskLog } = clackPrompts;
const exitPrompt = () => {
outro(import_utils.chalk.red("Exit create-win"));
process.exit(1);
};
const setName = async () => {
name = await text({
message: "What's the target folder name?",
initialValue: name || "my-app",
validate: (value) => {
if (!value.length) {
return "Please input project name";
}
if (value != "." && import_utils.fsExtra.existsSync((0, import_path.join)(cwd, value))) {
return `Folder ${value} already exists`;
}
}
});
};
const selectAppTemplate = async () => {
appTemplate = await select({
message: "Pick WinJS App Template",
options: [
{ label: "Simple App", value: "sample" /* sample */ },
{
label: "PC Web",
value: "pc" /* pc */,
hint: "for pc web"
},
{ label: "H5 App", value: "app" /* app */ },
{
label: "WinJS Plugin",
value: "plugin" /* plugin */,
hint: "for plugin development"
}
],
initialValue: "sample" /* sample */
});
};
const selectNpmClient = async () => {
npmClient = await select({
message: "Pick Npm Client",
options: [
{ label: "npm" /* npm */, value: "npm" /* npm */ },
{ label: "yarn" /* yarn */, value: "yarn" /* yarn */, hint: "recommended" },
{ label: "pnpm" /* pnpm */, value: "pnpm" /* pnpm */ }
],
initialValue: "yarn" /* yarn */
});
};
const selectVueVersion = async () => {
vueVersion = await select({
message: "选择 Vue 版本",
options: [
{ label: "Vue 3", value: "3" /* vue3 */, hint: "推荐" },
{ label: "Vue 2", value: "2" /* vue2 */ }
],
initialValue: "3" /* vue3 */
});
};
const selectRegistry = async () => {
registry = await select({
message: "Pick Npm Registry",
options: [
{
label: "npm",
value: import_template.ERegistry.npm
},
{
label: "taobao",
value: import_template.ERegistry.taobao,
hint: "recommended for China"
}
],
initialValue: import_template.ERegistry.taobao
});
};
const internalTemplatePrompts = async () => {
intro("Creating a new WinJS project...");
await setName();
if (isCancel(name)) {
exitPrompt();
}
target = (0, import_path.join)(cwd, name);
await selectAppTemplate();
if (isCancel(appTemplate)) {
exitPrompt();
}
const needsVueSelection = appTemplate !== "plugin" /* plugin */ && appTemplate !== ETemplate.huipro;
if (needsVueSelection) {
await selectVueVersion();
if (isCancel(vueVersion)) {
exitPrompt();
}
}
await selectNpmClient();
if (isCancel(npmClient)) {
exitPrompt();
}
await selectRegistry();
if (isCancel(registry)) {
exitPrompt();
}
const isPlugin = appTemplate === "plugin" /* plugin */;
if (isPlugin) {
pluginName = await text({
message: `What's the plugin name?`,
placeholder: pluginName,
validate: (value) => {
if (!(value == null ? void 0 : value.length)) {
return "Please input plugin name";
}
}
});
if (isCancel(pluginName)) {
exitPrompt();
}
}
};
const useDefaultData = !!args.default;
const useExternalTemplate = !!args.template;
switch (true) {
case useExternalTemplate:
await selectNpmClient();
if (isCancel(npmClient)) {
exitPrompt();
}
await selectRegistry();
if (isCancel(registry)) {
exitPrompt();
}
await (0, import_template.unpackTemplate)({
template: args.template,
dest: target,
registry
});
break;
default:
if (!useDefaultData) {
await internalTemplatePrompts();
}
}
const version = pkg.version;
const monorepoRoot = await detectMonorepoRoot({ target });
const inMonorepo = !!monorepoRoot;
const projectRoot = inMonorepo ? monorepoRoot : target;
const shouldInitGit = args.git !== false;
const withHusky = shouldInitGit && !inMonorepo;
let pnpmExtraNpmrc = "";
const isPnpm = npmClient === "pnpm" /* pnpm */;
let pnpmMajorVersion;
if (isPnpm) {
pnpmMajorVersion = await getPnpmMajorVersion();
if (pnpmMajorVersion === 7) {
pnpmExtraNpmrc = `strict-peer-dependencies=false`;
}
}
const injectInternalTemplateFiles = async () => {
const generator = new import_utils.BaseGenerator({
path: (0, import_path.join)(__dirname, "..", "templates", appTemplate),
target,
slient: true,
data: useDefaultData ? defaultData : {
version: version.includes("-canary.") ? version : `^${version}`,
npmClient,
registry,
author,
email,
withHusky,
extraNpmrc: isPnpm ? pnpmExtraNpmrc : "",
pluginName,
projectName,
appContainerName,
vueVersion,
isVue2: vueVersion === "2" /* vue2 */,
isVue3: vueVersion === "3" /* vue3 */
}
});
await generator.run();
};
if (!useExternalTemplate) {
await injectInternalTemplateFiles();
}
const context = {
inMonorepo,
target,
projectRoot
};
if (!withHusky) {
await removeHusky(context);
}
if (inMonorepo) {
await moveNpmrc(context);
}
if (shouldInitGit) {
await initGit(context);
} else {
import_utils.logger.info(`Skip Git init`);
}
const isPnpm8 = pnpmMajorVersion === 8;
if (!useDefaultData && args.install !== false) {
const installTask = taskLog(`Installing dependencies with ${npmClient}...`);
if (isPnpm8) {
await installWithPnpm8(target);
} else {
try {
await execute(npmClient, ["install"], {
cwd: target,
onData: (data) => {
installTask.text = data;
}
});
} catch (error) {
installTask.fail(`Failed to install dependencies with ${npmClient}`);
throw error;
}
}
installTask.success(`Installed dependencies with ${npmClient}`);
} else {
import_utils.logger.info(`Skip install deps`);
if (isPnpm8) {
import_utils.logger.warn(
import_utils.chalk.yellow(
`You current using pnpm v8, it will install minimal version of dependencies`
)
);
import_utils.logger.warn(
import_utils.chalk.green(
`Recommended that you run ${import_utils.chalk.bold.cyan(
"pnpm up -L"
)} to install latest version of dependencies`
)
);
}
}
if ((0, import_fs.existsSync)((0, import_path.join)(target, ".husky/pre-commit"))) {
if (process.platform !== "win32") {
import_utils.execa.execaCommandSync(`chmod +x ${(0, import_path.join)(target, ".husky/pre-commit")}`);
import_utils.logger.info(`Chmod ${(0, import_path.join)(target, ".husky/pre-commit")} successful`);
}
}
if ((0, import_fs.existsSync)((0, import_path.join)(target, ".husky/commit-msg"))) {
if (process.platform !== "win32") {
import_utils.execa.execaCommandSync(`chmod +x ${(0, import_path.join)(target, ".husky/commit-msg")}`);
import_utils.logger.info(`Chmod ${(0, import_path.join)(target, ".husky/commit-msg")} successful`);
}
}
box(
`
1: ${import_utils.chalk.bold(import_utils.chalk.cyan(`cd ${target}`))}
2: ${import_utils.chalk.bold(import_utils.chalk.cyan(devCommands[npmClient]))}
To close the dev server, hit ${import_utils.chalk.bold(import_utils.chalk.cyan("Ctrl+C"))}
`.trim(),
"Next Steps"
);
outro(import_utils.chalk.green(`Create success!`));
};
async function detectMonorepoRoot(opts) {
const { target } = opts;
const rootPkg = await import_utils.pkgUp.pkgUp({ cwd: (0, import_path.dirname)(target) });
if (!rootPkg) {
return null;
}
const rootDir = (0, import_path.dirname)(rootPkg);
if ((0, import_utils.tryPaths)([
(0, import_path.join)(rootDir, "lerna.json"),
(0, import_path.join)(rootDir, "pnpm-workspace.yaml")
])) {
return rootDir;
}
return null;
}
async function moveNpmrc(opts) {
const { target, projectRoot } = opts;
const sourceNpmrc = (0, import_path.join)(target, "./.npmrc");
const targetNpmrc = (0, import_path.join)(projectRoot, "./.npmrc");
if (!(0, import_fs.existsSync)(targetNpmrc)) {
await import_utils.fsExtra.copyFile(sourceNpmrc, targetNpmrc);
}
await import_utils.fsExtra.remove(sourceNpmrc);
}
async function initGit(opts) {
const { projectRoot } = opts;
const isGit = (0, import_fs.existsSync)((0, import_path.join)(projectRoot, ".git"));
if (isGit) return;
try {
await import_utils.execa.execa("git", ["init"], { cwd: projectRoot });
} catch {
import_utils.logger.error(`Initial the git repo failed`);
}
}
async function removeHusky(opts) {
const dir = (0, import_path.join)(opts.target, "./.husky");
if ((0, import_fs.existsSync)(dir)) {
await import_utils.fsExtra.remove(dir);
}
}
async function installWithPnpm8(cwd) {
await import_utils.execa.execa("pnpm", ["up", "-L"], { cwd, stdio: "inherit" });
}
async function getPnpmMajorVersion() {
try {
const { stdout } = await import_utils.execa.execa("pnpm", ["--version"]);
return parseInt(stdout.trim().split(".")[0], 10);
} catch (e) {
throw new Error("Please install pnpm first", { cause: e });
}
}
async function execute(cmd, args, options) {
const child = import_utils.execa.execa(cmd, args, {
stdio: "pipe",
cwd: options.cwd
});
return new Promise((resolve, reject) => {
var _a, _b;
(_a = child.stdout) == null ? void 0 : _a.on("data", (data) => {
options.onData(data);
});
(_b = child.stderr) == null ? void 0 : _b.on("data", (data) => {
options.onData(data);
});
child.on("close", (code) => {
resolve(code);
});
child.on("error", (error) => {
reject(error);
});
});
}