@token-dashboard/typeless-usage-uploader 0.1.0 → 0.1.1
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 +10 -0
- package/dist/cli.js +58 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,16 @@ typeless-usage-uploader status
|
|
|
15
15
|
typeless-usage-uploader logs
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
+
`init` 默认会询问是否登录后自动启动;也可以用参数显式控制:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
typeless-usage-uploader init --backend-url http://localhost:8086 --auto-start
|
|
22
|
+
typeless-usage-uploader init --backend-url http://localhost:8086 --no-auto-start
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
如果之前开启了登录自动启动,重新执行 `init --no-auto-start` 会保存配置、移除
|
|
26
|
+
`~/Library/LaunchAgents` 下的自启动 plist,并重启当前后台服务。
|
|
27
|
+
|
|
18
28
|
开发环境:
|
|
19
29
|
|
|
20
30
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import readline from 'node:readline/promises';
|
|
4
|
+
import { stdin as input, stdout as output } from 'node:process';
|
|
3
5
|
import { fileURLToPath } from 'node:url';
|
|
4
6
|
import { TypelessUsageUploader } from './collector.js';
|
|
5
7
|
import {
|
|
@@ -15,7 +17,7 @@ import { StateDb } from './state-db.js';
|
|
|
15
17
|
const HELP_TEXT = `${PRODUCT_NAME}
|
|
16
18
|
|
|
17
19
|
Usage:
|
|
18
|
-
${CLI_NAME} init [--backend-url <url>] [--interval 300] [--yes]
|
|
20
|
+
${CLI_NAME} init [--backend-url <url>] [--interval 300] [--yes] [--auto-start|--no-auto-start]
|
|
19
21
|
${CLI_NAME} clear [--yes]
|
|
20
22
|
${CLI_NAME} start
|
|
21
23
|
${CLI_NAME} stop
|
|
@@ -31,6 +33,8 @@ Common options:
|
|
|
31
33
|
--typeless-db <path> Typeless typeless.db path
|
|
32
34
|
--typeless-storage <path> Typeless app-storage.json path
|
|
33
35
|
--state-db <path> Local SQLite state DB path
|
|
36
|
+
--auto-start Start automatically when you log in
|
|
37
|
+
--no-auto-start Do not start automatically when you log in
|
|
34
38
|
--yes Skip interactive prompts
|
|
35
39
|
--lines <n> Number of log lines for service logs
|
|
36
40
|
-h, --help Show help
|
|
@@ -44,6 +48,7 @@ class CliOperationalError extends Error {
|
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
export const cliDeps = {
|
|
51
|
+
promptConfirm,
|
|
47
52
|
createUploader(runtime) {
|
|
48
53
|
return new TypelessUsageUploader({
|
|
49
54
|
stateDbPath: runtime.stateDbPath,
|
|
@@ -82,6 +87,14 @@ export function parseCliArgs(argv) {
|
|
|
82
87
|
options.yes = true;
|
|
83
88
|
continue;
|
|
84
89
|
}
|
|
90
|
+
if (token === '--auto-start') {
|
|
91
|
+
options.autoStartOnLogin = true;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (token === '--no-auto-start') {
|
|
95
|
+
options.autoStartOnLogin = false;
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
85
98
|
|
|
86
99
|
const [key, inlineValue] = token.split('=', 2);
|
|
87
100
|
const takesValue = new Set([
|
|
@@ -152,6 +165,9 @@ function runtimeOverrides(options) {
|
|
|
152
165
|
overrides.typelessStoragePath = options.typelessStoragePath;
|
|
153
166
|
}
|
|
154
167
|
if (options.stateDbPath !== undefined) overrides.stateDbPath = options.stateDbPath;
|
|
168
|
+
if (options.autoStartOnLogin !== undefined) {
|
|
169
|
+
overrides.autoStartOnLogin = options.autoStartOnLogin;
|
|
170
|
+
}
|
|
155
171
|
return overrides;
|
|
156
172
|
}
|
|
157
173
|
|
|
@@ -159,7 +175,42 @@ function printHelp() {
|
|
|
159
175
|
console.log(HELP_TEXT);
|
|
160
176
|
}
|
|
161
177
|
|
|
178
|
+
async function promptValue(label, defaultValue) {
|
|
179
|
+
const rl = readline.createInterface({ input, output });
|
|
180
|
+
try {
|
|
181
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : '';
|
|
182
|
+
const answer = (await rl.question(`${label}${suffix}: `)).trim();
|
|
183
|
+
return answer || defaultValue || null;
|
|
184
|
+
} finally {
|
|
185
|
+
rl.close();
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function promptConfirm(label, defaultYes = false) {
|
|
190
|
+
const defaultValue = defaultYes ? 'y' : 'n';
|
|
191
|
+
const answer = await promptValue(
|
|
192
|
+
`${label} (${defaultYes ? 'Y/n' : 'y/N'})`,
|
|
193
|
+
defaultValue,
|
|
194
|
+
);
|
|
195
|
+
return /^(y|yes)$/i.test(String(answer ?? '').trim());
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
async function resolveAutoStartOnLogin(runtime, options) {
|
|
199
|
+
if (options.autoStartOnLogin !== undefined) {
|
|
200
|
+
return options.autoStartOnLogin;
|
|
201
|
+
}
|
|
202
|
+
if (options.yes) {
|
|
203
|
+
return runtime.autoStartOnLogin;
|
|
204
|
+
}
|
|
205
|
+
return cliDeps.promptConfirm(
|
|
206
|
+
'Start automatically when you log in on this Mac?',
|
|
207
|
+
runtime.autoStartOnLogin,
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
162
211
|
function currentEntryFile() {
|
|
212
|
+
const distBin = fileURLToPath(new URL('./bin/typeless-usage-uploader.js', import.meta.url));
|
|
213
|
+
if (fs.existsSync(distBin)) return distBin;
|
|
163
214
|
return fileURLToPath(new URL('../bin/typeless-usage-uploader.js', import.meta.url));
|
|
164
215
|
}
|
|
165
216
|
|
|
@@ -168,6 +219,7 @@ async function runInit(options) {
|
|
|
168
219
|
if (!overrides.backendUrl) overrides.backendUrl = DEFAULT_BACKEND_URL;
|
|
169
220
|
let runtime = mergeRuntimeConfig(options.configFile, overrides);
|
|
170
221
|
runtime.entryFile = currentEntryFile();
|
|
222
|
+
runtime.autoStartOnLogin = await resolveAutoStartOnLogin(runtime, options);
|
|
171
223
|
runtime = saveRuntimeConfig(runtime);
|
|
172
224
|
|
|
173
225
|
const uploader = cliDeps.createUploader(runtime);
|
|
@@ -179,6 +231,11 @@ async function runInit(options) {
|
|
|
179
231
|
try {
|
|
180
232
|
manager.start();
|
|
181
233
|
console.log(`${PRODUCT_NAME} initialized and started.`);
|
|
234
|
+
console.log(
|
|
235
|
+
runtime.autoStartOnLogin
|
|
236
|
+
? 'Login auto-start is enabled.'
|
|
237
|
+
: 'Login auto-start is disabled for future logins.',
|
|
238
|
+
);
|
|
182
239
|
} catch (error) {
|
|
183
240
|
console.log(`${PRODUCT_NAME} initialized. Service start skipped: ${error instanceof Error ? error.message : String(error)}`);
|
|
184
241
|
}
|