@tonk/cli 0.3.3 → 0.4.0
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 +15 -202
- package/bin/tonk.js +36 -1
- package/package.json +23 -89
- package/dist/commands/auth.d.ts +0 -3
- package/dist/commands/auth.d.ts.map +0 -1
- package/dist/commands/auth.js +0 -184
- package/dist/commands/auth.js.map +0 -1
- package/dist/commands/create.d.ts +0 -3
- package/dist/commands/create.d.ts.map +0 -1
- package/dist/commands/create.js +0 -55
- package/dist/commands/create.js.map +0 -1
- package/dist/commands/delete.d.ts +0 -3
- package/dist/commands/delete.d.ts.map +0 -1
- package/dist/commands/delete.js +0 -67
- package/dist/commands/delete.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -3
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js +0 -336
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/hello/index.d.ts +0 -3
- package/dist/commands/hello/index.d.ts.map +0 -1
- package/dist/commands/hello/index.js +0 -296
- package/dist/commands/hello/index.js.map +0 -1
- package/dist/commands/hello.d.ts +0 -3
- package/dist/commands/hello.d.ts.map +0 -1
- package/dist/commands/hello.js +0 -83
- package/dist/commands/hello.js.map +0 -1
- package/dist/commands/init.d.ts +0 -3
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -137
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/kill.d.ts +0 -3
- package/dist/commands/kill.d.ts.map +0 -1
- package/dist/commands/kill.js +0 -66
- package/dist/commands/kill.js.map +0 -1
- package/dist/commands/ls.d.ts +0 -3
- package/dist/commands/ls.d.ts.map +0 -1
- package/dist/commands/ls.js +0 -52
- package/dist/commands/ls.js.map +0 -1
- package/dist/commands/proxy.d.ts +0 -3
- package/dist/commands/proxy.d.ts.map +0 -1
- package/dist/commands/proxy.js +0 -86
- package/dist/commands/proxy.js.map +0 -1
- package/dist/commands/ps.d.ts +0 -3
- package/dist/commands/ps.d.ts.map +0 -1
- package/dist/commands/ps.js +0 -56
- package/dist/commands/ps.js.map +0 -1
- package/dist/commands/push.d.ts +0 -3
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -238
- package/dist/commands/push.js.map +0 -1
- package/dist/commands/server.d.ts +0 -3
- package/dist/commands/server.d.ts.map +0 -1
- package/dist/commands/server.js +0 -676
- package/dist/commands/server.js.map +0 -1
- package/dist/commands/start.d.ts +0 -3
- package/dist/commands/start.d.ts.map +0 -1
- package/dist/commands/start.js +0 -82
- package/dist/commands/start.js.map +0 -1
- package/dist/commands/worker/commands.d.ts +0 -42
- package/dist/commands/worker/commands.d.ts.map +0 -1
- package/dist/commands/worker/commands.js +0 -968
- package/dist/commands/worker/commands.js.map +0 -1
- package/dist/commands/worker/index.d.ts +0 -7
- package/dist/commands/worker/index.d.ts.map +0 -1
- package/dist/commands/worker/index.js +0 -30
- package/dist/commands/worker/index.js.map +0 -1
- package/dist/commands/worker/utils/config.d.ts +0 -26
- package/dist/commands/worker/utils/config.d.ts.map +0 -1
- package/dist/commands/worker/utils/config.js +0 -197
- package/dist/commands/worker/utils/config.js.map +0 -1
- package/dist/commands/worker/utils/display.d.ts +0 -6
- package/dist/commands/worker/utils/display.d.ts.map +0 -1
- package/dist/commands/worker/utils/display.js +0 -32
- package/dist/commands/worker/utils/display.js.map +0 -1
- package/dist/commands/worker/utils/finder.d.ts +0 -12
- package/dist/commands/worker/utils/finder.d.ts.map +0 -1
- package/dist/commands/worker/utils/finder.js +0 -60
- package/dist/commands/worker/utils/finder.js.map +0 -1
- package/dist/config/environment.d.ts +0 -52
- package/dist/config/environment.d.ts.map +0 -1
- package/dist/config/environment.js +0 -83
- package/dist/config/environment.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +0 -1
- package/dist/lib/tonkAuth.d.ts +0 -21
- package/dist/lib/tonkAuth.d.ts.map +0 -1
- package/dist/lib/tonkAuth.js +0 -140
- package/dist/lib/tonkAuth.js.map +0 -1
- package/dist/lib/workerManager.d.ts +0 -60
- package/dist/lib/workerManager.d.ts.map +0 -1
- package/dist/lib/workerManager.js +0 -417
- package/dist/lib/workerManager.js.map +0 -1
- package/dist/scripts/aws/create-key.sh +0 -20
- package/dist/scripts/aws/ec2-dns.sh +0 -20
- package/dist/scripts/aws/provision.sh +0 -93
- package/dist/tonk.d.ts +0 -2
- package/dist/tonk.d.ts.map +0 -1
- package/dist/tonk.js +0 -106
- package/dist/tonk.js.map +0 -1
- package/dist/types/worker.d.ts +0 -161
- package/dist/types/worker.d.ts.map +0 -1
- package/dist/types/worker.js +0 -7
- package/dist/types/worker.js.map +0 -1
- package/dist/types/workerConfig.d.ts +0 -164
- package/dist/types/workerConfig.d.ts.map +0 -1
- package/dist/types/workerConfig.js +0 -80
- package/dist/types/workerConfig.js.map +0 -1
- package/dist/utils/analytics.d.ts +0 -26
- package/dist/utils/analytics.d.ts.map +0 -1
- package/dist/utils/analytics.js +0 -218
- package/dist/utils/analytics.js.map +0 -1
- package/dist/utils/messages.d.ts +0 -6
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js +0 -18
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/serverUtils.d.ts +0 -5
- package/dist/utils/serverUtils.d.ts.map +0 -1
- package/dist/utils/serverUtils.js +0 -34
- package/dist/utils/serverUtils.js.map +0 -1
- package/dist/utils/version.d.ts +0 -2
- package/dist/utils/version.d.ts.map +0 -1
- package/dist/utils/version.js +0 -3
- package/dist/utils/version.js.map +0 -1
- package/scripts/aws/create-key.sh +0 -20
- package/scripts/aws/ec2-dns.sh +0 -20
- package/scripts/aws/provision.sh +0 -93
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,YAAY"}
|
package/dist/lib/tonkAuth.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
declare class TonkAuthManager {
|
|
2
|
-
private instance;
|
|
3
|
-
private initPromise;
|
|
4
|
-
private _isReady;
|
|
5
|
-
constructor();
|
|
6
|
-
private initialize;
|
|
7
|
-
get isSignedIn(): boolean;
|
|
8
|
-
get activeSubscription(): boolean;
|
|
9
|
-
get friendlyName(): string;
|
|
10
|
-
get isReady(): boolean;
|
|
11
|
-
ensureReady(): Promise<void>;
|
|
12
|
-
login(): Promise<any>;
|
|
13
|
-
logout(): Promise<any>;
|
|
14
|
-
getAuthToken(): Promise<string | null>;
|
|
15
|
-
destroy(): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
export declare const tonkAuth: TonkAuthManager;
|
|
18
|
-
export declare function checkAuth(): boolean;
|
|
19
|
-
export declare const authHook: () => Promise<void>;
|
|
20
|
-
export {};
|
|
21
|
-
//# sourceMappingURL=tonkAuth.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tonkAuth.d.ts","sourceRoot":"","sources":["../../src/lib/tonkAuth.ts"],"names":[],"mappings":"AAOA,cAAM,eAAe;IACnB,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,QAAQ,CAAS;;YAMX,UAAU;IA0BxB,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,KAAK;IAWL,MAAM;IAWN,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAYtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B;AAED,eAAO,MAAM,QAAQ,iBAAwB,CAAC;AAE9C,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED,eAAO,MAAM,QAAQ,qBAkEpB,CAAC"}
|
package/dist/lib/tonkAuth.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { RESPONSES } from '../utils/messages.js';
|
|
2
|
-
import { TonkAuth } from '@tonk/tonk-auth';
|
|
3
|
-
import chalk from 'chalk';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { shutdownAnalytics } from '../utils/analytics.js';
|
|
6
|
-
// TonkAuth wrapped in a Singleton class with (non-blocking) async initilization keeps the CLI load snappy 🐢
|
|
7
|
-
class TonkAuthManager {
|
|
8
|
-
instance = null;
|
|
9
|
-
initPromise = null;
|
|
10
|
-
_isReady = false;
|
|
11
|
-
constructor() {
|
|
12
|
-
this.initialize();
|
|
13
|
-
}
|
|
14
|
-
async initialize() {
|
|
15
|
-
if (this.initPromise)
|
|
16
|
-
return this.initPromise;
|
|
17
|
-
this.initPromise = TonkAuth({
|
|
18
|
-
onSubscriptionDisabled: () => {
|
|
19
|
-
console.log(chalk.red('🚨 Your subscription is inactive, upgrade your subscription to Deploy to Tonk'));
|
|
20
|
-
},
|
|
21
|
-
})
|
|
22
|
-
.then(auth => {
|
|
23
|
-
this.instance = auth;
|
|
24
|
-
this._isReady = true;
|
|
25
|
-
return auth;
|
|
26
|
-
})
|
|
27
|
-
.catch(error => {
|
|
28
|
-
console.error(chalk.red('Failed to initialize auth:'), error);
|
|
29
|
-
this._isReady = false;
|
|
30
|
-
return null;
|
|
31
|
-
});
|
|
32
|
-
return this.initPromise;
|
|
33
|
-
}
|
|
34
|
-
get isSignedIn() {
|
|
35
|
-
return this.instance?.isSignedIn ?? false;
|
|
36
|
-
}
|
|
37
|
-
get activeSubscription() {
|
|
38
|
-
return this.instance?.activeSubscription ?? false;
|
|
39
|
-
}
|
|
40
|
-
get friendlyName() {
|
|
41
|
-
return this.instance?.friendlyName ?? '';
|
|
42
|
-
}
|
|
43
|
-
get isReady() {
|
|
44
|
-
return this._isReady;
|
|
45
|
-
}
|
|
46
|
-
async ensureReady() {
|
|
47
|
-
if (!this._isReady && this.initPromise) {
|
|
48
|
-
await this.initPromise;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
async login() {
|
|
52
|
-
await this.ensureReady();
|
|
53
|
-
if (!this.instance)
|
|
54
|
-
return { ok: false, error: 'Auth not initialized' };
|
|
55
|
-
try {
|
|
56
|
-
return await this.instance.login();
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
return { ok: false, error: String(error) };
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
async logout() {
|
|
63
|
-
await this.ensureReady();
|
|
64
|
-
if (!this.instance)
|
|
65
|
-
return { ok: false, error: 'Auth not initialized' };
|
|
66
|
-
try {
|
|
67
|
-
return await this.instance.logout();
|
|
68
|
-
}
|
|
69
|
-
catch (error) {
|
|
70
|
-
return { ok: false, error: String(error) };
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async getAuthToken() {
|
|
74
|
-
await this.ensureReady();
|
|
75
|
-
if (!this.instance?.__session)
|
|
76
|
-
return null;
|
|
77
|
-
try {
|
|
78
|
-
return await this.instance.__session.getToken();
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
81
|
-
console.error('Failed to get auth token:', error);
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
async destroy() {
|
|
86
|
-
if (this.instance && typeof this.instance.destroy === 'function') {
|
|
87
|
-
this.instance.destroy();
|
|
88
|
-
}
|
|
89
|
-
await shutdownAnalytics();
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
export const tonkAuth = new TonkAuthManager();
|
|
93
|
-
export function checkAuth() {
|
|
94
|
-
return tonkAuth.isSignedIn && tonkAuth.activeSubscription;
|
|
95
|
-
}
|
|
96
|
-
export const authHook = async () => {
|
|
97
|
-
// Ensure auth is initialized
|
|
98
|
-
await tonkAuth.ensureReady();
|
|
99
|
-
if (checkAuth())
|
|
100
|
-
return;
|
|
101
|
-
// Check if user is signed in but doesn't have active subscription
|
|
102
|
-
if (tonkAuth.isSignedIn && !tonkAuth.activeSubscription) {
|
|
103
|
-
console.log(chalk.yellow(RESPONSES.needSubscription));
|
|
104
|
-
console.log(chalk.yellow('Please upgrade your subscription to use Tonk hosting features.'));
|
|
105
|
-
await tonkAuth.destroy();
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
// User is not signed in at all
|
|
109
|
-
if (!tonkAuth.isSignedIn) {
|
|
110
|
-
console.log(chalk.yellow('You need to be signed in to use Tonk hosting features.'));
|
|
111
|
-
const { confirm } = await inquirer.prompt([
|
|
112
|
-
{
|
|
113
|
-
type: 'confirm',
|
|
114
|
-
name: 'confirm',
|
|
115
|
-
message: 'Do you want to login?',
|
|
116
|
-
default: true,
|
|
117
|
-
},
|
|
118
|
-
]);
|
|
119
|
-
if (!confirm) {
|
|
120
|
-
console.log(chalk.yellow('Authentication required. Exiting.'));
|
|
121
|
-
await tonkAuth.destroy();
|
|
122
|
-
process.exit(1);
|
|
123
|
-
}
|
|
124
|
-
console.log("\n🗺️ Great, let's sign you in using your browser!");
|
|
125
|
-
const res = await tonkAuth.login();
|
|
126
|
-
if (!res.ok) {
|
|
127
|
-
console.error(chalk.red(`Failed to login to Tonk: ${res.error || 'Unknown error'}`));
|
|
128
|
-
await tonkAuth.destroy();
|
|
129
|
-
process.exit(1);
|
|
130
|
-
}
|
|
131
|
-
console.log(chalk.green(`🎉 Welcome back to Tonk ${tonkAuth.friendlyName || 'user'}!\n`));
|
|
132
|
-
// Check subscription status after login
|
|
133
|
-
if (!tonkAuth.activeSubscription) {
|
|
134
|
-
console.log(chalk.yellow('Please upgrade your subscription to use Tonk hosting features.'));
|
|
135
|
-
await tonkAuth.destroy();
|
|
136
|
-
process.exit(1);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
//# sourceMappingURL=tonkAuth.js.map
|
package/dist/lib/tonkAuth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tonkAuth.js","sourceRoot":"","sources":["../../src/lib/tonkAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { Worker, WorkerManager, WorkerRegistrationOptions } from '../types/worker.js';
|
|
2
|
-
/**
|
|
3
|
-
* Implementation of the WorkerManager interface
|
|
4
|
-
*/
|
|
5
|
-
export declare class TonkWorkerManager implements WorkerManager {
|
|
6
|
-
private workersPath;
|
|
7
|
-
constructor();
|
|
8
|
-
/**
|
|
9
|
-
* Register a new worker
|
|
10
|
-
*/
|
|
11
|
-
register(options: WorkerRegistrationOptions): Promise<Worker>;
|
|
12
|
-
/**
|
|
13
|
-
* Register a worker from a YAML configuration file
|
|
14
|
-
*/
|
|
15
|
-
registerFromYamlConfig(yamlConfig: any): Promise<Worker>;
|
|
16
|
-
/**
|
|
17
|
-
* Get a worker by ID
|
|
18
|
-
*/
|
|
19
|
-
get(id: string): Promise<Worker | null>;
|
|
20
|
-
/**
|
|
21
|
-
* Find a worker by name or ID
|
|
22
|
-
* If the identifier matches an ID exactly, returns that worker
|
|
23
|
-
* Otherwise, searches for a worker with a matching name
|
|
24
|
-
*/
|
|
25
|
-
findByNameOrId(identifier: string): Promise<Worker | null>;
|
|
26
|
-
/**
|
|
27
|
-
* List all registered workers
|
|
28
|
-
*/
|
|
29
|
-
list(): Promise<Worker[]>;
|
|
30
|
-
/**
|
|
31
|
-
* Update a worker
|
|
32
|
-
*/
|
|
33
|
-
update(id: string, updates: Partial<Worker>): Promise<Worker>;
|
|
34
|
-
/**
|
|
35
|
-
* Remove a worker
|
|
36
|
-
*/
|
|
37
|
-
remove(id: string): Promise<boolean>;
|
|
38
|
-
/**
|
|
39
|
-
* Start a worker
|
|
40
|
-
* @param id Worker ID to start
|
|
41
|
-
*/
|
|
42
|
-
start(id: string): Promise<boolean>;
|
|
43
|
-
/**
|
|
44
|
-
* Stop a worker
|
|
45
|
-
*/
|
|
46
|
-
stop(id: string): Promise<boolean>;
|
|
47
|
-
/**
|
|
48
|
-
* Check worker health
|
|
49
|
-
*/
|
|
50
|
-
checkHealth(id: string): Promise<boolean>;
|
|
51
|
-
/**
|
|
52
|
-
* Generate a worker ID
|
|
53
|
-
*/
|
|
54
|
-
private generateWorkerId;
|
|
55
|
-
/**
|
|
56
|
-
* Perform HTTP health check
|
|
57
|
-
*/
|
|
58
|
-
private httpHealthCheck;
|
|
59
|
-
}
|
|
60
|
-
//# sourceMappingURL=workerManager.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"workerManager.d.ts","sourceRoot":"","sources":["../../src/lib/workerManager.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,MAAM,EACN,aAAa,EACb,yBAAyB,EAC1B,MAAM,oBAAoB,CAAC;AAM5B;;GAEG;AACH,qBAAa,iBAAkB,YAAW,aAAa;IACrD,OAAO,CAAC,WAAW,CAAS;;IAc5B;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CnE;;OAEG;IACG,sBAAsB,CAAC,UAAU,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAiC9D;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAW7C;;;;OAIG;IACG,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgBhE;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAgB/B;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBnE;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAoC1C;;;OAGG;IACG,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuHzC;;OAEG;IACG,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAqCxC;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgE/C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACH,OAAO,CAAC,eAAe;CA0BxB"}
|
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import envPaths from 'env-paths';
|
|
4
|
-
import http from 'node:http';
|
|
5
|
-
import https from 'node:https';
|
|
6
|
-
import { exec } from 'node:child_process';
|
|
7
|
-
import { promisify } from 'node:util';
|
|
8
|
-
/**
|
|
9
|
-
* Implementation of the WorkerManager interface
|
|
10
|
-
*/
|
|
11
|
-
export class TonkWorkerManager {
|
|
12
|
-
workersPath;
|
|
13
|
-
constructor() {
|
|
14
|
-
// Create paths for Tonk daemon home
|
|
15
|
-
const paths = envPaths('tonk', { suffix: '' });
|
|
16
|
-
const tonkHome = paths.data;
|
|
17
|
-
this.workersPath = path.join(tonkHome, 'workers');
|
|
18
|
-
// Ensure workers directory exists
|
|
19
|
-
if (!fs.existsSync(this.workersPath)) {
|
|
20
|
-
fs.mkdirSync(this.workersPath, { recursive: true });
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Register a new worker
|
|
25
|
-
*/
|
|
26
|
-
async register(options) {
|
|
27
|
-
// Generate a unique ID for the worker
|
|
28
|
-
const workerId = this.generateWorkerId(options.name);
|
|
29
|
-
// Parse environment variables
|
|
30
|
-
const env = {};
|
|
31
|
-
if (options.env && Array.isArray(options.env)) {
|
|
32
|
-
options.env.forEach((envVar) => {
|
|
33
|
-
const [key, value] = envVar.split('=');
|
|
34
|
-
if (key && value) {
|
|
35
|
-
env[key] = value;
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
const workerConfig = {
|
|
40
|
-
...(options.config && typeof options.config === 'object'
|
|
41
|
-
? options.config
|
|
42
|
-
: {}),
|
|
43
|
-
type: options.type || 'custom',
|
|
44
|
-
};
|
|
45
|
-
// Create worker object
|
|
46
|
-
const worker = {
|
|
47
|
-
id: workerId,
|
|
48
|
-
name: options.name,
|
|
49
|
-
description: options.description || '',
|
|
50
|
-
endpoint: options.endpoint,
|
|
51
|
-
protocol: options.protocol || 'http',
|
|
52
|
-
status: {
|
|
53
|
-
active: false,
|
|
54
|
-
lastSeen: null,
|
|
55
|
-
},
|
|
56
|
-
env,
|
|
57
|
-
config: workerConfig,
|
|
58
|
-
createdAt: Date.now(),
|
|
59
|
-
updatedAt: Date.now(),
|
|
60
|
-
};
|
|
61
|
-
// Save worker to file
|
|
62
|
-
const workerFilePath = path.join(this.workersPath, `${workerId}.json`);
|
|
63
|
-
fs.writeFileSync(workerFilePath, JSON.stringify(worker, null, 2));
|
|
64
|
-
return worker;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Register a worker from a YAML configuration file
|
|
68
|
-
*/
|
|
69
|
-
async registerFromYamlConfig(yamlConfig) {
|
|
70
|
-
// Generate a unique ID for the worker
|
|
71
|
-
const workerId = this.generateWorkerId(yamlConfig.name);
|
|
72
|
-
// Create worker object from YAML config
|
|
73
|
-
const worker = {
|
|
74
|
-
id: workerId,
|
|
75
|
-
name: yamlConfig.name,
|
|
76
|
-
description: yamlConfig.description || '',
|
|
77
|
-
endpoint: yamlConfig.endpoint,
|
|
78
|
-
protocol: yamlConfig.protocol || 'http',
|
|
79
|
-
status: {
|
|
80
|
-
active: false,
|
|
81
|
-
lastSeen: null,
|
|
82
|
-
},
|
|
83
|
-
env: yamlConfig.process?.env || {},
|
|
84
|
-
config: {
|
|
85
|
-
type: yamlConfig.type || 'custom',
|
|
86
|
-
version: yamlConfig.version,
|
|
87
|
-
healthCheck: yamlConfig.healthCheck,
|
|
88
|
-
process: yamlConfig.process,
|
|
89
|
-
...yamlConfig.config,
|
|
90
|
-
},
|
|
91
|
-
createdAt: Date.now(),
|
|
92
|
-
updatedAt: Date.now(),
|
|
93
|
-
};
|
|
94
|
-
// Save worker to file
|
|
95
|
-
const workerFilePath = path.join(this.workersPath, `${workerId}.json`);
|
|
96
|
-
fs.writeFileSync(workerFilePath, JSON.stringify(worker, null, 2));
|
|
97
|
-
return worker;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Get a worker by ID
|
|
101
|
-
*/
|
|
102
|
-
async get(id) {
|
|
103
|
-
const workerFilePath = path.join(this.workersPath, `${id}.json`);
|
|
104
|
-
if (!fs.existsSync(workerFilePath)) {
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
const fileContent = fs.readFileSync(workerFilePath, 'utf-8');
|
|
108
|
-
return JSON.parse(fileContent);
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Find a worker by name or ID
|
|
112
|
-
* If the identifier matches an ID exactly, returns that worker
|
|
113
|
-
* Otherwise, searches for a worker with a matching name
|
|
114
|
-
*/
|
|
115
|
-
async findByNameOrId(identifier) {
|
|
116
|
-
// First try to get by ID (exact match)
|
|
117
|
-
const workerById = await this.get(identifier);
|
|
118
|
-
if (workerById) {
|
|
119
|
-
return workerById;
|
|
120
|
-
}
|
|
121
|
-
// If not found by ID, try to find by name
|
|
122
|
-
const workers = await this.list();
|
|
123
|
-
const matchingWorker = workers.find(worker => worker.name.toLowerCase() === identifier.toLowerCase());
|
|
124
|
-
return matchingWorker || null;
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* List all registered workers
|
|
128
|
-
*/
|
|
129
|
-
async list() {
|
|
130
|
-
const workerFiles = fs
|
|
131
|
-
.readdirSync(this.workersPath)
|
|
132
|
-
.filter(file => file.endsWith('.json'));
|
|
133
|
-
if (workerFiles.length === 0) {
|
|
134
|
-
return [];
|
|
135
|
-
}
|
|
136
|
-
return workerFiles.map(file => {
|
|
137
|
-
const filePath = path.join(this.workersPath, file);
|
|
138
|
-
const fileContent = fs.readFileSync(filePath, 'utf-8');
|
|
139
|
-
return JSON.parse(fileContent);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Update a worker
|
|
144
|
-
*/
|
|
145
|
-
async update(id, updates) {
|
|
146
|
-
const worker = await this.get(id);
|
|
147
|
-
if (!worker) {
|
|
148
|
-
throw new Error(`Worker with ID '${id}' not found.`);
|
|
149
|
-
}
|
|
150
|
-
// Update worker properties
|
|
151
|
-
const updatedWorker = {
|
|
152
|
-
...worker,
|
|
153
|
-
...updates,
|
|
154
|
-
updatedAt: Date.now(),
|
|
155
|
-
};
|
|
156
|
-
// Save updated worker
|
|
157
|
-
const workerFilePath = path.join(this.workersPath, `${id}.json`);
|
|
158
|
-
fs.writeFileSync(workerFilePath, JSON.stringify(updatedWorker, null, 2));
|
|
159
|
-
return updatedWorker;
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Remove a worker
|
|
163
|
-
*/
|
|
164
|
-
async remove(id) {
|
|
165
|
-
const workerFilePath = path.join(this.workersPath, `${id}.json`);
|
|
166
|
-
if (!fs.existsSync(workerFilePath)) {
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
// Get worker details before removing
|
|
170
|
-
const worker = await this.get(id);
|
|
171
|
-
if (!worker) {
|
|
172
|
-
return false;
|
|
173
|
-
}
|
|
174
|
-
// Try to stop and delete from PM2 if it's running
|
|
175
|
-
const execAsync = promisify(exec);
|
|
176
|
-
try {
|
|
177
|
-
// Check if worker is running in PM2
|
|
178
|
-
const { stdout } = await execAsync('pm2 list');
|
|
179
|
-
if (stdout.includes(`${worker.id}`)) {
|
|
180
|
-
// Stop the worker with PM2 first
|
|
181
|
-
await execAsync(`pm2 stop ${worker.id}`);
|
|
182
|
-
// Then delete it from PM2
|
|
183
|
-
await execAsync(`pm2 delete ${worker.id}`);
|
|
184
|
-
console.log(`Worker '${worker.name}' stopped and removed from PM2.`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
console.error(`Error stopping worker in PM2:`, error);
|
|
189
|
-
// Continue with removal even if PM2 operations fail
|
|
190
|
-
}
|
|
191
|
-
// Remove worker file
|
|
192
|
-
fs.unlinkSync(workerFilePath);
|
|
193
|
-
return true;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Start a worker
|
|
197
|
-
* @param id Worker ID to start
|
|
198
|
-
*/
|
|
199
|
-
async start(id) {
|
|
200
|
-
const worker = await this.get(id);
|
|
201
|
-
if (!worker) {
|
|
202
|
-
throw new Error(`Worker with ID '${id}' not found.`);
|
|
203
|
-
}
|
|
204
|
-
const execAsync = promisify(exec);
|
|
205
|
-
try {
|
|
206
|
-
// Check if worker is already running in PM2
|
|
207
|
-
const { stdout } = await execAsync('pm2 list');
|
|
208
|
-
if (stdout.includes(`${worker.id}`)) {
|
|
209
|
-
console.log(`Worker '${worker.name}' is already running. Restarting...`);
|
|
210
|
-
await execAsync(`pm2 restart ${worker.id}`);
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
// Prepare environment variables
|
|
214
|
-
const envVars = Object.entries(worker.env)
|
|
215
|
-
.map(([key, value]) => `${key}=${value}`)
|
|
216
|
-
.join(' ');
|
|
217
|
-
// Ensure log directory exists
|
|
218
|
-
const logDir = envPaths('tonk', { suffix: '' }).log;
|
|
219
|
-
if (!fs.existsSync(logDir)) {
|
|
220
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
221
|
-
}
|
|
222
|
-
// Add log configuration
|
|
223
|
-
const logConfig = `--log ${path.join(logDir, `${worker.id}.log`)}`;
|
|
224
|
-
const errorLogConfig = `--error ${path.join(logDir, `${worker.id}-error.log`)}`;
|
|
225
|
-
// Handle different worker types
|
|
226
|
-
if (worker.config.type === 'npm') {
|
|
227
|
-
// For npm-based workers, we directly use the package name as the command
|
|
228
|
-
const packageName = worker.name;
|
|
229
|
-
// Strip scope from package name for display purposes (e.g., @tonk/worker -> worker)
|
|
230
|
-
const commandName = packageName.replace(/^@[^/]+\//, '');
|
|
231
|
-
try {
|
|
232
|
-
// Start the npm package with PM2 using the package name as the command
|
|
233
|
-
// and 'start' as the argument
|
|
234
|
-
const startCmd = `${envVars} pm2 start "${commandName} start" --name ${worker.id} ${logConfig} ${errorLogConfig}`;
|
|
235
|
-
await execAsync(startCmd);
|
|
236
|
-
console.log(`Started npm worker '${packageName}' with command: ${commandName} start`);
|
|
237
|
-
}
|
|
238
|
-
catch (error) {
|
|
239
|
-
console.error(`Error starting npm worker:`, error);
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
// For traditional workers with process configuration
|
|
245
|
-
if (!worker.config.process || !worker.config.process.file) {
|
|
246
|
-
throw new Error(`Worker '${worker.name}' does not have a valid process configuration.`);
|
|
247
|
-
}
|
|
248
|
-
// Start the worker with PM2
|
|
249
|
-
const cwd = worker.config.process.cwd || '.';
|
|
250
|
-
const instances = worker.config.process.instances || 1;
|
|
251
|
-
const watch = worker.config.process.watch ? '--watch' : '';
|
|
252
|
-
const maxMemory = worker.config.process.max_memory_restart
|
|
253
|
-
? `--max-memory-restart ${worker.config.process.max_memory_restart}`
|
|
254
|
-
: '';
|
|
255
|
-
// Prepare the command to start the worker
|
|
256
|
-
let startCmd = '';
|
|
257
|
-
// Ensure we have a valid file path
|
|
258
|
-
if (!worker.config.process.file ||
|
|
259
|
-
worker.config.process.file.trim() === '') {
|
|
260
|
-
throw new Error(`Worker '${worker.name}' has an empty file path.`);
|
|
261
|
-
}
|
|
262
|
-
const filePath = worker.config.process.file;
|
|
263
|
-
const args = worker.config.process.args || '';
|
|
264
|
-
// Check if the file path is relative or absolute
|
|
265
|
-
const absoluteFilePath = path.join(cwd, filePath);
|
|
266
|
-
// Make the file executable if it exists
|
|
267
|
-
if (fs.existsSync(absoluteFilePath)) {
|
|
268
|
-
// First make the file executable, then start it with PM2
|
|
269
|
-
startCmd = `cd ${cwd} && chmod +x "${filePath}" && ${envVars} pm2 start "./${filePath} ${args ? args : ''}" --name ${worker.id} --instances ${instances} ${watch} ${maxMemory} ${logConfig} ${errorLogConfig}`;
|
|
270
|
-
}
|
|
271
|
-
await execAsync(startCmd);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
// Update worker status
|
|
275
|
-
await this.update(id, {
|
|
276
|
-
status: {
|
|
277
|
-
active: true,
|
|
278
|
-
lastSeen: Date.now(),
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
return true;
|
|
282
|
-
}
|
|
283
|
-
catch (error) {
|
|
284
|
-
console.error(`Error starting worker '${worker.name}':`, error);
|
|
285
|
-
// Log detailed error information
|
|
286
|
-
if (error instanceof Error) {
|
|
287
|
-
console.error(`Error message: ${error.message}`);
|
|
288
|
-
console.error(`Stack trace: ${error.stack}`);
|
|
289
|
-
}
|
|
290
|
-
return false;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Stop a worker
|
|
295
|
-
*/
|
|
296
|
-
async stop(id) {
|
|
297
|
-
const worker = await this.get(id);
|
|
298
|
-
if (!worker) {
|
|
299
|
-
throw new Error(`Worker with ID '${id}' not found.`);
|
|
300
|
-
}
|
|
301
|
-
const execAsync = promisify(exec);
|
|
302
|
-
try {
|
|
303
|
-
console.log(`Stopping worker '${worker.name}'...`);
|
|
304
|
-
// Check if worker is running in PM2
|
|
305
|
-
const { stdout } = await execAsync('pm2 list');
|
|
306
|
-
if (stdout.includes(`${worker.id}`)) {
|
|
307
|
-
// Stop the worker with PM2
|
|
308
|
-
await execAsync(`pm2 stop ${worker.id}`);
|
|
309
|
-
}
|
|
310
|
-
else {
|
|
311
|
-
console.log(`Worker '${worker.name}' is not running.`);
|
|
312
|
-
}
|
|
313
|
-
// Update worker status
|
|
314
|
-
await this.update(id, {
|
|
315
|
-
status: {
|
|
316
|
-
active: false,
|
|
317
|
-
lastSeen: worker.status.lastSeen,
|
|
318
|
-
},
|
|
319
|
-
});
|
|
320
|
-
return true;
|
|
321
|
-
}
|
|
322
|
-
catch (error) {
|
|
323
|
-
console.error(`Error stopping worker:`, error);
|
|
324
|
-
return false;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Check worker health
|
|
329
|
-
*/
|
|
330
|
-
async checkHealth(id) {
|
|
331
|
-
const worker = await this.get(id);
|
|
332
|
-
if (!worker) {
|
|
333
|
-
throw new Error(`Worker with ID '${id}' not found.`);
|
|
334
|
-
}
|
|
335
|
-
// Extract base URL from worker endpoint and combine with health check endpoint
|
|
336
|
-
let healthCheckEndpoint;
|
|
337
|
-
if (worker.config.runtime?.healthCheck?.endpoint) {
|
|
338
|
-
// Parse the worker endpoint to get the base URL (protocol + host + port)
|
|
339
|
-
const workerUrl = new URL(worker.endpoint);
|
|
340
|
-
const baseUrl = `${workerUrl.protocol}//${workerUrl.host}`;
|
|
341
|
-
healthCheckEndpoint =
|
|
342
|
-
baseUrl + worker.config.runtime.healthCheck.endpoint;
|
|
343
|
-
}
|
|
344
|
-
else {
|
|
345
|
-
// If no health check configured, just use the worker endpoint
|
|
346
|
-
healthCheckEndpoint = worker.endpoint;
|
|
347
|
-
}
|
|
348
|
-
const healthCheckTimeout = worker.config.runtime?.healthCheck?.timeout || 5000;
|
|
349
|
-
try {
|
|
350
|
-
// Perform health check based on protocol
|
|
351
|
-
if (worker.protocol === 'http' || worker.protocol === 'https') {
|
|
352
|
-
const isHealthy = await this.httpHealthCheck(healthCheckEndpoint, worker.protocol, healthCheckTimeout);
|
|
353
|
-
// Update worker status
|
|
354
|
-
await this.update(id, {
|
|
355
|
-
status: {
|
|
356
|
-
active: isHealthy,
|
|
357
|
-
lastSeen: isHealthy ? Date.now() : worker.status.lastSeen,
|
|
358
|
-
},
|
|
359
|
-
});
|
|
360
|
-
return isHealthy;
|
|
361
|
-
}
|
|
362
|
-
// For other protocols, we'll need to implement specific health checks
|
|
363
|
-
// For now, just return false for unsupported protocols
|
|
364
|
-
console.log(`Health check for protocol '${worker.protocol}' not implemented.`);
|
|
365
|
-
return false;
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
console.error(`Error checking worker health:`, error);
|
|
369
|
-
// Update worker status to inactive
|
|
370
|
-
await this.update(id, {
|
|
371
|
-
status: {
|
|
372
|
-
active: false,
|
|
373
|
-
lastSeen: worker.status.lastSeen,
|
|
374
|
-
},
|
|
375
|
-
});
|
|
376
|
-
return false;
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
/**
|
|
380
|
-
* Generate a worker ID
|
|
381
|
-
*/
|
|
382
|
-
generateWorkerId(name) {
|
|
383
|
-
// Normalize the name: lowercase and replace non-alphanumeric chars with hyphens
|
|
384
|
-
let normalizedName = name.toLowerCase().replace(/[^a-z0-9]/g, '-');
|
|
385
|
-
// Ensure the name doesn't start with a hyphen (would cause issues with PM2)
|
|
386
|
-
normalizedName = normalizedName.replace(/^-+/, '');
|
|
387
|
-
// If after normalization the name is empty, use a default prefix
|
|
388
|
-
if (!normalizedName) {
|
|
389
|
-
normalizedName = 'worker';
|
|
390
|
-
}
|
|
391
|
-
const timestamp = Date.now().toString(36);
|
|
392
|
-
return `${normalizedName}-${timestamp}`;
|
|
393
|
-
}
|
|
394
|
-
/**
|
|
395
|
-
* Perform HTTP health check
|
|
396
|
-
*/
|
|
397
|
-
httpHealthCheck(endpoint, protocol, timeout) {
|
|
398
|
-
return new Promise(resolve => {
|
|
399
|
-
const client = protocol === 'https' ? https : http;
|
|
400
|
-
const req = client.get(endpoint, res => {
|
|
401
|
-
// Consider 2xx status codes as healthy
|
|
402
|
-
const isHealthy = res.statusCode !== undefined &&
|
|
403
|
-
res.statusCode >= 200 &&
|
|
404
|
-
res.statusCode < 300;
|
|
405
|
-
resolve(isHealthy);
|
|
406
|
-
});
|
|
407
|
-
req.on('error', () => {
|
|
408
|
-
resolve(false);
|
|
409
|
-
});
|
|
410
|
-
req.setTimeout(timeout, () => {
|
|
411
|
-
req.destroy();
|
|
412
|
-
resolve(false);
|
|
413
|
-
});
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
//# sourceMappingURL=workerManager.js.map
|