11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayPrototypeMap, 51cb0ef41Sopenharmony_ci JSONParse, 61cb0ef41Sopenharmony_ci ObjectCreate, 71cb0ef41Sopenharmony_ci ObjectKeys, 81cb0ef41Sopenharmony_ci ObjectGetOwnPropertyDescriptor, 91cb0ef41Sopenharmony_ci ObjectPrototypeHasOwnProperty, 101cb0ef41Sopenharmony_ci RegExpPrototypeExec, 111cb0ef41Sopenharmony_ci RegExpPrototypeSymbolSplit, 121cb0ef41Sopenharmony_ci SafeMap, 131cb0ef41Sopenharmony_ci StringPrototypeSplit, 141cb0ef41Sopenharmony_ci} = primordials; 151cb0ef41Sopenharmony_ci 161cb0ef41Sopenharmony_cifunction ObjectGetValueSafe(obj, key) { 171cb0ef41Sopenharmony_ci const desc = ObjectGetOwnPropertyDescriptor(obj, key); 181cb0ef41Sopenharmony_ci return ObjectPrototypeHasOwnProperty(desc, 'value') ? desc.value : undefined; 191cb0ef41Sopenharmony_ci} 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_ci// See https://sourcemaps.info/spec.html for SourceMap V3 specification. 221cb0ef41Sopenharmony_ciconst { Buffer } = require('buffer'); 231cb0ef41Sopenharmony_cilet debug = require('internal/util/debuglog').debuglog('source_map', (fn) => { 241cb0ef41Sopenharmony_ci debug = fn; 251cb0ef41Sopenharmony_ci}); 261cb0ef41Sopenharmony_ci 271cb0ef41Sopenharmony_ciconst { validateBoolean } = require('internal/validators'); 281cb0ef41Sopenharmony_ciconst { 291cb0ef41Sopenharmony_ci setSourceMapsEnabled: setSourceMapsNative, 301cb0ef41Sopenharmony_ci setPrepareStackTraceCallback, 311cb0ef41Sopenharmony_ci} = internalBinding('errors'); 321cb0ef41Sopenharmony_ciconst { getLazy } = require('internal/util'); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci// Since the CJS module cache is mutable, which leads to memory leaks when 351cb0ef41Sopenharmony_ci// modules are deleted, we use a WeakMap so that the source map cache will 361cb0ef41Sopenharmony_ci// be purged automatically: 371cb0ef41Sopenharmony_ciconst getCjsSourceMapCache = getLazy(() => { 381cb0ef41Sopenharmony_ci const { IterableWeakMap } = require('internal/util/iterable_weak_map'); 391cb0ef41Sopenharmony_ci return new IterableWeakMap(); 401cb0ef41Sopenharmony_ci}); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci// The esm cache is not mutable, so we can use a Map without memory concerns: 431cb0ef41Sopenharmony_ciconst esmSourceMapCache = new SafeMap(); 441cb0ef41Sopenharmony_ci// The generated sources is not mutable, so we can use a Map without memory concerns: 451cb0ef41Sopenharmony_ciconst generatedSourceMapCache = new SafeMap(); 461cb0ef41Sopenharmony_ciconst kLeadingProtocol = /^\w+:\/\//; 471cb0ef41Sopenharmony_ciconst kSourceMappingURLMagicComment = /\/[*/]#\s+sourceMappingURL=(?<sourceMappingURL>[^\s]+)/g; 481cb0ef41Sopenharmony_ciconst kSourceURLMagicComment = /\/[*/]#\s+sourceURL=(?<sourceURL>[^\s]+)/g; 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciconst { fileURLToPath, pathToFileURL, URL } = require('internal/url'); 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_cilet SourceMap; 531cb0ef41Sopenharmony_ci 541cb0ef41Sopenharmony_ci// This is configured with --enable-source-maps during pre-execution. 551cb0ef41Sopenharmony_cilet sourceMapsEnabled = false; 561cb0ef41Sopenharmony_cifunction getSourceMapsEnabled() { 571cb0ef41Sopenharmony_ci return sourceMapsEnabled; 581cb0ef41Sopenharmony_ci} 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_cifunction setSourceMapsEnabled(val) { 611cb0ef41Sopenharmony_ci validateBoolean(val, 'val'); 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci setSourceMapsNative(val); 641cb0ef41Sopenharmony_ci if (val) { 651cb0ef41Sopenharmony_ci const { 661cb0ef41Sopenharmony_ci prepareStackTrace, 671cb0ef41Sopenharmony_ci } = require('internal/source_map/prepare_stack_trace'); 681cb0ef41Sopenharmony_ci setPrepareStackTraceCallback(prepareStackTrace); 691cb0ef41Sopenharmony_ci } else if (sourceMapsEnabled !== undefined) { 701cb0ef41Sopenharmony_ci // Reset prepare stack trace callback only when disabling source maps. 711cb0ef41Sopenharmony_ci const { 721cb0ef41Sopenharmony_ci prepareStackTrace, 731cb0ef41Sopenharmony_ci } = require('internal/errors'); 741cb0ef41Sopenharmony_ci setPrepareStackTraceCallback(prepareStackTrace); 751cb0ef41Sopenharmony_ci } 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci sourceMapsEnabled = val; 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_cifunction extractSourceURLMagicComment(content) { 811cb0ef41Sopenharmony_ci let match; 821cb0ef41Sopenharmony_ci let matchSourceURL; 831cb0ef41Sopenharmony_ci // A while loop is used here to get the last occurrence of sourceURL. 841cb0ef41Sopenharmony_ci // This is needed so that we don't match sourceURL in string literals. 851cb0ef41Sopenharmony_ci while ((match = RegExpPrototypeExec(kSourceURLMagicComment, content))) { 861cb0ef41Sopenharmony_ci matchSourceURL = match; 871cb0ef41Sopenharmony_ci } 881cb0ef41Sopenharmony_ci if (matchSourceURL == null) { 891cb0ef41Sopenharmony_ci return null; 901cb0ef41Sopenharmony_ci } 911cb0ef41Sopenharmony_ci let sourceURL = matchSourceURL.groups.sourceURL; 921cb0ef41Sopenharmony_ci if (sourceURL != null && RegExpPrototypeExec(kLeadingProtocol, sourceURL) === null) { 931cb0ef41Sopenharmony_ci sourceURL = pathToFileURL(sourceURL).href; 941cb0ef41Sopenharmony_ci } 951cb0ef41Sopenharmony_ci return sourceURL; 961cb0ef41Sopenharmony_ci} 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_cifunction extractSourceMapURLMagicComment(content) { 991cb0ef41Sopenharmony_ci let match; 1001cb0ef41Sopenharmony_ci let lastMatch; 1011cb0ef41Sopenharmony_ci // A while loop is used here to get the last occurrence of sourceMappingURL. 1021cb0ef41Sopenharmony_ci // This is needed so that we don't match sourceMappingURL in string literals. 1031cb0ef41Sopenharmony_ci while ((match = RegExpPrototypeExec(kSourceMappingURLMagicComment, content))) { 1041cb0ef41Sopenharmony_ci lastMatch = match; 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci if (lastMatch == null) { 1071cb0ef41Sopenharmony_ci return null; 1081cb0ef41Sopenharmony_ci } 1091cb0ef41Sopenharmony_ci return lastMatch.groups.sourceMappingURL; 1101cb0ef41Sopenharmony_ci} 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_cifunction maybeCacheSourceMap(filename, content, cjsModuleInstance, isGeneratedSource, sourceURL, sourceMapURL) { 1131cb0ef41Sopenharmony_ci const sourceMapsEnabled = getSourceMapsEnabled(); 1141cb0ef41Sopenharmony_ci if (!(process.env.NODE_V8_COVERAGE || sourceMapsEnabled)) return; 1151cb0ef41Sopenharmony_ci try { 1161cb0ef41Sopenharmony_ci const { normalizeReferrerURL } = require('internal/modules/helpers'); 1171cb0ef41Sopenharmony_ci filename = normalizeReferrerURL(filename); 1181cb0ef41Sopenharmony_ci } catch (err) { 1191cb0ef41Sopenharmony_ci // This is most likely an invalid filename in sourceURL of [eval]-wrapper. 1201cb0ef41Sopenharmony_ci debug(err); 1211cb0ef41Sopenharmony_ci return; 1221cb0ef41Sopenharmony_ci } 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci if (sourceMapURL === undefined) { 1251cb0ef41Sopenharmony_ci sourceMapURL = extractSourceMapURLMagicComment(content); 1261cb0ef41Sopenharmony_ci } 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci // Bail out when there is no source map url. 1291cb0ef41Sopenharmony_ci if (typeof sourceMapURL !== 'string') { 1301cb0ef41Sopenharmony_ci return; 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci 1331cb0ef41Sopenharmony_ci if (sourceURL === undefined) { 1341cb0ef41Sopenharmony_ci sourceURL = extractSourceURLMagicComment(content); 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci 1371cb0ef41Sopenharmony_ci const data = dataFromUrl(filename, sourceMapURL); 1381cb0ef41Sopenharmony_ci const url = data ? null : sourceMapURL; 1391cb0ef41Sopenharmony_ci if (cjsModuleInstance) { 1401cb0ef41Sopenharmony_ci getCjsSourceMapCache().set(cjsModuleInstance, { 1411cb0ef41Sopenharmony_ci filename, 1421cb0ef41Sopenharmony_ci lineLengths: lineLengths(content), 1431cb0ef41Sopenharmony_ci data, 1441cb0ef41Sopenharmony_ci url, 1451cb0ef41Sopenharmony_ci sourceURL, 1461cb0ef41Sopenharmony_ci }); 1471cb0ef41Sopenharmony_ci } else if (isGeneratedSource) { 1481cb0ef41Sopenharmony_ci const entry = { 1491cb0ef41Sopenharmony_ci lineLengths: lineLengths(content), 1501cb0ef41Sopenharmony_ci data, 1511cb0ef41Sopenharmony_ci url, 1521cb0ef41Sopenharmony_ci sourceURL, 1531cb0ef41Sopenharmony_ci }; 1541cb0ef41Sopenharmony_ci generatedSourceMapCache.set(filename, entry); 1551cb0ef41Sopenharmony_ci if (sourceURL) { 1561cb0ef41Sopenharmony_ci generatedSourceMapCache.set(sourceURL, entry); 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci } else { 1591cb0ef41Sopenharmony_ci // If there is no cjsModuleInstance and is not generated source assume we are in a 1601cb0ef41Sopenharmony_ci // "modules/esm" context. 1611cb0ef41Sopenharmony_ci const entry = { 1621cb0ef41Sopenharmony_ci lineLengths: lineLengths(content), 1631cb0ef41Sopenharmony_ci data, 1641cb0ef41Sopenharmony_ci url, 1651cb0ef41Sopenharmony_ci sourceURL, 1661cb0ef41Sopenharmony_ci }; 1671cb0ef41Sopenharmony_ci esmSourceMapCache.set(filename, entry); 1681cb0ef41Sopenharmony_ci if (sourceURL) { 1691cb0ef41Sopenharmony_ci esmSourceMapCache.set(sourceURL, entry); 1701cb0ef41Sopenharmony_ci } 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci} 1731cb0ef41Sopenharmony_ci 1741cb0ef41Sopenharmony_cifunction maybeCacheGeneratedSourceMap(content) { 1751cb0ef41Sopenharmony_ci const sourceMapsEnabled = getSourceMapsEnabled(); 1761cb0ef41Sopenharmony_ci if (!(process.env.NODE_V8_COVERAGE || sourceMapsEnabled)) return; 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci const sourceURL = extractSourceURLMagicComment(content); 1791cb0ef41Sopenharmony_ci if (sourceURL === null) { 1801cb0ef41Sopenharmony_ci return; 1811cb0ef41Sopenharmony_ci } 1821cb0ef41Sopenharmony_ci try { 1831cb0ef41Sopenharmony_ci maybeCacheSourceMap(sourceURL, content, null, true, sourceURL); 1841cb0ef41Sopenharmony_ci } catch (err) { 1851cb0ef41Sopenharmony_ci // This can happen if the filename is not a valid URL. 1861cb0ef41Sopenharmony_ci // If we fail to cache the source map, we should not fail the whole process. 1871cb0ef41Sopenharmony_ci debug(err); 1881cb0ef41Sopenharmony_ci } 1891cb0ef41Sopenharmony_ci} 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_cifunction dataFromUrl(sourceURL, sourceMappingURL) { 1921cb0ef41Sopenharmony_ci try { 1931cb0ef41Sopenharmony_ci const url = new URL(sourceMappingURL); 1941cb0ef41Sopenharmony_ci switch (url.protocol) { 1951cb0ef41Sopenharmony_ci case 'data:': 1961cb0ef41Sopenharmony_ci return sourceMapFromDataUrl(sourceURL, url.pathname); 1971cb0ef41Sopenharmony_ci default: 1981cb0ef41Sopenharmony_ci debug(`unknown protocol ${url.protocol}`); 1991cb0ef41Sopenharmony_ci return null; 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci } catch (err) { 2021cb0ef41Sopenharmony_ci debug(err); 2031cb0ef41Sopenharmony_ci // If no scheme is present, we assume we are dealing with a file path. 2041cb0ef41Sopenharmony_ci const mapURL = new URL(sourceMappingURL, sourceURL).href; 2051cb0ef41Sopenharmony_ci return sourceMapFromFile(mapURL); 2061cb0ef41Sopenharmony_ci } 2071cb0ef41Sopenharmony_ci} 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci// Cache the length of each line in the file that a source map was extracted 2101cb0ef41Sopenharmony_ci// from. This allows translation from byte offset V8 coverage reports, 2111cb0ef41Sopenharmony_ci// to line/column offset Source Map V3. 2121cb0ef41Sopenharmony_cifunction lineLengths(content) { 2131cb0ef41Sopenharmony_ci // We purposefully keep \r as part of the line-length calculation, in 2141cb0ef41Sopenharmony_ci // cases where there is a \r\n separator, so that this can be taken into 2151cb0ef41Sopenharmony_ci // account in coverage calculations. 2161cb0ef41Sopenharmony_ci return ArrayPrototypeMap(RegExpPrototypeSymbolSplit(/\n|\u2028|\u2029/, content), (line) => { 2171cb0ef41Sopenharmony_ci return line.length; 2181cb0ef41Sopenharmony_ci }); 2191cb0ef41Sopenharmony_ci} 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_cifunction sourceMapFromFile(mapURL) { 2221cb0ef41Sopenharmony_ci try { 2231cb0ef41Sopenharmony_ci const fs = require('fs'); 2241cb0ef41Sopenharmony_ci const content = fs.readFileSync(fileURLToPath(mapURL), 'utf8'); 2251cb0ef41Sopenharmony_ci const data = JSONParse(content); 2261cb0ef41Sopenharmony_ci return sourcesToAbsolute(mapURL, data); 2271cb0ef41Sopenharmony_ci } catch (err) { 2281cb0ef41Sopenharmony_ci debug(err); 2291cb0ef41Sopenharmony_ci return null; 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci} 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci// data:[<mediatype>][;base64],<data> see: 2341cb0ef41Sopenharmony_ci// https://tools.ietf.org/html/rfc2397#section-2 2351cb0ef41Sopenharmony_cifunction sourceMapFromDataUrl(sourceURL, url) { 2361cb0ef41Sopenharmony_ci const { 0: format, 1: data } = StringPrototypeSplit(url, ','); 2371cb0ef41Sopenharmony_ci const splitFormat = StringPrototypeSplit(format, ';'); 2381cb0ef41Sopenharmony_ci const contentType = splitFormat[0]; 2391cb0ef41Sopenharmony_ci const base64 = splitFormat[splitFormat.length - 1] === 'base64'; 2401cb0ef41Sopenharmony_ci if (contentType === 'application/json') { 2411cb0ef41Sopenharmony_ci const decodedData = base64 ? 2421cb0ef41Sopenharmony_ci Buffer.from(data, 'base64').toString('utf8') : data; 2431cb0ef41Sopenharmony_ci try { 2441cb0ef41Sopenharmony_ci const parsedData = JSONParse(decodedData); 2451cb0ef41Sopenharmony_ci return sourcesToAbsolute(sourceURL, parsedData); 2461cb0ef41Sopenharmony_ci } catch (err) { 2471cb0ef41Sopenharmony_ci debug(err); 2481cb0ef41Sopenharmony_ci return null; 2491cb0ef41Sopenharmony_ci } 2501cb0ef41Sopenharmony_ci } else { 2511cb0ef41Sopenharmony_ci debug(`unknown content-type ${contentType}`); 2521cb0ef41Sopenharmony_ci return null; 2531cb0ef41Sopenharmony_ci } 2541cb0ef41Sopenharmony_ci} 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci// If the sources are not absolute URLs after prepending of the "sourceRoot", 2571cb0ef41Sopenharmony_ci// the sources are resolved relative to the SourceMap (like resolving script 2581cb0ef41Sopenharmony_ci// src in a html document). 2591cb0ef41Sopenharmony_cifunction sourcesToAbsolute(baseURL, data) { 2601cb0ef41Sopenharmony_ci data.sources = data.sources.map((source) => { 2611cb0ef41Sopenharmony_ci source = (data.sourceRoot || '') + source; 2621cb0ef41Sopenharmony_ci return new URL(source, baseURL).href; 2631cb0ef41Sopenharmony_ci }); 2641cb0ef41Sopenharmony_ci // The sources array is now resolved to absolute URLs, sourceRoot should 2651cb0ef41Sopenharmony_ci // be updated to noop. 2661cb0ef41Sopenharmony_ci data.sourceRoot = ''; 2671cb0ef41Sopenharmony_ci return data; 2681cb0ef41Sopenharmony_ci} 2691cb0ef41Sopenharmony_ci 2701cb0ef41Sopenharmony_ci// WARNING: The `sourceMapCacheToObject` and `appendCJSCache` run during 2711cb0ef41Sopenharmony_ci// shutdown. In particular, they also run when Workers are terminated, making 2721cb0ef41Sopenharmony_ci// it important that they do not call out to any user-provided code, including 2731cb0ef41Sopenharmony_ci// built-in prototypes that might have been tampered with. 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci// Get serialized representation of source-map cache, this is used 2761cb0ef41Sopenharmony_ci// to persist a cache of source-maps to disk when NODE_V8_COVERAGE is enabled. 2771cb0ef41Sopenharmony_cifunction sourceMapCacheToObject() { 2781cb0ef41Sopenharmony_ci const obj = ObjectCreate(null); 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci for (const { 0: k, 1: v } of esmSourceMapCache) { 2811cb0ef41Sopenharmony_ci obj[k] = v; 2821cb0ef41Sopenharmony_ci } 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci appendCJSCache(obj); 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci if (ObjectKeys(obj).length === 0) { 2871cb0ef41Sopenharmony_ci return undefined; 2881cb0ef41Sopenharmony_ci } 2891cb0ef41Sopenharmony_ci return obj; 2901cb0ef41Sopenharmony_ci} 2911cb0ef41Sopenharmony_ci 2921cb0ef41Sopenharmony_cifunction appendCJSCache(obj) { 2931cb0ef41Sopenharmony_ci for (const value of getCjsSourceMapCache()) { 2941cb0ef41Sopenharmony_ci obj[ObjectGetValueSafe(value, 'filename')] = { 2951cb0ef41Sopenharmony_ci lineLengths: ObjectGetValueSafe(value, 'lineLengths'), 2961cb0ef41Sopenharmony_ci data: ObjectGetValueSafe(value, 'data'), 2971cb0ef41Sopenharmony_ci url: ObjectGetValueSafe(value, 'url'), 2981cb0ef41Sopenharmony_ci }; 2991cb0ef41Sopenharmony_ci } 3001cb0ef41Sopenharmony_ci} 3011cb0ef41Sopenharmony_ci 3021cb0ef41Sopenharmony_cifunction findSourceMap(sourceURL) { 3031cb0ef41Sopenharmony_ci if (RegExpPrototypeExec(kLeadingProtocol, sourceURL) === null) { 3041cb0ef41Sopenharmony_ci sourceURL = pathToFileURL(sourceURL).href; 3051cb0ef41Sopenharmony_ci } 3061cb0ef41Sopenharmony_ci if (!SourceMap) { 3071cb0ef41Sopenharmony_ci SourceMap = require('internal/source_map/source_map').SourceMap; 3081cb0ef41Sopenharmony_ci } 3091cb0ef41Sopenharmony_ci let sourceMap = esmSourceMapCache.get(sourceURL) ?? generatedSourceMapCache.get(sourceURL); 3101cb0ef41Sopenharmony_ci if (sourceMap === undefined) { 3111cb0ef41Sopenharmony_ci for (const value of getCjsSourceMapCache()) { 3121cb0ef41Sopenharmony_ci const filename = ObjectGetValueSafe(value, 'filename'); 3131cb0ef41Sopenharmony_ci const cachedSourceURL = ObjectGetValueSafe(value, 'sourceURL'); 3141cb0ef41Sopenharmony_ci if (sourceURL === filename || sourceURL === cachedSourceURL) { 3151cb0ef41Sopenharmony_ci sourceMap = { 3161cb0ef41Sopenharmony_ci data: ObjectGetValueSafe(value, 'data'), 3171cb0ef41Sopenharmony_ci }; 3181cb0ef41Sopenharmony_ci } 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci } 3211cb0ef41Sopenharmony_ci if (sourceMap && sourceMap.data) { 3221cb0ef41Sopenharmony_ci return new SourceMap(sourceMap.data); 3231cb0ef41Sopenharmony_ci } 3241cb0ef41Sopenharmony_ci return undefined; 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_cimodule.exports = { 3281cb0ef41Sopenharmony_ci findSourceMap, 3291cb0ef41Sopenharmony_ci getSourceMapsEnabled, 3301cb0ef41Sopenharmony_ci setSourceMapsEnabled, 3311cb0ef41Sopenharmony_ci maybeCacheSourceMap, 3321cb0ef41Sopenharmony_ci maybeCacheGeneratedSourceMap, 3331cb0ef41Sopenharmony_ci sourceMapCacheToObject, 3341cb0ef41Sopenharmony_ci}; 335