@memberjunction/server 5.34.0 → 5.34.1
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/generated/generated.d.ts +365 -365
- package/dist/generated/generated.d.ts.map +1 -1
- package/dist/generated/generated.js +2331 -2331
- package/dist/generated/generated.js.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.d.ts +12 -0
- package/dist/resolvers/QuerySystemUserResolver.d.ts.map +1 -1
- package/dist/resolvers/QuerySystemUserResolver.js +38 -6
- package/dist/resolvers/QuerySystemUserResolver.js.map +1 -1
- package/package.json +68 -68
- package/src/generated/generated.ts +1861 -1861
- package/src/resolvers/QuerySystemUserResolver.ts +42 -6
|
@@ -110,6 +110,9 @@ export class CreateQuerySystemUserInput {
|
|
|
110
110
|
|
|
111
111
|
@Field(() => [QueryParameterHintInput], { nullable: true })
|
|
112
112
|
ParameterHints?: QueryParameterHintInput[];
|
|
113
|
+
|
|
114
|
+
@Field(() => Boolean, { nullable: true, defaultValue: false })
|
|
115
|
+
AutoResolveCollision?: boolean;
|
|
113
116
|
}
|
|
114
117
|
|
|
115
118
|
@InputType()
|
|
@@ -250,18 +253,24 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
250
253
|
const existingQuery = await this.findExistingQuery(provider, input.Name, finalCategoryID, context.userPayload.userRecord);
|
|
251
254
|
|
|
252
255
|
if (existingQuery) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
256
|
+
if (input.AutoResolveCollision) {
|
|
257
|
+
// Server-side collision resolution: find a unique name using sequential numeric suffixes
|
|
258
|
+
input.Name = await this.findUniqueName(provider, input.Name, finalCategoryID, context.userPayload.userRecord);
|
|
259
|
+
LogStatus(`[CreateQuery] Auto-resolved name collision: "${existingQuery.Name}" -> "${input.Name}"`);
|
|
260
|
+
} else {
|
|
261
|
+
const categoryInfo = input.CategoryPath ? `category path '${input.CategoryPath}'` : `category ID '${finalCategoryID}'`;
|
|
262
|
+
return {
|
|
263
|
+
Success: false,
|
|
264
|
+
ErrorMessage: `Query with name '${input.Name}' already exists in ${categoryInfo}`
|
|
265
|
+
};
|
|
266
|
+
}
|
|
258
267
|
}
|
|
259
268
|
|
|
260
269
|
// Use MJQueryEntityServer which handles AI processing
|
|
261
270
|
const record = await provider.GetEntityObject<MJQueryEntityServer>("MJ: Queries", context.userPayload.userRecord);
|
|
262
271
|
|
|
263
272
|
// Destructure out non-database fields, keep only fields to persist
|
|
264
|
-
const { Permissions: _permissions, CategoryPath: _categoryPath, ParameterHints: _parameterHints, ...fieldsToSet } = {
|
|
273
|
+
const { Permissions: _permissions, CategoryPath: _categoryPath, ParameterHints: _parameterHints, AutoResolveCollision: _autoResolve, ...fieldsToSet } = {
|
|
265
274
|
...input,
|
|
266
275
|
CategoryID: finalCategoryID || input.CategoryID,
|
|
267
276
|
Status: input.Status || 'Approved',
|
|
@@ -734,6 +743,33 @@ export class MJQueryResolverExtended extends MJQueryResolver {
|
|
|
734
743
|
}
|
|
735
744
|
}
|
|
736
745
|
|
|
746
|
+
/**
|
|
747
|
+
* Finds a unique query name by appending sequential numeric suffixes.
|
|
748
|
+
* Format: "Name (1)", "Name (2)", etc.
|
|
749
|
+
* Uses direct DB queries (not cache) for authoritative uniqueness checks.
|
|
750
|
+
* @param provider - Database provider for direct DB queries
|
|
751
|
+
* @param baseName - The original desired name that is already taken
|
|
752
|
+
* @param categoryID - Category ID to check uniqueness within
|
|
753
|
+
* @param contextUser - User context for database operations
|
|
754
|
+
* @returns A unique name in the format "baseName (N)"
|
|
755
|
+
*/
|
|
756
|
+
private async findUniqueName(
|
|
757
|
+
provider: DatabaseProviderBase,
|
|
758
|
+
baseName: string,
|
|
759
|
+
categoryID: string | null,
|
|
760
|
+
contextUser: UserInfo
|
|
761
|
+
): Promise<string> {
|
|
762
|
+
const MAX_ATTEMPTS = 50;
|
|
763
|
+
for (let i = 1; i <= MAX_ATTEMPTS; i++) {
|
|
764
|
+
const candidateName = `${baseName} (${i})`;
|
|
765
|
+
const existing = await this.findExistingQuery(provider, candidateName, categoryID, contextUser);
|
|
766
|
+
if (!existing) {
|
|
767
|
+
return candidateName;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
throw new Error(`Unable to find unique name for "${baseName}" after ${MAX_ATTEMPTS} attempts`);
|
|
771
|
+
}
|
|
772
|
+
|
|
737
773
|
/**
|
|
738
774
|
* Finds a category by name and parent ID using RunView.
|
|
739
775
|
* Bypasses metadata cache to ensure we get the latest data from database.
|