d3ro-voice/scripts/ci/lib/forgejo-generic-file-delete.mjs
Yun Chan ba9ef9741e fix: red-team round 3 hardening across desktop, mobile, core and server
Batch of red-team r3 fixes that were in the working tree before the
2026-09-28 design overhaul, committed as one unit with their tests.

- desktop main: STT timeouts and sidecar, voice recording store, sync
  (credentials, audio, knowledge reindex, push gates), runtime
  provisioner, update policy, AltGr keybindings, voice-command policy,
  dictionary file codec/limits, meeting transcript condensing and a
  local recording ledger so interrupted-session recovery only closes
  meetings this device recorded (a phone's live meeting is left alone).
- mobile: login CSRF via implicit token callbacks rejected, account
  deletion/retention, durable queue retention, knowledge realtime
  without unfiltered DELETE, meeting re-record failure paths, cloud STT
  client, preferences store/resync.
- core: text chunking splits long unbroken transcripts to fit, template
  field policy, dictionary limits, meeting markdown inline handling.
- server: payple webhook policy and cancellation order scope, meeting
  document generation quota, team RPC null-role guard, unified LLM
  quota in-flight accounting, knowledge chunk vector index, meeting
  re-record failure paths (migrations 20260929*).
- ci: portable/runtime feed gates, update-policy schema, Forgejo file
  delete and alias planning.

Four older tests are updated to the new contracts rather than the old
behavior: token-pair auth callbacks are rejected, knowledge realtime no
longer subscribes to DELETE, long transcript lines are split, and
meeting recovery requires the local recording ledger for empty rows.
2026-09-28 20:45:52 +09:00

27 lines
1.3 KiB
JavaScript

// scripts/ci/lib/forgejo-generic-file-delete.mjs
// Forgejo generic registry 어댑터에 파일 단위 삭제(PackageRegistry.deleteFile)를 더한다.
//
// 별칭(*-latest)을 패키지 버전째 지우면 인덱스가 수백 MB 업로드 내내 404가 된다.
// Forgejo generic registry는 파일 하나만 지우는 엔드포인트
// DELETE /api/packages/{owner}/generic/{name}/{version}/{file}
// 를 제공하므로, 바뀐 파일만 DELETE→PUT 해 404 구간을 파일 하나 교체 시간으로 줄인다.
// 404는 이미 없는 것이므로 성공으로 본다. 그 밖의 오류는 예외(fail-closed).
/**
* @template {{ fileUrl: (versionPath: string, name: string) => string }} R
* @param {R} registry
* @param {{ fetchImpl: (url: string, init?: RequestInit) => Promise<Response> }} deps
* @returns {R & { deleteFile: (versionPath: string, name: string) => Promise<void> }}
*/
export function withFileDeletion(registry, { fetchImpl }) {
return {
...registry,
async deleteFile(versionPath, name) {
const url = registry.fileUrl(versionPath, name);
const response = await fetchImpl(url, { method: "DELETE" });
if (!response.ok && response.status !== 404) {
throw new Error(`파일 삭제 실패 (HTTP ${response.status}): ${url}`);
}
},
};
}