
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@mj-biz-apps/common-entities
Advanced tools
This package contains automatically generated TypeScript entity classes that provide strongly-typed representations of database tables in the MemberJunction ecosystem.
mj_generatedentities contains entity subclasses that are generated and maintained by MemberJunction's code generation system. These entities map directly to database tables and views, providing type-safe access to your data while abstracting away the complexity of data access.
Key features:
LoadGeneratedEntities() function to ensure proper bundlingThis package is a private package used internally within MemberJunction applications:
# Within the MemberJunction monorepo workspace
npm install
Note: This package is marked as private ("private": true) in package.json and is not published to npm.
@memberjunction/core (v2.43.0): Core MemberJunction functionality including BaseEntity@memberjunction/global (v2.43.0): Global utilities and constantszod (v3.23.8): Schema validation librarymj_generatedentities/
├── src/
│ ├── index.ts # Main export file
│ ├── generated/
│ │ └── entity_subclasses.ts # Auto-generated entity classes
│ └── demo/
│ └── demoContactEntitySubclass.ts # Example of extending entities
├── dist/ # Compiled JavaScript output
├── package.json
├── tsconfig.json
└── README.md
Never directly instantiate entity classes. Always use the Metadata system to ensure proper class registration:
import { Metadata } from '@memberjunction/core';
// ❌ Wrong - bypasses MJ class system
const entity = new UserEntity();
// ✅ Correct - uses MJ metadata system
const md = new Metadata();
const entity = await md.GetEntityObject<UserEntity>('Users');
To ensure generated entities are included in webpack builds (avoiding tree-shaking issues):
import { LoadGeneratedEntities } from 'mj_generatedentities';
// Call this function early in your application initialization
LoadGeneratedEntities();
import { Metadata, RunView } from '@memberjunction/core';
// Load a single entity by ID
async function getUserById(userId: string): Promise<UserEntity | null> {
const md = new Metadata();
const user = await md.GetEntityObject<UserEntity>('Users');
if (await user.Load(userId)) {
return user;
}
return null;
}
// Load multiple entities with RunView
async function getActiveUsers(): Promise<UserEntity[]> {
const rv = new RunView();
const result = await rv.RunView<UserEntity>({
EntityName: 'Users',
ExtraFilter: `IsActive = 1`,
OrderBy: 'CreatedAt DESC',
ResultType: 'entity_object' // Returns entity objects, not raw data
});
return result.Results;
}
// Update an entity
async function updateUser(userId: string, updates: Partial<UserEntity>): Promise<boolean> {
const md = new Metadata();
const user = await md.GetEntityObject<UserEntity>('Users');
if (await user.Load(userId)) {
// Apply updates
Object.assign(user, updates);
// Save changes
const result = await user.Save();
return result.Success;
}
return false;
}
import { Metadata, RunView } from '@memberjunction/core';
async function getUserWithRoles(userId: string) {
const md = new Metadata();
const user = await md.GetEntityObject<UserEntity>('Users');
if (await user.Load(userId)) {
// Load related entities using RunView
const rv = new RunView();
const rolesResult = await rv.RunView<RoleEntity>({
EntityName: 'User Roles',
ExtraFilter: `UserID = '${userId}'`,
ResultType: 'entity_object'
});
return {
user,
roles: rolesResult.Results
};
}
return null;
}
You can extend the generated entities with custom business logic. Use the @RegisterClass decorator to ensure proper registration:
import { RegisterClass } from '@memberjunction/global';
import { BaseEntity } from '@memberjunction/core';
// Example from demo/demoContactEntitySubclass.ts
@RegisterClass(BaseEntity, 'Contacts', 1)
export class ContactEntity extends ContactBaseEntity {
// Override property getters/setters (must override both)
get FirstName(): string {
console.log("Getting FirstName from subclass");
return super.FirstName;
}
set FirstName(value: string) {
super.FirstName = value;
console.log("Setting FirstName from subclass");
}
// Add custom methods
async getFullName(): Promise<string> {
return `${this.FirstName} ${this.LastName}`;
}
// Add custom validation
override async Validate(): Promise<ValidationResult> {
const result = await super.Validate();
if (this.Email && !this.Email.includes('@')) {
result.Success = false;
result.Errors.push({
Source: 'Email',
Message: 'Email must contain @ symbol',
Type: ValidationErrorType.Failure
});
}
return result;
}
}
@RegisterClass decorator to register your subclass with MemberJunction@RegisterClass allows for entity versioningGenerated entities use Zod for schema validation:
import { z } from 'zod';
// Each generated entity includes a Zod schema
const userSchema = z.object({
ID: z.string(),
FirstName: z.string(),
LastName: z.string(),
Email: z.string().email(),
IsActive: z.boolean(),
CreatedAt: z.date(),
UpdatedAt: z.date()
});
// Validate data before creating entities
async function createUserFromData(userData: unknown) {
const result = userSchema.safeParse(userData);
if (result.success) {
const md = new Metadata();
const user = await md.GetEntityObject<UserEntity>('Users');
await user.LoadFromData(result.data);
const saveResult = await user.Save();
return saveResult.Success;
} else {
console.error('Validation errors:', result.error.format());
return false;
}
}
All generated entities inherit from BaseEntity and provide these key methods:
| Method | Description |
|---|---|
Load(id: CompositeKey) | Loads an entity by its primary key |
LoadFromData(data: any) | Populates entity from a data object |
Save(options?: EntitySaveOptions) | Saves changes to the database |
Delete() | Deletes the entity from the database |
Validate() | Validates the entity, returns ValidationResult |
GetFieldValue(fieldName: string) | Gets the value of a specific field |
SetFieldValue(fieldName: string, value: any) | Sets the value of a specific field |
TransactionMode | Property to control transaction behavior |
# Build the package
npm run build
# Development mode with auto-reload
npm run start
# Run tests (not implemented yet)
npm test
This package is automatically maintained by MemberJunction's code generation system. The entity_subclasses.ts file is generated based on your database schema.
Important: Do not manually edit files in the generated/ directory as they will be overwritten during the next code generation cycle.
To regenerate entities:
*.d.ts) in the dist folderloadModule export in entity_subclasses.ts ensures the module is valid even when emptyBusiness Source License 1.1 — see LICENSE for details.
FAQs
MJ BizApps Common Entity Subclasses
We found that @mj-biz-apps/common-entities demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 10 open source maintainers collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.