Files

41 lines
2.1 KiB
JavaScript
Raw Permalink Normal View History

// One-time copy of the user-authored folders into a custom data directory.
//
// `OPENCHAMBER_DATA_DIR` is documented as "the OpenChamber data directory",
// but for a long time only the flat files (settings, auth, push tokens)
// followed it while `projects/`, `themes/`, and `speech-models/` stayed under
// `~/.config/openchamber`. Now every folder hangs off the data directory, so an
// instance that already ran with a custom directory finds those folders in
// the old place. This copies each one over once: only when the new location
// does not exist yet and the old one does. It copies rather than moves
// because a second instance on the same machine (a custom directory next to
// the default one) must not strip the default instance of its projects.
const USER_DIR_ENTRIES = Object.freeze(['projects', 'themes', 'speech-models']);
const exists = async (fsPromises, target) => fsPromises.access(target).then(() => true, () => false);
/**
* Copy the user folders from `legacyRoot` into `dataDir`. Returns the entries
* copied. A no-op when the two roots are the same directory. A folder whose
* copy fails is reported through `warn` and its partial copy removed; the
* server keeps starting, reading the (empty) new location.
*/
export const migrateLegacyUserDirs = async ({ fsPromises, path, dataDir, legacyRoot, warn = () => {}, entries = USER_DIR_ENTRIES }) => {
if (path.resolve(dataDir) === path.resolve(legacyRoot)) return [];
const moved = [];
for (const entry of entries) {
const from = path.join(legacyRoot, entry);
const to = path.join(dataDir, entry);
if (await exists(fsPromises, to) || !(await exists(fsPromises, from))) continue;
try {
await fsPromises.mkdir(dataDir, { recursive: true });
await fsPromises.cp(from, to, { recursive: true, errorOnExist: true, force: false });
moved.push(entry);
} catch (error) {
await fsPromises.rm(to, { recursive: true, force: true }).catch(() => {});
warn(`Failed to copy ${from} to ${to}: ${error instanceof Error ? error.message : String(error)}`);
}
}
return moved;
};