Support built in extensions in serverless

- Use different entry point instead of static extensions
- Intrdouce web extension management service
This commit is contained in:
Sandeep Somavarapu
2020-06-18 15:21:17 +02:00
parent 9683615c00
commit 7c574546f7
10 changed files with 180 additions and 77 deletions

View File

@@ -6,7 +6,6 @@
*--------------------------------------------------------------------------------------------*/
// @ts-check
/** @typedef {import('../../src/vs/workbench/workbench.web.api').IWorkbenchConstructionOptions} WebConfiguration **/
const http = require('http');
const url = require('url');
@@ -62,27 +61,46 @@ const exists = (path) => util.promisify(fs.exists)(path);
const readFile = (path) => util.promisify(fs.readFile)(path);
const CharCode_PC = '%'.charCodeAt(0);
function toStaticExtensionUri(path) {
return { scheme: SCHEME, authority: AUTHORITY, path: `/static-extension/${path}` };
}
async function initialize() {
const extensionFolders = await util.promisify(fs.readdir)(EXTENSIONS_ROOT);
const staticExtensions = [];
const builtinExtensions = [];
const webpackConfigs = [];
await Promise.all(extensionFolders.map(async extensionFolder => {
const packageJSONPath = path.join(EXTENSIONS_ROOT, extensionFolder, 'package.json');
const children = await util.promisify(fs.readdir)(EXTENSIONS_ROOT, { withFileTypes: true });
const folders = children.filter(c => !c.isFile());
await Promise.all(folders.map(async folder => {
const folderName = folder.name;
const extensionPath = path.join(EXTENSIONS_ROOT, folderName);
let children = [];
try {
children = await util.promisify(fs.readdir)(extensionPath);
} catch (error) {
console.log(error);
return;
}
const readme = children.filter(child => /^readme(\.txt|\.md|)$/i.test(child))[0];
const readmeUrl = readme ? toStaticExtensionUri(path.join(extensionPath, readme)) : undefined;
const changelog = children.filter(child => /^changelog(\.txt|\.md|)$/i.test(child))[0];
const changelogUrl = changelog ? toStaticExtensionUri(path.join(extensionPath, changelog)) : undefined;
const packageJSONPath = path.join(EXTENSIONS_ROOT, folderName, 'package.json');
if (await exists(packageJSONPath)) {
try {
const packageJSON = JSON.parse((await readFile(packageJSONPath)).toString());
if (packageJSON.main && !packageJSON.browser) {
const manifest = JSON.parse((await readFile(packageJSONPath)).toString());
if (manifest.main && !manifest.browser) {
return; // unsupported
}
if (packageJSON.browser) {
packageJSON.main = packageJSON.browser;
if (manifest.browser) {
manifest.main = manifest.browser;
const webpackConfigLocations = await util.promisify(glob)(
path.join(EXTENSIONS_ROOT, extensionFolder, '**', 'extension-browser.webpack.config.js'),
path.join(EXTENSIONS_ROOT, folderName, '**', 'extension-browser.webpack.config.js'),
{ ignore: ['**/node_modules'] }
);
@@ -99,7 +117,7 @@ async function initialize() {
}
}
const packageNlsPath = path.join(EXTENSIONS_ROOT, extensionFolder, 'package.nls.json');
const packageNlsPath = path.join(EXTENSIONS_ROOT, folderName, 'package.nls.json');
if (await exists(packageNlsPath)) {
const packageNls = JSON.parse((await readFile(packageNlsPath)).toString());
const translate = (obj) => {
@@ -117,13 +135,15 @@ async function initialize() {
}
}
};
translate(packageJSON);
translate(manifest);
}
packageJSON.extensionKind = ['web']; // enable for Web
staticExtensions.push({
packageJSON,
extensionLocation: { scheme: SCHEME, authority: AUTHORITY, path: `/static-extension/${extensionFolder}` },
isBuiltin: true
manifest.extensionKind = ['web']; // enable for Web
builtinExtensions.push({
identifier: { id: `${manifest.publisher}.${manifest.name}`},
manifest,
location: toStaticExtensionUri(folderName),
readmeUrl,
changelogUrl
});
} catch (e) {
console.log(e);
@@ -139,7 +159,7 @@ async function initialize() {
reject();
} else {
console.log(stats.toString());
resolve(staticExtensions);
resolve(builtinExtensions);
}
});
} else {
@@ -149,14 +169,14 @@ async function initialize() {
reject();
} else {
console.log(stats.toString());
resolve(staticExtensions);
resolve(builtinExtensions);
}
});
}
});
}
const staticExtensionsPromise = initialize();
const builtinExtensionsPromise = initialize();
const mapCallbackUriToRequestId = new Map();
@@ -262,14 +282,9 @@ async function handleRoot(req, res) {
}
}
const staticExtensions = await staticExtensionsPromise;
/** @type {WebConfiguration} */
const webConfig = {
staticExtensions: staticExtensions,
};
const builtinExtensions = await builtinExtensionsPromise;
const webConfigJSON = escapeAttribute(JSON.stringify({
...webConfig,
folderUri: ghPath
? { scheme: 'github', authority: 'HEAD', path: ghPath }
: { scheme: 'memfs', path: `/sample-folder` },
@@ -277,6 +292,7 @@ async function handleRoot(req, res) {
const data = (await util.promisify(fs.readFile)(WEB_MAIN)).toString()
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', () => webConfigJSON) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied
.replace('{{WORKBENCH_BUILTIN_EXTENSIONS}}', () => escapeAttribute(JSON.stringify(builtinExtensions)))
.replace('{{WEBVIEW_ENDPOINT}}', '')
.replace('{{REMOTE_USER_DATA_URI}}', '');