@strapi/core 5.50.2 → 5.51.1

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 (29) hide show
  1. package/dist/migrations/database/5.0.0-discard-drafts.d.ts.map +1 -1
  2. package/dist/migrations/database/5.0.0-discard-drafts.js +77 -7
  3. package/dist/migrations/database/5.0.0-discard-drafts.js.map +1 -1
  4. package/dist/migrations/database/5.0.0-discard-drafts.mjs +77 -7
  5. package/dist/migrations/database/5.0.0-discard-drafts.mjs.map +1 -1
  6. package/dist/package.json.js +14 -14
  7. package/dist/package.json.mjs +14 -14
  8. package/dist/services/document-service/entries.d.ts.map +1 -1
  9. package/dist/services/document-service/entries.js +16 -2
  10. package/dist/services/document-service/entries.js.map +1 -1
  11. package/dist/services/document-service/entries.mjs +16 -2
  12. package/dist/services/document-service/entries.mjs.map +1 -1
  13. package/dist/services/document-service/first-published-at.d.ts.map +1 -1
  14. package/dist/services/document-service/first-published-at.js +9 -2
  15. package/dist/services/document-service/first-published-at.js.map +1 -1
  16. package/dist/services/document-service/first-published-at.mjs +9 -2
  17. package/dist/services/document-service/first-published-at.mjs.map +1 -1
  18. package/dist/services/entity-validator/index.d.ts +1 -0
  19. package/dist/services/entity-validator/index.d.ts.map +1 -1
  20. package/dist/services/entity-validator/index.js +152 -25
  21. package/dist/services/entity-validator/index.js.map +1 -1
  22. package/dist/services/entity-validator/index.mjs +152 -25
  23. package/dist/services/entity-validator/index.mjs.map +1 -1
  24. package/dist/services/entity-validator/validators.d.ts.map +1 -1
  25. package/dist/services/entity-validator/validators.js +6 -0
  26. package/dist/services/entity-validator/validators.js.map +1 -1
  27. package/dist/services/entity-validator/validators.mjs +6 -0
  28. package/dist/services/entity-validator/validators.mjs.map +1 -1
  29. package/package.json +14 -14
@@ -1 +1 @@
1
- {"version":3,"file":"5.0.0-discard-drafts.d.ts","sourceRoot":"","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAY5D,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9D,KAAK,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AA24G3C;;;;;GAKG;AACH,wBAAuB,iBAAiB,CAAC,EACvC,EAAE,EACF,GAAG,EACH,GAAG,EACH,gBAAuB,GACxB,EAAE;IACD,EAAE,EAAE,QAAQ,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,oDAwBA;AAED,eAAO,MAAM,qBAAqB,EAAE,SAQnC,CAAC"}
1
+ {"version":3,"file":"5.0.0-discard-drafts.d.ts","sourceRoot":"","sources":["../../../src/migrations/database/5.0.0-discard-drafts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAY5D,KAAK,eAAe,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAC9D,KAAK,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AA2+G3C;;;;;GAKG;AACH,wBAAuB,iBAAiB,CAAC,EACvC,EAAE,EACF,GAAG,EACH,GAAG,EACH,gBAAuB,GACxB,EAAE;IACD,EAAE,EAAE,QAAQ,CAAC;IACb,GAAG,EAAE,IAAI,CAAC;IACV,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,oDAwBA;AAED,eAAO,MAAM,qBAAqB,EAAE,SAQnC,CAAC"}
@@ -483,6 +483,62 @@ const recordClonedComponentPair = (clonedComponentPairsCache, componentUid, orig
483
483
  enqueueColumn(joinTable?.orderColumn, 'asc');
484
484
  enqueueColumn('id', 'asc');
485
485
  };
486
+ /**
487
+ * v4 join rows often only persisted order on one side of a bidirectional join table.
488
+ * When cloning relations for draft rows, derive missing order values from the other side
489
+ * so populate does not fall back to primary-key order.
490
+ */ const assignMissingOrderColumnFromFallback = (relations, { orderColumn, fallbackOrderColumn, groupByColumn, tieBreakerColumn })=>{
491
+ if (!orderColumn || !fallbackOrderColumn || relations.length === 0) {
492
+ return relations;
493
+ }
494
+ const byGroup = new Map();
495
+ for (const relation of relations){
496
+ const groupId = relation[groupByColumn];
497
+ const key = groupId ?? 'null';
498
+ const group = byGroup.get(key);
499
+ if (group) {
500
+ group.push(relation);
501
+ } else {
502
+ byGroup.set(key, [
503
+ relation
504
+ ]);
505
+ }
506
+ }
507
+ for (const group of byGroup.values()){
508
+ if (!group.some((relation)=>relation[orderColumn] == null)) {
509
+ continue;
510
+ }
511
+ const sorted = [
512
+ ...group
513
+ ].sort((left, right)=>{
514
+ const leftOrder = left[fallbackOrderColumn];
515
+ const rightOrder = right[fallbackOrderColumn];
516
+ if (leftOrder != null && rightOrder != null) {
517
+ if (leftOrder !== rightOrder) {
518
+ return leftOrder - rightOrder;
519
+ }
520
+ } else if (leftOrder != null) {
521
+ return -1;
522
+ } else if (rightOrder != null) {
523
+ return 1;
524
+ }
525
+ if (tieBreakerColumn) {
526
+ const leftTie = normalizeId(left[tieBreakerColumn]) ?? left[tieBreakerColumn];
527
+ const rightTie = normalizeId(right[tieBreakerColumn]) ?? right[tieBreakerColumn];
528
+ if (leftTie != null && rightTie != null && leftTie !== rightTie) {
529
+ return leftTie < rightTie ? -1 : 1;
530
+ }
531
+ }
532
+ return 0;
533
+ });
534
+ sorted.forEach((relation, index)=>{
535
+ if (relation[orderColumn] == null) {
536
+ relation[orderColumn] = index + 1;
537
+ }
538
+ });
539
+ }
540
+ return relations;
541
+ };
486
542
  /**
487
543
  * Builds a stable key for join-table relations to detect duplicates.
488
544
  * Key format: sourceId::targetId::field::componentType
@@ -494,14 +550,15 @@ const recordClonedComponentPair = (clonedComponentPairsCache, componentUid, orig
494
550
  };
495
551
  /**
496
552
  * Queries existing relations from a join table and builds a set of keys for duplicate detection.
497
- */ async function getExistingRelationKeys({ trx, joinTable, sourceColumnName, targetColumnName, sourceIds }) {
553
+ */ async function getExistingRelationKeys({ trx, joinTable, sourceColumnName, targetColumnName, filterIds, filterColumnName }) {
498
554
  const existingKeys = new Set();
499
- if (sourceIds.length === 0) {
555
+ const columnName = filterColumnName ?? sourceColumnName;
556
+ if (filterIds.length === 0) {
500
557
  return existingKeys;
501
558
  }
502
- const idChunks = chunkArray(sourceIds, getBatchSize(trx, 1000));
559
+ const idChunks = chunkArray(filterIds, getBatchSize(trx, 1000));
503
560
  for (const chunk of idChunks){
504
- const existingRelationsQuery = trx(joinTable.name).select('*').whereIn(sourceColumnName, chunk);
561
+ const existingRelationsQuery = trx(joinTable.name).select('*').whereIn(columnName, chunk);
505
562
  applyJoinTableOrdering(existingRelationsQuery, joinTable, sourceColumnName);
506
563
  const existingRelations = await existingRelationsQuery;
507
564
  for (const relation of existingRelations){
@@ -1446,7 +1503,7 @@ const debug = createDebug__default.default('strapi::migration::discard-drafts');
1446
1503
  joinTable,
1447
1504
  sourceColumnName,
1448
1505
  targetColumnName,
1449
- sourceIds: draftSourceIds
1506
+ filterIds: draftSourceIds
1450
1507
  });
1451
1508
  const relationsToInsert = newRelations.filter((relation)=>{
1452
1509
  const targetId = normalizeId(relation[targetColumnName]) ?? relation[targetColumnName];
@@ -1518,7 +1575,8 @@ const debug = createDebug__default.default('strapi::migration::discard-drafts');
1518
1575
  joinTable,
1519
1576
  sourceColumnName,
1520
1577
  targetColumnName,
1521
- sourceIds: draftTargetIds
1578
+ filterIds: draftTargetIds,
1579
+ filterColumnName: targetColumnName
1522
1580
  });
1523
1581
  const publishedIdChunks = chunkArray(publishedTargetIds, getBatchSize(trx, 1000));
1524
1582
  for (const chunk of publishedIdChunks){
@@ -1548,6 +1606,12 @@ const debug = createDebug__default.default('strapi::migration::discard-drafts');
1548
1606
  if (newRelations.length === 0) {
1549
1607
  continue;
1550
1608
  }
1609
+ assignMissingOrderColumnFromFallback(newRelations, {
1610
+ orderColumn: joinTable.inverseOrderColumnName,
1611
+ fallbackOrderColumn: joinTable.orderColumnName,
1612
+ groupByColumn: targetColumnName,
1613
+ tieBreakerColumn: sourceColumnName
1614
+ });
1551
1615
  await insertRelationsWithDuplicateHandling({
1552
1616
  trx,
1553
1617
  tableName: joinTable.name,
@@ -1663,7 +1727,7 @@ const debug = createDebug__default.default('strapi::migration::discard-drafts');
1663
1727
  joinTable,
1664
1728
  sourceColumnName,
1665
1729
  targetColumnName,
1666
- sourceIds: draftSourceIds
1730
+ filterIds: draftSourceIds
1667
1731
  });
1668
1732
  // Filter out relations that already exist
1669
1733
  const relationsToInsert = safeRelations.filter((relation)=>{
@@ -1672,6 +1736,12 @@ const debug = createDebug__default.default('strapi::migration::discard-drafts');
1672
1736
  return !existingKeys.has(key);
1673
1737
  });
1674
1738
  if (relationsToInsert.length > 0) {
1739
+ assignMissingOrderColumnFromFallback(relationsToInsert, {
1740
+ orderColumn: joinTable.orderColumnName,
1741
+ fallbackOrderColumn: joinTable.inverseOrderColumnName,
1742
+ groupByColumn: sourceColumnName,
1743
+ tieBreakerColumn: targetColumnName
1744
+ });
1675
1745
  await insertRelationsWithDuplicateHandling({
1676
1746
  trx,
1677
1747
  tableName: joinTable.name,