mirror of
https://github.com/google/blockly.git
synced 2025-12-15 13:50:08 +01:00
* chore(deps): Bump prettier from 3.0.3 to 3.1.0 Bumps [prettier](https://github.com/prettier/prettier) from 3.0.3 to 3.1.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.3...3.1.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * chore: format --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Beka Westberg <bwestberg@google.com>
169 lines
6.0 KiB
JavaScript
Executable File
169 lines
6.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const filenames = process.argv.slice(2); // Trim off node and script name.
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Load deps files via require (since they're executalbe .js files).
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Dictionary mapping goog.module ID to absolute pathname of the file
|
|
* containing the goog.declareModuleId for that ID.
|
|
* @type {!Object<string, string>}
|
|
*/
|
|
const modulePaths = {};
|
|
|
|
/** Absolute path of repository root. */
|
|
const repoPath = path.resolve(__dirname, '..', '..');
|
|
|
|
/**
|
|
* Absolute path of directory containing base.js (the version used as
|
|
* input to tsc, not the one output by it).
|
|
* @type {string}
|
|
*/
|
|
const closurePath = path.resolve(repoPath, 'closure', 'goog');
|
|
|
|
globalThis.goog = {};
|
|
|
|
/**
|
|
* Stub version of addDependency that store mappings in modulePaths.
|
|
* @param {string} relPath The path to the js file.
|
|
* @param {!Array<string>} provides An array of strings with
|
|
* the names of the objects this file provides.
|
|
* @param {!Array<string>} _requires An array of strings with
|
|
* the names of the objects this file requires (unused).
|
|
* @param {boolean|!Object<string>=} opt_loadFlags Parameters indicating
|
|
* how the file must be loaded. The boolean 'true' is equivalent
|
|
* to {'module': 'goog'} for backwards-compatibility. Valid properties
|
|
* and values include {'module': 'goog'} and {'lang': 'es6'}.
|
|
*/
|
|
goog.addDependency = function (relPath, provides, _requires, opt_loadFlags) {
|
|
// Ignore any non-ESM files, as they can't be imported.
|
|
if (opt_loadFlags?.module !== 'es6') return;
|
|
|
|
// There should be only one "provide" from an ESM, but...
|
|
for (const moduleId of provides) {
|
|
// Store absolute path to source file (i.e., treating relPath
|
|
// relative to closure/goog/, not build/src/closure/goog/).
|
|
modulePaths[moduleId] = path.resolve(closurePath, relPath);
|
|
}
|
|
};
|
|
|
|
// Load deps files relative to this script's location.
|
|
require(path.resolve(__dirname, '../../build/deps.js'));
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
// Process files mentioned on the command line.
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
/** RegExp matching goog.require statements. */
|
|
const requireRE =
|
|
/(?:const\s+(?:([$\w]+)|(\{[^}]*\}))\s+=\s+)?goog.require(Type)?\('([^']+)'\);/gm;
|
|
|
|
/** RegExp matching key: value pairs in destructuring assignments. */
|
|
const keyValueRE = /([$\w]+)\s*:\s*([$\w]+)\s*(?=,|})/g;
|
|
|
|
for (const filename of filenames) {
|
|
let contents = null;
|
|
try {
|
|
contents = String(fs.readFileSync(filename));
|
|
} catch (e) {
|
|
console.error(`error while reading ${filename}: ${e.message}`);
|
|
continue;
|
|
}
|
|
console.log(`Converting ${filename} to TypeScript...`);
|
|
|
|
// Remove "use strict".
|
|
contents = contents.replace(/^\s*["']use strict["']\s*; *\n/m, '');
|
|
|
|
// Migrate from goog.module to goog.declareModuleId.
|
|
const closurePathRelative = path.relative(
|
|
path.dirname(path.resolve(filename)),
|
|
closurePath,
|
|
);
|
|
contents = contents.replace(
|
|
/^goog.module\('([$\w.]+)'\);$/m,
|
|
`import * as goog from '${closurePathRelative}/goog.js';\n` +
|
|
`goog.declareModuleId('$1');`,
|
|
);
|
|
|
|
// Migrate from goog.require to import.
|
|
contents = contents.replace(
|
|
requireRE,
|
|
function (
|
|
orig, // Whole statement to be replaced.
|
|
name, // Name of named import of whole module (if applicable).
|
|
names, // {}-enclosed list of destructured imports.
|
|
type, // If truthy, it is a requireType not require.
|
|
moduleId, // goog.module ID that was goog.require()d.
|
|
) {
|
|
const importPath = modulePaths[moduleId];
|
|
type = type ? ' type' : '';
|
|
if (!importPath) {
|
|
console.warn(
|
|
`Unable to migrate goog.require('${moduleId}') as no ES module path known.`,
|
|
);
|
|
return orig;
|
|
}
|
|
let relativePath = path.relative(
|
|
path.dirname(path.resolve(filename)),
|
|
importPath,
|
|
);
|
|
if (relativePath[0] !== '.') relativePath = './' + relativePath;
|
|
if (name) {
|
|
return `import${type} * as ${name} from '${relativePath}';`;
|
|
} else if (names) {
|
|
names = names.replace(keyValueRE, '$1 as $2');
|
|
return `import${type} ${names} from '${relativePath}';`;
|
|
} else {
|
|
// Side-effect only require.
|
|
return `import${type} '${relativePath}';`;
|
|
}
|
|
},
|
|
);
|
|
|
|
// Find and update or remove old-style export assignemnts.
|
|
/** @type {!Array<{name: string, re: RegExp>}>} */
|
|
const easyExports = [];
|
|
contents = contents.replace(
|
|
/^\s*exports\.([$\w]+)\s*=\s*([$\w]+)\s*;\n/gm,
|
|
function (
|
|
orig, // Whole statement to be replaced.
|
|
exportName, // Name to export item as.
|
|
declName, // Already-declared name for item being exported.
|
|
) {
|
|
// Renamed exports have to be transalted as-is.
|
|
if (exportName !== declName) {
|
|
return `export {${declName} as ${exportName}};\n`;
|
|
}
|
|
// OK, we're doing "export.foo = foo;". Can we update the
|
|
// declaration? We can't actualy modify it yet as we're in
|
|
// the middle of a search-and-replace on contents already, but
|
|
// we can delete the old export and later update the
|
|
// declaration into an export.
|
|
const declRE = new RegExp(
|
|
`^(\\s*)((?:const|let|var|function|class)\\s+${declName})\\b`,
|
|
'gm',
|
|
);
|
|
if (contents.match(declRE)) {
|
|
easyExports.push({exportName, declRE});
|
|
return ''; // Delete existing export assignment.
|
|
} else {
|
|
return `export ${exportName};\n`; // Safe fallback.
|
|
}
|
|
},
|
|
);
|
|
// Add 'export' to existing declarations where appropriate.
|
|
for (const {exportName, declRE} of easyExports) {
|
|
contents = contents.replace(declRE, '$1export $2');
|
|
}
|
|
|
|
// Write converted file with new extension.
|
|
const newFilename = filename.replace(/.js$/, '.ts');
|
|
fs.writeFileSync(newFilename, contents);
|
|
console.log(`Wrote ${newFilename}.`);
|
|
}
|