amplifyquery 1.0.21 → 2.0.2

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 (2) hide show
  1. package/dist/service.js +75 -21
  2. package/package.json +2 -1
package/dist/service.js CHANGED
@@ -73,17 +73,25 @@ function getOwnerByAuthMode(authMode) {
73
73
  if (authMode === "userPool") {
74
74
  try {
75
75
  const { username, userId } = yield (0, auth_1.getCurrentUser)();
76
- // Canonical "owner" in Amplify is typically the Cognito user sub / userId.
77
- // Some legacy codepaths used `${userId}::${username}`. We keep it as a fallback
78
- // candidate so list-by-owner can still find older records.
79
- const canonicalOwner = userId;
80
- // Avoid useless legacy candidates like `${userId}::${userId}` (can happen depending on username config).
81
- const legacyOwner = username && userId && username !== userId ? `${userId}::${username}` : "";
82
- owner = canonicalOwner;
83
- ownerCandidates = [canonicalOwner].filter(Boolean);
84
- if (legacyOwner && legacyOwner !== canonicalOwner) {
85
- ownerCandidates.push(legacyOwner);
86
- }
76
+ // IMPORTANT:
77
+ // Amplify "owner" authorization commonly uses `cognito:username` by default,
78
+ // but some projects store `sub` (userId) instead. To avoid "refetch clears list"
79
+ // issues when using list-by-owner secondary indexes, we try multiple candidates.
80
+ //
81
+ // Candidates priority (unique, non-empty):
82
+ // - userId (sub)
83
+ // - username (cognito:username)
84
+ // - legacy `${userId}::${username}` (older patterns)
85
+ const canonicalSub = typeof userId === "string" ? userId : "";
86
+ const canonicalUsername = typeof username === "string" ? username : "";
87
+ const legacyOwner = canonicalSub && canonicalUsername && canonicalUsername !== canonicalSub
88
+ ? `${canonicalSub}::${canonicalUsername}`
89
+ : "";
90
+ // Keep `owner` for compatibility (used in some create/update paths), prefer sub.
91
+ owner = canonicalSub || canonicalUsername;
92
+ const candidates = [canonicalSub, canonicalUsername, legacyOwner].filter((v) => typeof v === "string" && v.length > 0);
93
+ // De-dupe while preserving order
94
+ ownerCandidates = Array.from(new Set(candidates));
87
95
  }
88
96
  catch (error) {
89
97
  console.error("Error getting user authentication info:", error);
@@ -667,7 +675,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
667
675
  }
668
676
  const client = (0, client_1.getClient)();
669
677
  const model = (_b = client.models) === null || _b === void 0 ? void 0 : _b[modelName];
670
- // Execute owner query (try canonical owner first, then legacy owner formats)
678
+ // Execute owner query (try multiple owner candidates)
671
679
  const ownersToTry = Array.isArray(ownerCandidates) && ownerCandidates.length > 0
672
680
  ? ownerCandidates
673
681
  : owner
@@ -690,6 +698,21 @@ function createAmplifyService(modelName, defaultAuthMode) {
690
698
  }
691
699
  // If empty, try next candidate (legacy owner format)
692
700
  }
701
+ // If owner-query returns empty for all candidates, fall back to default list().
702
+ // This prevents "data disappears on refetch" when the project stores owner using
703
+ // a different identity claim than expected (e.g., username vs sub) OR when the
704
+ // owner secondary index exists but doesn't match stored owner values.
705
+ if (!result) {
706
+ (0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned 0 items for all candidates, falling back to model.list()`, { ownersToTry, authMode });
707
+ const { data: fallback } = yield model.list({}, authModeParams);
708
+ const fallbackItems = ((fallback === null || fallback === void 0 ? void 0 : fallback.items) ||
709
+ (fallback === null || fallback === void 0 ? void 0 : fallback.data) ||
710
+ fallback ||
711
+ []).filter((item) => item !== null);
712
+ // Use the same shape below by setting `result` to array-ish
713
+ result = fallbackItems;
714
+ usedOwner = null;
715
+ }
693
716
  if (usedOwner && usedOwner !== ownersToTry[0]) {
694
717
  (0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned results only for legacy owner format`, { tried: ownersToTry, usedOwner });
695
718
  }
@@ -1122,14 +1145,13 @@ function createAmplifyService(modelName, defaultAuthMode) {
1122
1145
  // Determine auth mode (use provided options if available)
1123
1146
  const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
1124
1147
  // Get owner and parameters based on auth mode
1125
- const { owner, authModeParams } = yield getOwnerByAuthMode(authMode);
1126
- // Add owner value to queries requiring owner field when userPool auth
1148
+ const { owner, ownerCandidates, authModeParams } = yield getOwnerByAuthMode(authMode);
1149
+ // Add owner value to queries requiring owner field when userPool auth.
1150
+ // IMPORTANT: many projects store owner as `cognito:username`, not `sub`.
1151
+ // If this is an owner-based index query, try multiple owner candidates to
1152
+ // avoid returning empty results and accidentally clearing UI state on refetch.
1153
+ const isOwnerQuery = authMode === "userPool" && queryName.toLowerCase().includes("owner");
1127
1154
  const enhancedArgs = Object.assign({}, args);
1128
- if (owner &&
1129
- authMode === "userPool" &&
1130
- queryName.toLowerCase().includes("owner")) {
1131
- enhancedArgs.owner = owner;
1132
- }
1133
1155
  // Detect relational query (if fields like dailyId, userId exist)
1134
1156
  const relationField = Object.keys(enhancedArgs).find((key) => key.endsWith("Id"));
1135
1157
  const isRelationalQuery = !!relationField;
@@ -1165,8 +1187,40 @@ function createAmplifyService(modelName, defaultAuthMode) {
1165
1187
  if (!((_a = (0, client_1.getClient)().models[modelName]) === null || _a === void 0 ? void 0 : _a[queryName])) {
1166
1188
  throw new Error(`🍬 Query ${queryName} does not exist.`);
1167
1189
  }
1168
- // Execute index query - apply auth mode
1169
- const { data: result } = yield (0, client_1.getClient)().models[modelName][queryName](enhancedArgs, authModeParams);
1190
+ const model = (0, client_1.getClient)().models[modelName];
1191
+ // Execute index query - apply auth mode (with owner-candidate fallback)
1192
+ let result = null;
1193
+ if (isOwnerQuery) {
1194
+ const candidates = [
1195
+ // If caller explicitly passed owner, try that first
1196
+ typeof (args === null || args === void 0 ? void 0 : args.owner) === "string" ? args.owner : "",
1197
+ ...(Array.isArray(ownerCandidates) ? ownerCandidates : []),
1198
+ typeof owner === "string" ? owner : "",
1199
+ ].filter((v) => typeof v === "string" && v.length > 0);
1200
+ const ownersToTry = Array.from(new Set(candidates));
1201
+ if (ownersToTry.length === 0) {
1202
+ throw new Error(`🍬 owner is missing for ${modelName}.${queryName}`);
1203
+ }
1204
+ for (const candidateOwner of ownersToTry) {
1205
+ const nextArgs = Object.assign(Object.assign({}, enhancedArgs), { owner: candidateOwner });
1206
+ const { data } = yield model[queryName](nextArgs, authModeParams);
1207
+ const items = ((data === null || data === void 0 ? void 0 : data.items) || (data === null || data === void 0 ? void 0 : data.data) || data || []).filter((item) => item !== null);
1208
+ if (items.length > 0) {
1209
+ result = data;
1210
+ if (candidateOwner !== ownersToTry[0]) {
1211
+ (0, config_1.debugWarn)(`🍬 ${modelName} ${queryName}: returned results only for non-primary owner candidate`, { tried: ownersToTry, usedOwner: candidateOwner });
1212
+ }
1213
+ break;
1214
+ }
1215
+ }
1216
+ // If still empty, return empty list (do not throw unless requested)
1217
+ if (!result) {
1218
+ result = [];
1219
+ }
1220
+ }
1221
+ else {
1222
+ ({ data: result } = yield model[queryName](enhancedArgs, authModeParams));
1223
+ }
1170
1224
  // Extract result data
1171
1225
  const items = (result === null || result === void 0 ? void 0 : result.items) || (result === null || result === void 0 ? void 0 : result.data) || result || [];
1172
1226
  (0, config_1.debugLog)(`🍬 ${modelName} ${queryName} result:`, items.length, "items");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amplifyquery",
3
- "version": "1.0.21",
3
+ "version": "2.0.2",
4
4
  "description": "Amplify+Query",
5
5
  "keywords": [
6
6
  "Amplify",
@@ -29,6 +29,7 @@
29
29
  "dev": "expo-module build --watch",
30
30
  "lint": "expo-module lint",
31
31
  "typecheck": "expo-module typecheck",
32
+ "codegen:service": "node ./codegen/generateAmplifyService.js",
32
33
  "prepare": "expo-module prepare",
33
34
  "prepublishOnly": "expo-module prepublishOnly",
34
35
  "test": "expo-module test"