1
import deepDiff from 'deep-diff';
2
import type { Snapshot, SnapshotDiff } from '../types/index.js';
3
import { DiffKind } from '../types/index.js';
4
import { sanitizeCollection, sanitizeField, sanitizeRelation } from './sanitize-schema.js';
6
export function getSnapshotDiff(current: Snapshot, after: Snapshot): SnapshotDiff {
7
const diffedSnapshot: SnapshotDiff = {
9
...current.collections.map((currentCollection) => {
10
const afterCollection = after.collections.find(
11
(afterCollection) => afterCollection.collection === currentCollection.collection,
15
collection: currentCollection.collection,
16
diff: deepDiff.diff(sanitizeCollection(currentCollection), sanitizeCollection(afterCollection)),
20
.filter((afterCollection) => {
21
const currentCollection = current.collections.find(
22
(currentCollection) => currentCollection.collection === afterCollection.collection,
25
return !!currentCollection === false;
27
.map((afterCollection) => ({
28
collection: afterCollection.collection,
29
diff: deepDiff.diff(undefined, sanitizeCollection(afterCollection)),
31
].filter((obj) => Array.isArray(obj.diff)) as SnapshotDiff['collections'],
33
...current.fields.map((currentField) => {
34
const afterField = after.fields.find(
35
(afterField) => afterField.collection === currentField.collection && afterField.field === currentField.field,
38
const isAutoIncrementPrimaryKey =
39
!!currentField.schema?.is_primary_key && !!currentField.schema?.has_auto_increment;
42
collection: currentField.collection,
43
field: currentField.field,
45
sanitizeField(currentField, isAutoIncrementPrimaryKey),
46
sanitizeField(afterField, isAutoIncrementPrimaryKey),
51
.filter((afterField) => {
52
const currentField = current.fields.find(
54
currentField.collection === afterField.collection && afterField.field === currentField.field,
57
return !!currentField === false;
59
.map((afterField) => ({
60
collection: afterField.collection,
61
field: afterField.field,
62
diff: deepDiff.diff(undefined, sanitizeField(afterField)),
64
].filter((obj) => Array.isArray(obj.diff)) as SnapshotDiff['fields'],
67
...current.relations.map((currentRelation) => {
68
const afterRelation = after.relations.find(
70
afterRelation.collection === currentRelation.collection && afterRelation.field === currentRelation.field,
74
collection: currentRelation.collection,
75
field: currentRelation.field,
76
related_collection: currentRelation.related_collection,
77
diff: deepDiff.diff(sanitizeRelation(currentRelation), sanitizeRelation(afterRelation)),
81
.filter((afterRelation) => {
82
const currentRelation = current.relations.find(
84
currentRelation.collection === afterRelation.collection && afterRelation.field === currentRelation.field,
87
return !!currentRelation === false;
89
.map((afterRelation) => ({
90
collection: afterRelation.collection,
91
field: afterRelation.field,
92
related_collection: afterRelation.related_collection,
93
diff: deepDiff.diff(undefined, sanitizeRelation(afterRelation)),
95
].filter((obj) => Array.isArray(obj.diff)) as SnapshotDiff['relations'],
99
* When you delete a collection, we don't have to individually drop all the fields/relations as well
102
const deletedCollections = diffedSnapshot.collections
103
.filter((collection) => collection.diff?.[0]?.kind === DiffKind.DELETE)
104
.map(({ collection }) => collection);
106
diffedSnapshot.fields = diffedSnapshot.fields.filter(
107
(field) => deletedCollections.includes(field.collection) === false,
110
diffedSnapshot.relations = diffedSnapshot.relations.filter(
111
(relation) => deletedCollections.includes(relation.collection) === false,
114
return diffedSnapshot;