41 lines
2.0 KiB
TypeScript
41 lines
2.0 KiB
TypeScript
import { CorrectiveCommandRegistry } from "./corrective-command-registry";
|
|
import { CorrectiveCaseRunnerError, MainMutationCommand } from "./corrective-case-runner";
|
|
import { CORRECTIVE_FAMILIES, CorrectiveFamily } from "./corrective-family-runner";
|
|
import { InMemoryMainStore, runAtomicMutation } from "./corrective-main-transaction";
|
|
|
|
export interface GenericFamilyMain {
|
|
family: CorrectiveFamily;
|
|
value: string;
|
|
}
|
|
|
|
const VALUE = /^[A-Za-z0-9._:-]{1,128}$/u;
|
|
|
|
function payload(command: MainMutationCommand): { family: CorrectiveFamily; value: string } {
|
|
const input = command.payload;
|
|
if (typeof input.family !== "string" || !CORRECTIVE_FAMILIES.includes(input.family as CorrectiveFamily) || typeof input.value !== "string" || !VALUE.test(input.value) || Object.keys(input).some((key) => !["family", "value"].includes(key))) {
|
|
throw new CorrectiveCaseRunnerError("COMMAND_MALFORMED", "family payload must contain only a bounded family and value");
|
|
}
|
|
return { family: input.family as CorrectiveFamily, value: input.value };
|
|
}
|
|
|
|
export function createGenericFamilyMain(family: CorrectiveFamily, value = "before", revision = 1, dirty = false): InMemoryMainStore<GenericFamilyMain> {
|
|
return new InMemoryMainStore({ family, value }, revision, dirty, (state) => ({ ...state }));
|
|
}
|
|
|
|
export function createGenericFamilyRegistry(main: InMemoryMainStore<GenericFamilyMain>): CorrectiveCommandRegistry {
|
|
return new CorrectiveCommandRegistry().register({
|
|
commandType: "familySetState",
|
|
targetKinds: ["DATABLOCK", "SCENE"],
|
|
authorizations: ["USER_EDIT", "SYSTEM"],
|
|
execute: async (command) => {
|
|
const change = payload(command);
|
|
return runAtomicMutation(main, command, (draft) => {
|
|
if (draft.family !== change.family) throw new CorrectiveCaseRunnerError("INVALID_CONTEXT", "family does not match Main");
|
|
const previous = draft.value;
|
|
draft.value = change.value;
|
|
return { delta: { family: change.family, previous, value: change.value }, persistence: { dirty: true } };
|
|
});
|
|
},
|
|
});
|
|
}
|