(args: { target?: string; selector?: string })
| 735 | // Resolve the command target (a project dir or a single .html) into surfaced |
| 736 | // compositions, applying the optional --selector filter. |
| 737 | function resolveScope(args: { target?: string; selector?: string }): { |
| 738 | comps: SurfacedComposition[]; |
| 739 | allComps: SurfacedComposition[]; |
| 740 | projectName: string; |
| 741 | projectDir: string | undefined; |
| 742 | } { |
| 743 | const raw = args.target?.trim(); |
| 744 | let comps: SurfacedComposition[]; |
| 745 | let projectName: string; |
| 746 | let projectDir: string | undefined; |
| 747 | if (raw && raw.endsWith(".html") && existsSync(raw) && statSync(raw).isFile()) { |
| 748 | comps = [surfaceComposition(readFileSync(raw, "utf-8"), basename(raw), raw)]; |
| 749 | projectName = basename(raw); |
| 750 | projectDir = dirname(raw); |
| 751 | } else { |
| 752 | const project = resolveProject(raw); |
| 753 | comps = collectCompositions(project.indexPath); |
| 754 | projectName = project.name; |
| 755 | projectDir = project.dir; |
| 756 | } |
| 757 | // allComps keeps the unfiltered set so --shot --selector can resolve a STATIC |
| 758 | // wrapper (e.g. `.clip`) to its animated descendants in the live DOM, even |
| 759 | // though the literal selector filter (for print/json) drops it to empty. |
| 760 | const allComps = comps; |
| 761 | if (args.selector) { |
| 762 | const sel = args.selector; |
| 763 | const matches = (target: string) => target.split(",").some((s) => s.trim() === sel); |
| 764 | comps = comps |
| 765 | .map((cmp) => ({ |
| 766 | ...cmp, |
| 767 | tweens: cmp.tweens.filter((t) => matches(t.target)), |
| 768 | traces: cmp.traces.filter((tr) => matches(tr.target)), |
| 769 | cssKeyframes: cmp.cssKeyframes.filter((kf) => kf.selectors.some(matches)), |
| 770 | anime: cmp.anime.filter((a) => a.targets.some(matches)), |
| 771 | })) |
| 772 | .filter( |
| 773 | (cmp) => |
| 774 | cmp.tweens.length > 0 || |
| 775 | cmp.traces.length > 0 || |
| 776 | cmp.cssKeyframes.length > 0 || |
| 777 | cmp.anime.length > 0, |
| 778 | ); |
| 779 | } |
| 780 | return { comps, allComps, projectName, projectDir }; |
| 781 | } |
| 782 | |
| 783 | function isEmptyComposition(cmp: SurfacedComposition): boolean { |
| 784 | return ( |
no test coverage detected