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
这个提交包含在:
@@ -0,0 +1,50 @@
|
||||
import type { ResourceEntity } from '../../services/database/types';
|
||||
import * as mime from '../../mime-utils';
|
||||
import { filename } from '@joplin/utils/path';
|
||||
|
||||
// This file contains resource-related utilities that do not
|
||||
// depend on the database, settings, etc.
|
||||
|
||||
export const resourceFilename = (resource: ResourceEntity, encryptedBlob = false) => {
|
||||
let extension = encryptedBlob ? 'crypted' : resource.file_extension;
|
||||
if (!extension) extension = resource.mime ? mime.toFileExtension(resource.mime) : '';
|
||||
extension = extension ? `.${extension}` : '';
|
||||
const filename = resource.id + extension;
|
||||
// Defence in depth: even if a malformed id/extension reaches this point,
|
||||
// the result must be a single filename component (no path separators, no
|
||||
// parent-directory segments). BaseItem.unserialize is the primary check.
|
||||
if (/[/\\]/.test(filename) || filename.split(/[/\\]/).some(p => p === '..')) {
|
||||
throw new Error(`Invalid resource filename: ${JSON.stringify(filename)}`);
|
||||
}
|
||||
return filename;
|
||||
};
|
||||
|
||||
export const resourceRelativePath = (resource: ResourceEntity, relativeResourceDirPath: string, encryptedBlob = false) => {
|
||||
return `${relativeResourceDirPath}/${resourceFilename(resource, encryptedBlob)}`;
|
||||
};
|
||||
|
||||
export const resourceFullPath = (resource: ResourceEntity, resourceDirPath: string, encryptedBlob = false) => {
|
||||
return `${resourceDirPath}/${resourceFilename(resource, encryptedBlob)}`;
|
||||
};
|
||||
|
||||
export const internalUrl = (resource: ResourceEntity) => {
|
||||
return `:/${resource.id}`;
|
||||
};
|
||||
|
||||
export const resourcePathToId = (path: string) => {
|
||||
return filename(path);
|
||||
};
|
||||
|
||||
export const isResourceUrl = (url: string) => {
|
||||
return url && url.length === 34 && url[0] === ':' && url[1] === '/';
|
||||
};
|
||||
|
||||
export const resourceUrlToId = (url: string) => {
|
||||
if (!isResourceUrl(url)) throw new Error(`Not a valid resource URL: ${url}`);
|
||||
return url.substring(2);
|
||||
};
|
||||
|
||||
export const isSupportedImageMimeType = (type: string) => {
|
||||
const imageMimeTypes = ['image/jpg', 'image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'image/webp', 'image/avif', 'image/bmp'];
|
||||
return imageMimeTypes.indexOf(type.toLowerCase()) >= 0;
|
||||
};
|
||||
在新工单中引用
屏蔽一个用户