feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
110
packages/lib/SyncTargetRegistry.ts
普通文件
110
packages/lib/SyncTargetRegistry.ts
普通文件
@@ -0,0 +1,110 @@
|
||||
import type BaseSyncTarget from './BaseSyncTarget';
|
||||
|
||||
export interface SyncTargetInfo {
|
||||
id: number;
|
||||
name: string;
|
||||
label: string;
|
||||
supportsSelfHosted: boolean;
|
||||
supportsConfigCheck: boolean;
|
||||
supportsRecursiveLinkedNotes: boolean;
|
||||
supportsShare: boolean;
|
||||
description: string;
|
||||
classRef: typeof BaseSyncTarget;
|
||||
}
|
||||
|
||||
export default class SyncTargetRegistry {
|
||||
|
||||
private static reg_: Record<string, typeof BaseSyncTarget> = {};
|
||||
|
||||
private static get reg() {
|
||||
return this.reg_;
|
||||
}
|
||||
|
||||
public static classById(syncTargetId: number) {
|
||||
const info = SyncTargetRegistry.reg[syncTargetId];
|
||||
if (!info) throw new Error(`Invalid id: ${syncTargetId}`);
|
||||
return info;
|
||||
}
|
||||
|
||||
public static infoByName(name: string): SyncTargetInfo {
|
||||
for (const [, SyncTargetClass] of Object.entries(this.reg)) {
|
||||
if (SyncTargetClass.targetName() === name) {
|
||||
const output: SyncTargetInfo = {
|
||||
id: SyncTargetClass.id(),
|
||||
name: SyncTargetClass.targetName(),
|
||||
label: SyncTargetClass.label(),
|
||||
classRef: SyncTargetClass,
|
||||
description: SyncTargetClass.description(),
|
||||
supportsSelfHosted: SyncTargetClass.supportsSelfHosted(),
|
||||
supportsConfigCheck: SyncTargetClass.supportsConfigCheck(),
|
||||
supportsRecursiveLinkedNotes: SyncTargetClass.supportsRecursiveLinkedNotes(),
|
||||
supportsShare: SyncTargetClass.supportsShare(),
|
||||
};
|
||||
return output;
|
||||
}
|
||||
}
|
||||
throw new Error(`Unknown name: ${name}`);
|
||||
}
|
||||
|
||||
public static infoById(id: number): SyncTargetInfo {
|
||||
return this.infoByName(this.idToName(id));
|
||||
}
|
||||
|
||||
public static addClass(SyncTargetClass: typeof BaseSyncTarget) {
|
||||
this.reg[SyncTargetClass.id()] = SyncTargetClass;
|
||||
}
|
||||
|
||||
public static allIds() {
|
||||
return Object.keys(this.reg).map(key => Number(key));
|
||||
}
|
||||
|
||||
public static nameToId(name: string) {
|
||||
for (const n in this.reg) {
|
||||
if (!this.reg.hasOwnProperty(n)) continue;
|
||||
if (this.reg[n].targetName() === name) return this.reg[n].id();
|
||||
}
|
||||
throw new Error(`Name not found: ${name}. Was the sync target registered?`);
|
||||
}
|
||||
|
||||
public static idToMetadata(id: number) {
|
||||
return this.infoById(id);
|
||||
}
|
||||
|
||||
public static idToName(id: number) {
|
||||
return this.reg[id].targetName();
|
||||
}
|
||||
|
||||
public static idAndLabelPlainObject(os: string, includeKeys: string[]|null = null) {
|
||||
includeKeys ??= Object.keys(this.reg);
|
||||
|
||||
const output: Record<string, string> = {};
|
||||
for (const n of includeKeys) {
|
||||
if (!this.reg.hasOwnProperty(n)) continue;
|
||||
const info = this.infoById(this.reg[n].id());
|
||||
if (info.classRef.unsupportedPlatforms().indexOf(os) >= 0) {
|
||||
continue;
|
||||
}
|
||||
output[n] = info.label;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static optionsOrder(): string[] {
|
||||
return [
|
||||
'0', // None
|
||||
'10', // Joplin Cloud
|
||||
'7', // Dropbox
|
||||
'3', // OneDrive
|
||||
];
|
||||
}
|
||||
|
||||
public static isJoplinServerOrCloud(id: number) {
|
||||
return [
|
||||
SyncTargetRegistry.nameToId('joplinServer'),
|
||||
SyncTargetRegistry.nameToId('joplinCloud'),
|
||||
SyncTargetRegistry.nameToId('joplinServerSaml'),
|
||||
].includes(id);
|
||||
}
|
||||
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户