Newer
Older
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 getParamValue(paramName: string): string | null {
return new URLSearchParams(window.location.search).get(paramName);
}
/**
* Fetch a dialogSet based on the hash value
*/
export async function fetchDialogSet(): Promise<DialogSet> {
const setName = getParamValue("dialogSet");
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;
}
}
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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;
}