forest-cli
Version:
The Lumberjacks' toolbelt is the Forest CLI which makes easy to manage your back office application directly from the terminal.
123 lines • 10.4 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const fs_1 = require("fs");
const abstract_authenticated_command_1 = __importDefault(require("../../abstract-authenticated-command"));
const environment_manager_1 = __importDefault(require("../../services/environment-manager"));
const role_manager_1 = __importDefault(require("../../services/role-manager"));
const roles_csv_1 = require("../../services/roles-csv");
const with_current_project_1 = __importDefault(require("../../services/with-current-project"));
class RolesExportCommand extends abstract_authenticated_command_1.default {
constructor(argv, config, plan) {
super(argv, config, plan);
const { assertPresent, env } = this.context;
assertPresent({ env });
this.env = env;
}
resolveEnvByName(environments, name) {
const match = environments.find(e => e.name === name);
if (match)
return match;
const available = environments.map(e => e.name).join(', ') || '(none)';
this.logger.error(`Environment "${name}" not found in this project. Available: ${available}.`);
return this.exit(1);
}
async runAuthenticated() {
const { flags } = await this.parse(RolesExportCommand);
const config = await (0, with_current_project_1.default)({ ...this.env, projectId: flags.projectId });
try {
await this.exportRoles(config, flags.env, flags.output);
}
catch (error) {
this.surfaceApiError(error);
}
}
async exportRoles(config, envName, output) {
const environments = await new environment_manager_1.default(config).listEnvironments();
const environment = this.resolveEnvByName(environments, envName);
const roleManager = new role_manager_1.default(config);
const roleList = await roleManager.listForProject();
const fullRoles = [];
let failures = 0;
// eslint-disable-next-line no-restricted-syntax -- sequential: one fetch at a time
for (const role of roleList) {
try {
// eslint-disable-next-line no-await-in-loop
fullRoles.push(await roleManager.getRoleById(role.id));
}
catch (error) {
const { status } = error;
// Auth / server / network failures are fatal; only a per-role 4xx is skippable.
if (status === undefined || status === 401 || status === 403 || status >= 500)
throw error;
failures += 1;
this.logger.warn(`Could not fetch permissions for role "${role.name}" (id: ${role.id}): skipped (HTTP ${status}).`);
}
}
if (roleList.length > 0 && fullRoles.length === 0) {
this.logger.error(`Could not fetch permissions for any of the ${roleList.length} role(s).`);
this.exit(1);
return;
}
if (failures > 0) {
this.logger.warn(`${failures} of ${roleList.length} role(s) could not be exported.`);
}
this.writeOutput((0, roles_csv_1.formatWide)(fullRoles, environment.id), output, fullRoles.length);
}
writeOutput(csv, output, count) {
if (!output) {
process.stdout.write(csv);
process.stderr.write(`Exported ${count} role(s).\n`);
return;
}
try {
(0, fs_1.writeFileSync)(output, csv, 'utf8');
}
catch (error) {
this.logger.error(`Could not write export to "${output}": ${error.message}.`);
this.exit(1);
return;
}
process.stderr.write(`Exported ${count} role(s) to ${output}.\n`);
}
surfaceApiError(error) {
// 401/403 keep flowing to the authenticated-command handler.
const { response, status } = error;
if (response && status !== 401 && status !== 403 && response.text) {
let detail;
try {
detail = JSON.parse(response.text)?.errors?.[0]?.detail;
}
catch {
// Non-JSON error body: fall through and rethrow the original error.
}
if (detail) {
this.logger.error(detail);
this.exit(1);
return;
}
}
throw error;
}
}
exports.default = RolesExportCommand;
RolesExportCommand.description = 'Export all roles and their permissions to a wide CSV file.';
RolesExportCommand.flags = {
env: core_1.Flags.string({
char: 'e',
description: 'Environment name to export permissions for.',
required: true,
}),
projectId: core_1.Flags.integer({
char: 'p',
description: 'Forest project ID.',
}),
output: core_1.Flags.string({
char: 'o',
description: 'Output file path (default: stdout).',
}),
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbW1hbmRzL3JvbGVzL2V4cG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUVBLHNDQUFvQztBQUNwQywyQkFBbUM7QUFFbkMsMEdBQWdGO0FBQ2hGLDZGQUFvRTtBQUNwRSwrRUFBc0Q7QUFDdEQsd0RBQXNEO0FBQ3RELCtGQUFxRTtBQUlyRSxNQUFxQixrQkFBbUIsU0FBUSx3Q0FBNEI7SUFxQjFFLFlBQVksSUFBYyxFQUFFLE1BQWMsRUFBRSxJQUFLO1FBQy9DLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzFCLE1BQU0sRUFBRSxhQUFhLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM1QyxhQUFhLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxZQUEyQixFQUFFLElBQVk7UUFDaEUsTUFBTSxLQUFLLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUM7UUFDdEQsSUFBSSxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDeEIsTUFBTSxTQUFTLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksUUFBUSxDQUFDO1FBQ3ZFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixJQUFJLDJDQUEyQyxTQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQy9GLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0QixD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