amplifyquery 2.0.1 → 2.0.3
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/service.js +85 -21
- package/package.json +2 -1
package/dist/service.js
CHANGED
|
@@ -73,17 +73,35 @@ function getOwnerByAuthMode(authMode) {
|
|
|
73
73
|
if (authMode === "userPool") {
|
|
74
74
|
try {
|
|
75
75
|
const { username, userId } = yield (0, auth_1.getCurrentUser)();
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
76
|
+
// IMPORTANT:
|
|
77
|
+
// In this workspace we standardize on the default Amplify owner claim:
|
|
78
|
+
// `cognito:username` (i.e. `username` from getCurrentUser()).
|
|
79
|
+
//
|
|
80
|
+
// This prevents a common bug where some records are written with `sub` (userId)
|
|
81
|
+
// while the owner secondary index is queried with `username`, or vice versa,
|
|
82
|
+
// causing refetch to "lose" most items and overwrite cache with a partial list.
|
|
83
|
+
const canonicalUsername = typeof username === "string" ? username : "";
|
|
84
|
+
const canonicalSub = typeof userId === "string" ? userId : "";
|
|
85
|
+
const legacyOwner = canonicalSub && canonicalUsername && canonicalUsername !== canonicalSub
|
|
86
|
+
? `${canonicalSub}::${canonicalUsername}`
|
|
87
|
+
: "";
|
|
88
|
+
// Preferred owner value for create/update payloads.
|
|
89
|
+
owner = canonicalUsername || canonicalSub;
|
|
90
|
+
// Preferred owner candidates for list-by-owner queries.
|
|
91
|
+
// If username is available, ONLY use username-based owner to keep list results consistent.
|
|
92
|
+
// If username is missing for some reason, fall back to sub to avoid total failure.
|
|
93
|
+
const candidates = canonicalUsername
|
|
94
|
+
? [canonicalUsername, legacyOwner]
|
|
95
|
+
: [canonicalSub];
|
|
96
|
+
ownerCandidates = Array.from(new Set(candidates.filter((v) => typeof v === "string" && v.length > 0)));
|
|
97
|
+
// Debug: surface the actual Cognito identifiers in dev logs
|
|
98
|
+
(0, config_1.debugLog)(`🍬 Auth identity resolved`, {
|
|
99
|
+
authMode,
|
|
100
|
+
username,
|
|
101
|
+
userId,
|
|
102
|
+
owner,
|
|
103
|
+
ownerCandidates,
|
|
104
|
+
});
|
|
87
105
|
}
|
|
88
106
|
catch (error) {
|
|
89
107
|
console.error("Error getting user authentication info:", error);
|
|
@@ -667,7 +685,7 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
667
685
|
}
|
|
668
686
|
const client = (0, client_1.getClient)();
|
|
669
687
|
const model = (_b = client.models) === null || _b === void 0 ? void 0 : _b[modelName];
|
|
670
|
-
// Execute owner query (try
|
|
688
|
+
// Execute owner query (try multiple owner candidates)
|
|
671
689
|
const ownersToTry = Array.isArray(ownerCandidates) && ownerCandidates.length > 0
|
|
672
690
|
? ownerCandidates
|
|
673
691
|
: owner
|
|
@@ -690,6 +708,21 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
690
708
|
}
|
|
691
709
|
// If empty, try next candidate (legacy owner format)
|
|
692
710
|
}
|
|
711
|
+
// If owner-query returns empty for all candidates, fall back to default list().
|
|
712
|
+
// This prevents "data disappears on refetch" when the project stores owner using
|
|
713
|
+
// a different identity claim than expected (e.g., username vs sub) OR when the
|
|
714
|
+
// owner secondary index exists but doesn't match stored owner values.
|
|
715
|
+
if (!result) {
|
|
716
|
+
(0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned 0 items for all candidates, falling back to model.list()`, { ownersToTry, authMode });
|
|
717
|
+
const { data: fallback } = yield model.list({}, authModeParams);
|
|
718
|
+
const fallbackItems = ((fallback === null || fallback === void 0 ? void 0 : fallback.items) ||
|
|
719
|
+
(fallback === null || fallback === void 0 ? void 0 : fallback.data) ||
|
|
720
|
+
fallback ||
|
|
721
|
+
[]).filter((item) => item !== null);
|
|
722
|
+
// Use the same shape below by setting `result` to array-ish
|
|
723
|
+
result = fallbackItems;
|
|
724
|
+
usedOwner = null;
|
|
725
|
+
}
|
|
693
726
|
if (usedOwner && usedOwner !== ownersToTry[0]) {
|
|
694
727
|
(0, config_1.debugWarn)(`🍬 ${modelName} list: owner-query returned results only for legacy owner format`, { tried: ownersToTry, usedOwner });
|
|
695
728
|
}
|
|
@@ -1122,14 +1155,13 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1122
1155
|
// Determine auth mode (use provided options if available)
|
|
1123
1156
|
const authMode = (options === null || options === void 0 ? void 0 : options.authMode) || currentAuthMode;
|
|
1124
1157
|
// 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
|
|
1158
|
+
const { owner, ownerCandidates, authModeParams } = yield getOwnerByAuthMode(authMode);
|
|
1159
|
+
// Add owner value to queries requiring owner field when userPool auth.
|
|
1160
|
+
// IMPORTANT: many projects store owner as `cognito:username`, not `sub`.
|
|
1161
|
+
// If this is an owner-based index query, try multiple owner candidates to
|
|
1162
|
+
// avoid returning empty results and accidentally clearing UI state on refetch.
|
|
1163
|
+
const isOwnerQuery = authMode === "userPool" && queryName.toLowerCase().includes("owner");
|
|
1127
1164
|
const enhancedArgs = Object.assign({}, args);
|
|
1128
|
-
if (owner &&
|
|
1129
|
-
authMode === "userPool" &&
|
|
1130
|
-
queryName.toLowerCase().includes("owner")) {
|
|
1131
|
-
enhancedArgs.owner = owner;
|
|
1132
|
-
}
|
|
1133
1165
|
// Detect relational query (if fields like dailyId, userId exist)
|
|
1134
1166
|
const relationField = Object.keys(enhancedArgs).find((key) => key.endsWith("Id"));
|
|
1135
1167
|
const isRelationalQuery = !!relationField;
|
|
@@ -1165,8 +1197,40 @@ function createAmplifyService(modelName, defaultAuthMode) {
|
|
|
1165
1197
|
if (!((_a = (0, client_1.getClient)().models[modelName]) === null || _a === void 0 ? void 0 : _a[queryName])) {
|
|
1166
1198
|
throw new Error(`🍬 Query ${queryName} does not exist.`);
|
|
1167
1199
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1200
|
+
const model = (0, client_1.getClient)().models[modelName];
|
|
1201
|
+
// Execute index query - apply auth mode (with owner-candidate fallback)
|
|
1202
|
+
let result = null;
|
|
1203
|
+
if (isOwnerQuery) {
|
|
1204
|
+
const candidates = [
|
|
1205
|
+
// If caller explicitly passed owner, try that first
|
|
1206
|
+
typeof (args === null || args === void 0 ? void 0 : args.owner) === "string" ? args.owner : "",
|
|
1207
|
+
...(Array.isArray(ownerCandidates) ? ownerCandidates : []),
|
|
1208
|
+
typeof owner === "string" ? owner : "",
|
|
1209
|
+
].filter((v) => typeof v === "string" && v.length > 0);
|
|
1210
|
+
const ownersToTry = Array.from(new Set(candidates));
|
|
1211
|
+
if (ownersToTry.length === 0) {
|
|
1212
|
+
throw new Error(`🍬 owner is missing for ${modelName}.${queryName}`);
|
|
1213
|
+
}
|
|
1214
|
+
for (const candidateOwner of ownersToTry) {
|
|
1215
|
+
const nextArgs = Object.assign(Object.assign({}, enhancedArgs), { owner: candidateOwner });
|
|
1216
|
+
const { data } = yield model[queryName](nextArgs, authModeParams);
|
|
1217
|
+
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);
|
|
1218
|
+
if (items.length > 0) {
|
|
1219
|
+
result = data;
|
|
1220
|
+
if (candidateOwner !== ownersToTry[0]) {
|
|
1221
|
+
(0, config_1.debugWarn)(`🍬 ${modelName} ${queryName}: returned results only for non-primary owner candidate`, { tried: ownersToTry, usedOwner: candidateOwner });
|
|
1222
|
+
}
|
|
1223
|
+
break;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
// If still empty, return empty list (do not throw unless requested)
|
|
1227
|
+
if (!result) {
|
|
1228
|
+
result = [];
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
else {
|
|
1232
|
+
({ data: result } = yield model[queryName](enhancedArgs, authModeParams));
|
|
1233
|
+
}
|
|
1170
1234
|
// Extract result data
|
|
1171
1235
|
const items = (result === null || result === void 0 ? void 0 : result.items) || (result === null || result === void 0 ? void 0 : result.data) || result || [];
|
|
1172
1236
|
(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": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
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"
|