sb-mig
Version:
CLI to rule the world. (and handle stuff related to Storyblok CMS)
134 lines (133 loc) • 4.69 kB
JavaScript
import Logger from "../../utils/logger.js";
import { getAllItemsWithPagination } from "../utils/request.js";
// POST
export const createRole = (role, config) => {
const { sbApi, spaceId } = config;
return sbApi
.post(`spaces/${spaceId}/space_roles/`, {
space_role: role,
})
.then(() => {
Logger.success(`Role '${role.role}' has been created.`);
})
.catch((err) => {
Logger.error("error happened... :(");
console.log(`${err.message} in migration of ${role.role} in createRole function`);
throw err;
});
};
// PUT
export const updateRole = (role, config) => {
const { sbApi, spaceId } = config;
return sbApi
.put(`spaces/${spaceId}/space_roles/${role.id}`, {
space_role: role,
})
.then(() => {
Logger.success(`Role '${role.role}' has been updated.`);
})
.catch((err) => {
Logger.error("error happened... :(");
console.log(`${err.message} in migration of ${role.role} in updateRole function`);
throw err;
});
};
// GET
export const getAllRoles = async (config) => {
const { sbApi, spaceId } = config;
Logger.log("Trying to get all roles.");
// TODO: All Roles doesnt support pagination...
// https://github.com/storyblok/storyblok-js-client/issues/535
return getAllItemsWithPagination({
apiFn: ({ per_page, page }) => sbApi
.get(`spaces/${spaceId}/space_roles/`, { per_page, page })
.then((res) => {
Logger.log(`Amount of roles: ${res.total}`);
return res;
})
.catch((err) => {
if (err.response.status === 404) {
Logger.error(`There is no roles in your Storyblok ${spaceId} space.`);
return true;
}
else {
Logger.error(err);
return false;
}
}),
params: {
spaceId,
},
itemsKey: "space_roles",
});
};
// GET
export const getRole = async (roleName, config) => {
Logger.log(`Trying to get '${roleName}' role.`);
return getAllRoles(config)
.then((res) => res.filter((role) => role.role === roleName))
.then((res) => {
if (Array.isArray(res) && res.length === 0) {
Logger.warning(`There is no role named '${roleName}'`);
return false;
}
return res;
})
.catch((err) => Logger.error(err));
};
export const syncRolesData = async ({ roles, dryRun }, config) => {
const result = {
created: [],
updated: [],
skipped: [],
errors: [],
};
if (dryRun) {
Logger.warning("[dry-run] Role sync will only read remote data and report planned changes.");
}
const space_roles_raw = await getAllRoles(config);
const space_roles = Array.isArray(space_roles_raw) ? space_roles_raw : [];
const rolesToUpdate = [];
const rolesToCreate = [];
for (const role of roles) {
if (!role || typeof role !== "object" || !("role" in role)) {
result.skipped.push(String(role?.role ?? "unknown"));
continue;
}
const shouldBeUpdated = space_roles.find((remoteRole) => role.role === remoteRole.role);
if (shouldBeUpdated) {
rolesToUpdate.push({ id: shouldBeUpdated.id, ...role });
}
else {
rolesToCreate.push(role);
}
}
const updateResults = dryRun
? rolesToUpdate.map(() => ({ status: "fulfilled" }))
: await Promise.allSettled(rolesToUpdate.map((role) => updateRole(role, config)));
updateResults.forEach((r, idx) => {
const name = String(rolesToUpdate[idx]?.role ?? "unknown");
if (dryRun) {
Logger.warning(`[dry-run] Would update role '${name}'.`);
}
if (r.status === "fulfilled")
result.updated.push(name);
else
result.errors.push({ name, message: String(r.reason) });
});
const createResults = dryRun
? rolesToCreate.map(() => ({ status: "fulfilled" }))
: await Promise.allSettled(rolesToCreate.map((role) => createRole(role, config)));
createResults.forEach((r, idx) => {
const name = String(rolesToCreate[idx]?.role ?? "unknown");
if (dryRun) {
Logger.warning(`[dry-run] Would create role '${name}'.`);
}
if (r.status === "fulfilled")
result.created.push(name);
else
result.errors.push({ name, message: String(r.reason) });
});
return result;
};
// File-based sync wrapper lives in `roles.sync.ts` to keep this module CJS-safe.