@snteam/amplify-angular-core 1.0.39 → 1.0.41
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.
|
@@ -2296,11 +2296,29 @@ class AmplifyModelService {
|
|
|
2296
2296
|
selectionSetGenerator;
|
|
2297
2297
|
errorHandler;
|
|
2298
2298
|
client;
|
|
2299
|
+
relationshipConfig = null;
|
|
2299
2300
|
constructor(selectionSetGenerator, errorHandler) {
|
|
2300
2301
|
this.selectionSetGenerator = selectionSetGenerator;
|
|
2301
2302
|
this.errorHandler = errorHandler;
|
|
2302
2303
|
// Client will be initialized when Amplify is configured by the consuming application
|
|
2303
2304
|
}
|
|
2305
|
+
/**
|
|
2306
|
+
* Configure the service with relationship selection sets
|
|
2307
|
+
* This should be called by the consuming application to define how relationships should be queried
|
|
2308
|
+
*/
|
|
2309
|
+
configure(config) {
|
|
2310
|
+
if (config.relationshipSelectionSets) {
|
|
2311
|
+
this.relationshipConfig = config.relationshipSelectionSets;
|
|
2312
|
+
console.log('AmplifyModelService: Configured with relationship selection sets:', this.relationshipConfig);
|
|
2313
|
+
}
|
|
2314
|
+
}
|
|
2315
|
+
/**
|
|
2316
|
+
* Set relationship selection set configuration directly
|
|
2317
|
+
*/
|
|
2318
|
+
setRelationshipConfig(config) {
|
|
2319
|
+
this.relationshipConfig = config;
|
|
2320
|
+
console.log('AmplifyModelService: Updated relationship selection sets configuration:', this.relationshipConfig);
|
|
2321
|
+
}
|
|
2304
2322
|
/**
|
|
2305
2323
|
* Initialize the service with the Amplify client
|
|
2306
2324
|
* This should be called by the consuming application after Amplify.configure()
|
|
@@ -2486,9 +2504,8 @@ class AmplifyModelService {
|
|
|
2486
2504
|
}
|
|
2487
2505
|
}
|
|
2488
2506
|
/**
|
|
2489
|
-
*
|
|
2490
|
-
*
|
|
2491
|
-
* Enhanced with comprehensive error handling and logging
|
|
2507
|
+
* Get selection set for relationship queries using configuration
|
|
2508
|
+
* This replaces the complex dynamic generation with simple configuration lookup
|
|
2492
2509
|
* @param config Relationship configuration object
|
|
2493
2510
|
* @param baseId Base record ID (for compatibility, not used in generation)
|
|
2494
2511
|
* @returns Array of GraphQL field selectors
|
|
@@ -2496,55 +2513,88 @@ class AmplifyModelService {
|
|
|
2496
2513
|
getAmplifySelectionSet(config, baseId) {
|
|
2497
2514
|
try {
|
|
2498
2515
|
if (!config) {
|
|
2499
|
-
|
|
2500
|
-
method: 'getAmplifySelectionSet',
|
|
2501
|
-
baseId,
|
|
2502
|
-
clientAvailable: !!this.client
|
|
2503
|
-
});
|
|
2504
|
-
// Return minimal fallback
|
|
2516
|
+
console.warn('AmplifyModelService: Configuration is null or undefined, using minimal fallback');
|
|
2505
2517
|
return ['id'];
|
|
2506
2518
|
}
|
|
2507
|
-
console.log('AmplifyModelService:
|
|
2519
|
+
console.log('AmplifyModelService: Getting selection set for relationship:', {
|
|
2508
2520
|
relationshipModel: config.relationshipModelName,
|
|
2509
2521
|
fieldName: config.fieldName,
|
|
2522
|
+
baseModelName: config.baseModelName,
|
|
2523
|
+
associatedWith: config.associatedWith,
|
|
2510
2524
|
baseId
|
|
2511
2525
|
});
|
|
2512
|
-
//
|
|
2513
|
-
const
|
|
2514
|
-
if (
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
return
|
|
2526
|
+
// Try to get selection set from configuration first
|
|
2527
|
+
const configuredSelectionSet = this.getConfiguredSelectionSet(config);
|
|
2528
|
+
if (configuredSelectionSet && configuredSelectionSet.length > 0) {
|
|
2529
|
+
console.log('AmplifyModelService: Using configured selection set:', configuredSelectionSet);
|
|
2530
|
+
return configuredSelectionSet;
|
|
2531
|
+
}
|
|
2532
|
+
// Fall back to default selection set if configured
|
|
2533
|
+
if (this.relationshipConfig?.defaultSelectionSet && this.relationshipConfig.defaultSelectionSet.length > 0) {
|
|
2534
|
+
console.log('AmplifyModelService: Using default configured selection set:', this.relationshipConfig.defaultSelectionSet);
|
|
2535
|
+
return this.relationshipConfig.defaultSelectionSet;
|
|
2536
|
+
}
|
|
2537
|
+
// Fall back to dynamic generation if enabled and no configuration found
|
|
2538
|
+
if (this.relationshipConfig?.enableFallback !== false) {
|
|
2539
|
+
console.log('AmplifyModelService: No configuration found, falling back to dynamic generation');
|
|
2540
|
+
const dynamicSelectionSet = this.selectionSetGenerator.generateSelectionSet(config);
|
|
2541
|
+
if (dynamicSelectionSet && dynamicSelectionSet.length > 0) {
|
|
2542
|
+
console.log('AmplifyModelService: Using dynamic selection set:', dynamicSelectionSet);
|
|
2543
|
+
return dynamicSelectionSet;
|
|
2544
|
+
}
|
|
2522
2545
|
}
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
});
|
|
2528
|
-
return selectionSet;
|
|
2546
|
+
// Final fallback - use a simple, predictable selection set
|
|
2547
|
+
const fallbackSelectionSet = this.generateSimpleFallbackSelectionSet(config);
|
|
2548
|
+
console.log('AmplifyModelService: Using simple fallback selection set:', fallbackSelectionSet);
|
|
2549
|
+
return fallbackSelectionSet;
|
|
2529
2550
|
}
|
|
2530
2551
|
catch (error) {
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2552
|
+
console.error('AmplifyModelService: Error getting selection set, using minimal fallback:', error);
|
|
2553
|
+
return ['id'];
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
/**
|
|
2557
|
+
* Get configured selection set for a specific relationship
|
|
2558
|
+
*/
|
|
2559
|
+
getConfiguredSelectionSet(config) {
|
|
2560
|
+
if (!this.relationshipConfig?.relationships) {
|
|
2561
|
+
return null;
|
|
2562
|
+
}
|
|
2563
|
+
// Look for exact match first
|
|
2564
|
+
const exactMatch = this.relationshipConfig.relationships.find(rel => rel.relationshipModel === config.relationshipModelName &&
|
|
2565
|
+
rel.fieldName === config.fieldName);
|
|
2566
|
+
if (exactMatch) {
|
|
2567
|
+
console.log('AmplifyModelService: Found exact configuration match:', exactMatch);
|
|
2568
|
+
return exactMatch.selectionSet;
|
|
2569
|
+
}
|
|
2570
|
+
// Look for relationship model match
|
|
2571
|
+
const modelMatch = this.relationshipConfig.relationships.find(rel => rel.relationshipModel === config.relationshipModelName);
|
|
2572
|
+
if (modelMatch) {
|
|
2573
|
+
console.log('AmplifyModelService: Found relationship model match:', modelMatch);
|
|
2574
|
+
return modelMatch.selectionSet;
|
|
2575
|
+
}
|
|
2576
|
+
// Look for field name match
|
|
2577
|
+
const fieldMatch = this.relationshipConfig.relationships.find(rel => rel.fieldName === config.fieldName);
|
|
2578
|
+
if (fieldMatch) {
|
|
2579
|
+
console.log('AmplifyModelService: Found field name match:', fieldMatch);
|
|
2580
|
+
return fieldMatch.selectionSet;
|
|
2581
|
+
}
|
|
2582
|
+
return null;
|
|
2583
|
+
}
|
|
2584
|
+
/**
|
|
2585
|
+
* Generate a simple, predictable fallback selection set
|
|
2586
|
+
*/
|
|
2587
|
+
generateSimpleFallbackSelectionSet(config) {
|
|
2588
|
+
const selectionSet = ['id'];
|
|
2589
|
+
if (config.fieldName) {
|
|
2590
|
+
// Add the relationship field itself
|
|
2591
|
+
selectionSet.push(config.fieldName);
|
|
2592
|
+
// Add common nested fields
|
|
2593
|
+
selectionSet.push(`${config.fieldName}.id`);
|
|
2594
|
+
selectionSet.push(`${config.fieldName}.name`);
|
|
2595
|
+
selectionSet.push(`${config.fieldName}.title`);
|
|
2547
2596
|
}
|
|
2597
|
+
return selectionSet;
|
|
2548
2598
|
}
|
|
2549
2599
|
setRelatedSub(config, baseId) {
|
|
2550
2600
|
if (!this.client) {
|
|
@@ -2748,104 +2798,43 @@ class AmplifyModelService {
|
|
|
2748
2798
|
}
|
|
2749
2799
|
/**
|
|
2750
2800
|
* Validate that relationship field data is populated in query results
|
|
2751
|
-
*
|
|
2801
|
+
* Simplified validation that's more predictable and easier to debug
|
|
2752
2802
|
*/
|
|
2753
2803
|
validateRelationshipFieldPopulation(result, config) {
|
|
2754
2804
|
try {
|
|
2755
2805
|
if (!result || !result.data) {
|
|
2756
|
-
|
|
2757
|
-
method: 'validateRelationshipFieldPopulation',
|
|
2758
|
-
hasResult: !!result,
|
|
2759
|
-
hasData: !!(result?.data)
|
|
2760
|
-
});
|
|
2806
|
+
console.warn('AmplifyModelService: Query result is missing or has no data property');
|
|
2761
2807
|
return false;
|
|
2762
2808
|
}
|
|
2763
|
-
// Check if any records have the relationship field populated
|
|
2764
2809
|
const records = Array.isArray(result.data) ? result.data : [result.data];
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
populatedCount++;
|
|
2780
|
-
}
|
|
2781
|
-
// If it's an empty object or array, consider it partially populated
|
|
2782
|
-
else {
|
|
2783
|
-
partiallyPopulatedCount++;
|
|
2784
|
-
}
|
|
2785
|
-
}
|
|
2786
|
-
// Also check if the record has any nested relationship data
|
|
2787
|
-
// This handles cases where the selection set includes nested fields like "table.id", "table.name"
|
|
2788
|
-
const hasNestedRelationshipData = this.hasNestedRelationshipData(record, config.fieldName);
|
|
2789
|
-
if (hasNestedRelationshipData) {
|
|
2790
|
-
populatedCount++;
|
|
2810
|
+
if (records.length === 0) {
|
|
2811
|
+
console.warn('AmplifyModelService: No records returned from query');
|
|
2812
|
+
return false;
|
|
2813
|
+
}
|
|
2814
|
+
console.log(`AmplifyModelService: Validating relationship field '${config.fieldName}' in ${records.length} records`);
|
|
2815
|
+
// Simple validation: if we have records, consider it successful
|
|
2816
|
+
// The actual relationship data validation will happen at the UI level
|
|
2817
|
+
let hasAnyData = false;
|
|
2818
|
+
for (let i = 0; i < records.length; i++) {
|
|
2819
|
+
const record = records[i];
|
|
2820
|
+
if (record && typeof record === 'object' && Object.keys(record).length > 0) {
|
|
2821
|
+
hasAnyData = true;
|
|
2822
|
+
console.log(`AmplifyModelService: Record ${i} has data:`, Object.keys(record));
|
|
2823
|
+
break;
|
|
2791
2824
|
}
|
|
2792
2825
|
}
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
if (totalValidRecords === 0) {
|
|
2796
|
-
// Log detailed information about what we found
|
|
2797
|
-
this.errorHandler.logSelectionSetError(SelectionSetErrorType.FIELD_NOT_FOUND, `No records have relationship field '${config.fieldName}' populated`, config, undefined, {
|
|
2798
|
-
method: 'validateRelationshipFieldPopulation',
|
|
2799
|
-
recordCount: records.length,
|
|
2800
|
-
populatedCount,
|
|
2801
|
-
partiallyPopulatedCount,
|
|
2802
|
-
sampleRecord: records[0] ? Object.keys(records[0]) : [],
|
|
2803
|
-
sampleRecordData: records[0] ? records[0] : null,
|
|
2804
|
-
fieldName: config.fieldName,
|
|
2805
|
-
relationshipFieldValue: records[0] ? records[0][config.fieldName] : undefined
|
|
2806
|
-
});
|
|
2807
|
-
console.warn(`AmplifyModelService: No records have relationship field '${config.fieldName}' populated`, {
|
|
2808
|
-
config,
|
|
2809
|
-
recordCount: records.length,
|
|
2810
|
-
sampleRecord: records[0],
|
|
2811
|
-
sampleRelationshipValue: records[0] ? records[0][config.fieldName] : undefined
|
|
2812
|
-
});
|
|
2826
|
+
if (!hasAnyData) {
|
|
2827
|
+
console.warn('AmplifyModelService: No valid records found in query result');
|
|
2813
2828
|
return false;
|
|
2814
2829
|
}
|
|
2815
|
-
console.log(`AmplifyModelService: Relationship
|
|
2830
|
+
console.log(`AmplifyModelService: Relationship validation successful - found ${records.length} records with data`);
|
|
2816
2831
|
return true;
|
|
2817
2832
|
}
|
|
2818
2833
|
catch (error) {
|
|
2819
|
-
this.errorHandler.logSelectionSetError(SelectionSetErrorType.GRAPHQL_ERROR, `Error validating relationship field population: ${error instanceof Error ? error.message : String(error)}`, config, undefined, {
|
|
2820
|
-
method: 'validateRelationshipFieldPopulation',
|
|
2821
|
-
originalError: {
|
|
2822
|
-
message: error instanceof Error ? error.message : String(error),
|
|
2823
|
-
stack: error instanceof Error ? error.stack : undefined
|
|
2824
|
-
}
|
|
2825
|
-
});
|
|
2826
2834
|
console.error('AmplifyModelService: Error validating relationship field population:', error);
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
}
|
|
2830
|
-
/**
|
|
2831
|
-
* Check if a record has nested relationship data based on field patterns
|
|
2832
|
-
* This helps validate cases where selection sets use nested field access like "table.id", "table.name"
|
|
2833
|
-
*/
|
|
2834
|
-
hasNestedRelationshipData(record, fieldName) {
|
|
2835
|
-
if (!record || typeof record !== 'object') {
|
|
2836
|
-
return false;
|
|
2837
|
-
}
|
|
2838
|
-
// Look for any fields that start with the relationship field name followed by a dot
|
|
2839
|
-
const nestedFieldPattern = `${fieldName}.`;
|
|
2840
|
-
for (const key of Object.keys(record)) {
|
|
2841
|
-
if (key.startsWith(nestedFieldPattern)) {
|
|
2842
|
-
const value = record[key];
|
|
2843
|
-
if (value !== undefined && value !== null) {
|
|
2844
|
-
return true;
|
|
2845
|
-
}
|
|
2846
|
-
}
|
|
2835
|
+
// Be permissive on validation errors
|
|
2836
|
+
return true;
|
|
2847
2837
|
}
|
|
2848
|
-
return false;
|
|
2849
2838
|
}
|
|
2850
2839
|
/**
|
|
2851
2840
|
* Log query attempt details
|