@loomcore/api 0.2.46 → 0.2.47

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.
@@ -1,5 +1,6 @@
1
- import { setIdSchema } from '@loomcore/common/validation';
1
+ import { initializeTypeBox, setIdSchema, TypeboxObjectId } from '@loomcore/common/validation';
2
2
  import { Type } from '@sinclair/typebox';
3
+ initializeTypeBox();
3
4
  if (!process.env.TEST_DATABASE) {
4
5
  process.env.TEST_DATABASE = 'postgres';
5
6
  }
@@ -8,7 +9,7 @@ if (testDatabase === 'postgres') {
8
9
  setIdSchema(Type.Number({ title: 'ID', integer: true, minimum: 1 }));
9
10
  }
10
11
  else if (testDatabase === 'mongodb') {
11
- setIdSchema(Type.String({ title: 'ID', pattern: '^[0-9a-fA-F]{24}$' }));
12
+ setIdSchema(TypeboxObjectId({ title: 'ID' }));
12
13
  }
13
14
  else {
14
15
  throw new Error(`Invalid TEST_DATABASE value: ${testDatabase}. Must be 'postgres' or 'mongodb'`);
@@ -1 +1,6 @@
1
- export const PROPERTIES_THAT_ARE_NOT_OBJECT_IDS = ['_orgId'];
1
+ export const PROPERTIES_THAT_ARE_NOT_OBJECT_IDS = [
2
+ '_orgId',
3
+ '_createdBy',
4
+ '_updatedBy',
5
+ '_deletedBy',
6
+ ];
@@ -2,17 +2,42 @@ import { entityUtils } from '@loomcore/common/utils';
2
2
  import { ObjectId } from 'mongodb';
3
3
  import { PROPERTIES_THAT_ARE_NOT_OBJECT_IDS } from '../../models/constants.js';
4
4
  import { getPropertySchema } from '../../utils/get-property-schema.util.js';
5
+ function isExcludedFromObjectIdConversion(key) {
6
+ return PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key);
7
+ }
8
+ function shouldConvertEqToObjectId(key, propSchema, hasSchema) {
9
+ if (isExcludedFromObjectIdConversion(key)) {
10
+ return false;
11
+ }
12
+ if (key === '_id' || propSchema?.format === 'objectid') {
13
+ return true;
14
+ }
15
+ return !hasSchema && key.endsWith('Id');
16
+ }
17
+ function shouldConvertInToObjectIds(key, propSchema, hasSchema) {
18
+ if (isExcludedFromObjectIdConversion(key)) {
19
+ return false;
20
+ }
21
+ if (key === '_id' || propSchema?.format === 'objectid') {
22
+ return true;
23
+ }
24
+ const isObjectIdArray = propSchema?.type === 'array' && propSchema.items?.format === 'objectid';
25
+ if (isObjectIdArray) {
26
+ return true;
27
+ }
28
+ return !hasSchema && (key.endsWith('Id') || key.endsWith('Ids'));
29
+ }
5
30
  export function buildNoSqlMatch(queryOptions, modelSpec) {
6
31
  const filters = queryOptions.filters || {};
7
32
  const schema = modelSpec?.fullSchema;
33
+ const hasSchema = !!schema;
8
34
  let match = {};
9
35
  for (const [key, value] of Object.entries(filters)) {
10
36
  if (value) {
11
37
  const propSchema = schema ? getPropertySchema(key, schema) : undefined;
12
38
  if (value.eq !== undefined) {
13
- const isObjectIdField = propSchema?.format === 'objectid';
14
39
  const valueToCompare = value.eq;
15
- if ((key === '_id' || isObjectIdField || (!schema && key.endsWith('Id') && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)))
40
+ if (shouldConvertEqToObjectId(key, propSchema, hasSchema)
16
41
  && typeof valueToCompare === 'string' && entityUtils.isValidObjectId(valueToCompare)) {
17
42
  match[key] = new ObjectId(valueToCompare);
18
43
  }
@@ -24,8 +49,7 @@ export function buildNoSqlMatch(queryOptions, modelSpec) {
24
49
  }
25
50
  }
26
51
  if (value.in !== undefined && Array.isArray(value.in)) {
27
- const isObjectIdArray = propSchema?.type === 'array' && propSchema.items?.format === 'objectid';
28
- if (key === '_id' || isObjectIdArray || (!schema && (key.endsWith('Id') || key.endsWith('Ids')) && !PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key))) {
52
+ if (shouldConvertInToObjectIds(key, propSchema, hasSchema)) {
29
53
  const objectIds = value.in
30
54
  .filter(val => typeof val === 'string' && entityUtils.isValidObjectId(val))
31
55
  .map(val => new ObjectId(val));
@@ -26,10 +26,11 @@ export function convertStringsToObjectIds(entity, schema) {
26
26
  const items = subSchema.items;
27
27
  if (!items)
28
28
  return obj;
29
+ const propertyName = path[path.length - 1];
30
+ if (propertyName && PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(propertyName)) {
31
+ return obj;
32
+ }
29
33
  if (items.format === 'objectid') {
30
- if (path.length === 1 && PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(path[0])) {
31
- return obj;
32
- }
33
34
  return obj.map(item => {
34
35
  if (typeof item === 'string' && entityUtils.isValidObjectId(item)) {
35
36
  return new ObjectId(item);
@@ -51,10 +52,10 @@ export function convertStringsToObjectIds(entity, schema) {
51
52
  const typedPropSchema = propSchema;
52
53
  const fullPath = [...path, key];
53
54
  const value = result[key];
54
- const isObjectIdField = typedPropSchema.format === 'objectid';
55
- if (isObjectIdField && path.length === 0 && PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)) {
55
+ if (PROPERTIES_THAT_ARE_NOT_OBJECT_IDS.includes(key)) {
56
56
  continue;
57
57
  }
58
+ const isObjectIdField = typedPropSchema.format === 'objectid';
58
59
  if (isObjectIdField && typeof value === 'string' && entityUtils.isValidObjectId(value)) {
59
60
  result[key] = new ObjectId(value);
60
61
  }
@@ -4,10 +4,7 @@ export function createPublicSpec(spec) {
4
4
  if (config.debug?.showAuditFields) {
5
5
  return spec;
6
6
  }
7
- const publicSpec = entityUtils.getModelSpec(spec.schema, {
8
- isAuditable: spec.isAuditable,
7
+ return entityUtils.getModelSpec(spec.schema, {
9
8
  isEntity: spec.isEntity,
10
- addAuditableSchema: false,
11
9
  });
12
- return publicSpec;
13
10
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loomcore/api",
3
- "version": "0.2.46",
3
+ "version": "0.2.47",
4
4
  "private": false,
5
5
  "description": "Loom Core Api - An opinionated Node.js api using Typescript, Express, and MongoDb or PostgreSQL",
6
6
  "scripts": {
@@ -60,7 +60,7 @@
60
60
  "reflect-metadata": "^0.2.2"
61
61
  },
62
62
  "peerDependencies": {
63
- "@loomcore/common": "^0.0.84",
63
+ "@loomcore/common": "^0.0.86",
64
64
  "@sinclair/typebox": "0.34.33",
65
65
  "cookie-parser": "^1.4.6",
66
66
  "cors": "^2.8.5",