Socket
Socket
Sign inDemoInstall

pake-cli

Package Overview
Dependencies
Maintainers
3
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pake-cli - npm Package Compare versions

Comparing version 2.1.1 to 2.1.2

871

dist/cli.js

@@ -1,16 +0,11 @@

import ora from 'ora';
import chalk from 'chalk';
import { InvalidArgumentError, program } from 'commander';
import log from 'loglevel';
import { InvalidArgumentError, program } from 'commander';
import path from 'path';
import fsExtra from 'fs-extra';
import path from 'path';
import axios from 'axios';
import { dir } from 'tmp-promise';
import { fileTypeFromBuffer } from 'file-type';
import chalk from 'chalk';
import { fileURLToPath } from 'url';
import psl from 'psl';
import isUrl from 'is-url';
import crypto from 'crypto';
import prompts from 'prompts';
import shelljs from 'shelljs';
import crypto from 'crypto';
import ora from 'ora';
import { fileURLToPath } from 'url';
import dns from 'dns';

@@ -20,143 +15,110 @@ import http from 'http';

import updateNotifier from 'update-notifier';
import axios from 'axios';
import { dir } from 'tmp-promise';
import { fileTypeFromBuffer } from 'file-type';
import psl from 'psl';
import isUrl from 'is-url';
import fs from 'fs';
const logger = {
info(...msg) {
log.info(...msg.map((m) => chalk.blue.bold(m)));
},
debug(...msg) {
log.debug(...msg);
},
error(...msg) {
log.error(...msg.map((m) => chalk.red.bold(m)));
},
warn(...msg) {
log.info(...msg.map((m) => chalk.yellow.bold(m)));
},
success(...msg) {
log.info(...msg.map((m) => chalk.green.bold(m)));
}
var name = "pake-cli";
var version = "2.1.2";
var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with Rust. ๐Ÿคฑ๐Ÿป ๅพˆ็ฎ€ๅ•็š„็”จ Rust ๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆๅพˆๅฐ็š„ๆกŒ้ข Appใ€‚";
var engines = {
node: ">=16.0.0"
};
var bin = {
pake: "./cli.js"
};
var repository = {
type: "git",
url: "https://github.com/tw93/pake.git"
};
var author = {
name: "Tw93",
email: "tw93@qq.com"
};
var keywords = [
"pake",
"pake-cli",
"rust",
"tauri",
"no-electron",
"productivity"
];
var files = [
"dist",
"src-tauri",
"cli.js"
];
var scripts = {
start: "npm run dev",
dev: "npm run tauri dev",
build: "npm run tauri build --release",
"build:mac": "npm run tauri build -- --target universal-apple-darwin",
"build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh",
"build:all-windows": "pwsh ./script/build.ps1",
analyze: "cd src-tauri && cargo bloat --release --crates",
tauri: "tauri",
cli: "rollup -c rollup.config.js --watch",
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
prepublishOnly: "npm run cli:build"
};
var type = "module";
var exports = "./dist/pake.js";
var license = "MIT";
var dependencies = {
"@tauri-apps/api": "^1.4.0",
"@tauri-apps/cli": "^1.4.0",
axios: "^1.1.3",
chalk: "^5.1.2",
commander: "^11.0.0",
"file-type": "^18.0.0",
"fs-extra": "^11.1.0",
"is-url": "^1.2.4",
loglevel: "^1.8.1",
ora: "^6.1.2",
prompts: "^2.4.2",
psl: "^1.9.0",
shelljs: "^0.8.5",
"tmp-promise": "^3.0.3",
"update-notifier": "^6.0.2"
};
var devDependencies = {
"@rollup/plugin-alias": "^4.0.2",
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-json": "^5.0.2",
"@rollup/plugin-terser": "^0.1.0",
"@types/fs-extra": "^9.0.13",
"@types/is-url": "^1.2.30",
"@types/page-icon": "^0.3.4",
"@types/prompts": "^2.4.1",
"@types/psl": "^1.1.0",
"@types/shelljs": "^0.8.11",
"@types/tmp": "^0.2.3",
"@types/update-notifier": "^6.0.1",
"app-root-path": "^3.1.0",
"cross-env": "^7.0.3",
rollup: "^3.3.0",
"rollup-plugin-typescript2": "^0.34.1",
tslib: "^2.4.1",
typescript: "^4.9.3"
};
var packageJson = {
name: name,
version: version,
description: description,
engines: engines,
bin: bin,
repository: repository,
author: author,
keywords: keywords,
files: files,
scripts: scripts,
type: type,
exports: exports,
license: license,
dependencies: dependencies,
devDependencies: devDependencies
};
// Convert the current module URL to a file path
const currentModulePath = fileURLToPath(import.meta.url);
// Resolve the parent directory of the current module
const npmDirectory = path.join(path.dirname(currentModulePath), '..');
const { platform: platform$2 } = process;
const IS_MAC = platform$2 === 'darwin';
const IS_WIN = platform$2 === 'win32';
const IS_LINUX = platform$2 === 'linux';
async function handleIcon(options) {
if (options.icon) {
if (options.icon.startsWith('http')) {
return downloadIcon(options.icon);
}
else {
return path.resolve(options.icon);
}
}
else {
logger.info('No app icon provided, default icon used. Use --icon option to assign an icon.');
const iconPath = IS_WIN ? 'src-tauri/png/icon_256.ico' : IS_LINUX ? 'src-tauri/png/icon_512.png' : 'src-tauri/icons/icon.icns';
return path.join(npmDirectory, iconPath);
}
}
async function downloadIcon(iconUrl) {
try {
const iconResponse = await axios.get(iconUrl, { responseType: 'arraybuffer' });
const iconData = await iconResponse.data;
if (!iconData) {
return null;
}
const fileDetails = await fileTypeFromBuffer(iconData);
if (!fileDetails) {
return null;
}
const { path: tempPath } = await dir();
const iconPath = `${tempPath}/icon.${fileDetails.ext}`;
await fsExtra.outputFile(iconPath, iconData);
return iconPath;
}
catch (error) {
if (error.response && error.response.status === 404) {
return null;
}
throw error;
}
}
// Extracts the domain from a given URL.
function getDomain(inputUrl) {
try {
const url = new URL(inputUrl);
// Use PSL to parse domain names.
const parsed = psl.parse(url.hostname);
// If domain is available, split it and return the SLD.
if ("domain" in parsed && parsed.domain) {
return parsed.domain.split('.')[0];
}
else {
return null;
}
}
catch (error) {
return null;
}
}
// Appends 'https://' protocol to the URL if not present.
function appendProtocol(inputUrl) {
try {
new URL(inputUrl);
return inputUrl;
}
catch {
return `https://${inputUrl}`;
}
}
// Normalizes the URL by ensuring it has a protocol and is valid.
function normalizeUrl(urlToNormalize) {
const urlWithProtocol = appendProtocol(urlToNormalize);
if (isUrl(urlWithProtocol)) {
return urlWithProtocol;
}
else {
throw new Error(`Your url "${urlWithProtocol}" is invalid`);
}
}
// Generates an identifier based on the given URL.
function getIdentifier(url) {
const postFixHash = crypto.createHash('md5')
.update(url)
.digest('hex')
.substring(0, 6);
return `pake-${postFixHash}`;
}
async function promptText(message, initial) {
const response = await prompts({
type: 'text',
name: 'content',
message,
initial,
});
return response.content;
}
async function handleOptions(options, url) {
const appOptions = {
...options,
identifier: getIdentifier(url),
};
let urlExists = await fsExtra.pathExists(url);
if (!appOptions.name) {
const defaultName = urlExists ? "" : getDomain(url);
const promptMessage = 'Enter your application name';
appOptions.name = await promptText(promptMessage, defaultName);
}
appOptions.icon = await handleIcon(appOptions);
return appOptions;
}
var windows = [

@@ -349,5 +311,5 @@ {

};
const { platform: platform$1 } = process;
const { platform: platform$2 } = process;
// @ts-ignore
const platformConfig = platformConfigs[platform$1];
const platformConfig = platformConfigs[platform$2];
let tauriConfig = {

@@ -363,2 +325,48 @@ tauri: {

// Generates an identifier based on the given URL.
function getIdentifier(url) {
const postFixHash = crypto.createHash('md5')
.update(url)
.digest('hex')
.substring(0, 6);
return `pake-${postFixHash}`;
}
async function promptText(message, initial) {
const response = await prompts({
type: 'text',
name: 'content',
message,
initial,
});
return response.content;
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function getSpinner(text) {
const loadingType = {
"interval": 80,
"frames": [
"โœถ",
"โœต",
"โœธ",
"โœน",
"โœบ",
"โœน",
"โœท",
]
};
return ora({ text: `${text}\n`, spinner: loadingType }).start();
}
const { platform: platform$1 } = process;
const IS_MAC = platform$1 === 'darwin';
const IS_WIN = platform$1 === 'win32';
const IS_LINUX = platform$1 === 'linux';
// Convert the current module URL to a file path
const currentModulePath = fileURLToPath(import.meta.url);
// Resolve the parent directory of the current module
const npmDirectory = path.join(path.dirname(currentModulePath), '..');
function shellExec(command) {

@@ -377,2 +385,20 @@ return new Promise((resolve, reject) => {

const logger = {
info(...msg) {
log.info(...msg.map((m) => chalk.blue.bold(m)));
},
debug(...msg) {
log.debug(...msg);
},
error(...msg) {
log.error(...msg.map((m) => chalk.red.bold(m)));
},
warn(...msg) {
log.info(...msg.map((m) => chalk.yellow.bold(m)));
},
success(...msg) {
log.info(...msg.map((m) => chalk.green.bold(m)));
}
};
const resolve = promisify(dns.resolve);

@@ -397,3 +423,3 @@ const ping = async (host) => {

reject(new Error('Request timed out after 3 seconds'));
}, 3000);
}, 1000);
});

@@ -409,3 +435,3 @@ return Promise.race([requestPromise, timeoutPromise]);

logger.debug(`${domain} can't be parse!`);
return false;
return true;
}

@@ -417,7 +443,7 @@ }

logger.debug(`${domain} latency is ${delay} ms`);
return delay > 500;
return delay > 1000;
}
catch (error) {
logger.debug(`ping ${domain} failed!`);
return false;
return true;
}

@@ -432,11 +458,10 @@ }

const rustInstallScriptForWindows = 'winget install --id Rustlang.Rustup';
const spinner = ora('Downloading Rust').start();
const spinner = getSpinner('Downloading Rust...');
try {
await shellExec(IS_WIN ? rustInstallScriptForWindows : rustInstallScriptForMac);
spinner.succeed();
spinner.succeed('Rust installed successfully.');
}
catch (error) {
console.error('Error installing Rust:', error.message);
spinner.fail();
//@ts-ignore
spinner.fail('Rust installation failed.');
process.exit(1);

@@ -449,44 +474,2 @@ }

class BaseBuilder {
async prepare() {
// Windows and Linux need to install necessary build tools.
if (!IS_MAC) {
logger.info('Install Rust and required build tools to build the app.');
logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing.');
}
if (checkRustInstalled()) {
return;
}
const res = await prompts({
type: 'confirm',
message: 'Rust not detected. Install now?',
name: 'value',
});
if (res.value) {
await installRust();
}
else {
logger.error('Error: Rust required to package your webapp!');
process.exit(2);
}
}
async runBuildCommand(directory, command) {
const spinner = ora('Building...').start();
setTimeout(() => spinner.succeed(), 5000);
const isChina = await isChinaDomain("www.npmjs.com");
if (isChina) {
logger.info("Located in China, using npm/Rust CN mirror.");
const rustProjectDir = path.join(directory, 'src-tauri', ".cargo");
await fsExtra.ensureDir(rustProjectDir);
const projectCnConf = path.join(directory, "src-tauri", "rust_proxy.toml");
const projectConf = path.join(rustProjectDir, "config");
await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${directory}" && npm install --registry=https://registry.npmmirror.com && ${command}`);
}
else {
await shellExec(`cd "${directory}" && npm install && ${command}`);
}
}
}
async function mergeConfig(url, options, tauriConf) {

@@ -504,23 +487,7 @@ const { width, height, fullscreen, transparent, resizable, userAgent, showMenu, showSystemTray, systemTrayIcon, iterCopyFile, identifier, name, } = options;

Object.assign(tauriConf.pake.windows[0], { url, ...tauriConfWindowOptions });
// Determine whether the package name is valid.
// for Linux, package name must be a-z, 0-9 or "-", not allow to A-Z and other
const platformRegexMapping = {
linux: /[0-9]*[a-z]+[0-9]*\-?[0-9]*[a-z]*[0-9]*\-?[0-9]*[a-z]*[0-9]*/,
default: /([0-9]*[a-zA-Z]+[0-9]*)+/,
};
const reg = platformRegexMapping[platform] || platformRegexMapping.default;
const nameCheck = reg.test(name) && reg.exec(name)[0].length === name.length;
if (!nameCheck) {
const errorMsg = platform === 'linux'
? `Package name is invalid. It should only include lowercase letters, numbers, and dashes, and must contain at least one lowercase letter. Examples: com-123-xxx, 123pan, pan123, weread, we-read.`
: `Package name is invalid. It should only include letters and numbers, and must contain at least one letter. Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead.`;
logger.error(errorMsg);
process.exit();
}
tauriConf.package.productName = name;
tauriConf.tauri.bundle.identifier = identifier;
// Judge the type of URL, whether it is a file or a website.
// If it is a file and the recursive copy function is enabled then the file and all files in its parent folder need to be copied to the "src" directory. Otherwise, only the single file will be copied.
const urlExists = await fsExtra.pathExists(url);
if (urlExists) {
//Judge the type of URL, whether it is a file or a website.
const pathExists = await fsExtra.pathExists(url);
if (pathExists) {
logger.warn('Your input might be a local file.');

@@ -661,46 +628,118 @@ tauriConf.pake.windows[0].url_type = 'local';

class MacBuilder extends BaseBuilder {
async build(url, options) {
const { name } = options;
await mergeConfig(url, options, tauriConfig);
let dmgName;
if (options.multiArch) {
await this.runBuildCommand(npmDirectory, 'npm run build:mac');
dmgName = `${name}_${tauriConfig.package.version}_universal.dmg`;
class BaseBuilder {
constructor(options) {
this.options = options;
}
async prepare() {
if (!IS_MAC) {
logger.info('The first use requires installing system dependencies.');
logger.info('See more in https://tauri.app/v1/guides/getting-started/prerequisites#installing.');
}
if (!checkRustInstalled()) {
const res = await prompts({
type: 'confirm',
message: 'Rust not detected. Install now?',
name: 'value',
});
if (res.value) {
await installRust();
}
else {
logger.error('Error: Rust required to package your webapp!');
process.exit(0);
}
}
const isChina = await isChinaDomain("www.npmjs.com");
const spinner = getSpinner('Installing package...');
if (isChina) {
logger.info("Located in China, using npm/rsProxy CN mirror.");
const rustProjectDir = path.join(npmDirectory, 'src-tauri', ".cargo");
await fsExtra.ensureDir(rustProjectDir);
const projectCnConf = path.join(npmDirectory, "src-tauri", "rust_proxy.toml");
const projectConf = path.join(rustProjectDir, "config");
await fsExtra.copy(projectCnConf, projectConf);
await shellExec(`cd "${npmDirectory}" && npm install --registry=https://registry.npmmirror.com`);
}
else {
await this.runBuildCommand(npmDirectory, 'npm run build');
let arch = process.arch === "arm64" ? "aarch64" : process.arch;
dmgName = `${name}_${tauriConfig.package.version}_${arch}.dmg`;
await shellExec(`cd "${npmDirectory}" && npm install`);
}
const appPath = this.getBuildAppPath(npmDirectory, dmgName, options.multiArch);
const distPath = path.resolve(`${name}.dmg`);
spinner.succeed('Package installed.');
}
async buildAndCopy(url) {
const { name } = this.options;
await mergeConfig(url, this.options, tauriConfig);
await this.runBuildCommand();
const fileName = this.getFileName();
const appPath = this.getBuildAppPath(npmDirectory, fileName);
const distPath = path.resolve(`${name}.${this.getExtension()}`);
await fsExtra.copy(appPath, distPath);
await fsExtra.remove(appPath);
logger.success('Build success!');
logger.success('App installer located in', distPath);
logger.success('โœ” Build success!');
logger.success('โœ” App installer located in', distPath);
}
getBuildAppPath(npmDirectory, dmgName, multiArch) {
const dmgPath = multiArch ? 'src-tauri/target/universal-apple-darwin/release/bundle/dmg' : 'src-tauri/target/release/bundle/dmg';
return path.join(npmDirectory, dmgPath, dmgName);
getArch() {
return process.arch === "x64" ? "amd64" : process.arch;
}
getBuildCommand() {
return "npm run build";
}
runBuildCommand() {
const spinner = getSpinner('Building app...');
setTimeout(() => spinner.stop(), 3000);
return shellExec(`cd ${npmDirectory} && ${this.getBuildCommand()}`);
}
getBasePath() {
return 'src-tauri/target/release/bundle/';
}
getBuildAppPath(npmDirectory, fileName) {
return path.join(npmDirectory, this.getBasePath(), this.getExtension().toLowerCase(), `${fileName}.${this.getExtension()}`);
}
}
class MacBuilder extends BaseBuilder {
constructor(options) {
super(options);
}
async build(url) {
await this.buildAndCopy(url);
}
getFileName() {
const { name } = this.options;
let arch;
if (this.options.multiArch) {
arch = 'universal';
}
else {
arch = process.arch === "arm64" ? "aarch64" : process.arch;
}
return `${name}_${tauriConfig.package.version}_${arch}`;
}
getExtension() {
return "dmg";
}
getBuildCommand() {
return this.options.multiArch ? 'npm run build:mac' : super.getBuildCommand();
}
getBasePath() {
return this.options.multiArch
? 'src-tauri/target/universal-apple-darwin/release/bundle'
: super.getBasePath();
}
}
class WinBuilder extends BaseBuilder {
async build(url, options) {
const { name } = options;
await mergeConfig(url, options, tauriConfig);
await this.runBuildCommand(npmDirectory, 'npm run build');
constructor(options) {
super(options);
}
async build(url) {
await this.buildAndCopy(url);
}
getFileName() {
const { name } = this.options;
const arch = this.getArch();
const language = tauriConfig.tauri.bundle.windows.wix.language[0];
const arch = process.arch;
const msiName = `${name}_${tauriConfig.package.version}_${arch}_${language}.msi`;
const appPath = this.getBuildAppPath(npmDirectory, msiName);
const distPath = path.resolve(`${name}.msi`);
await fsExtra.copy(appPath, distPath);
await fsExtra.remove(appPath);
logger.success('Build success!');
logger.success('App installer located in', distPath);
return `${name}_${tauriConfig.package.version}_${arch}_${language}`;
}
getBuildAppPath(npmDirectory, msiName) {
return path.join(npmDirectory, 'src-tauri/target/release/bundle/msi', msiName);
getExtension() {
return "msi";
}

@@ -710,29 +749,24 @@ }

class LinuxBuilder extends BaseBuilder {
async build(url, options) {
const { name } = options;
await mergeConfig(url, options, tauriConfig);
await this.runBuildCommand(npmDirectory, 'npm run build');
const arch = process.arch === "x64" ? "amd64" : process.arch;
if (options.targets === "deb" || options.targets === "all") {
const debName = `${name}_${tauriConfig.package.version}_${arch}.deb`;
const appPath = this.getBuildAppPath(npmDirectory, "deb", debName);
const distPath = path.resolve(`${name}.deb`);
await fsExtra.copy(appPath, distPath);
await fsExtra.remove(appPath);
logger.success('Build Deb success!');
logger.success('Deb app installer located in', distPath);
constructor(options) {
super(options);
}
async build(url) {
const targetTypes = ['deb', 'appimage'];
for (const type of targetTypes) {
if (this.options.targets === type || this.options.targets === "all") {
await this.buildAndCopy(url);
}
}
if (options.targets === "appimage" || options.targets === "all") {
const appImageName = `${name}_${tauriConfig.package.version}_${arch}.AppImage`;
const appImagePath = this.getBuildAppPath(npmDirectory, "appimage", appImageName);
const distAppPath = path.resolve(`${name}.AppImage`);
await fsExtra.copy(appImagePath, distAppPath);
await fsExtra.remove(appImagePath);
logger.success('Build AppImage success!');
logger.success('AppImage installer located in', distAppPath);
}
getFileName() {
const { name } = this.options;
const arch = this.getArch();
return `${name}_${tauriConfig.package.version}_${arch}`;
}
getExtension() {
if (this.options.targets === 'appimage') {
return 'AppImage';
}
return this.options.targets;
}
getBuildAppPath(npmDirectory, packageType, packageName) {
return path.join(npmDirectory, 'src-tauri/target/release/bundle/', packageType, packageName);
}
}

@@ -747,3 +781,3 @@

class BuilderProvider {
static create() {
static create(options) {
const Builder = buildersMap[platform];

@@ -753,106 +787,22 @@ if (!Builder) {

}
return new Builder();
return new Builder(options);
}
}
var name = "pake-cli";
var version = "2.1.1";
var description = "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with Rust. ๐Ÿคฑ๐Ÿป ๅพˆ็ฎ€ๅ•็š„็”จ Rust ๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆๅพˆๅฐ็š„ๆกŒ้ข Appใ€‚";
var engines = {
node: ">=16.0.0"
const DEFAULT_PAKE_OPTIONS = {
icon: '',
height: 780,
width: 1200,
fullscreen: false,
resizable: true,
transparent: false,
userAgent: '',
showMenu: false,
showSystemTray: false,
multiArch: false,
targets: 'deb',
iterCopyFile: false,
systemTrayIcon: '',
debug: false,
};
var bin = {
pake: "./cli.js"
};
var repository = {
type: "git",
url: "https://github.com/tw93/pake.git"
};
var author = {
name: "Tw93",
email: "tw93@qq.com"
};
var keywords = [
"pake",
"pake-cli",
"rust",
"tauri",
"no-electron",
"productivity"
];
var files = [
"dist",
"src-tauri",
"cli.js"
];
var scripts = {
start: "npm run dev",
dev: "npm run tauri dev",
build: "npm run tauri build --release",
"build:mac": "npm run tauri build -- --target universal-apple-darwin",
"build:all-unix": "chmod +x ./script/build.sh && ./script/build.sh",
"build:all-windows": "pwsh ./script/build.ps1",
analyze: "cd src-tauri && cargo bloat --release --crates",
tauri: "tauri",
cli: "rollup -c rollup.config.js --watch",
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
prepublishOnly: "npm run cli:build"
};
var type = "module";
var exports = "./dist/pake.js";
var license = "MIT";
var dependencies = {
"@tauri-apps/api": "^1.4.0",
"@tauri-apps/cli": "^1.4.0",
axios: "^1.1.3",
chalk: "^5.1.2",
commander: "^11.0.0",
"file-type": "^18.0.0",
"fs-extra": "^11.1.0",
"is-url": "^1.2.4",
loglevel: "^1.8.1",
ora: "^6.1.2",
prompts: "^2.4.2",
psl: "^1.9.0",
shelljs: "^0.8.5",
"tmp-promise": "^3.0.3",
"update-notifier": "^6.0.2"
};
var devDependencies = {
"@rollup/plugin-alias": "^4.0.2",
"@rollup/plugin-commonjs": "^23.0.2",
"@rollup/plugin-json": "^5.0.2",
"@rollup/plugin-terser": "^0.1.0",
"@types/fs-extra": "^9.0.13",
"@types/is-url": "^1.2.30",
"@types/page-icon": "^0.3.4",
"@types/prompts": "^2.4.1",
"@types/psl": "^1.1.0",
"@types/shelljs": "^0.8.11",
"@types/tmp": "^0.2.3",
"@types/update-notifier": "^6.0.1",
"app-root-path": "^3.1.0",
"cross-env": "^7.0.3",
rollup: "^3.3.0",
"rollup-plugin-typescript2": "^0.34.1",
tslib: "^2.4.1",
typescript: "^4.9.3"
};
var packageJson = {
name: name,
version: version,
description: description,
engines: engines,
bin: bin,
repository: repository,
author: author,
keywords: keywords,
files: files,
scripts: scripts,
type: type,
exports: exports,
license: license,
dependencies: dependencies,
devDependencies: devDependencies
};

@@ -863,2 +813,128 @@ async function checkUpdateTips() {

async function handleIcon(options) {
if (options.icon) {
if (options.icon.startsWith('http')) {
return downloadIcon(options.icon);
}
else {
return path.resolve(options.icon);
}
}
else {
logger.info('No app icon provided, default icon used. Use --icon option to assign an icon.');
const iconPath = IS_WIN ? 'src-tauri/png/icon_256.ico' : IS_LINUX ? 'src-tauri/png/icon_512.png' : 'src-tauri/icons/icon.icns';
return path.join(npmDirectory, iconPath);
}
}
async function downloadIcon(iconUrl) {
const spinner = getSpinner('Downloading icon...');
try {
const iconResponse = await axios.get(iconUrl, { responseType: 'arraybuffer' });
const iconData = await iconResponse.data;
if (!iconData) {
return null;
}
const fileDetails = await fileTypeFromBuffer(iconData);
if (!fileDetails) {
return null;
}
const { path: tempPath } = await dir();
const iconPath = `${tempPath}/icon.${fileDetails.ext}`;
await fsExtra.outputFile(iconPath, iconData);
spinner.succeed('Icon downloaded successfully.');
return iconPath;
}
catch (error) {
spinner.fail('Icon download failed.');
if (error.response && error.response.status === 404) {
return null;
}
throw error;
}
}
// Extracts the domain from a given URL.
function getDomain(inputUrl) {
try {
const url = new URL(inputUrl);
// Use PSL to parse domain names.
const parsed = psl.parse(url.hostname);
// If domain is available, split it and return the SLD.
if ("domain" in parsed && parsed.domain) {
return parsed.domain.split('.')[0];
}
else {
return null;
}
}
catch (error) {
return null;
}
}
// Appends 'https://' protocol to the URL if not present.
function appendProtocol(inputUrl) {
try {
new URL(inputUrl);
return inputUrl;
}
catch {
return `https://${inputUrl}`;
}
}
// Normalizes the URL by ensuring it has a protocol and is valid.
function normalizeUrl(urlToNormalize) {
const urlWithProtocol = appendProtocol(urlToNormalize);
if (isUrl(urlWithProtocol)) {
return urlWithProtocol;
}
else {
throw new Error(`Your url "${urlWithProtocol}" is invalid`);
}
}
function resolveAppName(name, platform) {
const domain = getDomain(name) || 'pake';
return platform !== 'linux' ? capitalizeFirstLetter(domain) : domain;
}
function isValidName(name, platform) {
const platformRegexMapping = {
linux: /^[a-z0-9]+(-[a-z0-9]+)*$/,
default: /^[a-zA-Z0-9]+$/,
};
const reg = platformRegexMapping[platform] || platformRegexMapping.default;
return !!name && reg.test(name);
}
async function handleOptions(options, url) {
const { platform } = process;
const isActions = process.env.GITHUB_ACTIONS;
let name = options.name;
const pathExists = await fsExtra.pathExists(url);
if (!options.name) {
const defaultName = pathExists ? "" : resolveAppName(url, platform);
const promptMessage = 'Enter your application name';
const namePrompt = await promptText(promptMessage, defaultName);
name = namePrompt || defaultName;
}
if (!isValidName(name, platform)) {
const LINUX_NAME_ERROR = `Package name is invalid. It should only include lowercase letters, numbers, and dashes, and must contain at least one lowercase letter. Examples: com-123-xxx, 123pan, pan123, weread, we-read.`;
const DEFAULT_NAME_ERROR = `Package name is invalid. It should only include letters and numbers, and must contain at least one letter. Examples: 123pan, 123Pan, Pan123, weread, WeRead, WERead.`;
const errorMsg = platform === 'linux' ? LINUX_NAME_ERROR : DEFAULT_NAME_ERROR;
logger.error(errorMsg);
if (isActions) {
name = resolveAppName(url, platform);
logger.warn(`Inside github actions, use the default name: ${name}`);
}
else {
process.exit(1);
}
}
const appOptions = {
...options,
name,
identifier: getIdentifier(url),
};
appOptions.icon = await handleIcon(appOptions);
return appOptions;
}
function validateNumberInput(value) {

@@ -884,22 +960,5 @@ const parsedValue = Number(value);

const DEFAULT_PAKE_OPTIONS = {
icon: '',
height: 780,
width: 1200,
fullscreen: false,
resizable: true,
transparent: false,
userAgent: '',
showMenu: false,
showSystemTray: false,
multiArch: false,
targets: 'deb',
iterCopyFile: false,
systemTrayIcon: '',
debug: false,
};
program
.version(packageJson.version)
.description('A CLI that can turn any webpage into a desktop app with Rust.')
.description(chalk.green('Pake can turn any webpage into a desktop app with Rust.'))
.usage('[url] [options]')
.showHelpAfterError();

@@ -912,3 +971,2 @@ program

.option('--width <number>', 'Window width', validateNumberInput, DEFAULT_PAKE_OPTIONS.width)
.option('--no-resizable', 'Whether the window can be resizable', DEFAULT_PAKE_OPTIONS.resizable)
.option('--fullscreen', 'Start the packaged app in full screen', DEFAULT_PAKE_OPTIONS.fullscreen)

@@ -921,11 +979,16 @@ .option('--transparent', 'Transparent title bar', DEFAULT_PAKE_OPTIONS.transparent)

.option('--iter-copy-file', 'Copy files to app when URL is a local file', DEFAULT_PAKE_OPTIONS.iterCopyFile)
.option('--multi-arch', 'Available for Mac only, supports both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
.option('--multi-arch', 'Only for Mac, supports both Intel and M1', DEFAULT_PAKE_OPTIONS.multiArch)
.option('--targets <string>', 'Only for Linux, option "deb", "appimage" or "all"', DEFAULT_PAKE_OPTIONS.targets)
.option('--debug', 'Debug mode', DEFAULT_PAKE_OPTIONS.debug)
.version(packageJson.version, '-v, --version', 'Output the current version')
.action(async (url, options) => {
//Check for update prompt
await checkUpdateTips();
// If no URL is provided, display help information
if (!url) {
program.help();
program.outputHelp((str) => {
return str
.split('\n')
.filter((line) => !/((-h,|--help)|((-v|-V),|--version))\s+.+$/.test(line))
.join('\n');
});
process.exit(0);
}

@@ -936,10 +999,8 @@ log.setDefaultLevel('info');

}
const spinner = ora('Preparing...').start();
const builder = BuilderProvider.create();
await builder.prepare();
const appOptions = await handleOptions(options, url);
spinner.succeed();
log.debug('PakeAppOptions', appOptions);
await builder.build(url, appOptions);
const builder = BuilderProvider.create(appOptions);
await builder.prepare();
await builder.build(url);
});
program.parse();
{
"name": "pake-cli",
"version": "2.1.1",
"version": "2.1.2",
"description": "๐Ÿคฑ๐Ÿป Turn any webpage into a desktop app with Rust. ๐Ÿคฑ๐Ÿป ๅพˆ็ฎ€ๅ•็š„็”จ Rust ๆ‰“ๅŒ…็ฝ‘้กต็”Ÿๆˆๅพˆๅฐ็š„ๆกŒ้ข Appใ€‚",

@@ -5,0 +5,0 @@ "engines": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with โšก๏ธ by Socket Inc