diff --git a/packages/bundler/src/index-html.ts b/packages/bundler/src/index-html.ts index d1874d627d6..351df9c0030 100644 --- a/packages/bundler/src/index-html.ts +++ b/packages/bundler/src/index-html.ts @@ -1,6 +1,5 @@ import type { GitSource, - InstallablePackage, PackageManager, RenderDefaults, } from '@remotion/studio-shared'; @@ -45,7 +44,7 @@ export const indexHtml = ({ renderDefaults: RenderDefaults | undefined; gitSource: GitSource | null; projectName: string; - installedDependencies: InstallablePackage[] | null; + installedDependencies: string[] | null; packageManager: PackageManager | 'unknown'; logLevel: LogLevel; mode: 'dev' | 'bundle'; diff --git a/packages/studio-server/src/helpers/get-installed-installable-packages.ts b/packages/studio-server/src/helpers/get-installed-installable-packages.ts index 1cc921c14c4..1b27137610b 100644 --- a/packages/studio-server/src/helpers/get-installed-installable-packages.ts +++ b/packages/studio-server/src/helpers/get-installed-installable-packages.ts @@ -1,10 +1,9 @@ -import type {InstallablePackage} from '@remotion/studio-shared'; -import {listOfInstallableRemotionPackages} from '@remotion/studio-shared'; +import {installableMap} from '@remotion/studio-shared'; import {getInstalledDependencies} from './get-installed-dependencies'; export const getInstalledInstallablePackages = ( remotionRoot: string, -): InstallablePackage[] => { +): string[] => { const {dependencies, devDependencies, optionalDependencies} = getInstalledDependencies(remotionRoot); const installablePackages = [ @@ -13,7 +12,8 @@ export const getInstalledInstallablePackages = ( ...optionalDependencies, ]; - return listOfInstallableRemotionPackages.filter((pkg) => - installablePackages.includes(pkg), - ); + return Object.entries(installableMap) + .filter(([, _installable]) => _installable) + .map(([pkg]) => (pkg === 'core' ? 'remotion' : `@remotion/${pkg}`)) + .filter((pkg) => installablePackages.includes(pkg)); }; diff --git a/packages/studio-server/src/preview-server/routes/install-dependency.ts b/packages/studio-server/src/preview-server/routes/install-dependency.ts index 5f43e5c8cad..49dc78bd93f 100644 --- a/packages/studio-server/src/preview-server/routes/install-dependency.ts +++ b/packages/studio-server/src/preview-server/routes/install-dependency.ts @@ -1,6 +1,5 @@ import {RenderInternals} from '@remotion/renderer'; import { - listOfInstallableRemotionPackages, type InstallPackageRequest, type InstallPackageResponse, } from '@remotion/studio-shared'; @@ -15,7 +14,7 @@ export const handleInstallPackage: ApiHandler< InstallPackageResponse > = async ({logLevel, remotionRoot, input: {packageNames}}) => { for (const packageName of packageNames) { - if (listOfInstallableRemotionPackages.includes(packageName) === false) { + if (!packageName.startsWith('@remotion/')) { return Promise.reject( new Error(`Package ${packageName} is not allowed to be installed.`), ); diff --git a/packages/studio-shared/src/api-requests.ts b/packages/studio-shared/src/api-requests.ts index b49812264f6..788173b081c 100644 --- a/packages/studio-shared/src/api-requests.ts +++ b/packages/studio-shared/src/api-requests.ts @@ -12,7 +12,6 @@ import type { } from '@remotion/renderer'; import type {HardwareAccelerationOption} from '@remotion/renderer/client'; import type {RecastCodemod} from './codemods'; -import type {InstallablePackage} from './installable-packages'; import type {PackageManager} from './package-manager'; import type {ProjectInfo} from './project-info'; import type {RequiredChromiumOptions} from './render-job'; @@ -199,7 +198,7 @@ export type RestartStudioRequest = {}; export type RestartStudioResponse = {}; export type InstallPackageRequest = { - packageNames: InstallablePackage[]; + packageNames: string[]; }; export type InstallPackageResponse = {}; diff --git a/packages/studio-shared/src/index.ts b/packages/studio-shared/src/index.ts index 14b498e888b..d8a897f327c 100644 --- a/packages/studio-shared/src/index.ts +++ b/packages/studio-shared/src/index.ts @@ -45,12 +45,14 @@ export { ModuleMap, hotMiddlewareOptions, } from './hot-middleware'; -export { - InstallablePackage, - listOfInstallableRemotionPackages, -} from './installable-packages'; export {DEFAULT_TIMELINE_TRACKS} from './max-timeline-tracks'; -export {Pkgs, apiDocs, descriptions, packages} from './package-info'; +export { + Pkgs, + apiDocs, + descriptions, + installableMap, + packages, +} from './package-info'; export {PackageManager} from './package-manager'; export {ProjectInfo} from './project-info'; export type {RenderDefaults} from './render-defaults'; diff --git a/packages/studio-shared/src/installable-packages.ts b/packages/studio-shared/src/installable-packages.ts deleted file mode 100644 index 7a7fa0f65fc..00000000000 --- a/packages/studio-shared/src/installable-packages.ts +++ /dev/null @@ -1,30 +0,0 @@ -export const listOfInstallableRemotionPackages = [ - '@remotion/animated-emoji', - '@remotion/animation-utils', - '@remotion/cloudrun', - '@remotion/captions', - '@remotion/enable-scss', - '@remotion/gif', - '@remotion/google-fonts', - '@remotion/lambda', - '@remotion/layout-utils', - '@remotion/lottie', - '@remotion/media-parser', - '@remotion/media-utils', - '@remotion/motion-blur', - '@remotion/noise', - '@remotion/paths', - '@remotion/rive', - '@remotion/shapes', - '@remotion/skia', - '@remotion/studio', - '@remotion/tailwind', - '@remotion/tailwind-v4', - '@remotion/three', - '@remotion/transitions', - '@remotion/zod-types', - '@remotion/openai-whisper', -] as const; - -export type InstallablePackage = - (typeof listOfInstallableRemotionPackages)[number]; diff --git a/packages/studio-shared/src/package-info.ts b/packages/studio-shared/src/package-info.ts index 66d0fc63299..4865c4f2bfa 100644 --- a/packages/studio-shared/src/package-info.ts +++ b/packages/studio-shared/src/package-info.ts @@ -157,6 +157,82 @@ export const descriptions: {[key in Pkgs]: string | null} = { 'promo-pages': null, 'svg-3d-engine': '3D SVG extrusion effects', }; +export const installableMap: {[key in Pkgs]: boolean} = { + 'svg-3d-engine': false, + 'ai-improvements': false, + 'animation-utils': true, + 'animated-emoji': true, + 'astro-example': false, + 'babel-loader': false, + bugs: false, + bundler: false, + 'cli-autocomplete': false, + cli: false, + cloudrun: true, + 'compositor-darwin-arm64': false, + 'compositor-darwin-x64': false, + 'compositor-linux-arm64-gnu': false, + 'compositor-linux-arm64-musl': false, + 'compositor-linux-x64-gnu': false, + 'compositor-linux-x64-musl': false, + 'compositor-win32-x64-msvc': false, + core: false, + 'create-video': false, + 'discord-poster': false, + 'docusaurus-plugin': false, + docs: false, + 'enable-scss': true, + 'eslint-config': false, + 'eslint-config-flat': false, + 'eslint-config-internal': false, + 'eslint-plugin': false, + 'example-without-zod': false, + example: false, + fonts: true, + gif: true, + 'google-fonts': true, + 'install-whisper-cpp': true, + 'it-tests': false, + 'lambda-go-example': false, + 'lambda-go': false, + 'lambda-php': false, + 'lambda-ruby': false, + 'lambda-python': false, + lambda: true, + 'layout-utils': true, + licensing: true, + lottie: true, + 'media-utils': true, + 'motion-blur': true, + noise: true, + paths: true, + 'player-example': false, + player: true, + preload: true, + renderer: true, + rive: true, + shapes: true, + skia: true, + 'promo-pages': false, + streaming: false, + serverless: false, + 'studio-server': false, + 'studio-shared': false, + studio: true, + tailwind: true, + 'tailwind-v4': true, + 'test-utils': false, + three: true, + transitions: true, + 'media-parser': true, + 'zod-types': true, + webcodecs: true, + convert: false, + captions: true, + 'openai-whisper': true, + compositor: false, + 'example-videos': false, +}; export const apiDocs: {[key in Pkgs]: string | null} = { player: 'https://www.remotion.dev/docs/player', diff --git a/packages/studio-shared/src/render-defaults.ts b/packages/studio-shared/src/render-defaults.ts index 34333dd3c61..3c110175843 100644 --- a/packages/studio-shared/src/render-defaults.ts +++ b/packages/studio-shared/src/render-defaults.ts @@ -13,7 +13,6 @@ import type { } from '@remotion/renderer'; import type {HardwareAccelerationOption} from '@remotion/renderer/client'; import type {GitSource} from './git-source'; -import type {InstallablePackage} from './installable-packages'; import type {PackageManager} from './package-manager'; export type RenderDefaults = { @@ -59,7 +58,7 @@ declare global { interface Window { remotion_renderDefaults: RenderDefaults | undefined; remotion_gitSource: GitSource | null; - remotion_installedPackages: InstallablePackage[] | null; + remotion_installedPackages: string[] | null; remotion_packageManager: PackageManager | 'unknown'; } } diff --git a/packages/studio/src/api/install-package.ts b/packages/studio/src/api/install-package.ts index 5c538045028..d24322d62c3 100644 --- a/packages/studio/src/api/install-package.ts +++ b/packages/studio/src/api/install-package.ts @@ -1,12 +1,9 @@ -import type { - InstallPackageResponse, - InstallablePackage, -} from '@remotion/studio-shared'; +import type {InstallPackageResponse} from '@remotion/studio-shared'; import {getRemotionEnvironment} from 'remotion'; import {callApi} from '../components/call-api'; export const installPackages = ( - packageNames: InstallablePackage[], + packageNames: string[], ): Promise => { if (!getRemotionEnvironment().isStudio) { throw new Error('installPackages() is only available in the Studio'); diff --git a/packages/studio/src/components/InstallPackage.tsx b/packages/studio/src/components/InstallPackage.tsx index daa2340014b..b4b01fd5d88 100644 --- a/packages/studio/src/components/InstallPackage.tsx +++ b/packages/studio/src/components/InstallPackage.tsx @@ -1,10 +1,5 @@ import type {PackageManager, Pkgs} from '@remotion/studio-shared'; -import { - apiDocs, - descriptions, - listOfInstallableRemotionPackages, - type InstallablePackage, -} from '@remotion/studio-shared'; +import {apiDocs, descriptions, installableMap} from '@remotion/studio-shared'; import React, {useCallback, useContext, useEffect} from 'react'; import {VERSION} from 'remotion'; import {installPackages} from '../api/install-package'; @@ -55,38 +50,10 @@ export const InstallPackageModal: React.FC<{ }> = ({packageManager}) => { const [state, setState] = React.useState({type: 'idle'}); - const [map, setMap] = React.useState<{[key in InstallablePackage]: boolean}>({ - '@remotion/animated-emoji': false, - '@remotion/gif': false, - '@remotion/lottie': false, - '@remotion/media-utils': false, - '@remotion/animation-utils': false, - '@remotion/cloudrun': false, - '@remotion/google-fonts': false, - '@remotion/enable-scss': false, - '@remotion/lambda': false, - '@remotion/layout-utils': false, - '@remotion/media-parser': false, - '@remotion/motion-blur': false, - '@remotion/noise': false, - '@remotion/paths': false, - '@remotion/rive': false, - '@remotion/shapes': false, - '@remotion/skia': false, - '@remotion/studio': false, - '@remotion/tailwind': false, - '@remotion/tailwind-v4': false, - '@remotion/three': false, - '@remotion/transitions': false, - '@remotion/zod-types': false, - '@remotion/captions': false, - '@remotion/openai-whisper': false, - }); + const [map, setMap] = React.useState>({}); const {previewServerState: ctx} = useContext(StudioServerConnectionCtx); - const selectedPackages = (Object.keys(map) as InstallablePackage[]).filter( - (pkg) => map[pkg], - ); + const selectedPackages = Object.keys(map).filter((pkg) => map[pkg]); const onClick = useCallback(async () => { if (state.type === 'done') { @@ -151,40 +118,43 @@ export const InstallPackageModal: React.FC<{ ) : (
- {listOfInstallableRemotionPackages.map((pkg) => { - const isInstalled = - window.remotion_installedPackages?.includes(pkg) ?? false; - const link = apiDocs[pkg.replace('@remotion/', '') as Pkgs]; - const description = - descriptions[pkg.replace('@remotion/', '') as Pkgs]; - if (!link) { - throw new Error('No link for ' + pkg); - } - - if (!description) { - throw new Error('No description for ' + pkg); - } - - return ( - - { - setMap((prev) => ({...prev, [pkg]: !prev[pkg]})); - }} - disabled={!canSelectPackages || isInstalled} - /> - - - - ); - })} + {Object.entries(installableMap) + .filter(([, install]) => install) + .map(([pkgShort]) => { + const pkg = + pkgShort === 'core' ? 'remotion' : `@remotion/${pkgShort}`; + const isInstalled = + window.remotion_installedPackages?.includes(pkg) ?? false; + const link = apiDocs[pkgShort as Pkgs]; + const description = descriptions[pkgShort as Pkgs]; + if (!link) { + throw new Error('No link for ' + pkg); + } + + if (!description) { + throw new Error('No description for ' + pkg); + } + + return ( + + { + setMap((prev) => ({...prev, [pkg]: !prev[pkg]})); + }} + disabled={!canSelectPackages || isInstalled} + /> + + + + ); + })}
)}