@memberjunction/data-context-server 4.0.0 → 4.1.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 +59 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/readme.md +36 -210
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @memberjunction/data-context-server
|
|
2
|
+
|
|
3
|
+
Server-side implementation of the MemberJunction Data Context system. Provides SQL-based data loading for `DataContextItem` objects using direct database connections.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The `@memberjunction/data-context-server` package extends the base `DataContextItem` class from `@memberjunction/data-context` with a server-side implementation that executes SQL queries directly against SQL Server using `mssql` connection pools. This is the server counterpart to the client-side GraphQL-based data context loading.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
graph TD
|
|
11
|
+
A["DataContextItemServer"] -->|extends| B["DataContextItem<br/>(data-context package)"]
|
|
12
|
+
A -->|uses| C["mssql ConnectionPool"]
|
|
13
|
+
C --> D["SQL Server"]
|
|
14
|
+
|
|
15
|
+
E["Server-Side Code<br/>(MJAPI, Actions, etc.)"] --> A
|
|
16
|
+
F["Client-Side Code<br/>(Angular, React)"] --> G["DataContextItemClient<br/>(GraphQL-based)"]
|
|
17
|
+
|
|
18
|
+
style A fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
19
|
+
style B fill:#7c5295,stroke:#563a6b,color:#fff
|
|
20
|
+
style C fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
21
|
+
style D fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
22
|
+
style E fill:#b8762f,stroke:#8a5722,color:#fff
|
|
23
|
+
style G fill:#b8762f,stroke:#8a5722,color:#fff
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @memberjunction/data-context-server
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## How It Works
|
|
33
|
+
|
|
34
|
+
The package registers `DataContextItemServer` as a subclass of `DataContextItem` using MemberJunction's `@RegisterClass` decorator. When server-side code creates a `DataContextItem`, the class factory automatically returns the server implementation that uses direct SQL execution rather than GraphQL.
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import '@memberjunction/data-context-server';
|
|
38
|
+
// DataContextItem instances now use direct SQL execution on the server
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The `LoadFromSQL` method:
|
|
42
|
+
1. Receives a SQL Server `ConnectionPool` as the data source
|
|
43
|
+
2. Creates a new `Request` from the pool
|
|
44
|
+
3. Executes the `DataContextItem.SQL` query directly
|
|
45
|
+
4. Stores the resulting recordset in `DataContextItem.Data`
|
|
46
|
+
5. Returns success/failure with error details on `DataLoadingError`
|
|
47
|
+
|
|
48
|
+
## Dependencies
|
|
49
|
+
|
|
50
|
+
| Package | Purpose |
|
|
51
|
+
|---------|---------|
|
|
52
|
+
| `@memberjunction/core` | UserInfo, LogError utilities |
|
|
53
|
+
| `@memberjunction/global` | RegisterClass decorator |
|
|
54
|
+
| `@memberjunction/data-context` | Base DataContextItem class |
|
|
55
|
+
| `mssql` | SQL Server connectivity |
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
ISC
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { RegisterClass } from "@memberjunction/global";
|
|
8
8
|
import { LogError } from "@memberjunction/core";
|
|
9
9
|
import { DataContextItem } from "@memberjunction/data-context";
|
|
10
|
-
import
|
|
10
|
+
import sql from "mssql";
|
|
11
11
|
let DataContextItemServer = class DataContextItemServer extends DataContextItem {
|
|
12
12
|
/**
|
|
13
13
|
* Server-Side only method to load the data context item from a SQL statement
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAY,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,GAAG,MAAM,OAAO,CAAC;AAGjB,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,eAAe;IACtD;;;;OAIG;IACgB,KAAK,CAAC,WAAW,CAAC,UAAe,EAAE,WAAsB;QACxE,IAAI,CAAC;YACD,MAAM,IAAI,GAAG,UAAgC,CAAC;YAC9C,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC;YAC7B,OAAO,IAAI,CAAC,CAAC,mGAAmG;QACpH,CAAC;QACD,OAAO,CAAC,EAAE,CAAC;YACP,IAAI,CAAC,gBAAgB,GAAG,6CAA6C,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;YACrG,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YAChC,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;CACJ,CAAA;AApBY,qBAAqB;IADjC,aAAa,CAAC,eAAe,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC;GAC9C,qBAAqB,CAoBjC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/data-context-server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.1.0",
|
|
5
5
|
"description": "This library provides a server-side implementation of the DataContextItem class from @memberjunction/data-context that can handle the server-side only use case of loading data into a context using raw SQL statements.",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"typescript": "^5.9.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@memberjunction/core": "4.
|
|
24
|
-
"@memberjunction/data-context": "4.
|
|
25
|
-
"@memberjunction/global": "4.
|
|
23
|
+
"@memberjunction/core": "4.1.0",
|
|
24
|
+
"@memberjunction/data-context": "4.1.0",
|
|
25
|
+
"@memberjunction/global": "4.1.0",
|
|
26
26
|
"mssql": "^12.2.0"
|
|
27
27
|
},
|
|
28
28
|
"repository": {
|
package/readme.md
CHANGED
|
@@ -1,233 +1,59 @@
|
|
|
1
1
|
# @memberjunction/data-context-server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Server-side implementation of the MemberJunction Data Context system. Provides SQL-based data loading for `DataContextItem` objects using direct database connections.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
The `@memberjunction/data-context-server` package extends the base `DataContextItem` class
|
|
7
|
+
The `@memberjunction/data-context-server` package extends the base `DataContextItem` class from `@memberjunction/data-context` with a server-side implementation that executes SQL queries directly against SQL Server using `mssql` connection pools. This is the server counterpart to the client-side GraphQL-based data context loading.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
## Purpose and Functionality
|
|
16
|
-
|
|
17
|
-
This package serves a critical role in the MemberJunction ecosystem by:
|
|
9
|
+
```mermaid
|
|
10
|
+
graph TD
|
|
11
|
+
A["DataContextItemServer"] -->|extends| B["DataContextItem<br/>(data-context package)"]
|
|
12
|
+
A -->|uses| C["mssql ConnectionPool"]
|
|
13
|
+
C --> D["SQL Server"]
|
|
18
14
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
3. **Automatic Registration**: Registers itself with higher priority (2) to override the base implementation when running on the server
|
|
22
|
-
4. **Tree-Shaking Prevention**: Includes a utility function to ensure the class isn't removed during build optimization
|
|
15
|
+
E["Server-Side Code<br/>(MJAPI, Actions, etc.)"] --> A
|
|
16
|
+
F["Client-Side Code<br/>(Angular, React)"] --> G["DataContextItemClient<br/>(GraphQL-based)"]
|
|
23
17
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
import { LoadDataContextItemsServer } from '@memberjunction/data-context-server';
|
|
32
|
-
|
|
33
|
-
// Call this once in your server initialization code
|
|
34
|
-
LoadDataContextItemsServer();
|
|
18
|
+
style A fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
19
|
+
style B fill:#7c5295,stroke:#563a6b,color:#fff
|
|
20
|
+
style C fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
21
|
+
style D fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
22
|
+
style E fill:#b8762f,stroke:#8a5722,color:#fff
|
|
23
|
+
style G fill:#b8762f,stroke:#8a5722,color:#fff
|
|
35
24
|
```
|
|
36
25
|
|
|
37
|
-
|
|
26
|
+
## Installation
|
|
38
27
|
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
import { DataSource } from 'typeorm';
|
|
42
|
-
import { UserInfo } from '@memberjunction/core';
|
|
43
|
-
|
|
44
|
-
// Assume you have a TypeORM DataSource configured
|
|
45
|
-
const dataSource: DataSource = /* your configured data source */;
|
|
46
|
-
|
|
47
|
-
// Load a data context that includes SQL-type items
|
|
48
|
-
const context = new DataContext();
|
|
49
|
-
const user = /* current user context */;
|
|
50
|
-
|
|
51
|
-
// Load metadata and data in one operation
|
|
52
|
-
const success = await context.Load(
|
|
53
|
-
dataContextId,
|
|
54
|
-
dataSource, // Pass the TypeORM DataSource
|
|
55
|
-
false, // forceRefresh
|
|
56
|
-
false, // loadRelatedDataOnSingleRecords
|
|
57
|
-
0, // maxRecordsPerRelationship
|
|
58
|
-
user // contextUser
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
if (success) {
|
|
62
|
-
// Access the loaded data
|
|
63
|
-
context.Items.forEach(item => {
|
|
64
|
-
if (item.Type === 'sql' && item.DataLoaded) {
|
|
65
|
-
console.log(`SQL Item Data:`, item.Data);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
}
|
|
28
|
+
```bash
|
|
29
|
+
npm install @memberjunction/data-context-server
|
|
69
30
|
```
|
|
70
31
|
|
|
71
|
-
|
|
32
|
+
## How It Works
|
|
33
|
+
|
|
34
|
+
The package registers `DataContextItemServer` as a subclass of `DataContextItem` using MemberJunction's `@RegisterClass` decorator. When server-side code creates a `DataContextItem`, the class factory automatically returns the server implementation that uses direct SQL execution rather than GraphQL.
|
|
72
35
|
|
|
73
36
|
```typescript
|
|
74
|
-
import
|
|
75
|
-
|
|
76
|
-
const context = new DataContext();
|
|
77
|
-
const sqlItem = context.AddDataContextItem();
|
|
78
|
-
|
|
79
|
-
// Configure as SQL type
|
|
80
|
-
sqlItem.Type = 'sql';
|
|
81
|
-
sqlItem.SQL = 'SELECT * FROM Customers WHERE Country = @country';
|
|
82
|
-
sqlItem.RecordName = 'US Customers';
|
|
83
|
-
sqlItem.AdditionalDescription = 'All customers from the United States';
|
|
84
|
-
|
|
85
|
-
// Load the data
|
|
86
|
-
const dataSource = /* your TypeORM DataSource */;
|
|
87
|
-
const loaded = await sqlItem.LoadData(dataSource);
|
|
88
|
-
|
|
89
|
-
if (loaded) {
|
|
90
|
-
console.log('SQL Results:', sqlItem.Data);
|
|
91
|
-
} else {
|
|
92
|
-
console.error('Loading failed:', sqlItem.DataLoadingError);
|
|
93
|
-
}
|
|
37
|
+
import '@memberjunction/data-context-server';
|
|
38
|
+
// DataContextItem instances now use direct SQL execution on the server
|
|
94
39
|
```
|
|
95
40
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
#### Protected Methods
|
|
103
|
-
|
|
104
|
-
##### `LoadFromSQL(dataSource: any, contextUser?: UserInfo): Promise<boolean>`
|
|
105
|
-
|
|
106
|
-
Executes a SQL statement and loads the results into the DataContextItem.
|
|
107
|
-
|
|
108
|
-
**Parameters:**
|
|
109
|
-
- `dataSource` (any): The TypeORM DataSource object used to execute queries
|
|
110
|
-
- `contextUser` (UserInfo, optional): The user context for the operation
|
|
111
|
-
|
|
112
|
-
**Returns:**
|
|
113
|
-
- `Promise<boolean>`: Returns `true` if successful, `false` if an error occurs
|
|
114
|
-
|
|
115
|
-
**Error Handling:**
|
|
116
|
-
- Catches and logs any SQL execution errors
|
|
117
|
-
- Sets the `DataLoadingError` property with error details
|
|
118
|
-
- Returns `false` on failure
|
|
119
|
-
|
|
120
|
-
### Utility Functions
|
|
121
|
-
|
|
122
|
-
#### `LoadDataContextItemsServer(): void`
|
|
123
|
-
|
|
124
|
-
Prevents tree-shaking from removing the `DataContextItemServer` class during build optimization.
|
|
125
|
-
|
|
126
|
-
**Usage:**
|
|
127
|
-
Call this function after importing the package in your server application to ensure the class registration takes effect.
|
|
128
|
-
|
|
129
|
-
## Integration with MemberJunction Packages
|
|
130
|
-
|
|
131
|
-
This package integrates seamlessly with:
|
|
132
|
-
|
|
133
|
-
- **@memberjunction/data-context**: Provides the base `DataContextItem` class and `DataContext` functionality
|
|
134
|
-
- **@memberjunction/global**: Uses the class registration system for runtime polymorphism
|
|
135
|
-
- **@memberjunction/core**: Leverages logging utilities and user context
|
|
136
|
-
- **typeorm**: Utilizes TypeORM's DataSource for database operations
|
|
41
|
+
The `LoadFromSQL` method:
|
|
42
|
+
1. Receives a SQL Server `ConnectionPool` as the data source
|
|
43
|
+
2. Creates a new `Request` from the pool
|
|
44
|
+
3. Executes the `DataContextItem.SQL` query directly
|
|
45
|
+
4. Stores the resulting recordset in `DataContextItem.Data`
|
|
46
|
+
5. Returns success/failure with error details on `DataLoadingError`
|
|
137
47
|
|
|
138
48
|
## Dependencies
|
|
139
49
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Configuration
|
|
149
|
-
|
|
150
|
-
No special configuration is required. The package automatically registers itself with the MemberJunction class factory system when imported.
|
|
151
|
-
|
|
152
|
-
## Build and Development
|
|
153
|
-
|
|
154
|
-
### Scripts
|
|
155
|
-
|
|
156
|
-
- `npm run build`: Compiles TypeScript to JavaScript
|
|
157
|
-
- `npm start`: Runs the TypeScript code directly using ts-node-dev
|
|
158
|
-
|
|
159
|
-
### TypeScript Configuration
|
|
160
|
-
|
|
161
|
-
The package uses a standard TypeScript configuration that compiles to ES modules and includes type definitions.
|
|
162
|
-
|
|
163
|
-
## Important Notes
|
|
164
|
-
|
|
165
|
-
1. **Server-Side Only**: This package is designed for server-side use only. Client-side applications should not include this package.
|
|
166
|
-
|
|
167
|
-
2. **Class Registration Priority**: The `DataContextItemServer` class registers with priority 2, ensuring it overrides the base implementation when present.
|
|
168
|
-
|
|
169
|
-
3. **Error Handling**: SQL execution errors are caught and stored in the `DataLoadingError` property rather than throwing exceptions.
|
|
170
|
-
|
|
171
|
-
4. **Data Loading**: The `LoadFromSQL` method stores query results directly in the `Data` property as an array of objects.
|
|
172
|
-
|
|
173
|
-
## Example: Complete Server Application
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
import { DataContext } from '@memberjunction/data-context';
|
|
177
|
-
import { LoadDataContextItemsServer } from '@memberjunction/data-context-server';
|
|
178
|
-
import { createConnection, DataSource } from 'typeorm';
|
|
179
|
-
import { Metadata } from '@memberjunction/core';
|
|
180
|
-
|
|
181
|
-
// Initialize the server-side data context support
|
|
182
|
-
LoadDataContextItemsServer();
|
|
183
|
-
|
|
184
|
-
// Configure your database connection
|
|
185
|
-
const dataSource = new DataSource({
|
|
186
|
-
type: 'mssql',
|
|
187
|
-
host: 'localhost',
|
|
188
|
-
username: 'your_username',
|
|
189
|
-
password: 'your_password',
|
|
190
|
-
database: 'your_database',
|
|
191
|
-
// ... other TypeORM configuration
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
async function loadDataContextWithSQL() {
|
|
195
|
-
await dataSource.initialize();
|
|
196
|
-
|
|
197
|
-
const context = new DataContext();
|
|
198
|
-
const user = await Metadata.Provider.GetCurrentUser();
|
|
199
|
-
|
|
200
|
-
// Create a SQL-based data context item
|
|
201
|
-
const item = context.AddDataContextItem();
|
|
202
|
-
item.Type = 'sql';
|
|
203
|
-
item.SQL = `
|
|
204
|
-
SELECT
|
|
205
|
-
c.CustomerID,
|
|
206
|
-
c.CompanyName,
|
|
207
|
-
COUNT(o.OrderID) as OrderCount,
|
|
208
|
-
SUM(od.Quantity * od.UnitPrice) as TotalRevenue
|
|
209
|
-
FROM Customers c
|
|
210
|
-
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
|
|
211
|
-
LEFT JOIN [Order Details] od ON o.OrderID = od.OrderID
|
|
212
|
-
GROUP BY c.CustomerID, c.CompanyName
|
|
213
|
-
ORDER BY TotalRevenue DESC
|
|
214
|
-
`;
|
|
215
|
-
item.RecordName = 'Customer Revenue Summary';
|
|
216
|
-
|
|
217
|
-
// Load the data
|
|
218
|
-
const success = await item.LoadData(dataSource, false, false, 0, user);
|
|
219
|
-
|
|
220
|
-
if (success) {
|
|
221
|
-
console.log('Customer revenue data:', item.Data);
|
|
222
|
-
|
|
223
|
-
// Save the context if needed
|
|
224
|
-
await context.SaveItems(user, true); // true to persist the data
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
await dataSource.destroy();
|
|
228
|
-
}
|
|
229
|
-
```
|
|
50
|
+
| Package | Purpose |
|
|
51
|
+
|---------|---------|
|
|
52
|
+
| `@memberjunction/core` | UserInfo, LogError utilities |
|
|
53
|
+
| `@memberjunction/global` | RegisterClass decorator |
|
|
54
|
+
| `@memberjunction/data-context` | Base DataContextItem class |
|
|
55
|
+
| `mssql` | SQL Server connectivity |
|
|
230
56
|
|
|
231
57
|
## License
|
|
232
58
|
|
|
233
|
-
|
|
59
|
+
ISC
|