fix(results): support legacy render refs
This commit is contained in:
+68
-4
@@ -10,9 +10,11 @@ import {
|
||||
listJsonFiles,
|
||||
readJsonFile,
|
||||
removeFileIfExists,
|
||||
toProjectKey,
|
||||
} from "../utils/fileStore.js";
|
||||
|
||||
export const RESULT_REF_PATTERN = /^res-[a-f0-9-]{16}$/;
|
||||
export const RESULT_REF_PATTERN = /^res-[a-f0-9-]{8,64}$/;
|
||||
const RESULT_REF_FILE_PATTERN = /^(res-[a-f0-9-]{8,64})(?:\.json)?$/;
|
||||
|
||||
export const RESULT_REFERENCE_KIND = {
|
||||
dynamicHttpResult: "dynamic-http-result",
|
||||
@@ -138,12 +140,15 @@ export class ResultReferenceStore {
|
||||
}
|
||||
|
||||
async getAuthorizedRecord(resultRef: string, context: RetrievalContext) {
|
||||
if (!RESULT_REF_PATTERN.test(resultRef)) {
|
||||
const normalizedResultRef = normalizeResultRef(resultRef);
|
||||
if (!normalizedResultRef) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const rawRecord = await readJsonFile<unknown>(this.filePath(resultRef));
|
||||
const record = normalizeResultReferenceRecord(rawRecord);
|
||||
const rawRecord = await readJsonFile<unknown>(this.filePath(normalizedResultRef));
|
||||
const record =
|
||||
normalizeResultReferenceRecord(rawRecord) ??
|
||||
normalizeLegacyRenderReferenceRecord(rawRecord, normalizedResultRef, context);
|
||||
if (!record) {
|
||||
return null;
|
||||
}
|
||||
@@ -301,6 +306,65 @@ const normalizeResultReferenceSource = (
|
||||
const isValidResultRef = (value: unknown): value is string =>
|
||||
typeof value === "string" && RESULT_REF_PATTERN.test(value);
|
||||
|
||||
const normalizeResultRef = (value: string) => {
|
||||
const match = value.trim().match(RESULT_REF_FILE_PATTERN);
|
||||
return match?.[1] ?? null;
|
||||
};
|
||||
|
||||
const normalizeLegacyRenderReferenceRecord = (
|
||||
value: unknown,
|
||||
resultRef: string,
|
||||
context: RetrievalContext,
|
||||
): ResultReferenceRecord | null => {
|
||||
const data = extractLegacyRenderPayload(value);
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const root = isRecord(value) ? value : {};
|
||||
const metadata = isRecord(root.metadata) ? root.metadata : {};
|
||||
const projectId = firstNonEmptyString(root.projectId, metadata.projectId);
|
||||
const createdAt =
|
||||
firstNonEmptyString(root.createdAt, metadata.createdAt) ?? new Date().toISOString();
|
||||
|
||||
return {
|
||||
resultRef,
|
||||
actorKey: context.actorKey,
|
||||
clientSessionId: context.clientSessionId ?? "",
|
||||
createdAt,
|
||||
data,
|
||||
kind: RESULT_REFERENCE_KIND.renderJunctionsPayload,
|
||||
preview: buildPreview(data),
|
||||
projectId,
|
||||
projectKey: toProjectKey(projectId),
|
||||
schemaVersion: 1,
|
||||
sessionId: context.clientSessionId ?? resultRef,
|
||||
sizeBytes: estimateBytes(data),
|
||||
source: RESULT_REFERENCE_SOURCE.legacy,
|
||||
traceId: "legacy-render-ref",
|
||||
};
|
||||
};
|
||||
|
||||
const extractLegacyRenderPayload = (value: unknown) => {
|
||||
if (!isRecord(value)) {
|
||||
return null;
|
||||
}
|
||||
const candidate = isRecord(value.data) ? value.data : value;
|
||||
if (!isRecord(candidate.node_area_map)) {
|
||||
return null;
|
||||
}
|
||||
return candidate;
|
||||
};
|
||||
|
||||
const firstNonEmptyString = (...values: unknown[]) => {
|
||||
for (const value of values) {
|
||||
if (typeof value === "string" && value.trim().length > 0) {
|
||||
return value.trim();
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const isResultPreview = (value: unknown): value is ResultPreview =>
|
||||
isRecord(value) &&
|
||||
typeof value.count === "number" &&
|
||||
|
||||
Reference in New Issue
Block a user