@twick/vite-plugin 0.14.21 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/index.cjs +866 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +172 -0
  4. package/dist/index.d.ts +172 -0
  5. package/dist/index.js +842 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +31 -18
  8. package/lib/index.d.ts +0 -3
  9. package/lib/index.js +0 -23
  10. package/lib/index.js.map +0 -1
  11. package/lib/main.d.ts +0 -71
  12. package/lib/main.js +0 -40
  13. package/lib/main.js.map +0 -1
  14. package/lib/openInExplorer.d.ts +0 -1
  15. package/lib/openInExplorer.js +0 -44
  16. package/lib/openInExplorer.js.map +0 -1
  17. package/lib/partials/assets.d.ts +0 -6
  18. package/lib/partials/assets.js +0 -50
  19. package/lib/partials/assets.js.map +0 -1
  20. package/lib/partials/editor.d.ts +0 -8
  21. package/lib/partials/editor.js +0 -73
  22. package/lib/partials/editor.js.map +0 -1
  23. package/lib/partials/ffmpegBridge.d.ts +0 -40
  24. package/lib/partials/ffmpegBridge.js +0 -195
  25. package/lib/partials/ffmpegBridge.js.map +0 -1
  26. package/lib/partials/imageExporter.d.ts +0 -6
  27. package/lib/partials/imageExporter.js +0 -45
  28. package/lib/partials/imageExporter.js.map +0 -1
  29. package/lib/partials/index.d.ts +0 -11
  30. package/lib/partials/index.js +0 -28
  31. package/lib/partials/index.js.map +0 -1
  32. package/lib/partials/meta.d.ts +0 -2
  33. package/lib/partials/meta.js +0 -68
  34. package/lib/partials/meta.js.map +0 -1
  35. package/lib/partials/metrics.d.ts +0 -2
  36. package/lib/partials/metrics.js +0 -13
  37. package/lib/partials/metrics.js.map +0 -1
  38. package/lib/partials/projects.d.ts +0 -10
  39. package/lib/partials/projects.js +0 -34
  40. package/lib/partials/projects.js.map +0 -1
  41. package/lib/partials/rive.d.ts +0 -2
  42. package/lib/partials/rive.js +0 -70
  43. package/lib/partials/rive.js.map +0 -1
  44. package/lib/partials/settings.d.ts +0 -2
  45. package/lib/partials/settings.js +0 -65
  46. package/lib/partials/settings.js.map +0 -1
  47. package/lib/partials/wasmExporter.d.ts +0 -2
  48. package/lib/partials/wasmExporter.js +0 -87
  49. package/lib/partials/wasmExporter.js.map +0 -1
  50. package/lib/partials/webgl.d.ts +0 -10
  51. package/lib/partials/webgl.js +0 -88
  52. package/lib/partials/webgl.js.map +0 -1
  53. package/lib/plugins.d.ts +0 -99
  54. package/lib/plugins.js +0 -9
  55. package/lib/plugins.js.map +0 -1
  56. package/lib/tsconfig.tsbuildinfo +0 -1
  57. package/lib/utils.d.ts +0 -6
  58. package/lib/utils.js +0 -44
  59. package/lib/utils.js.map +0 -1
  60. package/lib/versions.d.ts +0 -6
  61. package/lib/versions.js +0 -28
  62. package/lib/versions.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/main.ts","../src/partials/assets.ts","../src/partials/editor.ts","../src/partials/ffmpegBridge.ts","../src/partials/imageExporter.ts","../src/openInExplorer.ts","../src/partials/meta.ts","../src/partials/metrics.ts","../src/partials/projects.ts","../src/partials/rive.ts","../src/partials/settings.ts","../src/partials/wasmExporter.ts","../src/partials/webgl.ts","../src/plugins.ts","../src/utils.ts"],"sourcesContent":["import motionCanvas from './main';\n\nexport default motionCanvas;\nexport * from './plugins';\n","import path from 'path';\nimport type {Plugin} from 'vite';\nimport {\n assetsPlugin,\n editorPlugin,\n exporterPlugin,\n ffmpegBridgePlugin,\n metaPlugin,\n metricsPlugin,\n projectsPlugin,\n rivePlugin,\n settingsPlugin,\n wasmExporterPlugin,\n webglPlugin,\n} from './partials';\nimport type {PluginOptions} from './plugins';\nimport {PLUGIN_OPTIONS, isPlugin} from './plugins';\nimport {getProjects} from './utils';\n\nexport interface MotionCanvasPluginConfig {\n /**\n * The import path of the project file or an array of paths.\n * Also supports globs.\n *\n * @remarks\n * Each file must contain a default export exposing an instance of the\n * {@link Project} class.\n *\n * @example\n * ```ts\n * motionCanvas({\n * project: [\n * './src/firstProject.ts',\n * './src/secondProject.ts',\n * ]\n * })\n * ```\n *\n * @defaultValue './src/project.ts'\n */\n project?: string | string[];\n /**\n * A directory path to which the animation will be rendered.\n *\n * @defaultValue './output'\n */\n output?: string;\n /**\n * Defines which assets should be buffered before being sent to the browser.\n *\n * @remarks\n * Streaming larger assets directly from the drive may cause issues with other\n * applications. For instance, if an audio file is being used in the project,\n * Adobe Audition will perceive it as \"being used by another application\"\n * and refuse to override it.\n *\n * Buffered assets are first loaded to the memory and then streamed from\n * there. This leaves the original files open for modification with hot module\n * replacement still working.\n *\n * @defaultValue /^$/\n */\n bufferedAssets?: RegExp | false;\n /**\n * The import path of the editor package.\n *\n * @remarks\n * This path will be resolved using Node.js module resolution rules.\n * It should lead to a directory containing the following files:\n * - `editor.html` - The HTML template for the editor.\n * - `styles.css` - The editor styles.\n * - `main.js` - A module exporting necessary factory functions.\n *\n * `main.js` should export the following functions:\n * - `editor` - Receives the project factory as its first argument and creates\n * the user interface.\n * - `index` - Receives a list of all projects as its first argument and\n * creates the initial page for selecting a project.\n *\n * @defaultValue '\\@twick/ui'\n */\n editor?: string;\n\n /**\n * Build the project to run in the editor.\n */\n buildForEditor?: boolean;\n}\n\nexport default ({\n project = './src/project.ts',\n output = './output',\n bufferedAssets = /^$/,\n editor = '@twick/ui',\n buildForEditor,\n}: MotionCanvasPluginConfig = {}): Plugin[] => {\n const plugins: PluginOptions[] = [];\n const outputPath = path.resolve(output);\n const projects = getProjects(project);\n\n return [\n {\n name: 'twick',\n async configResolved(resolvedConfig) {\n plugins.push(\n ...resolvedConfig.plugins\n .filter(isPlugin)\n .map(plugin => plugin[PLUGIN_OPTIONS]),\n );\n await Promise.all(\n plugins.map(plugin =>\n plugin.config?.({\n output: outputPath,\n projects: projects.list,\n }),\n ),\n );\n },\n },\n metaPlugin(),\n settingsPlugin(),\n exporterPlugin({outputPath}),\n ffmpegBridgePlugin({output: outputPath}),\n editorPlugin({editor, projects}),\n projectsPlugin({projects, plugins, buildForEditor}),\n assetsPlugin({bufferedAssets}),\n wasmExporterPlugin(),\n rivePlugin(),\n webglPlugin(),\n metricsPlugin(),\n ];\n};\n","import fs from 'fs';\nimport path from 'path';\nimport {Readable} from 'stream';\nimport type {ModuleNode, Plugin, ResolvedConfig} from 'vite';\n\nconst AUDIO_EXTENSION_REGEX = /\\.(mp3|wav|ogg|aac|flac)(?:$|\\?)/;\nconst AUDIO_HMR_DELAY = 1000;\n\ninterface AssetsPluginConfig {\n bufferedAssets: RegExp | false;\n}\n\nexport function assetsPlugin({bufferedAssets}: AssetsPluginConfig): Plugin {\n let config: ResolvedConfig;\n return {\n name: 'twick:assets',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n if (req.url && bufferedAssets && bufferedAssets.test(req.url)) {\n const file = fs.readFileSync(\n path.resolve(config.root, req.url.slice(1)),\n );\n Readable.from(file).pipe(res);\n return;\n }\n\n next();\n });\n },\n\n async handleHotUpdate(ctx) {\n const urls = [];\n const modules: ModuleNode[] = [];\n\n for (const module of ctx.modules) {\n urls.push(module.url);\n if (!AUDIO_EXTENSION_REGEX.test(module.url)) {\n modules.push(module);\n } else {\n await new Promise(resolve => {\n setTimeout(resolve, AUDIO_HMR_DELAY);\n });\n }\n }\n\n if (urls.length > 0) {\n ctx.server.ws.send('twick:assets', {urls});\n }\n\n return modules;\n },\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport type {Plugin} from 'vite';\nimport type {Projects} from '../utils';\n\ninterface EditorPluginConfig {\n editor: string;\n projects: Projects;\n}\n\nexport function editorPlugin({editor, projects}: EditorPluginConfig): Plugin {\n const editorPath = path.dirname(require.resolve(editor));\n const editorFile = fs.readFileSync(path.resolve(editorPath, 'editor.html'));\n const htmlParts = editorFile\n .toString()\n .replace('{{style}}', `/@fs/${path.resolve(editorPath, 'style.css')}`)\n .split('{{source}}');\n const createHtml = (src: string) => htmlParts[0] + src + htmlParts[1];\n\n const resolvedEditorId = '\\0virtual:editor';\n\n return {\n name: 'twick:editor',\n\n async load(id) {\n const [, query] = id.split('?');\n\n if (id.startsWith(resolvedEditorId)) {\n if (projects.list.length === 1) {\n /* language=typescript */\n return `\\\nimport {editor} from '${editor}';\nimport project from '${projects.list[0].url}';\nimport {addEditorToProject} from '@twick/core';\neditor(await addEditorToProject(project));\n`;\n }\n\n if (query) {\n const params = new URLSearchParams(query);\n const name = params.get('project');\n if (name && projects.lookup.has(name)) {\n /* language=typescript */\n return `\\\nimport {editor} from '${editor}';\nimport project from '${projects.lookup.get(name)!.url}';\nimport {addEditorToProject} from '@twick/core';\neditor(await addEditorToProject(project));\n`;\n }\n }\n\n /* language=typescript */\n return `\\\nimport {index} from '${editor}';\nindex(${JSON.stringify(projects.list)});\n`;\n }\n },\n\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n if (req.url) {\n const url = new URL(req.url, `http://${req.headers.host}`);\n if (url.pathname === '/') {\n res.setHeader('Content-Type', 'text/html');\n res.end(createHtml('/@id/__x00__virtual:editor'));\n return;\n }\n\n const name = url.pathname.slice(1);\n if (name && projects.lookup.has(name)) {\n res.setHeader('Content-Type', 'text/html');\n res.end(createHtml(`/@id/__x00__virtual:editor?project=${name}`));\n return;\n }\n }\n\n next();\n });\n },\n };\n}\n","import type {FFmpegExporterSettings} from '@twick/ffmpeg';\nimport {\n FFmpegExporterServer,\n VideoFrameExtractor,\n generateAudio,\n mergeMedia,\n} from '@twick/ffmpeg';\nimport {existsSync, unlinkSync} from 'fs';\nimport type {IncomingMessage, ServerResponse} from 'http';\nimport type {Plugin, WebSocketServer} from 'vite';\n\ninterface BrowserRequest {\n method: string;\n data: unknown;\n}\n\ninterface ExporterPluginConfig {\n output: string;\n}\n\nexport function ffmpegBridgePlugin({output}: ExporterPluginConfig): Plugin {\n return {\n name: 'twick/ffmpeg',\n\n configureServer(server) {\n const ffmpegBridge = new FFmpegBridge(server.ws, {output});\n\n const handlePostRequest = async (\n req: IncomingMessage,\n res: ServerResponse,\n handler: (data: any) => Promise<any>,\n ) => {\n if (req.method !== 'POST') {\n res.statusCode = 405;\n res.end('Method Not Allowed');\n return;\n }\n\n try {\n const body: any = await new Promise((resolve, reject) => {\n let data = '';\n req.on('data', (chunk: string) => (data += chunk));\n req.on('end', () => resolve(data));\n req.on('error', reject);\n });\n\n const parsedBody = JSON.parse(body);\n const result = await handler(parsedBody);\n\n if (res.writableEnded) {\n return;\n }\n\n res.statusCode = 200;\n if (result) {\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(result));\n return;\n }\n res.end('OK');\n } catch (error) {\n console.error('error in request handler', error);\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n };\n\n server.middlewares.use('/audio-processing/generate-audio', (req, res) =>\n handlePostRequest(\n req,\n res,\n async ({tempDir, assets, startFrame, endFrame, fps}) =>\n generateAudio({\n outputDir: output,\n tempDir,\n assets,\n startFrame,\n endFrame,\n fps,\n }),\n ),\n );\n\n server.middlewares.use('/audio-processing/merge-media', (req, res) =>\n handlePostRequest(req, res, async ({outputFilename, tempDir, format}) =>\n mergeMedia(outputFilename, output, tempDir, format),\n ),\n );\n\n server.middlewares.use(\n '/twick-ffmpeg-decoder/video-frame',\n (req, res) =>\n handlePostRequest(req, res, async data => {\n const {frame, width, height} =\n await ffmpegBridge.handleDecodeVideoFrame(data);\n res.setHeader('X-Frame-Width', width.toString());\n res.setHeader('X-Frame-Height', height.toString());\n res.setHeader('Content-Type', 'application/octet-stream');\n res.end(Buffer.from(frame as Buffer));\n }),\n );\n\n server.middlewares.use('/twick-ffmpeg-decoder/finished', (req, res) => {\n handlePostRequest(req, res, async () => {\n await ffmpegBridge.handleRenderFinished();\n });\n });\n\n server.middlewares.use(\n '/twick-ffmpeg-decoder/download-video-chunks',\n (req, res) =>\n handlePostRequest(req, res, async videoDurations => {\n const downloadedPaths =\n await ffmpegBridge.handleDownloadVideoChunks(videoDurations);\n return {success: true, paths: downloadedPaths};\n }),\n );\n },\n };\n}\n\n/**\n * A simple bridge between the FFmpegExporterServer and FFmpegExporterClient.\n *\n * @remarks\n * This class lets the client exporter invoke methods on the server and receive\n * responses using a simple Promise-based API.\n */\nexport class FFmpegBridge {\n private process: FFmpegExporterServer | null = null;\n\n public constructor(\n private readonly ws: WebSocketServer,\n private readonly config: ExporterPluginConfig,\n ) {\n ws.on('twick:ffmpeg-exporter', this.handleMessage);\n }\n\n private handleMessage = async ({method, data}: BrowserRequest) => {\n if (method === 'start') {\n try {\n this.process = new FFmpegExporterServer({\n ...(data as FFmpegExporterSettings),\n ...this.config,\n });\n this.respondSuccess(method, await this.process.start());\n } catch (e: any) {\n this.respondError(method, e?.message);\n }\n return;\n }\n\n if (!this.process) {\n this.respondError(method, 'The exporting process has not been started.');\n return;\n }\n\n if (!(method in this.process)) {\n this.respondError(method, `Unknown method: \"${method}\".`);\n return;\n }\n\n try {\n this.respondSuccess(method, await (this.process as any)[method](data));\n } catch (e: any) {\n this.respondError(method, e?.message);\n }\n\n if (method === 'kill') {\n this.process = null;\n return;\n }\n };\n\n private respondSuccess(method: string, data: any = {}) {\n this.ws.send('twick:ffmpeg-exporter-ack', {\n status: 'success',\n method,\n data,\n });\n }\n\n private respondError(method: string, message = 'Unknown error.') {\n this.ws.send('twick:ffmpeg-exporter-ack', {\n status: 'error',\n method,\n message,\n });\n }\n\n // List of VideoFrameExtractors\n private videoFrameExtractors = new Map<string, VideoFrameExtractor>();\n\n public async handleDownloadVideoChunks(\n videoDurations: {src: string; startTime: number; endTime: number}[],\n ) {\n const downloadPromises = videoDurations.map(({src, startTime, endTime}) =>\n VideoFrameExtractor.downloadVideoChunk(src, startTime, endTime),\n );\n await Promise.all(downloadPromises);\n }\n\n public async handleDecodeVideoFrame(data: {\n id: string;\n filePath: string;\n startTime: number;\n duration: number;\n fps: number;\n }) {\n const typedData = data as {\n id: string;\n filePath: string;\n startTime: number;\n duration: number;\n fps: number;\n };\n\n // Check if we already have a VideoFrameExtractor for this video\n const id = typedData.filePath + '-' + typedData.id;\n let extractor = this.videoFrameExtractors.get(id);\n\n const frameDuration = 1 / typedData.fps;\n\n const isOldFrame =\n extractor &&\n Math.abs(typedData.startTime - extractor.getLastTime()) <\n frameDuration / 2;\n\n // If time has not changed, return the last frame\n if (isOldFrame) {\n const frame = extractor!.getLastFrame();\n return {\n frame,\n width: extractor!.getWidth(),\n height: extractor!.getHeight(),\n };\n }\n\n // If the video has skipped back we need to create a new extractor\n if (\n extractor &&\n typedData.startTime + frameDuration < extractor.getTime()\n ) {\n extractor.destroy();\n this.videoFrameExtractors.delete(id);\n extractor = undefined;\n }\n\n // If the video has skipped forward we need to create a new extractor\n if (\n extractor &&\n typedData.startTime > extractor.getTime() + frameDuration\n ) {\n extractor.destroy();\n this.videoFrameExtractors.delete(id);\n extractor = undefined;\n }\n\n if (!extractor) {\n extractor = new VideoFrameExtractor(\n data.filePath,\n data.startTime,\n data.fps,\n data.duration,\n );\n this.videoFrameExtractors.set(id, extractor);\n }\n\n // Go to the frame that is closest to the requested time\n const frame = await extractor.popImage();\n\n return {\n frame: frame,\n width: extractor!.getWidth(),\n height: extractor!.getHeight(),\n };\n }\n\n public async handleRenderFinished() {\n this.videoFrameExtractors.forEach(extractor => {\n extractor.destroy();\n const localFile = VideoFrameExtractor.downloadedVideoMap.get(\n extractor.filePath,\n )?.localPath;\n if (localFile && existsSync(localFile)) {\n unlinkSync(localFile);\n }\n });\n this.videoFrameExtractors.clear();\n }\n}\n","import fs from 'fs';\nimport mime from 'mime-types';\nimport path from 'path';\nimport type {Plugin} from 'vite';\nimport {openInExplorer} from '../openInExplorer';\n\ninterface ExporterPluginConfig {\n outputPath: string;\n}\n\nexport function exporterPlugin({outputPath}: ExporterPluginConfig): Plugin {\n return {\n name: 'twick:exporter',\n\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n if (req.url === '/__open-output-path') {\n if (!fs.existsSync(outputPath)) {\n fs.mkdirSync(outputPath, {recursive: true});\n }\n openInExplorer(outputPath);\n res.end();\n return;\n }\n\n next();\n });\n\n server.ws.on(\n 'twick:export',\n async (\n {data, frame, sceneFrame, subDirectories, mimeType, groupByScene},\n client,\n ) => {\n const name = (groupByScene ? sceneFrame : frame)\n .toString()\n .padStart(6, '0');\n const extension = mime.extension(mimeType);\n const outputFilePath = path.join(\n outputPath,\n ...subDirectories,\n `${name}.${extension}`,\n );\n const outputDirectory = path.dirname(outputFilePath);\n\n if (!fs.existsSync(outputDirectory)) {\n fs.mkdirSync(outputDirectory, {recursive: true});\n }\n\n const base64Data = data.slice(data.indexOf(',') + 1);\n await fs.promises.writeFile(outputFilePath, base64Data, {\n encoding: 'base64',\n });\n client.send('twick:export-ack', {frame});\n },\n );\n },\n };\n}\n","import {execSync, spawn} from 'child_process';\nimport {platform} from 'os';\n\nexport function openInExplorer(file: string) {\n let command: string | null = null;\n let args = [file];\n const os = platform();\n\n switch (os) {\n case 'win32':\n command = 'explorer';\n break;\n case 'linux':\n if (isRunningOnWSL()) {\n command = 'bash';\n args = ['-c', `cd ${file} && explorer.exe .`];\n } else {\n command = 'xdg-open';\n }\n break;\n case 'darwin':\n command = 'open';\n break;\n }\n\n if (command) {\n spawn(command, args, {detached: true}).unref();\n } else {\n console.warn(`Unsupported OS: ${os}`);\n }\n}\n\nfunction isRunningOnWSL(): boolean {\n try {\n const uname = execSync('uname -a').toString().toLowerCase();\n return uname.includes('microsoft');\n } catch (error) {\n console.error(`exec error: ${error}`);\n return false;\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport type {Plugin, ResolvedConfig} from 'vite';\n\nexport function metaPlugin(): Plugin {\n const timeStamps: Record<string, number> = {};\n let config: ResolvedConfig;\n return {\n name: 'twick:meta',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n\n async transform(code, id) {\n const [base] = id.split('?');\n const {name, ext} = path.posix.parse(base);\n if (ext !== '.meta') {\n return;\n }\n\n const sourceFile =\n config.command === 'build' ? false : JSON.stringify(id);\n\n /* language=typescript */\n return `\\\nimport {MetaFile} from '@twick/core';\nlet meta;\nif (import.meta.hot) {\n meta = import.meta.hot.data.meta;\n}\nmeta ??= new MetaFile('${name}', ${sourceFile});\nif (import.meta.hot) {\n import.meta.hot.accept();\n import.meta.hot.data.meta = meta;\n}\nmeta.loadData(${code});\nexport default meta;\n`;\n },\n\n configureServer(server) {\n server.ws.on('twick:meta', async ({source, data}, client) => {\n // Ignore virtual meta files.\n if (source.startsWith('\\0')) {\n return;\n }\n\n timeStamps[source] = Date.now();\n if (!process.env.DONT_WRITE_TO_META_FILES) {\n await fs.promises.writeFile(\n source,\n JSON.stringify(data, undefined, 2),\n 'utf8',\n );\n }\n client.send('twick:meta-ack', {source});\n });\n },\n\n handleHotUpdate(ctx) {\n const now = Date.now();\n const modules = [];\n\n for (const module of ctx.modules) {\n if (\n module.file !== null &&\n timeStamps[module.file] &&\n timeStamps[module.file] + 1000 > now\n ) {\n continue;\n }\n\n modules.push(module);\n }\n\n return modules;\n },\n };\n}\n","import {EventName, sendEvent} from '@twick/telemetry';\nimport type {Plugin} from 'vite';\n\nexport function metricsPlugin(): Plugin {\n return {\n name: 'twick:metrics',\n\n async configResolved() {\n sendEvent(EventName.ServerStarted);\n },\n };\n}\n","import type {Plugin} from 'vite';\nimport type {PluginOptions} from '../plugins';\nimport type {Projects} from '../utils';\n// import {getVersions} from '../versions';\n\ninterface ProjectPluginConfig {\n buildForEditor?: boolean;\n plugins: PluginOptions[];\n projects: Projects;\n}\n\nexport function projectsPlugin({\n buildForEditor,\n projects,\n}: ProjectPluginConfig): Plugin {\n // TODO(refactor): use version information\n // const versions = JSON.stringify(getVersions());\n return {\n name: 'twick:project',\n\n config(config) {\n return {\n build: {\n target: buildForEditor ? 'esnext' : 'modules',\n assetsDir: './',\n rollupOptions: {\n preserveEntrySignatures: 'strict',\n input: Object.fromEntries(\n projects.list.map(project => [project.name, project.url]),\n ),\n },\n },\n server: {\n port: config?.server?.port ?? 9000,\n },\n esbuild: {\n jsx: 'automatic',\n jsxImportSource: '@twick/2d/lib',\n },\n optimizeDeps: {\n entries: projects.list.map(project => project.url),\n exclude: ['preact', 'preact/*', '@preact/signals'],\n },\n };\n },\n };\n}\n","import * as fs from 'fs';\nimport path from 'path';\nimport {Readable} from 'stream';\nimport type {Plugin} from 'vite';\n\nasync function getRiveWasmPath() {\n try {\n const packageJsonPath = require.resolve(\n '@rive-app/canvas-advanced/package.json',\n );\n const packageDir = path.dirname(packageJsonPath);\n const wasmPath = path.join(packageDir, 'rive.wasm');\n\n await fs.promises.access(wasmPath, fs.constants.F_OK);\n\n return wasmPath;\n } catch (error) {\n console.error('Error finding Rive WASM file:', error);\n throw new Error('Could not find Rive WASM file');\n }\n}\n\nexport function rivePlugin(): Plugin {\n return {\n name: 'twick:rive-wasm',\n configureServer(server) {\n server.middlewares.use(async (req, res, next) => {\n if (req.url && req.url === '/@rive-wasm') {\n try {\n const wasmPath = await getRiveWasmPath();\n const file = await fs.promises.readFile(wasmPath);\n\n res.setHeader('Content-Type', 'application/wasm');\n Readable.from(file).pipe(res);\n } catch (error) {\n console.error('Error serving Rive WASM file:', error);\n res.statusCode = 500;\n res.end('Error serving Rive WASM file');\n }\n return;\n }\n next();\n });\n },\n };\n}\n","import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport type {Plugin} from 'vite';\n\nexport function settingsPlugin(): Plugin {\n const settingsId = 'virtual:settings.meta';\n const resolvedSettingsId = '\\0' + settingsId;\n const settingsPath = path.resolve(os.homedir(), '.twick/settings.json');\n const outputDirectory = path.dirname(settingsPath);\n\n return {\n name: 'twick:settings',\n\n resolveId(id) {\n if (id === settingsId) {\n return resolvedSettingsId;\n }\n },\n\n async load(id) {\n if (id === resolvedSettingsId) {\n let parsed = {};\n try {\n parsed = JSON.parse(await fs.promises.readFile(settingsPath, 'utf8'));\n } catch (_) {\n // Ignore an invalid settings file\n }\n\n return JSON.stringify(parsed);\n }\n },\n\n configureServer(server) {\n server.ws.on('twick:meta', async ({source, data}, client) => {\n if (source !== resolvedSettingsId) {\n return;\n }\n\n await fs.promises.mkdir(outputDirectory, {recursive: true});\n const newData = JSON.stringify(data, undefined, 2);\n let oldData = '';\n try {\n oldData = await fs.promises.readFile(settingsPath, 'utf8');\n } catch (_) {\n // Ignore an invalid settings file\n }\n\n if (oldData !== newData) {\n await Promise.all([\n fs.promises.writeFile(settingsPath, newData, 'utf8'),\n // Invalidate the module so that the settings are up-to-date next\n // time the browser is refreshed.\n server.moduleGraph.getModuleByUrl(source).then(module => {\n if (module) {\n server.moduleGraph.invalidateModule(module);\n }\n }),\n ]);\n }\n\n client.send('twick:meta-ack', {source});\n });\n },\n };\n}\n","import type formidable from 'formidable';\nimport {IncomingForm} from 'formidable';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport path from 'path';\nimport {Readable} from 'stream';\nimport type {Plugin} from 'vite';\n\nexport function wasmExporterPlugin(): Plugin {\n return {\n name: 'twick:mp4-wasm',\n\n configureServer(server) {\n // Virtual file for mp4-wasm\n server.middlewares.use(async (req, res, next) => {\n if (req.url && req.url === '/@mp4-wasm') {\n const pathNew = path.dirname(require.resolve('mp4-wasm'));\n const filePath = path.resolve(pathNew, 'mp4.wasm');\n const file = await fs.promises.readFile(filePath);\n\n res.setHeader('Content-Type', 'application/wasm');\n Readable.from(file).pipe(res);\n return;\n }\n\n next();\n });\n\n // Endpoint to download the video file from the client\n server.middlewares.use('/uploadVideoFile', async (req, res) => {\n if (req.method === 'POST') {\n const form = new IncomingForm({maxFileSize: 1024 * 1024 * 1024 * 10}); // 10GB limit\n\n form.parse(req, async (err, fields, files) => {\n if (err) {\n console.error('Error parsing form:', err);\n res.statusCode = 500;\n res.end();\n return;\n }\n\n try {\n const tempDir = fields.tempDir![0];\n const file = files.file![0] as formidable.File;\n\n const outputPath = path.join(os.tmpdir(), tempDir, 'visuals.mp4');\n const writeStream = fs.createWriteStream(outputPath);\n\n await new Promise((resolve, reject) => {\n fs.createReadStream(file.filepath)\n .pipe(writeStream)\n .on('finish', resolve)\n .on('error', reject);\n });\n\n res.statusCode = 200;\n res.end();\n } catch (err) {\n console.error('Error uploading video:', err);\n res.statusCode = 500;\n res.end();\n }\n });\n }\n });\n },\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport {SourceNode} from 'source-map';\nimport type {Plugin, ResolvedConfig} from 'vite';\nimport {normalizePath} from 'vite';\n\ndeclare module 'source-map' {\n interface SourceNode {\n add(value: string | SourceNode): void;\n }\n\n interface SourceMapGenerator {\n toJSON(): any;\n }\n}\n\nconst GLSL_EXTENSION_REGEX = /\\.glsl(?:$|\\?)/;\nconst INCLUDE_REGEX = /^#include \"([^\"]+)\"/;\n\nexport function webglPlugin(): Plugin {\n let config: ResolvedConfig;\n return {\n name: 'twick:webgl',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig;\n },\n\n async transform(code, id) {\n if (!GLSL_EXTENSION_REGEX.test(id)) {\n return;\n }\n\n const [base, query] = id.split('?');\n const {dir} = path.posix.parse(base);\n const params = new URLSearchParams(query);\n if (params.has('raw')) {\n return;\n }\n\n const context: ResolutionContext = {\n rootDir: dir,\n fileStack: [],\n includeMap: new Map(),\n watchFile: file => this.addWatchFile(file),\n resolve: async (source, importer) => {\n const resolved = await this.resolve(source, importer);\n return resolved?.id;\n },\n };\n\n const glslSource = await resolveGlsl(context, id, code);\n const sourceUrl = normalizePath(path.relative(config.root, base));\n\n const result = glslSource.toStringWithSourceMap();\n const map = result.map.toJSON();\n map.includeMap = Object.fromEntries(context.includeMap);\n\n return {\n map,\n code: `export default \\`${result.code}\\n//# sourceURL=${sourceUrl}\\`;`,\n };\n },\n };\n}\n\ninterface ResolutionContext {\n watchFile: (file: string) => void;\n resolve: (source: string, importer: string) => Promise<string | undefined>;\n rootDir: string;\n includeMap: Map<string, [string, number]>;\n fileStack: string[];\n}\n\nasync function resolveGlsl(\n context: ResolutionContext,\n id: string,\n code: string,\n): Promise<SourceNode> {\n const lines = code.split(/\\r?\\n/);\n const source = new SourceNode(1, 0, '', '');\n\n if (context.fileStack.includes(id)) {\n throw new Error(\n `Circular dependency detected: ${context.fileStack.join(' -> ')}`,\n );\n }\n\n context.fileStack.push(id);\n\n const sourceMapId = path.posix.relative(context.rootDir, id);\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n const match = line.match(INCLUDE_REGEX);\n if (match) {\n const childId = await context.resolve(match[1], id);\n if (!childId) {\n continue;\n }\n\n const childSourceMapId = path.posix.relative(context.rootDir, childId);\n if (context.includeMap.has(childSourceMapId)) {\n continue;\n }\n\n context.includeMap.set(childSourceMapId, [sourceMapId, i + 1]);\n context.watchFile(childId);\n const childCode = await fs.promises.readFile(childId, 'utf-8');\n source.add(await resolveGlsl(context, childId, childCode));\n } else {\n let j = 0;\n for (; j < line.length; j++) {\n source.add(new SourceNode(i + 1, j, sourceMapId, line[j]));\n }\n source.add(new SourceNode(i + 1, j, sourceMapId, '\\n'));\n }\n }\n context.fileStack.pop();\n\n return source;\n}\n","import type {Plugin as VitePlugin} from 'vite';\n\n/**\n * Represents a Twick project configured in the Vite plugin.\n */\nexport interface ProjectData {\n /**\n * The name of the project.\n */\n name: string;\n /**\n * The file name containing the project.\n */\n fileName: string;\n /**\n * The path to the project relative to the Vite configuration file.\n */\n url: string;\n}\n\n/**\n * The Twick configuration passed to each plugin.\n */\nexport interface PluginConfig {\n /**\n * The projects configured in the Vite plugin.\n */\n projects: ProjectData[];\n /**\n * The output path relative to the Vite configuration file.\n */\n output: string;\n}\n\nexport const PLUGIN_OPTIONS = Symbol.for('@twick/vite-plugin/PLUGIN_OPTIONS');\n\nexport interface PluginOptions {\n /**\n * An entry point of the runtime plugin.\n *\n * @remarks\n * While the Vite plugin can extend the backend functionality, this entry\n * point lets you include custom runtime code that will be loaded by the\n * browser.\n *\n * It should be a valid module specifier from which the plugin will be\n * imported. The module should contain a default export of a runtime plugin.\n */\n entryPoint: string;\n\n /**\n * The configuration hook of the plugin.\n *\n * @remarks\n * Invoked during `configResolved` hook of Vite, contains the Twick\n * specific configuration.\n *\n * @param config - The configuration passed to the plugin.\n */\n config?(config: PluginConfig): Promise<void>;\n\n /**\n * Get custom configuration that will be passed to the runtime plugin.\n *\n * @remarks\n * The config will be passed as the first argument to the default export of\n * the runtime plugin. When provided as a string, it will be injected to the\n * code as is, letting you define non-serializable values such as functions.\n *\n * If the returned value is an object, it will be converted to a JavaScript\n * object using JSON serialization.\n *\n * @example\n * Returning an object:\n * ```ts\n * {\n * runtimeConfig: () => ({\n * myText: 'Hello!',\n * myNumber: 42,\n * })\n * }\n * ```\n * Returning a string:\n * ```ts\n * {\n * runtimeConfig: () => `{myRegex: /\\\\.wav$/}`\n * }\n * ```\n */\n runtimeConfig?(): Promise<any>;\n}\n\n/**\n * Represents a Twick plugin.\n *\n * @remarks\n * It's a normal Vite plugin that can provide additional configuration specific\n * to Twick.\n */\nexport type Plugin = VitePlugin & {\n /**\n * The configuration specific to Twick.\n */\n [PLUGIN_OPTIONS]: PluginOptions;\n};\n\nexport function isPlugin(value: any): value is Plugin {\n return value && typeof value === 'object' && PLUGIN_OPTIONS in value;\n}\n","import fg from 'fast-glob';\nimport fs from 'fs';\nimport path from 'path';\nimport type {ProjectData} from './plugins';\n\nexport interface Projects {\n list: ProjectData[];\n lookup: Map<string, ProjectData>;\n}\n\nexport function getProjects(project: string | string[]): Projects {\n const list: ProjectData[] = [];\n const lookup = new Map<string, ProjectData>();\n\n const projectList = expandFilePaths(project);\n for (const url of projectList) {\n const {name, dir} = path.posix.parse(url);\n const metaFile = `${name}.meta`;\n const metaData = getMeta(path.join(dir, metaFile));\n const data = {name: metaData?.name ?? name, fileName: name, url};\n list.push(data);\n lookup.set(data.name, data);\n }\n\n return {list, lookup};\n}\n\nfunction expandFilePaths(filePaths: string[] | string): string[] {\n const expandedFilePaths = [];\n\n for (const filePath of typeof filePaths === 'string'\n ? [filePaths]\n : filePaths) {\n if (fg.isDynamicPattern(filePath)) {\n const matchingFilePaths = fg.sync(filePath, {onlyFiles: true});\n expandedFilePaths.push(...matchingFilePaths);\n } else {\n expandedFilePaths.push(filePath);\n }\n }\n\n return expandedFilePaths;\n}\n\nfunction getMeta(metaPath: string) {\n if (fs.existsSync(metaPath)) {\n return JSON.parse(fs.readFileSync(metaPath, 'utf8'));\n }\n}\n"],"mappings":"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","names":["import_path","fs","path","module","import_fs","import_path","path","fs","import_fs","frame","import_fs","import_path","os","fs","mime","path","import_fs","import_path","path","fs","module","fs","import_path","import_stream","path","import_fs","import_os","import_path","path","os","fs","module","fs","os","import_path","import_stream","path","err","import_fs","import_path","path","fs","import_fs","import_path","path","fg","fs","path"]}
@@ -0,0 +1,172 @@
1
+ import { Plugin as Plugin$1 } from 'vite';
2
+
3
+ interface MotionCanvasPluginConfig {
4
+ /**
5
+ * The import path of the project file or an array of paths.
6
+ * Also supports globs.
7
+ *
8
+ * @remarks
9
+ * Each file must contain a default export exposing an instance of the
10
+ * {@link Project} class.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * motionCanvas({
15
+ * project: [
16
+ * './src/firstProject.ts',
17
+ * './src/secondProject.ts',
18
+ * ]
19
+ * })
20
+ * ```
21
+ *
22
+ * @defaultValue './src/project.ts'
23
+ */
24
+ project?: string | string[];
25
+ /**
26
+ * A directory path to which the animation will be rendered.
27
+ *
28
+ * @defaultValue './output'
29
+ */
30
+ output?: string;
31
+ /**
32
+ * Defines which assets should be buffered before being sent to the browser.
33
+ *
34
+ * @remarks
35
+ * Streaming larger assets directly from the drive may cause issues with other
36
+ * applications. For instance, if an audio file is being used in the project,
37
+ * Adobe Audition will perceive it as "being used by another application"
38
+ * and refuse to override it.
39
+ *
40
+ * Buffered assets are first loaded to the memory and then streamed from
41
+ * there. This leaves the original files open for modification with hot module
42
+ * replacement still working.
43
+ *
44
+ * @defaultValue /^$/
45
+ */
46
+ bufferedAssets?: RegExp | false;
47
+ /**
48
+ * The import path of the editor package.
49
+ *
50
+ * @remarks
51
+ * This path will be resolved using Node.js module resolution rules.
52
+ * It should lead to a directory containing the following files:
53
+ * - `editor.html` - The HTML template for the editor.
54
+ * - `styles.css` - The editor styles.
55
+ * - `main.js` - A module exporting necessary factory functions.
56
+ *
57
+ * `main.js` should export the following functions:
58
+ * - `editor` - Receives the project factory as its first argument and creates
59
+ * the user interface.
60
+ * - `index` - Receives a list of all projects as its first argument and
61
+ * creates the initial page for selecting a project.
62
+ *
63
+ * @defaultValue '\@twick/ui'
64
+ */
65
+ editor?: string;
66
+ /**
67
+ * Build the project to run in the editor.
68
+ */
69
+ buildForEditor?: boolean;
70
+ }
71
+ declare const _default: ({ project, output, bufferedAssets, editor, buildForEditor, }?: MotionCanvasPluginConfig) => Plugin$1[];
72
+
73
+ /**
74
+ * Represents a Twick project configured in the Vite plugin.
75
+ */
76
+ interface ProjectData {
77
+ /**
78
+ * The name of the project.
79
+ */
80
+ name: string;
81
+ /**
82
+ * The file name containing the project.
83
+ */
84
+ fileName: string;
85
+ /**
86
+ * The path to the project relative to the Vite configuration file.
87
+ */
88
+ url: string;
89
+ }
90
+ /**
91
+ * The Twick configuration passed to each plugin.
92
+ */
93
+ interface PluginConfig {
94
+ /**
95
+ * The projects configured in the Vite plugin.
96
+ */
97
+ projects: ProjectData[];
98
+ /**
99
+ * The output path relative to the Vite configuration file.
100
+ */
101
+ output: string;
102
+ }
103
+ declare const PLUGIN_OPTIONS: unique symbol;
104
+ interface PluginOptions {
105
+ /**
106
+ * An entry point of the runtime plugin.
107
+ *
108
+ * @remarks
109
+ * While the Vite plugin can extend the backend functionality, this entry
110
+ * point lets you include custom runtime code that will be loaded by the
111
+ * browser.
112
+ *
113
+ * It should be a valid module specifier from which the plugin will be
114
+ * imported. The module should contain a default export of a runtime plugin.
115
+ */
116
+ entryPoint: string;
117
+ /**
118
+ * The configuration hook of the plugin.
119
+ *
120
+ * @remarks
121
+ * Invoked during `configResolved` hook of Vite, contains the Twick
122
+ * specific configuration.
123
+ *
124
+ * @param config - The configuration passed to the plugin.
125
+ */
126
+ config?(config: PluginConfig): Promise<void>;
127
+ /**
128
+ * Get custom configuration that will be passed to the runtime plugin.
129
+ *
130
+ * @remarks
131
+ * The config will be passed as the first argument to the default export of
132
+ * the runtime plugin. When provided as a string, it will be injected to the
133
+ * code as is, letting you define non-serializable values such as functions.
134
+ *
135
+ * If the returned value is an object, it will be converted to a JavaScript
136
+ * object using JSON serialization.
137
+ *
138
+ * @example
139
+ * Returning an object:
140
+ * ```ts
141
+ * {
142
+ * runtimeConfig: () => ({
143
+ * myText: 'Hello!',
144
+ * myNumber: 42,
145
+ * })
146
+ * }
147
+ * ```
148
+ * Returning a string:
149
+ * ```ts
150
+ * {
151
+ * runtimeConfig: () => `{myRegex: /\\.wav$/}`
152
+ * }
153
+ * ```
154
+ */
155
+ runtimeConfig?(): Promise<any>;
156
+ }
157
+ /**
158
+ * Represents a Twick plugin.
159
+ *
160
+ * @remarks
161
+ * It's a normal Vite plugin that can provide additional configuration specific
162
+ * to Twick.
163
+ */
164
+ type Plugin = Plugin$1 & {
165
+ /**
166
+ * The configuration specific to Twick.
167
+ */
168
+ [PLUGIN_OPTIONS]: PluginOptions;
169
+ };
170
+ declare function isPlugin(value: any): value is Plugin;
171
+
172
+ export { PLUGIN_OPTIONS, type Plugin, type PluginConfig, type PluginOptions, type ProjectData, _default as default, isPlugin };
@@ -0,0 +1,172 @@
1
+ import { Plugin as Plugin$1 } from 'vite';
2
+
3
+ interface MotionCanvasPluginConfig {
4
+ /**
5
+ * The import path of the project file or an array of paths.
6
+ * Also supports globs.
7
+ *
8
+ * @remarks
9
+ * Each file must contain a default export exposing an instance of the
10
+ * {@link Project} class.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * motionCanvas({
15
+ * project: [
16
+ * './src/firstProject.ts',
17
+ * './src/secondProject.ts',
18
+ * ]
19
+ * })
20
+ * ```
21
+ *
22
+ * @defaultValue './src/project.ts'
23
+ */
24
+ project?: string | string[];
25
+ /**
26
+ * A directory path to which the animation will be rendered.
27
+ *
28
+ * @defaultValue './output'
29
+ */
30
+ output?: string;
31
+ /**
32
+ * Defines which assets should be buffered before being sent to the browser.
33
+ *
34
+ * @remarks
35
+ * Streaming larger assets directly from the drive may cause issues with other
36
+ * applications. For instance, if an audio file is being used in the project,
37
+ * Adobe Audition will perceive it as "being used by another application"
38
+ * and refuse to override it.
39
+ *
40
+ * Buffered assets are first loaded to the memory and then streamed from
41
+ * there. This leaves the original files open for modification with hot module
42
+ * replacement still working.
43
+ *
44
+ * @defaultValue /^$/
45
+ */
46
+ bufferedAssets?: RegExp | false;
47
+ /**
48
+ * The import path of the editor package.
49
+ *
50
+ * @remarks
51
+ * This path will be resolved using Node.js module resolution rules.
52
+ * It should lead to a directory containing the following files:
53
+ * - `editor.html` - The HTML template for the editor.
54
+ * - `styles.css` - The editor styles.
55
+ * - `main.js` - A module exporting necessary factory functions.
56
+ *
57
+ * `main.js` should export the following functions:
58
+ * - `editor` - Receives the project factory as its first argument and creates
59
+ * the user interface.
60
+ * - `index` - Receives a list of all projects as its first argument and
61
+ * creates the initial page for selecting a project.
62
+ *
63
+ * @defaultValue '\@twick/ui'
64
+ */
65
+ editor?: string;
66
+ /**
67
+ * Build the project to run in the editor.
68
+ */
69
+ buildForEditor?: boolean;
70
+ }
71
+ declare const _default: ({ project, output, bufferedAssets, editor, buildForEditor, }?: MotionCanvasPluginConfig) => Plugin$1[];
72
+
73
+ /**
74
+ * Represents a Twick project configured in the Vite plugin.
75
+ */
76
+ interface ProjectData {
77
+ /**
78
+ * The name of the project.
79
+ */
80
+ name: string;
81
+ /**
82
+ * The file name containing the project.
83
+ */
84
+ fileName: string;
85
+ /**
86
+ * The path to the project relative to the Vite configuration file.
87
+ */
88
+ url: string;
89
+ }
90
+ /**
91
+ * The Twick configuration passed to each plugin.
92
+ */
93
+ interface PluginConfig {
94
+ /**
95
+ * The projects configured in the Vite plugin.
96
+ */
97
+ projects: ProjectData[];
98
+ /**
99
+ * The output path relative to the Vite configuration file.
100
+ */
101
+ output: string;
102
+ }
103
+ declare const PLUGIN_OPTIONS: unique symbol;
104
+ interface PluginOptions {
105
+ /**
106
+ * An entry point of the runtime plugin.
107
+ *
108
+ * @remarks
109
+ * While the Vite plugin can extend the backend functionality, this entry
110
+ * point lets you include custom runtime code that will be loaded by the
111
+ * browser.
112
+ *
113
+ * It should be a valid module specifier from which the plugin will be
114
+ * imported. The module should contain a default export of a runtime plugin.
115
+ */
116
+ entryPoint: string;
117
+ /**
118
+ * The configuration hook of the plugin.
119
+ *
120
+ * @remarks
121
+ * Invoked during `configResolved` hook of Vite, contains the Twick
122
+ * specific configuration.
123
+ *
124
+ * @param config - The configuration passed to the plugin.
125
+ */
126
+ config?(config: PluginConfig): Promise<void>;
127
+ /**
128
+ * Get custom configuration that will be passed to the runtime plugin.
129
+ *
130
+ * @remarks
131
+ * The config will be passed as the first argument to the default export of
132
+ * the runtime plugin. When provided as a string, it will be injected to the
133
+ * code as is, letting you define non-serializable values such as functions.
134
+ *
135
+ * If the returned value is an object, it will be converted to a JavaScript
136
+ * object using JSON serialization.
137
+ *
138
+ * @example
139
+ * Returning an object:
140
+ * ```ts
141
+ * {
142
+ * runtimeConfig: () => ({
143
+ * myText: 'Hello!',
144
+ * myNumber: 42,
145
+ * })
146
+ * }
147
+ * ```
148
+ * Returning a string:
149
+ * ```ts
150
+ * {
151
+ * runtimeConfig: () => `{myRegex: /\\.wav$/}`
152
+ * }
153
+ * ```
154
+ */
155
+ runtimeConfig?(): Promise<any>;
156
+ }
157
+ /**
158
+ * Represents a Twick plugin.
159
+ *
160
+ * @remarks
161
+ * It's a normal Vite plugin that can provide additional configuration specific
162
+ * to Twick.
163
+ */
164
+ type Plugin = Plugin$1 & {
165
+ /**
166
+ * The configuration specific to Twick.
167
+ */
168
+ [PLUGIN_OPTIONS]: PluginOptions;
169
+ };
170
+ declare function isPlugin(value: any): value is Plugin;
171
+
172
+ export { PLUGIN_OPTIONS, type Plugin, type PluginConfig, type PluginOptions, type ProjectData, _default as default, isPlugin };