-
Notifications
You must be signed in to change notification settings - Fork 299
/
Copy pathpostInstall.js
131 lines (125 loc) · 5.94 KB
/
postInstall.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
'use strict';
const { EOL } = require('os');
const colors = require('colors/safe');
const fs = require('fs-extra');
const path = require('path');
const constants = require('../constants');
const child_process = require('child_process');
/**
* In order to get raw kernels working, we reuse the default kernel that jupyterlab ships.
* However it expects to be talking to a websocket which is serializing the messages to strings.
* Our raw kernel is not a web socket and needs to do its own serialization. To do so, we make a copy
* of the default kernel with the serialization stripped out. This is simpler than making a copy of the module
* at runtime.
*/
function createJupyterKernelWithoutSerialization() {
var relativePath = path.join('node_modules', '@jupyterlab', 'services', 'lib', 'kernel', 'default.js');
var filePath = path.join(constants.ExtensionRootDir, relativePath);
if (!fs.existsSync(filePath)) {
throw new Error(
"Jupyter lab default kernel not found '" + filePath + "' (Jupyter Extension post install script)"
);
}
var fileContents = fs.readFileSync(filePath, { encoding: 'utf8' });
var replacedContents = fileContents.replace(
/^const serialize =.*$/gm,
'const serialize = { serialize: (a) => a, deserialize: (a) => a };'
);
if (replacedContents === fileContents) {
throw new Error('Jupyter lab default kernel cannot be made non serializing');
}
var destPath = path.join(path.dirname(filePath), 'nonSerializingKernel.js');
fs.writeFileSync(destPath, replacedContents);
console.log(colors.green(destPath + ' file generated (by Jupyter VSC)'));
}
/**
* Fix compilation issues in jsdom files.
*/
function updateJSDomTypeDefinition() {
var relativePath = path.join('node_modules', '@types', 'jsdom', 'base.d.ts');
var filePath = path.join(constants.ExtensionRootDir, relativePath);
if (!fs.existsSync(filePath)) {
console.warn("JSdom base.d.ts not found '" + filePath + "' (Jupyter Extension post install script)");
return;
}
var fileContents = fs.readFileSync(filePath, { encoding: 'utf8' });
var replacedContents = fileContents.replace(
/\s*globalThis: DOMWindow;\s*readonly \["Infinity"]: number;\s*readonly \["NaN"]: number;/g,
[
'globalThis: DOMWindow;',
'// @ts-ignore',
'readonly ["Infinity"]: number;',
'// @ts-ignore',
'readonly ["NaN"]: number;'
].join(`${EOL} `)
);
if (replacedContents === fileContents) {
console.warn('JSdom base.d.ts not updated');
return;
}
fs.writeFileSync(filePath, replacedContents);
}
/**
* The Variable Explorer currently uses react-data-grid@6.1.0 and is the only component that does.
* We retrieve variable names sorted so there will never be a time where variables are unsorted.
* react-data-grid is on v7+ now and a PR to implement this would cause a lot of cascading changes for us,
* so we modify the compiled javascript so that the react-data-grid is always sorted by something.
*/
function makeVariableExplorerAlwaysSorted() {
const fileNames = ['react-data-grid.js', 'react-data-grid.min.js'];
const alwaysSortedCode = 'case g.NONE:e=r?g.DESC:g.ASC;break;case g.ASC:e=g.DESC;break;case g.DESC:e=g.ASC';
const originalCode =
'case g.NONE:e=r?g.DESC:g.ASC;break;case g.ASC:e=r?g.NONE:g.DESC;break;case g.DESC:e=r?g.ASC:g.NONE';
for (const fileName of fileNames) {
var relativePath = path.join('node_modules', 'react-data-grid', 'dist', fileName);
var filePath = path.join(constants.ExtensionRootDir, relativePath);
if (!fs.existsSync(filePath)) {
throw new Error("react-data-grid dist file not found '" + filePath + "' (pvsc post install script)");
}
var fileContents = fs.readFileSync(filePath, { encoding: 'utf8' });
if (fileContents.indexOf(alwaysSortedCode) > 0) {
// tslint:disable-next-line:no-console
console.log(colors.blue(relativePath + ' file already updated (by Jupyter VSC)'));
return;
}
if (fileContents.indexOf(originalCode) > 0) {
var replacedText = fileContents.replace(originalCode, alwaysSortedCode);
if (fileContents === replacedText) {
throw new Error(`Fix for react-data-grid file ${fileName} failed (pvsc post install script)`);
}
fs.writeFileSync(filePath, replacedText);
// tslint:disable-next-line:no-console
console.log(colors.green(relativePath + ' file updated (by Jupyter VSC)'));
} else {
// tslint:disable-next-line:no-console
console.log(colors.red(relativePath + ' file does not need updating.'));
}
}
}
function fixJupyterLabRenderers() {
const warnings = [];
['node_modules/@jupyterlab/cells/lib/widget.js', 'node_modules/@jupyterlab/rendermime/lib/renderers.js'].forEach(
(file) => {
const filePath = path.join(__dirname, '..', '..', file);
if (!fs.existsSync(filePath)) {
return;
}
const textToReplace = `import marked from 'marked'`;
const textToReplaceWith = `import { marked } from 'marked'`;
const fileContents = fs.readFileSync(filePath, 'utf8').toString();
if (fileContents.indexOf(textToReplace) === -1 && fileContents.indexOf(textToReplaceWith) === -1) {
warnings.push('Unable to find Jupyter marked usage to replace!');
}
fs.writeFileSync(filePath, fileContents.replace(textToReplace, `import { marked } from 'marked'`));
}
);
if (warnings.length === 2) {
throw new Error(warnings[0] + '\n' + warnings[1]);
}
}
fixJupyterLabRenderers();
makeVariableExplorerAlwaysSorted();
createJupyterKernelWithoutSerialization();
updateJSDomTypeDefinition();