@@ -1,3 +1,3 @@
|
||||
{
|
||||
"Exclude": ["Cargo\\.lock$"]
|
||||
"Exclude": ["Cargo\\.lock$", "dist"]
|
||||
}
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,11 +9,13 @@ lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
dist-ssr
|
||||
dist/cli.js
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
!.vscode/settings.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
|
||||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"cSpell.words": ["loglevel", "Pake", "tauri"],
|
||||
"typescript.preferences.importModuleSpecifierEnding": "js"
|
||||
}
|
||||
20
README.md
20
README.md
@@ -85,6 +85,26 @@
|
||||
- Windows 下不能安装到 C:\Program File,会直接闪退。建议安装到其他非管理员权限目录,比如 D:\Program Files (x86) 。
|
||||
- ~~Linux 下暂时不能存 cookie,即应用关闭后数据清空,账号自动推出(已修复)~~。
|
||||
|
||||
## 使用命令行打包
|
||||
|
||||
Pake 提供了命令行工具,可以更快捷方便地打包。(目前仅支持 MacOS)
|
||||
|
||||
### 安装
|
||||
|
||||
```bash
|
||||
npm install -g pake-cli
|
||||
```
|
||||
|
||||
如果安装失败提示没有权限,请使用 `sudo` 运行。
|
||||
|
||||
### 用法
|
||||
|
||||
```bash
|
||||
pake [options] url
|
||||
```
|
||||
|
||||
更多用法可查看[文档](./bin//README.md)。
|
||||
|
||||
## 开发
|
||||
|
||||
开始前参考 [Tauri](https://tauri.app/v1/guides/getting-started/prerequisites#setting-up-macos) 快速配置好环境。
|
||||
|
||||
72
bin/README.md
Normal file
72
bin/README.md
Normal file
@@ -0,0 +1,72 @@
|
||||
## 安装
|
||||
|
||||
```bash
|
||||
npm install -g pake-cli
|
||||
```
|
||||
|
||||
如果安装失败提示没有权限,请使用 `sudo` 运行。
|
||||
|
||||
## 用法
|
||||
|
||||
```bash
|
||||
pake [options] url
|
||||
```
|
||||
打包完成后的应用程序默认为当前工作目录。
|
||||
|
||||
Note: 打包需要用 `Rust` 环境,如果没有 `Rust`,会提示确认安装。如遇安装失败或超时,可[自行安装](https://www.rust-lang.org/tools/install)。
|
||||
|
||||
Note: 目前仅支持 MacOs,后续会支持其他平台。
|
||||
|
||||
|
||||
### url
|
||||
url 为你需要打包的网页链接🔗,必须提供。
|
||||
|
||||
### [options]
|
||||
|
||||
提供了一些特定的选项,打包时可以传递对应参数达到定制化的效果。
|
||||
|
||||
#### [name]
|
||||
应用名称,如输入时未指定,会提示你输入。
|
||||
```shell
|
||||
--name <value>
|
||||
```
|
||||
|
||||
#### [icon]
|
||||
应用icon,支持本地/远程文件,默认为 Pake 自带图标。
|
||||
- MacOS下必须为 `.icns`
|
||||
```shell
|
||||
--icon <path>
|
||||
```
|
||||
|
||||
#### [height]
|
||||
打包后的应用窗口高度,默认 `800px`。
|
||||
```
|
||||
--height <number>
|
||||
```
|
||||
|
||||
|
||||
#### [width]
|
||||
打包后的应用窗口宽度,默认 `1280px`。
|
||||
```
|
||||
--width <number>
|
||||
```
|
||||
|
||||
|
||||
#### [transparent]
|
||||
是否开启沉浸式头部,默认为 `false` 不开启。
|
||||
```
|
||||
--transparent
|
||||
```
|
||||
|
||||
|
||||
#### [resize]
|
||||
是否可以拖动大小,默认为 `true` 可拖动。
|
||||
```
|
||||
--no-resizable
|
||||
```
|
||||
|
||||
#### [fullscreen]
|
||||
打开应用后是否开启全屏,默认为 `false`。
|
||||
```
|
||||
--fullscreen <value>
|
||||
```
|
||||
12
bin/builders/BuilderFactory.ts
Normal file
12
bin/builders/BuilderFactory.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { IS_MAC } from '@/utils/platform.js';
|
||||
import { IBuilder } from './base.js';
|
||||
import MacBuilder from './MacBuilder.js';
|
||||
|
||||
export default class BuilderFactory {
|
||||
static create(): IBuilder {
|
||||
if (IS_MAC) {
|
||||
return new MacBuilder();
|
||||
}
|
||||
throw new Error('The current system does not support');
|
||||
}
|
||||
}
|
||||
0
bin/builders/LinuxBuilder.ts
Normal file
0
bin/builders/LinuxBuilder.ts
Normal file
65
bin/builders/MacBuilder.ts
Normal file
65
bin/builders/MacBuilder.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import prompts from 'prompts';
|
||||
import { checkRustInstalled, installRust } from '@/helpers/rust.js';
|
||||
import { PakeAppOptions } from '@/types.js';
|
||||
import { IBuilder } from './base.js';
|
||||
import { shellExec } from '@/utils/shell.js';
|
||||
import tauriConf from '../../src-tauri/tauri.conf.json';
|
||||
import { fileURLToPath } from 'url';
|
||||
import log from 'loglevel';
|
||||
|
||||
export default class MacBuilder implements IBuilder {
|
||||
async prepare() {
|
||||
if (checkRustInstalled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await prompts({
|
||||
type: 'confirm',
|
||||
message: 'We detected that you have not installed Rust. Install it now?',
|
||||
name: 'value',
|
||||
});
|
||||
|
||||
if (res.value) {
|
||||
// TODO 国内有可能会超时
|
||||
await installRust();
|
||||
} else {
|
||||
log.error('Error: Pake need Rust to package your webapp!!!');
|
||||
process.exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
async build(url: string, options: PakeAppOptions) {
|
||||
log.debug('PakeAppOptions', options);
|
||||
|
||||
const { width, height, fullscreen, transparent, resizable, identifier, name } = options;
|
||||
|
||||
const tauriConfWindowOptions = {
|
||||
width,
|
||||
height,
|
||||
fullscreen,
|
||||
transparent,
|
||||
resizable,
|
||||
};
|
||||
|
||||
// TODO 下面这块逻辑还可以再拆 目前比较简单
|
||||
Object.assign(tauriConf.tauri.windows[0], { url, ...tauriConfWindowOptions });
|
||||
tauriConf.package.productName = name;
|
||||
tauriConf.tauri.bundle.identifier = identifier;
|
||||
tauriConf.tauri.bundle.icon = [options.icon];
|
||||
|
||||
const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const configJsonPath = path.join(npmDirectory, 'src-tauri/tauri.conf.json');
|
||||
await fs.writeFile(configJsonPath, Buffer.from(JSON.stringify(tauriConf), 'utf-8'));
|
||||
|
||||
const code = await shellExec(`cd ${npmDirectory} && npm run build`);
|
||||
const dmgName = `${name}_${'0.2.0'}_universal.dmg`;
|
||||
const appPath = this.getBuildedAppPath(npmDirectory, dmgName);
|
||||
await fs.copyFile(appPath, path.resolve(`${name}_universal.dmg`));
|
||||
}
|
||||
|
||||
getBuildedAppPath(npmDirectory: string, dmgName: string) {
|
||||
return path.join(npmDirectory, 'src-tauri/target/universal-apple-darwin/release/bundle/dmg', dmgName);
|
||||
}
|
||||
}
|
||||
0
bin/builders/WinBulider.ts
Normal file
0
bin/builders/WinBulider.ts
Normal file
16
bin/builders/base.ts
Normal file
16
bin/builders/base.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { PakeAppOptions } from '@/types.js';
|
||||
|
||||
/**
|
||||
* Builder接口
|
||||
* 不同平台打包过程需要实现 prepare 和 build 方法
|
||||
*/
|
||||
export interface IBuilder {
|
||||
/** 前置检查 */
|
||||
prepare(): Promise<void>;
|
||||
/**
|
||||
* 开始打包
|
||||
* @param url 打包url
|
||||
* @param options 配置参数
|
||||
*/
|
||||
build(url: string, options: PakeAppOptions): Promise<void>;
|
||||
}
|
||||
11
bin/builders/common.ts
Normal file
11
bin/builders/common.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import prompts from 'prompts';
|
||||
|
||||
export async function promptText(message: string, initial?: string) {
|
||||
const response = await prompts({
|
||||
type: 'text',
|
||||
name: 'content',
|
||||
message,
|
||||
initial,
|
||||
});
|
||||
return response.content;
|
||||
}
|
||||
36
bin/cli.ts
Normal file
36
bin/cli.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { program } from 'commander';
|
||||
import { DEFAULT_PAKE_OPTIONS } from './defaults.js';
|
||||
import { PakeCliOptions } from './types.js';
|
||||
import { validateNumberInput, validateUrlInput } from './utils/validate.js';
|
||||
import handleInputOptions from './options/index.js';
|
||||
import BuilderFactory from './builders/BuilderFactory.js';
|
||||
import log from 'loglevel';
|
||||
|
||||
program.version('0.0.1').description('A cli application can package a web page to desktop application');
|
||||
|
||||
program
|
||||
.showHelpAfterError()
|
||||
.argument('<url>', 'the web url you want to package', validateUrlInput)
|
||||
.option('--name <string>', 'application name')
|
||||
.option('--icon <string>', 'application icon', DEFAULT_PAKE_OPTIONS.icon)
|
||||
.option('--height <number>', 'window height', validateNumberInput, DEFAULT_PAKE_OPTIONS.height)
|
||||
.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', 'makes the packaged app start in full screen', DEFAULT_PAKE_OPTIONS.fullscreen)
|
||||
.option('--transparent', 'transparent title bar', DEFAULT_PAKE_OPTIONS.transparent)
|
||||
.option('--debug', 'debug', DEFAULT_PAKE_OPTIONS.transparent)
|
||||
.action(async (url: string, options: PakeCliOptions) => {
|
||||
log.setDefaultLevel('info')
|
||||
if (options.debug) {
|
||||
log.setLevel('debug');
|
||||
}
|
||||
|
||||
const builder = BuilderFactory.create();
|
||||
await builder.prepare();
|
||||
|
||||
const appOptions = await handleInputOptions(options, url);
|
||||
|
||||
builder.build(url, appOptions);
|
||||
});
|
||||
|
||||
program.parse();
|
||||
13
bin/defaults.ts
Normal file
13
bin/defaults.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { PakeCliOptions } from './types.js';
|
||||
|
||||
export const DEFAULT_PAKE_OPTIONS: PakeCliOptions = {
|
||||
icon: '',
|
||||
height: 800,
|
||||
width: 1280,
|
||||
fullscreen: false,
|
||||
resizable: true,
|
||||
transparent: false,
|
||||
debug: false,
|
||||
};
|
||||
|
||||
export const DEFAULT_APP_NAME = 'Pake';
|
||||
21
bin/helpers/rust.ts
Normal file
21
bin/helpers/rust.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import ora from 'ora';
|
||||
import shelljs from 'shelljs';
|
||||
import { shellExec } from '../utils/shell.js';
|
||||
|
||||
const InstallRustScript = "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y";
|
||||
export async function installRust() {
|
||||
const spinner = ora('Downloading Rust').start();
|
||||
try {
|
||||
await shellExec(InstallRustScript);
|
||||
spinner.succeed();
|
||||
} catch (error) {
|
||||
console.error('install rust return code', error.message);
|
||||
spinner.fail();
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function checkRustInstalled() {
|
||||
return shelljs.exec('rustc --version', { silent: true }).code === 0;
|
||||
}
|
||||
8
bin/helpers/tauriConfig.ts
Normal file
8
bin/helpers/tauriConfig.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import crypto from 'crypto';
|
||||
|
||||
export function getIdentifier(name: string, url: string) {
|
||||
const hash = crypto.createHash('md5');
|
||||
hash.update(url);
|
||||
const postFixHash = hash.digest('hex').substring(0, 6);
|
||||
return `pake-${postFixHash}`;
|
||||
}
|
||||
91
bin/options/icon.ts
Normal file
91
bin/options/icon.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import axios from 'axios';
|
||||
import { fileTypeFromBuffer } from 'file-type';
|
||||
import { PakeAppOptions } from '../types.js';
|
||||
import { dir } from 'tmp-promise';
|
||||
import path from 'path';
|
||||
import fs from 'fs/promises';
|
||||
import { fileURLToPath } from 'url';
|
||||
import log from 'loglevel';
|
||||
|
||||
export async function handleIcon(options: PakeAppOptions, url: string) {
|
||||
if (options.icon) {
|
||||
if (options.icon.startsWith('http')) {
|
||||
return downloadIcon(options.icon);
|
||||
} else {
|
||||
return path.resolve(options.icon);
|
||||
}
|
||||
}
|
||||
if (!options.icon) {
|
||||
return inferIcon(options.name, url);
|
||||
}
|
||||
}
|
||||
|
||||
export async function inferIcon(name: string, url: string) {
|
||||
log.info('You have not provided an app icon, use the default icon(can use --icon option to assign an icon)')
|
||||
const npmDirectory = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
return path.join(npmDirectory, 'pake-default.icns');
|
||||
}
|
||||
|
||||
// export async function getIconFromPageUrl(url: string) {
|
||||
// const icon = await pageIcon(url);
|
||||
// console.log(icon);
|
||||
// if (icon.ext === '.ico') {
|
||||
// const a = await ICO.parse(icon.data);
|
||||
// icon.data = Buffer.from(a[0].buffer);
|
||||
// }
|
||||
|
||||
// const iconDir = (await dir()).path;
|
||||
// const iconPath = path.join(iconDir, `/icon.icns`);
|
||||
|
||||
// const out = png2icons.createICNS(icon.data, png2icons.BILINEAR, 0);
|
||||
|
||||
// await fs.writeFile(iconPath, out);
|
||||
// return iconPath;
|
||||
// }
|
||||
|
||||
// export async function getIconFromMacosIcons(name: string) {
|
||||
// const data = {
|
||||
// query: name,
|
||||
// filters: 'approved:true',
|
||||
// hitsPerPage: 10,
|
||||
// page: 1,
|
||||
// };
|
||||
// const res = await axios.post('https://p1txh7zfb3-2.algolianet.com/1/indexes/macOSicons/query?x-algolia-agent=Algolia%20for%20JavaScript%20(4.13.1)%3B%20Browser', data, {
|
||||
// headers: {
|
||||
// 'x-algolia-api-key': '0ba04276e457028f3e11e38696eab32c',
|
||||
// 'x-algolia-application-id': 'P1TXH7ZFB3',
|
||||
// },
|
||||
// });
|
||||
// if (!res.data.hits.length) {
|
||||
// return '';
|
||||
// } else {
|
||||
// return downloadIcon(res.data.hits[0].icnsUrl);
|
||||
// }
|
||||
// }
|
||||
|
||||
export async function downloadIcon(iconUrl: string) {
|
||||
let iconResponse;
|
||||
try {
|
||||
iconResponse = await axios.get(iconUrl, {
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 404) {
|
||||
return null;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const iconData = await iconResponse.data;
|
||||
if (!iconData) {
|
||||
return null;
|
||||
}
|
||||
const fileDetails = await fileTypeFromBuffer(iconData);
|
||||
if (!fileDetails) {
|
||||
return null;
|
||||
}
|
||||
const { path } = await dir();
|
||||
const iconPath = `${path}/icon.${fileDetails.ext}`;
|
||||
await fs.writeFile(iconPath, iconData);
|
||||
return iconPath;
|
||||
}
|
||||
22
bin/options/index.ts
Normal file
22
bin/options/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { promptText } from '@/builders/common.js';
|
||||
import { getDomain } from '@/utils/url.js';
|
||||
import { getIdentifier } from '../helpers/tauriConfig.js';
|
||||
import { PakeAppOptions, PakeCliOptions } from '../types.js';
|
||||
import { handleIcon } from './icon.js';
|
||||
|
||||
export default async function handleOptions(options: PakeCliOptions, url: string): Promise<PakeAppOptions> {
|
||||
const appOptions: PakeAppOptions = {
|
||||
...options,
|
||||
identifier: '',
|
||||
};
|
||||
|
||||
if (!appOptions.name) {
|
||||
appOptions.name = await promptText('please input your application name', getDomain(url));
|
||||
}
|
||||
|
||||
appOptions.identifier = getIdentifier(appOptions.name, url);
|
||||
|
||||
appOptions.icon = await handleIcon(appOptions, url);
|
||||
|
||||
return appOptions;
|
||||
}
|
||||
29
bin/types.ts
Normal file
29
bin/types.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export interface PakeCliOptions {
|
||||
/** 应用名称 */
|
||||
name?: string;
|
||||
|
||||
/** 应用icon */
|
||||
icon: string;
|
||||
|
||||
/** 应用窗口宽度,默认 1280px */
|
||||
width: number;
|
||||
|
||||
/** 应用窗口高度,默认 800px */
|
||||
height: number;
|
||||
|
||||
/** 是否可以拖动,默认true */
|
||||
resizable: boolean;
|
||||
|
||||
/** 是否可以全屏,默认 false */
|
||||
fullscreen: boolean;
|
||||
|
||||
/** 是否开启沉浸式头部,默认为 false 不开启 ƒ*/
|
||||
transparent: boolean;
|
||||
|
||||
/** 调试模式,会输出更多日志 */
|
||||
debug: boolean;
|
||||
}
|
||||
|
||||
export interface PakeAppOptions extends PakeCliOptions {
|
||||
identifier: string;
|
||||
}
|
||||
5
bin/utils/platform.ts
Normal file
5
bin/utils/platform.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const IS_MAC = process.platform === 'darwin';
|
||||
|
||||
export const IS_WIN = process.platform === 'win32';
|
||||
|
||||
export const IS_LINUX = process.platform === 'linux';
|
||||
13
bin/utils/shell.ts
Normal file
13
bin/utils/shell.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import shelljs from "shelljs";
|
||||
|
||||
export function shellExec(command: string) {
|
||||
return new Promise<number>((resolve, reject) => {
|
||||
shelljs.exec(command, { async: true, silent: false }, (code) => {
|
||||
if (code === 0) {
|
||||
resolve(0);
|
||||
} else {
|
||||
reject(new Error(`${code}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
1489
bin/utils/tlds.ts
Normal file
1489
bin/utils/tlds.ts
Normal file
File diff suppressed because it is too large
Load Diff
47
bin/utils/url.ts
Normal file
47
bin/utils/url.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import url from 'url';
|
||||
import isurl from 'is-url';
|
||||
import tlds from './tlds.js';
|
||||
|
||||
export function getDomain(inputUrl: string) {
|
||||
const parsed = url.parse(inputUrl).host;
|
||||
var parts = parsed.split('.');
|
||||
if (parts[0] === 'www' && parts[1] !== 'com') {
|
||||
parts.shift();
|
||||
}
|
||||
var ln = parts.length,
|
||||
i = ln,
|
||||
minLength = parts[parts.length - 1].length,
|
||||
part;
|
||||
|
||||
// iterate backwards
|
||||
while ((part = parts[--i])) {
|
||||
// stop when we find a non-TLD part
|
||||
if (
|
||||
i === 0 || // 'asia.com' (last remaining must be the SLD)
|
||||
i < ln - 2 || // TLDs only span 2 levels
|
||||
part.length < minLength || // 'www.cn.com' (valid TLD as second-level domain)
|
||||
tlds.indexOf(part) < 0 // officialy not a TLD
|
||||
) {
|
||||
return part;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function appendProtocol(inputUrl: string): string {
|
||||
const parsed = url.parse(inputUrl);
|
||||
if (!parsed.protocol) {
|
||||
const urlWithProtocol = `https://${inputUrl}`;
|
||||
return urlWithProtocol;
|
||||
}
|
||||
return inputUrl;
|
||||
}
|
||||
|
||||
export function normalizeUrl(urlToNormalize: string): string {
|
||||
const urlWithProtocol = appendProtocol(urlToNormalize);
|
||||
|
||||
if (isurl(urlWithProtocol)) {
|
||||
return urlWithProtocol;
|
||||
} else {
|
||||
throw new Error(`Your url "${urlWithProtocol}" is invalid`);
|
||||
}
|
||||
}
|
||||
18
bin/utils/validate.ts
Normal file
18
bin/utils/validate.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as Commander from 'commander';
|
||||
import { normalizeUrl } from './url.js';
|
||||
|
||||
export function validateNumberInput(value: string) {
|
||||
const parsedValue = Number(value);
|
||||
if (isNaN(parsedValue)) {
|
||||
throw new Commander.InvalidArgumentError('Not a number.');
|
||||
}
|
||||
return parsedValue;
|
||||
}
|
||||
|
||||
export function validateUrlInput(url: string) {
|
||||
try {
|
||||
return normalizeUrl(url);
|
||||
} catch (error) {
|
||||
throw new Commander.InvalidArgumentError(error.message);
|
||||
}
|
||||
}
|
||||
1918
dist/cli.js
vendored
Normal file
1918
dist/cli.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42
package.json
42
package.json
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"name": "pake",
|
||||
"name": "pake-cli",
|
||||
"version": "0.0.2",
|
||||
"description": "用 Rust 来打包你的 App,底层使用 Tauri,当前支持微信读书、Flomo、Vercel",
|
||||
"bin": {
|
||||
"pake": "./cli.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tw93/pake.git"
|
||||
@@ -16,13 +20,43 @@
|
||||
"build": "npm run tauri build -- --target universal-apple-darwin",
|
||||
"build:windows": "npm run tauri build -- --target x86_64-pc-windows-msvc",
|
||||
"build:linux": "npm run tauri build --release",
|
||||
"tauri": "tauri"
|
||||
"tauri": "tauri",
|
||||
"cli": "rollup -c rollup.config.js --watch",
|
||||
"cli:build": "rollup -c rollup.config.js",
|
||||
"cli:publish": "npm run cli:build && npm publish"
|
||||
},
|
||||
"type": "module",
|
||||
"exports": "./dist/pake.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^1.2.0"
|
||||
"@tauri-apps/api": "^1.2.0",
|
||||
"@tauri-apps/cli": "^1.2.0",
|
||||
"axios": "^1.1.3",
|
||||
"commander": "^9.4.1",
|
||||
"file-type": "^18.0.0",
|
||||
"is-url": "^1.2.4",
|
||||
"loglevel": "^1.8.1",
|
||||
"ora": "^6.1.2",
|
||||
"prompts": "^2.4.2",
|
||||
"shelljs": "^0.8.5",
|
||||
"tmp-promise": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tauri-apps/cli": "^1.2.0"
|
||||
"@rollup/plugin-alias": "^4.0.2",
|
||||
"@rollup/plugin-commonjs": "^23.0.2",
|
||||
"@rollup/plugin-json": "^5.0.1",
|
||||
"@rollup/plugin-typescript": "^9.0.2",
|
||||
"@types/is-url": "^1.2.30",
|
||||
"@types/page-icon": "^0.3.4",
|
||||
"@types/prompts": "^2.4.1",
|
||||
"@types/shelljs": "^0.8.11",
|
||||
"@types/tmp": "^0.2.3",
|
||||
"app-root-path": "^3.1.0",
|
||||
"concurrently": "^7.5.0",
|
||||
"rollup": "^3.3.0",
|
||||
"rollup-plugin-typescript2": "^0.34.1",
|
||||
"tsc-alias": "^1.7.1",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^4.8.4"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
pake-default.icns
Normal file
BIN
pake-default.icns
Normal file
Binary file not shown.
24
rollup.config.js
Normal file
24
rollup.config.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import path from 'path';
|
||||
import appRootPath from 'app-root-path';
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import alias from '@rollup/plugin-alias';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
|
||||
export default {
|
||||
input: 'bin/cli.ts',
|
||||
output: {
|
||||
file: 'dist/cli.js',
|
||||
format: 'es'
|
||||
},
|
||||
plugins: [
|
||||
json(),
|
||||
typescript({
|
||||
sourceMap: false,
|
||||
}),
|
||||
commonjs(),
|
||||
alias({
|
||||
entries: [{ find: '@', replacement: path.join(appRootPath.path, 'bin') }],
|
||||
}),
|
||||
],
|
||||
};
|
||||
BIN
src-tauri/icons/icon.icns
Normal file
BIN
src-tauri/icons/icon.icns
Normal file
Binary file not shown.
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "Node16",
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"target": "es6",
|
||||
"noImplicitAny": true,
|
||||
"moduleResolution": "Node16",
|
||||
"sourceMap": true,
|
||||
"outDir": "dist",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["bin/*"]
|
||||
}
|
||||
},
|
||||
"include": ["bin/**/*"]
|
||||
}
|
||||
Reference in New Issue
Block a user