Skip to content

Commit

Permalink
feat: Update data property type to handle both JSON objects and strings
Browse files Browse the repository at this point in the history
  • Loading branch information
rahul-rocket committed Sep 25, 2024
1 parent db4d838 commit ae85f5a
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
5 changes: 4 additions & 1 deletion packages/contracts/src/activity-log.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ActorTypeEnum, IBasePerTenantAndOrganizationEntityModel, ID } from './base-entity.model';
import { IUser } from './user.model';

// Define a type for JSON data
export type JsonData = Record<string, any> | string;

/**
* Interface representing an activity log entry.
*/
Expand All @@ -17,7 +20,7 @@ export interface IActivityLog extends IBasePerTenantAndOrganizationEntityModel {
updatedEntities?: IActivityLogUpdatedValues[]; // Stores updated IDs, or other values for related entities. Eg : {members: ['member_1_ID', 'member_2_ID']},
creator?: IUser;
creatorId?: ID;
data?: Record<string, any>;
data?: JsonData;
}

export interface IActivityLogUpdatedValues {
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/activity-log/activity-log.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@ import { EntityRepositoryType } from '@mikro-orm/core';
import { JoinColumn, RelationId } from 'typeorm';
import { IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator';
import { isMySQL, isPostgres } from '@gauzy/config';
import { ActivityLogEntityEnum, ActionTypeEnum, ActorTypeEnum, IActivityLog, ID, IUser } from '@gauzy/contracts';
import {
ActivityLogEntityEnum,
ActionTypeEnum,
ActorTypeEnum,
IActivityLog,
ID,
IUser,
JsonData
} from '@gauzy/contracts';
import { TenantOrganizationBaseEntity, User } from '../core/entities/internal';
import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from '../core/decorators/entity';
import { MikroOrmActivityLogRepository } from './repository/mikro-orm-activity-log.repository';
Expand Down Expand Up @@ -80,7 +88,7 @@ export class ActivityLog extends TenantOrganizationBaseEntity implements IActivi
@IsOptional()
@IsArray()
@MultiORMColumn({ type: isPostgres() ? 'jsonb' : isMySQL() ? 'json' : 'text', nullable: true })
data?: Record<string, any>;
data?: JsonData;

/*
|--------------------------------------------------------------------------
Expand Down
29 changes: 26 additions & 3 deletions packages/core/src/activity-log/activity-log.subscriber.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EventSubscriber } from 'typeorm';
import { isJsObject } from '@gauzy/common';
import { isBetterSqlite3, isSqlite } from '@gauzy/config';
import { BaseEntityEventSubscriber } from '../core/entities/subscribers/base-entity-event.subscriber';
import { MultiOrmEntityManager } from '../core/entities/subscribers/entity-event-subscriber.types';
import { ActivityLog } from './activity-log.entity';

@EventSubscriber()
Expand All @@ -24,12 +24,35 @@ export class ActivityLogSubscriber extends BaseEntityEventSubscriber<ActivityLog
async beforeEntityCreate(entity: ActivityLog): Promise<void> {
try {
// Check if the database is SQLite and the entity's metaData is a JavaScript object
if ((isSqlite() || isBetterSqlite3()) && isJsObject(entity.data)) {
if (isSqlite() || isBetterSqlite3()) {
// ToDo: If need convert data to JSON before save
entity.data = JSON.stringify(entity.data);
}
} catch (error) {
// In case of error during JSON serialization, reset metaData to an empty object
console.error('ActivityLogSubscriber: Error during the beforeEntityCreate process:', error);
entity.data = JSON.stringify({});
}
}

/**
* Handles the parsing of JSON data after the ActivityLog entity is loaded from the database.
* This function ensures that if the database is SQLite, the `data` field, stored as a JSON string,
* is parsed back into a JavaScript object.
*
* @param {ActivityLog} entity - The ActivityLog entity that has been loaded from the database.
* @param {MultiOrmEntityManager} [em] - The optional EntityManager instance, if provided.
* @returns {Promise<void>} A promise that resolves once the after-load processing is complete.
*/
async afterEntityLoad(entity: ActivityLog, em?: MultiOrmEntityManager): Promise<void> {
try {
// Check if the database is SQLite and if `data` is a non-null string
if ((isSqlite() || isBetterSqlite3()) && entity.data && typeof entity.data === 'string') {
entity.data = JSON.parse(entity.data);
}
} catch (error) {
// Log the error and reset the data to an empty object if JSON parsing fails
console.error('Error parsing JSON data in afterEntityLoad:', error);
entity.data = {};
}
}
}

0 comments on commit ae85f5a

Please sign in to comment.