docs: update union member resolution documentation
Refactor union resolution to explicitly try reference members before non-reference members. This replaces the previous error-message-based fallback with a deterministic, structural approach. - Update `parseValueWithReferences` and `resolveNestedReferences` to partition members by reference presence. - Update documentation in `README.md`, `AGENTS.md`, and `syntax-rework-plan.md` to reflect this behavior.
This commit is contained in:
@@ -299,39 +299,27 @@ export function parseValueWithReferences(
|
||||
);
|
||||
}
|
||||
case "union": {
|
||||
// Try reference members first (more specific), then non-reference members.
|
||||
// This makes the fallback structural rather than error-message-driven.
|
||||
const refMembers = schema.members.filter(hasNestedReferences);
|
||||
const nonRefMembers = schema.members.filter((m) => !hasNestedReferences(m));
|
||||
const errors: Error[] = [];
|
||||
for (const member of schema.members) {
|
||||
if (hasNestedReferences(member)) {
|
||||
try {
|
||||
const parsed = parseValue(member, valueString);
|
||||
return resolveNestedReferences(
|
||||
parsed,
|
||||
member,
|
||||
refBaseDir,
|
||||
defaultPrimaryKey,
|
||||
currentFilePath,
|
||||
currentRowPk,
|
||||
);
|
||||
} catch (e) {
|
||||
errors.push(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
for (const member of [...refMembers, ...nonRefMembers]) {
|
||||
try {
|
||||
const parsed = parseValue(member, valueString);
|
||||
return resolveNestedReferences(
|
||||
parsed,
|
||||
member,
|
||||
refBaseDir,
|
||||
defaultPrimaryKey,
|
||||
currentFilePath,
|
||||
currentRowPk,
|
||||
);
|
||||
} catch (e) {
|
||||
errors.push(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
}
|
||||
if (
|
||||
errors.length > 0 &&
|
||||
errors.every((e) =>
|
||||
/not found|Circular reference|Failed to load/.test(e.message),
|
||||
)
|
||||
) {
|
||||
for (const member of schema.members) {
|
||||
if (!hasNestedReferences(member)) {
|
||||
try {
|
||||
return parseValue(member, valueString);
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
||||
return parseValue(schema, valueString);
|
||||
throw errors[0] ?? new Error("Value does not match any union member");
|
||||
}
|
||||
default:
|
||||
return parseValue(schema, valueString);
|
||||
@@ -425,21 +413,22 @@ export function resolveNestedReferences(
|
||||
);
|
||||
}
|
||||
case "union": {
|
||||
// Try reference members first (more specific), then non-reference members.
|
||||
const refMembers = schema.members.filter(hasNestedReferences);
|
||||
const nonRefMembers = schema.members.filter((m) => !hasNestedReferences(m));
|
||||
const errors: Error[] = [];
|
||||
for (const member of schema.members) {
|
||||
if (hasNestedReferences(member)) {
|
||||
try {
|
||||
return resolveNestedReferences(
|
||||
value,
|
||||
member,
|
||||
refBaseDir,
|
||||
defaultPrimaryKey,
|
||||
currentFilePath,
|
||||
currentRowPk,
|
||||
);
|
||||
} catch (e) {
|
||||
errors.push(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
for (const member of [...refMembers, ...nonRefMembers]) {
|
||||
try {
|
||||
return resolveNestedReferences(
|
||||
value,
|
||||
member,
|
||||
refBaseDir,
|
||||
defaultPrimaryKey,
|
||||
currentFilePath,
|
||||
currentRowPk,
|
||||
);
|
||||
} catch (e) {
|
||||
errors.push(e instanceof Error ? e : new Error(String(e)));
|
||||
}
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user