* Resolve an issue number that may be a temporary ID or an actual issue number * Returns structured result with the resolved number, repo, and metadata * @param {any} value - The value to resolve (can be temporary ID, number, or string) * @param {Map } temporaryIdMap - Map of temporar
(value, temporaryIdMap)
| 345 | * @returns {{resolved: RepoIssuePair|null, wasTemporaryId: boolean, errorMessage: string|null}} |
| 346 | */ |
| 347 | function resolveIssueNumber(value, temporaryIdMap) { |
| 348 | if (value === undefined || value === null) { |
| 349 | return { resolved: null, wasTemporaryId: false, errorMessage: "Issue number is missing" }; |
| 350 | } |
| 351 | |
| 352 | const valueStr = String(value).trim(); |
| 353 | // Strip surrounding quotes (agent sometimes double-quotes string values, e.g. `"aw_foo"`) |
| 354 | const unquoted = /^(["'])(.+)\1$/.test(valueStr) ? valueStr.slice(1, -1) : valueStr; |
| 355 | |
| 356 | // Check if it's a temporary ID (accepts both '#aw_xxx' and 'aw_xxx' forms) |
| 357 | if (isTemporaryId(unquoted)) { |
| 358 | const resolvedPair = temporaryIdMap.get(normalizeTemporaryId(unquoted)); |
| 359 | if (resolvedPair !== undefined) { |
| 360 | // Support legacy format where the map value is the issue number. |
| 361 | const contextRepo = typeof context !== "undefined" ? `${context.repo.owner}/${context.repo.repo}` : ""; |
| 362 | if (typeof resolvedPair === "number") { |
| 363 | return { resolved: { repo: contextRepo, number: resolvedPair }, wasTemporaryId: true, errorMessage: null }; |
| 364 | } |
| 365 | if (typeof resolvedPair === "object" && resolvedPair !== null) { |
| 366 | if ("repo" in resolvedPair && "number" in resolvedPair) { |
| 367 | return { |
| 368 | resolved: { repo: String(resolvedPair.repo), number: Number(resolvedPair.number) }, |
| 369 | wasTemporaryId: true, |
| 370 | errorMessage: null, |
| 371 | }; |
| 372 | } |
| 373 | if ("number" in resolvedPair) { |
| 374 | return { resolved: { repo: contextRepo, number: Number(resolvedPair.number) }, wasTemporaryId: true, errorMessage: null }; |
| 375 | } |
| 376 | } |
| 377 | } |
| 378 | return { |
| 379 | resolved: null, |
| 380 | wasTemporaryId: true, |
| 381 | errorMessage: `Temporary ID '${valueStr}' not found in map. Ensure the issue was created before linking.`, |
| 382 | }; |
| 383 | } |
| 384 | |
| 385 | // Check if it looks like a malformed temporary ID |
| 386 | const withoutHash = unquoted.startsWith("#") ? unquoted.substring(1) : unquoted; |
| 387 | if (withoutHash.startsWith("aw_")) { |
| 388 | return { |
| 389 | resolved: null, |
| 390 | wasTemporaryId: false, |
| 391 | errorMessage: `Invalid temporary ID format: '${valueStr}'. Temporary IDs must be in format 'aw_' followed by 3 to 12 alphanumeric or underscore characters (A-Za-z0-9_). Example: 'aw_abc' or 'aw_pr_fix'`, |
| 392 | }; |
| 393 | } |
| 394 | |
| 395 | // It's a real issue number - use context repo as default |
| 396 | const issueNumber = typeof value === "number" ? value : parseInt(withoutHash, 10); |
| 397 | if (isNaN(issueNumber) || issueNumber <= 0) { |
| 398 | return { resolved: null, wasTemporaryId: false, errorMessage: `Invalid issue number: ${value}. Expected either a valid temporary ID (format: aw_ followed by 3-12 alphanumeric or underscore characters) or a numeric issue number.` }; |
| 399 | } |
| 400 | |
| 401 | const contextRepo = typeof context !== "undefined" ? `${context.repo.owner}/${context.repo.repo}` : ""; |
| 402 | return { resolved: { repo: contextRepo, number: issueNumber }, wasTemporaryId: false, errorMessage: null }; |
| 403 | } |
| 404 |
no test coverage detected