backend-manager 5.0.99 → 5.0.100
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/package.json
CHANGED
|
@@ -79,14 +79,17 @@ class FirestoreIndexesRequiredTest extends BaseTest {
|
|
|
79
79
|
return false;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// Strip implicit __name__ fields that Firebase adds to live indexes
|
|
83
|
+
const existingFields = (existing.fields || []).filter(f => f.fieldPath !== '__name__');
|
|
84
|
+
|
|
82
85
|
// Must have same number of fields
|
|
83
|
-
if (
|
|
86
|
+
if (existingFields.length !== required.fields.length) {
|
|
84
87
|
return false;
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
// Each field must match
|
|
88
91
|
return required.fields.every((reqField, i) => {
|
|
89
|
-
const exField =
|
|
92
|
+
const exField = existingFields[i];
|
|
90
93
|
|
|
91
94
|
if (exField.fieldPath !== reqField.fieldPath) {
|
|
92
95
|
return false;
|
|
@@ -25,10 +25,63 @@ class FirestoreIndexesSyncedTest extends BaseTest {
|
|
|
25
25
|
if (localIndexes_exists) {
|
|
26
26
|
localIndexes = require(`${self.firebaseProjectPath}/firestore.indexes.json`);
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
// Firebase adds implicit properties to live indexes (__name__ fields, density, etc.)
|
|
30
|
+
// and returns them in a different order. Normalize before comparing.
|
|
31
|
+
const normalizeIndexes = (indexes) => {
|
|
32
|
+
if (!indexes?.indexes) {
|
|
33
|
+
return indexes;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
...indexes,
|
|
37
|
+
indexes: _.sortBy(indexes.indexes.map(idx => {
|
|
38
|
+
const { density, ...rest } = idx;
|
|
39
|
+
return {
|
|
40
|
+
...rest,
|
|
41
|
+
fields: (rest.fields || []).filter(f => f.fieldPath !== '__name__'),
|
|
42
|
+
};
|
|
43
|
+
}), idx => `${idx.collectionGroup}:${(idx.fields || []).map(f => f.fieldPath).join(',')}`),
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const equal = _.isEqual(normalizeIndexes(liveIndexes), normalizeIndexes(localIndexes));
|
|
29
48
|
|
|
30
49
|
jetpack.remove(`${self.firebaseProjectPath}/${tempPath}`);
|
|
31
50
|
|
|
51
|
+
if (!equal && localIndexes_exists) {
|
|
52
|
+
// Log what differs so the user can see why (use stripped versions for accurate comparison)
|
|
53
|
+
const strippedLocal = normalizeIndexes(localIndexes);
|
|
54
|
+
const strippedLive = normalizeIndexes(liveIndexes);
|
|
55
|
+
const localOnly = _.differenceWith(strippedLocal?.indexes || [], strippedLive?.indexes || [], _.isEqual);
|
|
56
|
+
const liveOnly = _.differenceWith(strippedLive?.indexes || [], strippedLocal?.indexes || [], _.isEqual);
|
|
57
|
+
|
|
58
|
+
if (localOnly.length > 0) {
|
|
59
|
+
console.log(chalk.yellow(` Indexes in local but not live:`));
|
|
60
|
+
for (const idx of localOnly) {
|
|
61
|
+
console.log(chalk.gray(` - ${idx.collectionGroup} [${(idx.fields || []).map(f => `${f.fieldPath} ${f.order || f.arrayConfig}`).join(', ')}]`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (liveOnly.length > 0) {
|
|
65
|
+
console.log(chalk.yellow(` Indexes in live but not local:`));
|
|
66
|
+
for (const idx of liveOnly) {
|
|
67
|
+
console.log(chalk.gray(` - ${idx.collectionGroup} [${(idx.fields || []).map(f => `${f.fieldPath} ${f.order || f.arrayConfig}`).join(', ')}]`));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (localOnly.length === 0 && liveOnly.length === 0) {
|
|
71
|
+
// Indexes arrays match but fieldOverrides or other top-level keys differ
|
|
72
|
+
const localKeys = Object.keys(localIndexes || {});
|
|
73
|
+
const liveKeys = Object.keys(liveIndexes || {});
|
|
74
|
+
const allKeys = _.union(localKeys, liveKeys);
|
|
75
|
+
for (const key of allKeys) {
|
|
76
|
+
if (!_.isEqual(localIndexes?.[key], liveIndexes?.[key])) {
|
|
77
|
+
console.log(chalk.yellow(` Difference in "${key}":`));
|
|
78
|
+
console.log(chalk.gray(` Local: ${JSON.stringify(localIndexes?.[key])}`));
|
|
79
|
+
console.log(chalk.gray(` Live: ${JSON.stringify(liveIndexes?.[key])}`));
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
32
85
|
return !localIndexes_exists || equal;
|
|
33
86
|
}
|
|
34
87
|
|
|
@@ -41,14 +94,14 @@ class FirestoreIndexesSyncedTest extends BaseTest {
|
|
|
41
94
|
name: 'direction',
|
|
42
95
|
message: 'Firestore indexes are out of sync. Which direction?',
|
|
43
96
|
choices: [
|
|
44
|
-
{
|
|
45
|
-
name: `Live → Local (replace ${chalk.bold('local')} indexes with ${chalk.bold('live')})`,
|
|
46
|
-
value: 'live-to-local',
|
|
47
|
-
},
|
|
48
97
|
{
|
|
49
98
|
name: `Local → Live (replace ${chalk.bold('live')} indexes with ${chalk.bold('local')})`,
|
|
50
99
|
value: 'local-to-live',
|
|
51
100
|
},
|
|
101
|
+
{
|
|
102
|
+
name: `Live → Local (replace ${chalk.bold('local')} indexes with ${chalk.bold('live')})`,
|
|
103
|
+
value: 'live-to-local',
|
|
104
|
+
},
|
|
52
105
|
{
|
|
53
106
|
name: 'Skip',
|
|
54
107
|
value: 'skip',
|