fix: 0.1.0 사전 점검 차단 결함을 보정
공유 archive 마이그레이션과 런타임 설정 보존, AVIF 판별 및 문서 생성을 수정한다. 조건부 통합 격리를 보강하고 취약 의존성을 갱신하며 릴리스 메타데이터를 정리한다.
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/cors": "^11.2.0",
|
||||
"@fastify/static": "^9.0.0",
|
||||
"@fastify/static": "^10.1.3",
|
||||
"@sammo-ts/common": "workspace:*",
|
||||
"@sammo-ts/game-engine": "workspace:*",
|
||||
"@sammo-ts/infra": "workspace:*",
|
||||
@@ -43,7 +43,7 @@
|
||||
"fastify": "^5.6.2",
|
||||
"redis": "^5.10.0",
|
||||
"sanitize-html": "2.17.6",
|
||||
"sharp": "^0.34.4",
|
||||
"sharp": "^0.35.0",
|
||||
"zod": "^4.3.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +228,7 @@ export const boardRouter = router({
|
||||
}
|
||||
|
||||
const format = metadata.format;
|
||||
const isAvif = metadata.mediaType === 'image/avif';
|
||||
const isAnimated = (metadata.pages ?? 1) > 1;
|
||||
const needsResize = Math.max(metadata.width, metadata.height) > MAX_LONG_EDGE;
|
||||
|
||||
@@ -237,9 +238,9 @@ export const boardRouter = router({
|
||||
}
|
||||
|
||||
let outputBuffer = buffer;
|
||||
let outputFormat = format === 'avif' ? 'avif' : 'webp';
|
||||
let outputFormat = isAvif ? 'avif' : 'webp';
|
||||
|
||||
if (format === 'avif') {
|
||||
if (isAvif) {
|
||||
if (needsResize) {
|
||||
outputBuffer = await buildAvifBuffer(buffer, true);
|
||||
}
|
||||
|
||||
@@ -288,6 +288,29 @@ describe('board router actor, nation, and secret permissions', () => {
|
||||
expect(result).toMatchObject({ width: 64, height: 48, format: 'webp', animated: false });
|
||||
});
|
||||
|
||||
it('preserves an AVIF editor image when resizing is unnecessary', async () => {
|
||||
const upload = vi.fn(async ({ filename }: { filename: string }) => ({
|
||||
publicUrl: `https://sam-image.hided.net/uploads/core2026/${filename}`,
|
||||
}));
|
||||
const fixture = buildContext({
|
||||
me: buildGeneral({ officerLevel: 5 }),
|
||||
contentImageUpload: { upload },
|
||||
});
|
||||
const avif = await sharp({
|
||||
create: { width: 64, height: 48, channels: 4, background: '#224466' },
|
||||
})
|
||||
.avif()
|
||||
.toBuffer();
|
||||
|
||||
const result = await appRouter.createCaller(fixture.context).board.uploadImage({
|
||||
dataUrl: `data:image/avif;base64,${avif.toString('base64')}`,
|
||||
});
|
||||
|
||||
expect(result.url).toMatch(/^https:\/\/sam-image\.hided\.net\/uploads\/core2026\/[a-f0-9]{32}\.avif$/);
|
||||
expect(upload).toHaveBeenCalledWith(expect.objectContaining({ contentType: 'image/avif', body: avif }));
|
||||
expect(result).toMatchObject({ width: 64, height: 48, format: 'avif', animated: false });
|
||||
});
|
||||
|
||||
it('rejects editor image uploads from an ordinary nation member', async () => {
|
||||
const upload = vi.fn();
|
||||
const fixture = buildContext({
|
||||
|
||||
@@ -204,9 +204,8 @@ integration('scenario 903 select pool through the durable turn daemon', () => {
|
||||
await expect(
|
||||
appRouter.createCaller(buildContext('select-pool-public-lobby')).lobby.info()
|
||||
).resolves.toMatchObject({ selectionPoolEnabled: true });
|
||||
await expect(
|
||||
appRouter.createCaller(buildContext('select-pool-config')).join.getConfig()
|
||||
).resolves.toMatchObject({
|
||||
const joinConfig = await appRouter.createCaller(buildContext('select-pool-config')).join.getConfig();
|
||||
expect(joinConfig).toMatchObject({
|
||||
serverInfo: {
|
||||
currentYear: 180,
|
||||
currentMonth: 1,
|
||||
@@ -392,6 +391,7 @@ integration('scenario 903 select pool through the durable turn daemon', () => {
|
||||
|
||||
const fullWorld = await db.worldState.findUniqueOrThrow({ where: { id: worldStateId } });
|
||||
const fullConfig = fullWorld.config as Record<string, unknown>;
|
||||
runtime!.world.updateWorldConfig({ maxGeneral: 1 });
|
||||
await db.worldState.update({
|
||||
where: { id: worldStateId },
|
||||
data: { config: { ...fullConfig, maxGeneral: 1 } as GamePrisma.InputJsonValue },
|
||||
@@ -427,6 +427,7 @@ integration('scenario 903 select pool through the durable turn daemon', () => {
|
||||
})
|
||||
).rejects.toMatchObject({ message: '더 이상 등록 할 수 없습니다.' });
|
||||
expect(await db.general.count({ where: { userId: otherUserId } })).toBe(0);
|
||||
runtime!.world.updateWorldConfig({ maxGeneral: joinConfig.serverInfo.maxGeneral });
|
||||
await db.worldState.update({
|
||||
where: { id: worldStateId },
|
||||
data: { config: fullConfig as GamePrisma.InputJsonValue },
|
||||
|
||||
Reference in New Issue
Block a user