( options: ApplyImportOptions, )
| 491 | } |
| 492 | |
| 493 | export async function applyPackageImport( |
| 494 | options: ApplyImportOptions, |
| 495 | ): Promise<ApplyImportResult> { |
| 496 | const { app, existingChoices, pkg } = options; |
| 497 | const choiceDecisionMap: Map<string, ChoiceImportMode> = new Map( |
| 498 | options.choiceDecisions.map((decision) => [decision.choiceId, decision.mode]), |
| 499 | ); |
| 500 | const assetDecisionMap: Map<string, AssetImportDecision> = new Map( |
| 501 | options.assetDecisions.map((decision) => [decision.originalPath, decision]), |
| 502 | ); |
| 503 | |
| 504 | const catalog = new Map(pkg.choices.map((entry) => [entry.choice.id, entry])); |
| 505 | const secretOptionNamesByPath = buildSecretOptionNamesByPath(pkg); |
| 506 | const importableChoiceIds = new Set<string>(); |
| 507 | const importableCache = new Map<string, boolean>(); |
| 508 | const importableVisiting = new Set<string>(); |
| 509 | |
| 510 | const isChoiceImportable = (choiceId: string): boolean => { |
| 511 | const finalizeImportable = (isImportable: boolean): boolean => { |
| 512 | importableCache.set(choiceId, isImportable); |
| 513 | importableVisiting.delete(choiceId); |
| 514 | return isImportable; |
| 515 | }; |
| 516 | |
| 517 | if (importableCache.has(choiceId)) { |
| 518 | return importableCache.get(choiceId) as boolean; |
| 519 | } |
| 520 | |
| 521 | if (importableVisiting.has(choiceId)) { |
| 522 | // Break potential cycles by treating the current path as importable. |
| 523 | return true; |
| 524 | } |
| 525 | |
| 526 | importableVisiting.add(choiceId); |
| 527 | |
| 528 | const decision = choiceDecisionMap.get(choiceId); |
| 529 | if (decision === "skip") { |
| 530 | return finalizeImportable(false); |
| 531 | } |
| 532 | |
| 533 | const entry = catalog.get(choiceId); |
| 534 | if (!entry) { |
| 535 | return finalizeImportable(false); |
| 536 | } |
| 537 | |
| 538 | const parentId = entry.parentChoiceId; |
| 539 | if (!parentId) { |
| 540 | return finalizeImportable(true); |
| 541 | } |
| 542 | |
| 543 | if (!catalog.has(parentId)) { |
| 544 | return finalizeImportable(true); |
| 545 | } |
| 546 | |
| 547 | const parentDecision = choiceDecisionMap.get(parentId); |
| 548 | if (parentDecision === "skip") { |
| 549 | return finalizeImportable(true); |
| 550 | } |
no test coverage detected