@njdamstra/appwrite-utils-cli 1.11.6 → 1.11.7
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.
|
@@ -275,6 +275,27 @@ export async function executeMigrationPlan(adapter, options) {
|
|
|
275
275
|
MessageFormatter.error(` ${entry.attributeKey}: FAILED — ${cpEntry.error}`, undefined, { prefix: "Execute" });
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
|
+
// Restore required flags after all attributes in this collection are done.
|
|
279
|
+
// This must happen AFTER all migrations to avoid partial-update validation
|
|
280
|
+
// errors (Appwrite rejects updateRow if a required attribute is missing
|
|
281
|
+
// from the payload, even for partial updates).
|
|
282
|
+
const completedRequired = entries.filter((e) => {
|
|
283
|
+
const cp = findCheckpointEntry(checkpoint, e);
|
|
284
|
+
return cp?.phase === "completed" && e.isRequired;
|
|
285
|
+
});
|
|
286
|
+
for (const entry of completedRequired) {
|
|
287
|
+
try {
|
|
288
|
+
await tryAwaitWithRetry(() => adapter.updateAttribute({
|
|
289
|
+
databaseId: entry.databaseId,
|
|
290
|
+
tableId: entry.collectionId,
|
|
291
|
+
key: entry.attributeKey,
|
|
292
|
+
required: true,
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
MessageFormatter.info(` Warning: could not set ${entry.attributeKey} back to required`, { prefix: "Execute" });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
278
299
|
// After collection completes, offer to update local YAML
|
|
279
300
|
const successInGroup = entries.filter((e) => {
|
|
280
301
|
const cp = findCheckpointEntry(checkpoint, e);
|
|
@@ -426,21 +447,8 @@ async function migrateOneAttribute(adapter, entry, cpEntry, checkpoint, checkpoi
|
|
|
426
447
|
advance("backup_deleted");
|
|
427
448
|
}
|
|
428
449
|
// Step 9: Mark completed
|
|
429
|
-
//
|
|
430
|
-
|
|
431
|
-
try {
|
|
432
|
-
await tryAwaitWithRetry(() => adapter.updateAttribute({
|
|
433
|
-
databaseId,
|
|
434
|
-
tableId: collectionId,
|
|
435
|
-
key: attributeKey,
|
|
436
|
-
required: true,
|
|
437
|
-
}));
|
|
438
|
-
}
|
|
439
|
-
catch {
|
|
440
|
-
// Non-fatal — attribute is migrated, just not set back to required
|
|
441
|
-
MessageFormatter.info(` Warning: could not set ${attributeKey} back to required`, { prefix: "Migrate" });
|
|
442
|
-
}
|
|
443
|
-
}
|
|
450
|
+
// NOTE: required flag is restored AFTER all attributes in the collection
|
|
451
|
+
// are migrated, to avoid partial-update validation errors on other attributes.
|
|
444
452
|
advance("completed");
|
|
445
453
|
}
|
|
446
454
|
// ────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@njdamstra/appwrite-utils-cli",
|
|
3
3
|
"description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
|
|
4
|
-
"version": "1.11.
|
|
4
|
+
"version": "1.11.7",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -382,6 +382,32 @@ export async function executeMigrationPlan(
|
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
|
|
385
|
+
// Restore required flags after all attributes in this collection are done.
|
|
386
|
+
// This must happen AFTER all migrations to avoid partial-update validation
|
|
387
|
+
// errors (Appwrite rejects updateRow if a required attribute is missing
|
|
388
|
+
// from the payload, even for partial updates).
|
|
389
|
+
const completedRequired = entries.filter((e) => {
|
|
390
|
+
const cp = findCheckpointEntry(checkpoint, e);
|
|
391
|
+
return cp?.phase === "completed" && e.isRequired;
|
|
392
|
+
});
|
|
393
|
+
for (const entry of completedRequired) {
|
|
394
|
+
try {
|
|
395
|
+
await tryAwaitWithRetry(() =>
|
|
396
|
+
adapter.updateAttribute({
|
|
397
|
+
databaseId: entry.databaseId,
|
|
398
|
+
tableId: entry.collectionId,
|
|
399
|
+
key: entry.attributeKey,
|
|
400
|
+
required: true,
|
|
401
|
+
} as any)
|
|
402
|
+
);
|
|
403
|
+
} catch {
|
|
404
|
+
MessageFormatter.info(
|
|
405
|
+
` Warning: could not set ${entry.attributeKey} back to required`,
|
|
406
|
+
{ prefix: "Execute" }
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
385
411
|
// After collection completes, offer to update local YAML
|
|
386
412
|
const successInGroup = entries.filter((e) => {
|
|
387
413
|
const cp = findCheckpointEntry(checkpoint, e);
|
|
@@ -630,25 +656,8 @@ async function migrateOneAttribute(
|
|
|
630
656
|
}
|
|
631
657
|
|
|
632
658
|
// Step 9: Mark completed
|
|
633
|
-
//
|
|
634
|
-
|
|
635
|
-
try {
|
|
636
|
-
await tryAwaitWithRetry(() =>
|
|
637
|
-
adapter.updateAttribute({
|
|
638
|
-
databaseId,
|
|
639
|
-
tableId: collectionId,
|
|
640
|
-
key: attributeKey,
|
|
641
|
-
required: true,
|
|
642
|
-
} as any)
|
|
643
|
-
);
|
|
644
|
-
} catch {
|
|
645
|
-
// Non-fatal — attribute is migrated, just not set back to required
|
|
646
|
-
MessageFormatter.info(
|
|
647
|
-
` Warning: could not set ${attributeKey} back to required`,
|
|
648
|
-
{ prefix: "Migrate" }
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
}
|
|
659
|
+
// NOTE: required flag is restored AFTER all attributes in the collection
|
|
660
|
+
// are migrated, to avoid partial-update validation errors on other attributes.
|
|
652
661
|
advance("completed");
|
|
653
662
|
}
|
|
654
663
|
|