Loosely based on the API of Sequelize, intended to connect to FileMaker Connect.
import Model from 'filemaker-connect-orm';
import FilemakerConnect from 'filemaker-connect';
const filemaker = new FilemakerConnect(/* options */)
class User extends Model {
static layout = 'fm_user';
static attributes = {
id: 'ID',
firstName: 'NAME_FIRST',
lastName: 'NAME_LAST',
};
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
}
class Team extends Model {
static attributes = {
id: 'ID',
name: 'NAME'
}
}
class Project extends Model {
static attributes = {
id: 'ID',
name: 'NAME'
}
}
User.init(filemaker);
Team.init(filemaker);
Project.init(filemaker);
// implies that there are fields called 'TEAM__USER::ID', 'TEAM__USER::NAME' on the layout 'fm_user'
User.belongsTo(Team, { prefix: 'TEAM__USER' });
// implies that there is a portal named 'user_project' on the layout 'fm_user'
User.hasMany(Project, { portal: 'user_project', prefix: 'PROJECT__USER', as: 'hobbies' })
const users = User.findAll({ where: { team: { name: 'Jets' } }, order: [['name', 'asc']] });
const user = User.findByPk('USER-123');
user.fullName // Johnny Appleseed
user.team.name // 'Jets'
user.hobbies // [Project{ id: 'Project-1', name: 'Painting' }, Project{ id: 'Project-2', name: 'Coding' }]init(filemakerConnection)- initialized model. Required before it can be usedfilemakerConnection- an instance ofFileMakerConnect
hasMany(model, { portal, prefix, as })- Describes how to format records found in a portal on the layoutmodel- related model classportal- name of the object on the layoutprefix- the table occurance name from which the portal records are shownas- the default accessor for the related records property is plural class name, but you can specify a different accessor
belongsTo(model, { prefix, as })- Describes how to format related fields found on the layoutmodel- related model classprefix- the table occurance name of the fieldas- the default accessor for the field is the camelCase class name, but you can specify a different accessor
findAll({ limit, offset, order, where, timeout })limit- number to limit resultsoffset- the record to start the return. i.e.offset: 2omits the first record. Used for paginationorder- set of arrays to specify sort order. Can include related fields on the layout.[[{ project: 'name' }, 'asc'], ['firstName', 'desc']]where: see query docs belowtimeout: request timeout in ms
findByPk(id, { timeout })- finds the first record by theidfield. Note that this does not userecordIdcreate(data, { timeout })data- object of values to update. Related fields are updateable. HasMany related records must have arecordId
createAndReturn(data, { timeout })- same as create, but does a find request afterward and returns the updated record.update(recordId, data, { timeout })- updates record byrecordIdrecordId- primary key used by FileMaker, as accessible in FileMaker by Get(RecordId)data- object of values to update. Note related fields are not updateable here
updateAndReturn(recordId, data, { timeout })- same as update, but does a find request afterward and returns the updated record.destroy(recordId, { timeout })- deletes record byrecordId
update(data, { timeout })data- object of values to update. Note related fields are not updateable here
destroy({ timeout })save({ timeout })- can be used after setting attributes directly, likerecord.name = 'Titans'; await record.save()
The object passed to the where and whereNot paramater of findAll specifies the find criteria
- Arrays are used to represent
ORclauses - Object Literals are used to represent
ANDclauses - Related fields can be specified by nested objects:
{ team: { name: 'Jets' } } - Query Operators can be used for operations other than
=like(string)between(lowerBound, upperBound)