Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,5 @@ jobs:
TEST_PROBE_ONLY: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/2.x' }}
BS_USERNAME: ${{ secrets.BS_USERNAME }}
BS_ACCESSKEY: ${{ secrets.BS_ACCESSKEY }}
- name: Verify TypeScript
run: npm run verify-typescript
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"test:jsdom": "cross-env NODE_ENV=test BABEL_ENV=rollup node test/jsdom-node-runner --dot",
"test:karma": "cross-env NODE_ENV=test BABEL_ENV=rollup karma start test/karma.conf.js --log-level warn ",
"test:ci": "cross-env NODE_ENV=test BABEL_ENV=rollup npm run test:jsdom && npm run test:karma -- --log-level error --reporters dots --single-run --shouldTestOnBrowserStack=\"${TEST_BROWSERSTACK}\" --shouldProbeOnly=\"${TEST_PROBE_ONLY}\"",
"test": "cross-env NODE_ENV=test BABEL_ENV=rollup npm run lint && npm run test:jsdom && npm run test:karma -- --browsers Chrome"
"test": "cross-env NODE_ENV=test BABEL_ENV=rollup npm run lint && npm run test:jsdom && npm run test:karma -- --browsers Chrome",
"verify-typescript": "node ./typescript/verify.js"
},
"main": "./dist/purify.cjs.js",
"module": "./dist/purify.es.mjs",
Expand Down
4 changes: 4 additions & 0 deletions typescript/commonjs-with-no-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
7 changes: 7 additions & 0 deletions typescript/commonjs-with-no-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "CommonJS",
"target": "ES2015",
"typeRoots": ["types"]
}
}
1 change: 1 addition & 0 deletions typescript/commonjs-with-no-types/types/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This simulates not having `@types/trusted-types` installed.
4 changes: 4 additions & 0 deletions typescript/commonjs-with-specific-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
7 changes: 7 additions & 0 deletions typescript/commonjs-with-specific-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "CommonJS",
"target": "ES2015",
"types": ["node"]
}
}
4 changes: 4 additions & 0 deletions typescript/commonjs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
6 changes: 6 additions & 0 deletions typescript/commonjs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"module": "CommonJS",
"target": "ES2015"
}
}
4 changes: 4 additions & 0 deletions typescript/esm-with-no-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
3 changes: 3 additions & 0 deletions typescript/esm-with-no-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
7 changes: 7 additions & 0 deletions typescript/esm-with-no-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "bundler",
"typeRoots": ["types"]
}
}
1 change: 1 addition & 0 deletions typescript/esm-with-no-types/types/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This simulates not having `@types/trusted-types` installed.
4 changes: 4 additions & 0 deletions typescript/esm-with-specific-types/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
3 changes: 3 additions & 0 deletions typescript/esm-with-specific-types/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
7 changes: 7 additions & 0 deletions typescript/esm-with-specific-types/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "bundler",
"types": ["node"]
}
}
4 changes: 4 additions & 0 deletions typescript/esm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
3 changes: 3 additions & 0 deletions typescript/esm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"type": "module"
}
6 changes: 6 additions & 0 deletions typescript/esm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "bundler"
}
}
4 changes: 4 additions & 0 deletions typescript/nodenext/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dompurify from 'dompurify';

dompurify.sanitize('<p>');
dompurify().sanitize('<p>');
6 changes: 6 additions & 0 deletions typescript/nodenext/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "nodenext"
}
}
5 changes: 5 additions & 0 deletions typescript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"dompurify": "file:.."
}
}
122 changes: 122 additions & 0 deletions typescript/verify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// @ts-check

const fs = require('node:fs/promises');
const path = require('node:path');
const ts = require('typescript');
const { exec } = require('child_process');

run().catch((ex) => {
console.error(ex);
process.exitCode = 1;
});

async function run() {
// Install node modules so that `dompurify` can be resolved.
process.stdout.write(`\x1b[30mInstalling node modules...\x1b[0m\n`);

await new Promise((resolve, reject) => {
exec('npm install --no-package-lock', { cwd: __dirname }, (err) => {
if (err) {
reject(err);
} else {
resolve(undefined);
}
});
});

process.stdout.write('\n');

let projects = await fs.readdir(__dirname, { withFileTypes: true });

for (let project of projects
.filter((x) => x.isDirectory())
.filter((x) => x.name !== 'node_modules')
.sort((a, b) => a.name.localeCompare(b.name))) {
await verify(project.name, path.join(__dirname, project.name));
}
}

/**
* Verifies that a TypeScript project compiles.
* @param {string} name The name of the project.
* @param {string} directory The project directory.
* @returns {Promise<void>}
*/
async function verify(name, directory) {
let line = ` ${name}...`;
process.stdout.write(line);

let diagnostics = await compile(path.join(directory, 'tsconfig.json'));
let success = diagnostics.length === 0;
let report = `\x1b${success ? '[32mβœ”' : '[31mX'}\x1b[0m`;

if (process.stdout.isTTY) {
process.stdout.write(`\x1b[${line.length}D${report} ${name} \n`);
} else {
process.stdout.write(` ${report}\n`);
}

if (!success) {
printDiagnostics(diagnostics);
process.exitCode = 1;
}
}

/**
* Compiles a TypeScript project.
* @param {string} configFileName The file name of the TypeScript config file.
* @returns {Promise<ts.Diagnostic[]>} The diagnostics produced.
*/
async function compile(configFileName) {
let jsonParseResult = ts.parseConfigFileTextToJson(
configFileName,
await fs.readFile(configFileName, { encoding: 'utf8' })
);

if (!jsonParseResult.config && jsonParseResult.error) {
return [jsonParseResult.error];
}

let config = ts.parseJsonConfigFileContent(
jsonParseResult.config,
ts.sys,
path.dirname(configFileName)
);
if (config.errors.length > 0) {
return config.errors;
}

let program = ts.createProgram(config.fileNames, config.options);
let emitResult = program.emit(
undefined,
// Do not emit anything.
() => undefined
);

return ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics);
}

/**
* Prints the diagnostics to stdout.
* @param {ts.Diagnostic[]} diagnostics The diagnostics to report.
*/
function printDiagnostics(diagnostics) {
diagnostics.forEach((diagnostic) => {
let message = '';

if (diagnostic.file && diagnostic.start) {
let start = diagnostic.file.getLineAndCharacterOfPosition(
diagnostic.start
);

message += ` ${diagnostic.file.fileName} (${start.line + 1},${
start.character + 1
})`;
}

message +=
': ' + ts.flattenDiagnosticMessageText(diagnostic.messageText, ' \n');

process.stdout.write(`\x1b[30m ${message}\x1b[0m\n`);
});
}
Loading