feat: introduce @afilmory/typing package and update imports across the codebase

- Added a new package `@afilmory/typing` to centralize type definitions.
- Updated various files to import types from `@afilmory/typing` instead of individual modules.
- Adjusted package dependencies in `package.json` files for affected packages.
- Modified `pnpm-lock.yaml` to include the new package and its dependencies.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2026-01-10 23:31:41 +08:00
parent e09159dad0
commit 7e216d90d7
35 changed files with 87 additions and 109 deletions

View File

@@ -14,6 +14,7 @@
},
"dependencies": {
"@afilmory/og-renderer": "workspace:*",
"@afilmory/typing": "workspace:*",
"@resvg/resvg-js": "2.6.2",
"@vingle/bmp-js": "^0.2.5",
"blurhash": "2.0.5",

View File

@@ -1,5 +1,7 @@
import path from 'node:path'
import type { AfilmoryManifest, CameraInfo, LensInfo, PhotoManifestItem, ProcessPhotoResult } from '@afilmory/typing'
import { thumbnailExists } from '../image/thumbnail.js'
import { logger } from '../logger/index.js'
import { handleDeletedPhotos, loadExistingManifest, needsUpdate, saveManifest } from '../manifest/manager.js'
@@ -17,8 +19,6 @@ import type { StorageProviderFactory, StorageProviderRegistrationOptions } from
import type { StorageConfig } from '../storage/index.js'
import { StorageFactory, StorageManager } from '../storage/index.js'
import type { BuilderConfig, UserBuilderSettings } from '../types/config.js'
import type { AfilmoryManifest, CameraInfo, LensInfo } from '../types/manifest.js'
import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js'
import { ClusterPool } from '../worker/cluster-pool.js'
import type { TaskCompletedPayload } from '../worker/pool.js'
import { WorkerPool } from '../worker/pool.js'

View File

@@ -1,12 +1,12 @@
import { mkdir, unlink, writeFile } from 'node:fs/promises'
import path from 'node:path'
import type { PickedExif } from '@afilmory/typing'
import { isNil, noop } from 'es-toolkit'
import type { ExifDateTime, Tags } from 'exiftool-vendored'
import { ExifTool } from 'exiftool-vendored'
import { getGlobalLoggers } from '../photo/logger-adapter.js'
import type { PickedExif } from '../types/photo.js'
const exiftool = new ExifTool({
...(process.env.EXIFTOOL_PATH ? { exiftoolPath: process.env.EXIFTOOL_PATH } : {}),

View File

@@ -1,4 +1,4 @@
import type { HistogramData, ToneAnalysis, ToneType } from '@afilmory/builder/types/photo.js'
import type { HistogramData, ToneAnalysis, ToneType } from '@afilmory/typing'
import type sharp from 'sharp'
import { getGlobalLoggers } from '../photo'

View File

@@ -1,12 +1,12 @@
import path from 'node:path'
import type { ImageMetadata } from '@afilmory/typing'
import * as bmp from '@vingle/bmp-js'
import heicConvert from 'heic-convert'
import sharp from 'sharp'
import { HEIC_FORMATS } from '../constants/index.js'
import { getGlobalLoggers } from '../photo/logger-adapter.js'
import type { ImageMetadata } from '../types/photo.js'
// 获取图片元数据(复用 Sharp 实例)
export async function getImageMetadataWithSharp(sharpInstance: sharp.Sharp): Promise<ImageMetadata | null> {

View File

@@ -2,10 +2,10 @@ import fs from 'node:fs/promises'
import path from 'node:path'
import { workdir } from '@afilmory/builder/path.js'
import type { ThumbnailResult } from '@afilmory/typing'
import sharp from 'sharp'
import { getGlobalLoggers } from '../photo/logger-adapter.js'
import type { ThumbnailResult } from '../types/photo.js'
import { generateBlurhash } from './blurhash.js'
// 常量定义

View File

@@ -57,9 +57,16 @@ export { LOCAL_STORAGE_PROVIDERS, REMOTE_STORAGE_PROVIDERS } from './storage/ind
export { StorageFactory, StorageManager } from './storage/index.js'
export type { B2Config, ManagedStorageConfig, S3CompatibleConfig } from './storage/interfaces.js'
export type { BuilderConfig, BuilderConfigInput } from './types/config.js'
export type { AfilmoryManifest, CameraInfo, LensInfo } from './types/manifest.js'
export type { FujiRecipe, PhotoManifestItem, PickedExif, ToneAnalysis } from './types/photo.js'
export type { S3ObjectLike } from './types/s3.js'
export type {
AfilmoryManifest,
CameraInfo,
FujiRecipe,
LensInfo,
PhotoManifestItem,
PickedExif,
ToneAnalysis,
} from '@afilmory/typing'
///// Mirgation
export { migrateManifest } from './manifest/migrate.js'

View File

@@ -2,10 +2,9 @@ import fs from 'node:fs/promises'
import path, { basename } from 'node:path'
import { workdir } from '@afilmory/builder/path.js'
import type { AfilmoryManifest, CameraInfo, LensInfo, PhotoManifestItem } from '@afilmory/typing'
import { logger } from '../logger/index.js'
import type { AfilmoryManifest, CameraInfo, LensInfo } from '../types/manifest.js'
import type { PhotoManifestItem } from '../types/photo.js'
import type { S3ObjectLike } from '../types/s3.js'
import { migrateManifestFileIfNeeded } from './migrate.js'
import { CURRENT_MANIFEST_VERSION } from './version.js'

View File

@@ -2,11 +2,10 @@ import fs from 'node:fs/promises'
import path from 'node:path'
import { workdir } from '@afilmory/builder/path.js'
import type { AfilmoryManifest, ManifestVersion } from '@afilmory/typing'
import { logger } from '../logger/index.js'
import type { AfilmoryManifest } from '../types/manifest.js'
import { MIGRATION_STEPS } from './migrations/index.js'
import type { ManifestVersion } from './version.js'
import { CURRENT_MANIFEST_VERSION } from './version.js'
const manifestPath = path.join(workdir, 'src/data/photos-manifest.json')

View File

@@ -1,5 +1,6 @@
import type { AfilmoryManifest } from '@afilmory/typing'
import { logger } from '../../logger/index.js'
import type { AfilmoryManifest } from '../../types/manifest.js'
import type { ManifestMigrator, MigrationContext } from '../migrate.js'
/**

View File

@@ -1,4 +1,5 @@
import type { AfilmoryManifest } from '../../types/manifest.js'
import type { AfilmoryManifest } from '@afilmory/typing'
import type { ManifestMigrator, MigrationContext } from '../migrate.js'
/**

View File

@@ -1,5 +1,6 @@
import type { AfilmoryManifest } from '@afilmory/typing'
import { logger } from '../../logger/index.js'
import type { AfilmoryManifest } from '../../types/manifest.js'
import type { ManifestMigrator, MigrationContext } from '../migrate.js'
/**

View File

@@ -1,6 +1,7 @@
import path from 'node:path'
import type { AfilmoryManifest } from '../../types/manifest.js'
import type { AfilmoryManifest } from '@afilmory/typing'
import type { ManifestMigrator, MigrationContext } from '../migrate.js'
/**

View File

@@ -1,7 +1,7 @@
// exif.GPSAltitudeRef === 'Below Sea Level' => 1
// exif.GPSAltitudeRef === 'Above Sea Level' => 0
import type { AfilmoryManifest } from '@afilmory/builder/types/manifest.js'
import type { AfilmoryManifest } from '@afilmory/typing'
import type { ManifestMigrator, MigrationContext } from '../migrate'

View File

@@ -1,3 +1,3 @@
export type ManifestVersion = `v${number}`
import type { ManifestVersion } from '@afilmory/typing'
export const CURRENT_MANIFEST_VERSION: ManifestVersion = 'v10'

View File

@@ -1,5 +1,6 @@
import type { PhotoManifestItem } from '@afilmory/typing'
import { thumbnailExists } from '../image/thumbnail.js'
import type { PhotoManifestItem } from '../types/photo.js'
import type { PhotoProcessorOptions } from './processor.js'
export interface CacheableData {

View File

@@ -1,6 +1,7 @@
import fs from 'node:fs/promises'
import path from 'node:path'
import type { PhotoManifestItem, PickedExif, ToneAnalysis } from '@afilmory/typing'
import { decompressUint8Array } from '@afilmory/utils'
import type sharp from 'sharp'
@@ -9,7 +10,6 @@ import { extractExifData } from '../image/exif.js'
import { calculateHistogramAndAnalyzeTone } from '../image/histogram.js'
import { generateThumbnailAndBlurhash, thumbnailExists } from '../image/thumbnail.js'
import { workdir } from '../path.js'
import type { PhotoManifestItem, PickedExif, ToneAnalysis } from '../types/photo.js'
import { getGlobalLoggers } from './logger-adapter.js'
import type { PhotoProcessorOptions } from './processor.js'

View File

@@ -3,7 +3,8 @@ import fs from 'node:fs/promises'
import os from 'node:os'
import path from 'node:path'
import type { LocationInfo, PickedExif } from '../types/photo.js'
import type { LocationInfo, PickedExif } from '@afilmory/typing'
import { getGlobalLoggers } from './logger-adapter.js'
const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms))

View File

@@ -1,6 +1,7 @@
import crypto from 'node:crypto'
import path from 'node:path'
import type { PhotoManifestItem, ProcessPhotoResult } from '@afilmory/typing'
import { compressUint8Array } from '@afilmory/utils'
import sharp from 'sharp'
@@ -13,7 +14,6 @@ import {
} from '../image/processor.js'
import type { PluginRunState } from '../plugins/manager.js'
import { THUMBNAIL_PLUGIN_DATA_KEY } from '../plugins/thumbnail-storage/shared.js'
import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js'
import type { S3ObjectLike } from '../types/s3.js'
import { shouldProcessPhoto } from './cache-manager.js'
import { processExifData, processThumbnailAndBlurhash, processToneAnalysis } from './data-processors.js'

View File

@@ -1,6 +1,7 @@
import path from 'node:path'
import type { PhotoInfo, PickedExif } from '../types/photo.js'
import type { PhotoInfo, PickedExif } from '@afilmory/typing'
import { getPhotoExecutionContext } from './execution-context.js'
import { getGlobalLoggers } from './logger-adapter.js'

View File

@@ -1,7 +1,8 @@
import type { PhotoManifestItem, ProcessPhotoResult } from '@afilmory/typing'
import type { AfilmoryBuilder, BuilderOptions } from '../builder/builder.js'
import { logger } from '../logger/index.js'
import type { PluginRunState } from '../plugins/manager.js'
import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js'
import type { S3ObjectLike } from '../types/s3.js'
import { createStorageKeyNormalizer, runWithPhotoExecutionContext } from './execution-context.js'
import type { PhotoProcessingContext } from './image-pipeline.js'

View File

@@ -1,3 +1,5 @@
import type { LocationInfo, PhotoManifestItem, PickedExif } from '@afilmory/typing'
import type { AfilmoryBuilder } from '../builder/builder.js'
import type { Logger } from '../logger/index.js'
import {
@@ -8,7 +10,6 @@ import {
import type { GeocodingProvider } from '../photo/geocoding.js'
import { createGeocodingProvider, extractLocationFromGPS, parseGPSCoordinates } from '../photo/geocoding.js'
import { createPhotoProcessingLoggers } from '../photo/logger-adapter.js'
import type { LocationInfo, PhotoManifestItem, PickedExif } from '../types/photo.js'
import type { BuilderPlugin } from './types.js'
const PLUGIN_NAME = 'afilmory:geocoding'

View File

@@ -4,13 +4,13 @@ import { fileURLToPath } from 'node:url'
import type { ExifInfo } from '@afilmory/og-renderer'
import { renderOgImage } from '@afilmory/og-renderer'
import type { PhotoManifestItem } from '@afilmory/typing'
import type { SatoriOptions } from 'satori'
import type { Logger } from '../../logger/index.js'
import { workdir } from '../../path.js'
import { StorageManager } from '../../storage/index.js'
import type { S3CompatibleConfig, StorageConfig } from '../../storage/interfaces.js'
import type { PhotoManifestItem } from '../../types/photo.js'
import type { ThumbnailPluginData } from '../thumbnail-storage/shared.js'
import { THUMBNAIL_PLUGIN_DATA_KEY } from '../thumbnail-storage/shared.js'
import type { BuilderPlugin } from '../types.js'

View File

@@ -1,11 +1,11 @@
import type { AfilmoryManifest, CameraInfo, LensInfo, PhotoManifestItem, ProcessPhotoResult } from '@afilmory/typing'
import type { AfilmoryBuilder, BuilderOptions, BuilderResult } from '../builder/builder.js'
import type { Logger } from '../logger/index.js'
import type { PhotoProcessingContext } from '../photo/image-pipeline.js'
import type { PhotoProcessorOptions } from '../photo/processor.js'
import type { StorageObject } from '../storage/interfaces.js'
import type { BuilderConfig } from '../types/config.js'
import type { AfilmoryManifest, CameraInfo, LensInfo } from '../types/manifest.js'
import type { PhotoManifestItem, ProcessPhotoResult } from '../types/photo.js'
export type BuilderPluginESMImporter = () => Promise<{
default: (() => BuilderPlugin | Promise<BuilderPlugin>) | BuilderPlugin

View File

@@ -1,12 +1,13 @@
import process from 'node:process'
import { deserialize } from 'node:v8'
import type { PhotoManifestItem } from '@afilmory/typing'
import type { BuilderOptions } from './builder/builder.js'
import { AfilmoryBuilder } from './builder/builder.js'
import type { PluginRunState } from './plugins/manager.js'
import type { StorageObject } from './storage/interfaces'
import type { BuilderConfig } from './types/config.js'
import type { PhotoManifestItem } from './types/photo'
import type { BatchTaskMessage, BatchTaskResult, TaskMessage, TaskResult } from './worker/cluster-pool'
// 新增接口定义

View File

@@ -0,0 +1,13 @@
{
"name": "@afilmory/typing",
"type": "module",
"version": "0.0.1",
"private": true,
"exports": {
".": "./src/index.ts",
"./*": "./src/*"
},
"dependencies": {
"exiftool-vendored": "33.5.0"
}
}

View File

@@ -0,0 +1,2 @@
export * from './manifest'
export * from './photo'

View File

@@ -1,6 +1,7 @@
import type { ManifestVersion } from '../manifest/version'
import type { PhotoManifestItem } from './photo'
export type ManifestVersion = `v${number}`
export interface CameraInfo {
make: string // e.g., "Canon", "Sony", "Fujifilm"
model: string // e.g., "EOS R5", "α7R V", "X-T5"

View File

@@ -83,6 +83,12 @@ export interface ProcessPhotoResult {
pluginData?: Record<string, unknown>
}
export interface ThumbnailResult {
thumbnailUrl: string | null
thumbnailBuffer: Buffer | null
thumbHash: Uint8Array | null
}
export interface PickedExif {
// 时区和时间相关
zone?: string
@@ -184,12 +190,6 @@ export interface PickedExif {
MicroVideoPresentationTimestampUs?: Tags['MicroVideoPresentationTimestampUs']
}
export interface ThumbnailResult {
thumbnailUrl: string | null
thumbnailBuffer: Buffer | null
thumbHash: Uint8Array | null
}
export type FujiRecipe = {
FilmMode:
| 'F0/Standard (Provia)'

View File

@@ -8,7 +8,7 @@
"./*": "./src/*"
},
"dependencies": {
"@afilmory/builder": "workspace:*",
"@afilmory/typing": "workspace:*",
"clsx": "^2.1.1",
"tailwind-merge": "^3.4.0"
},

View File

@@ -1,4 +1,4 @@
import type { PhotoManifestItem } from '@afilmory/builder'
import type { PhotoManifestItem } from '@afilmory/typing'
const GENERATOR_NAME = 'Afilmory Feed Generator'
const EXIF_NAMESPACE = 'https://afilmory.art/rss/exif'