fql-toolkit
Version:
112 lines • 4.19 kB
JavaScript
import FQLQueryBuilder from './builders.js';
import FQLError from './errors.js';
import { normalizeType } from './constants.js';
/**
* Manages form-level operations.
* Accessed via `client.forms`.
*
* @example
* await client.forms.create({
* name: 'customers',
* dataSpecs: [
* { name: 'name', type: 'text' },
* { name: 'email', type: 'text' },
* ],
* });
* await client.forms.show(['customers']);
* await client.forms.modify('customers', { add: [{ name: 'age', type: 'number' }], remove: ['email'] });
* await client.forms.remove('customers');
*/
export default class FormsManager {
constructor(httpClient) {
this._http = httpClient;
}
/**
* Creates a new form.
*
* @param input.name - Form name
* @param input.dataSpecs - Plain data fields (name, type, notNull?, unique?)
* @param input.dataRefs - Reference fields (name, cardinality?, path, totally?, unique?)
*/
async create({ name, dataSpecs = [], dataRefs = [] }) {
if (!name || typeof name !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
if (dataSpecs.length === 0 && dataRefs.length === 0) {
throw new FQLError('Form must have at least one field');
}
const specs = [
...dataSpecs.map(({ name, type, notNull = false, unique = false }) => {
if (!name || !type)
throw new FQLError('Each dataSpec requires name and type');
return { name, type: normalizeType(type), notNull, unique };
}),
...dataRefs.map(({ name, cardinality = [0, 1], path, totally = false, unique = false }) => {
if (!name || !path)
throw new FQLError('Each dataRef requires name and path');
return { name, type: 'reference', cardinality, path, totally, unique };
}),
];
const query = FQLQueryBuilder.buildCreateFormQuery({ name, specs });
return this._http.executeFQL(query);
}
/**
* Shows one or more forms, or all forms when called with no arguments.
*
* @param formNames - Optional list of form names to show
*/
async show(formNames = []) {
const query = FQLQueryBuilder.buildShowFormsQuery(formNames);
return this._http.executeFQL(query);
}
/**
* Removes one or more forms.
* ⚠️ Irreversible. Blocked if another form references this one.
*
* @param formNames - A name, an array of names, or omit to remove all forms.
*/
async remove(formNames) {
const names = Array.isArray(formNames)
? formNames
: formNames
? [formNames]
: [];
const query = FQLQueryBuilder.buildRemoveFormsQuery(names);
return this._http.executeFQL(query);
}
/**
* Modifies the structure of an existing form (add or remove fields).
*
* @param formName
* @param options.add - Fields to add (same shape as dataSpecs / dataRefs in create)
* @param options.remove - Field names to remove
*
* @example
* await client.forms.modify('customers', {
* add: [{ name: 'country', type: 'text' }],
* remove: ['email'],
* });
*/
async modify(formName, { add = [], remove = [] } = {}) {
if (!formName || typeof formName !== 'string') {
throw new FQLError('Form name is required and must be a string');
}
if (add.length === 0 && remove.length === 0) {
throw new FQLError('Provide at least one field to add or remove');
}
const normalizedAdd = add.map((spec) => {
if ('path' in spec) {
const ref = spec;
return { ...ref, type: 'reference' };
}
const def = spec;
return { ...def, type: normalizeType(def.type) };
});
const query = FQLQueryBuilder.buildModifyFormQuery(formName, {
add: normalizedAdd,
remove,
});
return this._http.executeFQL(query);
}
}
//# sourceMappingURL=FormsManager.js.map