152 lines
3.9 KiB
TypeScript
152 lines
3.9 KiB
TypeScript
import type { RemoteObject } from "../types";
|
|
|
|
export function asRecord(value: unknown): RemoteObject {
|
|
return value && typeof value === "object" && !Array.isArray(value) ? (value as RemoteObject) : {};
|
|
}
|
|
|
|
export function isObjectRecord(value: unknown): value is RemoteObject {
|
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
}
|
|
|
|
export function firstString(source: RemoteObject, keys: string[], fallback = ""): string {
|
|
for (const key of keys) {
|
|
const value = source[key];
|
|
if (typeof value === "string" && value.trim()) {
|
|
return value;
|
|
}
|
|
if (typeof value === "number") {
|
|
return String(value);
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
export function findStringDeep(value: unknown, keys: string[], depth = 0): string {
|
|
if (depth > 3) {
|
|
return "";
|
|
}
|
|
|
|
if (typeof value === "string") {
|
|
return value;
|
|
}
|
|
|
|
if (!isObjectRecord(value)) {
|
|
return "";
|
|
}
|
|
|
|
for (const key of keys) {
|
|
const direct = value[key];
|
|
if (typeof direct === "string" && direct.trim()) {
|
|
return direct;
|
|
}
|
|
if (isObjectRecord(direct)) {
|
|
const nested = findStringDeep(direct, keys, depth + 1);
|
|
if (nested) {
|
|
return nested;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const nestedValue of Object.values(value)) {
|
|
if (Array.isArray(nestedValue)) {
|
|
continue;
|
|
}
|
|
const nested = findStringDeep(nestedValue, keys, depth + 1);
|
|
if (nested) {
|
|
return nested;
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
export function extractObjectPath(value: unknown): string {
|
|
if (typeof value === "string") {
|
|
return value;
|
|
}
|
|
|
|
return findStringDeep(value, [
|
|
"objectPath",
|
|
"ObjectPath",
|
|
"path",
|
|
"Path",
|
|
"actorPath",
|
|
"ActorPath",
|
|
"softObjectPath",
|
|
"SoftObjectPath",
|
|
"name",
|
|
"Name",
|
|
]);
|
|
}
|
|
|
|
export function nestedString(source: RemoteObject, keys: string[], fallback = ""): string {
|
|
for (const key of keys) {
|
|
const value = source[key];
|
|
if (typeof value === "string" && value.trim()) {
|
|
return value;
|
|
}
|
|
const nested = asRecord(value);
|
|
const nestedValue = firstString(nested, ["Name", "name", "Path", "path", "ObjectPath", "objectPath"]);
|
|
if (nestedValue) {
|
|
return nestedValue;
|
|
}
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
export function basename(path: string): string {
|
|
const clean = path.replace(/["']/g, "");
|
|
const colonName = clean.split(":").pop() ?? clean;
|
|
const dotName = colonName.split(".").pop() ?? colonName;
|
|
const slashName = dotName.split("/").pop() ?? dotName;
|
|
return slashName || clean || "Actor";
|
|
}
|
|
|
|
export function cleanObjectName(name: string): string {
|
|
return name
|
|
.replace(/^Default__/, "")
|
|
.replace(/^UEDPIE_\d+_/, "")
|
|
.replace(/_\d+$/, (suffix) => (suffix === "_0" ? "_0" : suffix));
|
|
}
|
|
|
|
export function deriveLevelNameFromPath(path: string): string {
|
|
if (!path) {
|
|
return "";
|
|
}
|
|
|
|
const clean = path.replace(/["']/g, "");
|
|
const packagePath = clean.includes(":") ? clean.split(":")[0] : clean;
|
|
const objectName = packagePath.split(".").pop() ?? packagePath;
|
|
return cleanObjectName(basename(objectName));
|
|
}
|
|
|
|
export function extractReturnValue(payload: unknown): unknown[] {
|
|
if (Array.isArray(payload)) {
|
|
return payload;
|
|
}
|
|
const record = asRecord(payload);
|
|
const returnValue = record.ReturnValue ?? record.returnValue ?? record.Result ?? record.result;
|
|
if (Array.isArray(returnValue)) {
|
|
return returnValue;
|
|
}
|
|
const nested = asRecord(returnValue);
|
|
for (const value of Object.values(nested)) {
|
|
if (Array.isArray(value)) {
|
|
return value;
|
|
}
|
|
}
|
|
return [];
|
|
}
|
|
|
|
export function extractFirstReturnString(payload: unknown): string {
|
|
const record = asRecord(payload);
|
|
const returnValue = record.ReturnValue ?? record.returnValue ?? record.Result ?? record.result;
|
|
if (typeof returnValue === "string") {
|
|
return returnValue;
|
|
}
|
|
if (typeof returnValue === "number") {
|
|
return String(returnValue);
|
|
}
|
|
return firstString(asRecord(returnValue), ["Name", "name", "Label", "label", "DisplayName", "displayName"]);
|
|
}
|