fql-toolkit
Version:
391 lines (344 loc) • 9.62 kB
JavaScript
import FQLError from "./errors.js";
import { FQL_VALID_TYPES, FQL_DURING_EVENTS } from "./constants.js";
import FQLQueryBuilder from "./builders.js";
class FQLBuilderBase {
constructor(fqlClient) {
this.fqlClient = fqlClient;
}
async execute() {
const query = this.getFQL();
return await this.fqlClient.executeFQL(query);
}
}
class FQLFormBuilder extends FQLBuilderBase {
constructor(name, fqlClient) {
super(fqlClient);
if (!name || typeof name !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.name = name;
this.specs = [];
}
addDataDefinition({ name, type, notNull = false, unique = false }) {
if (!name || !type) {
throw new FQLError('Field name and type are required');
}
if (!FQL_VALID_TYPES.includes(type)) {
throw new FQLError(`Invalid FQL type: ${type}. Valid types: ${FQL_VALID_TYPES.join(', ')}`);
}
this.specs.push({ name, type, notNull, unique });
return this;
}
addDataReference({ name, cardinality = [0, 1], path, totally = false, unique = false }) {
if (!name || !path) {
throw new FQLError('Reference name and path are required');
}
if (typeof cardinality[0] !== 'number' || typeof cardinality[1] !== 'number') {
throw new FQLError("Reference cardinality must be a list of two integers");
}
if (!this.isPath(path)) {
throw new FQLError('Reference path is invalid');
}
this.specs.push({ name, type: "reference", cardinality, path, totally, unique });
return this;
}
isPath(path = []) {
if (typeof path === 'string') {
return true;
} else if (Array.isArray(path)) {
return path.every(this.isPath);
}
return false;
}
getFQL() {
if (this.specs.length === 0) {
throw new FQLError('Form must have at least one spec');
}
return FQLQueryBuilder.buildCreateFormQuery({ name: this.name, specs: this.specs });
}
}
class FQLShowFormsBuilder extends FQLBuilderBase {
constructor(fqlClient) {
super(fqlClient);
this.forms = [];
}
setForm(form) {
if (!form || typeof form !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.forms.push(form);
return this;
}
setForms(forms) {
forms.forEach(form => this.setForm(form));
return this;
}
getFQL() {
return FQLQueryBuilder.buildShowFormsQuery(this.forms);
}
}
class FQLRemoveFormsBuilder extends FQLBuilderBase {
constructor(fqlClient) {
super(fqlClient);
this.forms = [];
}
setForm(form) {
if (!form || typeof form !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.forms.push(form);
return this;
}
setForms(forms) {
forms.forEach(form => this.setForm(form));
return this;
}
getFQL() {
return FQLQueryBuilder.buildRemoveFormsQuery(this.forms);
}
}
class FQLDataBuilder extends FQLBuilderBase {
constructor(formName, fqlClient) {
super(fqlClient);
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.formName = formName;
this.values = [];
}
setValue(value) {
this.values.push(value);
return this;
}
setValues(...values) {
values.forEach(value => this.setValue(value));
return this;
}
getFQL() {
if (this.values.length === 0) {
throw new FQLError('Form must have at least one spec');
}
return FQLQueryBuilder.buildCreateNewQuery(this.formName, this.values);
}
}
class FQLGetCaseBuilder extends FQLBuilderBase {
constructor(formName, fqlClient) {
super(fqlClient);
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.formName = formName;
this.fields = [];
this.condition = null;
}
setField(field) {
if (typeof field !== 'string') {
throw new FQLError('Field must be a string');
}
this.fields.push(field);
return this;
}
setFields(fields) {
fields.forEach(field => this.setField(field));
return this;
}
with(condition) {
this.condition = condition;
return this;
}
getFQL() {
return FQLQueryBuilder.buildGetCaseQuery(this.formName, this.fields, this.condition);
}
}
class FQLRemoveCaseBuilder extends FQLBuilderBase {
constructor(formName, fqlClient) {
super(fqlClient);
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.formName = formName;
this.condition = null;
}
with(condition) {
this.condition = condition;
return this;
}
getFQL() {
if (!this.condition) {
throw new FQLError('Condition required');
}
return FQLQueryBuilder.buildRemoveCaseQuery(this.formName, this.condition);
}
}
class FQLModifyCaseBuilder extends FQLBuilderBase {
constructor(formName, fqlClient) {
super(fqlClient);
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
this.formName = formName;
this.values = [];
this.condition = null;
this.fqlToken = null;
}
setValue(value) {
this.values.push(value);
return this;
}
setValues(...values) {
values.forEach(value => this.setValue(value));
return this;
}
with(condition) {
this.condition = condition;
return this;
}
setFqlToken(token) {
this.fqlToken = token;
return this;
}
async execute() {
const query = this.getFQL();
return await this.fqlClient.executeFQL(query, this.fqlToken);
}
getFQL() {
if (this.values.length === 0) {
throw new FQLError('Modify case require values to modify');
}
if (!this.fqlToken) {
throw new FQLError('Modify case require an FQL Token');
}
return FQLQueryBuilder.buildModifyCaseQuery(this.formName, this.values, this.condition);
}
}
class FQLDefineRuleBuilder extends FQLBuilderBase {
constructor(ruleName, fqlClient) {
super(fqlClient);
if (!ruleName || typeof ruleName !== 'string') {
throw new FQLError('Rule name is required and must be a string');
}
this.ruleName = ruleName;
this.formName = null;
this.fields = [];
this.events = [];
this.condition = null;
this.action = null;
this.dict = [];
}
on(formName, fields = []) {
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name must be a string');
}
this.formName = formName;
this.fields = fields.map(field => {
if (typeof field !== 'string') {
throw new FQLError("Field value must be string");
}
return field;
});
return this;
}
during(...events) {
if (!events.every(event => FQL_DURING_EVENTS.includes(event))) {
throw new FQLError("During events must be: 'create', 'remove', or 'modify'");
}
this.events = events;
return this;
}
when(condition) {
if (!condition || !Array.isArray(condition)) {
throw new FQLError('The rule condition is wrong');
}
this.condition = condition;
return this;
}
isInvalid() {
this.action = "is invalid";
return this;
}
isUnique() {
this.action = "is unique";
return this;
}
set(key, value) {
this.action = "set";
this.dict.push({ key, value });
return this;
}
getFQL() {
if (!this.action) {
throw new FQLError("Action required");
}
if (!this.formName) {
throw new FQLError('Form name required');
}
switch (this.action) {
case "is invalid":
if (!this.condition) {
throw new FQLError("Condition required");
}
break;
case "is unique":
if (this.fields.length === 0) {
throw new FQLError("Fields required");
}
break;
case "set":
if (!this.condition) {
throw new FQLError("Condition required");
}
if (this.dict.length === 0) {
throw new FQLError("Set values required");
}
break;
default:
break;
}
return FQLQueryBuilder.buildDefineRuleQuery(this.ruleName, this.formName, this.fields, this.events, this.condition, this.action, this.dict);
}
}
class FQLDefineConceptBuilder extends FQLBuilderBase {
constructor(conceptName, fqlClient) {
super(fqlClient);
if (!conceptName || typeof conceptName !== 'string') {
throw new FQLError('Concept name is required and must be a string');
}
this.conceptName = conceptName;
this.entityName = null;
this.condition = null;
}
is(entityName) {
if (!entityName || typeof entityName !== 'string') {
throw new FQLError('Concept name is required and must be a string');
}
this.entityName = entityName;
return this;
}
with(condition) {
if (!condition || !Array.isArray(condition)) {
throw new FQLError('The rule condition is wrong');
}
this.condition = condition;
return this;
}
getFQL() {
if (!this.entityName) {
throw new FQLError('Entity name required');
}
if (!this.condition) {
throw new FQLError('Condition required');
}
return FQLQueryBuilder.buildDefineConceptQuery(this.conceptName, this.entityName, this.condition);
}
}
export {
FQLFormBuilder,
FQLShowFormsBuilder,
FQLRemoveFormsBuilder,
FQLDataBuilder,
FQLGetCaseBuilder,
FQLRemoveCaseBuilder,
FQLModifyCaseBuilder,
FQLDefineRuleBuilder,
FQLDefineConceptBuilder
};