|
1 | 1 | import { |
| 2 | + getProjectSlidesWithScripts, |
2 | 3 | getScriptText, |
3 | 4 | getScriptVersionList, |
4 | 5 | postScriptVersion, |
5 | 6 | updateScriptText, |
6 | 7 | } from "../repositories/script.repository.js"; |
| 8 | +import { ProjectNotFoundError } from "../errors/project.error.js"; |
| 9 | +import { |
| 10 | + ScriptBulkEditDuplicateSlideError, |
| 11 | + ScriptBulkEditPayloadError, |
| 12 | + ScriptBulkEditSlideNotFoundError, |
| 13 | +} from "../errors/script.error.js"; |
7 | 14 |
|
8 | 15 | export const processScriptUpdate = async (slideId, text) => { |
9 | 16 | try { |
@@ -76,3 +83,100 @@ export const processScriptRestore = async (id, versionNumber) => { |
76 | 83 | throw error; |
77 | 84 | } |
78 | 85 | }; |
| 86 | + |
| 87 | +const normalizeBulkEditScripts = (scripts) => { |
| 88 | + if (!Array.isArray(scripts) || scripts.length < 1) { |
| 89 | + throw new ScriptBulkEditPayloadError({ scripts }); |
| 90 | + } |
| 91 | + |
| 92 | + const normalized = []; |
| 93 | + const usedSlideIds = new Set(); |
| 94 | + |
| 95 | + for (let i = 0; i < scripts.length; i++) { |
| 96 | + const item = scripts[i]; |
| 97 | + if (!item || typeof item !== "object") { |
| 98 | + throw new ScriptBulkEditPayloadError({ index: i, item }); |
| 99 | + } |
| 100 | + |
| 101 | + const slideId = item.slideId != null ? String(item.slideId) : ""; |
| 102 | + if (!slideId || !/^\d+$/.test(slideId)) { |
| 103 | + throw new ScriptBulkEditPayloadError({ index: i, slideId: item.slideId }); |
| 104 | + } |
| 105 | + |
| 106 | + if (usedSlideIds.has(slideId)) { |
| 107 | + throw new ScriptBulkEditDuplicateSlideError({ slideId }); |
| 108 | + } |
| 109 | + |
| 110 | + if (typeof item.scriptText !== "string") { |
| 111 | + throw new ScriptBulkEditPayloadError({ index: i, slideId, scriptText: item.scriptText }); |
| 112 | + } |
| 113 | + |
| 114 | + usedSlideIds.add(slideId); |
| 115 | + normalized.push({ slideId, scriptText: item.scriptText }); |
| 116 | + } |
| 117 | + |
| 118 | + return normalized; |
| 119 | +}; |
| 120 | + |
| 121 | +export const processGetProjectScripts = async ({ projectId, userId }) => { |
| 122 | + const project = await getProjectSlidesWithScripts(projectId, userId); |
| 123 | + if (!project) { |
| 124 | + throw new ProjectNotFoundError({ projectId }); |
| 125 | + } |
| 126 | + |
| 127 | + return { |
| 128 | + projectId: project.id.toString(), |
| 129 | + scripts: (project.slides || []).map((slide) => ({ |
| 130 | + slideId: slide.id.toString(), |
| 131 | + scriptText: slide.script?.scriptText || "", |
| 132 | + })), |
| 133 | + }; |
| 134 | +}; |
| 135 | + |
| 136 | +export const processBulkEditProjectScripts = async ({ projectId, userId, scripts }) => { |
| 137 | + const normalizedScripts = normalizeBulkEditScripts(scripts); |
| 138 | + |
| 139 | + const project = await getProjectSlidesWithScripts(projectId, userId); |
| 140 | + if (!project) { |
| 141 | + throw new ProjectNotFoundError({ projectId }); |
| 142 | + } |
| 143 | + |
| 144 | + const projectSlideIds = new Set((project.slides || []).map((slide) => slide.id.toString())); |
| 145 | + const invalidSlideIds = normalizedScripts |
| 146 | + .filter((item) => !projectSlideIds.has(item.slideId)) |
| 147 | + .map((item) => item.slideId); |
| 148 | + |
| 149 | + if (invalidSlideIds.length > 0) { |
| 150 | + throw new ScriptBulkEditSlideNotFoundError({ |
| 151 | + projectId, |
| 152 | + slideIds: invalidSlideIds, |
| 153 | + }); |
| 154 | + } |
| 155 | + |
| 156 | + let updatedSlideCount = 0; |
| 157 | + let unchangedSlideCount = 0; |
| 158 | + const updatedSlideIds = []; |
| 159 | + |
| 160 | + const updateResults = await Promise.all( |
| 161 | + normalizedScripts.map((item) => processScriptUpdate(item.slideId, item.scriptText)), |
| 162 | + ); |
| 163 | + |
| 164 | + for (let i = 0; i < updateResults.length; i++) { |
| 165 | + const { isUpdated } = updateResults[i]; |
| 166 | + if (isUpdated) { |
| 167 | + updatedSlideCount += 1; |
| 168 | + updatedSlideIds.push(normalizedScripts[i].slideId); |
| 169 | + continue; |
| 170 | + } |
| 171 | + |
| 172 | + unchangedSlideCount += 1; |
| 173 | + } |
| 174 | + |
| 175 | + return { |
| 176 | + projectId: project.id.toString(), |
| 177 | + requestedSlideCount: normalizedScripts.length, |
| 178 | + updatedSlideCount, |
| 179 | + unchangedSlideCount, |
| 180 | + updatedSlideIds, |
| 181 | + }; |
| 182 | +}; |
0 commit comments