Skip to content

Commit

Permalink
Add taxonomy ids into context
Browse files Browse the repository at this point in the history
  • Loading branch information
JiriLojda committed Dec 8, 2023
1 parent 53a9480 commit 08e2cd0
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 7 deletions.
4 changes: 3 additions & 1 deletion src/commands/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ const importEntities = async (params: ImportEntitiesParams) => {

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

await serially(entityDefinitions.map(def => async () => {
Expand Down
27 changes: 21 additions & 6 deletions src/commands/importExportEntities/entities/taxonomies.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { TaxonomyContracts } from "@kontent-ai/management-sdk";

import { zip } from "../../../utils/array.js";
import { serially } from "../../../utils/requests.js";
import { EntityDefinition } from "../entityDefinition.js";

export const taxonomiesEntity: EntityDefinition<ReadonlyArray<TaxonomyContracts.ITaxonomyContract>> = {
name: "taxonomies",
fetchEntities: client => client.listTaxonomies().toAllPromise().then(res => res.data.items.map(t => t._raw)),
serializeEntities: taxonomies => JSON.stringify(taxonomies),
importEntities: async (client, fileTaxonomies) => {
await serially(fileTaxonomies.map(taxonomy => () =>
client
.addTaxonomy()
.withData(addExternalIds(taxonomy))
.toPromise()));
importEntities: async (client, fileTaxonomies, context) => {
const projectTaxonomies = await serially<ReadonlyArray<() => Promise<TaxonomyContracts.ITaxonomyContract>>>(
fileTaxonomies.map(taxonomy => () =>
client
.addTaxonomy()
.withData(addExternalIds(taxonomy))
.toPromise()
.then(res => res.data._raw))
);

return {
...context,
taxonomyGroupIdsByOldIds: new Map(zip(fileTaxonomies.map(t => t.id), projectTaxonomies.map(t => t.id))),
taxonomyTermIdsByOldIds: new Map(zip(fileTaxonomies.flatMap(t => t.terms), projectTaxonomies.flatMap(t => t.terms)).flatMap(extractTermIdsEntries)),
};
},
deserializeEntities: JSON.parse,
};
Expand All @@ -22,3 +32,8 @@ const addExternalIds = (taxonomy: TaxonomyContracts.ITaxonomyContract): Taxonomy
external_id: taxonomy.external_id ?? taxonomy.codename,
terms: taxonomy.terms.map(addExternalIds),
});

const extractTermIdsEntries = ([fileTaxonomy, projectTaxonomy]: readonly [TaxonomyContracts.ITaxonomyContract, TaxonomyContracts.ITaxonomyContract]): ReadonlyArray<readonly [string, string]> => [
[fileTaxonomy.id, projectTaxonomy.id] as const,
...zip(fileTaxonomy.terms, projectTaxonomy.terms).flatMap(extractTermIdsEntries),
];
4 changes: 4 additions & 0 deletions src/commands/importExportEntities/entityDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ export type EntityDefinition<T> = Readonly<{
export type ImportContext = Readonly<{
collectionIdsByOldIds: ReadonlyMap<string, string>;
languageIdsByOldIds: ReadonlyMap<string, string>;
taxonomyGroupIdsByOldIds: IdsMap;
taxonomyTermIdsByOldIds: IdsMap;
}>;

type IdsMap = ReadonlyMap<string, string>;
29 changes: 29 additions & 0 deletions src/utils/array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const zip = <T1 extends ReadonlyArray<any>, T2 extends ReadonlyArray<any>>(arr1: T1, arr2: T2): Zip<T1, T2> =>
arr1
.slice(0, Math.min(arr1.length, arr2.length))
.map((el1, i) => [el1, arr2[i]] as const) as unknown as Zip<T1, T2>;

type Zip<T1 extends ReadonlyArray<any>, T2 extends ReadonlyArray<any>> =
true extends IsEmptyTuple<T1> | IsEmptyTuple<T2>
? readonly []
: [IsNonEmptyTuple<T1>, IsNonEmptyTuple<T2>] extends [true, true]
? ZipTuples<T1, T2>
: ZipArrays<T1, T2>;

type IsEmptyTuple<T extends ReadonlyArray<any>> = T extends readonly [] ? true : false;

type IsNonEmptyTuple<T extends ReadonlyArray<any>> = T extends readonly [any, ...ReadonlyArray<any>] ? true : false;

/**
* Handles zip of two types where at least one is an array of unknown length.
*/
type ZipArrays<T1 extends ReadonlyArray<any>, T2 extends ReadonlyArray<any>> = ReadonlyArray<readonly [T1[number], T2[number]]>;

/**
* Handles zip of two tuples (arrays of known length and exact types for different positions).
* This type expects two tuples and doesn't work well with arrays of unknown length.
*/
type ZipTuples<T1 extends ReadonlyArray<any>, T2 extends ReadonlyArray<any>, Accum extends ReadonlyArray<readonly [any, any]> = readonly []> =
[T1, T2] extends [readonly [infer First1, ...infer Rest1 extends ReadonlyArray<any>], readonly [infer First2, ...infer Rest2 extends ReadonlyArray<any>]]
? ZipTuples<Rest1, Rest2, readonly [...Accum, readonly [First1, First2]]>
: Accum;

0 comments on commit 08e2cd0

Please sign in to comment.