@memberjunction/server 5.23.0 → 5.25.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/dist/agents/skip-sdk.d.ts +12 -0
- package/dist/agents/skip-sdk.d.ts.map +1 -1
- package/dist/agents/skip-sdk.js +70 -1
- package/dist/agents/skip-sdk.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/generated/generated.d.ts +954 -0
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +26108 -20749
- package/dist/generated/generated.js.map +1 -1
- package/dist/generic/RunViewResolver.d.ts.map +1 -1
- package/dist/generic/RunViewResolver.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resolvers/ArtifactFileResolver.d.ts +15 -0
- package/dist/resolvers/ArtifactFileResolver.d.ts.map +1 -0
- package/dist/resolvers/ArtifactFileResolver.js +74 -0
- package/dist/resolvers/ArtifactFileResolver.js.map +1 -0
- package/dist/resolvers/AutotagPipelineResolver.d.ts +23 -1
- package/dist/resolvers/AutotagPipelineResolver.d.ts.map +1 -1
- package/dist/resolvers/AutotagPipelineResolver.js +197 -13
- package/dist/resolvers/AutotagPipelineResolver.js.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.d.ts.map +1 -1
- package/dist/resolvers/FetchEntityVectorsResolver.js +6 -2
- package/dist/resolvers/FetchEntityVectorsResolver.js.map +1 -1
- package/dist/resolvers/FileResolver.d.ts.map +1 -1
- package/dist/resolvers/FileResolver.js +12 -32
- package/dist/resolvers/FileResolver.js.map +1 -1
- package/dist/resolvers/GeoResolver.d.ts +58 -0
- package/dist/resolvers/GeoResolver.d.ts.map +1 -0
- package/dist/resolvers/GeoResolver.js +302 -0
- package/dist/resolvers/GeoResolver.js.map +1 -0
- package/dist/resolvers/RunAIAgentResolver.d.ts +34 -1
- package/dist/resolvers/RunAIAgentResolver.d.ts.map +1 -1
- package/dist/resolvers/RunAIAgentResolver.js +183 -48
- package/dist/resolvers/RunAIAgentResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeResolver.d.ts +23 -41
- package/dist/resolvers/SearchKnowledgeResolver.d.ts.map +1 -1
- package/dist/resolvers/SearchKnowledgeResolver.js +133 -382
- package/dist/resolvers/SearchKnowledgeResolver.js.map +1 -1
- package/dist/resolvers/SearchKnowledgeSystemUserResolver.d.ts +19 -0
- package/dist/resolvers/SearchKnowledgeSystemUserResolver.d.ts.map +1 -0
- package/dist/resolvers/SearchKnowledgeSystemUserResolver.js +149 -0
- package/dist/resolvers/SearchKnowledgeSystemUserResolver.js.map +1 -0
- package/package.json +63 -63
- package/src/__tests__/search-knowledge-tags.test.ts +255 -0
- package/src/__tests__/skip-sdk-organic-keys.test.ts +274 -0
- package/src/agents/skip-sdk.ts +83 -2
- package/src/config.ts +11 -0
- package/src/generated/generated.ts +3690 -1
- package/src/generic/RunViewResolver.ts +1 -0
- package/src/index.ts +2 -0
- package/src/resolvers/ArtifactFileResolver.ts +71 -0
- package/src/resolvers/AutotagPipelineResolver.ts +213 -10
- package/src/resolvers/FetchEntityVectorsResolver.ts +6 -2
- package/src/resolvers/FileResolver.ts +12 -41
- package/src/resolvers/GeoResolver.ts +258 -0
- package/src/resolvers/RunAIAgentResolver.ts +229 -76
- package/src/resolvers/SearchKnowledgeResolver.ts +118 -462
- package/src/resolvers/SearchKnowledgeSystemUserResolver.ts +138 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { Resolver, Query, Arg, Ctx, ObjectType, Field, InputType, Float, Int } from 'type-graphql';
|
|
2
|
+
import { AppContext } from '../types.js';
|
|
3
|
+
import { ResolverBase } from '../generic/ResolverBase.js';
|
|
4
|
+
import { RunView, LogError, Metadata, UserInfo } from '@memberjunction/core';
|
|
5
|
+
import { MJCountryEntity, MJStateProvinceEntity } from '@memberjunction/core-entities';
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Types
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
@ObjectType()
|
|
12
|
+
export class GeoCountryResult {
|
|
13
|
+
@Field()
|
|
14
|
+
ID!: string;
|
|
15
|
+
|
|
16
|
+
@Field()
|
|
17
|
+
Name!: string;
|
|
18
|
+
|
|
19
|
+
@Field()
|
|
20
|
+
ISO2!: string;
|
|
21
|
+
|
|
22
|
+
@Field()
|
|
23
|
+
ISO3!: string;
|
|
24
|
+
|
|
25
|
+
@Field(() => Float, { nullable: true })
|
|
26
|
+
Latitude!: number | null;
|
|
27
|
+
|
|
28
|
+
@Field(() => Float, { nullable: true })
|
|
29
|
+
Longitude!: number | null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@ObjectType()
|
|
33
|
+
export class GeoStateProvinceResult {
|
|
34
|
+
@Field()
|
|
35
|
+
ID!: string;
|
|
36
|
+
|
|
37
|
+
@Field()
|
|
38
|
+
CountryID!: string;
|
|
39
|
+
|
|
40
|
+
@Field()
|
|
41
|
+
Name!: string;
|
|
42
|
+
|
|
43
|
+
@Field()
|
|
44
|
+
Code!: string;
|
|
45
|
+
|
|
46
|
+
@Field()
|
|
47
|
+
ISO3166_2!: string;
|
|
48
|
+
|
|
49
|
+
@Field(() => Float, { nullable: true })
|
|
50
|
+
Latitude!: number | null;
|
|
51
|
+
|
|
52
|
+
@Field(() => Float, { nullable: true })
|
|
53
|
+
Longitude!: number | null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@ObjectType()
|
|
57
|
+
export class GeoResolveResult {
|
|
58
|
+
@Field()
|
|
59
|
+
Success!: boolean;
|
|
60
|
+
|
|
61
|
+
@Field({ nullable: true })
|
|
62
|
+
CountryID?: string;
|
|
63
|
+
|
|
64
|
+
@Field({ nullable: true })
|
|
65
|
+
CountryName?: string;
|
|
66
|
+
|
|
67
|
+
@Field({ nullable: true })
|
|
68
|
+
StateProvinceID?: string;
|
|
69
|
+
|
|
70
|
+
@Field({ nullable: true })
|
|
71
|
+
StateProvinceName?: string;
|
|
72
|
+
|
|
73
|
+
@Field(() => Float, { nullable: true })
|
|
74
|
+
Latitude?: number;
|
|
75
|
+
|
|
76
|
+
@Field(() => Float, { nullable: true })
|
|
77
|
+
Longitude?: number;
|
|
78
|
+
|
|
79
|
+
@Field({ nullable: true })
|
|
80
|
+
ErrorMessage?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ---------------------------------------------------------------------------
|
|
84
|
+
// Resolver
|
|
85
|
+
// ---------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* GraphQL resolver for geographic reference data resolution.
|
|
89
|
+
* Provides country/state text-to-reference matching via the GeoResolver service.
|
|
90
|
+
* Used by clients that need to resolve free-text location strings to structured
|
|
91
|
+
* reference data (Country/StateProvince IDs, centroids) without a full geocoding API call.
|
|
92
|
+
*/
|
|
93
|
+
@Resolver()
|
|
94
|
+
export class GeoResolver extends ResolverBase {
|
|
95
|
+
private _countries: MJCountryEntity[] | null = null;
|
|
96
|
+
private _states: MJStateProvinceEntity[] | null = null;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Lazily load all countries into memory (~250 records).
|
|
100
|
+
*/
|
|
101
|
+
private async GetCountries(contextUser: UserInfo | undefined): Promise<MJCountryEntity[]> {
|
|
102
|
+
if (this._countries) return this._countries;
|
|
103
|
+
const rv = new RunView();
|
|
104
|
+
const result = await rv.RunView<MJCountryEntity>({
|
|
105
|
+
EntityName: 'MJ: Countries',
|
|
106
|
+
ResultType: 'entity_object'
|
|
107
|
+
}, contextUser);
|
|
108
|
+
if (result.Success) {
|
|
109
|
+
this._countries = result.Results;
|
|
110
|
+
}
|
|
111
|
+
return this._countries ?? [];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Lazily load all state/provinces into memory (~5000 records).
|
|
116
|
+
*/
|
|
117
|
+
private async GetStates(contextUser: UserInfo | undefined): Promise<MJStateProvinceEntity[]> {
|
|
118
|
+
if (this._states) return this._states;
|
|
119
|
+
const rv = new RunView();
|
|
120
|
+
const result = await rv.RunView<MJStateProvinceEntity>({
|
|
121
|
+
EntityName: 'MJ: State Provinces',
|
|
122
|
+
ResultType: 'entity_object'
|
|
123
|
+
}, contextUser);
|
|
124
|
+
if (result.Success) {
|
|
125
|
+
this._states = result.Results;
|
|
126
|
+
}
|
|
127
|
+
return this._states ?? [];
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Resolve a free-text country string to a Country reference record.
|
|
132
|
+
* Matches by Name, ISO2, ISO3, or CommonAliases.
|
|
133
|
+
*/
|
|
134
|
+
@Query(() => GeoResolveResult)
|
|
135
|
+
async ResolveCountry(
|
|
136
|
+
@Arg('input', () => String) input: string,
|
|
137
|
+
@Ctx() { userPayload }: AppContext
|
|
138
|
+
): Promise<GeoResolveResult> {
|
|
139
|
+
try {
|
|
140
|
+
const user = this.GetUserFromPayload(userPayload);
|
|
141
|
+
const countries = await this.GetCountries(user);
|
|
142
|
+
const normalized = input.trim().toLowerCase();
|
|
143
|
+
|
|
144
|
+
// 1. Exact match on Name, ISO2, ISO3
|
|
145
|
+
const exact = countries.find(c =>
|
|
146
|
+
c.Name.toLowerCase() === normalized ||
|
|
147
|
+
c.ISO2.toLowerCase() === normalized ||
|
|
148
|
+
c.ISO3.toLowerCase() === normalized
|
|
149
|
+
);
|
|
150
|
+
if (exact) {
|
|
151
|
+
return {
|
|
152
|
+
Success: true,
|
|
153
|
+
CountryID: exact.ID,
|
|
154
|
+
CountryName: exact.Name,
|
|
155
|
+
Latitude: exact.Latitude ?? undefined,
|
|
156
|
+
Longitude: exact.Longitude ?? undefined
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// 2. CommonAliases search
|
|
161
|
+
const aliasMatch = countries.find(c => {
|
|
162
|
+
if (!c.CommonAliases) return false;
|
|
163
|
+
try {
|
|
164
|
+
const aliases: string[] = JSON.parse(c.CommonAliases);
|
|
165
|
+
return aliases.some(a => a.toLowerCase() === normalized);
|
|
166
|
+
} catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
if (aliasMatch) {
|
|
171
|
+
return {
|
|
172
|
+
Success: true,
|
|
173
|
+
CountryID: aliasMatch.ID,
|
|
174
|
+
CountryName: aliasMatch.Name,
|
|
175
|
+
Latitude: aliasMatch.Latitude ?? undefined,
|
|
176
|
+
Longitude: aliasMatch.Longitude ?? undefined
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return { Success: false, ErrorMessage: `No country match for "${input}"` };
|
|
181
|
+
} catch (e: unknown) {
|
|
182
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
183
|
+
LogError(`GeoResolver.ResolveCountry error: ${msg}`);
|
|
184
|
+
return { Success: false, ErrorMessage: msg };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Resolve a free-text state/province string with country context.
|
|
190
|
+
* Country context is critical: "CA" = California (US) vs Canada (ISO2).
|
|
191
|
+
*/
|
|
192
|
+
@Query(() => GeoResolveResult)
|
|
193
|
+
async ResolveStateProvince(
|
|
194
|
+
@Arg('stateInput', () => String) stateInput: string,
|
|
195
|
+
@Arg('countryInput', () => String) countryInput: string,
|
|
196
|
+
@Ctx() { userPayload }: AppContext
|
|
197
|
+
): Promise<GeoResolveResult> {
|
|
198
|
+
try {
|
|
199
|
+
const user = this.GetUserFromPayload(userPayload);
|
|
200
|
+
|
|
201
|
+
// First resolve country
|
|
202
|
+
const countryResult = await this.ResolveCountry(countryInput, { userPayload } as AppContext);
|
|
203
|
+
if (!countryResult.Success || !countryResult.CountryID) {
|
|
204
|
+
return { Success: false, ErrorMessage: `Could not resolve country "${countryInput}"` };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const states = await this.GetStates(user);
|
|
208
|
+
const countryStates = states.filter(s => s.CountryID === countryResult.CountryID);
|
|
209
|
+
const normalized = stateInput.trim().toLowerCase();
|
|
210
|
+
|
|
211
|
+
// 1. Exact match on Name, Code, ISO3166_2
|
|
212
|
+
const exact = countryStates.find(s =>
|
|
213
|
+
s.Name.toLowerCase() === normalized ||
|
|
214
|
+
s.Code.toLowerCase() === normalized ||
|
|
215
|
+
s.ISO3166_2.toLowerCase() === normalized
|
|
216
|
+
);
|
|
217
|
+
if (exact) {
|
|
218
|
+
return {
|
|
219
|
+
Success: true,
|
|
220
|
+
CountryID: countryResult.CountryID,
|
|
221
|
+
CountryName: countryResult.CountryName,
|
|
222
|
+
StateProvinceID: exact.ID,
|
|
223
|
+
StateProvinceName: exact.Name,
|
|
224
|
+
Latitude: exact.Latitude ?? undefined,
|
|
225
|
+
Longitude: exact.Longitude ?? undefined
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// 2. CommonAliases search
|
|
230
|
+
const aliasMatch = countryStates.find(s => {
|
|
231
|
+
if (!s.CommonAliases) return false;
|
|
232
|
+
try {
|
|
233
|
+
const aliases: string[] = JSON.parse(s.CommonAliases);
|
|
234
|
+
return aliases.some(a => a.toLowerCase() === normalized);
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
if (aliasMatch) {
|
|
240
|
+
return {
|
|
241
|
+
Success: true,
|
|
242
|
+
CountryID: countryResult.CountryID,
|
|
243
|
+
CountryName: countryResult.CountryName,
|
|
244
|
+
StateProvinceID: aliasMatch.ID,
|
|
245
|
+
StateProvinceName: aliasMatch.Name,
|
|
246
|
+
Latitude: aliasMatch.Latitude ?? undefined,
|
|
247
|
+
Longitude: aliasMatch.Longitude ?? undefined
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return { Success: false, ErrorMessage: `No state/province match for "${stateInput}" in ${countryResult.CountryName}` };
|
|
252
|
+
} catch (e: unknown) {
|
|
253
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
254
|
+
LogError(`GeoResolver.ResolveStateProvince error: ${msg}`);
|
|
255
|
+
return { Success: false, ErrorMessage: msg };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|