bgipfs
Version:
BuidlGuidl IPFS CLI
94 lines (93 loc) • 3.39 kB
JavaScript
import { promises as fs } from 'node:fs';
import path from 'node:path';
export const computeIpfsConfigChanges = (config, ownedKeys, removedKeys = []) => [
...removedKeys
.filter((key) => getNestedValue(config, key) !== undefined)
.map((key) => ({
key,
nextValue: undefined,
previousValue: getNestedValue(config, key),
type: 'remove',
})),
...Object.entries(ownedKeys)
.filter(([key, nextValue]) => !isEqual(getNestedValue(config, key), nextValue))
.map(([key, nextValue]) => ({
key,
nextValue,
previousValue: getNestedValue(config, key),
type: 'set',
})),
];
export const mergeIpfsConfig = (config, ownedKeys, removedKeys = []) => {
const merged = structuredClone(config);
for (const key of removedKeys) {
deleteNestedValue(merged, key);
}
for (const [key, value] of Object.entries(ownedKeys)) {
setNestedValue(merged, key, value);
}
return merged;
};
export const readIpfsConfig = async (configPath = 'ipfs.config.json') => {
const content = await fs.readFile(configPath, 'utf8');
const parsed = JSON.parse(content);
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
throw new Error(`${configPath} must contain a JSON object`);
}
return parsed;
};
export const readIpfsRepoVersion = async (versionPath = 'data/ipfs/version') => {
try {
const content = await fs.readFile(versionPath, 'utf8');
const version = Number.parseInt(content.trim(), 10);
return Number.isNaN(version) ? undefined : version;
}
catch {
return undefined;
}
};
export const backupIpfsConfig = async (configPath = 'ipfs.config.json', backupDir = 'config-backup') => {
await fs.mkdir(backupDir, { recursive: true });
const timestamp = new Date().toISOString().replaceAll(/[.:]/g, '-');
const backupPath = path.join(backupDir, `${path.basename(configPath)}.${timestamp}`);
await fs.copyFile(configPath, backupPath);
return backupPath;
};
export const writeIpfsConfig = async (config, configPath = 'ipfs.config.json') => {
await fs.writeFile(configPath, JSON.stringify(config, null, 2) + '\n');
};
const getNestedValue = (config, key) => {
let current = config;
for (const segment of key.split('.')) {
if (!current || typeof current !== 'object' || Array.isArray(current)) {
return undefined;
}
current = current[segment];
}
return current;
};
const setNestedValue = (config, key, value) => {
const segments = key.split('.');
let current = config;
for (const segment of segments.slice(0, -1)) {
const next = current[segment];
if (!next || typeof next !== 'object' || Array.isArray(next)) {
current[segment] = {};
}
current = current[segment];
}
current[segments.at(-1)] = value;
};
const deleteNestedValue = (config, key) => {
const segments = key.split('.');
let current = config;
for (const segment of segments.slice(0, -1)) {
const next = current[segment];
if (!next || typeof next !== 'object' || Array.isArray(next)) {
return;
}
current = next;
}
delete current[segments.at(-1)];
};
const isEqual = (left, right) => JSON.stringify(left) === JSON.stringify(right);