feat: add Intellisense for Node.js (#988)

This commit is contained in:
Shelley Vohr 2022-07-20 17:51:49 +02:00 коммит произвёл GitHub
Родитель 56328141fa
Коммит 6e36abfc3b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
12 изменённых файлов: 708 добавлений и 35 удалений

Просмотреть файл

@ -55,6 +55,7 @@
"namor": "^2.0.2",
"node-watch": "^0.7.3",
"p-debounce": "^2.0.0",
"package-json": "^7.0.0",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-mosaic-component": "^4.1.1",
@ -89,6 +90,7 @@
"@types/react": "^16.14.0",
"@types/react-dom": "^16.9.11",
"@types/react-window": "^1.8.5",
"@types/recursive-readdir": "^2.2.0",
"@types/semver": "^7.3.4",
"@types/tmp": "0.2.0",
"@types/valid-url": "^1.0.3",
@ -120,6 +122,7 @@
"npm-run-all": "^4.1.5",
"prettier": "^2.2.1",
"resolve-url-loader": "^5.0.0",
"recursive-readdir": "^2.2.2",
"rimraf": "^3.0.2",
"standard": "^16.0.3",
"stylelint": "^13.11.0",

Просмотреть файл

@ -31,6 +31,7 @@ export interface Version {
version: string;
name?: string;
localPath?: string;
node?: string;
}
export enum RunResult {

Просмотреть файл

@ -42,6 +42,7 @@ export class App {
this.electronTypes = new ElectronTypes(
window.ElectronFiddle.monaco,
path.join(USER_DATA_PATH, 'electron-typedef'),
path.join(USER_DATA_PATH, 'nodejs-typedef'),
);
}

Просмотреть файл

@ -2,8 +2,13 @@ import * as MonacoType from 'monaco-editor';
import * as fs from 'fs-extra';
import * as path from 'path';
import watch from 'node-watch';
import releases from '../../static/releases.json';
import readdir from 'recursive-readdir';
import packageJson from 'package-json';
import semver from 'semver';
import { RunnableVersion, VersionSource } from '../interfaces';
import { RunnableVersion, Version, VersionSource } from '../interfaces';
import { normalizeVersion } from '../utils/normalize-version';
const ELECTRON_DTS = 'electron.d.ts';
@ -15,56 +20,102 @@ const ELECTRON_DTS = 'electron.d.ts';
* - if it's a remote version, fetch() the .d.ts and cache it locally
*/
export class ElectronTypes {
private disposable: MonacoType.IDisposable | undefined;
private disposables: MonacoType.IDisposable[] = [];
private watcher: fs.FSWatcher | undefined;
constructor(
private readonly monaco: typeof MonacoType,
private readonly cacheDir: string,
private readonly electronCacheDir: string,
private readonly nodeCacheDir: string,
) {}
public async setVersion(ver?: RunnableVersion): Promise<void> {
this.clear();
if (!ver) return;
await this.setElectronTypes(ver);
await this.setNodeTypes(ver.version);
}
private async setElectronTypes(ver: RunnableVersion): Promise<void> {
const { localPath: dir, source, version } = ver;
// If it's a local development version, pull Electron types from out directory.
if (dir) {
const file = path.join(dir, 'gen/electron/tsc/typings', ELECTRON_DTS);
this.setTypesFromFile(file, ver);
this.setTypesFromFile(file, version);
try {
this.watcher = watch(file, () => this.setTypesFromFile(file, ver));
this.watcher = watch(file, () => this.setTypesFromFile(file, version));
} catch (err) {
console.debug(`Unable to watch "${file}" for changes: ${err}`);
}
}
// If it's a published version, pull from cached file.
if (source === VersionSource.remote) {
const file = this.getCacheFile(ver);
await ElectronTypes.ensureVersionIsCachedAt(version, file);
this.setTypesFromFile(file, ver);
const file = this.getCacheFile(version);
await this.ensureElectronVersionIsCachedAt(version, file);
this.setTypesFromFile(file, version);
}
}
private async setNodeTypes(version: string): Promise<void> {
// Get the Node.js version corresponding to the current Electron version.
const v = releases.find((release: Version) => {
return normalizeVersion(release.version) === version;
})?.node;
if (!v) return;
const dir = this.getCacheDir(v);
const ver = await this.cacheAndReturnNodeTypesVersion(v, dir);
await this.setTypesFromDir(dir, ver);
}
public uncache(ver: RunnableVersion) {
if (ver.source === VersionSource.remote)
fs.removeSync(this.getCacheFile(ver));
fs.removeSync(this.getCacheFile(ver.version));
}
private setTypesFromFile(file: string, ver: RunnableVersion) {
private async setTypesFromDir(dir: string, version: string) {
this.dispose();
try {
console.log(`Updating Monaco with "${ELECTRON_DTS}@${ver.version}"`);
this.disposable = this.monaco.languages.typescript.javascriptDefaults.addExtraLib(
const files = await readdir(dir);
for (const file of files) {
if (file.endsWith('.d.ts')) {
const { base: filename } = path.parse(file);
console.log(`Updating Monaco with "${filename}@${version}"`);
const lib = this.monaco.languages.typescript.javascriptDefaults.addExtraLib(
fs.readFileSync(file, 'utf8'),
);
this.disposables.push(lib);
}
}
} catch (err) {
console.debug(`Unable to read types from "${dir}": ${err.message}`);
}
}
private setTypesFromFile(file: string, version: string) {
this.dispose();
try {
console.log(`Updating Monaco with "${ELECTRON_DTS}@${version}"`);
const lib = this.monaco.languages.typescript.javascriptDefaults.addExtraLib(
fs.readFileSync(file, 'utf8'),
);
this.disposables.push(lib);
} catch (err) {
console.debug(`Unable to read types from "${file}": ${err.message}`);
}
}
private getCacheFile(ver: RunnableVersion) {
return path.join(this.cacheDir, ver.version, ELECTRON_DTS);
private getCacheFile(version: string) {
return path.join(this.electronCacheDir, version, ELECTRON_DTS);
}
private getCacheDir(version: string) {
return path.join(this.nodeCacheDir, version);
}
private clear() {
@ -73,9 +124,11 @@ export class ElectronTypes {
}
private dispose() {
if (this.disposable) {
this.disposable.dispose();
delete this.disposable;
if (this.disposables.length > 0) {
for (const disposable of this.disposables) {
disposable.dispose();
}
this.disposables = [];
}
}
@ -86,7 +139,63 @@ export class ElectronTypes {
}
}
private static async ensureVersionIsCachedAt(version: string, file: string) {
/**
* This function ensures that the Node.js version for a given version of
* Electron is downloaded and cached. It can be the case that DefinitelyTyped
* doesn't have specific Node.js versions, and if it's missing a certain version,
* we instead download the most recent version of Node.js in that release line older
* than the target version and return that. This also allows Electron versions to share
* versions of Node.js types.
*
* @param version - version of Node.js to fetch types for.
* @param dir - directory where the Node.js types version may be stored.
* @returns the version of Node.js types for this version of Electron.
*/
private async cacheAndReturnNodeTypesVersion(version: string, dir: string) {
if (fs.existsSync(dir)) return version;
let downloadVersion = version;
let response = await fetch(
`https://unpkg.com/@types/node@${version}/?meta`,
);
if (response.status === 404) {
const types = await packageJson('@types/node', {
version: semver.major(version).toString(),
fullMetadata: false,
});
downloadVersion = types.version as string;
console.log(
`falling back to the latest applicable Node.js version type: ${downloadVersion}`,
);
const maybeCachedDir = path.join(this.nodeCacheDir, downloadVersion);
if (fs.existsSync(maybeCachedDir)) return downloadVersion;
response = await fetch(
`https://unpkg.com/@types/node@${downloadVersion}/?meta`,
);
}
const { files: fileJson } = await response.json();
fileJson
.flatMap((item: { files?: { path: string }[]; path: string }) => {
return item.files ? item.files.map((f: any) => f.path) : item.path;
})
.filter((path: string) => path.endsWith('.d.ts'))
.map(async (path: string) => {
const res = await fetch(
`https://unpkg.com/@types/node@${downloadVersion}${path}`,
);
const text = await res.text();
await fs.outputFileSync(`${dir}${path}`, text);
});
return downloadVersion;
}
private async ensureElectronVersionIsCachedAt(version: string, file: string) {
if (fs.existsSync(file)) return;
const name = version.includes('nightly') ? 'electron-nightly' : 'electron';

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

464
tests/fixtures/node-types.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,464 @@
[
{
"path": "/LICENSE",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-yWgCRx67lpqaSTXwZCh+wBD99dMrZpUCSCioemYwrmohaFB5gXhsuOgT76ezQKOv",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 1141
},
{
"path": "/README.md",
"type": "file",
"contentType": "text/markdown",
"integrity": "sha384-dIIngn2EIZkAJj3AaDHuGptA7IlfbE5NYs+PL36pRpw1hvONz82b4e4m8y1vaADO",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 2482
},
{
"path": "/assert.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-aVDpKnDCrODPmsYC+nG5u88KejmDfpHuH47auur+7vQpidt26FTffEDQdrWiQT77",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 38561
},
{
"path": "/async_hooks.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-779C6cx/lwi/y9KcMilZTWD5sAv+Io4H3A5umjL9Vd1UZvArhX46pUBigXbJL9VV",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 20764
},
{
"path": "/buffer.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-6zqAkHHkgUecgYj7PcSOq0nHGDPAN2/FLXS/1Yk0D/MraKZqnmo1b8tmhB1gJ+OD",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 102086
},
{
"path": "/child_process.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-wP8rsAv01nin361bDlnIfYHICSbR0QlMTon6iuqEeexnAglbPz8mxV3v7tU/OAuP",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 66120
},
{
"path": "/cluster.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-o1bofDyeh6lzsS89Tg6CU+RQXOoagQJBW0xbCsbS7s/+iyv23glQNeIPRmn1QVDn",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 20539
},
{
"path": "/console.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-xyzuf7Zku3CPqbl2rJ5VlZZoHufrdBByGcRjH2GjphX1RwNyQ17KGPkxB9943DiA",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 18331
},
{
"path": "/constants.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-OFa2LcDjpUEulO2UQ2ODaBH4cKnp2M16CJnI+yiYRi+SfRTn0WMwQ4r/CJDsxNCn",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 613
},
{
"path": "/crypto.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-CbSqhgy8JKXc4mTBZ/QJkGXZUQX+fC0x/Cs8V3xojyH6Lrq5t8htyqSQRJokEyIp",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 152388
},
{
"path": "/dgram.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-zx2NcwTt/P4kr38B+vK88hBBWHqPYsDqrrsY/bQXkefbLpA/DzUK/LamLCI5K8+Y",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 26733
},
{
"path": "/diagnostics_channel.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-jEfeQTk8mC1P2h3kG6VbIqa14rjrVBEKAOktGOLdF45zgmmBtZ1X0sQs2emSUwW6",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 5936
},
{
"path": "/dns.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-n0D8X2QZenDyPGYWNtFrEDgL0airfA4er6EmanrgAxQv6sdnHfJnW5Rzqhcs2BSk",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 29576
},
{
"path": "/domain.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-hmyKHE8ZplUeHoU0ZXRZdXoP0RIp7DRHWR2BJn+dtDJsxgKzNqbhzhyuSKIulRXE",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 7809
},
{
"path": "/events.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-6oLm5EXlnRFBjhWqCQXh1JD9iJ4+PThdNvFl7vsxKqvhbByO/ZtMj9dk8P2ZoP4g",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 27849
},
{
"path": "/fs.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-dIg9GDCVelFJCmd4FW3FTVnGOGavivOlM0YJDAey2xgIZcdGrcqL8HTg7lpFhmA3",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 172480
},
{
"path": "/globals.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-QTpU5c8wJ3EzhE4xKXUe4hhMn8FLWJ+awa8HFl4DzbyxaaCIl6kmZwxhZJV5wrOe",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 9040
},
{
"path": "/globals.global.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-D3Zgwr8vn7w6zsEw3mR9reGjcelPGd3kReXiewwqT9FVhYE9RNFHxYzV0cFeAMcR",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 39
},
{
"path": "/http.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-4NiB4h02evZQUrYmjd9iqz0/KQGld+7LBQzNNQEzWOdp1h7FPBat2vjXlMmNvHAA",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 63884
},
{
"path": "/http2.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-85Wv25qZ+Zmz33y6VJ0505d39SpUcEpsO7leK8O9WNqIC95OHaJ2au9n0qUrZePu",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 112377
},
{
"path": "/https.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-7MiscC8x9DClXE4xfpwH/6QPnCcncnXLnuk4uHh2E1Fe6fytg0Xo0ErzQAf7Vhq0",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 21371
},
{
"path": "/index.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-M6q+PEt2iCk9rwHvaYRAzkRA12LRHln8d1iJunnHwHu63dPPqZirIP4ut0q1dqfF",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 6393
},
{
"path": "/inspector.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-l+zYLENXsahu/19jOiUEExDx78jZWsnV+jcgt+s6cnm4YRh/zKbzJCleHFr48AYu",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 125429
},
{
"path": "/module.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-pUfNXtfxoXWZ3V+2B4moLoDpDxTwb30c3focVDqUH5UnpdlScIo1m9scGiWqaVaM",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 4089
},
{
"path": "/net.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-cdmhKKSzUJOoEzqnX2RjhoMYCf7+cDka4+DsIPNpr592/HGpP3S2InknVLwrpjax",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 36666
},
{
"path": "/os.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-D8A9d7G3BPsO+2bO+FWTPDSdcsUshAnnhnnsNprR+NuHt7cLyoCMl24sp0B12zsP",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 16674
},
{
"path": "/package.json",
"type": "file",
"contentType": "application/json",
"integrity": "sha384-XF1p5s5zHrJxDG6Vuv0G7FV5EV5/HK6JIH0SKHYnh+JLPz67Xa8Qcq5w+dKQvKbI",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 6785
},
{
"path": "/path.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-u3jZr0EMkdi4QnTJ0R08uPt2P4rpYjvgGhSWX4/7z04DWdg4xm7TgQ3QugrN2svv",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 7064
},
{
"path": "/perf_hooks.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-6XDpMYytR9j8xUvQjki2FMSodzXV5VGCyyji8CtcO22l7xiCJeonhVkTSnbP1c42",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 21006
},
{
"path": "/process.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-azscyY6LckF3yyd4+otuBLBG0KAy3oPq3CIN+YVFJ55nYXlNtoqQ15qyJWUOrXSV",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 72913
},
{
"path": "/punycode.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-9Q8PERMwTcZ2DVzYyoYQBbtI3NGGVIpH3lGiOUOZ6SkP2Wa/Rq7OzvmuhDXei6WA",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 5482
},
{
"path": "/querystring.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-rV2dCE1fIL2A9AcF2GerQfi5vtY5zViOMmkOnixXev3RJ0MGzkYj7IWTOzOZfbSb",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 6487
},
{
"path": "/readline.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-KG02+zYaJ8x5zs7eXT9ptz+Q/CaG92mTJ6Zh0s55Jkh+fy9i8ijF9ZPmb9a54hgX",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 23319
},
{
"path": "/repl.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-jEK+QcDiW8WCxx/Ck7z1CCNaEtvexcpSBgkK7O0TOxADuv2GAeylyEO8Oh+C5KQv",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 19463
},
{
"path": "/stream.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-ZRsdRpdp90yAF/NHNK/Y3yeI23TyXi9wL2mXtcVk2hiNbB3QBtJLIFPXnkCyEQiT",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 64195
},
{
"path": "/string_decoder.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-LgRkg/n9oSaM+mkt6+znfLwpBgLTBl/KUqS8ZQw25yXvn49t/tP4WT6R8diQ7CCR",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 2818
},
{
"path": "/timers.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-BcgqsL3K7iJsxigxRviXoxFTUZAyHfY8A09ma/yGf5Ss+9MMtOggAPBmFCysEdF3",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 4604
},
{
"path": "/tls.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-LrNEgIGRJ6LRyDY/3LaUcOFXjtcRJhcISk4LqCbATGWXdS7sdrHkau/ttQQHU+lf",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 50719
},
{
"path": "/trace_events.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-TI5ZIzl9v7X23uS2t71XtAMyTtv0UcVlD3UHfkPiCcbyfH9yOxToobIwve1N/Bl4",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 6780
},
{
"path": "/tty.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-A8eu7v4Umkt/2CXT52ZOwmbFMDseVus8DWgnVOk0DE2N13yRXEtHGERnftVS28d9",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 9854
},
{
"path": "/url.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-QB/VKEKiQ34G0yk4L5ajeXwKiy4O3GY5B3yle2KSkRnjBwI1XCjjGzmz+e/EE65S",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 36480
},
{
"path": "/util.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-gYZc8ldwlDNVfPzcPwskL3YthdXbDA1EJPdfvElh9nBfMTJdQSyp8xyaeRGD97qc",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 64278
},
{
"path": "/v8.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-0DwB9Ky1fJmpQcBmMxyhlX8+shSA+QsCQwqVC9qWZ7BSZ10Btek7qsDNKntd4dhb",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 15249
},
{
"path": "/vm.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-8L9Q1uF34uJFaLBJGuhMbaoTb8Ymguu+uGseSxSRa3cN93vNYr1JKCvF7PBYegrg",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 20970
},
{
"path": "/wasi.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-pdMvWz6jvpa2b/TKJonrhiALPv1SkMruQsB3192Qn3gs1qqnsN+/XBMIdaAIqUpx",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 7051
},
{
"path": "/worker_threads.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-/wT+uq/EggMBIVbC6xNUh/4xtj4pspT9BVQPIRYs12bsOrAGdc1Ditb19mAGNSmZ",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 32204
},
{
"path": "/zlib.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-B0NXKiIeISWaAm+9y2FHYDM6S+EKyA3dvRFpZ+zfmld3tXU2bq1dch3ubLUJGH8D",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 19520
},
{
"path": "/assert",
"type": "directory",
"files": [
{
"path": "/assert/strict.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-hPKOzyKqYRa3itWbeXHu4ICyoyJsZetRnsF/XMwlGG5jhkbAW4I9o+D/S/vAShZv",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 201
}
]
},
{
"path": "/dns",
"type": "directory",
"files": [
{
"path": "/dns/promises.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-WCfGD97bIYOwKyEXa5LuYjgXR25ytou8uDZvoSwQQvw8/5bc3kgXZasPmdqWDxLp",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 15584
}
]
},
{
"path": "/fs",
"type": "directory",
"files": [
{
"path": "/fs/promises.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-HfIuD5zly5XTjjzdos0Ws9lqoLZqoCzbKKbGG2cgyK9qAa1D8ygPWze9OOImp/9R",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 49731
}
]
},
{
"path": "/stream",
"type": "directory",
"files": [
{
"path": "/stream/consumers.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-taj+b9yxduQCdUGWNmyyLTdKXtMqbQIARVngE/hx0M+UYAeNN8AgDATbj9YSBCuZ",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 1196
},
{
"path": "/stream/promises.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-oOLBPzo/WclEJl0G9y8OIRQKrUpswZQK3YFNUcZZKTMWjXFAOagSr+uU93yILWCK",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 2374
},
{
"path": "/stream/web.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-43zv2RgZyP8QI75DkUIrGD3m7nkWER8UMdryhJf5CZNcFu/jRgTf8L6VTOL5+S9R",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 13927
}
]
},
{
"path": "/timers",
"type": "directory",
"files": [
{
"path": "/timers/promises.d.ts",
"type": "file",
"contentType": "text/plain",
"integrity": "sha384-H5VV0TH88hZ2iHYxlAdsC/qAt6bTz/jwLQ1fFQr1ooVHkiMldiK7YH/XTFDctYIf",
"lastModified": "Wed, 15 Jun 2022 15:01:36 GMT",
"size": 1954
}
]
}
]

Просмотреть файл

@ -2,3 +2,12 @@ export class ElectronTypesMock {
public setVersion = jest.fn();
public uncache = jest.fn();
}
export interface NodeTypesMock {
path: string;
type: string;
contentType: string;
integrity: string;
lastModified: string;
size: number;
}

Просмотреть файл

@ -8,7 +8,7 @@ import { MonacoEditorMock, MonacoMock, MonacoModelMock } from './monaco';
import { RemoteLoaderMock } from './remote-loader';
import { RunnerMock } from './runner';
import { StateMock } from './state';
import { ElectronTypesMock } from './electron-types';
import { ElectronTypesMock, NodeTypesMock } from './electron-types';
import { VersionsMock } from './electron-versions';
import { WebContentsMock } from './web-contents';
import { createEditorValues } from './editor-values';
@ -36,6 +36,7 @@ export {
MonacoMock,
MonacoModelMock,
NativeImageMock,
NodeTypesMock,
RemoteLoaderMock,
RunnerMock,
StateMock,

Просмотреть файл

@ -9,7 +9,7 @@ import {
VersionState,
} from '../../src/interfaces';
import { MonacoMock } from '../mocks/mocks';
import { MonacoMock, NodeTypesMock } from '../mocks/mocks';
import { waitFor } from '../utils';
jest.unmock('fs-extra');
@ -24,26 +24,38 @@ describe('ElectronTypes', () => {
let remoteVersion: RunnableVersion;
let tmpdir: tmp.DirResult;
let electronTypes: ElectronTypes;
let nodeTypesData: NodeTypesMock[];
let disposable: { dispose: typeof jest.fn };
beforeEach(() => {
tmpdir = tmp.dirSync({
template: 'electron-fiddle-typedefs-XXXXXX',
unsafeCleanup: true,
});
const cacheDir = path.join(tmpdir.name, 'cache');
const electronCacheDir = path.join(tmpdir.name, 'electron-cache');
const nodeCacheDir = path.join(tmpdir.name, 'node-cache');
const localDir = path.join(tmpdir.name, 'local');
fs.ensureDirSync(cacheDir);
fs.ensureDirSync(electronCacheDir);
fs.ensureDirSync(nodeCacheDir);
fs.ensureDirSync(localDir);
monaco = new MonacoMock();
({ addExtraLib } = monaco.languages.typescript.javascriptDefaults);
disposable = { dispose: jest.fn() };
addExtraLib.mockReturnValue(disposable);
remoteVersion = {
version,
state: VersionState.ready,
source: VersionSource.remote,
} as const;
cacheFile = path.join(cacheDir, remoteVersion.version, 'electron.d.ts');
cacheFile = path.join(
electronCacheDir,
remoteVersion.version,
'electron.d.ts',
);
localVersion = {
version,
@ -53,7 +65,12 @@ describe('ElectronTypes', () => {
} as const;
localFile = path.join(localDir, 'gen/electron/tsc/typings/electron.d.ts');
electronTypes = new ElectronTypes(monaco as any, cacheDir);
electronTypes = new ElectronTypes(
monaco as any,
electronCacheDir,
nodeCacheDir,
);
nodeTypesData = require('../fixtures/node-types.json');
});
afterEach(() => {
@ -64,6 +81,7 @@ describe('ElectronTypes', () => {
function makeFetchSpy(text: string) {
return jest.spyOn(global, 'fetch').mockResolvedValue({
text: () => Promise.resolve(text),
json: () => Promise.resolve({ files: nodeTypesData }),
} as any);
}
@ -88,8 +106,6 @@ describe('ElectronTypes', () => {
it('disposes the previous monaco content', async () => {
// setup: call setVersion once to get some content into monaco
const disposable = { dispose: jest.fn() };
addExtraLib.mockReturnValue(disposable);
const types = saveTypesFile('some types');
await electronTypes.setVersion(localVersion);
expect(addExtraLib).toHaveBeenCalledWith(types);
@ -139,20 +155,30 @@ describe('ElectronTypes', () => {
});
describe('setVersion({ source: remote })', () => {
beforeEach(() => {
addExtraLib.mockReturnValue({ dispose: jest.fn() });
});
it('fetches types', async () => {
const types = 'here are the types';
const fetchSpy = makeFetchSpy(types);
const version = { ...remoteVersion, version: '15.0.0-nightly.20210628' };
await electronTypes.setVersion(version);
// test that the types are fetched
expect(fetchSpy).toHaveBeenCalledTimes(1);
expect(fetchSpy).toHaveBeenLastCalledWith(
expect(fetchSpy).toHaveBeenCalledTimes(nodeTypesData.length + 1);
expect(fetchSpy).toHaveBeenCalledWith(
expect.stringMatching('electron-nightly'),
);
// test that setVersion calls addExtraLib with the fetched types
for (const file of nodeTypesData.filter(({ path }) =>
path.endsWith('.d.ts'),
)) {
expect(fetchSpy).toHaveBeenCalledWith(expect.stringMatching(file.path));
}
expect(addExtraLib).toHaveBeenCalledTimes(1);
expect(addExtraLib).toHaveBeenLastCalledWith(types);
expect(addExtraLib).toHaveBeenCalledWith(types);
});
it('caches fetched types', async () => {

Просмотреть файл

@ -16,7 +16,7 @@ async function getReleases() {
async function main() {
const data = await getReleases();
const releases = data.map(({ version }) => ({ version }));
const releases = data.map(({ version, node }) => ({ version, node }));
console.log(`Updating local releases.json with ${releases.length} versions.`);

Просмотреть файл

@ -23,6 +23,7 @@
"noUnusedParameters": true,
"importHelpers": true,
"noEmitHelpers": true,
"resolveJsonModule": true,
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,

Просмотреть файл

@ -2236,6 +2236,13 @@
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/recursive-readdir@^2.2.0":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@types/recursive-readdir/-/recursive-readdir-2.2.1.tgz#330f5ec0b73e8aeaf267a6e056884e393f3543a3"
integrity sha512-Xd+Ptc4/F2ueInqy5yK2FI5FxtwwbX2+VZpcg+9oYsFJVen8qQKGapCr+Bi5wQtHU1cTXT8s+07lo/nKPgu8Gg==
dependencies:
"@types/node" "*"
"@types/responselike@*", "@types/responselike@^1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
@ -4054,6 +4061,11 @@ deep-equal@^1.1.1:
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-is@^0.1.3, deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
@ -5891,7 +5903,7 @@ gonzales-pe@^4.3.0:
dependencies:
minimist "^1.2.5"
got@^11.7.0:
got@^11.7.0, got@^11.8.2:
version "11.8.5"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.5.tgz#ce77d045136de56e8f024bebb82ea349bc730046"
integrity sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==
@ -6344,7 +6356,7 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
ini@^1.3.4, ini@^1.3.5:
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@ -8651,6 +8663,16 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
package-json@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/package-json/-/package-json-7.0.0.tgz#1355416e50a5c1b8f1a6f471197a3650d21186bf"
integrity sha512-CHJqc94AA8YfSLHGQT3DbvSIuE12NLFekpM4n7LRrAd3dOJtA911+4xe9q6nC3/jcKraq7nNS9VxgtT0KC+diA==
dependencies:
got "^11.8.2"
registry-auth-token "^4.0.0"
registry-url "^5.0.0"
semver "^7.3.5"
pako@~1.0.2:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@ -9261,6 +9283,16 @@ raw-body@2.5.1:
iconv-lite "0.4.24"
unpipe "1.0.0"
rc@1.2.8, rc@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
rcedit@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-3.0.1.tgz#ae21b43e49c075f4d84df1929832a12c302f3c90"
@ -9496,6 +9528,13 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
recursive-readdir@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f"
integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==
dependencies:
minimatch "3.0.4"
redent@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f"
@ -9539,6 +9578,20 @@ regexpp@^3.0.0, regexpp@^3.1.0:
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
registry-auth-token@^4.0.0:
version "4.2.2"
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac"
integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==
dependencies:
rc "1.2.8"
registry-url@^5.0.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009"
integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==
dependencies:
rc "^1.2.8"
relateurl@^0.2.7:
version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
@ -10476,6 +10529,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
strip-outer@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631"