Skip to content

Commit

Permalink
Add validate-tsc-types type validation step after build
Browse files Browse the repository at this point in the history
  • Loading branch information
etrepum committed Apr 18, 2024
1 parent 28c4de9 commit bae93d3
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 2 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
"dev": "npm run dev --prefix packages/lexical-playground",
"start-test-server": "npm run preview --prefix packages/lexical-playground -- --port 4000",
"build": "node scripts/build.js",
"build-prod": "npm run clean && npm run build -- --prod",
"build-prod": "npm run clean && npm run build -- --prod && node ./scripts/validate-tsc-types.js",
"build-playground-prod": "npm run build-prod && npm run build-prod --prefix packages/lexical-playground",
"build-release": "npm run build-prod -- --release",
"build-release": "npm run build-prod -- --release && node ./scripts/validate-tsc-types.js",
"build-www": "npm run clean && npm run build -- --www && npm run build -- --www --prod && npm run prepare-www",
"build-types": "tsc -p ./tsconfig.build.json && node ./scripts/validate-tsc-types.js",
"clean": "node scripts/clean.js",
"extract-codes": "node scripts/build.js --codes",
"flow": "node ./scripts/check-flow-types.js",
Expand Down
88 changes: 88 additions & 0 deletions scripts/validate-tsc-types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
// @ts-check
'use strict';

const fs = require('fs-extra');
const glob = require('glob');
const ts = require('typescript');

const pretty = process.env.CI !== 'true';

/** @type {ts.FormatDiagnosticsHost} */
const diagnosticsHost = {
getCanonicalFileName: (fn) => fn,
getCurrentDirectory: () => './',
getNewLine: () => '\n',
};

/**
* Validate that the published .d.ts types do not have dependencies
* on any private module (currently shared/*).
*
* `process.exit(1)` on failure.
*/
function validateTscTypes() {
const dtsFilesPattern = './.ts-temp/{lexical,lexical-*}/**/*.d.ts';
const dtsFiles = glob.sync(dtsFilesPattern);
if (dtsFiles.length === 0) {
console.error(
`Missing ${dtsFilesPattern}, \`npm run build-prod\` or \`npm run build-release\` first`,
);
process.exit(1);
}
/** @type {ts.Diagnostic[]} */
const diagnostics = [];
for (const fn of dtsFiles) {
// console.log(fn);
const ast = ts.createSourceFile(
fn,
fs.readFileSync(fn, 'utf-8'),
ts.ScriptTarget.Latest,
);
const checkSpecifier = (/** @type {ts.Node | undefined} */ node) => {
if (!node || node.kind !== ts.SyntaxKind.StringLiteral) {
return;
}
const specifier = /** @type {import('typescript').StringLiteral} */ (
node
);
if (/^shared(\/|$)/.test(specifier.text)) {
const start = specifier.getStart(ast);
diagnostics.push({
category: ts.DiagnosticCategory.Error,
code: Infinity,
file: ast,
length: specifier.getEnd() - start,
messageText: `Published .d.ts files must not import private module '${specifier.text}'.`,
start,
});
}
};
ast.forEachChild((node) => {
if (node.kind === ts.SyntaxKind.ExportDeclaration) {
const exportNode =
/** @type {import('typescript').ExportDeclaration} */ (node);
checkSpecifier(exportNode.moduleSpecifier);
} else if (node.kind === ts.SyntaxKind.ImportDeclaration) {
const importNode =
/** @type {import('typescript').ImportDeclaration} */ (node);
checkSpecifier(importNode.moduleSpecifier);
}
});
}
if (diagnostics.length > 0) {
const msg = (
pretty ? ts.formatDiagnosticsWithColorAndContext : ts.formatDiagnostics
)(diagnostics, diagnosticsHost);
console.error(msg.replace(/ TSInfinity:/g, ':'));
process.exit(1);
}
}

validateTscTypes();

0 comments on commit bae93d3

Please sign in to comment.