import fs from 'node:fs/promises' import path from 'node:path' import { tmpdir } from 'node:os' import { expect, test } from 'vitest' import { discoverVideoResources } from './index' test('discovers scene, transition and theme resources from installed packages', async () => { const projectRoot = await fs.mkdtemp(path.join(tmpdir(), 'component-project-helper-discovery-')) const packageRoot = path.join(projectRoot, 'node_modules', '@vibecuting', 'demo-pack') const srcRoot = path.join(packageRoot, 'src') await fs.mkdir(srcRoot, { recursive: true }) await fs.writeFile( path.join(packageRoot, 'package.json'), JSON.stringify({ name: '@vibecuting/demo-pack', version: '0.1.0', main: './src/index.ts', types: './src/index.ts', }), 'utf8', ) await fs.writeFile( path.join(srcRoot, 'index.ts'), ` export const sceneMetadata = defineScenePluginMetadata({ resourceKind: 'scene', name: 'DemoScene', description: 'Demo scene resource', sourceFile: 'src/index.ts', pluginKey: 'demo.scene', tags: ['demo'], aspectRatio: '16:9', sceneType: 'scene', motion: 'static', sceneFamily: 'custom', rootLayout: 'absolute-fill', }) export const transitionMetadata = defineTransitionPluginMetadata({ resourceKind: 'transition', name: 'DemoTransition', description: 'Demo transition resource', sourceFile: 'src/index.ts', pluginKey: 'demo.transition', tags: ['demo'], transitionKind: 'transition', }) export const themeMetadata = defineThemePluginMetadata({ resourceKind: 'theme', name: 'DemoTheme', description: 'Demo theme resource', sourceFile: 'src/index.ts', pluginKey: 'demo.theme', tags: ['demo'], supportedSceneFamilies: ['custom'], cssVariables: ['--scene-bg'], }) export const DemoScene = VideoComponent(sceneMetadata)( defineSceneComponent({ family: 'custom', propsSchema: null, component: function DemoScene() { return null }, }), ) export const DemoTransition = TransitionComponent(transitionMetadata)( defineTransitionPlugin({ key: 'demo.transition', kind: 'transition', metadata: transitionMetadata, propsSchema: null, renderBoundary: () => null, getBoundaryDurationInFrames: () => 1, getTimelineOverlapInFrames: () => 1, }), ) export const DemoTheme = ThemeComponent(themeMetadata)( defineSceneTheme({ key: 'demo.theme', name: 'Demo theme', variables: { '--scene-bg': '#000000', }, }), ) `, 'utf8', ) const discovered = await discoverVideoResources(projectRoot) expect(discovered.map((resource) => resource.exportName)).toEqual([ 'DemoScene', 'DemoTheme', 'DemoTransition', ]) expect(discovered.map((resource) => resource.metadata.resourceKind)).toEqual([ 'scene', 'theme', 'transition', ]) expect(discovered[0]?.metadata.pluginKey).toBe('demo.scene') expect(discovered[1]?.metadata.pluginKey).toBe('demo.theme') expect(discovered[2]?.metadata.pluginKey).toBe('demo.transition') })