1
import type { SchemaOverview } from '@directus/types';
2
import { version } from 'directus/version';
3
import type { Knex } from 'knex';
4
import { fromPairs, isArray, isPlainObject, mapValues, omit, sortBy, toPairs } from 'lodash-es';
5
import getDatabase, { getDatabaseClient } from '../database/index.js';
6
import { CollectionsService } from '../services/collections.js';
7
import { FieldsService } from '../services/fields.js';
8
import { RelationsService } from '../services/relations.js';
9
import type { Collection, Snapshot, SnapshotField, SnapshotRelation } from '../types/index.js';
10
import { getSchema } from './get-schema.js';
11
import { sanitizeCollection, sanitizeField, sanitizeRelation } from './sanitize-schema.js';
13
export async function getSnapshot(options?: { database?: Knex; schema?: SchemaOverview }): Promise<Snapshot> {
14
const database = options?.database ?? getDatabase();
15
const vendor = getDatabaseClient(database);
16
const schema = options?.schema ?? (await getSchema({ database, bypassCache: true }));
18
const collectionsService = new CollectionsService({ knex: database, schema });
19
const fieldsService = new FieldsService({ knex: database, schema });
20
const relationsService = new RelationsService({ knex: database, schema });
22
const [collectionsRaw, fieldsRaw, relationsRaw] = await Promise.all([
23
collectionsService.readByQuery(),
24
fieldsService.readAll(),
25
relationsService.readAll(),
28
const collectionsFiltered = collectionsRaw.filter((item: any) => excludeSystem(item));
29
const fieldsFiltered = fieldsRaw.filter((item: any) => excludeSystem(item));
30
const relationsFiltered = relationsRaw.filter((item: any) => excludeSystem(item));
32
const collectionsSorted = sortBy(mapValues(collectionsFiltered, sortDeep), ['collection']);
34
const fieldsSorted = sortBy(mapValues(fieldsFiltered, sortDeep), ['collection', 'meta.id']).map(
38
const relationsSorted = sortBy(mapValues(relationsFiltered, sortDeep), ['collection', 'meta.id']).map(
40
) as SnapshotRelation[];
46
collections: collectionsSorted.map((collection) => sanitizeCollection(collection)) as Collection[],
47
fields: fieldsSorted.map((field) => sanitizeField(field)) as SnapshotField[],
48
relations: relationsSorted.map((relation) => sanitizeRelation(relation)) as SnapshotRelation[],
52
function excludeSystem(item: { meta?: { system?: boolean } }) {
53
if (item?.meta?.system === true) return false;
57
function omitID(item: Record<string, any>) {
58
return omit(item, 'meta.id');
61
function sortDeep(raw: any): any {
62
if (isPlainObject(raw)) {
63
const mapped = mapValues(raw, sortDeep);
64
const pairs = toPairs(mapped);
65
const sorted = sortBy(pairs);
66
return fromPairs(sorted);