@git.zone/tswatch 2.3.13 → 3.0.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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/index.d.ts +4 -1
- package/dist_ts/index.js +5 -2
- package/dist_ts/interfaces/index.d.ts +1 -1
- package/dist_ts/interfaces/index.js +2 -2
- package/dist_ts/interfaces/interfaces.config.d.ts +58 -0
- package/dist_ts/interfaces/interfaces.config.js +2 -0
- package/dist_ts/tswatch.classes.confighandler.d.ts +30 -0
- package/dist_ts/tswatch.classes.confighandler.js +172 -0
- package/dist_ts/tswatch.classes.tswatch.d.ts +28 -3
- package/dist_ts/tswatch.classes.tswatch.js +135 -165
- package/dist_ts/tswatch.classes.watcher.d.ts +31 -3
- package/dist_ts/tswatch.classes.watcher.js +105 -25
- package/dist_ts/tswatch.cli.js +39 -28
- package/dist_ts/tswatch.init.d.ts +25 -0
- package/dist_ts/tswatch.init.js +168 -0
- package/dist_ts/tswatch.plugins.d.ts +3 -1
- package/dist_ts/tswatch.plugins.js +7 -5
- package/npmextra.json +12 -6
- package/package.json +21 -15
- package/readme.hints.md +88 -46
- package/readme.md +284 -149
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/index.ts +6 -2
- package/ts/interfaces/index.ts +1 -1
- package/ts/interfaces/interfaces.config.ts +61 -0
- package/ts/tswatch.classes.confighandler.ts +185 -0
- package/ts/tswatch.classes.tswatch.ts +161 -197
- package/ts/tswatch.classes.watcher.ts +134 -23
- package/ts/tswatch.cli.ts +37 -31
- package/ts/tswatch.init.ts +199 -0
- package/ts/tswatch.plugins.ts +7 -3
- package/dist_ts/interfaces/interfaces.watchmodes.d.ts +0 -1
- package/dist_ts/interfaces/interfaces.watchmodes.js +0 -2
- package/ts/interfaces/interfaces.watchmodes.ts +0 -1
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import * as plugins from './tswatch.plugins.js';
|
|
2
|
+
import * as interfaces from './interfaces/index.js';
|
|
2
3
|
import { logger } from './tswatch.logging.js';
|
|
3
4
|
|
|
4
5
|
export interface IWatcherConstructorOptions {
|
|
5
|
-
|
|
6
|
+
/** Name for this watcher (used in logging) */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Path(s) to watch - can be a single path or array */
|
|
9
|
+
filePathToWatch: string | string[];
|
|
10
|
+
/** Shell command to execute on changes */
|
|
6
11
|
commandToExecute?: string;
|
|
12
|
+
/** Function to call on changes */
|
|
7
13
|
functionToCall?: () => Promise<any>;
|
|
14
|
+
/** Timeout for the watcher */
|
|
8
15
|
timeout?: number;
|
|
16
|
+
/** If true, kill previous process before restarting (default: true) */
|
|
17
|
+
restart?: boolean;
|
|
18
|
+
/** Debounce delay in ms (default: 300) */
|
|
19
|
+
debounce?: number;
|
|
20
|
+
/** If true, run the command immediately on start (default: true) */
|
|
21
|
+
runOnStart?: boolean;
|
|
9
22
|
}
|
|
10
23
|
|
|
11
24
|
/**
|
|
@@ -22,53 +35,148 @@ export class Watcher {
|
|
|
22
35
|
private currentExecution: plugins.smartshell.IExecResultStreaming;
|
|
23
36
|
private smartwatchInstance = new plugins.smartwatch.Smartwatch([]);
|
|
24
37
|
private options: IWatcherConstructorOptions;
|
|
38
|
+
private debounceTimer: NodeJS.Timeout | null = null;
|
|
39
|
+
private isExecuting = false;
|
|
40
|
+
private pendingExecution = false;
|
|
25
41
|
|
|
26
42
|
constructor(optionsArg: IWatcherConstructorOptions) {
|
|
27
|
-
this.options =
|
|
43
|
+
this.options = {
|
|
44
|
+
restart: true,
|
|
45
|
+
debounce: 300,
|
|
46
|
+
runOnStart: true,
|
|
47
|
+
...optionsArg,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Create a Watcher from config
|
|
53
|
+
*/
|
|
54
|
+
public static fromConfig(config: interfaces.IWatcherConfig): Watcher {
|
|
55
|
+
const watchPaths = Array.isArray(config.watch) ? config.watch : [config.watch];
|
|
56
|
+
return new Watcher({
|
|
57
|
+
name: config.name,
|
|
58
|
+
filePathToWatch: watchPaths,
|
|
59
|
+
commandToExecute: config.command,
|
|
60
|
+
restart: config.restart ?? true,
|
|
61
|
+
debounce: config.debounce ?? 300,
|
|
62
|
+
runOnStart: config.runOnStart ?? true,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the watcher name for logging
|
|
68
|
+
*/
|
|
69
|
+
private getName(): string {
|
|
70
|
+
return this.options.name || 'unnamed';
|
|
28
71
|
}
|
|
29
72
|
|
|
30
73
|
/**
|
|
31
74
|
* start the file
|
|
32
75
|
*/
|
|
33
76
|
public async start() {
|
|
34
|
-
|
|
77
|
+
const name = this.getName();
|
|
78
|
+
logger.log('info', `[${name}] starting watcher`);
|
|
35
79
|
await this.setupCleanup();
|
|
36
|
-
|
|
37
|
-
// Convert
|
|
38
|
-
const
|
|
39
|
-
?
|
|
40
|
-
:
|
|
41
|
-
|
|
80
|
+
|
|
81
|
+
// Convert paths to glob patterns
|
|
82
|
+
const paths = Array.isArray(this.options.filePathToWatch)
|
|
83
|
+
? this.options.filePathToWatch
|
|
84
|
+
: [this.options.filePathToWatch];
|
|
85
|
+
|
|
86
|
+
const watchPatterns = paths.map((p) => {
|
|
87
|
+
// Convert directory path to glob pattern for smartwatch
|
|
88
|
+
if (p.endsWith('/')) {
|
|
89
|
+
return `${p}**/*`;
|
|
90
|
+
}
|
|
91
|
+
// If it's already a glob pattern, use as-is
|
|
92
|
+
if (p.includes('*')) {
|
|
93
|
+
return p;
|
|
94
|
+
}
|
|
95
|
+
// Otherwise assume it's a directory
|
|
96
|
+
return `${p}/**/*`;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
logger.log('info', `[${name}] watching patterns: ${watchPatterns.join(', ')}`);
|
|
100
|
+
this.smartwatchInstance.add(watchPatterns);
|
|
42
101
|
await this.smartwatchInstance.start();
|
|
102
|
+
|
|
43
103
|
const changeObservable = await this.smartwatchInstance.getObservableFor('change');
|
|
44
104
|
changeObservable.subscribe(() => {
|
|
45
|
-
this.
|
|
105
|
+
this.handleChange();
|
|
46
106
|
});
|
|
47
|
-
|
|
48
|
-
|
|
107
|
+
|
|
108
|
+
// Run on start if configured
|
|
109
|
+
if (this.options.runOnStart) {
|
|
110
|
+
await this.executeCommand();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
logger.log('info', `[${name}] watcher started`);
|
|
49
114
|
}
|
|
50
115
|
|
|
51
116
|
/**
|
|
52
|
-
*
|
|
117
|
+
* Handle file change with debouncing
|
|
53
118
|
*/
|
|
54
|
-
private
|
|
119
|
+
private handleChange() {
|
|
120
|
+
const name = this.getName();
|
|
121
|
+
|
|
122
|
+
// Clear existing debounce timer
|
|
123
|
+
if (this.debounceTimer) {
|
|
124
|
+
clearTimeout(this.debounceTimer);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Set new debounce timer
|
|
128
|
+
this.debounceTimer = setTimeout(async () => {
|
|
129
|
+
this.debounceTimer = null;
|
|
130
|
+
|
|
131
|
+
// If currently executing and not in restart mode, mark pending
|
|
132
|
+
if (this.isExecuting && !this.options.restart) {
|
|
133
|
+
logger.log('info', `[${name}] change detected, queuing execution`);
|
|
134
|
+
this.pendingExecution = true;
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
await this.executeCommand();
|
|
139
|
+
|
|
140
|
+
// If there was a pending execution, run it
|
|
141
|
+
if (this.pendingExecution) {
|
|
142
|
+
this.pendingExecution = false;
|
|
143
|
+
await this.executeCommand();
|
|
144
|
+
}
|
|
145
|
+
}, this.options.debounce);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Execute the command or function
|
|
150
|
+
*/
|
|
151
|
+
private async executeCommand() {
|
|
152
|
+
const name = this.getName();
|
|
153
|
+
|
|
55
154
|
if (this.options.commandToExecute) {
|
|
56
|
-
if (this.currentExecution) {
|
|
57
|
-
logger.log('ok', `
|
|
155
|
+
if (this.currentExecution && this.options.restart) {
|
|
156
|
+
logger.log('ok', `[${name}] restarting: ${this.options.commandToExecute}`);
|
|
58
157
|
this.currentExecution.kill();
|
|
59
|
-
} else {
|
|
60
|
-
logger.log('ok', `executing ${this.options.commandToExecute}
|
|
158
|
+
} else if (!this.currentExecution) {
|
|
159
|
+
logger.log('ok', `[${name}] executing: ${this.options.commandToExecute}`);
|
|
61
160
|
}
|
|
161
|
+
|
|
162
|
+
this.isExecuting = true;
|
|
62
163
|
this.currentExecution = await this.smartshellInstance.execStreaming(
|
|
63
164
|
this.options.commandToExecute,
|
|
64
165
|
);
|
|
65
|
-
|
|
66
|
-
|
|
166
|
+
|
|
167
|
+
// Track when execution completes
|
|
168
|
+
this.currentExecution.childProcess.on('exit', () => {
|
|
169
|
+
this.isExecuting = false;
|
|
170
|
+
});
|
|
67
171
|
}
|
|
172
|
+
|
|
68
173
|
if (this.options.functionToCall) {
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
|
|
174
|
+
this.isExecuting = true;
|
|
175
|
+
try {
|
|
176
|
+
await this.options.functionToCall();
|
|
177
|
+
} finally {
|
|
178
|
+
this.isExecuting = false;
|
|
179
|
+
}
|
|
72
180
|
}
|
|
73
181
|
}
|
|
74
182
|
|
|
@@ -103,6 +211,9 @@ export class Watcher {
|
|
|
103
211
|
* stops the watcher
|
|
104
212
|
*/
|
|
105
213
|
public async stop() {
|
|
214
|
+
if (this.debounceTimer) {
|
|
215
|
+
clearTimeout(this.debounceTimer);
|
|
216
|
+
}
|
|
106
217
|
await this.smartwatchInstance.stop();
|
|
107
218
|
if (this.currentExecution && !this.currentExecution.childProcess.killed) {
|
|
108
219
|
this.currentExecution.kill();
|
package/ts/tswatch.cli.ts
CHANGED
|
@@ -3,42 +3,48 @@ import * as paths from './tswatch.paths.js';
|
|
|
3
3
|
import { logger } from './tswatch.logging.js';
|
|
4
4
|
|
|
5
5
|
import { TsWatch } from './tswatch.classes.tswatch.js';
|
|
6
|
+
import { ConfigHandler } from './tswatch.classes.confighandler.js';
|
|
7
|
+
import { runInit } from './tswatch.init.js';
|
|
6
8
|
|
|
7
9
|
const tswatchCli = new plugins.smartcli.Smartcli();
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Standard command (no args) - run with config or launch wizard
|
|
13
|
+
*/
|
|
14
|
+
tswatchCli.standardCommand().subscribe(async (argvArg) => {
|
|
15
|
+
const configHandler = new ConfigHandler();
|
|
16
|
+
|
|
17
|
+
if (configHandler.hasConfig()) {
|
|
18
|
+
// Config exists - run with it
|
|
19
|
+
const tsWatch = TsWatch.fromConfig();
|
|
20
|
+
if (tsWatch) {
|
|
21
|
+
logger.log('info', 'Starting tswatch with configuration from npmextra.json');
|
|
22
|
+
await tsWatch.start();
|
|
23
|
+
} else {
|
|
24
|
+
logger.log('error', 'Failed to load configuration');
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
// No config - launch wizard
|
|
29
|
+
logger.log('info', 'No tswatch configuration found in npmextra.json');
|
|
30
|
+
const config = await runInit();
|
|
31
|
+
if (config) {
|
|
32
|
+
// Run with the newly created config
|
|
33
|
+
const tsWatch = new TsWatch(config);
|
|
34
|
+
await tsWatch.start();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
12
37
|
});
|
|
13
38
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
await tsWatch.start();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
tswatchCli.addCommand('service').subscribe(async (argvArg) => {
|
|
27
|
-
logger.log('info', `running test task`);
|
|
28
|
-
const tsWatch = new TsWatch('service');
|
|
29
|
-
await tsWatch.start();
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
tswatchCli.addCommand('test').subscribe(async (argvArg) => {
|
|
33
|
-
logger.log('info', `running test task`);
|
|
34
|
-
const tsWatch = new TsWatch('test');
|
|
35
|
-
await tsWatch.start();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
tswatchCli.addCommand('website').subscribe(async (argvArg) => {
|
|
39
|
-
logger.log('info', `running watch task for a gitzone website project`);
|
|
40
|
-
const tsWatch = new TsWatch('website');
|
|
41
|
-
await tsWatch.start();
|
|
39
|
+
/**
|
|
40
|
+
* Init command - force run wizard (overwrite existing config)
|
|
41
|
+
*/
|
|
42
|
+
tswatchCli.addCommand('init').subscribe(async (argvArg) => {
|
|
43
|
+
logger.log('info', 'Running tswatch configuration wizard');
|
|
44
|
+
const config = await runInit();
|
|
45
|
+
if (config) {
|
|
46
|
+
logger.log('ok', 'Configuration created successfully');
|
|
47
|
+
}
|
|
42
48
|
});
|
|
43
49
|
|
|
44
50
|
export const runCli = async () => {
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as plugins from './tswatch.plugins.js';
|
|
2
|
+
import * as paths from './tswatch.paths.js';
|
|
3
|
+
import * as interfaces from './interfaces/index.js';
|
|
4
|
+
import { ConfigHandler } from './tswatch.classes.confighandler.js';
|
|
5
|
+
import { logger } from './tswatch.logging.js';
|
|
6
|
+
|
|
7
|
+
const CONFIG_KEY = '@git.zone/tswatch';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Interactive init wizard for creating tswatch configuration
|
|
11
|
+
*/
|
|
12
|
+
export class TswatchInit {
|
|
13
|
+
private configHandler: ConfigHandler;
|
|
14
|
+
private smartInteract: plugins.smartinteract.SmartInteract;
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
this.configHandler = new ConfigHandler();
|
|
18
|
+
this.smartInteract = new plugins.smartinteract.SmartInteract([]);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Run the interactive init wizard
|
|
23
|
+
*/
|
|
24
|
+
public async run(): Promise<interfaces.ITswatchConfig | null> {
|
|
25
|
+
console.log('\n=== tswatch Configuration Wizard ===\n');
|
|
26
|
+
|
|
27
|
+
// Ask for template choice
|
|
28
|
+
const templateAnswer = await this.smartInteract.askQuestion({
|
|
29
|
+
name: 'template',
|
|
30
|
+
type: 'list',
|
|
31
|
+
message: 'Select a configuration template:',
|
|
32
|
+
default: 'npm',
|
|
33
|
+
choices: [
|
|
34
|
+
{ name: 'npm - Watch ts/ and test/, run npm test', value: 'npm' },
|
|
35
|
+
{ name: 'test - Watch ts/ and test/, run npm run test2', value: 'test' },
|
|
36
|
+
{ name: 'service - Watch ts/, restart npm run startTs', value: 'service' },
|
|
37
|
+
{ name: 'element - Dev server + bundling for web components', value: 'element' },
|
|
38
|
+
{ name: 'website - Full stack: backend + frontend + assets', value: 'website' },
|
|
39
|
+
{ name: 'custom - Configure watchers manually', value: 'custom' },
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const template = templateAnswer.value as string;
|
|
44
|
+
|
|
45
|
+
let config: interfaces.ITswatchConfig;
|
|
46
|
+
|
|
47
|
+
if (template === 'custom') {
|
|
48
|
+
config = await this.runCustomWizard();
|
|
49
|
+
} else {
|
|
50
|
+
// Get preset config
|
|
51
|
+
const preset = this.configHandler.getPreset(template);
|
|
52
|
+
if (!preset) {
|
|
53
|
+
console.error(`Unknown template: ${template}`);
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
config = { ...preset, preset: template as interfaces.ITswatchConfig['preset'] };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Save to npmextra.json
|
|
60
|
+
await this.saveConfig(config);
|
|
61
|
+
|
|
62
|
+
console.log('\nConfiguration saved to npmextra.json');
|
|
63
|
+
console.log('Run "tswatch" to start watching.\n');
|
|
64
|
+
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Run custom configuration wizard
|
|
70
|
+
*/
|
|
71
|
+
private async runCustomWizard(): Promise<interfaces.ITswatchConfig> {
|
|
72
|
+
const config: interfaces.ITswatchConfig = {};
|
|
73
|
+
|
|
74
|
+
// Ask about server
|
|
75
|
+
const serverAnswer = await this.smartInteract.askQuestion({
|
|
76
|
+
name: 'enableServer',
|
|
77
|
+
type: 'confirm',
|
|
78
|
+
message: 'Enable development server?',
|
|
79
|
+
default: false,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (serverAnswer.value) {
|
|
83
|
+
const portAnswer = await this.smartInteract.askQuestion({
|
|
84
|
+
name: 'port',
|
|
85
|
+
type: 'input',
|
|
86
|
+
message: 'Server port:',
|
|
87
|
+
default: '3002',
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const serveDirAnswer = await this.smartInteract.askQuestion({
|
|
91
|
+
name: 'serveDir',
|
|
92
|
+
type: 'input',
|
|
93
|
+
message: 'Directory to serve:',
|
|
94
|
+
default: './dist_watch/',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
config.server = {
|
|
98
|
+
enabled: true,
|
|
99
|
+
port: parseInt(portAnswer.value as string, 10),
|
|
100
|
+
serveDir: serveDirAnswer.value as string,
|
|
101
|
+
liveReload: true,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Add watchers
|
|
106
|
+
config.watchers = [];
|
|
107
|
+
let addMore = true;
|
|
108
|
+
|
|
109
|
+
while (addMore) {
|
|
110
|
+
console.log('\n--- Add a watcher ---');
|
|
111
|
+
|
|
112
|
+
const nameAnswer = await this.smartInteract.askQuestion({
|
|
113
|
+
name: 'name',
|
|
114
|
+
type: 'input',
|
|
115
|
+
message: 'Watcher name:',
|
|
116
|
+
default: `watcher-${config.watchers.length + 1}`,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const watchAnswer = await this.smartInteract.askQuestion({
|
|
120
|
+
name: 'watch',
|
|
121
|
+
type: 'input',
|
|
122
|
+
message: 'Glob pattern(s) to watch (comma-separated):',
|
|
123
|
+
default: './ts/**/*',
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const commandAnswer = await this.smartInteract.askQuestion({
|
|
127
|
+
name: 'command',
|
|
128
|
+
type: 'input',
|
|
129
|
+
message: 'Command to execute:',
|
|
130
|
+
default: 'npm run test',
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const restartAnswer = await this.smartInteract.askQuestion({
|
|
134
|
+
name: 'restart',
|
|
135
|
+
type: 'confirm',
|
|
136
|
+
message: 'Restart command on each change (vs queue)?',
|
|
137
|
+
default: true,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Parse watch patterns
|
|
141
|
+
const watchPatterns = (watchAnswer.value as string)
|
|
142
|
+
.split(',')
|
|
143
|
+
.map((p) => p.trim())
|
|
144
|
+
.filter((p) => p.length > 0);
|
|
145
|
+
|
|
146
|
+
config.watchers.push({
|
|
147
|
+
name: nameAnswer.value as string,
|
|
148
|
+
watch: watchPatterns.length === 1 ? watchPatterns[0] : watchPatterns,
|
|
149
|
+
command: commandAnswer.value as string,
|
|
150
|
+
restart: restartAnswer.value as boolean,
|
|
151
|
+
debounce: 300,
|
|
152
|
+
runOnStart: true,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const moreAnswer = await this.smartInteract.askQuestion({
|
|
156
|
+
name: 'addMore',
|
|
157
|
+
type: 'confirm',
|
|
158
|
+
message: 'Add another watcher?',
|
|
159
|
+
default: false,
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
addMore = moreAnswer.value as boolean;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return config;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Save configuration to npmextra.json
|
|
170
|
+
*/
|
|
171
|
+
private async saveConfig(config: interfaces.ITswatchConfig): Promise<void> {
|
|
172
|
+
const npmextraPath = plugins.path.join(paths.cwd, 'npmextra.json');
|
|
173
|
+
|
|
174
|
+
// Read existing npmextra.json if it exists
|
|
175
|
+
let existingConfig: Record<string, any> = {};
|
|
176
|
+
try {
|
|
177
|
+
const smartfsInstance = new plugins.smartfs.SmartFs(new plugins.smartfs.SmartFsProviderNode());
|
|
178
|
+
const content = await smartfsInstance.file(npmextraPath).encoding('utf8').read() as string;
|
|
179
|
+
existingConfig = JSON.parse(content);
|
|
180
|
+
} catch {
|
|
181
|
+
// File doesn't exist or is invalid, start fresh
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Update with new tswatch config
|
|
185
|
+
existingConfig[CONFIG_KEY] = config;
|
|
186
|
+
|
|
187
|
+
// Write back
|
|
188
|
+
const smartfsInstance = new plugins.smartfs.SmartFs(new plugins.smartfs.SmartFsProviderNode());
|
|
189
|
+
await smartfsInstance.file(npmextraPath).encoding('utf8').write(JSON.stringify(existingConfig, null, 2));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Run the init wizard
|
|
195
|
+
*/
|
|
196
|
+
export const runInit = async (): Promise<interfaces.ITswatchConfig | null> => {
|
|
197
|
+
const init = new TswatchInit();
|
|
198
|
+
return init.run();
|
|
199
|
+
};
|
package/ts/tswatch.plugins.ts
CHANGED
|
@@ -2,20 +2,22 @@
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
export { path };
|
|
4
4
|
|
|
5
|
-
// @
|
|
5
|
+
// @git.zone scope
|
|
6
6
|
import * as tsbundle from '@git.zone/tsbundle';
|
|
7
7
|
export { tsbundle };
|
|
8
8
|
|
|
9
|
-
// @
|
|
9
|
+
// @api.global scope
|
|
10
10
|
import * as typedserver from '@api.global/typedserver';
|
|
11
11
|
|
|
12
12
|
export { typedserver };
|
|
13
13
|
|
|
14
|
-
// @
|
|
14
|
+
// @push.rocks scope
|
|
15
15
|
import * as lik from '@push.rocks/lik';
|
|
16
|
+
import * as npmextra from '@push.rocks/npmextra';
|
|
16
17
|
import * as smartcli from '@push.rocks/smartcli';
|
|
17
18
|
import * as smartdelay from '@push.rocks/smartdelay';
|
|
18
19
|
import * as smartfs from '@push.rocks/smartfs';
|
|
20
|
+
import * as smartinteract from '@push.rocks/smartinteract';
|
|
19
21
|
import * as smartlog from '@push.rocks/smartlog';
|
|
20
22
|
import * as smartlogDestinationLocal from '@push.rocks/smartlog-destination-local';
|
|
21
23
|
import * as smartshell from '@push.rocks/smartshell';
|
|
@@ -24,9 +26,11 @@ import * as taskbuffer from '@push.rocks/taskbuffer';
|
|
|
24
26
|
|
|
25
27
|
export {
|
|
26
28
|
lik,
|
|
29
|
+
npmextra,
|
|
27
30
|
smartcli,
|
|
28
31
|
smartdelay,
|
|
29
32
|
smartfs,
|
|
33
|
+
smartinteract,
|
|
30
34
|
smartlog,
|
|
31
35
|
smartlogDestinationLocal,
|
|
32
36
|
smartshell,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type TWatchModes = 'test' | 'node' | 'service' | 'element' | 'website' | 'echo';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export type TWatchModes = 'test' | 'node' | 'service' | 'element' | 'website' | 'echo';
|