Skip to content

Commit d1d7469

Browse files
committed
Add plugin override for watchFactory
1 parent 67d6ee5 commit d1d7469

File tree

38 files changed

+91
-22
lines changed

38 files changed

+91
-22
lines changed

src/compiler/sys.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,11 @@ namespace ts {
963963
),
964964
};
965965

966+
function getWatchFactoryPlugin(options: WatchOptions) {
967+
const plugin = isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory!;
968+
return options.watchFactoryWithConfigOverride?.(plugin) || plugin;
969+
}
970+
966971
function createWatcherConsideringFactory(
967972
options: WatchOptions | undefined,
968973
createWatcher: (factory?: UserWatchModule) => FileWatcher,
@@ -1001,7 +1006,7 @@ namespace ts {
10011006
setImportPluginResult(
10021007
options,
10031008
resolveModule<UserWatchFactory>(
1004-
isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory,
1009+
getWatchFactoryPlugin(options),
10051010
searchPaths,
10061011
getSystem(),
10071012
sysLog
@@ -1022,7 +1027,7 @@ namespace ts {
10221027
function importFactory(options: WatchOptions, searchPaths: readonly string[], system: System) {
10231028
return setGetResolvedWatchFactory(options, {
10241029
pending: importPlugin<UserWatchFactory>(
1025-
isString(options.watchFactory) ? { name: options.watchFactory } : options.watchFactory!,
1030+
getWatchFactoryPlugin(options),
10261031
searchPaths,
10271032
system,
10281033
sysLog
@@ -1037,7 +1042,13 @@ namespace ts {
10371042
{ resolvedModule, errorLogs, pluginConfigEntry }: ImportPluginResult<UserWatchFactory>,
10381043
) {
10391044
if (typeof resolvedModule === "function") {
1040-
return setGetResolvedWatchFactory(options, { resolved: resolvedModule({ typescript: ts }) });
1045+
return setGetResolvedWatchFactory(options, {
1046+
resolved: resolvedModule({
1047+
typescript: ts,
1048+
options,
1049+
config: pluginConfigEntry
1050+
})
1051+
});
10411052
}
10421053
else if (!resolvedModule) {
10431054
forEach(errorLogs, sysLog);

src/compiler/types.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -6673,7 +6673,7 @@ namespace ts {
66736673
[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
66746674
}
66756675

6676-
export type UserWatchFactory = (mod: { typescript: typeof ts }) => UserWatchModule;
6676+
export type UserWatchFactory = (mod: { typescript: typeof ts, options: WatchOptions, config: any }) => UserWatchModule;
66776677
export interface UserWatchModule {
66786678
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;
66796679
watchDirectory?(fileName: string, callback: DirectoryWatcherCallback, recursive: boolean, options: WatchOptions | undefined): FileWatcher;
@@ -6696,6 +6696,7 @@ namespace ts {
66966696
/* @internal */ readonly configFile?: TsConfigSourceFile;
66976697
/* @internal */ getResolvedWatchFactory?(): ResolvedWatchFactory | undefined;
66986698
/* @internal */ watchFactorySearchPaths?(): readonly string[];
6699+
/* @internal */ watchFactoryWithConfigOverride?(plugin: PluginImport): PluginImport;
66996700

67006701
[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
67016702
}

src/server/editorServices.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ namespace ts.server {
784784
public readonly pluginProbeLocations: readonly string[];
785785
public readonly allowLocalPluginLoads: boolean;
786786
/*@internal*/
787-
currentPluginConfigOverrides: ESMap<string, any> | undefined;
787+
private currentPluginConfigOverrides: ESMap<string, any> | undefined;
788788

789789
public readonly typesMapLocation: string | undefined;
790790

@@ -2237,7 +2237,10 @@ namespace ts.server {
22372237
configFileExistenceInfo.config.watchedDirectoriesStale = true;
22382238
configFileExistenceInfo.config.reloadLevel = undefined;
22392239
}
2240-
if (parsedCommandLine.watchOptions) parsedCommandLine.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths(canonicalConfigFilePath);
2240+
if (parsedCommandLine.watchOptions) {
2241+
parsedCommandLine.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths(canonicalConfigFilePath);
2242+
parsedCommandLine.watchOptions.watchFactoryWithConfigOverride = plugin => this.getPluginWithConfigOverride(plugin);
2243+
}
22412244

22422245
// If watch options different than older options when setting for the first time, update the config file watcher
22432246
if (!oldCommandLine && !isJsonEqual(
@@ -3053,6 +3056,7 @@ namespace ts.server {
30533056
if (this.hostConfiguration.watchOptions?.watchFactory) {
30543057
// Set the watchFactory searchPaths same as global paths
30553058
this.hostConfiguration.watchOptions.watchFactorySearchPaths = () => this.getGlobalPluginSearchPaths();
3059+
this.hostConfiguration.watchOptions.watchFactoryWithConfigOverride = plugin => this.getPluginWithConfigOverride(plugin);
30563060
}
30573061
this.projectWatchOptions.clear();
30583062
this.logger.info(`Host watch options changed to ${JSON.stringify(this.hostConfiguration.watchOptions)}, it will be take effect for next watches.`);
@@ -4132,6 +4136,18 @@ namespace ts.server {
41324136
return searchPaths;
41334137
}
41344138

4139+
/*@internal*/
4140+
getPluginWithConfigOverride(pluginConfigEntry: PluginImport) {
4141+
const configurationOverride = this.currentPluginConfigOverrides?.get(pluginConfigEntry.name);
4142+
if (configurationOverride) {
4143+
// Preserve the name property since it's immutable
4144+
const pluginName = pluginConfigEntry.name;
4145+
pluginConfigEntry = configurationOverride;
4146+
pluginConfigEntry.name = pluginName;
4147+
}
4148+
return pluginConfigEntry;
4149+
}
4150+
41354151
/*@internal*/
41364152
requestEnablePlugin(project: Project, pluginConfigEntry: PluginImport, searchPaths: string[]) {
41374153
if (!this.host.importPlugin && !this.host.require) {

src/server/project.ts

+2-9
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,7 @@ namespace ts.server {
14421442
this.watchOptions = watchOptions;
14431443
if (this.watchOptions?.watchFactory) {
14441444
this.watchOptions.watchFactorySearchPaths = () => this.getProjectPluginSearchPaths();
1445+
this.watchOptions.watchFactoryWithConfigOverride = plugin => this.projectService.getPluginWithConfigOverride(plugin);
14451446
}
14461447
}
14471448

@@ -1612,15 +1613,7 @@ namespace ts.server {
16121613
/*@internal*/
16131614
endEnablePlugin({ pluginConfigEntry, resolvedModule, errorLogs }: BeginEnablePluginResult) {
16141615
if (resolvedModule) {
1615-
const configurationOverride = this.projectService.currentPluginConfigOverrides?.get(pluginConfigEntry.name);
1616-
if (configurationOverride) {
1617-
// Preserve the name property since it's immutable
1618-
const pluginName = pluginConfigEntry.name;
1619-
pluginConfigEntry = configurationOverride;
1620-
pluginConfigEntry.name = pluginName;
1621-
}
1622-
1623-
this.enableProxy(resolvedModule, pluginConfigEntry);
1616+
this.enableProxy(resolvedModule, this.projectService.getPluginWithConfigOverride(pluginConfigEntry));
16241617
}
16251618
else {
16261619
forEach(errorLogs, message => this.projectService.logger.info(message));

src/testRunner/unittests/tscWatch/watchEnvironment.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -900,10 +900,13 @@ namespace ts.tscWatch {
900900
system.require = (initialPath, moduleName) => {
901901
system.write(`Require:: Resolving ${moduleName} from ${initialPath}\n`);
902902
return {
903-
module: () => ({
904-
watchFile: !excludeWatchFile ? system.factoryData.watchFile : undefined,
905-
watchDirectory: system.factoryData.watchDirectory,
906-
}),
903+
module: (({ options, config }) => {
904+
system.write(`Require:: Module ${moduleName} created with config: ${JSON.stringify(config)} and options: ${JSON.stringify(options)}\n`);
905+
return {
906+
watchFile: !excludeWatchFile ? system.factoryData.watchFile : undefined,
907+
watchDirectory: system.factoryData.watchDirectory,
908+
};
909+
}) as UserWatchFactory,
907910
error: undefined
908911
};
909912
};

src/testRunner/unittests/tsserver/watchEnvironment.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -831,9 +831,12 @@ namespace ts.projectSystem {
831831
return (initialPath, moduleName) => {
832832
session.logger.logs.push(`CustomRequire:: Resolving ${moduleName} from ${initialPath}`);
833833
return {
834-
module: (): UserWatchModule => !plugin2 || moduleName === "myplugin" ?
835-
plugin :
836-
plugin2,
834+
module: (({ options, config }) => {
835+
session.logger.logs.push(`Require:: Module ${moduleName} created with config: ${JSON.stringify(config)} and options: ${JSON.stringify(options)}`);
836+
return !plugin2 || moduleName === "myplugin" ?
837+
plugin :
838+
plugin2;
839+
}) as UserWatchFactory,
837840
error: undefined
838841
};
839842
};

tests/baselines/reference/api/tsserverlibrary.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3092,6 +3092,8 @@ declare namespace ts {
30923092
}
30933093
export type UserWatchFactory = (mod: {
30943094
typescript: typeof ts;
3095+
options: WatchOptions;
3096+
config: any;
30953097
}) => UserWatchModule;
30963098
export interface UserWatchModule {
30973099
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;

tests/baselines/reference/api/typescript.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -3092,6 +3092,8 @@ declare namespace ts {
30923092
}
30933093
export type UserWatchFactory = (mod: {
30943094
typescript: typeof ts;
3095+
options: WatchOptions;
3096+
config: any;
30953097
}) => UserWatchModule;
30963098
export interface UserWatchModule {
30973099
watchFile?(fileName: string, callback: FileWatcherCallback, pollingInterval: number, options: WatchOptions | undefined): FileWatcher;

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/in-config-file-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
3435
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
3536
Synchronizing program
3637
CreatingProgramWith::

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/in-config-file.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
3435
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
3536
Synchronizing program
3637
CreatingProgramWith::

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/through-commandline-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
3435
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
3536
Synchronizing program
3637
CreatingProgramWith::

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/through-commandline.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
3435
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
3536
Synchronizing program
3637
CreatingProgramWith::

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/when-plugin-does-not-implements-watchFile-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
3435
Synchronizing program
3536
CreatingProgramWith::
3637
roots: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"]

tests/baselines/reference/tscWatch/watchEnvironment/watchFactory/when-plugin-does-not-implements-watchFile.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json
3131
Enabling watchFactory myplugin from candidate paths: /user/username/projects/myproject,/a/lib/tsc.js/../../..
3232
Loading myplugin from /user/username/projects/myproject (resolved to /user/username/projects/myproject/node_modules)
3333
Require:: Resolving myplugin from /user/username/projects/myproject/node_modules
34+
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
3435
Synchronizing program
3536
CreatingProgramWith::
3637
roots: ["/user/username/projects/myproject/a.ts","/user/username/projects/myproject/b.ts"]

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-allowLocalPluginLoads-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
9595
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
9696
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
9797
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
98+
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
9899
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
99100
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
100101
"rootNames": [

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-allowLocalPluginLoads.js

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
9292
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
9393
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
9494
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
95+
Require:: Module myplugin created with config: {"name":"myplugin"} and options: {"watchFactory":"myplugin"}
9596
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
9697
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
9798
"rootNames": [

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Info 7 [00:00:30.000] For info: /user/username/projects/myproject/a.ts :: Con
9595
Info 8 [00:00:31.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
9696
Info 9 [00:00:32.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
9797
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
98+
Require:: Module myplugin created with config: {"name":"myplugin","myconfig":"somethingelse"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
9899
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
99100
Info 10 [00:00:33.000] Config: /user/username/projects/myproject/tsconfig.json : {
100101
"rootNames": [

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-with-pluginoverride-allowLocalPluginLoads-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
139139
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
140140
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
141141
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
142+
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
142143
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
143144
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
144145
"rootNames": [

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-with-pluginoverride-allowLocalPluginLoads.js

+1
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
136136
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
137137
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
138138
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
139+
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":"myplugin"}
139140
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":"myplugin"}
140141
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
141142
"rootNames": [

tests/baselines/reference/tsserver/watchEnvironment/watchFactory-as-configuration-of-host-with-pluginoverride-object.js

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ Info 10 [00:00:33.000] For info: /user/username/projects/myproject/a.ts :: Con
139139
Info 11 [00:00:34.000] Creating configuration project /user/username/projects/myproject/tsconfig.json
140140
Info 12 [00:00:35.000] FileWatcher:: Added:: WatchInfo: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}} Project: /user/username/projects/myproject/tsconfig.json WatchType: Config file
141141
CustomRequire:: Resolving myplugin from /a/pluginprobe1/node_modules
142+
Require:: Module myplugin created with config: {"init":"initialConfig","name":"myplugin"} and options: {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
142143
Custom watchFile: /user/username/projects/myproject/tsconfig.json 2000 {"watchFactory":{"name":"myplugin","myconfig":"somethingelse"}}
143144
Info 13 [00:00:36.000] Config: /user/username/projects/myproject/tsconfig.json : {
144145
"rootNames": [

0 commit comments

Comments
 (0)