返回 html-video
templates.ts
根目录 / packages / cli / src / commands / templates.ts
1 import type { CliContext } from '../context.js';
2 import { fail, ok } from '../output.js';
3
4 interface SearchOpts {
5 intent?: string;
6 aspect?: string;
7 licenseAllow?: string;
8 top?: number;
9 }
10
11 export async function searchTemplates(ctx: CliContext, opts: SearchOpts): Promise<void> {
12 const allowed = opts.licenseAllow?.split(',').map((s) => s.trim()).filter(Boolean);
13 const enginesAvailable = ctx.engines.list().map((e) => e.id);
14 const matches = ctx.templates.search({
15 ...(opts.intent !== undefined && { intent: opts.intent }),
16 ...(opts.aspect !== undefined && { aspect: opts.aspect }),
17 ...(allowed && { licenseAllow: allowed }),
18 enginesAvailable,
19 top: opts.top ?? 5,
20 });
21 ok({
22 matches: matches.map((m) => ({
23 id: m.template.id,
24 name: m.template.name,
25 engine: m.template.engine,
26 engine_installed: ctx.engines.has(m.template.engine),
27 score: m.score,
28 score_reason: m.reason,
29 preview_poster: m.template.preview.poster,
30 best_for: m.template.best_for,
31 category: m.template.category,
32 license: m.template.license.spdx,
33 duration_min_sec: m.template.output.duration.min_sec,
34 duration_max_sec: m.template.output.duration.max_sec,
35 })),
36 });
37 }
38
39 export async function inspectTemplate(ctx: CliContext, id: string): Promise<void> {
40 if (!ctx.templates.has(id)) {
41 fail('template-not-found', `Template "${id}" not found`, {
42 available: ctx.templates.list().map((t) => t.id),
43 });
44 }
45 const t = ctx.templates.get(id);
46 ok({ template: t });
47 }
48
48 lines TYPESCRIPT