/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import path = require('path'); import fs = require('fs'); import { REPO_ROOT, readFiles, writeFiles, IFile, readFile } from '../build/utils'; import { removeDir } from '../build/fs'; import ts = require('typescript'); import { generateMetadata } from './releaseMetadata'; removeDir(`out/monaco-editor`); // dev folder AMD_releaseOne('dev'); // min folder AMD_releaseOne('min'); // esm folder ESM_release(); // monaco.d.ts, editor.api.d.ts releaseDTS(); // ThirdPartyNotices.txt releaseThirdPartyNotices(); // esm/metadata.d.ts, esm/metadata.js generateMetadata(); // package.json (() => { const packageJSON = readFiles('package.json', { base: '' })[0]; const json = JSON.parse(packageJSON.contents.toString()); json.private = false; delete json.scripts['postinstall']; packageJSON.contents = Buffer.from(JSON.stringify(json, null, ' ')); writeFiles([packageJSON], `out/monaco-editor`); })(); (() => { /** @type {IFile[]} */ let otherFiles = []; otherFiles = otherFiles.concat(readFiles('README.md', { base: '' })); otherFiles = otherFiles.concat(readFiles('CHANGELOG.md', { base: '' })); otherFiles = otherFiles.concat( readFiles('node_modules/monaco-editor-core/min-maps/**/*', { base: 'node_modules/monaco-editor-core/' }) ); otherFiles = otherFiles.concat( readFiles('node_modules/monaco-editor-core/LICENSE', { base: 'node_modules/monaco-editor-core/' }) ); writeFiles(otherFiles, `out/monaco-editor`); })(); /** * Release to `dev` or `min`. */ function AMD_releaseOne(type: 'dev' | 'min') { let coreFiles = readFiles(`node_modules/monaco-editor-core/${type}/**/*`, { base: `node_modules/monaco-editor-core/${type}` }); coreFiles = fixNlsFiles(coreFiles); AMD_addPluginContribs(type, coreFiles); writeFiles(coreFiles, `out/monaco-editor/${type}`); const pluginFiles = readFiles(`out/languages/bundled/amd-${type}/**/*`, { base: `out/languages/bundled/amd-${type}`, ignore: ['**/monaco.contribution.js'] }); writeFiles(pluginFiles, `out/monaco-editor/${type}`); } function fixNlsFiles(files: IFile[]): IFile[] { return files.map((f) => { if (!f.path.match(/nls\.messages\.[a-z\-]+\.js/)) { return f; } const dirName = path.dirname(f.path); const fileName = path.basename(f.path); const newPath = path.join(dirName, 'vs', fileName); let contentStr = f.contents.toString('utf-8'); contentStr = ` define([], function () { ${contentStr} }); `; const newContents = Buffer.from(contentStr, 'utf-8'); return { path: newPath, contents: newContents }; }); } /** * Edit editor.main.js: * - rename the AMD module 'vs/editor/editor.main' to 'vs/editor/edcore.main' * - append monaco.contribution modules from plugins * - append new AMD module 'vs/editor/editor.main' that stiches things together */ function AMD_addPluginContribs(type: 'dev' | 'min', files: IFile[]) { for (const file of files) { if (!/editor\.main\.js$/.test(file.path)) { continue; } let contents = file.contents.toString(); // Rename the AMD module 'vs/editor/editor.main' to 'vs/editor/edcore.main' contents = contents.replace(/"vs\/editor\/editor\.main\"/, '"vs/editor/edcore.main"'); // This ensures that old nls-plugin configurations are still respected by the new localization solution. const contentPrefixSource = readFile('src/nls-fix.js') .contents.toString('utf-8') .replace(/\r\n|\n/g, ' '); // TODO: Instead of adding this source to the header to maintain the source map indices, it should rewrite the sourcemap! const searchValue = 'https://github.com/microsoft/vscode/blob/main/LICENSE.txt'; contents = contents.replace(searchValue, searchValue + ' */ ' + contentPrefixSource + ' /*'); const pluginFiles = readFiles(`out/languages/bundled/amd-${type}/**/monaco.contribution.js`, { base: `out/languages/bundled/amd-${type}` }); const extraContent = pluginFiles.map((file) => { return file.contents .toString() .replace( /define\((['"][a-z\/\-]+\/fillers\/monaco-editor-core['"]),\[\],/, "define($1,['vs/editor/editor.api']," ); }); const allPluginsModuleIds = pluginFiles.map((file) => { return file.path.replace(/\.js$/, ''); }); extraContent.push( `define("vs/editor/editor.main", ["vs/editor/edcore.main","${allPluginsModuleIds.join( '","' )}"], function(api) { return api; });` ); let insertIndex = contents.lastIndexOf('//# sourceMappingURL='); if (insertIndex === -1) { insertIndex = contents.length; } contents = contents.substring(0, insertIndex) + '\n' + extraContent.join('\n') + '\n' + contents.substring(insertIndex); file.contents = Buffer.from(contents); } } function ESM_release() { const coreFiles = readFiles(`node_modules/monaco-editor-core/esm/**/*`, { base: 'node_modules/monaco-editor-core/esm', // we will create our own editor.api.d.ts which also contains the plugins API ignore: ['node_modules/monaco-editor-core/esm/vs/editor/editor.api.d.ts'] }); ESM_addImportSuffix(coreFiles); ESM_addPluginContribs(coreFiles); writeFiles(coreFiles, `out/monaco-editor/esm`); ESM_releasePlugins(); } /** * Release a plugin to `esm`. * Adds a dependency to 'vs/editor/editor.api' in contrib files in order for `monaco` to be defined. * Rewrites imports for 'monaco-editor-core/**' */ function ESM_releasePlugins() { const files = readFiles(`out/languages/bundled/esm/**/*`, { base: 'out/languages/bundled/esm/' }); for (const file of files) { if (!/(\.js$)|(\.ts$)/.test(file.path)) { continue; } let contents = file.contents.toString(); const info = ts.preProcessFile(contents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { let importText = info.importedFiles[i].fileName; const pos = info.importedFiles[i].pos; const end = info.importedFiles[i].end; if (!/(^\.\/)|(^\.\.\/)/.test(importText)) { // non-relative import if (!/^monaco-editor-core/.test(importText)) { console.error(`Non-relative import for unknown module: ${importText} in ${file.path}`); process.exit(1); } if (importText === 'monaco-editor-core') { importText = 'monaco-editor-core/esm/vs/editor/editor.api'; } const importFilePath = importText.substring('monaco-editor-core/esm/'.length); let relativePath = path .relative(path.dirname(file.path), importFilePath) .replace(/\\/g, '/'); if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { relativePath = './' + relativePath; } contents = contents.substring(0, pos + 1) + relativePath + contents.substring(end + 1); } } file.contents = Buffer.from(contents); } for (const file of files) { if (!/monaco\.contribution\.js$/.test(file.path)) { continue; } const apiFilePath = 'vs/editor/editor.api'; let relativePath = path.relative(path.dirname(file.path), apiFilePath).replace(/\\/g, '/'); if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { relativePath = './' + relativePath; } let contents = file.contents.toString(); contents = `import '${relativePath}';\n` + contents; file.contents = Buffer.from(contents); } ESM_addImportSuffix(files); writeFiles(files, `out/monaco-editor/esm`); } /** * Adds `.js` to all import statements. */ function ESM_addImportSuffix(files: IFile[]) { for (const file of files) { if (!/\.js$/.test(file.path)) { continue; } let contents = file.contents.toString(); const info = ts.preProcessFile(contents); for (let i = info.importedFiles.length - 1; i >= 0; i--) { const importText = info.importedFiles[i].fileName; const pos = info.importedFiles[i].pos; const end = info.importedFiles[i].end; if (/(\.css)|(\.js)$/.test(importText)) { // A CSS import or an import already using .js continue; } contents = contents.substring(0, pos + 1) + importText + '.js' + contents.substring(end + 1); } file.contents = Buffer.from(contents); } } /** * - Rename esm/vs/editor/editor.main.js to esm/vs/editor/edcore.main.js * - Create esm/vs/editor/editor.main.js that that stiches things together */ function ESM_addPluginContribs(files: IFile[]) { for (const file of files) { if (!/editor\.main\.js$/.test(file.path)) { continue; } file.path = file.path.replace(/editor\.main/, 'edcore.main'); } const mainFileDestPath = 'vs/editor/editor.main.js'; const mainFileImports = readFiles(`out/languages/bundled/esm/**/monaco.contribution.js`, { base: `out/languages/bundled/esm` }).map((file) => { let relativePath = path .relative(path.dirname(mainFileDestPath), file.path) .replace(/\\/g, '/') .replace(/\.js$/, ''); if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) { relativePath = './' + relativePath; } return relativePath; }); const mainFileContents = mainFileImports.map((name) => `import '${name}';`).join('\n') + `\n\nexport * from './edcore.main';`; files.push({ path: mainFileDestPath, contents: Buffer.from(mainFileContents) }); } /** * Edit monaco.d.ts: * - append monaco.d.ts from plugins */ function releaseDTS() { const monacodts = readFiles('node_modules/monaco-editor-core/monaco.d.ts', { base: 'node_modules/monaco-editor-core' })[0]; let contents = monacodts.contents.toString(); const extraContent = readFiles('out/languages/bundled/*.d.ts', { base: 'out/languages/bundled/' }).map((file) => { return file.contents.toString().replace(/\/\/\/