Skip to content

Commit

Permalink
Add context to import command and add collection ids into it
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriLojda committed Dec 7, 2023
1 parent 5aab24a commit 063a138
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 10 deletions.
11 changes: 8 additions & 3 deletions src/commands/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import JSZip from "jszip";
import { RegisterCommand } from "../types/yargs.js";
import { serially } from "../utils/requests.js";
import { collectionsEntity } from "./importExportEntities/entities/collections.js";
import { EntityDefinition } from "./importExportEntities/entityDefinition.js";
import { EntityDefinition, ImportContext } from "./importExportEntities/entityDefinition.js";

export const register: RegisterCommand = yargs => yargs.command({
command: "import <fileName> <environmentId>",
Expand Down Expand Up @@ -50,14 +50,19 @@ const importEntities = async (params: ImportEntitiesParams) => {

console.log("Importing entities...");

let context: ImportContext = {
collectionIdsByOldIds: new Map(),
};

await serially(entityDefinitions.map(def => async () => {
console.log(`Importing ${def.name}...`);

try {
await root.file(`${def.name}.json`)
context = await root.file(`${def.name}.json`)
?.async("string")
.then(def.deserializeEntities)
.then(e => def.importEntities(client, e, root));
.then(e => def.importEntities(client, e, context, root))
?? context;

console.log(`${def.name} imported`);

Expand Down
27 changes: 21 additions & 6 deletions src/commands/importExportEntities/entities/collections.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { CollectionContracts } from "@kontent-ai/management-sdk";

import { notNull } from "../../../utils/typeguards.js";
import { compareExternalIds } from "../../import/utils.js";
import { EntityDefinition } from "../entityDefinition.js";

export const collectionsEntity: EntityDefinition<ReadonlyArray<CollectionContracts.ICollectionContract>> = {
name: "collections",
fetchEntities: client => client.listCollections().toPromise().then(res => res.rawData.collections),
serializeEntities: collections => JSON.stringify(collections),
importEntities: async (client, fileCollections) => {
importEntities: async (client, fileCollections, context) => {
const existingCollections = await client.listCollections().toPromise().then(res => res.rawData.collections);
const matchResults = findCollectionMatches(fileCollections, existingCollections);
const matchErrors = matchResults.filter(isMatchError);
Expand All @@ -19,7 +20,7 @@ export const collectionsEntity: EntityDefinition<ReadonlyArray<CollectionContrac
.filter(c => !collectionsToUpdate.find(m => m.fileCollection.id === c.id))
.map((c: Collection) => ({ ...c, external_id: c.external_id ?? c.codename }));

await client
const newCollections = await client
.setCollections()
.withData([
...collectionsToUpdate.map(match => ({
Expand All @@ -37,7 +38,21 @@ export const collectionsEntity: EntityDefinition<ReadonlyArray<CollectionContrac
},
})),
])
.toPromise();
.toPromise()
.then(res => res.data.collections);

return {
...context,
collectionIdsByOldIds: new Map([
...collectionsToUpdate.map(match => [match.fileCollection.id, match.projectCollection.id] as const),
...newCollections
.map(c => {
const newC = collectionsToAdd.find(oldC => oldC.codename === c.codename);
return newC ? [c.id, newC.id] as const : null;
})
.filter(notNull),
]),
};
},
deserializeEntities: JSON.parse,
};
Expand All @@ -57,13 +72,13 @@ const isMatch = (matchResult: MatchResult): matchResult is Readonly<{ match: tru
"match" in matchResult && !!matchResult.match;

const matchCollections = (fileCollection: Collection, projectCollection: Collection): MatchResult => {
const hasSameCollection = fileCollection.codename === projectCollection.codename;
const hasSameCodename = fileCollection.codename === projectCollection.codename;
const externalIdComparison = compareExternalIds(projectCollection.external_id, fileCollection.external_id);

if (!hasSameCollection && externalIdComparison === "Same") {
if (!hasSameCodename && externalIdComparison === "Same") {
return { error: `Cannot update codename of collections. Collections with external id "${fileCollection.external_id}" have different codenames (file: "${fileCollection.codename}", project: "${projectCollection.codename}").` };
}
if (!hasSameCollection) {
if (!hasSameCodename) {
return { match: false };
}
switch (externalIdComparison) {
Expand Down
6 changes: 5 additions & 1 deletion src/commands/importExportEntities/entityDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ export type EntityDefinition<T> = Readonly<{
serializeEntities: (entities: T) => string;
addOtherFiles?: (loadedEntities: T, zip: JSZip) => Promise<void>;
deserializeEntities: (serialized: string) => T;
importEntities: (client: ManagementClient, entities: T, zip: JSZip) => Promise<void>;
importEntities: (client: ManagementClient, entities: T, context: ImportContext, zip: JSZip) => Promise<void | ImportContext>;
}>;

export type ImportContext = Readonly<{
collectionIdsByOldIds: ReadonlyMap<string, string>;
}>;
2 changes: 2 additions & 0 deletions src/utils/typeguards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const notNull = <T>(arg: T | null): arg is T =>
arg !== null;

0 comments on commit 063a138

Please sign in to comment.