- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스) - Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포 - 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
348 lines
8.8 KiB
Plaintext
348 lines
8.8 KiB
Plaintext
/**
|
|
* 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.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
* @oncall react_native
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
import type {IConsumer} from './Consumer/types.flow';
|
|
import type {BabelSourceMapSegment} from '@babel/generator';
|
|
|
|
const {BundleBuilder, createIndexMap} = require('./BundleBuilder');
|
|
const composeSourceMaps = require('./composeSourceMaps');
|
|
const Consumer = require('./Consumer');
|
|
// We need to export this for `metro-symbolicate`
|
|
const normalizeSourcePath = require('./Consumer/normalizeSourcePath');
|
|
const {
|
|
functionMapBabelPlugin,
|
|
generateFunctionMap,
|
|
} = require('./generateFunctionMap');
|
|
const Generator = require('./Generator');
|
|
// $FlowFixMe[untyped-import] - source-map
|
|
const SourceMap = require('source-map');
|
|
|
|
export type {IConsumer};
|
|
|
|
type GeneratedCodeMapping = [number, number];
|
|
type SourceMapping = [number, number, number, number];
|
|
type SourceMappingWithName = [number, number, number, number, string];
|
|
|
|
export type MetroSourceMapSegmentTuple =
|
|
| SourceMappingWithName
|
|
| SourceMapping
|
|
| GeneratedCodeMapping;
|
|
|
|
export type HermesFunctionOffsets = {[number]: $ReadOnlyArray<number>, ...};
|
|
|
|
export type FBSourcesArray = $ReadOnlyArray<?FBSourceMetadata>;
|
|
export type FBSourceMetadata = [?FBSourceFunctionMap];
|
|
export type FBSourceFunctionMap = {
|
|
+names: $ReadOnlyArray<string>,
|
|
+mappings: string,
|
|
};
|
|
|
|
export type FBSegmentMap = {[id: string]: MixedSourceMap, ...};
|
|
|
|
export type BasicSourceMap = {
|
|
+file?: string,
|
|
+mappings: string,
|
|
+names: Array<string>,
|
|
+sourceRoot?: string,
|
|
+sources: Array<string>,
|
|
+sourcesContent?: Array<?string>,
|
|
+version: number,
|
|
+x_facebook_offsets?: Array<number>,
|
|
+x_metro_module_paths?: Array<string>,
|
|
+x_facebook_sources?: FBSourcesArray,
|
|
+x_facebook_segments?: FBSegmentMap,
|
|
+x_hermes_function_offsets?: HermesFunctionOffsets,
|
|
+x_google_ignoreList?: Array<number>,
|
|
};
|
|
|
|
export type IndexMapSection = {
|
|
map: IndexMap | BasicSourceMap,
|
|
offset: {
|
|
line: number,
|
|
column: number,
|
|
...
|
|
},
|
|
...
|
|
};
|
|
|
|
export type IndexMap = {
|
|
+file?: string,
|
|
+mappings?: void, // avoids SourceMap being a disjoint union
|
|
+sourcesContent?: void,
|
|
+sections: Array<IndexMapSection>,
|
|
+version: number,
|
|
+x_facebook_offsets?: Array<number>,
|
|
+x_metro_module_paths?: Array<string>,
|
|
+x_facebook_sources?: void,
|
|
+x_facebook_segments?: FBSegmentMap,
|
|
+x_hermes_function_offsets?: HermesFunctionOffsets,
|
|
+x_google_ignoreList?: void,
|
|
};
|
|
|
|
export type MixedSourceMap = IndexMap | BasicSourceMap;
|
|
|
|
type SourceMapConsumerMapping = {
|
|
generatedLine: number,
|
|
generatedColumn: number,
|
|
originalLine: ?number,
|
|
originalColumn: ?number,
|
|
source: ?string,
|
|
name: ?string,
|
|
};
|
|
|
|
function fromRawMappingsImpl(
|
|
isBlocking: boolean,
|
|
onDone: Generator => void,
|
|
modules: $ReadOnlyArray<{
|
|
+map: ?Array<MetroSourceMapSegmentTuple>,
|
|
+functionMap: ?FBSourceFunctionMap,
|
|
+path: string,
|
|
+source: string,
|
|
+code: string,
|
|
+isIgnored: boolean,
|
|
+lineCount?: number,
|
|
}>,
|
|
offsetLines: number,
|
|
): void {
|
|
const modulesToProcess = modules.slice();
|
|
const generator = new Generator();
|
|
let carryOver = offsetLines;
|
|
|
|
function processNextModule() {
|
|
if (modulesToProcess.length === 0) {
|
|
return true;
|
|
}
|
|
|
|
const mod = modulesToProcess.shift();
|
|
// $FlowFixMe[incompatible-use]
|
|
const {code, map} = mod;
|
|
if (Array.isArray(map)) {
|
|
// $FlowFixMe[incompatible-call]
|
|
addMappingsForFile(generator, map, mod, carryOver);
|
|
} else if (map != null) {
|
|
throw new Error(
|
|
// $FlowFixMe[incompatible-use]
|
|
`Unexpected module with full source map found: ${mod.path}`,
|
|
);
|
|
}
|
|
carryOver = carryOver + countLines(code);
|
|
return false;
|
|
}
|
|
|
|
function workLoop() {
|
|
const time = process.hrtime();
|
|
while (true) {
|
|
const isDone = processNextModule();
|
|
if (isDone) {
|
|
onDone(generator);
|
|
break;
|
|
}
|
|
if (!isBlocking) {
|
|
// Keep the loop running but try to avoid blocking
|
|
// for too long because this is not in a worker yet.
|
|
const diff = process.hrtime(time);
|
|
const NS_IN_MS = 1000000;
|
|
if (diff[1] > 50 * NS_IN_MS) {
|
|
// We've blocked for more than 50ms.
|
|
// This code currently runs on the main thread,
|
|
// so let's give Metro an opportunity to handle requests.
|
|
setImmediate(workLoop);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
workLoop();
|
|
}
|
|
|
|
/**
|
|
* Creates a source map from modules with "raw mappings", i.e. an array of
|
|
* tuples with either 2, 4, or 5 elements:
|
|
* generated line, generated column, source line, source line, symbol name.
|
|
* Accepts an `offsetLines` argument in case modules' code is to be offset in
|
|
* the resulting bundle, e.g. by some prefix code.
|
|
*/
|
|
function fromRawMappings(
|
|
modules: $ReadOnlyArray<{
|
|
+map: ?Array<MetroSourceMapSegmentTuple>,
|
|
+functionMap: ?FBSourceFunctionMap,
|
|
+path: string,
|
|
+source: string,
|
|
+code: string,
|
|
+isIgnored: boolean,
|
|
+lineCount?: number,
|
|
}>,
|
|
offsetLines: number = 0,
|
|
): Generator {
|
|
let generator: void | Generator;
|
|
fromRawMappingsImpl(
|
|
true,
|
|
g => {
|
|
generator = g;
|
|
},
|
|
modules,
|
|
offsetLines,
|
|
);
|
|
if (generator == null) {
|
|
throw new Error('Expected fromRawMappingsImpl() to finish synchronously.');
|
|
}
|
|
return generator;
|
|
}
|
|
|
|
async function fromRawMappingsNonBlocking(
|
|
modules: $ReadOnlyArray<{
|
|
+map: ?Array<MetroSourceMapSegmentTuple>,
|
|
+functionMap: ?FBSourceFunctionMap,
|
|
+path: string,
|
|
+source: string,
|
|
+code: string,
|
|
+isIgnored: boolean,
|
|
+lineCount?: number,
|
|
}>,
|
|
offsetLines: number = 0,
|
|
): Promise<Generator> {
|
|
return new Promise(resolve => {
|
|
fromRawMappingsImpl(false, resolve, modules, offsetLines);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Transforms a standard source map object into a Raw Mappings object, to be
|
|
* used across the bundler.
|
|
*/
|
|
function toBabelSegments(
|
|
sourceMap: BasicSourceMap,
|
|
): Array<BabelSourceMapSegment> {
|
|
const rawMappings: Array<BabelSourceMapSegment> = [];
|
|
|
|
new SourceMap.SourceMapConsumer(sourceMap).eachMapping(
|
|
(map: SourceMapConsumerMapping) => {
|
|
rawMappings.push(
|
|
map.originalLine == null || map.originalColumn == null
|
|
? {
|
|
generated: {
|
|
line: map.generatedLine,
|
|
column: map.generatedColumn,
|
|
},
|
|
source: map.source,
|
|
name: map.name,
|
|
}
|
|
: {
|
|
generated: {
|
|
line: map.generatedLine,
|
|
column: map.generatedColumn,
|
|
},
|
|
original: {
|
|
line: map.originalLine,
|
|
column: map.originalColumn,
|
|
},
|
|
source: map.source,
|
|
name: map.name,
|
|
},
|
|
);
|
|
},
|
|
);
|
|
|
|
return rawMappings;
|
|
}
|
|
|
|
function toSegmentTuple(
|
|
mapping: BabelSourceMapSegment,
|
|
): MetroSourceMapSegmentTuple {
|
|
const {column, line} = mapping.generated;
|
|
const {name, original} = mapping;
|
|
|
|
if (original == null) {
|
|
return [line, column];
|
|
}
|
|
|
|
if (typeof name !== 'string') {
|
|
return [line, column, original.line, original.column];
|
|
}
|
|
|
|
return [line, column, original.line, original.column, name];
|
|
}
|
|
|
|
function addMappingsForFile(
|
|
generator: Generator,
|
|
mappings: Array<MetroSourceMapSegmentTuple>,
|
|
module: {
|
|
+code: string,
|
|
+functionMap: ?FBSourceFunctionMap,
|
|
+map: ?Array<MetroSourceMapSegmentTuple>,
|
|
+path: string,
|
|
+source: string,
|
|
+isIgnored: boolean,
|
|
+lineCount?: number,
|
|
},
|
|
carryOver: number,
|
|
) {
|
|
generator.startFile(module.path, module.source, module.functionMap, {
|
|
addToIgnoreList: module.isIgnored,
|
|
});
|
|
|
|
for (let i = 0, n = mappings.length; i < n; ++i) {
|
|
addMapping(generator, mappings[i], carryOver);
|
|
}
|
|
|
|
generator.endFile();
|
|
}
|
|
|
|
function addMapping(
|
|
generator: Generator,
|
|
mapping: MetroSourceMapSegmentTuple,
|
|
carryOver: number,
|
|
) {
|
|
const line = mapping[0] + carryOver;
|
|
// lines start at 1, columns start at 0
|
|
const column = mapping[1];
|
|
switch (mapping.length) {
|
|
case 2:
|
|
generator.addSimpleMapping(line, column);
|
|
return;
|
|
case 4:
|
|
generator.addSourceMapping(line, column, mapping[2], mapping[3]);
|
|
return;
|
|
case 5:
|
|
generator.addNamedSourceMapping(
|
|
line,
|
|
column,
|
|
mapping[2],
|
|
mapping[3],
|
|
mapping[4],
|
|
);
|
|
return;
|
|
}
|
|
throw new Error(`Invalid mapping: [${mapping.join(', ')}]`);
|
|
}
|
|
|
|
const newline = /\r\n?|\n|\u2028|\u2029/g;
|
|
|
|
const countLines = (string: string): number =>
|
|
(string.match(newline) || []).length + 1;
|
|
|
|
module.exports = {
|
|
BundleBuilder,
|
|
composeSourceMaps,
|
|
Consumer,
|
|
createIndexMap,
|
|
generateFunctionMap,
|
|
fromRawMappings,
|
|
fromRawMappingsNonBlocking,
|
|
functionMapBabelPlugin,
|
|
normalizeSourcePath,
|
|
toBabelSegments,
|
|
toSegmentTuple,
|
|
};
|