- 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>
382 lines
10 KiB
JavaScript
382 lines
10 KiB
JavaScript
"use strict";
|
|
|
|
var _traverse = _interopRequireDefault(require("@babel/traverse"));
|
|
var _types = require("@babel/types");
|
|
function _interopRequireDefault(obj) {
|
|
return obj && obj.__esModule ? obj : { default: obj };
|
|
}
|
|
const B64Builder = require("./B64Builder");
|
|
const t = require("@babel/types");
|
|
const invariant = require("invariant");
|
|
const nullthrows = require("nullthrows");
|
|
const fsPath = require("path");
|
|
function generateFunctionMap(ast, context) {
|
|
const encoder = new MappingEncoder();
|
|
forEachMapping(ast, context, (mapping) => encoder.push(mapping));
|
|
return encoder.getResult();
|
|
}
|
|
function generateFunctionMappingsArray(ast, context) {
|
|
const mappings = [];
|
|
forEachMapping(ast, context, (mapping) => {
|
|
mappings.push(mapping);
|
|
});
|
|
return mappings;
|
|
}
|
|
function functionMapBabelPlugin() {
|
|
return {
|
|
visitor: {},
|
|
pre: ({ path, metadata, opts }) => {
|
|
const { filename } = nullthrows(opts);
|
|
const encoder = new MappingEncoder();
|
|
const visitor = getFunctionMapVisitor(
|
|
{
|
|
filename,
|
|
},
|
|
(mapping) => encoder.push(mapping)
|
|
);
|
|
invariant(
|
|
path && t.isProgram(path.node),
|
|
"path missing or not a program node"
|
|
);
|
|
const programPath = path;
|
|
visitor.enter(programPath);
|
|
programPath.traverse({
|
|
Function: visitor,
|
|
Class: visitor,
|
|
});
|
|
visitor.exit(programPath);
|
|
const metroMetadata = metadata;
|
|
const functionMap = encoder.getResult();
|
|
if (!metroMetadata.metro) {
|
|
metroMetadata.metro = {
|
|
functionMap,
|
|
};
|
|
} else {
|
|
metroMetadata.metro.functionMap = functionMap;
|
|
}
|
|
},
|
|
};
|
|
}
|
|
function getFunctionMapVisitor(context, pushMapping) {
|
|
const nameStack = [];
|
|
let tailPos = {
|
|
line: 1,
|
|
column: 0,
|
|
};
|
|
let tailName = null;
|
|
function advanceToPos(pos) {
|
|
if (tailPos && positionGreater(pos, tailPos)) {
|
|
const name = nameStack[0].name;
|
|
if (name !== tailName) {
|
|
pushMapping({
|
|
name,
|
|
start: {
|
|
line: tailPos.line,
|
|
column: tailPos.column,
|
|
},
|
|
});
|
|
tailName = name;
|
|
}
|
|
}
|
|
tailPos = pos;
|
|
}
|
|
function pushFrame(name, loc) {
|
|
advanceToPos(loc.start);
|
|
nameStack.unshift({
|
|
name,
|
|
loc,
|
|
});
|
|
}
|
|
function popFrame() {
|
|
const top = nameStack[0];
|
|
if (top) {
|
|
const { loc } = top;
|
|
advanceToPos(loc.end);
|
|
nameStack.shift();
|
|
}
|
|
}
|
|
if (!context) {
|
|
context = {};
|
|
}
|
|
const basename = context.filename
|
|
? fsPath.basename(context.filename).replace(/\..+$/, "")
|
|
: null;
|
|
return {
|
|
enter(path) {
|
|
let name = getNameForPath(path);
|
|
if (basename) {
|
|
name = removeNamePrefix(name, basename);
|
|
}
|
|
pushFrame(name, nullthrows(path.node.loc));
|
|
},
|
|
exit(path) {
|
|
popFrame();
|
|
},
|
|
};
|
|
}
|
|
function forEachMapping(ast, context, pushMapping) {
|
|
const visitor = getFunctionMapVisitor(context, pushMapping);
|
|
const previousCache = _traverse.default.cache.path;
|
|
_traverse.default.cache.clearPath();
|
|
(0, _traverse.default)(ast, {
|
|
noScope: true,
|
|
Function: visitor,
|
|
Program: visitor,
|
|
Class: visitor,
|
|
});
|
|
_traverse.default.cache.path = previousCache;
|
|
}
|
|
const ANONYMOUS_NAME = "<anonymous>";
|
|
function getNameForPath(path) {
|
|
const { node, parent, parentPath } = path;
|
|
if ((0, _types.isProgram)(node)) {
|
|
return "<global>";
|
|
}
|
|
let { id } = path;
|
|
if (node.id) {
|
|
return node.id.name;
|
|
}
|
|
let propertyPath;
|
|
let kind;
|
|
if ((0, _types.isObjectMethod)(node) || (0, _types.isClassMethod)(node)) {
|
|
id = node.key;
|
|
if (node.kind !== "method" && node.kind !== "constructor") {
|
|
kind = node.kind;
|
|
}
|
|
propertyPath = path;
|
|
} else if (
|
|
(0, _types.isObjectProperty)(parent) ||
|
|
(0, _types.isClassProperty)(parent)
|
|
) {
|
|
id = parent.key;
|
|
propertyPath = parentPath;
|
|
} else if ((0, _types.isVariableDeclarator)(parent)) {
|
|
id = parent.id;
|
|
} else if ((0, _types.isAssignmentExpression)(parent)) {
|
|
id = parent.left;
|
|
} else if ((0, _types.isJSXExpressionContainer)(parent)) {
|
|
const grandParentNode = parentPath?.parentPath?.node;
|
|
if ((0, _types.isJSXElement)(grandParentNode)) {
|
|
const openingElement = grandParentNode.openingElement;
|
|
id = t.jsxMemberExpression(
|
|
t.jsxMemberExpression(openingElement.name, t.jsxIdentifier("props")),
|
|
t.jsxIdentifier("children")
|
|
);
|
|
} else if ((0, _types.isJSXAttribute)(grandParentNode)) {
|
|
const openingElement = parentPath?.parentPath?.parentPath?.node;
|
|
const prop = grandParentNode;
|
|
id = t.jsxMemberExpression(
|
|
t.jsxMemberExpression(openingElement.name, t.jsxIdentifier("props")),
|
|
prop.name
|
|
);
|
|
}
|
|
}
|
|
let name = getNameFromId(id);
|
|
if (name == null) {
|
|
if (isAnyCallExpression(parent)) {
|
|
const argIndex = parent.arguments.indexOf(node);
|
|
if (argIndex !== -1) {
|
|
const calleeName = getNameFromId(parent.callee);
|
|
if (argIndex === 0 && calleeName === "Object.freeze") {
|
|
return getNameForPath(nullthrows(parentPath));
|
|
}
|
|
if (
|
|
argIndex === 0 &&
|
|
(calleeName === "useCallback" || calleeName === "React.useCallback")
|
|
) {
|
|
return getNameForPath(nullthrows(parentPath));
|
|
}
|
|
if (calleeName) {
|
|
return `${calleeName}$argument_${argIndex}`;
|
|
}
|
|
}
|
|
}
|
|
if (
|
|
(0, _types.isTypeCastExpression)(parent) &&
|
|
parent.expression === node
|
|
) {
|
|
return getNameForPath(nullthrows(parentPath));
|
|
}
|
|
if ((0, _types.isExportDefaultDeclaration)(parent)) {
|
|
return "default";
|
|
}
|
|
return ANONYMOUS_NAME;
|
|
}
|
|
if (kind != null) {
|
|
name = kind + "__" + name;
|
|
}
|
|
if (propertyPath) {
|
|
if ((0, _types.isClassBody)(propertyPath.parent)) {
|
|
const className = getNameForPath(propertyPath.parentPath.parentPath);
|
|
if (className !== ANONYMOUS_NAME) {
|
|
const separator = propertyPath.node.static ? "." : "#";
|
|
name = className + separator + name;
|
|
}
|
|
} else if ((0, _types.isObjectExpression)(propertyPath.parent)) {
|
|
const objectName = getNameForPath(nullthrows(propertyPath.parentPath));
|
|
if (objectName !== ANONYMOUS_NAME) {
|
|
name = objectName + "." + name;
|
|
}
|
|
}
|
|
}
|
|
return name;
|
|
}
|
|
function isAnyCallExpression(node) {
|
|
return (
|
|
node.type === "CallExpression" ||
|
|
node.type === "NewExpression" ||
|
|
node.type === "OptionalCallExpression"
|
|
);
|
|
}
|
|
function isAnyMemberExpression(node) {
|
|
return (
|
|
node.type === "MemberExpression" ||
|
|
node.type === "JSXMemberExpression" ||
|
|
node.type === "OptionalMemberExpression"
|
|
);
|
|
}
|
|
function isAnyIdentifier(node) {
|
|
return (0, _types.isIdentifier)(node) || (0, _types.isJSXIdentifier)(node);
|
|
}
|
|
function getNameFromId(id) {
|
|
const parts = getNamePartsFromId(id);
|
|
if (!parts.length) {
|
|
return null;
|
|
}
|
|
if (parts.length > 5) {
|
|
return (
|
|
parts[0] +
|
|
"." +
|
|
parts[1] +
|
|
"..." +
|
|
parts[parts.length - 2] +
|
|
"." +
|
|
parts[parts.length - 1]
|
|
);
|
|
}
|
|
return parts.join(".");
|
|
}
|
|
function getNamePartsFromId(id) {
|
|
if (!id) {
|
|
return [];
|
|
}
|
|
if (isAnyCallExpression(id)) {
|
|
return getNamePartsFromId(id.callee);
|
|
}
|
|
if ((0, _types.isTypeCastExpression)(id)) {
|
|
return getNamePartsFromId(id.expression);
|
|
}
|
|
let name;
|
|
if (isAnyIdentifier(id)) {
|
|
name = id.name;
|
|
} else if ((0, _types.isNullLiteral)(id)) {
|
|
name = "null";
|
|
} else if ((0, _types.isRegExpLiteral)(id)) {
|
|
name = `_${id.pattern}_${id.flags ?? ""}`;
|
|
} else if ((0, _types.isTemplateLiteral)(id)) {
|
|
name = id.quasis.map((quasi) => quasi.value.raw).join("");
|
|
} else if ((0, _types.isLiteral)(id) && id.value != null) {
|
|
name = String(id.value);
|
|
}
|
|
if (name != null) {
|
|
return [t.toBindingIdentifierName(name)];
|
|
}
|
|
if ((0, _types.isImport)(id)) {
|
|
name = "import";
|
|
}
|
|
if (name != null) {
|
|
return [name];
|
|
}
|
|
if (isAnyMemberExpression(id)) {
|
|
if (
|
|
isAnyIdentifier(id.object) &&
|
|
id.object.name === "Symbol" &&
|
|
(isAnyIdentifier(id.property) || (0, _types.isLiteral)(id.property))
|
|
) {
|
|
const propertyName = getNameFromId(id.property);
|
|
if (propertyName) {
|
|
name = "@@" + propertyName;
|
|
}
|
|
} else {
|
|
const propertyName = getNamePartsFromId(id.property);
|
|
if (propertyName.length) {
|
|
const objectName = getNamePartsFromId(id.object);
|
|
if (objectName.length) {
|
|
return [...objectName, ...propertyName];
|
|
} else {
|
|
return propertyName;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return name ? [name] : [];
|
|
}
|
|
const DELIMITER_START_RE = /^[^A-Za-z0-9_$@]+/;
|
|
function removeNamePrefix(name, namePrefix) {
|
|
if (!namePrefix.length || !name.startsWith(namePrefix)) {
|
|
return name;
|
|
}
|
|
const shortenedName = name.substr(namePrefix.length);
|
|
const [delimiterMatch] = shortenedName.match(DELIMITER_START_RE) || [];
|
|
if (delimiterMatch) {
|
|
return shortenedName.substr(delimiterMatch.length) || name;
|
|
}
|
|
return name;
|
|
}
|
|
class MappingEncoder {
|
|
constructor() {
|
|
this._namesMap = new Map();
|
|
this._names = [];
|
|
this._line = new RelativeValue(1);
|
|
this._column = new RelativeValue(0);
|
|
this._nameIndex = new RelativeValue(0);
|
|
this._mappings = new B64Builder();
|
|
}
|
|
getResult() {
|
|
return {
|
|
names: this._names,
|
|
mappings: this._mappings.toString(),
|
|
};
|
|
}
|
|
push({ name, start }) {
|
|
let nameIndex = this._namesMap.get(name);
|
|
if (typeof nameIndex !== "number") {
|
|
nameIndex = this._names.length;
|
|
this._names[nameIndex] = name;
|
|
this._namesMap.set(name, nameIndex);
|
|
}
|
|
const lineDelta = this._line.next(start.line);
|
|
const firstOfLine = this._mappings.pos === 0 || lineDelta > 0;
|
|
if (lineDelta > 0) {
|
|
this._mappings.markLines(1);
|
|
this._column.reset(0);
|
|
}
|
|
this._mappings.startSegment(this._column.next(start.column));
|
|
this._mappings.append(this._nameIndex.next(nameIndex));
|
|
if (firstOfLine) {
|
|
this._mappings.append(lineDelta);
|
|
}
|
|
}
|
|
}
|
|
class RelativeValue {
|
|
constructor(value = 0) {
|
|
this.reset(value);
|
|
}
|
|
next(absoluteValue) {
|
|
const delta = absoluteValue - this._value;
|
|
this._value = absoluteValue;
|
|
return delta;
|
|
}
|
|
reset(value = 0) {
|
|
this._value = value;
|
|
}
|
|
}
|
|
function positionGreater(x, y) {
|
|
return x.line > y.line || (x.line === y.line && x.column > y.column);
|
|
}
|
|
module.exports = {
|
|
functionMapBabelPlugin,
|
|
generateFunctionMap,
|
|
generateFunctionMappingsArray,
|
|
};
|