sb-mig
Version:
CLI to rule the world. (and handle stuff related to Storyblok CMS)
173 lines (172 loc) • 8.01 kB
JavaScript
import chalk from "chalk";
import Logger from "../../utils/logger.js";
import { isObjectEmpty } from "../../utils/object-utils.js";
import { getAllItemsWithPagination } from "../utils/request.js";
import { getDatasource } from "./datasources.js";
import { formatDatasourceApiError } from "./error-formatting.js";
const _decorateWithDimensions = async (args, config) => {
const { currentDatasource, dimensionsData, _callback } = args;
const { spaceId, sbApi } = config;
// callback for create or update
await _callback();
const dimensionValueEntries = Object.entries(dimensionsData.dimensionValues);
return dimensionValueEntries.map(([name, value]) => {
const data = dimensionsData.datasourceDimensions.find((dimension) => dimension.name === name);
const params = {
datasource_entry: {
...dimensionsData.finalDatasource_entry,
id: dimensionsData.finalDatasource_entry.datasource_id,
dimension_value: value,
},
dimension_id: data.id,
};
return sbApi
.put(`spaces/${spaceId}/datasource_entries/${dimensionsData.finalDatasource_entry.id}`, params)
.then((_) => {
console.log(`${chalk.green("✓ Datasource Entry Dimension value for")} ${chalk.blue(dimensionsData.finalDatasource_entry.name)} and dimension ${chalk.blue(name)} in ${chalk.red(currentDatasource.datasource.name)} datasource ${chalk.green("was successfully updated.")}`);
return true;
})
.catch((err) => {
Logger.error(err);
});
});
};
export const getDatasourceEntries = async (args, config) => {
const { datasourceName } = args;
const { spaceId, sbApi } = config;
Logger.log(`Trying to get '${datasourceName}' datasource entries.`);
const data = await getDatasource({ datasourceName }, config); // TODO: maybe this step is not needed, i think we can retrieve entries directly using slug (but using delivery api, not management)
if (data) {
const datasourceEntries = await getAllItemsWithPagination({
apiFn: ({ per_page, page }) => sbApi.get(`spaces/${spaceId}/datasource_entries/`, {
datasource_id: data[0].id,
per_page,
page,
}),
params: {},
itemsKey: "datasource_entries",
});
Logger.success(`Datasource Entries for '${datasourceName}' datasource successfully retrieved.`);
return { datasource_entries: datasourceEntries };
}
return { datasource_entries: [] };
};
export const createDatasourceEntries = (args, config) => {
const { datasource_entries, remoteDatasourceEntries, data, dryRun } = args;
const remoteEntries = Array.isArray(remoteDatasourceEntries?.datasource_entries)
? remoteDatasourceEntries.datasource_entries
: [];
return Promise.all(datasource_entries.map((datasourceEntry) => {
const datasourceEntryName = datasourceEntry.name ?? Object.values(datasourceEntry)[0];
const datasourceToBeUpdated = remoteEntries.find((remoteDatasourceEntry) => remoteDatasourceEntry.name === datasourceEntryName);
if (dryRun) {
const action = datasourceToBeUpdated ? "update" : "create";
Logger.warning(`[dry-run] Would ${action} datasource entry '${datasourceEntryName}' in '${data.datasource.name}' datasource.`);
return data;
}
if (datasourceToBeUpdated) {
return updateDatasourceEntry({ data, datasourceEntry, datasourceToBeUpdated }, config);
}
return createDatasourceEntry({ data, datasourceEntry }, config);
}))
.then((_) => {
if (dryRun) {
Logger.warning(`[dry-run] Datasource entries for ${data.datasource.id} datasource id were planned without API writes.`);
return data;
}
Logger.success(`Datasource entries for ${data.datasource.id} datasource id has been successfully synced.`);
return data;
})
.catch((err) => Logger.error(err));
};
const _createDatasourceEntry = (args, config) => {
const { currentDatasource, finalDatasource_entry } = args;
const { spaceId, sbApi } = config;
if (config.debug) {
console.log("############# Entity to Create: ");
console.log(finalDatasource_entry);
console.log("################################");
}
return sbApi
.post(`spaces/${spaceId}/datasource_entries/`, {
datasource_entry: finalDatasource_entry,
})
.then(({ data }) => {
console.log(`${chalk.green("✓ Datasource Entry")} ${chalk.blue(data.datasource_entry.name)} in ${chalk.red(currentDatasource.datasource.name)} datasource ${chalk.green("was successfully created.")}`);
return data;
})
.catch((err) => {
if (config.debug) {
console.log("Full Create error: ");
console.log(err);
}
Logger.error(`Unable to create datasource entry '${finalDatasource_entry.name}' in ${currentDatasource.datasource.name} datasource. Value: '${finalDatasource_entry.value}'. ${formatDatasourceApiError(err)}`);
});
};
export const createDatasourceEntry = (args, config) => {
const { datasourceEntry, data } = args;
const finalDatasource_entry = {
name: datasourceEntry.name,
value: datasourceEntry.value,
datasource_id: data.datasource.id,
};
if (isObjectEmpty(datasourceEntry.dimension_values)) {
return _createDatasourceEntry({ currentDatasource: data, finalDatasource_entry }, config);
}
else {
return _decorateWithDimensions({
currentDatasource: data,
dimensionsData: {
finalDatasource_entry,
dimensionValues: datasourceEntry.dimension_values,
datasourceDimensions: data.datasource.dimensions,
},
_callback: () => _createDatasourceEntry({ currentDatasource: data, finalDatasource_entry }, config),
}, config);
}
};
const _updateDatasourceEntry = (args, config) => {
const { currentDatasource, finalDatasource_entry } = args;
const { spaceId, sbApi } = config;
return sbApi
.put(`spaces/${spaceId}/datasource_entries/${finalDatasource_entry.id}`, {
datasource_entry: finalDatasource_entry,
})
.then((_) => {
console.log(`${chalk.green("✓ Datasource Entry")} ${chalk.blue(finalDatasource_entry.name)} in ${chalk.red(currentDatasource.datasource.name)} datasource ${chalk.green("was successfully updated.")}`);
return true;
})
.catch((err) => {
if (config.debug) {
console.log("Full update error: ");
console.log(err);
}
Logger.error(`Unable to update datasource entry '${finalDatasource_entry.name}' in ${currentDatasource.datasource.name} datasource. Value: '${finalDatasource_entry.value}'. ${formatDatasourceApiError(err)}`);
});
};
export const updateDatasourceEntry = (args, config) => {
const { datasourceEntry, datasourceToBeUpdated, data } = args;
const finalDatasource_entry = {
name: datasourceEntry.name,
value: datasourceEntry.value,
datasource_id: data.datasource.id,
id: datasourceToBeUpdated.id,
};
if (isObjectEmpty(datasourceEntry.dimension_values)) {
return _updateDatasourceEntry({ currentDatasource: data, finalDatasource_entry }, config);
}
else {
return _decorateWithDimensions({
currentDatasource: data,
_callback: () => _updateDatasourceEntry({
currentDatasource: data,
finalDatasource_entry,
}, config),
dimensionsData: {
finalDatasource_entry,
dimensionValues: datasourceEntry.dimension_values,
datasourceDimensions: data.datasource.dimensions,
},
}, config);
}
};