Supports numeric naming

This commit is contained in:
Tw93
2025-08-11 20:03:33 +08:00
parent 69d606653d
commit a0452a0789
2 changed files with 246 additions and 205 deletions

View File

@@ -37,8 +37,8 @@ export default async function handleOptions(
}
if (!isValidName(name, platform)) {
const LINUX_NAME_ERROR = `✕ Name should only include lowercase letters, numbers, and dashes (not leading dashes), and must contain at least one lowercase letter or number. Examples: com-123-xxx, 123pan, pan123, weread, we-read.`;
const DEFAULT_NAME_ERROR = `✕ Name should only include letters, numbers, dashes, and spaces (not leading dashes and spaces), and must contain at least one letter or number. Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read, We Read.`;
const LINUX_NAME_ERROR = `✕ Name should only include lowercase letters, numbers, and dashes (not leading dashes). Examples: com-123-xxx, 123pan, pan123, weread, we-read, 123.`;
const DEFAULT_NAME_ERROR = `✕ Name should only include letters, numbers, dashes, and spaces (not leading dashes and spaces). Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read, We Read, 123.`;
const errorMsg =
platform === 'linux' ? LINUX_NAME_ERROR : DEFAULT_NAME_ERROR;
logger.error(errorMsg);

115
dist/cli.js vendored
View File

@@ -61,6 +61,7 @@ var scripts = {
cli: "rollup -c rollup.config.js --watch",
"cli:dev": "cross-env NODE_ENV=development rollup -c rollup.config.js -w",
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
format: "npx prettier --write . --ignore-unknown && cd src-tauri && cargo fmt --verbose",
prepublishOnly: "npm run cli:build"
};
var type = "module";
@@ -274,7 +275,11 @@ let tauriConfig = {
// Generates an identifier based on the given URL.
function getIdentifier(url) {
const postFixHash = crypto.createHash('md5').update(url).digest('hex').substring(0, 6);
const postFixHash = crypto
.createHash('md5')
.update(url)
.digest('hex')
.substring(0, 6);
return `com.pake.${postFixHash}`;
}
async function promptText(message, initial) {
@@ -316,7 +321,7 @@ async function shellExec(command) {
try {
const { exitCode } = await execa(command, {
cwd: npmDirectory,
stdio: 'inherit'
stdio: 'inherit',
});
return exitCode;
}
@@ -327,19 +332,19 @@ async function shellExec(command) {
const logger = {
info(...msg) {
log.info(...msg.map(m => chalk.white(m)));
log.info(...msg.map((m) => chalk.white(m)));
},
debug(...msg) {
log.debug(...msg);
},
error(...msg) {
log.error(...msg.map(m => chalk.red(m)));
log.error(...msg.map((m) => chalk.red(m)));
},
warn(...msg) {
log.info(...msg.map(m => chalk.yellow(m)));
log.info(...msg.map((m) => chalk.yellow(m)));
},
success(...msg) {
log.info(...msg.map(m => chalk.green(m)));
log.info(...msg.map((m) => chalk.green(m)));
},
};
@@ -350,12 +355,12 @@ const ping = async (host) => {
const start = new Date();
// Prevent timeouts from affecting user experience.
const requestPromise = new Promise((resolve, reject) => {
const req = http.get(`http://${ip.address}`, res => {
const req = http.get(`http://${ip.address}`, (res) => {
const delay = new Date().getTime() - start.getTime();
res.resume();
resolve(delay);
});
req.on('error', err => {
req.on('error', (err) => {
reject(err);
});
});
@@ -417,14 +422,16 @@ function checkRustInstalled() {
}
async function combineFiles(files, output) {
const contents = files.map(file => {
const contents = files.map((file) => {
const fileContent = fs.readFileSync(file);
if (file.endsWith('.css')) {
return ("window.addEventListener('DOMContentLoaded', (_event) => { const css = `" +
fileContent +
"`; const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); });");
}
return "window.addEventListener('DOMContentLoaded', (_event) => { " + fileContent + ' });';
return ("window.addEventListener('DOMContentLoaded', (_event) => { " +
fileContent +
' });');
});
fs.writeFileSync(output, contents.join('\n'));
return files;
@@ -472,7 +479,7 @@ async function mergeConfig(url, options, tauriConf) {
// ignore it, because about_pake.html have be erased.
// const filesToCopyBack = ['cli.js', 'about_pake.html'];
const filesToCopyBack = ['cli.js'];
await Promise.all(filesToCopyBack.map(file => fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file))));
await Promise.all(filesToCopyBack.map((file) => fsExtra.copy(path.join(distBakDir, file), path.join(distDir, file))));
}
tauriConf.pake.windows[0].url = fileName;
tauriConf.pake.windows[0].url_type = 'local';
@@ -576,11 +583,11 @@ async function mergeConfig(url, options, tauriConf) {
const injectFilePath = path.join(npmDirectory, `src-tauri/src/inject/custom.js`);
// inject js or css files
if (inject?.length > 0) {
if (!inject.every(item => item.endsWith('.css') || item.endsWith('.js'))) {
if (!inject.every((item) => item.endsWith('.css') || item.endsWith('.js'))) {
logger.error('The injected file must be in either CSS or JS format.');
return;
}
const files = inject.map(filepath => (path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath)));
const files = inject.map((filepath) => path.isAbsolute(filepath) ? filepath : path.join(process.cwd(), filepath));
tauriConf.pake.inject = files;
await combineFiles(files, injectFilePath);
}
@@ -708,7 +715,9 @@ class MacBuilder extends BaseBuilder {
return `${name}_${tauriConfig.version}_${arch}`;
}
getBuildCommand() {
return this.options.multiArch ? 'npm run build:mac' : super.getBuildCommand();
return this.options.multiArch
? 'npm run build:mac'
: super.getBuildCommand();
}
getBasePath() {
return this.options.multiArch
@@ -798,7 +807,7 @@ const DEFAULT_PAKE_OPTIONS = {
targets: 'deb',
useLocalFile: false,
systemTrayIcon: '',
proxyUrl: "",
proxyUrl: '',
debug: false,
inject: [],
installerLanguage: 'en-US',
@@ -806,7 +815,9 @@ const DEFAULT_PAKE_OPTIONS = {
};
async function checkUpdateTips() {
updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({ isGlobal: true });
updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 }).notify({
isGlobal: true,
});
}
async function handleIcon(options) {
@@ -831,7 +842,9 @@ async function handleIcon(options) {
async function downloadIcon(iconUrl) {
const spinner = getSpinner('Downloading icon...');
try {
const iconResponse = await axios.get(iconUrl, { responseType: 'arraybuffer' });
const iconResponse = await axios.get(iconUrl, {
responseType: 'arraybuffer',
});
const iconData = await iconResponse.data;
if (!iconData) {
return null;
@@ -926,8 +939,8 @@ async function handleOptions(options, url) {
name = namePrompt || defaultName;
}
if (!isValidName(name, platform)) {
const LINUX_NAME_ERROR = `✕ Name should only include lowercase letters, numbers, and dashes (not leading dashes), and must contain at least one lowercase letter or number. Examples: com-123-xxx, 123pan, pan123, weread, we-read.`;
const DEFAULT_NAME_ERROR = `✕ Name should only include letters, numbers, dashes, and spaces (not leading dashes and spaces), and must contain at least one letter or number. Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read, We Read.`;
const LINUX_NAME_ERROR = `✕ Name should only include lowercase letters, numbers, and dashes (not leading dashes). Examples: com-123-xxx, 123pan, pan123, weread, we-read, 123.`;
const DEFAULT_NAME_ERROR = `✕ Name should only include letters, numbers, dashes, and spaces (not leading dashes and spaces). Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead, we-read, We Read, 123.`;
const errorMsg = platform === 'linux' ? LINUX_NAME_ERROR : DEFAULT_NAME_ERROR;
logger.error(errorMsg);
if (isActions) {
@@ -974,7 +987,10 @@ ${green('| |_) / _` | |/ / _ \\')}
${green('| __/ (_| | < __/')} ${yellow('https://github.com/tw93/pake')}
${green('|_| \\__,_|_|\\_\\___| can turn any webpage into a desktop app with Rust.')}
`;
program.addHelpText('beforeAll', logo).usage(`[url] [options]`).showHelpAfterError();
program
.addHelpText('beforeAll', logo)
.usage(`[url] [options]`)
.showHelpAfterError();
program
.argument('[url]', 'The web URL you want to package', validateUrlInput)
// Refer to https://github.com/tj/commander.js#custom-option-processing, turn string array into a string connected with custom connectors.
@@ -997,33 +1013,58 @@ program
if (!val)
return DEFAULT_PAKE_OPTIONS.inject;
// Split by comma and trim whitespace, filter out empty strings
const files = val.split(',')
.map(item => item.trim())
.filter(item => item.length > 0);
const files = val
.split(',')
.map((item) => item.trim())
.filter((item) => item.length > 0);
// If previous values exist (from multiple --inject options), merge them
return previous ? [...previous, ...files] : files;
}, DEFAULT_PAKE_OPTIONS.inject)
.option('--debug', 'Debug build and more output', DEFAULT_PAKE_OPTIONS.debug)
.addOption(new Option('--proxy-url <url>', 'Proxy URL for all network requests').default(DEFAULT_PAKE_OPTIONS.proxyUrl).hideHelp())
.addOption(new Option('--user-agent <string>', 'Custom user agent').default(DEFAULT_PAKE_OPTIONS.userAgent).hideHelp())
.addOption(new Option('--targets <string>', 'For Linux, option "deb" or "appimage"').default(DEFAULT_PAKE_OPTIONS.targets).hideHelp())
.addOption(new Option('--app-version <string>', 'App version, the same as package.json version').default(DEFAULT_PAKE_OPTIONS.appVersion).hideHelp())
.addOption(new Option('--always-on-top', 'Always on the top level').default(DEFAULT_PAKE_OPTIONS.alwaysOnTop).hideHelp())
.addOption(new Option('--dark-mode', 'Force Mac app to use dark mode').default(DEFAULT_PAKE_OPTIONS.darkMode).hideHelp())
.addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts').default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts).hideHelp())
.addOption(new Option('--activation-shortcut <string>', 'Shortcut key to active App').default(DEFAULT_PAKE_OPTIONS.activationShortcut).hideHelp())
.addOption(new Option('--show-system-tray', 'Show system tray in app').default(DEFAULT_PAKE_OPTIONS.showSystemTray).hideHelp())
.addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon').default(DEFAULT_PAKE_OPTIONS.systemTrayIcon).hideHelp())
.addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting').default(DEFAULT_PAKE_OPTIONS.hideOnClose).hideHelp())
.addOption(new Option('--installer-language <string>', 'Installer language').default(DEFAULT_PAKE_OPTIONS.installerLanguage).hideHelp())
.addOption(new Option('--proxy-url <url>', 'Proxy URL for all network requests')
.default(DEFAULT_PAKE_OPTIONS.proxyUrl)
.hideHelp())
.addOption(new Option('--user-agent <string>', 'Custom user agent')
.default(DEFAULT_PAKE_OPTIONS.userAgent)
.hideHelp())
.addOption(new Option('--targets <string>', 'For Linux, option "deb" or "appimage"')
.default(DEFAULT_PAKE_OPTIONS.targets)
.hideHelp())
.addOption(new Option('--app-version <string>', 'App version, the same as package.json version')
.default(DEFAULT_PAKE_OPTIONS.appVersion)
.hideHelp())
.addOption(new Option('--always-on-top', 'Always on the top level')
.default(DEFAULT_PAKE_OPTIONS.alwaysOnTop)
.hideHelp())
.addOption(new Option('--dark-mode', 'Force Mac app to use dark mode')
.default(DEFAULT_PAKE_OPTIONS.darkMode)
.hideHelp())
.addOption(new Option('--disabled-web-shortcuts', 'Disabled webPage shortcuts')
.default(DEFAULT_PAKE_OPTIONS.disabledWebShortcuts)
.hideHelp())
.addOption(new Option('--activation-shortcut <string>', 'Shortcut key to active App')
.default(DEFAULT_PAKE_OPTIONS.activationShortcut)
.hideHelp())
.addOption(new Option('--show-system-tray', 'Show system tray in app')
.default(DEFAULT_PAKE_OPTIONS.showSystemTray)
.hideHelp())
.addOption(new Option('--system-tray-icon <string>', 'Custom system tray icon')
.default(DEFAULT_PAKE_OPTIONS.systemTrayIcon)
.hideHelp())
.addOption(new Option('--hide-on-close', 'Hide window on close instead of exiting')
.default(DEFAULT_PAKE_OPTIONS.hideOnClose)
.hideHelp())
.addOption(new Option('--installer-language <string>', 'Installer language')
.default(DEFAULT_PAKE_OPTIONS.installerLanguage)
.hideHelp())
.version(packageJson.version, '-v, --version', 'Output the current version')
.action(async (url, options) => {
await checkUpdateTips();
if (!url) {
program.outputHelp(str => {
program.outputHelp((str) => {
return str
.split('\n')
.filter(line => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
.filter((line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
.join('\n');
});
process.exit(0);