release: v1.2.0 — unified images/ storage and legacy migration
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
ci / ci (22, ubuntu-latest) (push) Canceled after 0s
Publish Docker image / build (linux/amd64, ubuntu-latest, amd64) (push) Canceled after 0s
Publish Docker image / build (linux/arm64, ubuntu-24.04-arm, arm64) (push) Canceled after 0s
Publish Docker image / merge (push) Canceled after 0s
GitHub Release / release (push) Canceled after 0s
Consolidate local images under data/images/, add docker migrate CLI, startup index sync with orphan cleanup, and remove upload folder UI/API.
This commit is contained in:
1 parent
3dee0437e6
commit
469d3be735
50 files changed
+1273
-956
No files matched your search
@@ -1,31 +1,29 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { generateImageKey, sortFolderNames, validateImageKey } from './image-key'
|
||||
import { generateImageKey, validateImageKey } from './image-key'
|
||||
|
||||
describe('validateImageKey', () => {
|
||||
it('accepts valid date-layout keys', () => {
|
||||
expect(validateImageKey('images/2026/08/abc123.webp')).toBe(true)
|
||||
expect(validateImageKey('twikoo/2025/01/photo.jpg')).toBe(true)
|
||||
})
|
||||
|
||||
it('accepts valid flat-layout keys', () => {
|
||||
expect(validateImageKey('images/abc123.webp')).toBe(true)
|
||||
expect(validateImageKey('twikoo/photo.jpg')).toBe(true)
|
||||
})
|
||||
|
||||
it('sorts images first then alphabetically', () => {
|
||||
expect(sortFolderNames(['blog', 'images', 'twikoo'])).toEqual(['images', 'blog', 'twikoo'])
|
||||
expect(sortFolderNames(['blog'])).toEqual(['images', 'blog'])
|
||||
it('accepts migrated nested paths under images/', () => {
|
||||
expect(validateImageKey('images/file/111.webp')).toBe(true)
|
||||
expect(validateImageKey('images/2026/08/28/123.webp')).toBe(true)
|
||||
expect(validateImageKey('images/twikoo/2025/01/photo.jpg')).toBe(true)
|
||||
})
|
||||
|
||||
it('rejects path traversal and malformed keys', () => {
|
||||
it('rejects non-images top-level and path traversal', () => {
|
||||
expect(validateImageKey('')).toBe(false)
|
||||
expect(validateImageKey('/images/2026/08/a.webp')).toBe(false)
|
||||
expect(validateImageKey('images/2026/08/../secret.webp')).toBe(false)
|
||||
expect(validateImageKey('images//2026/08/a.webp')).toBe(false)
|
||||
expect(validateImageKey('api/2026/08/a.webp')).toBe(false)
|
||||
expect(validateImageKey('images/26/8/a.webp')).toBe(false)
|
||||
expect(validateImageKey('blog/2026/08/a.webp')).toBe(false)
|
||||
expect(validateImageKey('twikoo/photo.jpg')).toBe(false)
|
||||
expect(validateImageKey('images/2026/08/a.txt')).toBe(false)
|
||||
expect(validateImageKey('images/2026/a.webp')).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -33,14 +31,20 @@ describe('generateImageKey', () => {
|
||||
const date = new Date('2026-08-15T12:00:00Z')
|
||||
|
||||
it('generates date-layout keys by default', () => {
|
||||
const key = generateImageKey('image/webp', date, 'images')
|
||||
expect(key).toMatch(/^images\/2026\/08\/[A-Za-z0-9]+\.webp$/)
|
||||
const key = generateImageKey('image/webp', date)
|
||||
expect(key).toMatch(/^images\/2026\/08\/[A-Za-z0-9]{12}\.webp$/)
|
||||
expect(validateImageKey(key)).toBe(true)
|
||||
})
|
||||
|
||||
it('generates flat-layout keys when requested', () => {
|
||||
const key = generateImageKey('image/webp', date, 'images', 'flat')
|
||||
expect(key).toMatch(/^images\/[A-Za-z0-9]+\.webp$/)
|
||||
const key = generateImageKey('image/webp', date, 'flat')
|
||||
expect(key).toMatch(/^images\/[A-Za-z0-9]{12}\.webp$/)
|
||||
expect(validateImageKey(key)).toBe(true)
|
||||
})
|
||||
|
||||
it('uses 12-character random IDs', () => {
|
||||
const key = generateImageKey('image/webp', date, 'flat')
|
||||
const id = key.split('/')[1]?.replace('.webp', '') ?? ''
|
||||
expect(id.length).toBe(12)
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user