mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 10:41:56 -05:00
Allow plugins to be loaded from package subpaths (#57266)
Co-authored-by: Sheetal Nandi <sheetalkamat@users.noreply.github.com>
This commit is contained in:
@@ -66,6 +66,7 @@ import {
|
||||
IncompleteCompletionsCache,
|
||||
IndentStyle,
|
||||
isArray,
|
||||
isExternalModuleNameRelative,
|
||||
isIgnoredFileFromWildCardWatching,
|
||||
isInsideNodeModules,
|
||||
isJsonEqual,
|
||||
@@ -90,7 +91,6 @@ import {
|
||||
ParsedCommandLine,
|
||||
parseJsonSourceFileConfigFileContent,
|
||||
parseJsonText,
|
||||
parsePackageName,
|
||||
Path,
|
||||
PerformanceEvent,
|
||||
PluginImport,
|
||||
@@ -4474,7 +4474,11 @@ export class ProjectService {
|
||||
}
|
||||
|
||||
this.logger.info(`Enabling plugin ${pluginConfigEntry.name} from candidate paths: ${searchPaths.join(",")}`);
|
||||
if (!pluginConfigEntry.name || parsePackageName(pluginConfigEntry.name).rest) {
|
||||
if (
|
||||
!pluginConfigEntry.name ||
|
||||
isExternalModuleNameRelative(pluginConfigEntry.name) ||
|
||||
/[\\/]\.\.?($|[\\/])/.test(pluginConfigEntry.name)
|
||||
) {
|
||||
this.logger.info(`Skipped loading plugin ${pluginConfigEntry.name || JSON.stringify(pluginConfigEntry)} because only package name is allowed plugin name`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,20 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
|
||||
}
|
||||
|
||||
it("With local plugins", () => {
|
||||
const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"];
|
||||
const notToLoad = ["../myPlugin", "myPlugin/../malicious"];
|
||||
const expectedToLoad = [
|
||||
"@myscoped/plugin",
|
||||
"@myscoped/plugin/subpath",
|
||||
"@myscoped/plugin/sub/path",
|
||||
"unscopedPlugin",
|
||||
"unscopedPlugin/subpath",
|
||||
"unscopedPlugin/sub/path",
|
||||
];
|
||||
const notToLoad = [
|
||||
"../myPlugin",
|
||||
"@myscoped/plugin/../malicious",
|
||||
"myPlugin/../malicious",
|
||||
"myPlugin/subpath/../../malicious",
|
||||
];
|
||||
const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` };
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
@@ -65,8 +77,20 @@ describe("unittests:: tsserver:: plugins:: loading", () => {
|
||||
});
|
||||
|
||||
it("With global plugins", () => {
|
||||
const expectedToLoad = ["@myscoped/plugin", "unscopedPlugin"];
|
||||
const notToLoad = ["../myPlugin", "myPlugin/../malicious"];
|
||||
const expectedToLoad = [
|
||||
"@myscoped/plugin",
|
||||
"@myscoped/plugin/subpath",
|
||||
"@myscoped/plugin/sub/path",
|
||||
"unscopedPlugin",
|
||||
"unscopedPlugin/subpath",
|
||||
"unscopedPlugin/sub/path",
|
||||
];
|
||||
const notToLoad = [
|
||||
"../myPlugin",
|
||||
"@myscoped/plugin/../malicious",
|
||||
"myPlugin/../malicious",
|
||||
"myPlugin/subpath/../../malicious",
|
||||
];
|
||||
const aTs: File = { path: "/a.ts", content: `class c { prop = "hello"; foo() { return this.prop; } }` };
|
||||
const tsconfig: File = {
|
||||
path: "/tsconfig.json",
|
||||
|
||||
@@ -60,17 +60,43 @@ Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin from candidate paths:
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin
|
||||
Info seq [hh:mm:ss:mss] Plugin validation succeeded
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin @myscoped/plugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/subpath from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin/subpath from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin @myscoped/plugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/sub/path from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin/sub/path from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin unscopedPlugin
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin unscopedPlugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin/subpath from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin/subpath from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin unscopedPlugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin/sub/path from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin/sub/path from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin ../myPlugin
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin ../myPlugin from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin ../myPlugin because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin @myscoped/plugin/../malicious
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin @myscoped/plugin/../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin myPlugin/../malicious
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin myPlugin/../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin myPlugin/../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Loading global plugin myPlugin/subpath/../../malicious
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin myPlugin/subpath/../../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin myPlugin/subpath/../../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info
|
||||
Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json
|
||||
Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms
|
||||
|
||||
@@ -11,15 +11,33 @@ class c { prop = "hello"; foo() { return this.prop; } }
|
||||
{
|
||||
"name": "@myscoped/plugin"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/subpath"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/sub/path"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin/subpath"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin/sub/path"
|
||||
},
|
||||
{
|
||||
"name": "../myPlugin"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/../malicious"
|
||||
},
|
||||
{
|
||||
"name": "myPlugin/../malicious"
|
||||
},
|
||||
{
|
||||
"name": "myPlugin/subpath/../../malicious"
|
||||
},
|
||||
{
|
||||
"transform": "some-transform"
|
||||
}
|
||||
@@ -74,15 +92,33 @@ Info seq [hh:mm:ss:mss] Config: /tsconfig.json : {
|
||||
{
|
||||
"name": "@myscoped/plugin"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/subpath"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/sub/path"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin/subpath"
|
||||
},
|
||||
{
|
||||
"name": "unscopedPlugin/sub/path"
|
||||
},
|
||||
{
|
||||
"name": "../myPlugin"
|
||||
},
|
||||
{
|
||||
"name": "@myscoped/plugin/../malicious"
|
||||
},
|
||||
{
|
||||
"name": "myPlugin/../malicious"
|
||||
},
|
||||
{
|
||||
"name": "myPlugin/subpath/../../malicious"
|
||||
},
|
||||
{
|
||||
"transform": "some-transform"
|
||||
}
|
||||
@@ -96,14 +132,34 @@ Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin from candidate paths:
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin
|
||||
Info seq [hh:mm:ss:mss] Plugin validation succeeded
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/subpath from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin/subpath from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/sub/path from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading @myscoped/plugin/sub/path from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: @myscoped/plugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin/subpath from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin/subpath from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin/subpath
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin unscopedPlugin/sub/path from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Loading unscopedPlugin/sub/path from /a/lib/tsc.js/../../.. (resolved to /a/lib/tsc.js/../../../node_modules)
|
||||
Loading plugin: unscopedPlugin/sub/path
|
||||
Info seq [hh:mm:ss:mss] Plugin activation failed: Error: Protocol handler already exists for command "testProtocolCommand"
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin ../myPlugin from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin ../myPlugin because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin @myscoped/plugin/../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin @myscoped/plugin/../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin myPlugin/../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin myPlugin/../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin myPlugin/subpath/../../malicious from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin myPlugin/subpath/../../malicious because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] Enabling plugin undefined from candidate paths: /a/lib/tsc.js/../../..
|
||||
Info seq [hh:mm:ss:mss] Skipped loading plugin {"transform":"some-transform"} because only package name is allowed plugin name
|
||||
Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info
|
||||
@@ -155,6 +211,12 @@ Info seq [hh:mm:ss:mss] event:
|
||||
},
|
||||
"compilerOptions": {
|
||||
"plugins": [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
||||
Reference in New Issue
Block a user