pal-explorer-cli 0.4.11 → 0.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +149 -149
- package/bin/pal.js +63 -2
- package/extensions/@palexplorer/analytics/extension.json +20 -1
- package/extensions/@palexplorer/analytics/index.js +19 -9
- package/extensions/@palexplorer/audit/extension.json +14 -0
- package/extensions/@palexplorer/auth-email/extension.json +15 -0
- package/extensions/@palexplorer/auth-oauth/extension.json +15 -0
- package/extensions/@palexplorer/chat/extension.json +14 -0
- package/extensions/@palexplorer/discovery/extension.json +17 -0
- package/extensions/@palexplorer/discovery/index.js +1 -1
- package/extensions/@palexplorer/email-notifications/extension.json +23 -0
- package/extensions/@palexplorer/groups/extension.json +15 -0
- package/extensions/@palexplorer/share-links/extension.json +15 -0
- package/extensions/@palexplorer/sync/extension.json +16 -0
- package/extensions/@palexplorer/user-mgmt/extension.json +15 -0
- package/lib/capabilities.js +24 -24
- package/lib/commands/analytics.js +175 -175
- package/lib/commands/api-keys.js +131 -131
- package/lib/commands/audit.js +235 -235
- package/lib/commands/auth.js +137 -137
- package/lib/commands/backup.js +76 -76
- package/lib/commands/billing.js +148 -148
- package/lib/commands/chat.js +217 -217
- package/lib/commands/cloud-backup.js +231 -231
- package/lib/commands/comment.js +99 -99
- package/lib/commands/completion.js +203 -203
- package/lib/commands/compliance.js +218 -218
- package/lib/commands/config.js +136 -136
- package/lib/commands/connect.js +44 -44
- package/lib/commands/dept.js +294 -294
- package/lib/commands/device.js +146 -146
- package/lib/commands/download.js +240 -226
- package/lib/commands/explorer.js +178 -178
- package/lib/commands/extension.js +1060 -970
- package/lib/commands/favorite.js +90 -90
- package/lib/commands/federation.js +270 -270
- package/lib/commands/file.js +533 -533
- package/lib/commands/group.js +271 -271
- package/lib/commands/gui-share.js +29 -29
- package/lib/commands/init.js +61 -61
- package/lib/commands/invite.js +59 -59
- package/lib/commands/list.js +58 -58
- package/lib/commands/log.js +116 -116
- package/lib/commands/nearby.js +108 -108
- package/lib/commands/network.js +251 -251
- package/lib/commands/notify.js +198 -198
- package/lib/commands/org.js +273 -273
- package/lib/commands/pal.js +403 -180
- package/lib/commands/permissions.js +216 -216
- package/lib/commands/pin.js +97 -97
- package/lib/commands/protocol.js +357 -357
- package/lib/commands/rbac.js +147 -147
- package/lib/commands/recover.js +36 -36
- package/lib/commands/register.js +171 -171
- package/lib/commands/relay.js +131 -131
- package/lib/commands/remote.js +368 -368
- package/lib/commands/revoke.js +50 -50
- package/lib/commands/scanner.js +280 -280
- package/lib/commands/schedule.js +344 -344
- package/lib/commands/scim.js +203 -203
- package/lib/commands/search.js +181 -181
- package/lib/commands/serve.js +438 -438
- package/lib/commands/server.js +350 -350
- package/lib/commands/share-link.js +199 -199
- package/lib/commands/share.js +336 -323
- package/lib/commands/sso.js +200 -200
- package/lib/commands/status.js +145 -145
- package/lib/commands/stream.js +562 -562
- package/lib/commands/su.js +187 -187
- package/lib/commands/sync.js +979 -979
- package/lib/commands/transfers.js +152 -152
- package/lib/commands/uninstall.js +188 -188
- package/lib/commands/update.js +204 -204
- package/lib/commands/user.js +276 -276
- package/lib/commands/vfs.js +84 -84
- package/lib/commands/web-login.js +79 -79
- package/lib/commands/web.js +52 -52
- package/lib/commands/webhook.js +180 -180
- package/lib/commands/whoami.js +59 -59
- package/lib/commands/workspace.js +121 -121
- package/lib/core/billing.js +16 -5
- package/lib/core/dhtDiscovery.js +9 -2
- package/lib/core/discoveryClient.js +13 -7
- package/lib/core/extensions.js +142 -1
- package/lib/core/identity.js +33 -2
- package/lib/core/imageProcessor.js +109 -0
- package/lib/core/imageTorrent.js +167 -0
- package/lib/core/permissions.js +1 -1
- package/lib/core/pro.js +11 -4
- package/lib/core/serverList.js +4 -1
- package/lib/core/shares.js +12 -1
- package/lib/core/signalingServer.js +14 -2
- package/lib/core/su.js +1 -1
- package/lib/core/users.js +1 -1
- package/lib/protocol/messages.js +12 -3
- package/lib/utils/explorer.js +1 -1
- package/lib/utils/help.js +357 -357
- package/lib/utils/torrent.js +1 -0
- package/package.json +4 -3
package/lib/commands/billing.js
CHANGED
|
@@ -1,148 +1,148 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import { PLANS, getActivePlan, activateLicenseKey, deactivateLicenseKey, getCheckoutUrl } from '../core/billing.js';
|
|
3
|
-
|
|
4
|
-
export default function billingCommand(program) {
|
|
5
|
-
const cmd = program
|
|
6
|
-
.command('billing')
|
|
7
|
-
.description('manage subscription and billing')
|
|
8
|
-
.addHelpText('after', `
|
|
9
|
-
Examples:
|
|
10
|
-
$
|
|
11
|
-
$
|
|
12
|
-
$
|
|
13
|
-
$
|
|
14
|
-
$
|
|
15
|
-
`)
|
|
16
|
-
.action(() => { cmd.outputHelp(); });
|
|
17
|
-
|
|
18
|
-
cmd
|
|
19
|
-
.command('status')
|
|
20
|
-
.description('show current plan, expiry, and limits')
|
|
21
|
-
.action(async () => {
|
|
22
|
-
const plan = getActivePlan();
|
|
23
|
-
const badge = plan.key === 'free' ? chalk.gray('Free') :
|
|
24
|
-
plan.key === 'enterprise' ? chalk.magenta('Enterprise') :
|
|
25
|
-
chalk.yellow('Pro');
|
|
26
|
-
|
|
27
|
-
console.log(`\n Plan: ${badge} (${plan.name})`);
|
|
28
|
-
if (plan.price > 0) {
|
|
29
|
-
console.log(` Price: $${plan.price}/${plan.interval || 'mo'}${plan.perSeat ? ' per seat' : ''}`);
|
|
30
|
-
}
|
|
31
|
-
if (plan.expiresAt) {
|
|
32
|
-
console.log(` Expires: ${chalk.white(new Date(plan.expiresAt).toLocaleDateString())}`);
|
|
33
|
-
}
|
|
34
|
-
if (plan.source === 'expired') {
|
|
35
|
-
console.log(chalk.red(' License expired. Please renew.'));
|
|
36
|
-
}
|
|
37
|
-
if (plan.customerEmail) {
|
|
38
|
-
console.log(` Email: ${plan.customerEmail}`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
console.log(`\n ${chalk.cyan.bold('Limits:')}`);
|
|
42
|
-
for (const [k, v] of Object.entries(plan.limits)) {
|
|
43
|
-
const display = v === Infinity ? chalk.green('unlimited') : chalk.white(String(v));
|
|
44
|
-
console.log(` ${k}: ${display}`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const enabled = Object.entries(plan.features).filter(([, v]) => v);
|
|
48
|
-
const disabled = Object.entries(plan.features).filter(([, v]) => !v);
|
|
49
|
-
if (enabled.length > 0) {
|
|
50
|
-
console.log(`\n ${chalk.green.bold('Enabled Features:')}`);
|
|
51
|
-
for (const [k] of enabled) {
|
|
52
|
-
console.log(` ${chalk.green('+')} ${k}`);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (disabled.length > 0) {
|
|
56
|
-
console.log(`\n ${chalk.gray('Disabled Features:')}`);
|
|
57
|
-
for (const [k] of disabled) {
|
|
58
|
-
console.log(` ${chalk.gray('-')} ${k}`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
console.log();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
cmd
|
|
65
|
-
.command('plans')
|
|
66
|
-
.description('show available plans with pricing')
|
|
67
|
-
.action(async () => {
|
|
68
|
-
console.log(`\n ${chalk.bold('Palexplorer Plans')}\n`);
|
|
69
|
-
|
|
70
|
-
const current = getActivePlan();
|
|
71
|
-
for (const [key, plan] of Object.entries(PLANS)) {
|
|
72
|
-
const isCurrent = key === current.key;
|
|
73
|
-
const marker = isCurrent ? chalk.green(' (current)') : '';
|
|
74
|
-
const price = plan.price === 0 ? 'Free' :
|
|
75
|
-
`$${plan.price}/${plan.interval || 'mo'}${plan.perSeat ? ' per seat' : ''}`;
|
|
76
|
-
|
|
77
|
-
console.log(` ${chalk.bold(plan.name)}${marker} — ${chalk.yellow(price)}`);
|
|
78
|
-
|
|
79
|
-
const highlights = [];
|
|
80
|
-
if (plan.limits.maxShares === Infinity) highlights.push('Unlimited shares');
|
|
81
|
-
else highlights.push(`${plan.limits.maxShares} shares`);
|
|
82
|
-
if (plan.limits.maxRecipients === Infinity) highlights.push('Unlimited recipients');
|
|
83
|
-
else highlights.push(`${plan.limits.maxRecipients} recipients`);
|
|
84
|
-
if (plan.limits.maxFileSize === Infinity) highlights.push('No file size limit');
|
|
85
|
-
else highlights.push(`${(plan.limits.maxFileSize / (1024 * 1024 * 1024)).toFixed(0)}GB max file`);
|
|
86
|
-
highlights.push(`${plan.limits.apiKeys} API keys`);
|
|
87
|
-
|
|
88
|
-
console.log(` ${chalk.gray(highlights.join(' | '))}`);
|
|
89
|
-
console.log();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
cmd
|
|
94
|
-
.command('activate <license-key>')
|
|
95
|
-
.description('activate a license key')
|
|
96
|
-
.action(async (key) => {
|
|
97
|
-
try {
|
|
98
|
-
console.log(chalk.gray('Activating license...'));
|
|
99
|
-
const result = await activateLicenseKey(key);
|
|
100
|
-
const plan = PLANS[result.plan];
|
|
101
|
-
console.log(chalk.green(`License activated! Plan: ${plan?.name || result.plan}`));
|
|
102
|
-
if (result.expiresAt) {
|
|
103
|
-
console.log(` Expires: ${new Date(result.expiresAt).toLocaleDateString()}`);
|
|
104
|
-
}
|
|
105
|
-
} catch (err) {
|
|
106
|
-
console.log(chalk.red(`Activation failed: ${err.message}`));
|
|
107
|
-
process.exitCode = 1;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
cmd
|
|
112
|
-
.command('deactivate')
|
|
113
|
-
.description('deactivate current license')
|
|
114
|
-
.action(async () => {
|
|
115
|
-
try {
|
|
116
|
-
await deactivateLicenseKey();
|
|
117
|
-
console.log(chalk.green('License deactivated. Reverted to Free plan.'));
|
|
118
|
-
} catch (err) {
|
|
119
|
-
console.log(chalk.red(`Deactivation failed: ${err.message}`));
|
|
120
|
-
process.exitCode = 1;
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
cmd
|
|
125
|
-
.command('checkout [plan]')
|
|
126
|
-
.description('open checkout URL in browser')
|
|
127
|
-
.addHelpText('after', '\nPlans: pro_monthly, pro_annual, enterprise')
|
|
128
|
-
.action(async (plan) => {
|
|
129
|
-
plan = plan || 'pro_monthly';
|
|
130
|
-
try {
|
|
131
|
-
const url = getCheckoutUrl(plan);
|
|
132
|
-
console.log(`\n Checkout URL: ${chalk.cyan(url)}`);
|
|
133
|
-
console.log(chalk.gray(' Opening in browser...'));
|
|
134
|
-
const { exec } = await import('child_process');
|
|
135
|
-
try {
|
|
136
|
-
const parsed = new URL(url);
|
|
137
|
-
if (parsed.protocol === 'https:') {
|
|
138
|
-
const cmd = process.platform === 'win32' ? `start "" "${parsed.href}"` :
|
|
139
|
-
process.platform === 'darwin' ? `open "${parsed.href}"` : `xdg-open "${parsed.href}"`;
|
|
140
|
-
exec(cmd);
|
|
141
|
-
}
|
|
142
|
-
} catch {}
|
|
143
|
-
} catch (err) {
|
|
144
|
-
console.log(chalk.red(err.message));
|
|
145
|
-
process.exitCode = 1;
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { PLANS, getActivePlan, activateLicenseKey, deactivateLicenseKey, getCheckoutUrl } from '../core/billing.js';
|
|
3
|
+
|
|
4
|
+
export default function billingCommand(program) {
|
|
5
|
+
const cmd = program
|
|
6
|
+
.command('billing')
|
|
7
|
+
.description('manage subscription and billing')
|
|
8
|
+
.addHelpText('after', `
|
|
9
|
+
Examples:
|
|
10
|
+
$ pal billing status Show current plan
|
|
11
|
+
$ pal billing plans Show available plans
|
|
12
|
+
$ pal billing activate XXXX-XXXX Activate a license key
|
|
13
|
+
$ pal billing deactivate Deactivate current license
|
|
14
|
+
$ pal billing checkout pro_monthly Open checkout in browser
|
|
15
|
+
`)
|
|
16
|
+
.action(() => { cmd.outputHelp(); });
|
|
17
|
+
|
|
18
|
+
cmd
|
|
19
|
+
.command('status')
|
|
20
|
+
.description('show current plan, expiry, and limits')
|
|
21
|
+
.action(async () => {
|
|
22
|
+
const plan = getActivePlan();
|
|
23
|
+
const badge = plan.key === 'free' ? chalk.gray('Free') :
|
|
24
|
+
plan.key === 'enterprise' ? chalk.magenta('Enterprise') :
|
|
25
|
+
chalk.yellow('Pro');
|
|
26
|
+
|
|
27
|
+
console.log(`\n Plan: ${badge} (${plan.name})`);
|
|
28
|
+
if (plan.price > 0) {
|
|
29
|
+
console.log(` Price: $${plan.price}/${plan.interval || 'mo'}${plan.perSeat ? ' per seat' : ''}`);
|
|
30
|
+
}
|
|
31
|
+
if (plan.expiresAt) {
|
|
32
|
+
console.log(` Expires: ${chalk.white(new Date(plan.expiresAt).toLocaleDateString())}`);
|
|
33
|
+
}
|
|
34
|
+
if (plan.source === 'expired') {
|
|
35
|
+
console.log(chalk.red(' License expired. Please renew.'));
|
|
36
|
+
}
|
|
37
|
+
if (plan.customerEmail) {
|
|
38
|
+
console.log(` Email: ${plan.customerEmail}`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
console.log(`\n ${chalk.cyan.bold('Limits:')}`);
|
|
42
|
+
for (const [k, v] of Object.entries(plan.limits)) {
|
|
43
|
+
const display = v === Infinity ? chalk.green('unlimited') : chalk.white(String(v));
|
|
44
|
+
console.log(` ${k}: ${display}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const enabled = Object.entries(plan.features).filter(([, v]) => v);
|
|
48
|
+
const disabled = Object.entries(plan.features).filter(([, v]) => !v);
|
|
49
|
+
if (enabled.length > 0) {
|
|
50
|
+
console.log(`\n ${chalk.green.bold('Enabled Features:')}`);
|
|
51
|
+
for (const [k] of enabled) {
|
|
52
|
+
console.log(` ${chalk.green('+')} ${k}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (disabled.length > 0) {
|
|
56
|
+
console.log(`\n ${chalk.gray('Disabled Features:')}`);
|
|
57
|
+
for (const [k] of disabled) {
|
|
58
|
+
console.log(` ${chalk.gray('-')} ${k}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
console.log();
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
cmd
|
|
65
|
+
.command('plans')
|
|
66
|
+
.description('show available plans with pricing')
|
|
67
|
+
.action(async () => {
|
|
68
|
+
console.log(`\n ${chalk.bold('Palexplorer Plans')}\n`);
|
|
69
|
+
|
|
70
|
+
const current = getActivePlan();
|
|
71
|
+
for (const [key, plan] of Object.entries(PLANS)) {
|
|
72
|
+
const isCurrent = key === current.key;
|
|
73
|
+
const marker = isCurrent ? chalk.green(' (current)') : '';
|
|
74
|
+
const price = plan.price === 0 ? 'Free' :
|
|
75
|
+
`$${plan.price}/${plan.interval || 'mo'}${plan.perSeat ? ' per seat' : ''}`;
|
|
76
|
+
|
|
77
|
+
console.log(` ${chalk.bold(plan.name)}${marker} — ${chalk.yellow(price)}`);
|
|
78
|
+
|
|
79
|
+
const highlights = [];
|
|
80
|
+
if (plan.limits.maxShares === Infinity) highlights.push('Unlimited shares');
|
|
81
|
+
else highlights.push(`${plan.limits.maxShares} shares`);
|
|
82
|
+
if (plan.limits.maxRecipients === Infinity) highlights.push('Unlimited recipients');
|
|
83
|
+
else highlights.push(`${plan.limits.maxRecipients} recipients`);
|
|
84
|
+
if (plan.limits.maxFileSize === Infinity) highlights.push('No file size limit');
|
|
85
|
+
else highlights.push(`${(plan.limits.maxFileSize / (1024 * 1024 * 1024)).toFixed(0)}GB max file`);
|
|
86
|
+
highlights.push(`${plan.limits.apiKeys} API keys`);
|
|
87
|
+
|
|
88
|
+
console.log(` ${chalk.gray(highlights.join(' | '))}`);
|
|
89
|
+
console.log();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
cmd
|
|
94
|
+
.command('activate <license-key>')
|
|
95
|
+
.description('activate a license key')
|
|
96
|
+
.action(async (key) => {
|
|
97
|
+
try {
|
|
98
|
+
console.log(chalk.gray('Activating license...'));
|
|
99
|
+
const result = await activateLicenseKey(key);
|
|
100
|
+
const plan = PLANS[result.plan];
|
|
101
|
+
console.log(chalk.green(`License activated! Plan: ${plan?.name || result.plan}`));
|
|
102
|
+
if (result.expiresAt) {
|
|
103
|
+
console.log(` Expires: ${new Date(result.expiresAt).toLocaleDateString()}`);
|
|
104
|
+
}
|
|
105
|
+
} catch (err) {
|
|
106
|
+
console.log(chalk.red(`Activation failed: ${err.message}`));
|
|
107
|
+
process.exitCode = 1;
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
cmd
|
|
112
|
+
.command('deactivate')
|
|
113
|
+
.description('deactivate current license')
|
|
114
|
+
.action(async () => {
|
|
115
|
+
try {
|
|
116
|
+
await deactivateLicenseKey();
|
|
117
|
+
console.log(chalk.green('License deactivated. Reverted to Free plan.'));
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.log(chalk.red(`Deactivation failed: ${err.message}`));
|
|
120
|
+
process.exitCode = 1;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
cmd
|
|
125
|
+
.command('checkout [plan]')
|
|
126
|
+
.description('open checkout URL in browser')
|
|
127
|
+
.addHelpText('after', '\nPlans: pro_monthly, pro_annual, enterprise')
|
|
128
|
+
.action(async (plan) => {
|
|
129
|
+
plan = plan || 'pro_monthly';
|
|
130
|
+
try {
|
|
131
|
+
const url = getCheckoutUrl(plan);
|
|
132
|
+
console.log(`\n Checkout URL: ${chalk.cyan(url)}`);
|
|
133
|
+
console.log(chalk.gray(' Opening in browser...'));
|
|
134
|
+
const { exec } = await import('child_process');
|
|
135
|
+
try {
|
|
136
|
+
const parsed = new URL(url);
|
|
137
|
+
if (parsed.protocol === 'https:') {
|
|
138
|
+
const cmd = process.platform === 'win32' ? `start "" "${parsed.href}"` :
|
|
139
|
+
process.platform === 'darwin' ? `open "${parsed.href}"` : `xdg-open "${parsed.href}"`;
|
|
140
|
+
exec(cmd);
|
|
141
|
+
}
|
|
142
|
+
} catch {}
|
|
143
|
+
} catch (err) {
|
|
144
|
+
console.log(chalk.red(err.message));
|
|
145
|
+
process.exitCode = 1;
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|