2023-07-24 17:54:31 +00:00
|
|
|
import {
|
|
|
|
findNodeOfType,
|
|
|
|
ParseTree,
|
2023-07-26 15:12:56 +00:00
|
|
|
replaceNodesMatchingAsync,
|
2023-07-24 17:54:31 +00:00
|
|
|
} from "$sb/lib/tree.ts";
|
|
|
|
|
2023-07-26 15:12:56 +00:00
|
|
|
import { YAML } from "$sb/plugos-syscall/mod.ts";
|
|
|
|
|
2023-07-24 17:54:31 +00:00
|
|
|
/**
|
|
|
|
* Extracts attributes from a tree, optionally cleaning them out of the tree.
|
|
|
|
* @param tree tree to extract attributes from
|
|
|
|
* @param clean whether or not to clean out the attributes from the tree
|
|
|
|
* @returns mapping from attribute name to attribute value
|
|
|
|
*/
|
2023-07-26 15:12:56 +00:00
|
|
|
export async function extractAttributes(
|
2023-07-24 17:54:31 +00:00
|
|
|
tree: ParseTree,
|
|
|
|
clean: boolean,
|
2023-07-26 15:12:56 +00:00
|
|
|
): Promise<Record<string, any>> {
|
2023-07-24 17:54:31 +00:00
|
|
|
const attributes: Record<string, any> = {};
|
2023-07-26 15:12:56 +00:00
|
|
|
await replaceNodesMatchingAsync(tree, async (n) => {
|
2023-07-24 17:54:31 +00:00
|
|
|
if (n.type === "ListItem") {
|
|
|
|
// Find top-level only, no nested lists
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
if (n.type === "Attribute") {
|
|
|
|
const nameNode = findNodeOfType(n, "AttributeName");
|
|
|
|
const valueNode = findNodeOfType(n, "AttributeValue");
|
|
|
|
if (nameNode && valueNode) {
|
2023-07-26 15:12:56 +00:00
|
|
|
const name = nameNode.children![0].text!;
|
|
|
|
const val = valueNode.children![0].text!;
|
|
|
|
try {
|
|
|
|
attributes[name] = await YAML.parse(val);
|
|
|
|
} catch (e: any) {
|
|
|
|
console.error("Error parsing attribute value as YAML", val, e);
|
2023-07-24 17:54:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Remove from tree
|
|
|
|
if (clean) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Go on...
|
|
|
|
return undefined;
|
|
|
|
});
|
|
|
|
return attributes;
|
|
|
|
}
|