@memberjunction/integration-actions 0.0.1 → 5.8.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,45 +1,79 @@
1
1
  # @memberjunction/integration-actions
2
2
 
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@memberjunction/integration-actions`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**
3
+ MJ Actions for triggering MemberJunction integration syncs. Connects the Integration Engine to the MJ Actions + Scheduling system.
4
+
5
+ ## Installation
6
+
7
+ This package is registered as a workspace package. Add it as a dependency and import it so the `@RegisterClass` decorator fires:
8
+
9
+ ```typescript
10
+ // In your bootstrap or entry point:
11
+ import '@memberjunction/integration-actions';
12
+ ```
13
+
14
+ ## Actions
15
+
16
+ ### Run Integration Sync
17
+
18
+ **Action Name**: `Run Integration Sync`
19
+
20
+ Triggers a full sync run for a `MJ: Company Integration` record.
21
+
22
+ | Parameter | Direction | Type | Required | Description |
23
+ |-----------|-----------|------|----------|-------------|
24
+ | `CompanyIntegrationID` | Input | string | Yes | ID of the CompanyIntegration to sync |
25
+ | `TriggerType` | Input | string | No | `Manual`, `Scheduled`, or `Webhook` (default: `Manual`) |
26
+ | `RecordsProcessed` | Output | number | — | Total records processed |
27
+ | `RecordsCreated` | Output | number | — | Records created in MJ |
28
+ | `RecordsUpdated` | Output | number | — | Records updated in MJ |
29
+ | `RecordsDeleted` | Output | number | — | Records deleted in MJ |
30
+ | `RecordsErrored` | Output | number | — | Records that encountered errors |
31
+ | `RecordsSkipped` | Output | number | — | Records that were skipped |
32
+ | `ErrorSummary` | Output | string | — | JSON array of first 10 errors (only when errors exist) |
33
+
34
+ **Result Codes**:
35
+ - `SUCCESS` — Sync completed without errors
36
+ - `SYNC_COMPLETED_WITH_ERRORS` — Sync completed but some records failed
37
+ - `MISSING_PARAMETER` — Required `CompanyIntegrationID` not provided
38
+ - `UNEXPECTED_ERROR` — Unhandled exception during sync
39
+
40
+ ## Scheduling via MJ Scheduler
41
+
42
+ 1. Create an `MJ: Actions` record for `Run Integration Sync`
43
+ 2. Create an `MJ: Action Params` record for `CompanyIntegrationID`
44
+ 3. Set up a Scheduled Job pointing to this action
45
+ 4. The scheduler calls the action on the configured cadence
46
+
47
+ ## Usage from Code
48
+
49
+ ```typescript
50
+ import '@memberjunction/integration-actions'; // ensure registration
51
+ import { ActionEngine } from '@memberjunction/actions';
52
+
53
+ const engine = ActionEngine.Instance;
54
+ const result = await engine.RunAction({
55
+ ActionName: 'Run Integration Sync',
56
+ ContextUser: currentUser,
57
+ Params: [
58
+ { Name: 'CompanyIntegrationID', Type: 'Input', Value: 'your-ci-id' },
59
+ { Name: 'TriggerType', Type: 'Input', Value: 'Scheduled' },
60
+ ],
61
+ });
62
+ ```
63
+
64
+ ## Direct Orchestrator Usage
65
+
66
+ For server-side code that doesn't go through the Actions system:
67
+
68
+ ```typescript
69
+ import { IntegrationOrchestrator } from '@memberjunction/integration-engine';
70
+
71
+ const orchestrator = new IntegrationOrchestrator();
72
+ const result = await orchestrator.RunSync(
73
+ companyIntegrationID,
74
+ contextUser,
75
+ 'Manual',
76
+ (progress) => console.log(`${progress.PercentComplete}%`),
77
+ (notification) => console.log(notification.Subject)
78
+ );
79
+ ```
@@ -0,0 +1,29 @@
1
+ import { BaseAction } from '@memberjunction/actions';
2
+ import { ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
3
+ /**
4
+ * MJ Action that triggers a sync for a CompanyIntegration.
5
+ *
6
+ * Parameters (Input):
7
+ * - CompanyIntegrationID (required): ID of the CompanyIntegration to sync
8
+ * - TriggerType (optional): 'Scheduled' | 'Manual' | 'Webhook' (default: 'Manual')
9
+ * - FullSync (optional): 'true' to force a full sync ignoring watermarks
10
+ * - EntityMapIDs (optional): comma-separated list of EntityMapIDs to restrict the sync
11
+ *
12
+ * Parameters (Output):
13
+ * - RecordsProcessed: total records processed
14
+ * - RecordsCreated: records created
15
+ * - RecordsUpdated: records updated
16
+ * - RecordsDeleted: records deleted
17
+ * - RecordsErrored: records that encountered errors
18
+ * - RecordsSkipped: records that were skipped
19
+ * - ErrorSummary: JSON string of error details (first 10 errors)
20
+ */
21
+ export declare class RunSyncAction extends BaseAction {
22
+ protected InternalRunAction(params: RunActionParams): Promise<ActionResultSimple>;
23
+ private parseTriggerType;
24
+ private buildResultMessage;
25
+ private addOutputParams;
26
+ private getStringParam;
27
+ private addOutputParam;
28
+ }
29
+ //# sourceMappingURL=RunSyncAction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunSyncAction.d.ts","sourceRoot":"","sources":["../src/RunSyncAction.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAe,MAAM,8BAA8B,CAAC;AAGhG;;;;;;;;;;;;;;;;;GAiBG;AACH,qBACa,aAAc,SAAQ,UAAU;cAEzB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuCvF,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,kBAAkB;IAY1B,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,cAAc;CAOzB"}
@@ -0,0 +1,117 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { RegisterClass } from '@memberjunction/global';
8
+ import { LogError } from '@memberjunction/core';
9
+ import { BaseAction } from '@memberjunction/actions';
10
+ import { ActionParam } from '@memberjunction/actions-base';
11
+ import { IntegrationOrchestrator } from '@memberjunction/integration-engine';
12
+ /**
13
+ * MJ Action that triggers a sync for a CompanyIntegration.
14
+ *
15
+ * Parameters (Input):
16
+ * - CompanyIntegrationID (required): ID of the CompanyIntegration to sync
17
+ * - TriggerType (optional): 'Scheduled' | 'Manual' | 'Webhook' (default: 'Manual')
18
+ * - FullSync (optional): 'true' to force a full sync ignoring watermarks
19
+ * - EntityMapIDs (optional): comma-separated list of EntityMapIDs to restrict the sync
20
+ *
21
+ * Parameters (Output):
22
+ * - RecordsProcessed: total records processed
23
+ * - RecordsCreated: records created
24
+ * - RecordsUpdated: records updated
25
+ * - RecordsDeleted: records deleted
26
+ * - RecordsErrored: records that encountered errors
27
+ * - RecordsSkipped: records that were skipped
28
+ * - ErrorSummary: JSON string of error details (first 10 errors)
29
+ */
30
+ let RunSyncAction = class RunSyncAction extends BaseAction {
31
+ async InternalRunAction(params) {
32
+ try {
33
+ const companyIntegrationID = this.getStringParam(params, 'CompanyIntegrationID');
34
+ if (!companyIntegrationID) {
35
+ return {
36
+ Success: false,
37
+ ResultCode: 'MISSING_PARAMETER',
38
+ Message: "Parameter 'CompanyIntegrationID' is required"
39
+ };
40
+ }
41
+ const triggerType = this.parseTriggerType(this.getStringParam(params, 'TriggerType'));
42
+ const orchestrator = new IntegrationOrchestrator();
43
+ const result = await orchestrator.RunSync(companyIntegrationID, params.ContextUser, triggerType);
44
+ this.addOutputParams(params, result);
45
+ return {
46
+ Success: result.Success,
47
+ ResultCode: result.Success ? 'SUCCESS' : 'SYNC_COMPLETED_WITH_ERRORS',
48
+ Message: this.buildResultMessage(result),
49
+ Params: params.Params
50
+ };
51
+ }
52
+ catch (error) {
53
+ const message = error instanceof Error ? error.message : String(error);
54
+ LogError(`[RunSyncAction] Unexpected error: ${message}`);
55
+ return {
56
+ Success: false,
57
+ ResultCode: 'UNEXPECTED_ERROR',
58
+ Message: message
59
+ };
60
+ }
61
+ }
62
+ parseTriggerType(value) {
63
+ if (value === 'Scheduled' || value === 'Webhook')
64
+ return value;
65
+ return 'Manual';
66
+ }
67
+ buildResultMessage(result) {
68
+ const parts = [
69
+ `Processed: ${result.RecordsProcessed}`,
70
+ `Created: ${result.RecordsCreated}`,
71
+ `Updated: ${result.RecordsUpdated}`,
72
+ ];
73
+ if (result.RecordsDeleted > 0)
74
+ parts.push(`Deleted: ${result.RecordsDeleted}`);
75
+ if (result.RecordsErrored > 0)
76
+ parts.push(`Errors: ${result.RecordsErrored}`);
77
+ if (result.RecordsSkipped > 0)
78
+ parts.push(`Skipped: ${result.RecordsSkipped}`);
79
+ return parts.join(', ');
80
+ }
81
+ addOutputParams(params, result) {
82
+ const outputs = [
83
+ { name: 'RecordsProcessed', value: result.RecordsProcessed },
84
+ { name: 'RecordsCreated', value: result.RecordsCreated },
85
+ { name: 'RecordsUpdated', value: result.RecordsUpdated },
86
+ { name: 'RecordsDeleted', value: result.RecordsDeleted },
87
+ { name: 'RecordsErrored', value: result.RecordsErrored },
88
+ { name: 'RecordsSkipped', value: result.RecordsSkipped },
89
+ ];
90
+ for (const { name, value } of outputs) {
91
+ this.addOutputParam(params, name, value);
92
+ }
93
+ if (result.Errors.length > 0) {
94
+ this.addOutputParam(params, 'ErrorSummary', JSON.stringify(result.Errors.slice(0, 10)));
95
+ }
96
+ }
97
+ getStringParam(params, name) {
98
+ const nameLower = name.toLowerCase();
99
+ const param = params.Params?.find(p => p.Name.trim().toLowerCase() === nameLower);
100
+ if (!param || param.Value == null)
101
+ return undefined;
102
+ const value = String(param.Value).trim();
103
+ return value.length > 0 ? value : undefined;
104
+ }
105
+ addOutputParam(params, name, value) {
106
+ const outputParam = new ActionParam();
107
+ outputParam.Name = name;
108
+ outputParam.Type = 'Output';
109
+ outputParam.Value = value;
110
+ params.Params.push(outputParam);
111
+ }
112
+ };
113
+ RunSyncAction = __decorate([
114
+ RegisterClass(BaseAction, 'Run Integration Sync')
115
+ ], RunSyncAction);
116
+ export { RunSyncAction };
117
+ //# sourceMappingURL=RunSyncAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunSyncAction.js","sourceRoot":"","sources":["../src/RunSyncAction.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAuC,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChG,OAAO,EAAE,uBAAuB,EAA+B,MAAM,oCAAoC,CAAC;AAE1G;;;;;;;;;;;;;;;;;GAiBG;AAEI,IAAM,aAAa,GAAnB,MAAM,aAAc,SAAQ,UAAU;IAE/B,KAAK,CAAC,iBAAiB,CAAC,MAAuB;QACrD,IAAI,CAAC;YACD,MAAM,oBAAoB,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;YACjF,IAAI,CAAC,oBAAoB,EAAE,CAAC;gBACxB,OAAO;oBACH,OAAO,EAAE,KAAK;oBACd,UAAU,EAAE,mBAAmB;oBAC/B,OAAO,EAAE,8CAA8C;iBAC1D,CAAC;YACN,CAAC;YAED,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;YACtF,MAAM,YAAY,GAAG,IAAI,uBAAuB,EAAE,CAAC;YAEnD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CACrC,oBAAoB,EACpB,MAAM,CAAC,WAAW,EAClB,WAAW,CACd,CAAC;YAEF,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAErC,OAAO;gBACH,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,4BAA4B;gBACrE,OAAO,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;gBACxC,MAAM,EAAE,MAAM,CAAC,MAAM;aACxB,CAAC;QACN,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,QAAQ,CAAC,qCAAqC,OAAO,EAAE,CAAC,CAAC;YACzD,OAAO;gBACH,OAAO,EAAE,KAAK;gBACd,UAAU,EAAE,kBAAkB;gBAC9B,OAAO,EAAE,OAAO;aACnB,CAAC;QACN,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,KAAyB;QAC9C,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAC/D,OAAO,QAAQ,CAAC;IACpB,CAAC;IAEO,kBAAkB,CAAC,MAAkB;QACzC,MAAM,KAAK,GAAa;YACpB,cAAc,MAAM,CAAC,gBAAgB,EAAE;YACvC,YAAY,MAAM,CAAC,cAAc,EAAE;YACnC,YAAY,MAAM,CAAC,cAAc,EAAE;SACtC,CAAC;QACF,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC/E,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC9E,IAAI,MAAM,CAAC,cAAc,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC;QAC/E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,MAAuB,EAAE,MAAkB;QAC/D,MAAM,OAAO,GAAoD;YAC7D,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,CAAC,gBAAgB,EAAE;YAC5D,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE;YACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE;YACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE;YACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE;YACxD,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE;SAC3D,CAAC;QACF,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,OAAO,EAAE,CAAC;YACpC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,cAAc,CACf,MAAM,EACN,cAAc,EACd,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAC7C,CAAC;QACN,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,MAAuB,EAAE,IAAY;QACxD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,SAAS,CAAC,CAAC;QAClF,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI;YAAE,OAAO,SAAS,CAAC;QACpD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,CAAC;IAEO,cAAc,CAAC,MAAuB,EAAE,IAAY,EAAE,KAAsB;QAChF,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;QACtC,WAAW,CAAC,IAAI,GAAG,IAAI,CAAC;QACxB,WAAW,CAAC,IAAI,GAAG,QAAQ,CAAC;QAC5B,WAAW,CAAC,KAAK,GAAG,KAAK,CAAC;QAC1B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACpC,CAAC;CACJ,CAAA;AA9FY,aAAa;IADzB,aAAa,CAAC,UAAU,EAAE,sBAAsB,CAAC;GACrC,aAAa,CA8FzB"}
@@ -0,0 +1,2 @@
1
+ export * from './RunSyncAction.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './RunSyncAction.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,34 @@
1
1
  {
2
2
  "name": "@memberjunction/integration-actions",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @memberjunction/integration-actions",
5
- "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
3
+ "type": "module",
4
+ "version": "5.8.0",
5
+ "description": "MemberJunction Integration Engine Actions - MJ Actions for triggering and managing integration syncs",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "/dist"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc && tsc-alias -f",
13
+ "test": "vitest run",
14
+ "test:watch": "vitest"
15
+ },
16
+ "dependencies": {
17
+ "@memberjunction/actions": "5.8.0",
18
+ "@memberjunction/actions-base": "5.8.0",
19
+ "@memberjunction/core": "5.8.0",
20
+ "@memberjunction/global": "5.8.0",
21
+ "@memberjunction/integration-engine": "5.8.0"
22
+ },
23
+ "devDependencies": {
24
+ "typescript": "^5.9.3",
25
+ "tsc-alias": "^1.8.16",
26
+ "vitest": "^4.0.18"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/MemberJunction/MJ"
31
+ },
32
+ "author": "MemberJunction.com",
33
+ "license": "ISC"
10
34
  }