···11+#!/usr/bin/env node
22+33+const {existsSync} = require(`fs`);
44+const {createRequire, createRequireFromPath} = require(`module`);
55+const {resolve} = require(`path`);
66+77+const relPnpApiPath = "../../../../.pnp.cjs";
88+99+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
1010+const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
1111+1212+if (existsSync(absPnpApiPath)) {
1313+ if (!process.versions.pnp) {
1414+ // Setup the environment to be able to require typescript/bin/tsc
1515+ require(absPnpApiPath).setup();
1616+ }
1717+}
1818+1919+// Defer to the real typescript/bin/tsc your application uses
2020+module.exports = absRequire(`typescript/bin/tsc`);
+20
.yarn/sdks/typescript/bin/tsserver
···11+#!/usr/bin/env node
22+33+const {existsSync} = require(`fs`);
44+const {createRequire, createRequireFromPath} = require(`module`);
55+const {resolve} = require(`path`);
66+77+const relPnpApiPath = "../../../../.pnp.cjs";
88+99+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
1010+const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
1111+1212+if (existsSync(absPnpApiPath)) {
1313+ if (!process.versions.pnp) {
1414+ // Setup the environment to be able to require typescript/bin/tsserver
1515+ require(absPnpApiPath).setup();
1616+ }
1717+}
1818+1919+// Defer to the real typescript/bin/tsserver your application uses
2020+module.exports = absRequire(`typescript/bin/tsserver`);
+20
.yarn/sdks/typescript/lib/tsc.js
···11+#!/usr/bin/env node
22+33+const {existsSync} = require(`fs`);
44+const {createRequire, createRequireFromPath} = require(`module`);
55+const {resolve} = require(`path`);
66+77+const relPnpApiPath = "../../../../.pnp.cjs";
88+99+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
1010+const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
1111+1212+if (existsSync(absPnpApiPath)) {
1313+ if (!process.versions.pnp) {
1414+ // Setup the environment to be able to require typescript/lib/tsc.js
1515+ require(absPnpApiPath).setup();
1616+ }
1717+}
1818+1919+// Defer to the real typescript/lib/tsc.js your application uses
2020+module.exports = absRequire(`typescript/lib/tsc.js`);
+125
.yarn/sdks/typescript/lib/tsserver.js
···11+#!/usr/bin/env node
22+33+const {existsSync} = require(`fs`);
44+const {createRequire, createRequireFromPath} = require(`module`);
55+const {resolve} = require(`path`);
66+77+const relPnpApiPath = "../../../../.pnp.cjs";
88+99+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
1010+const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
1111+1212+const moduleWrapper = tsserver => {
1313+ const {isAbsolute} = require(`path`);
1414+ const pnpApi = require(`pnpapi`);
1515+1616+ const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => {
1717+ return `${locator.name}@${locator.reference}`;
1818+ }));
1919+2020+ // VSCode sends the zip paths to TS using the "zip://" prefix, that TS
2121+ // doesn't understand. This layer makes sure to remove the protocol
2222+ // before forwarding it to TS, and to add it back on all returned paths.
2323+2424+ function toEditorPath(str) {
2525+ // We add the `zip:` prefix to both `.zip/` paths and virtual paths
2626+ if (isAbsolute(str) && !str.match(/^\^zip:/) && (str.match(/\.zip\//) || str.match(/\/(\$\$virtual|__virtual__)\//))) {
2727+ // We also take the opportunity to turn virtual paths into physical ones;
2828+ // this makes is much easier to work with workspaces that list peer
2929+ // dependencies, since otherwise Ctrl+Click would bring us to the virtual
3030+ // file instances instead of the real ones.
3131+ //
3232+ // We only do this to modules owned by the the dependency tree roots.
3333+ // This avoids breaking the resolution when jumping inside a vendor
3434+ // with peer dep (otherwise jumping into react-dom would show resolution
3535+ // errors on react).
3636+ //
3737+ const resolved = pnpApi.resolveVirtual(str);
3838+ if (resolved) {
3939+ const locator = pnpApi.findPackageLocator(resolved);
4040+ if (locator && dependencyTreeRoots.has(`${locator.name}@${locator.reference}`)) {
4141+ str = resolved;
4242+ }
4343+ }
4444+4545+ str = str.replace(/\\/g, `/`)
4646+ str = str.replace(/^\/?/, `/`);
4747+4848+ // Absolute VSCode `Uri.fsPath`s need to start with a slash.
4949+ // VSCode only adds it automatically for supported schemes,
5050+ // so we have to do it manually for the `zip` scheme.
5151+ // The path needs to start with a caret otherwise VSCode doesn't handle the protocol
5252+ //
5353+ // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910
5454+ //
5555+ if (str.match(/\.zip\//)) {
5656+ str = `${isVSCode ? `^` : ``}zip:${str}`;
5757+ }
5858+ }
5959+6060+ return str;
6161+ }
6262+6363+ function fromEditorPath(str) {
6464+ return process.platform === `win32`
6565+ ? str.replace(/^\^?zip:\//, ``)
6666+ : str.replace(/^\^?zip:/, ``);
6767+ }
6868+6969+ // Force enable 'allowLocalPluginLoads'
7070+ // TypeScript tries to resolve plugins using a path relative to itself
7171+ // which doesn't work when using the global cache
7272+ // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238
7373+ // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but
7474+ // TypeScript already does local loads and if this code is running the user trusts the workspace
7575+ // https://github.com/microsoft/vscode/issues/45856
7676+ const ConfiguredProject = tsserver.server.ConfiguredProject;
7777+ const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype;
7878+ ConfiguredProject.prototype.enablePluginsWithOptions = function() {
7979+ this.projectService.allowLocalPluginLoads = true;
8080+ return originalEnablePluginsWithOptions.apply(this, arguments);
8181+ };
8282+8383+ // And here is the point where we hijack the VSCode <-> TS communications
8484+ // by adding ourselves in the middle. We locate everything that looks
8585+ // like an absolute path of ours and normalize it.
8686+8787+ const Session = tsserver.server.Session;
8888+ const {onMessage: originalOnMessage, send: originalSend} = Session.prototype;
8989+ let isVSCode = false;
9090+9191+ return Object.assign(Session.prototype, {
9292+ onMessage(/** @type {string} */ message) {
9393+ const parsedMessage = JSON.parse(message)
9494+9595+ if (
9696+ parsedMessage != null &&
9797+ typeof parsedMessage === `object` &&
9898+ parsedMessage.arguments &&
9999+ parsedMessage.arguments.hostInfo === `vscode`
100100+ ) {
101101+ isVSCode = true;
102102+ }
103103+104104+ return originalOnMessage.call(this, JSON.stringify(parsedMessage, (key, value) => {
105105+ return typeof value === `string` ? fromEditorPath(value) : value;
106106+ }));
107107+ },
108108+109109+ send(/** @type {any} */ msg) {
110110+ return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => {
111111+ return typeof value === `string` ? toEditorPath(value) : value;
112112+ })));
113113+ }
114114+ });
115115+};
116116+117117+if (existsSync(absPnpApiPath)) {
118118+ if (!process.versions.pnp) {
119119+ // Setup the environment to be able to require typescript/lib/tsserver.js
120120+ require(absPnpApiPath).setup();
121121+ }
122122+}
123123+124124+// Defer to the real typescript/lib/tsserver.js your application uses
125125+module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`));
+20
.yarn/sdks/typescript/lib/typescript.js
···11+#!/usr/bin/env node
22+33+const {existsSync} = require(`fs`);
44+const {createRequire, createRequireFromPath} = require(`module`);
55+const {resolve} = require(`path`);
66+77+const relPnpApiPath = "../../../../.pnp.cjs";
88+99+const absPnpApiPath = resolve(__dirname, relPnpApiPath);
1010+const absRequire = (createRequire || createRequireFromPath)(absPnpApiPath);
1111+1212+if (existsSync(absPnpApiPath)) {
1313+ if (!process.versions.pnp) {
1414+ // Setup the environment to be able to require typescript/lib/typescript.js
1515+ require(absPnpApiPath).setup();
1616+ }
1717+}
1818+1919+// Defer to the real typescript/lib/typescript.js your application uses
2020+module.exports = absRequire(`typescript/lib/typescript.js`);
···11+MIT License
22+33+Copyright (c) 2021 Daniel Roe
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.