@memberjunction/server 2.43.0 → 2.44.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.
package/README.md CHANGED
@@ -1,8 +1,20 @@
1
1
  # @memberjunction/server
2
2
 
3
- The `@memberjunction/server` library provides a simple way to run the MemberJunction API server. It includes all the functions required to start up the GraphQL server, manage authentication, and connect to the common data store.
3
+ The `@memberjunction/server` library provides a comprehensive API server for MemberJunction, featuring both GraphQL and REST APIs. It includes all the functions required to start up the server, manage authentication, handle database connections, and provide a robust interface for accessing and managing metadata within MemberJunction.
4
4
 
5
- The server 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.
5
+ ## Key Features
6
+
7
+ - **Dual API Support**: Both GraphQL and REST APIs with consistent authentication
8
+ - **Multi-Database Support**: Read-write and optional read-only database connections
9
+ - **Advanced Authentication**: Support for MSAL (Azure AD) and Auth0 authentication providers
10
+ - **Transaction Management**: Automatic transaction wrapper for GraphQL mutations
11
+ - **Type-Safe Resolvers**: Full TypeScript support with type-graphql integration
12
+ - **Entity Management**: Comprehensive CRUD operations with change tracking
13
+ - **Real-time Support**: WebSocket subscriptions for GraphQL
14
+ - **Compression**: Built-in response compression for better performance
15
+ - **Extensible Architecture**: Support for custom resolvers and entity subclasses
16
+ - **AI Integration**: Built-in support for AI operations and learning cycle scheduling
17
+ - **Security Features**: Entity-level and schema-level access control for REST API
6
18
 
7
19
  ## Installation
8
20
 
@@ -10,6 +22,15 @@ The server provides a comprehensive interface for accessing and managing metadat
10
22
  npm install @memberjunction/server
11
23
  ```
12
24
 
25
+ ## Dependencies
26
+
27
+ This package depends on several core MemberJunction packages:
28
+ - `@memberjunction/core`: Core functionality and metadata management
29
+ - `@memberjunction/sqlserver-dataprovider`: SQL Server data provider
30
+ - `@memberjunction/graphql-dataprovider`: GraphQL data provider
31
+ - `@memberjunction/ai`: AI engine integration
32
+ - Various other MJ packages for specific functionality
33
+
13
34
  ## Configuration
14
35
 
15
36
  The server uses configuration from its environment
@@ -32,6 +53,8 @@ The server uses configuration from its environment
32
53
  | AUTH0_CLIENT_SECRET | The Auth0 Client secret |
33
54
  | MJ_CORE_SCHEMA | The core schema to use for the data provider |
34
55
  | CONFIG_FILE | An absolute path to the config file json |
56
+ | DB_READ_ONLY_USERNAME | Username for read-only database connection (optional) |
57
+ | DB_READ_ONLY_PASSWORD | Password for read-only database connection (optional) |
35
58
 
36
59
  ### REST API
37
60
 
@@ -50,6 +73,8 @@ The REST API supports:
50
73
 
51
74
  ## Usage
52
75
 
76
+ ### Basic Server Setup
77
+
53
78
  Import the `serve` function from the package and run it as part of the server's main function. The function accepts an array of absolute paths to the resolver code.
54
79
 
55
80
  ```ts
@@ -67,6 +92,46 @@ const resolverPaths = [
67
92
  serve(resolverPaths.map(localPath));
68
93
  ```
69
94
 
95
+ ### Advanced Server Options
96
+
97
+ The `serve` function accepts an optional `MJServerOptions` object:
98
+
99
+ ```typescript
100
+ import { serve, MJServerOptions } from '@memberjunction/server';
101
+
102
+ const options: MJServerOptions = {
103
+ onBeforeServe: async () => {
104
+ // Custom initialization logic
105
+ console.log('Server is about to start...');
106
+ },
107
+ restApiOptions: {
108
+ enabled: true,
109
+ includeEntities: ['User*', 'Entity*'],
110
+ excludeEntities: ['Password', 'APIKey*'],
111
+ includeSchemas: ['public'],
112
+ excludeSchemas: ['internal']
113
+ }
114
+ };
115
+
116
+ serve(resolverPaths.map(localPath), createApp(), options);
117
+ ```
118
+
119
+ ### Transaction Management
120
+
121
+ The server automatically wraps GraphQL mutations in database transactions. This ensures data consistency when multiple operations are performed:
122
+
123
+ ```typescript
124
+ mutation {
125
+ CreateUser(input: { FirstName: "John", LastName: "Doe" }) {
126
+ ID
127
+ }
128
+ CreateUserRole(input: { UserID: "...", RoleID: "..." }) {
129
+ ID
130
+ }
131
+ }
132
+ // Both operations will be committed together or rolled back on error
133
+ ```
134
+
70
135
  ### Custom New User Behavior
71
136
 
72
137
  The behavior to handle new users can be customized by subclassing the `NewUserBase` class. The subclass can pre-process, post-process or entirely override the base class behavior as needed. Import the class before calling `serve` to ensure the class is registered.
@@ -153,3 +218,164 @@ export class ExampleNewUserSubClass extends NewUserBase {
153
218
  }
154
219
  }
155
220
  ```
221
+
222
+ ## API Documentation
223
+
224
+ ### Core Exports
225
+
226
+ The package exports numerous utilities and types:
227
+
228
+ #### Server Functions
229
+ - `serve(resolverPaths: string[], app?: Express, options?: MJServerOptions)`: Main server initialization
230
+ - `createApp()`: Creates an Express application instance
231
+
232
+ #### Authentication
233
+ - `NewUserBase`: Base class for custom new user handling
234
+ - `TokenExpiredError`: Token expiration error class
235
+ - `getSystemUser(dataSource?: DataSource)`: Get system user for operations
236
+
237
+ #### Resolvers and Base Classes
238
+ - `ResolverBase`: Base class for custom resolvers
239
+ - `RunViewResolver`: Base resolver for view operations
240
+ - `PushStatusResolver`: Status update resolver base
241
+
242
+ #### Type Definitions
243
+ - `AppContext`: GraphQL context type
244
+ - `DataSourceInfo`: Database connection information
245
+ - `KeyValuePairInput`: Generic key-value input type
246
+ - `DeleteOptionsInput`: Delete operation options
247
+
248
+ #### Utility Functions
249
+ - `GetReadOnlyDataSource(dataSources: DataSourceInfo[])`: Get read-only data source
250
+ - `GetReadWriteDataSource(dataSources: DataSourceInfo[])`: Get read-write data source
251
+
252
+ ### Entity Subclasses
253
+
254
+ The server includes specialized entity subclasses:
255
+ - `UserViewEntityServer`: Server-side user view handling
256
+ - `EntityPermissionsEntityServer`: Entity permission management
257
+ - `DuplicateRunEntityServer`: Duplicate detection operations
258
+ - `ReportEntityServer`: Report generation and management
259
+
260
+ ## AI Integration
261
+
262
+ The server includes built-in AI capabilities:
263
+
264
+ ### Learning Cycle Scheduler
265
+
266
+ The server can automatically run AI learning cycles:
267
+
268
+ ```typescript
269
+ import { LearningCycleScheduler } from '@memberjunction/server/scheduler';
270
+
271
+ // In your server initialization
272
+ const scheduler = LearningCycleScheduler.Instance;
273
+ scheduler.setDataSources(dataSources);
274
+ scheduler.start(60); // Run every 60 minutes
275
+ ```
276
+
277
+ ### AI Resolvers
278
+
279
+ - `RunAIPromptResolver`: Execute AI prompts
280
+ - `AskSkipResolver`: Handle Skip AI queries
281
+
282
+ ## Security Configuration
283
+
284
+ ### Authentication Providers
285
+
286
+ The server supports multiple authentication providers:
287
+
288
+ 1. **Azure AD (MSAL)**:
289
+ - Set `TENANT_ID` and `WEB_CLIENT_ID` environment variables
290
+ - Supports Microsoft identity platform
291
+
292
+ 2. **Auth0**:
293
+ - Set `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID`, and `AUTH0_CLIENT_SECRET`
294
+ - Supports Auth0 authentication
295
+
296
+ ### API Key Authentication
297
+
298
+ The server also supports API key authentication via the `x-mj-api-key` header.
299
+
300
+ ### Access Control
301
+
302
+ For REST API access control, see the comprehensive documentation in [REST_API.md](./REST_API.md).
303
+
304
+ ## Performance Optimization
305
+
306
+ ### Compression
307
+
308
+ The server includes built-in compression middleware:
309
+ - Responses larger than 1KB are compressed
310
+ - Binary files are excluded from compression
311
+ - Uses compression level 6 for optimal balance
312
+
313
+ ### Connection Pooling
314
+
315
+ Database connections are managed with TypeORM's connection pooling. Configure pool size in your TypeORM configuration.
316
+
317
+ ### Caching
318
+
319
+ The server uses LRU caching for frequently accessed data. Configure cache settings in your `mj.config.cjs`:
320
+
321
+ ```javascript
322
+ databaseSettings: {
323
+ metadataCacheRefreshInterval: 300000 // 5 minutes
324
+ }
325
+ ```
326
+
327
+ ## Advanced Configuration
328
+
329
+ ### Custom Directives
330
+
331
+ The server includes custom GraphQL directives:
332
+ - `@RequireSystemUser`: Requires system user permissions
333
+ - `@Public`: Makes endpoints publicly accessible
334
+
335
+ ### WebSocket Configuration
336
+
337
+ For real-time subscriptions:
338
+
339
+ ```typescript
340
+ const webSocketServer = new WebSocketServer({
341
+ server: httpServer,
342
+ path: graphqlRootPath
343
+ });
344
+ ```
345
+
346
+ ## Troubleshooting
347
+
348
+ ### Common Issues
349
+
350
+ 1. **Authentication Errors**: Ensure all required environment variables are set
351
+ 2. **Database Connection**: Verify connection string and credentials
352
+ 3. **Module Loading**: Check resolver paths are correct and accessible
353
+ 4. **Transaction Errors**: Review mutation logic for proper error handling
354
+
355
+ ### Debug Mode
356
+
357
+ Enable detailed logging by setting environment variables:
358
+ ```shell
359
+ DEBUG=mj:*
360
+ NODE_ENV=development
361
+ ```
362
+
363
+ ## Best Practices
364
+
365
+ 1. **Use Read-Only Connections**: Configure read-only database connections for query operations
366
+ 2. **Implement Custom User Handling**: Extend `NewUserBase` for organization-specific user creation
367
+ 3. **Monitor Performance**: Use the built-in timing logs for transaction monitoring
368
+ 4. **Secure Your REST API**: Always configure entity and schema filters for production
369
+ 5. **Handle Errors Gracefully**: Implement proper error handling in custom resolvers
370
+
371
+ ## Contributing
372
+
373
+ When contributing to this package:
374
+ 1. Follow the existing code style and patterns
375
+ 2. Add appropriate TypeScript types
376
+ 3. Include tests for new functionality
377
+ 4. Update documentation as needed
378
+
379
+ ## License
380
+
381
+ ISC
@@ -1876,9 +1876,9 @@ export declare class User_ {
1876
1876
  UserNotifications_UserIDArray: UserNotification_[];
1877
1877
  Templates_UserIDArray: Template_[];
1878
1878
  UserFavorites_UserIDArray: UserFavorite_[];
1879
- ResourceLinks_UserIDArray: ResourceLink_[];
1880
1879
  ListCategories_UserIDArray: ListCategory_[];
1881
1880
  ScheduledActions_CreatedByUserIDArray: ScheduledAction_[];
1881
+ ResourceLinks_UserIDArray: ResourceLink_[];
1882
1882
  AIAgentRequests_ResponseByUserIDArray: AIAgentRequest_[];
1883
1883
  MJ_DashboardUserPreferences_UserIDArray: DashboardUserPreference_[];
1884
1884
  MJ_ReportUserStates_UserIDArray: ReportUserState_[];
@@ -1961,9 +1961,9 @@ export declare class UserResolverBase extends ResolverBase {
1961
1961
  UserNotifications_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1962
1962
  Templates_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1963
1963
  UserFavorites_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1964
- ResourceLinks_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1965
1964
  ListCategories_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1966
1965
  ScheduledActions_CreatedByUserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1966
+ ResourceLinks_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1967
1967
  AIAgentRequests_ResponseByUserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1968
1968
  MJ_DashboardUserPreferences_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
1969
1969
  MJ_ReportUserStates_UserIDArray(user_: User_, { dataSources, userPayload }: AppContext, pubSub: PubSubEngine): Promise<[]>;
@@ -3762,8 +3762,8 @@ export declare class Dashboard_ {
3762
3762
  Thumbnail?: string;
3763
3763
  Scope: string;
3764
3764
  ApplicationID?: string;
3765
- Code?: string;
3766
3765
  DriverClass?: string;
3766
+ Code?: string;
3767
3767
  User: string;
3768
3768
  Category?: string;
3769
3769
  Application?: string;
@@ -3780,8 +3780,8 @@ export declare class CreateDashboardInput {
3780
3780
  Thumbnail: string | null;
3781
3781
  Scope?: string;
3782
3782
  ApplicationID: string | null;
3783
- Code: string | null;
3784
3783
  DriverClass: string | null;
3784
+ Code: string | null;
3785
3785
  }
3786
3786
  export declare class UpdateDashboardInput {
3787
3787
  ID: string;
@@ -3794,8 +3794,8 @@ export declare class UpdateDashboardInput {
3794
3794
  Thumbnail?: string | null;
3795
3795
  Scope?: string;
3796
3796
  ApplicationID?: string | null;
3797
- Code?: string | null;
3798
3797
  DriverClass?: string | null;
3798
+ Code?: string | null;
3799
3799
  OldValues___?: KeyValuePairInput[];
3800
3800
  }
3801
3801
  export declare class RunDashboardViewResult {