@loomcore/api 0.0.53 → 0.0.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -87,7 +87,7 @@ export class GenericApiService {
87
87
  }
88
88
  async get(userContext, queryOptions = { ...DefaultQueryOptions }) {
89
89
  const preparedOptions = this.prepareQueryOptions(userContext, queryOptions);
90
- const match = dbUtils.buildMongoMatchFromQueryOptions(preparedOptions);
90
+ const match = dbUtils.buildMongoMatchFromQueryOptions(preparedOptions, this.modelSpec);
91
91
  const additionalStages = this.getAdditionalPipelineStages();
92
92
  const results = [...additionalStages];
93
93
  if (preparedOptions.orderBy) {
@@ -1,11 +1,11 @@
1
1
  import { ObjectId } from 'mongodb';
2
2
  import { TSchema } from '@sinclair/typebox';
3
- import { IQueryOptions, Filter } from '@loomcore/common/models';
3
+ import { IQueryOptions, Filter, IModelSpec } from '@loomcore/common/models';
4
4
  export declare const PROPERTIES_THAT_ARE_NOT_OBJECT_IDS: string[];
5
5
  declare function convertObjectIdsToStrings<T>(entity: T, schema?: TSchema): T;
6
6
  declare function convertStringsToObjectIds(entity: any, schema: TSchema): any;
7
7
  declare function convertStringToObjectId(value: any): ObjectId | any;
8
- declare function buildMongoMatchFromQueryOptions(queryOptions: IQueryOptions): {
8
+ declare function buildMongoMatchFromQueryOptions(queryOptions: IQueryOptions, modelSpec?: IModelSpec): {
9
9
  $match: any;
10
10
  };
11
11
  declare function buildSQLWhereClauseFromQueryOptions(queryOptions: IQueryOptions, columnAliasMap: {
@@ -2,6 +2,21 @@ import { ObjectId } from 'mongodb';
2
2
  import _ from 'lodash';
3
3
  import { entityUtils } from '@loomcore/common/utils';
4
4
  import { stringUtils } from './string.utils.js';
5
+ function getPropertySchema(key, schema) {
6
+ if (!schema || typeof schema !== 'object')
7
+ return undefined;
8
+ if (schema.allOf && Array.isArray(schema.allOf)) {
9
+ for (const nestedSchema of schema.allOf) {
10
+ const propSchema = getPropertySchema(key, nestedSchema);
11
+ if (propSchema)
12
+ return propSchema;
13
+ }
14
+ }
15
+ if (schema.type === 'object' && schema.properties) {
16
+ return schema.properties[key];
17
+ }
18
+ return undefined;
19
+ }
5
20
  export const PROPERTIES_THAT_ARE_NOT_OBJECT_IDS = ['_orgId'];
6
21
  function convertObjectIdsToStrings(entity, schema) {
7
22
  if (!entity)
@@ -149,27 +164,30 @@ function convertStringToObjectId(value) {
149
164
  }
150
165
  return value;
151
166
  }
152
- function buildMongoMatchFromQueryOptions(queryOptions) {
167
+ function buildMongoMatchFromQueryOptions(queryOptions, modelSpec) {
153
168
  const filters = queryOptions.filters || {};
169
+ const schema = modelSpec?.fullSchema;
154
170
  let match = {};
155
171
  for (const [key, value] of Object.entries(filters)) {
156
172
  if (value) {
173
+ const propSchema = schema ? getPropertySchema(key, schema) : undefined;
157
174
  if (value.eq !== undefined) {
158
- if (typeof value.eq === 'string'
159
- && key.endsWith('Id')
160
- && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)
161
- && entityUtils.isValidObjectId(value.eq)) {
162
- match[key] = new ObjectId(value.eq);
175
+ const isObjectIdField = propSchema?.format === 'objectid';
176
+ const valueToCompare = value.eq;
177
+ if ((isObjectIdField || (!schema && key.endsWith('Id') && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)))
178
+ && typeof valueToCompare === 'string' && entityUtils.isValidObjectId(valueToCompare)) {
179
+ match[key] = new ObjectId(valueToCompare);
163
180
  }
164
- else if (typeof value.eq === 'string' && !isNaN(Number(value.eq))) {
165
- match[key] = Number(value.eq);
181
+ else if (typeof valueToCompare === 'string' && !isNaN(Number(valueToCompare))) {
182
+ match[key] = Number(valueToCompare);
166
183
  }
167
184
  else {
168
- match[key] = value.eq;
185
+ match[key] = valueToCompare;
169
186
  }
170
187
  }
171
188
  else if (value.in !== undefined && Array.isArray(value.in)) {
172
- if (key.endsWith('Id') && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)) {
189
+ const isObjectIdArray = propSchema?.type === 'array' && propSchema.items?.format === 'objectid';
190
+ if (isObjectIdArray || (!schema && (key.endsWith('Id') || key.endsWith('Ids')) && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key))) {
173
191
  const objectIds = value.in
174
192
  .filter(val => typeof val === 'string' && entityUtils.isValidObjectId(val))
175
193
  .map(val => new ObjectId(val));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "private": false,
5
5
  "description": "Loom Core Api - An opinionated Node.js api using Typescript, Express, and MongoDb",
6
6
  "scripts": {
@@ -44,8 +44,8 @@
44
44
  "node-mailjet": "^6.0.8"
45
45
  },
46
46
  "peerDependencies": {
47
- "@loomcore/common": "^0.0.13",
48
- "@sinclair/typebox": "^0.34.31",
47
+ "@loomcore/common": "^0.0.14",
48
+ "@sinclair/typebox": "0.34.33",
49
49
  "cookie-parser": "^1.4.6",
50
50
  "cors": "^2.8.5",
51
51
  "express": "^5.1.0",