scanwarp 0.1.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/dist/api.js ADDED
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ScanWarpAPI = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ class ScanWarpAPI {
9
+ client;
10
+ serverUrl;
11
+ constructor(serverUrl = 'http://localhost:3000') {
12
+ this.serverUrl = serverUrl;
13
+ this.client = axios_1.default.create({
14
+ baseURL: serverUrl,
15
+ timeout: 10000,
16
+ headers: {
17
+ 'Content-Type': 'application/json',
18
+ },
19
+ });
20
+ }
21
+ async createProject(name) {
22
+ try {
23
+ // Check if project exists
24
+ const { data: existing } = await this.client.get('/projects', {
25
+ params: { name },
26
+ });
27
+ if (existing && existing.length > 0) {
28
+ return { id: existing[0].id };
29
+ }
30
+ }
31
+ catch {
32
+ // Project doesn't exist, will create
33
+ }
34
+ const { data } = await this.client.post('/projects', { name });
35
+ return data;
36
+ }
37
+ async createMonitor(projectId, url) {
38
+ const { data } = await this.client.post('/monitors', {
39
+ project_id: projectId,
40
+ url,
41
+ check_interval_seconds: 60,
42
+ });
43
+ return data.monitor;
44
+ }
45
+ async testConnection() {
46
+ try {
47
+ const { data } = await this.client.get('/health');
48
+ return data.status === 'ok';
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ async getWebhookUrl(path) {
55
+ return `${this.serverUrl}${path}`;
56
+ }
57
+ }
58
+ exports.ScanWarpAPI = ScanWarpAPI;
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initCommand = initCommand;
7
+ const inquirer_1 = __importDefault(require("inquirer"));
8
+ const chalk_1 = __importDefault(require("chalk"));
9
+ const ora_1 = __importDefault(require("ora"));
10
+ const detector_js_1 = require("../detector.js");
11
+ const api_js_1 = require("../api.js");
12
+ const vercel_js_1 = require("../integrations/vercel.js");
13
+ const stripe_js_1 = require("../integrations/stripe.js");
14
+ const supabase_js_1 = require("../integrations/supabase.js");
15
+ const mcp_js_1 = require("../integrations/mcp.js");
16
+ const notifications_js_1 = require("../integrations/notifications.js");
17
+ const config_js_1 = require("../config.js");
18
+ async function initCommand(options = {}) {
19
+ console.log(chalk_1.default.bold.cyan('\nšŸš€ ScanWarp Setup\n'));
20
+ console.log(chalk_1.default.gray('Your AI writes your code. ScanWarp keeps it running.\n'));
21
+ // Step 1: Auto-detect project
22
+ const spinner = (0, ora_1.default)('Detecting project...').start();
23
+ const detected = (0, detector_js_1.detectProject)();
24
+ spinner.succeed('Project detected');
25
+ // Print what was found
26
+ console.log(chalk_1.default.bold('\nāœ“ Project Details:'));
27
+ if (detected.framework) {
28
+ console.log(chalk_1.default.green(` āœ“ Framework: ${detected.framework}`));
29
+ }
30
+ if (detected.hosting) {
31
+ console.log(chalk_1.default.green(` āœ“ Hosting: ${detected.hosting}`));
32
+ }
33
+ if (detected.services.length > 0) {
34
+ console.log(chalk_1.default.green(` āœ“ Services: ${detected.services.join(', ')}`));
35
+ }
36
+ if (detected.projectName) {
37
+ console.log(chalk_1.default.green(` āœ“ Project: ${detected.projectName}`));
38
+ }
39
+ if (!detected.hasPackageJson) {
40
+ console.log(chalk_1.default.yellow('\n⚠ No package.json found. Are you in a Node.js project?'));
41
+ }
42
+ // Step 2: Get production URL
43
+ const defaultUrl = options.url || (0, detector_js_1.generateDefaultUrl)(detected);
44
+ const { productionUrl } = await inquirer_1.default.prompt([
45
+ {
46
+ type: 'input',
47
+ name: 'productionUrl',
48
+ message: 'What is your production URL?',
49
+ default: defaultUrl,
50
+ validate: (input) => {
51
+ try {
52
+ new URL(input);
53
+ return true;
54
+ }
55
+ catch {
56
+ return 'Please enter a valid URL (e.g., https://example.com)';
57
+ }
58
+ },
59
+ },
60
+ ]);
61
+ // Validate URL is reachable
62
+ const urlSpinner = (0, ora_1.default)('Checking if URL is reachable...').start();
63
+ try {
64
+ const response = await fetch(productionUrl, { method: 'HEAD' });
65
+ if (response.ok) {
66
+ urlSpinner.succeed(`URL is reachable (${response.status})`);
67
+ }
68
+ else {
69
+ urlSpinner.warn(`URL returned ${response.status} (continuing anyway)`);
70
+ }
71
+ }
72
+ catch (error) {
73
+ urlSpinner.warn('Could not reach URL (continuing anyway)');
74
+ }
75
+ // Step 3: Connect to ScanWarp server
76
+ const serverUrl = options.server || 'http://localhost:3000';
77
+ const api = new api_js_1.ScanWarpAPI(serverUrl);
78
+ const serverSpinner = (0, ora_1.default)('Connecting to ScanWarp server...').start();
79
+ const isConnected = await api.testConnection();
80
+ if (!isConnected) {
81
+ serverSpinner.fail(`Could not connect to ${serverUrl}`);
82
+ console.log(chalk_1.default.yellow('\n⚠ Make sure the ScanWarp server is running.'));
83
+ console.log(chalk_1.default.gray(' Run: cd apps/server && pnpm dev\n'));
84
+ process.exit(1);
85
+ }
86
+ serverSpinner.succeed(`Connected to ${serverUrl}`);
87
+ // Save server URL to config
88
+ config_js_1.config.setServerUrl(serverUrl);
89
+ // Step 4: Create project and monitor
90
+ const setupSpinner = (0, ora_1.default)('Setting up monitoring...').start();
91
+ try {
92
+ const project = await api.createProject(detected.projectName || 'my-app');
93
+ const monitor = await api.createMonitor(project.id, productionUrl);
94
+ // Save project ID to config
95
+ config_js_1.config.setProjectId(project.id);
96
+ setupSpinner.succeed('Monitoring configured');
97
+ console.log(chalk_1.default.green(`\n āœ“ Project ID: ${project.id}`));
98
+ console.log(chalk_1.default.green(` āœ“ Monitor ID: ${monitor.id}`));
99
+ console.log(chalk_1.default.green(` āœ“ Checking ${productionUrl} every 60 seconds\n`));
100
+ }
101
+ catch (error) {
102
+ setupSpinner.fail('Failed to set up monitoring');
103
+ console.error(chalk_1.default.red('\nError:'), error instanceof Error ? error.message : error);
104
+ process.exit(1);
105
+ }
106
+ // Step 5: Provider integrations
107
+ console.log(chalk_1.default.bold('\nšŸ“¦ Provider Integrations\n'));
108
+ // Vercel
109
+ if (detected.hosting === 'Vercel' && !options.skipVercel) {
110
+ await (0, vercel_js_1.setupVercel)(api, detected);
111
+ }
112
+ // Stripe
113
+ if (detected.services.includes('Stripe')) {
114
+ await (0, stripe_js_1.setupStripe)(api);
115
+ }
116
+ // Supabase
117
+ if (detected.services.includes('Supabase')) {
118
+ await (0, supabase_js_1.setupSupabase)(api);
119
+ }
120
+ // Step 6: MCP Configuration
121
+ if (!options.skipMcp) {
122
+ console.log(chalk_1.default.bold('\nšŸ¤– MCP Configuration\n'));
123
+ await (0, mcp_js_1.setupMCP)(serverUrl);
124
+ }
125
+ // Step 7: Notifications
126
+ console.log(chalk_1.default.bold('\nšŸ”” Notifications\n'));
127
+ await (0, notifications_js_1.setupNotifications)();
128
+ // Step 8: Summary
129
+ printSummary(api, productionUrl, detected);
130
+ }
131
+ function printSummary(api, url, _detected) {
132
+ console.log(chalk_1.default.bold.green('\n✨ Setup Complete!\n'));
133
+ console.log(chalk_1.default.bold('Your monitoring is now active:'));
134
+ console.log(chalk_1.default.gray(` • Monitoring: ${url}`));
135
+ console.log(chalk_1.default.gray(` • Check interval: Every 60 seconds`));
136
+ console.log(chalk_1.default.gray(` • Dashboard: ${api.serverUrl}\n`));
137
+ console.log(chalk_1.default.bold('Next steps:'));
138
+ console.log(chalk_1.default.gray(' 1. Deploy your app to trigger monitoring'));
139
+ console.log(chalk_1.default.gray(' 2. Visit the dashboard to see events and incidents'));
140
+ console.log(chalk_1.default.gray(' 3. Check your notifications for any alerts\n'));
141
+ console.log(chalk_1.default.bold('Useful commands:'));
142
+ console.log(chalk_1.default.gray(' • scanwarp status - Check monitoring status'));
143
+ console.log(chalk_1.default.gray(' • scanwarp events - View recent events'));
144
+ console.log(chalk_1.default.gray(' • scanwarp incidents - View open incidents\n'));
145
+ console.log(chalk_1.default.cyan('Happy shipping! šŸš€\n'));
146
+ }
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logsCommand = logsCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const api_js_1 = require("../api.js");
10
+ async function logsCommand(options = {}) {
11
+ const serverUrl = options.server || 'http://localhost:3000';
12
+ const api = new api_js_1.ScanWarpAPI(serverUrl);
13
+ const limit = options.limit || 50;
14
+ if (options.follow) {
15
+ await streamLogs(api, options);
16
+ }
17
+ else {
18
+ await fetchLogs(api, { ...options, limit });
19
+ }
20
+ }
21
+ async function fetchLogs(api, options) {
22
+ const spinner = (0, ora_1.default)('Fetching events...').start();
23
+ try {
24
+ const params = {
25
+ limit: options.limit,
26
+ };
27
+ if (options.type) {
28
+ params.type = options.type;
29
+ }
30
+ if (options.source) {
31
+ params.source = options.source;
32
+ }
33
+ const response = await api.client.get('/events', { params });
34
+ spinner.stop();
35
+ const events = response.data.events;
36
+ if (events.length === 0) {
37
+ console.log(chalk_1.default.yellow('\nNo events found.\n'));
38
+ return;
39
+ }
40
+ console.log(chalk_1.default.bold.cyan(`\nšŸ“‹ Recent Events (${events.length})\n`));
41
+ // Reverse to show oldest first
42
+ events.reverse();
43
+ for (const event of events) {
44
+ printEvent(event);
45
+ }
46
+ console.log(chalk_1.default.gray(`\nShowing ${events.length} events`));
47
+ console.log(chalk_1.default.gray('Use --follow to stream live events\n'));
48
+ }
49
+ catch (error) {
50
+ spinner.fail('Failed to fetch events');
51
+ console.log(chalk_1.default.red(`\nError: ${error instanceof Error ? error.message : 'Unknown error'}\n`));
52
+ process.exit(1);
53
+ }
54
+ }
55
+ async function streamLogs(api, options) {
56
+ console.log(chalk_1.default.bold.cyan('\nšŸ“” Streaming events (Ctrl+C to stop)\n'));
57
+ let lastEventId = null;
58
+ let isFirstFetch = true;
59
+ const poll = async () => {
60
+ try {
61
+ const params = {
62
+ limit: 20,
63
+ };
64
+ if (options.type) {
65
+ params.type = options.type;
66
+ }
67
+ if (options.source) {
68
+ params.source = options.source;
69
+ }
70
+ const response = await api.client.get('/events', { params });
71
+ const events = response.data.events;
72
+ // Filter to only show new events
73
+ let newEvents = events;
74
+ if (lastEventId) {
75
+ const lastIndex = events.findIndex((e) => e.id === lastEventId);
76
+ if (lastIndex > -1) {
77
+ newEvents = events.slice(0, lastIndex);
78
+ }
79
+ }
80
+ if (newEvents.length > 0) {
81
+ if (!isFirstFetch) {
82
+ // Show new events (they come in reverse chronological order)
83
+ for (let i = newEvents.length - 1; i >= 0; i--) {
84
+ printEvent(newEvents[i]);
85
+ }
86
+ }
87
+ else {
88
+ // On first fetch, show the most recent event
89
+ printEvent(newEvents[0]);
90
+ isFirstFetch = false;
91
+ }
92
+ lastEventId = newEvents[0].id;
93
+ }
94
+ }
95
+ catch (error) {
96
+ console.log(chalk_1.default.red(`\nError: ${error instanceof Error ? error.message : 'Unknown error'}`));
97
+ }
98
+ };
99
+ // Initial fetch
100
+ await poll();
101
+ // Poll every 2 seconds
102
+ const intervalId = setInterval(poll, 2000);
103
+ // Handle Ctrl+C
104
+ process.on('SIGINT', () => {
105
+ clearInterval(intervalId);
106
+ console.log(chalk_1.default.gray('\n\nStopped streaming.\n'));
107
+ process.exit(0);
108
+ });
109
+ }
110
+ function printEvent(event) {
111
+ const timestamp = new Date(event.created_at).toLocaleTimeString();
112
+ const severityColor = getSeverityColor(event.severity);
113
+ const typeIcon = getTypeIcon(event.type);
114
+ const sourceTag = chalk_1.default.gray(`[${event.source}]`);
115
+ console.log(`${chalk_1.default.gray(timestamp)} ${typeIcon} ${chalk_1.default[severityColor](event.severity.toUpperCase().padEnd(8))} ${sourceTag} ${event.message}`);
116
+ }
117
+ function getSeverityColor(severity) {
118
+ switch (severity.toLowerCase()) {
119
+ case 'critical':
120
+ return 'red';
121
+ case 'high':
122
+ return 'red';
123
+ case 'medium':
124
+ return 'yellow';
125
+ case 'low':
126
+ return 'blue';
127
+ default:
128
+ return 'gray';
129
+ }
130
+ }
131
+ function getTypeIcon(type) {
132
+ switch (type.toLowerCase()) {
133
+ case 'error':
134
+ return 'āœ—';
135
+ case 'down':
136
+ return '↓';
137
+ case 'up':
138
+ return '↑';
139
+ case 'slow':
140
+ return '⚠';
141
+ default:
142
+ return '•';
143
+ }
144
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.statusCommand = statusCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const api_js_1 = require("../api.js");
10
+ async function statusCommand(options = {}) {
11
+ const serverUrl = options.server || 'http://localhost:3000';
12
+ const api = new api_js_1.ScanWarpAPI(serverUrl);
13
+ const spinner = (0, ora_1.default)('Fetching status...').start();
14
+ try {
15
+ // Fetch monitors and incidents
16
+ const [monitorsResponse, incidentsResponse] = await Promise.all([
17
+ api.client.get('/monitors'),
18
+ api.client.get('/incidents', { params: { status: 'open' } }),
19
+ ]);
20
+ spinner.stop();
21
+ const monitors = monitorsResponse.data.monitors;
22
+ const incidents = incidentsResponse.data.incidents;
23
+ // Print header
24
+ console.log(chalk_1.default.bold.cyan('\nšŸ“Š ScanWarp Status\n'));
25
+ // Print monitors
26
+ if (monitors.length === 0) {
27
+ console.log(chalk_1.default.yellow('No monitors configured yet.'));
28
+ console.log(chalk_1.default.gray('Run "scanwarp init" to set up monitoring.\n'));
29
+ return;
30
+ }
31
+ console.log(chalk_1.default.bold('Monitors:\n'));
32
+ for (const monitor of monitors) {
33
+ const statusIcon = getStatusIcon(monitor.status);
34
+ const statusColor = getStatusColor(monitor.status);
35
+ const lastChecked = monitor.last_checked_at
36
+ ? formatRelativeTime(new Date(monitor.last_checked_at))
37
+ : 'never';
38
+ console.log(` ${statusIcon} ${chalk_1.default[statusColor](monitor.status.toUpperCase().padEnd(7))} ${monitor.url}`);
39
+ console.log(chalk_1.default.gray(` Last checked: ${lastChecked} • Every ${monitor.check_interval_seconds}s`));
40
+ }
41
+ // Print summary
42
+ const upCount = monitors.filter((m) => m.status === 'up').length;
43
+ const downCount = monitors.filter((m) => m.status === 'down').length;
44
+ const unknownCount = monitors.filter((m) => m.status === 'unknown').length;
45
+ console.log(chalk_1.default.bold(`\nSummary: ${monitors.length} total`));
46
+ if (upCount > 0)
47
+ console.log(chalk_1.default.green(` āœ“ ${upCount} up`));
48
+ if (downCount > 0)
49
+ console.log(chalk_1.default.red(` āœ— ${downCount} down`));
50
+ if (unknownCount > 0)
51
+ console.log(chalk_1.default.gray(` ? ${unknownCount} unknown`));
52
+ // Print active incidents
53
+ if (incidents.length > 0) {
54
+ console.log(chalk_1.default.bold.red(`\n⚠ ${incidents.length} Active Incident${incidents.length > 1 ? 's' : ''}:\n`));
55
+ for (const incident of incidents) {
56
+ const severityIcon = getSeverityIcon(incident.severity);
57
+ const severityColor = getSeverityColor(incident.severity);
58
+ console.log(` ${severityIcon} ${chalk_1.default[severityColor](incident.severity.toUpperCase())} • ${incident.status}`);
59
+ if (incident.diagnosis_text) {
60
+ const preview = incident.diagnosis_text.substring(0, 80);
61
+ console.log(chalk_1.default.gray(` ${preview}${incident.diagnosis_text.length > 80 ? '...' : ''}`));
62
+ }
63
+ console.log(chalk_1.default.gray(` Created: ${formatRelativeTime(new Date(incident.created_at))}`));
64
+ console.log(chalk_1.default.gray(` View: scanwarp incidents\n`));
65
+ }
66
+ }
67
+ else {
68
+ console.log(chalk_1.default.green('\nāœ“ No active incidents'));
69
+ }
70
+ console.log(chalk_1.default.gray(`\nServer: ${serverUrl}\n`));
71
+ }
72
+ catch (error) {
73
+ spinner.fail('Failed to fetch status');
74
+ if (error instanceof Error && 'code' in error && error.code === 'ECONNREFUSED') {
75
+ console.log(chalk_1.default.red('\nāœ— Could not connect to ScanWarp server'));
76
+ console.log(chalk_1.default.gray(` Server: ${serverUrl}`));
77
+ console.log(chalk_1.default.yellow(' Make sure the server is running.\n'));
78
+ }
79
+ else {
80
+ console.log(chalk_1.default.red(`\nError: ${error instanceof Error ? error.message : 'Unknown error'}\n`));
81
+ }
82
+ process.exit(1);
83
+ }
84
+ }
85
+ function getStatusIcon(status) {
86
+ switch (status) {
87
+ case 'up':
88
+ return chalk_1.default.green('ā—');
89
+ case 'down':
90
+ return chalk_1.default.red('ā—');
91
+ default:
92
+ return chalk_1.default.gray('ā—');
93
+ }
94
+ }
95
+ function getStatusColor(status) {
96
+ switch (status) {
97
+ case 'up':
98
+ return 'green';
99
+ case 'down':
100
+ return 'red';
101
+ default:
102
+ return 'gray';
103
+ }
104
+ }
105
+ function getSeverityIcon(severity) {
106
+ switch (severity.toLowerCase()) {
107
+ case 'critical':
108
+ return '🚨';
109
+ case 'warning':
110
+ return 'āš ļø';
111
+ default:
112
+ return 'ā„¹ļø';
113
+ }
114
+ }
115
+ function getSeverityColor(severity) {
116
+ switch (severity.toLowerCase()) {
117
+ case 'critical':
118
+ return 'red';
119
+ case 'warning':
120
+ return 'yellow';
121
+ default:
122
+ return 'blue';
123
+ }
124
+ }
125
+ function formatRelativeTime(date) {
126
+ const now = new Date();
127
+ const diffMs = now.getTime() - date.getTime();
128
+ const diffSecs = Math.floor(diffMs / 1000);
129
+ const diffMins = Math.floor(diffSecs / 60);
130
+ const diffHours = Math.floor(diffMins / 60);
131
+ const diffDays = Math.floor(diffHours / 24);
132
+ if (diffSecs < 60)
133
+ return `${diffSecs}s ago`;
134
+ if (diffMins < 60)
135
+ return `${diffMins}m ago`;
136
+ if (diffHours < 24)
137
+ return `${diffHours}h ago`;
138
+ return `${diffDays}d ago`;
139
+ }
package/dist/config.js ADDED
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.config = exports.ConfigManager = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const CONFIG_DIR = path_1.default.join(os_1.default.homedir(), '.scanwarp');
11
+ const CONFIG_FILE = path_1.default.join(CONFIG_DIR, 'config.json');
12
+ class ConfigManager {
13
+ config = {};
14
+ constructor() {
15
+ this.load();
16
+ }
17
+ ensureConfigDir() {
18
+ if (!fs_1.default.existsSync(CONFIG_DIR)) {
19
+ fs_1.default.mkdirSync(CONFIG_DIR, { recursive: true });
20
+ }
21
+ }
22
+ load() {
23
+ try {
24
+ if (fs_1.default.existsSync(CONFIG_FILE)) {
25
+ const content = fs_1.default.readFileSync(CONFIG_FILE, 'utf-8');
26
+ this.config = JSON.parse(content);
27
+ }
28
+ }
29
+ catch (error) {
30
+ console.warn('Failed to load config:', error);
31
+ this.config = {};
32
+ }
33
+ }
34
+ save() {
35
+ try {
36
+ this.ensureConfigDir();
37
+ fs_1.default.writeFileSync(CONFIG_FILE, JSON.stringify(this.config, null, 2));
38
+ }
39
+ catch (error) {
40
+ console.error('Failed to save config:', error);
41
+ }
42
+ }
43
+ get(key) {
44
+ return this.config[key];
45
+ }
46
+ set(key, value) {
47
+ this.config[key] = value;
48
+ this.save();
49
+ }
50
+ getAll() {
51
+ return { ...this.config };
52
+ }
53
+ clear() {
54
+ this.config = {};
55
+ this.save();
56
+ }
57
+ getServerUrl() {
58
+ return this.config.serverUrl || 'http://localhost:3000';
59
+ }
60
+ setServerUrl(url) {
61
+ this.set('serverUrl', url);
62
+ }
63
+ getProjectId() {
64
+ return this.config.projectId;
65
+ }
66
+ setProjectId(id) {
67
+ this.set('projectId', id);
68
+ }
69
+ getApiToken() {
70
+ return this.config.apiToken;
71
+ }
72
+ setApiToken(token) {
73
+ this.set('apiToken', token);
74
+ }
75
+ }
76
+ exports.ConfigManager = ConfigManager;
77
+ exports.config = new ConfigManager();