Migrate remaining legacy operator workflows
This commit is contained in:
@@ -13,6 +13,9 @@
|
||||
const MAXIMUM_PAGE_COUNT = 20;
|
||||
const MAXIMUM_STORED_PAGE_COUNT = 9999;
|
||||
const DEFAULT_MAXIMUM_DEFINITIONS = 200;
|
||||
const MAXIMUM_SELECTION_FIELD_LENGTH = 256;
|
||||
const MAXIMUM_SUBJECT_FIELD_LENGTH = 4000;
|
||||
const MAXIMUM_LIST_TEXT_LENGTH = 4000;
|
||||
const identifierPattern = /^[A-Za-z0-9_-]{1,128}$/;
|
||||
const programCodePattern = /^[0-9]{8}$/;
|
||||
const cutCodePattern = /^[0-9]{1,8}$/;
|
||||
@@ -145,11 +148,11 @@
|
||||
if (!hasExactKeys(value, ["groupCode", "subject", "graphicType", "subtype", "dataCode"])) {
|
||||
return null;
|
||||
}
|
||||
const groupCode = exactText(value.groupCode, 256, true);
|
||||
const subject = exactText(value.subject, 256, true);
|
||||
const graphicType = exactText(value.graphicType, 256, true);
|
||||
const subtype = exactText(value.subtype, 256, true);
|
||||
const dataCode = exactText(value.dataCode, 256, true);
|
||||
const groupCode = exactText(value.groupCode, MAXIMUM_SELECTION_FIELD_LENGTH, true);
|
||||
const subject = exactText(value.subject, MAXIMUM_SUBJECT_FIELD_LENGTH, true);
|
||||
const graphicType = exactText(value.graphicType, MAXIMUM_SELECTION_FIELD_LENGTH, true);
|
||||
const subtype = exactText(value.subtype, MAXIMUM_SELECTION_FIELD_LENGTH, true);
|
||||
const dataCode = exactText(value.dataCode, MAXIMUM_SELECTION_FIELD_LENGTH, true);
|
||||
if ([groupCode, subject, graphicType, subtype, dataCode].some(field => field === null)) return null;
|
||||
return Object.freeze({ groupCode, subject, graphicType, subtype, dataCode });
|
||||
}
|
||||
@@ -184,13 +187,18 @@
|
||||
fieldsValue.some(field => typeof field !== "string" || field.includes("^") ||
|
||||
controlCharacterPattern.test(field)) ||
|
||||
!["0", "1"].includes(fieldsValue[0]) ||
|
||||
fieldsValue.slice(1, 5).some(field => exactText(field, 256, true) === null) ||
|
||||
exactText(fieldsValue[6], 256, true) === null ||
|
||||
exactText(fieldsValue[1], MAXIMUM_SELECTION_FIELD_LENGTH, true) === null ||
|
||||
exactText(fieldsValue[2], MAXIMUM_SUBJECT_FIELD_LENGTH, true) === null ||
|
||||
exactText(fieldsValue[3], MAXIMUM_SELECTION_FIELD_LENGTH, true) === null ||
|
||||
exactText(fieldsValue[4], MAXIMUM_SELECTION_FIELD_LENGTH, true) === null ||
|
||||
exactText(fieldsValue[6], MAXIMUM_SELECTION_FIELD_LENGTH, true) === null ||
|
||||
(fieldsValue[5] !== "" && !parseStoredPageText(fieldsValue[5]))) {
|
||||
throw new TypeError("Exactly seven safe legacy playlist fields are required.");
|
||||
}
|
||||
const value = fieldsValue.join("^");
|
||||
if (value.length > 4000) throw new RangeError("The legacy LIST_TEXT value is too long.");
|
||||
if (value.length > MAXIMUM_LIST_TEXT_LENGTH) {
|
||||
throw new RangeError("The legacy LIST_TEXT value is too long.");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -209,6 +217,9 @@
|
||||
if (options.pageTextForEntry !== undefined && typeof options.pageTextForEntry !== "function") {
|
||||
throw new TypeError("pageTextForEntry must be a function when supplied.");
|
||||
}
|
||||
if (options.fieldsForEntry !== undefined && typeof options.fieldsForEntry !== "function") {
|
||||
throw new TypeError("fieldsForEntry must be a function when supplied.");
|
||||
}
|
||||
|
||||
const items = playlistEntries.map((entry, itemIndex) => {
|
||||
if (options.isTrustedEntry(entry, itemIndex) !== true) {
|
||||
@@ -217,7 +228,16 @@
|
||||
const pageText = options.pageTextForEntry
|
||||
? options.pageTextForEntry(entry, itemIndex)
|
||||
: "1/1";
|
||||
const fields = toLegacySevenFields(entry, pageText);
|
||||
const projected = options.fieldsForEntry
|
||||
? options.fieldsForEntry(entry, itemIndex, pageText)
|
||||
: undefined;
|
||||
const fields = options.fieldsForEntry
|
||||
? projected
|
||||
: toLegacySevenFields(entry, pageText);
|
||||
if (!Array.isArray(fields) || fields.length !== 7 ||
|
||||
fields[0] !== (entry.enabled ? "1" : "0") || fields[5] !== pageText) {
|
||||
throw new TypeError(`Playlist entry ${itemIndex} has no exact legacy seven-field projection.`);
|
||||
}
|
||||
legacyListText(fields);
|
||||
return Object.freeze({
|
||||
itemIndex,
|
||||
@@ -367,18 +387,29 @@
|
||||
return Object.freeze(copy);
|
||||
}
|
||||
|
||||
function trustedEntryMatchesRaw(entry, rawRow) {
|
||||
function compatibleSelection(entry, rawRow, compatibilityVerifier) {
|
||||
if (sameSelection(entry, rawRow)) return true;
|
||||
if (typeof compatibilityVerifier !== "function") return false;
|
||||
try {
|
||||
return compatibilityVerifier(entry, rawRow) === true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function trustedEntryMatchesRaw(entry, rawRow, compatibilityVerifier) {
|
||||
return isPlainObject(entry) && requestId(entry.id) &&
|
||||
typeof entry.builderKey === "string" && builderKeyPattern.test(entry.builderKey) &&
|
||||
typeof entry.code === "string" && cutCodePattern.test(entry.code) &&
|
||||
entry.enabled === rawRow.enabled && sameSelection(entry, rawRow);
|
||||
entry.enabled === rawRow.enabled && compatibleSelection(entry, rawRow, compatibilityVerifier);
|
||||
}
|
||||
|
||||
function restoreRawRows(loadValue, trustedResolver) {
|
||||
function restoreRawRows(loadValue, trustedResolver, compatibilityVerifier) {
|
||||
const load = loadValue?.kind === "named-playlist-load"
|
||||
? loadValue
|
||||
: normalizeLoadResponse(loadValue);
|
||||
if (!load || typeof trustedResolver !== "function") {
|
||||
if (!load || typeof trustedResolver !== "function" ||
|
||||
(compatibilityVerifier !== undefined && typeof compatibilityVerifier !== "function")) {
|
||||
throw new TypeError("A normalized load response and trusted resolver are required.");
|
||||
}
|
||||
const rows = load.rawRows.map(rawRow => {
|
||||
@@ -388,7 +419,7 @@
|
||||
} catch {
|
||||
candidate = null;
|
||||
}
|
||||
const trusted = trustedEntryMatchesRaw(candidate, rawRow);
|
||||
const trusted = trustedEntryMatchesRaw(candidate, rawRow, compatibilityVerifier);
|
||||
return Object.freeze({
|
||||
rawRow,
|
||||
entry: trusted ? freezeTrustedEntry(candidate) : null,
|
||||
|
||||
Reference in New Issue
Block a user