From a2853df4fa7df749e39189c4a446f2ca60546303 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Wed, 2 Oct 2024 15:15:01 -0700 Subject: [PATCH] Update to latest source-map-tests submodule Also adds validation logic to pass additional tests * Account for sourceRoot field when working with files * Check validation for file, sourceRoot * Make names field optional * Fix sourcesContent handling when wrong type --- source-map-tests | 2 +- src/util/collectSourceFiles.ts | 3 +- src/validators/SourceFilesValidator.ts | 4 +-- src/validators/SourceMapFormatValidator.ts | 32 ++++++++++++++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/source-map-tests b/source-map-tests index c016205..41c3d30 160000 --- a/source-map-tests +++ b/source-map-tests @@ -1 +1 @@ -Subproject commit c016205e30331d34bf2444c721438ead3ffb7d69 +Subproject commit 41c3d306d0f74275b0cedc4da0dce68b4d6ec13f diff --git a/src/util/collectSourceFiles.ts b/src/util/collectSourceFiles.ts index c7d0b7a..ad6474f 100644 --- a/src/util/collectSourceFiles.ts +++ b/src/util/collectSourceFiles.ts @@ -4,12 +4,13 @@ import type { SourceMap } from "./sourceMap.js"; export function collectSourceFiles(sourceMap: SourceMap, originalFolderPath: string) { const filesMap = new Map(); + const sourceRoot = sourceMap.sourceRoot || ""; sourceMap.sources.forEach((file: string | null, index: number) => { // When the source is null, it might make sense to map to an anonymous source // if a sourceContent is present, but for now just don't add it to the set. if (file !== null) - filesMap.set(file, TestingFile.forTextFile(path.join(originalFolderPath, file), sourceMap.sourcesContent ? sourceMap.sourcesContent[index] : null)) + filesMap.set(path.join(sourceRoot, file), TestingFile.forTextFile(path.join(originalFolderPath, sourceRoot, file), sourceMap.sourcesContent ? sourceMap.sourcesContent[index] : null)) }); return filesMap; diff --git a/src/validators/SourceFilesValidator.ts b/src/validators/SourceFilesValidator.ts index f246593..9c9673a 100644 --- a/src/validators/SourceFilesValidator.ts +++ b/src/validators/SourceFilesValidator.ts @@ -7,11 +7,11 @@ import type { ValidationContext } from "../util/ValidationContext.js"; export class SourceFilesValidator extends Validator { validate(context: ValidationContext): ValidationResult { const errors: Error[] = []; - const { sources, sourcesContent = [] } = context.sourceMap + const { sources, sourceRoot, sourcesContent = [] } = context.sourceMap function check(sources : any) { sources.forEach((sourceFileName: string | null, index: number) => { - const fullPath = sourceFileName === null ? null : path.join(context.originalFolderPath, sourceFileName); + const fullPath = sourceFileName === null ? null : path.join(context.originalFolderPath, sourceRoot || "", sourceFileName); // If the path is null, we won't use the source in subsequent passes so // it can be ignored. Otherwise ensure the source makes sense. if (fullPath !== null) { diff --git a/src/validators/SourceMapFormatValidator.ts b/src/validators/SourceMapFormatValidator.ts index a556144..273b4ab 100644 --- a/src/validators/SourceMapFormatValidator.ts +++ b/src/validators/SourceMapFormatValidator.ts @@ -11,6 +11,11 @@ function validateSourceMap(sourceMap : any) : Error[] { errors.push(new Error(`Source map version is not 3, got ${sourceMap.version}.`)); } + if ('file' in sourceMap) { + if (typeof sourceMap.file !== "string") + errors.push(new Error('Source map "file" field is not a string.')); + } + if ("sections" in sourceMap) { if ("mappings" in sourceMap) { errors.push(new Error('Source map cannot have both "mappings" and "sections" fields.')); @@ -31,6 +36,11 @@ function validateSourceMap(sourceMap : any) : Error[] { }); } } else { + if ('sourceRoot' in sourceMap) { + if (typeof sourceMap.sourceRoot !== "string") + errors.push(new Error('Source map "sourceRoot" field is not a string.')); + } + if (!sourceMap.sources || !Array.isArray(sourceMap.sources)) { errors.push(new Error('Source map "sources" field is invalid or missing.')); } else { @@ -39,12 +49,14 @@ function validateSourceMap(sourceMap : any) : Error[] { }) } - if (!sourceMap.names || !Array.isArray(sourceMap.names)) { - errors.push(new Error('Source map "names" field is missing.')); - } else { - sourceMap.names.forEach((x: unknown, i: number) => { - if (typeof x !== "string") errors.push(new Error(`There is a name with an invalid format on the index ${i}. Each name should be defined as a string`)) - }) + if ("names" in sourceMap) { + if (!Array.isArray(sourceMap.names)) { + errors.push(new Error('Source map "names" field is invalid.')); + } else { + sourceMap.names.forEach((x: unknown, i: number) => { + if (typeof x !== "string") errors.push(new Error(`There is a name with an invalid format on the index ${i}. Each name should be defined as a string`)) + }) + } } if (!("mappings" in sourceMap)) { @@ -56,9 +68,11 @@ function validateSourceMap(sourceMap : any) : Error[] { if ('sourcesContent' in sourceMap) { if (!Array.isArray(sourceMap.sourcesContent)) errors.push(new Error('Source map "sourcesContent" field is invalid.')); - sourceMap.sourcesContent.forEach((x: unknown, i: number) => { - if (x !== null && typeof x !== "string") errors.push(new Error(`There is a source content with an invalid format on the index ${i}. Each content should be defined as a strings or null`)) - }) + else { + sourceMap.sourcesContent.forEach((x: unknown, i: number) => { + if (x !== null && typeof x !== "string") errors.push(new Error(`There is a source content with an invalid format on the index ${i}. Each content should be defined as a strings or null`)) + }) + } } if ("ignoreList" in sourceMap) {