Files
knowledge-one-view-cli/tests/helpers/catalogs.mjs

191 lines
6.1 KiB
JavaScript

import fs from "node:fs/promises";
import path from "node:path";
import { skillHome } from "./cli.mjs";
export async function readSkillCatalogs() {
const [skill, scriptCatalog, initialContext, apiMap] = await Promise.all([
fs.readFile(path.join(skillHome, "SKILL.md"), "utf8"),
fs.readFile(path.join(skillHome, "references", "script-catalog.md"), "utf8"),
fs.readFile(path.join(skillHome, "references", "initial-context-catalog.md"), "utf8"),
fs.readFile(path.join(skillHome, "references", "api-map.md"), "utf8"),
]);
return {
skill,
scriptCatalog,
initialContext,
apiMap,
allText: [skill, scriptCatalog, initialContext, apiMap].join("\n"),
};
}
export function documentedFlags(catalogs) {
const flags = new Set();
const regex = /`(--[a-z0-9-]+)(?:\s+[^`]*)?`/gi;
let match = regex.exec(catalogs.allText);
while (match) {
flags.add(match[1]);
match = regex.exec(catalogs.allText);
}
return flags;
}
export function catalogMentionsIntent(catalogs, intentName) {
return new RegExp(`\\b${escapeRegExp(intentName)}\\b`).test(catalogs.skill + "\n" + catalogs.scriptCatalog);
}
export function catalogMentionsView(catalogs, viewName) {
return new RegExp(`\\b${escapeRegExp(viewName)}\\b`).test(catalogs.skill + "\n" + catalogs.scriptCatalog);
}
export function commandAppearsInCatalog(catalogs, args) {
const normalizedCatalog = normalizeWhitespace(catalogs.skill + "\n" + catalogs.scriptCatalog + "\n" + catalogs.apiMap);
const normalizedArgs = normalizeWhitespace(args.join(" "));
return normalizedCatalog.includes(normalizedArgs);
}
export function parseDefaultWeekYear(scriptCatalog) {
const match = /-\s*`week-year\s+(\d{4})`/i.exec(scriptCatalog);
if (!match) {
throw new Error("Could not parse default week-year from references/script-catalog.md.");
}
return Number(match[1]);
}
export function parseWeekRow(scriptCatalog, weekLabel) {
const normalizedLabel = String(weekLabel).toUpperCase().replace(/^W?/, "W");
const regex = new RegExp(`\\|\\s*${escapeRegExp(normalizedLabel)}\\s*\\|\\s*(\\d{4}-\\d{2}-\\d{2})\\s*\\|\\s*(\\d{4}-\\d{2}-\\d{2})\\s*\\|`, "i");
const match = regex.exec(scriptCatalog);
if (!match) {
throw new Error(`Could not parse ${normalizedLabel} from references/script-catalog.md.`);
}
return {
weekLabel: normalizedLabel,
fromDate: match[1],
toDate: match[2],
};
}
export function parseSaAttachDefaults(initialContext) {
const line = findLine(initialContext, "SA Attach defaults:");
const rawDefaults = line.slice(line.indexOf(":") + 1).split(";").map((part) => part.trim()).filter(Boolean);
const defaults = {};
for (const part of rawDefaults) {
const match = /`--([^=]+)=([^`]+)`/.exec(part);
if (!match) continue;
defaults[toCamelKey(match[1])] = splitCatalogCsv(match[2]);
}
return defaults;
}
export function parseSaAttachAliases(initialContext) {
const line = findLine(initialContext, "SA Attach aliases:");
const aliases = {};
const rawAliases = line.slice(line.indexOf(":") + 1).split(";").map((part) => part.trim()).filter(Boolean);
for (const item of rawAliases) {
const match = /`([^`]+)`\s*->\s*`([^`]+)`/.exec(item);
if (!match) continue;
aliases[match[1].toLowerCase()] = splitCatalogCsv(match[2]);
}
return aliases;
}
export function catalogSaysCurrentWorkloadDefaults(catalogs, intentName) {
try {
parseCurrentWorkloadDefaults(catalogs, intentName);
return true;
} catch {
return false;
}
}
export function parseCurrentWorkloadDefaults(catalogs, intentName) {
const source = catalogs.skill + "\n" + catalogs.scriptCatalog;
const pattern = new RegExp(
`\\\`${escapeRegExp(intentName)}\\\`[\\s\\S]{0,500}?defaults? to \\\`([^\\\`]+)\\\`, \\\`([^\\\`]+)\\\`, and \\\`([^\\\`]+)\\\``,
"i"
);
const match = pattern.exec(source);
if (!match) {
throw new Error(`Could not parse documented defaults for ${intentName}.`);
}
return {
quarter: match[1],
solution: match[2],
revenueTypeGroup: match[3],
};
}
export function catalogSaysUseRevenueLineCloseDate(catalogs) {
try {
parseSaAttachDateWindowField(catalogs);
return true;
} catch {
return false;
}
}
export function parseSaAttachDateWindowField(catalogs) {
const match =
/date-window flags now constrain `([^`]+)` directly/i.exec(catalogs.skill) ||
/date-window flags are applied to `([^`]+)`/i.exec(catalogs.scriptCatalog);
if (!match) {
throw new Error("Could not parse the SA Attach date-window field from references.");
}
return match[1];
}
export function parsePrimaryCommercialSubjectArea(apiMap) {
const match = /Primary commercial subject area:[\s\S]*?`([^`]+)`/i.exec(apiMap);
if (!match) {
throw new Error("Could not parse the primary commercial subject area from references/api-map.md.");
}
return match[1];
}
export function parsePrimaryCommercialSourceName(apiMap) {
const subjectArea = parsePrimaryCommercialSubjectArea(apiMap);
const match = /\.'([^']+)'\)$/i.exec(subjectArea);
if (!match) {
throw new Error("Could not parse the primary commercial source name from references/api-map.md.");
}
return match[1];
}
export function catalogSaysPreserveMixedRows(catalogs) {
return /preserve every org-wide opportunity\/workload row/i.test(catalogs.skill);
}
export function catalogSaysApiMetricsAreRawRows(catalogs) {
return /apiMetrics\.totalRowsPulledFromApi/i.test(catalogs.skill)
&& /Do not add local-cache-only rows/i.test(catalogs.skill);
}
export function splitCatalogCsv(value) {
return String(value || "")
.split(",")
.map((item) => item.trim())
.filter(Boolean);
}
function findLine(text, marker) {
const line = String(text)
.split(/\r?\n/)
.find((candidate) => candidate.includes(marker));
if (!line) {
throw new Error(`Could not find "${marker}" in catalog text.`);
}
return line;
}
function toCamelKey(flagName) {
return flagName.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
}
function normalizeWhitespace(value) {
return String(value).replace(/\s+/g, " ").trim();
}
function escapeRegExp(value) {
return String(value).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}