@feedmepos/custom-attributes

0.0.1-rc.3 • Public • Published

@feedmepos/custom-attributes

Package Features

The @feedmepos/custom-attributes package provides a set of tools to manage and filter custom attributes for entities such as restaurants. The main features include:

  1. Filter Builder: FmCustomAttributeFilter A vue component that enables users to build complex filter queries based on custom attributes.
  2. Rule Validation Function: validateRule A function that evaluates MongoDB-style queries against custom attribute data to determine if they match the specified rules.

Rule Validation Function

The mongoQuery function is used to evaluate a set of rules against custom attribute data. It takes two parameters: the data to be evaluated and the rule to be applied. The function returns a boolean indicating whether the data matches the rule.

Development

pnpm install
pnpm dev

Release Package

Typescript Package

  • Create a new release and tag on GitHub (custom-attributes-v* Eg. custom-attributes-v0.0.0-alpha)
  • The package will be published to npm and github registry by @feedmepos/custom-attributes-action

Dart Package


Add to existing project

Install packages

pnpm install @feedmepos/custom-attributes

Add style.css to your App.vue

import '@feedmepos/custom-attributes/style.css';

How to use the components

import { FmCustomAttributeFilter } from '@feedmepos/custom-attributes';

<FmCustomAttributeFilter
  :attributes="[
    { key: 'name', type: 'string', entity: 'restaurant' },
    { key: 'region', type: 'string', entity: 'restaurant' },
    { key: 'staffCount', type: 'number', entity: 'restaurant' },
    { key: 'memberCount', type: 'number', entity: 'restaurant' },
  ]"
  :model-value="filter"
  @update:model-value="(v) => (filter = v)"
/>

Filter Data

/**
 * filter = { "logic": "AND", "rules": [ { "logic": "AND", "rules": [ { "property": "name", "operator": "$eq", "value": "123" } ] }, { "logic": "AND", "rules": [ { "property": "region", "operator": "$eq", "value": "123" } ] }, { "logic": "AND", "rules": [ { "property": "name", "operator": "$eq", "value": "123123" }, { "property": "staffCount", "operator": "$eq", "value": 123 } ] } ] }
 *
 * values: FdoCustomAttribute = {
 *   name: '123',
 *   region: '123',
 *   staffCount: 123,
 *   memberCount: 123123
 * }
 */
const testResult = validateRule(values, filter);

const result = restaurants.filter((r) => validateRule(r.customAttribute, filter));

Screenshot

Multiple group

alt text

One group filter

alt text


Type-Safe MongoQuery

This package provides utilities to convert between FDO rules and MongoDB queries, and to validate data against MongoDB-style queries.

Operators

The following MongoDB operators are supported:

  • $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin, $regex
  • $between (for FDO compatibility, mapped to $gte and $lte)

Supported Operators by Type

String fields Supported: $eq, $ne, $in,$nin, $regex, $gt, $gte, $lt, $lte

Number fields Supported: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin

Boolean fields Supported: $eq, $ne, $in, $nin

Date fields Supported: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin

Array fields Supported:$in, $nin


Usage

1. FdoRuleToMongoQueryBuilder

Converts an FDO rule object to a MongoDB query object.

import { FdoRuleToMongoQueryBuilder } from 'feedmepos/custom-attributes';

const fdoRule = {
  property: 'age',
  operator: '$gt',
  value: 18,
  type: 'number'
};

const mongoQuery = FdoRuleToMongoQueryBuilder.build(fdoRule);
// mongoQuery: { age: { $gt: 18 } }

2. MongoQueryBuilderToFdoRule

Converts a MongoDB query object back to an FDO rule object.

import { MongoQueryBuilderToFdoRule } from '@feedmepos/custom-attributes';

const mongoQuery = { age: { $gt: 18 } };
const fdoRule = MongoQueryBuilderToFdoRule.build(mongoQuery);
// fdoRule: { property: 'age', operator: '$gt', value: 18, type: 'number'}

3. validateMongoQuery

Validates a data object against a MongoDB-style query.

import { validateMongoQuery, MongoQuery } from 'feedmepos/custom-attributes';

const user: User = {
  name: 'John',
  age: 25,
  active: true,
  tags: ['user', 'admin'],
  createdAt: new Date('2024-01-01'),
  profile: { email: 'john@example.com', score: 85 }
};

const query: MongoQuery<User> = {
  age: { $gt: 18 },
  active: { $eq: true },
  tags: { $in: ['admin'] },
  profile: { score: { $gte: 80 } }
};

const isValid = validateMongoQuery(user, query); // true

Example Usage of Type-Safe MongoQuery

import { MongoQuery, validateMongoQuery } from '@feedmepos/custom-attributes';

interface Profile {
  email: string;
  score: number;
}
interface User {
  name: string;
  age: number;
  active: boolean;
  tags: string[];
  createdAt: string | Date;
  profile: Profile;
}

const query: MongoQuery<User> = {
  name: { $eq: 'Alice' },
  age: { $gte: 18 },
  profile: { score: { $gt: 80 } },
  tags: { $in: ['admin'] },
  createdAt: { $gte: '2024-01-01' }
};

validateMongoQuery(user, query);

// OR

validateMongoQuery(user, {
  name: { $eq: 'Alice' },
  age: { $gte: 18 },
  profile: { score: { $gt: 80 } },
  tags: { $in: ['admin'] },
  createdAt: { $gte: '2024-01-01' }
});

TypeScript will show errors for:

  • Invalid keys (e.g., 'profile.score' instead of profile: { score: ... })
  • Invalid operators (e.g., { age: { $regex: 'foo' } })
  • Wrong value types (e.g., { age: { $eq: 'Alice' } })
// example of invalid query
const invalidQuery: MongoQuery<User> = {
  name: { $eq: 123, $regex: 456 }, // $eq expects string, $regex expects string
  age: { $regex: 'foo', $gt: 'twenty' }, // $regex not allowed for number, $gt expects number
  active: { $gte: true }, // $gte not allowed for boolean
  tags: { $eq: 'admin', $nin: 'user' }, // $eq not allowed for array, $nin expects string[]
  createdAt: { $regex: 2024, $gt: false }, // $regex expects string, $gt expects string or Date
  profile: {
    score: { $regex: 'foo' }, // $regex not allowed for number
    notAProfileField: { $eq: 1 } // 'notAProfileField' does not exist in Profile
  },
  notAUserField: { $eq: 1 }, // 'notAUserField' does not exist in User
  $and: [
    { name: { $eq: 'Alice' } },
    { 'profile.email': { $eq: 'foo@bar.com' } } // dot notation not allowed
  ]
};

Notes

  • Always use object notation for nested fields (not dot notation).
  • Annotate your query as MongoQuery<YourType>for best type safety.
  • If you use inline objects, use the generic on validateMongoQuery to enforce type checking.

Readme

Keywords

none

Package Sidebar

Install

npm i @feedmepos/custom-attributes

Weekly Downloads

2

Version

0.0.1-rc.3

License

none

Unpacked Size

361 kB

Total Files

34

Last publish

Collaborators

  • victor.chai
  • lokingwei