@memberjunction/core 2.43.0 → 2.45.0

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/readme.md +308 -55
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/core",
3
- "version": "2.43.0",
3
+ "version": "2.45.0",
4
4
  "description": "MemberJunction: Core Library including Metadata, Application, Entity Retrieval and Manipulation, and Utilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -20,7 +20,7 @@
20
20
  "@types/debug": "^4.1.12"
21
21
  },
22
22
  "dependencies": {
23
- "@memberjunction/global": "2.43.0",
23
+ "@memberjunction/global": "2.45.0",
24
24
  "rxjs": "^7.8.1",
25
25
  "zod": "^3.23.8",
26
26
  "debug": "^4.4.0"
package/readme.md CHANGED
@@ -1,107 +1,360 @@
1
1
  # @memberjunction/core
2
2
 
3
- The `@memberjunction/core` library provides a comprehensive interface for accessing and managing metadata within MemberJunction, along with facilities for working with entities, applications, and various other aspects central to the MemberJunction ecosystem. This library primarily exports a `Metadata` class which acts as the gateway to many functionalities.
3
+ The `@memberjunction/core` library provides a comprehensive interface for accessing and managing metadata within MemberJunction, along with facilities for working with entities, applications, and various other aspects central to the MemberJunction ecosystem. This library serves as the foundation for all MemberJunction applications and provides essential functionality for data access, manipulation, and metadata management.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
8
  npm install @memberjunction/core
9
+ ```
9
10
 
10
- ```markdown
11
- ## Usage
11
+ ## Overview
12
12
 
13
- ### Importing the Library
13
+ The `@memberjunction/core` library is the central package in the MemberJunction ecosystem, providing:
14
14
 
15
- ```javascript
16
- import { Metadata } from '@memberjunction/core';
17
- ```
15
+ - **Metadata Management**: Complete access to MemberJunction metadata including entities, fields, relationships, permissions, and more
16
+ - **Entity Data Access**: Base classes and utilities for loading, saving, and manipulating entity records
17
+ - **View Execution**: Powerful view running capabilities for both stored and dynamic views
18
+ - **Query & Report Execution**: Tools for running queries and reports
19
+ - **Security & Authorization**: User authentication, role management, and permission handling
20
+ - **Transaction Management**: Support for grouped database transactions
21
+ - **Provider Architecture**: Flexible provider model supporting different execution environments
18
22
 
19
- ### Working with the Metadata Class
23
+ ## Core Components
20
24
 
21
- The `Metadata` class is a crucial part of this library, providing access to a wide array of metadata, instantiating derived classes of `BaseEntity` for record access and manipulation, and more.
25
+ ### Metadata Class
22
26
 
23
- #### Instantiating the Metadata Class
27
+ The `Metadata` class is the primary entry point for accessing MemberJunction metadata and instantiating entity objects.
24
28
 
25
- ```javascript
26
- const md = new Metadata();
27
- ```
29
+ ```typescript
30
+ import { Metadata } from '@memberjunction/core';
28
31
 
29
- #### Refreshing Cached Metadata
32
+ // Create metadata instance
33
+ const md = new Metadata();
30
34
 
31
- ```javascript
35
+ // Refresh cached metadata
32
36
  await md.Refresh();
33
- ```
34
-
35
- #### Getting Applications, Entities, and Other Info
36
37
 
37
- ```javascript
38
+ // Access various metadata collections
38
39
  const applications = md.Applications;
39
40
  const entities = md.Entities;
40
41
  const currentUser = md.CurrentUser;
41
- // ... and so on for other properties
42
+ const roles = md.Roles;
43
+ const authorizations = md.Authorizations;
42
44
  ```
43
45
 
44
- #### Helper Functions
46
+ #### Key Metadata Properties
45
47
 
46
- ```javascript
47
- // Get Entity ID from name
48
- const entityId = md.EntityIDFromName('EntityName');
48
+ - `Applications`: Array of all applications in the system
49
+ - `Entities`: Array of all entity definitions
50
+ - `CurrentUser`: Current authenticated user (when available)
51
+ - `Roles`: System roles
52
+ - `AuditLogTypes`: Available audit log types
53
+ - `Authorizations`: Authorization definitions
54
+ - `Libraries`: Registered libraries
55
+ - `Queries`: Query definitions
56
+ - `QueryFields`: Query field metadata
57
+ - `QueryCategories`: Query categorization
58
+ - `QueryPermissions`: Query-level permissions
59
+ - `VisibleExplorerNavigationItems`: Navigation items visible to current user
60
+ - `AllExplorerNavigationItems`: All navigation items (including hidden)
49
61
 
50
- // Get Entity name from ID
51
- const entityName = md.EntityNameFromID(1);
62
+ #### Helper Methods
52
63
 
53
- // ... and other helper functions as defined in the class
64
+ ```typescript
65
+ // Get entity ID from name
66
+ const entityId = md.EntityIDFromName('Users');
67
+
68
+ // Get entity name from ID
69
+ const entityName = md.EntityNameFromID('12345');
70
+
71
+ // Find entity by name (case-insensitive)
72
+ const userEntity = md.EntityByName('users');
73
+
74
+ // Find entity by ID
75
+ const entity = md.EntityByID('12345');
76
+
77
+ // Get entity object instance (IMPORTANT: Always use this pattern)
78
+ const user = await md.GetEntityObject<UserEntity>('Users');
54
79
  ```
55
80
 
56
- #### Working with Datasets
81
+ ### BaseEntity Class
82
+
83
+ The `BaseEntity` class is the foundation for all entity record manipulation in MemberJunction. All entity classes generated by the MemberJunction code generator extend this class.
57
84
 
58
- ```javascript
59
- // Example: Getting a dataset by name
60
- const dataset = await md.GetDatasetByName('DatasetName');
85
+ ```typescript
86
+ import { Metadata } from '@memberjunction/core';
87
+
88
+ // IMPORTANT: Never instantiate entity classes directly
89
+ // Always use Metadata.GetEntityObject() to ensure proper class registration
90
+
91
+ // ✅ Correct way to create entity instances
92
+ const md = new Metadata();
93
+ const user = await md.GetEntityObject<UserEntity>('Users');
94
+
95
+ // Load a record by ID
96
+ await user.Load(123);
97
+
98
+ // Create a new record
99
+ user.NewRecord();
100
+ user.FirstName = 'John';
101
+ user.LastName = 'Doe';
102
+ user.Email = 'john.doe@example.com';
103
+
104
+ // Save the record (creates new or updates existing)
105
+ const saveResult = await user.Save();
106
+ if (saveResult) {
107
+ console.log('User saved successfully:', user.ID);
108
+ } else {
109
+ console.log('Save failed:', user.LatestResult.Message);
110
+ }
111
+
112
+ // Delete a record
113
+ const deleteResult = await user.Delete();
61
114
  ```
62
115
 
63
- This is a brief overview of how to interact with the `Metadata` class. The methods and properties provided by the `Metadata` class serve as a bridge to access and manage data in a structured and coherent manner within the MemberJunction ecosystem.
116
+ #### Entity Fields
64
117
 
65
- ## RunView and RunViewParams
118
+ Each entity field is represented by an `EntityField` object that tracks value, dirty state, and metadata:
66
119
 
67
- The `@memberjunction/core` library also provides a mechanism for running either a stored or dynamic view through the `RunView` class. The parameters for running these views are specified through the `RunViewParams` type.
120
+ ```typescript
121
+ // Access field value
122
+ const firstName = user.Get('FirstName');
68
123
 
69
- ### Importing Necessary Classes and Types
124
+ // Set field value
125
+ user.Set('FirstName', 'Jane');
70
126
 
71
- ```javascript
72
- import { RunView, RunViewParams } from '@memberjunction/core';
127
+ // Check if field is dirty
128
+ const isDirty = user.Fields.find(f => f.Name === 'FirstName').Dirty;
129
+
130
+ // Access field metadata
131
+ const field = user.Fields.find(f => f.Name === 'Email');
132
+ console.log(field.IsUnique); // true/false
133
+ console.log(field.IsPrimaryKey); // true/false
134
+ console.log(field.ReadOnly); // true/false
73
135
  ```
74
136
 
75
- ### Using RunViewParams
137
+ #### Save Options
138
+
139
+ ```typescript
140
+ import { EntitySaveOptions } from '@memberjunction/core';
141
+
142
+ const options = new EntitySaveOptions();
143
+ options.IgnoreDirtyState = true; // Force save even if no changes detected
144
+ options.SkipEntityAIActions = true; // Skip AI-related actions
145
+ options.SkipEntityActions = true; // Skip entity actions
146
+ options.SkipOldValuesCheck = true; // Skip concurrency check (client-side only)
147
+
148
+ await entity.Save(options);
149
+ ```
150
+
151
+ ### RunView Class
152
+
153
+ The `RunView` class provides powerful view execution capabilities for both stored views and dynamic queries.
154
+
155
+ ```typescript
156
+ import { RunView, RunViewParams } from '@memberjunction/core';
76
157
 
77
- `RunViewParams` is a type that helps in specifying the parameters required to run a view. The fields in `RunViewParams` allow you to specify whether you want to run a stored or dynamic view, and provide additional filters, sorting, and other options. Here's an example of how you might create a `RunViewParams` object:
158
+ const rv = new RunView();
78
159
 
79
- ```javascript
160
+ // Run a stored view by name
80
161
  const params: RunViewParams = {
81
- ViewName: 'MyView',
82
- ExtraFilter: 'Age > 25',
83
- OrderBy: 'LastName ASC',
84
- Fields: ['FirstName', 'LastName'],
85
- UserSearchString: 'Smith'
86
- // ... other optional properties as needed
162
+ ViewName: 'Active Users',
163
+ ExtraFilter: 'CreatedDate > \'2024-01-01\'',
164
+ UserSearchString: 'john'
87
165
  };
166
+
167
+ const results = await rv.RunView(params);
168
+
169
+ // Run a dynamic view with entity objects returned
170
+ const dynamicResults = await rv.RunView<UserEntity>({
171
+ EntityName: 'Users',
172
+ ExtraFilter: 'IsActive = 1',
173
+ OrderBy: 'LastName ASC, FirstName ASC',
174
+ Fields: ['ID', 'FirstName', 'LastName', 'Email'],
175
+ ResultType: 'entity_object' // Returns actual entity objects
176
+ });
177
+
178
+ // Access typed results
179
+ const users = dynamicResults.Results; // Properly typed as UserEntity[]
88
180
  ```
89
181
 
90
- ### Using the RunView Class
182
+ #### RunView Parameters
183
+
184
+ - `ViewID`: ID of stored view to run
185
+ - `ViewName`: Name of stored view to run
186
+ - `ViewEntity`: Pre-loaded view entity object (optimal for performance)
187
+ - `EntityName`: Entity name for dynamic views
188
+ - `ExtraFilter`: Additional SQL WHERE clause
189
+ - `OrderBy`: SQL ORDER BY clause (overrides stored view sorting)
190
+ - `Fields`: Array of field names to return
191
+ - `UserSearchString`: User search term
192
+ - `ExcludeUserViewRunID`: Exclude records from specific prior run
193
+ - `ExcludeDataFromAllPriorViewRuns`: Exclude all previously returned records
194
+ - `SaveViewResults`: Store run results for future exclusion
195
+ - `IgnoreMaxRows`: Bypass entity MaxRows setting
196
+ - `MaxRows`: Maximum rows to return
197
+ - `StartRow`: Row offset for pagination
198
+ - `ResultType`: 'simple' (default) or 'entity_object'
199
+
200
+ ### RunQuery Class
201
+
202
+ Execute stored queries with parameters:
203
+
204
+ ```typescript
205
+ import { RunQuery, RunQueryParams } from '@memberjunction/core';
206
+
207
+ const rq = new RunQuery();
208
+
209
+ const params: RunQueryParams = {
210
+ QueryID: '12345',
211
+ Parameters: {
212
+ StartDate: '2024-01-01',
213
+ EndDate: '2024-12-31',
214
+ Status: 'Active'
215
+ }
216
+ };
217
+
218
+ const results = await rq.RunQuery(params);
219
+ ```
91
220
 
92
- The `RunView` class provides a method to run a view based on the provided parameters.
221
+ ### RunReport Class
93
222
 
94
- #### Instantiating the RunView Class
223
+ Execute reports with various output formats:
95
224
 
96
- ```javascript
97
- const rv = new RunView();
225
+ ```typescript
226
+ import { RunReport, RunReportParams } from '@memberjunction/core';
227
+
228
+ const rr = new RunReport();
229
+
230
+ const params: RunReportParams = {
231
+ ReportID: '12345',
232
+ Parameters: {
233
+ Year: 2024,
234
+ Department: 'Sales'
235
+ }
236
+ };
237
+
238
+ const results = await rr.RunReport(params);
239
+ ```
240
+
241
+ ### Transaction Management
242
+
243
+ Group multiple operations in a transaction:
244
+
245
+ ```typescript
246
+ import { TransactionGroupBase } from '@memberjunction/core';
247
+
248
+ // Transaction management is provider-specific
249
+ // Consult your provider documentation for implementation details
250
+ ```
251
+
252
+ ## Entity Relationships
253
+
254
+ MemberJunction automatically handles entity relationships through the metadata system:
255
+
256
+ ```typescript
257
+ // Load an entity with related data
258
+ const order = await md.GetEntityObject<OrderEntity>('Orders');
259
+ await order.Load(123, ['OrderDetails', 'Customer']);
260
+
261
+ // Access related entities
262
+ const orderDetails = order.OrderDetails; // Array of OrderDetailEntity
263
+ const customer = order.Customer; // CustomerEntity
264
+ ```
265
+
266
+ ## Security & Permissions
267
+
268
+ The library provides comprehensive security features:
269
+
270
+ ```typescript
271
+ const md = new Metadata();
272
+
273
+ // Check current user
274
+ const user = md.CurrentUser;
275
+ console.log('Current user:', user.Email);
276
+
277
+ // Check user roles
278
+ const isAdmin = user.RoleName.includes('Admin');
279
+
280
+ // Entity permissions
281
+ const entity = md.EntityByName('Orders');
282
+ const canCreate = entity.CanCreate;
283
+ const canUpdate = entity.CanUpdate;
284
+ const canDelete = entity.CanDelete;
98
285
  ```
99
286
 
100
- #### Running a View
287
+ ## Error Handling
288
+
289
+ All operations return detailed error information:
290
+
291
+ ```typescript
292
+ const entity = await md.GetEntityObject('Users');
293
+ const result = await entity.Save();
294
+
295
+ if (!result) {
296
+ // Access detailed error information
297
+ const error = entity.LatestResult;
298
+ console.error('Error:', error.Message);
299
+ console.error('Details:', error.Details);
300
+
301
+ // Check validation errors
302
+ if (error.ValidationErrors && error.ValidationErrors.length > 0) {
303
+ error.ValidationErrors.forEach(ve => {
304
+ console.error(`Field ${ve.FieldName}: ${ve.Message}`);
305
+ });
306
+ }
307
+ }
308
+ ```
101
309
 
102
- ```javascript
103
- const result = await rv.RunView(params);
310
+ ## Provider Architecture
311
+
312
+ MemberJunction uses a provider model to support different execution environments:
313
+
314
+ ```typescript
315
+ import { SetProvider } from '@memberjunction/core';
316
+
317
+ // Provider setup is typically handled by your application initialization
318
+ // The provider determines how data is accessed (direct database, API, etc.)
319
+ SetProvider(myProvider);
104
320
  ```
105
321
 
106
- In this example, `params` is an object of type `RunViewParams` which contains the information necessary to run the view. The `RunView` method will return a `Promise<RunViewResult>` which will contain the result of running the view.
322
+ ## Best Practices
323
+
324
+ 1. **Always use Metadata.GetEntityObject()** to create entity instances - never use `new`
325
+ 2. **Use generic types** with RunView for type-safe results
326
+ 3. **Handle errors properly** - check return values and LatestResult
327
+ 4. **Use transactions** for related operations that must succeed/fail together
328
+ 5. **Leverage metadata** for dynamic UI generation and validation
329
+ 6. **Respect permissions** - always check CanCreate/Update/Delete before operations
330
+ 7. **Use ExtraFilter** carefully - ensure SQL injection protection
331
+ 8. **Cache metadata instances** when possible to improve performance
332
+
333
+ ## Integration with Other MemberJunction Packages
334
+
335
+ - **@memberjunction/global**: Global utilities and constants
336
+ - **@memberjunction/server**: Server-side provider implementation
337
+ - **@memberjunction/client**: Client-side provider implementation
338
+ - **@memberjunction/angular**: Angular-specific components and services
339
+ - **@memberjunction/react**: React-specific components and hooks
340
+ - **@memberjunction/ai**: AI integration features
341
+ - **@memberjunction/communication**: Communication and messaging features
342
+
343
+ ## Dependencies
344
+
345
+ - **@memberjunction/global**: Core global utilities
346
+ - **rxjs**: Reactive programming support
347
+ - **zod**: Schema validation
348
+ - **debug**: Debug logging
349
+
350
+ ## TypeScript Support
351
+
352
+ This library is written in TypeScript and provides full type definitions. All generated entity classes include proper typing for IntelliSense support.
353
+
354
+ ## License
355
+
356
+ ISC License - see LICENSE file for details
357
+
358
+ ## Support
107
359
 
360
+ For support, documentation, and examples, visit [MemberJunction.com](https://www.memberjunction.com)