Select Git revision
Jonas Zohren authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
utils.ts 2.68 KiB
import type { DialogMap, DialogOption, DialogSet } from "./types";
/**
* Returns true, if input is a valid name of a dialogSet.
* Intended to protect from loading anything other than dialogSet json.
* @param input input to check
*/
function isValidDialogSetName(input: unknown) {
if (typeof input !== "string") {
return false;
}
if (input.length === 0) {
return false;
}
if (input.length > 50) {
return false;
}
return !/[^a-zA-Z0-9\-\_]/i.test(input);
}
function getHashValue(): string {
return window.location.hash.substr(1);
}
/**
* Fetch a dialogSet based on the hash value
*/
export async function fetchDialogSet(): Promise<DialogSet> {
const setName = getHashValue();
if (!isValidDialogSetName(setName))
throw new Error("Name is not valid dialogSet name");
const dialogSetUrl = "./dialogs/" + setName + ".json";
try {
const dialogSet: DialogSet = await (await fetch(dialogSetUrl)).json();
return dialogSet;
} catch (error) {
throw error;
}
}
export function findDialogSetProblems(dialogSet: DialogSet) {
const dialogReferenceProblems = checkForInvalidDialogReferences(dialogSet);
return [...dialogReferenceProblems];
}
interface DialogReferenceProblem {
type: "DialogReferenceProblem";
sourceDialog: string;
text: string;
}
function checkForInvalidDialogReferences(
dialogSet: DialogSet
): DialogReferenceProblem[] {
const dialogs = dialogSet.dialogs;
const problems: DialogReferenceProblem[] = [];
const allDialogKeys = Object.keys(dialogs);
const allLinkedToDialogKeys: Set<string> = new Set();
for (const dialogName of allDialogKeys) {
// TODO check all buttons for invalid references
for (const { text, linksToDialog } of dialogs[dialogName].options) {
allLinkedToDialogKeys.add(linksToDialog);
if (!allDialogKeys.includes(linksToDialog)) {
problems.push({
type: "DialogReferenceProblem",
sourceDialog: dialogName,
text: `Dialog ${dialogName}'s option "${text}" links to unknown dialog '${linksToDialog}'`,
}); }
if (linksToDialog === dialogName) {
problems.push({
type: "DialogReferenceProblem",
sourceDialog: dialogName,
text: `Dialog ${dialogName}'s option "${text}" links to itself!`,
});
}
}
}
for (const dialogName of allDialogKeys) {
if (
!allLinkedToDialogKeys.has(dialogName) &&
dialogSet.startDialogName !== dialogName
) {
problems.push({
type: "DialogReferenceProblem",
sourceDialog: dialogName,
text: `Dialog ${dialogName} is unreachable: Neither linked to from any other dialog, nor startDialog`,
});
}
}
return problems;
}