1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00
joplin/packages/lib/services/profileConfig/index.ts

118 lines
3.8 KiB
TypeScript

import { rtrimSlashes } from '../../path-utils';
import shim from '../../shim';
import { CurrentProfileVersion, defaultProfile, defaultProfileConfig, DefaultProfileId, Profile, ProfileConfig } from './types';
import { customAlphabet } from 'nanoid/non-secure';
import { _ } from '../../locale';
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
export const migrateProfileConfig = (profileConfig: any, toVersion: number): ProfileConfig => {
let version = 2;
while (profileConfig.version < toVersion) {
if (profileConfig.version === 1) {
for (const profile of profileConfig.profiles) {
if (profile.path === '.') {
profile.id = DefaultProfileId;
} else {
profile.id = profile.path.split('-').pop();
}
delete profile.path;
}
const currentProfile = profileConfig.profiles[profileConfig.currentProfile];
profileConfig.currentProfileId = currentProfile.id;
delete profileConfig.currentProfile;
}
profileConfig.version = version;
version++;
}
return profileConfig;
};
export const loadProfileConfig = async (profileConfigPath: string): Promise<ProfileConfig> => {
if (!(await shim.fsDriver().exists(profileConfigPath))) {
return defaultProfileConfig();
}
try {
const configContent = await shim.fsDriver().readFile(profileConfigPath, 'utf8');
let parsed = JSON.parse(configContent) as ProfileConfig;
if (!parsed.profiles || !parsed.profiles.length) throw new Error(`Profile config should contain at least one profile: ${profileConfigPath}`);
parsed = migrateProfileConfig(parsed, CurrentProfileVersion);
const output: ProfileConfig = {
...defaultProfileConfig(),
...parsed,
};
for (let i = 0; i < output.profiles.length; i++) {
output.profiles[i] = {
...defaultProfile(),
...output.profiles[i],
};
}
if (!output.profiles.find(p => p.id === output.currentProfileId)) throw new Error(`Current profile ID is invalid: ${output.currentProfileId}`);
return output;
} catch (error) {
error.message = `Could not parse profile configuration: ${profileConfigPath}: ${error.message}`;
throw error;
}
};
export const saveProfileConfig = async (profileConfigPath: string, config: ProfileConfig) => {
await shim.fsDriver().writeFile(profileConfigPath, JSON.stringify(config, null, '\t'), 'utf8');
};
export const getCurrentProfile = (config: ProfileConfig): Profile => {
return config.profiles.find(p => p.id === config.currentProfileId);
};
export const getProfileFullPath = (profile: Profile, rootProfilePath: string): string => {
const folderName = profile.id === DefaultProfileId ? '' : `/profile-${profile.id}`;
return `${rtrimSlashes(rootProfilePath)}${folderName}`;
};
export const isSubProfile = (profile: Profile): boolean => {
return profile.id !== DefaultProfileId;
};
const profileIdGenerator = customAlphabet('0123456789abcdefghijklmnopqrstuvwxyz', 8);
export const createNewProfile = (config: ProfileConfig, profileName: string) => {
const newConfig: ProfileConfig = {
...config,
profiles: config.profiles.slice(),
};
const newProfile: Profile = {
name: profileName,
id: profileIdGenerator(),
};
newConfig.profiles.push(newProfile);
return {
newConfig: newConfig,
newProfile: newProfile,
};
};
export const deleteProfileById = (config: ProfileConfig, profileId: string): ProfileConfig => {
if (profileId === DefaultProfileId) throw new Error(_('The default profile cannot be deleted'));
if (profileId === config.currentProfileId) throw new Error(_('The active profile cannot be deleted. Switch to a different profile and try again.'));
const newProfiles = config.profiles.filter(p => p.id !== profileId);
return {
...config,
profiles: newProfiles,
};
};
export const profileIdByIndex = (config: ProfileConfig, index: number): string => {
return config.profiles[index].id;
};