feat: custom CDN for GitHub storage (#172) (#174)

Co-authored-by: Innei <tukon479@gmail.com>
This commit is contained in:
Chrys
2025-11-30 23:36:05 +08:00
committed by GitHub
parent 7b02aeaba6
commit a4ed1ecbc2
11 changed files with 107 additions and 2 deletions

View File

@@ -74,6 +74,37 @@ useRawUrl: true
This provides faster access and better caching for public repositories.
## Custom CDN Domain
For faster access in regions where `raw.githubusercontent.com` is slow, you can configure a custom CDN:
```typescript
import { defineBuilderConfig } from '@afilmory/builder'
export default defineBuilderConfig(() => ({
storage: {
provider: 'github',
owner: 'your-username',
repo: 'photo-storage',
branch: 'main',
path: 'photos',
// Use jsDelivr CDN instead of raw.githubusercontent.com
customDomain: 'cdn.jsdelivr.net/gh/your-username/photo-storage@main',
},
}))
```
**Popular CDN options:**
- **jsDelivr**: `cdn.jsdelivr.net/gh/owner/repo@branch`
- **Statically**: `cdn.statically.io/gh/owner/repo/branch`
- **Custom proxy**: Your own CDN proxy domain
When `customDomain` is set, it takes precedence over `useRawUrl`. The generated URL will be:
```
https://{customDomain}/{path}/{filename}
```
## Private Repositories
For private repositories:

View File

@@ -457,6 +457,12 @@ const enUiSchema = {
description: 'Optional path within the repository to limit syncing.',
placeholder: 'public/photos',
},
'custom-domain': {
label: 'Custom CDN domain',
description: 'CDN or proxy domain used when generating public URLs.',
placeholder: 'cdn.jsdelivr.net/gh/owner/repo@branch',
helper: 'Leave empty to keep raw.githubusercontent.com URLs.',
},
'use-raw': {
label: 'Use raw URL',
description: 'Use raw.githubusercontent.com when generating public URLs.',

View File

@@ -451,6 +451,12 @@ const zhCnUiSchema = {
description: '可选,限制同步的仓库路径。',
placeholder: 'public/photos可选',
},
'custom-domain': {
label: '自定义 CDN 域名',
description: '用于生成公开链接的 CDN 或代理域名。',
placeholder: 'cdn.jsdelivr.net/gh/owner/repo@branch示例',
helper: '留空则继续使用 raw.githubusercontent.com。',
},
'use-raw': {
label: '使用 raw 链接',
description: '生成公开链接时使用 raw.githubusercontent.com。',

View File

@@ -135,6 +135,13 @@ const STORAGE_PROVIDER_FIELD_CONFIG: Record<StorageProviderType, readonly Storag
placeholderKey: 'storage.providers.fields.github.path.placeholder',
descriptionKey: 'storage.providers.fields.github.path.description',
},
{
key: 'customDomain',
labelKey: 'storage.providers.fields.github.custom-domain.label',
placeholderKey: 'storage.providers.fields.github.custom-domain.placeholder',
descriptionKey: 'storage.providers.fields.github.custom-domain.description',
helperKey: 'storage.providers.fields.github.custom-domain.helper',
},
{
key: 'useRawUrl',
labelKey: 'storage.providers.fields.github.use-raw.label',

View File

@@ -191,6 +191,8 @@ export class PhotoStorageService {
if (pathValue) result.path = pathValue
const useRawUrl = parseBoolean(config.useRawUrl)
if (typeof useRawUrl === 'boolean') result.useRawUrl = useRawUrl
const customDomain = normalizeStringToUndefined(config.customDomain)
if (customDomain) result.customDomain = customDomain
return result
}

View File

@@ -46,6 +46,7 @@ const githubConfigSchema = z.object({
branch: z.string().optional(),
token: z.string().optional(),
path: z.string().optional(),
customDomain: z.string().optional(),
useRawUrl: z.boolean().optional(),
})

View File

@@ -614,6 +614,10 @@
"storage.providers.fields.github.branch.helper": "Defaults to master/main. Provide the full branch name if it differs.",
"storage.providers.fields.github.branch.label": "Branch",
"storage.providers.fields.github.branch.placeholder": "main",
"storage.providers.fields.github.custom-domain.description": "CDN or proxy domain used when generating public URLs.",
"storage.providers.fields.github.custom-domain.helper": "Leave blank to keep raw.githubusercontent.com URLs.",
"storage.providers.fields.github.custom-domain.label": "Custom CDN domain",
"storage.providers.fields.github.custom-domain.placeholder": "cdn.jsdelivr.net/gh/owner/repo@branch",
"storage.providers.fields.github.owner.description": "GitHub user or organization name.",
"storage.providers.fields.github.owner.label": "Repository owner",
"storage.providers.fields.github.owner.placeholder": "afilmory",
@@ -865,4 +869,4 @@
"welcome.tenant-restricted.register": "Create a new space",
"welcome.tenant-restricted.request": "Requested host:",
"welcome.tenant-restricted.title": "Space Reserved"
}
}

View File

@@ -613,6 +613,10 @@
"storage.providers.fields.github.branch.helper": "默认 master/main如有不同请填写完整分支名。",
"storage.providers.fields.github.branch.label": "分支",
"storage.providers.fields.github.branch.placeholder": "main示例",
"storage.providers.fields.github.custom-domain.description": "用于生成公开链接的 CDN 或代理域名。",
"storage.providers.fields.github.custom-domain.helper": "留空则继续使用 raw.githubusercontent.com。",
"storage.providers.fields.github.custom-domain.label": "自定义 CDN 域名",
"storage.providers.fields.github.custom-domain.placeholder": "cdn.jsdelivr.net/gh/owner/repo@branch示例",
"storage.providers.fields.github.owner.description": "GitHub 用户或组织名称。",
"storage.providers.fields.github.owner.label": "仓库拥有者",
"storage.providers.fields.github.owner.placeholder": "afilmory示例",
@@ -857,4 +861,4 @@
"welcome.tenant-restricted.register": "创建新空间",
"welcome.tenant-restricted.request": "请求的主机:",
"welcome.tenant-restricted.title": "空间已被保留"
}
}

View File

@@ -170,6 +170,14 @@ export type GitHubConfig = {
token?: string
path?: string
useRawUrl?: boolean
/**
* Optional custom CDN domain for generated URLs.
* When set, URLs will use this domain instead of raw.githubusercontent.com.
* Useful for jsDelivr, Cloudflare CDN, or other GitHub CDN proxies.
* @example 'cdn.jsdelivr.net/gh/owner/repo@branch'
* @example 'cdn.example.com'
*/
customDomain?: string
}
export type LocalConfig = {

View File

@@ -96,9 +96,38 @@ const githubConfig: StorageConfig = {
token: 'ghp_xxxxxxxxxxxx', // GitHub 访问令牌(可选)
path: 'photos', // 照片存储路径(可选)
useRawUrl: true, // 使用 raw.githubusercontent.com默认 true
customDomain: 'cdn.jsdelivr.net/gh/your-username/photo-gallery@main', // 自定义 CDN 域名(可选)
}
```
### 自定义 CDN 域名
如果 `raw.githubusercontent.com` 在你的地区访问速度较慢,可以配置自定义 CDN
```typescript
const githubConfig: StorageConfig = {
provider: 'github',
owner: 'your-username',
repo: 'photo-gallery',
branch: 'main',
path: 'photos',
// 使用 jsDelivr CDN
customDomain: 'cdn.jsdelivr.net/gh/your-username/photo-gallery@main',
}
```
**常用 CDN 选项:**
- **jsDelivr**: `cdn.jsdelivr.net/gh/owner/repo@branch`
- **Statically**: `cdn.statically.io/gh/owner/repo/branch`
- **自定义代理**: 你自己的 CDN 代理域名
当配置了 `customDomain` 时,它会优先于 `useRawUrl`。生成的 URL 格式为:
```
https://{customDomain}/{path}/{filename}
```
### 设置步骤
1. **创建 GitHub 仓库**
@@ -123,6 +152,7 @@ const githubConfig: StorageConfig = {
```
4. **更新配置文件**
```typescript
// builder.config.ts
export const builderConfig: BuilderConfig = {

View File

@@ -341,6 +341,12 @@ export class GitHubStorageProvider implements StorageProvider {
generatePublicUrl(key: string): string {
const fullPath = this.getFullPath(key)
// 如果设置了自定义 CDN 域名,直接使用
if (this.githubConfig.customDomain) {
const customDomain = this.githubConfig.customDomain.replace(/\/+$/, '') // 移除末尾的斜杠
return `https://${customDomain.replace(/^https?:\/\//, '')}/${fullPath}`
}
if (this.githubConfig.useRawUrl) {
// 使用 raw.githubusercontent.com 获取文件
return `https://raw.githubusercontent.com/${this.githubConfig.owner}/${this.githubConfig.repo}/${this.githubConfig.branch}/${fullPath}`