package service import ( "github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/dto" "github.com/QuantumNous/new-api/model" ) // BuildTaskPluginView converts a persisted task into the deliberately narrow // public shape permitted at JavaScript plugin boundaries. func BuildTaskPluginView(task *model.Task) (dto.TaskView, error) { createdAt := task.CreatedAt if createdAt == 0 { createdAt = task.SubmitTime } view := dto.TaskView{ TaskID: task.TaskID, Platform: string(task.Platform), Status: string(task.Status), Progress: task.Progress, FailReason: task.FailReason, CreatedAt: createdAt, UpdatedAt: task.UpdatedAt, FinishedAt: task.FinishTime, } if len(task.Data) > 0 { if err := common.Unmarshal(task.Data, &view.Data); err != nil { return dto.TaskView{}, err } view.Data = replacePrivateTaskID(view.Data, task.PrivateData.UpstreamTaskID, task.TaskID) } return view, nil } // replacePrivateTaskID rewrites exact private IDs only in known task-ID fields. // Map keys and opaque strings, including URLs containing the ID, are preserved. func replacePrivateTaskID(value any, privateTaskID, publicTaskID string) any { if privateTaskID == "" || privateTaskID == publicTaskID { return value } switch typed := value.(type) { case []any: replaced := make([]any, len(typed)) for index, item := range typed { replaced[index] = replacePrivateTaskID(item, privateTaskID, publicTaskID) } return replaced case map[string]any: replaced := make(map[string]any, len(typed)) for key, item := range typed { if (key == "id" || key == "task_id" || key == "taskId") && item == privateTaskID { replaced[key] = publicTaskID continue } replaced[key] = replacePrivateTaskID(item, privateTaskID, publicTaskID) } return replaced default: return value } }