@memberjunction/server 5.34.1 → 5.36.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 (41) hide show
  1. package/dist/generated/generated.d.ts +49 -4
  2. package/dist/generated/generated.d.ts.map +1 -1
  3. package/dist/generated/generated.js +236 -14
  4. package/dist/generated/generated.js.map +1 -1
  5. package/dist/generic/ResolverBase.d.ts +1 -1
  6. package/dist/generic/ResolverBase.d.ts.map +1 -1
  7. package/dist/generic/ResolverBase.js +7 -4
  8. package/dist/generic/ResolverBase.js.map +1 -1
  9. package/dist/generic/RunViewResolver.d.ts +4 -0
  10. package/dist/generic/RunViewResolver.d.ts.map +1 -1
  11. package/dist/generic/RunViewResolver.js +28 -0
  12. package/dist/generic/RunViewResolver.js.map +1 -1
  13. package/dist/resolvers/AdhocQueryResolver.d.ts +2 -0
  14. package/dist/resolvers/AdhocQueryResolver.d.ts.map +1 -1
  15. package/dist/resolvers/AdhocQueryResolver.js +42 -8
  16. package/dist/resolvers/AdhocQueryResolver.js.map +1 -1
  17. package/dist/resolvers/ListOperationsResolver.d.ts +175 -0
  18. package/dist/resolvers/ListOperationsResolver.d.ts.map +1 -0
  19. package/dist/resolvers/ListOperationsResolver.js +930 -0
  20. package/dist/resolvers/ListOperationsResolver.js.map +1 -0
  21. package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
  22. package/dist/resolvers/RunAIAgentResolver.js +111 -58
  23. package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
  24. package/dist/resolvers/artifact-routing.d.ts +39 -0
  25. package/dist/resolvers/artifact-routing.d.ts.map +1 -0
  26. package/dist/resolvers/artifact-routing.js +40 -0
  27. package/dist/resolvers/artifact-routing.js.map +1 -0
  28. package/dist/types.d.ts +6 -0
  29. package/dist/types.d.ts.map +1 -1
  30. package/dist/types.js.map +1 -1
  31. package/package.json +70 -68
  32. package/src/__tests__/ListOperationsResolver.test.ts +182 -0
  33. package/src/generated/generated.ts +173 -14
  34. package/src/generic/ResolverBase.ts +13 -4
  35. package/src/generic/RunViewResolver.ts +28 -0
  36. package/src/resolvers/AdhocQueryResolver.ts +41 -8
  37. package/src/resolvers/ListOperationsResolver.ts +607 -0
  38. package/src/resolvers/RunAIAgentResolver.ts +119 -61
  39. package/src/resolvers/__tests__/artifact-routing.test.ts +88 -0
  40. package/src/resolvers/artifact-routing.ts +80 -0
  41. package/src/types.ts +6 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/server",
3
- "version": "5.34.1",
3
+ "version": "5.36.0",
4
4
  "description": "MemberJunction: This project provides API access via GraphQL to the common data store.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./src/index.ts",
@@ -27,73 +27,75 @@
27
27
  "@as-integrations/express5": "^1.0.0",
28
28
  "@graphql-tools/schema": "latest",
29
29
  "@graphql-tools/utils": "^11.0.0",
30
- "@memberjunction/actions": "5.34.1",
31
- "@memberjunction/actions-apollo": "5.34.1",
32
- "@memberjunction/actions-base": "5.34.1",
33
- "@memberjunction/actions-bizapps-accounting": "5.34.1",
34
- "@memberjunction/actions-bizapps-crm": "5.34.1",
35
- "@memberjunction/actions-bizapps-formbuilders": "5.34.1",
36
- "@memberjunction/actions-bizapps-lms": "5.34.1",
37
- "@memberjunction/actions-bizapps-social": "5.34.1",
38
- "@memberjunction/ai": "5.34.1",
39
- "@memberjunction/ai-agent-manager": "5.34.1",
40
- "@memberjunction/ai-agent-manager-actions": "5.34.1",
41
- "@memberjunction/ai-agents": "5.34.1",
42
- "@memberjunction/ai-core-plus": "5.34.1",
43
- "@memberjunction/ai-mcp-client": "5.34.1",
44
- "@memberjunction/ai-prompts": "5.34.1",
45
- "@memberjunction/ai-provider-bundle": "5.34.1",
46
- "@memberjunction/ai-vector-sync": "5.34.1",
47
- "@memberjunction/ai-vectordb": "5.34.1",
48
- "@memberjunction/ai-vectors-pinecone": "5.34.1",
49
- "@memberjunction/aiengine": "5.34.1",
50
- "@memberjunction/api-keys": "5.34.1",
51
- "@memberjunction/auth-providers": "5.34.1",
52
- "@memberjunction/codegen-lib": "5.34.1",
53
- "@memberjunction/communication-ms-graph": "5.34.1",
54
- "@memberjunction/communication-sendgrid": "5.34.1",
55
- "@memberjunction/communication-types": "5.34.1",
56
- "@memberjunction/component-registry-client-sdk": "5.34.1",
57
- "@memberjunction/computer-use-engine": "5.34.1",
58
- "@memberjunction/config": "5.34.1",
59
- "@memberjunction/core": "5.34.1",
60
- "@memberjunction/core-actions": "5.34.1",
61
- "@memberjunction/core-entities": "5.34.1",
62
- "@memberjunction/core-entities-server": "5.34.1",
63
- "@memberjunction/data-context": "5.34.1",
64
- "@memberjunction/data-context-server": "5.34.1",
65
- "@memberjunction/doc-utils": "5.34.1",
66
- "@memberjunction/encryption": "5.34.1",
67
- "@memberjunction/entity-communications-base": "5.34.1",
68
- "@memberjunction/entity-communications-server": "5.34.1",
69
- "@memberjunction/external-change-detection": "5.34.1",
70
- "@memberjunction/generic-database-provider": "5.34.1",
71
- "@memberjunction/global": "5.34.1",
72
- "@memberjunction/graphql-dataprovider": "5.34.1",
73
- "@memberjunction/integration-engine": "5.34.1",
74
- "@memberjunction/integration-schema-builder": "5.34.1",
75
- "@memberjunction/interactive-component-types": "5.34.1",
76
- "@memberjunction/notifications": "5.34.1",
77
- "@memberjunction/postgresql-dataprovider": "5.34.1",
78
- "@memberjunction/queue": "5.34.1",
79
- "@memberjunction/redis-provider": "5.34.1",
80
- "@memberjunction/scheduling-actions": "5.34.1",
81
- "@memberjunction/scheduling-base-types": "5.34.1",
82
- "@memberjunction/scheduling-engine": "5.34.1",
83
- "@memberjunction/scheduling-engine-base": "5.34.1",
84
- "@memberjunction/schema-engine": "5.34.1",
85
- "@memberjunction/search-engine": "5.34.1",
86
- "@memberjunction/server-extensions-core": "5.34.1",
87
- "@memberjunction/skip-types": "5.34.1",
88
- "@memberjunction/sql-dialect": "5.34.1",
89
- "@memberjunction/sqlserver-dataprovider": "5.34.1",
90
- "@memberjunction/storage": "5.34.1",
91
- "@memberjunction/tag-engine": "5.34.1",
92
- "@memberjunction/tag-engine-base": "5.34.1",
93
- "@memberjunction/templates": "5.34.1",
94
- "@memberjunction/testing-engine": "5.34.1",
95
- "@memberjunction/testing-engine-base": "5.34.1",
96
- "@memberjunction/version-history": "5.34.1",
30
+ "@memberjunction/actions": "5.36.0",
31
+ "@memberjunction/actions-apollo": "5.36.0",
32
+ "@memberjunction/actions-base": "5.36.0",
33
+ "@memberjunction/actions-bizapps-accounting": "5.36.0",
34
+ "@memberjunction/actions-bizapps-crm": "5.36.0",
35
+ "@memberjunction/actions-bizapps-formbuilders": "5.36.0",
36
+ "@memberjunction/actions-bizapps-lms": "5.36.0",
37
+ "@memberjunction/actions-bizapps-social": "5.36.0",
38
+ "@memberjunction/ai": "5.36.0",
39
+ "@memberjunction/ai-agent-manager": "5.36.0",
40
+ "@memberjunction/ai-agent-manager-actions": "5.36.0",
41
+ "@memberjunction/ai-agents": "5.36.0",
42
+ "@memberjunction/ai-core-plus": "5.36.0",
43
+ "@memberjunction/ai-mcp-client": "5.36.0",
44
+ "@memberjunction/ai-prompts": "5.36.0",
45
+ "@memberjunction/ai-provider-bundle": "5.36.0",
46
+ "@memberjunction/ai-vector-sync": "5.36.0",
47
+ "@memberjunction/ai-vectordb": "5.36.0",
48
+ "@memberjunction/ai-vectors-pinecone": "5.36.0",
49
+ "@memberjunction/aiengine": "5.36.0",
50
+ "@memberjunction/api-keys": "5.36.0",
51
+ "@memberjunction/auth-providers": "5.36.0",
52
+ "@memberjunction/codegen-lib": "5.36.0",
53
+ "@memberjunction/communication-ms-graph": "5.36.0",
54
+ "@memberjunction/communication-sendgrid": "5.36.0",
55
+ "@memberjunction/communication-types": "5.36.0",
56
+ "@memberjunction/component-registry-client-sdk": "5.36.0",
57
+ "@memberjunction/computer-use-engine": "5.36.0",
58
+ "@memberjunction/config": "5.36.0",
59
+ "@memberjunction/core": "5.36.0",
60
+ "@memberjunction/core-actions": "5.36.0",
61
+ "@memberjunction/core-entities": "5.36.0",
62
+ "@memberjunction/core-entities-server": "5.36.0",
63
+ "@memberjunction/data-context": "5.36.0",
64
+ "@memberjunction/data-context-server": "5.36.0",
65
+ "@memberjunction/doc-utils": "5.36.0",
66
+ "@memberjunction/encryption": "5.36.0",
67
+ "@memberjunction/entity-communications-base": "5.36.0",
68
+ "@memberjunction/entity-communications-server": "5.36.0",
69
+ "@memberjunction/external-change-detection": "5.36.0",
70
+ "@memberjunction/generic-database-provider": "5.36.0",
71
+ "@memberjunction/global": "5.36.0",
72
+ "@memberjunction/graphql-dataprovider": "5.36.0",
73
+ "@memberjunction/integration-engine": "5.36.0",
74
+ "@memberjunction/integration-schema-builder": "5.36.0",
75
+ "@memberjunction/interactive-component-types": "5.36.0",
76
+ "@memberjunction/lists": "5.36.0",
77
+ "@memberjunction/lists-base": "5.36.0",
78
+ "@memberjunction/notifications": "5.36.0",
79
+ "@memberjunction/postgresql-dataprovider": "5.36.0",
80
+ "@memberjunction/queue": "5.36.0",
81
+ "@memberjunction/redis-provider": "5.36.0",
82
+ "@memberjunction/scheduling-actions": "5.36.0",
83
+ "@memberjunction/scheduling-base-types": "5.36.0",
84
+ "@memberjunction/scheduling-engine": "5.36.0",
85
+ "@memberjunction/scheduling-engine-base": "5.36.0",
86
+ "@memberjunction/schema-engine": "5.36.0",
87
+ "@memberjunction/search-engine": "5.36.0",
88
+ "@memberjunction/server-extensions-core": "5.36.0",
89
+ "@memberjunction/skip-types": "5.36.0",
90
+ "@memberjunction/sql-dialect": "5.36.0",
91
+ "@memberjunction/sqlserver-dataprovider": "5.36.0",
92
+ "@memberjunction/storage": "5.36.0",
93
+ "@memberjunction/tag-engine": "5.36.0",
94
+ "@memberjunction/tag-engine-base": "5.36.0",
95
+ "@memberjunction/templates": "5.36.0",
96
+ "@memberjunction/testing-engine": "5.36.0",
97
+ "@memberjunction/testing-engine-base": "5.36.0",
98
+ "@memberjunction/version-history": "5.36.0",
97
99
  "@types/compression": "^1.8.1",
98
100
  "@types/cors": "^2.8.19",
99
101
  "@types/jsonwebtoken": "9.0.10",
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Tests for the pure boundary converters in ListOperationsResolver.
3
+ *
4
+ * The resolver itself depends on type-graphql + AppContext, which would
5
+ * require a full test harness. The converters are standalone functions
6
+ * doing the GraphQL ↔ @memberjunction/lists translation — they have no
7
+ * side effects and are the most likely site of drift if either side's
8
+ * shape changes, so they're the right test target.
9
+ */
10
+
11
+ // type-graphql decorators (`@Field`, `@InputType`, etc.) call
12
+ // `Reflect.getMetadata`, which only exists when this polyfill is loaded
13
+ // first. Vitest doesn't bring it in automatically — `import` ordering
14
+ // matters: this line MUST come before any import that pulls in the
15
+ // resolver file.
16
+ import 'reflect-metadata';
17
+
18
+ import { describe, expect, it } from 'vitest';
19
+
20
+ import type { ApplyResult, ListDelta } from '@memberjunction/lists-base';
21
+
22
+ import {
23
+ ApplyDeltaInput,
24
+ ListSourceInput,
25
+ fromCoreApplyResult,
26
+ fromCoreDelta,
27
+ fromCoreWarning,
28
+ rebuildDeltaFromInput,
29
+ toCoreSource,
30
+ } from '../resolvers/ListOperationsResolver.js';
31
+
32
+ describe('ListOperationsResolver — boundary converters', () => {
33
+ describe('toCoreSource', () => {
34
+ it('maps a list-kind input to a core ListSource', () => {
35
+ const input = Object.assign(new ListSourceInput(), { Kind: 'list', ListID: 'list-1' });
36
+ const result = toCoreSource(input);
37
+ expect(result).toEqual({ kind: 'list', listId: 'list-1' });
38
+ });
39
+
40
+ it('maps a view-kind input to a core ListSource', () => {
41
+ const input = Object.assign(new ListSourceInput(), { Kind: 'view', ViewID: 'view-1' });
42
+ expect(toCoreSource(input)).toEqual({ kind: 'view', viewId: 'view-1' });
43
+ });
44
+
45
+ it('maps an adhoc-kind input to a core ListSource', () => {
46
+ const input = Object.assign(new ListSourceInput(), {
47
+ Kind: 'adhoc',
48
+ EntityName: 'Contacts',
49
+ ExtraFilter: "Status='Active'",
50
+ });
51
+ expect(toCoreSource(input)).toEqual({
52
+ kind: 'adhoc',
53
+ entityName: 'Contacts',
54
+ extraFilter: "Status='Active'",
55
+ });
56
+ });
57
+
58
+ it('throws when list-kind input has no ListID', () => {
59
+ const input = Object.assign(new ListSourceInput(), { Kind: 'list' });
60
+ expect(() => toCoreSource(input)).toThrow(/ListID is required/);
61
+ });
62
+
63
+ it('throws when view-kind input has no ViewID', () => {
64
+ const input = Object.assign(new ListSourceInput(), { Kind: 'view' });
65
+ expect(() => toCoreSource(input)).toThrow(/ViewID is required/);
66
+ });
67
+
68
+ it('throws when adhoc-kind input lacks EntityName or ExtraFilter', () => {
69
+ const input = Object.assign(new ListSourceInput(), { Kind: 'adhoc', EntityName: 'X' });
70
+ expect(() => toCoreSource(input)).toThrow(/EntityName and ExtraFilter/);
71
+ });
72
+
73
+ it('throws on an unknown discriminator', () => {
74
+ const input = Object.assign(new ListSourceInput(), { Kind: 'mystery' as never });
75
+ expect(() => toCoreSource(input)).toThrow(/Unknown ListSourceInput\.Kind/);
76
+ });
77
+ });
78
+
79
+ describe('fromCoreDelta', () => {
80
+ it('mirrors all fields and stringifies warning details', () => {
81
+ const delta: ListDelta = {
82
+ TargetListId: 'list-1',
83
+ EntityName: 'Contacts',
84
+ ToAdd: ['a', 'b'],
85
+ ToRemove: ['c'],
86
+ Unchanged: ['d', 'e'],
87
+ Counts: { Add: 2, Remove: 1, Unchanged: 2, SourceTotal: 4, TargetTotal: 3 },
88
+ Warnings: [
89
+ { Code: 'WILL_REMOVE_RECORDS', Message: '1 record will be removed', Details: { Count: 1 } },
90
+ ],
91
+ DeltaToken: 'abc.def',
92
+ };
93
+ const output = fromCoreDelta(delta);
94
+ expect(output).toMatchObject({
95
+ TargetListId: 'list-1',
96
+ EntityName: 'Contacts',
97
+ ToAdd: ['a', 'b'],
98
+ ToRemove: ['c'],
99
+ Unchanged: ['d', 'e'],
100
+ DeltaToken: 'abc.def',
101
+ });
102
+ expect(output.Counts).toEqual(delta.Counts);
103
+ expect(output.Warnings[0]).toMatchObject({
104
+ Code: 'WILL_REMOVE_RECORDS',
105
+ Message: '1 record will be removed',
106
+ });
107
+ const parsed = JSON.parse(output.Warnings[0].DetailsJSON!);
108
+ expect(parsed).toEqual({ Count: 1 });
109
+ });
110
+ });
111
+
112
+ describe('fromCoreWarning', () => {
113
+ it('leaves DetailsJSON undefined when no details supplied', () => {
114
+ const output = fromCoreWarning({ Code: 'EMPTY_SOURCE', Message: 'No records' });
115
+ expect(output.DetailsJSON).toBeUndefined();
116
+ });
117
+ });
118
+
119
+ describe('fromCoreApplyResult', () => {
120
+ it('flattens Counts into AddedCount / RemovedCount / FailedCount', () => {
121
+ const result: ApplyResult = {
122
+ Success: true,
123
+ ResultCode: 'SUCCESS',
124
+ Message: 'OK',
125
+ TargetListId: 'list-1',
126
+ CreatedListId: 'list-1',
127
+ Counts: { Added: 5, Removed: 2, Failed: 0 },
128
+ };
129
+ const output = fromCoreApplyResult(result);
130
+ expect(output).toMatchObject({
131
+ Success: true,
132
+ ResultCode: 'SUCCESS',
133
+ AddedCount: 5,
134
+ RemovedCount: 2,
135
+ FailedCount: 0,
136
+ CreatedListId: 'list-1',
137
+ TargetListId: 'list-1',
138
+ });
139
+ });
140
+
141
+ it('preserves Errors array when present', () => {
142
+ const result: ApplyResult = {
143
+ Success: false,
144
+ ResultCode: 'PARTIAL_SUCCESS',
145
+ Message: 'partial',
146
+ Errors: ['failed record a'],
147
+ };
148
+ expect(fromCoreApplyResult(result).Errors).toEqual(['failed record a']);
149
+ });
150
+ });
151
+
152
+ describe('rebuildDeltaFromInput', () => {
153
+ it('reconstructs a core ListDelta from a flat ApplyDeltaInput', () => {
154
+ const input = Object.assign(new ApplyDeltaInput(), {
155
+ TargetListId: 'list-1',
156
+ EntityName: 'Contacts',
157
+ ToAdd: ['a'],
158
+ ToRemove: ['b'],
159
+ Unchanged: ['c'],
160
+ AddCount: 1,
161
+ RemoveCount: 1,
162
+ UnchangedCount: 1,
163
+ SourceTotal: 2,
164
+ TargetTotal: 2,
165
+ DeltaToken: 'tok',
166
+ ConfirmDrops: true,
167
+ });
168
+ const out = rebuildDeltaFromInput(input);
169
+ expect(out).toMatchObject({
170
+ TargetListId: 'list-1',
171
+ EntityName: 'Contacts',
172
+ ToAdd: ['a'],
173
+ ToRemove: ['b'],
174
+ Unchanged: ['c'],
175
+ DeltaToken: 'tok',
176
+ });
177
+ expect(out.Counts).toEqual({ Add: 1, Remove: 1, Unchanged: 1, SourceTotal: 2, TargetTotal: 2 });
178
+ // Warnings are dropped on rebuild (they don't survive the wire round-trip in either direction)
179
+ expect(out.Warnings).toEqual([]);
180
+ });
181
+ });
182
+ });