@remotion/studio-server 4.0.473 → 4.0.474

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.
@@ -1,4 +1,4 @@
1
- import type { InsertableCompositionElement } from '@remotion/studio-shared';
1
+ import { type InsertableCompositionElement } from '@remotion/studio-shared';
2
2
  export type ResolvedCompositionComponent = {
3
3
  source: string;
4
4
  line: number;
@@ -39,6 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.insertJsxElementIntoComposition = exports.resolveCompositionComponent = void 0;
40
40
  const node_fs_1 = __importDefault(require("node:fs"));
41
41
  const node_path_1 = __importDefault(require("node:path"));
42
+ const studio_shared_1 = require("@remotion/studio-shared");
42
43
  const recast = __importStar(require("recast"));
43
44
  const format_file_content_1 = require("../codemods/format-file-content");
44
45
  const parse_ast_1 = require("../codemods/parse-ast");
@@ -508,6 +509,12 @@ const createSequenceElement = () => {
508
509
  const createNumberAttribute = (name, value) => {
509
510
  return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.numericLiteral(value)));
510
511
  };
512
+ const createStringAttribute = (name, value) => {
513
+ return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.stringLiteral(value));
514
+ };
515
+ const createBooleanAttribute = (name, value) => {
516
+ return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(name), recast.types.builders.jsxExpressionContainer(recast.types.builders.booleanLiteral(value)));
517
+ };
511
518
  const createPositionAbsoluteStyleAttribute = () => {
512
519
  return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('style'), recast.types.builders.jsxExpressionContainer(recast.types.builders.objectExpression([
513
520
  recast.types.builders.objectProperty(recast.types.builders.identifier('position'), recast.types.builders.stringLiteral('absolute')),
@@ -516,6 +523,18 @@ const createPositionAbsoluteStyleAttribute = () => {
516
523
  const createStaticFileSrcAttribute = ({ staticFileLocalName, src, }) => {
517
524
  return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('src'), recast.types.builders.jsxExpressionContainer(recast.types.builders.callExpression(recast.types.builders.identifier(staticFileLocalName), [recast.types.builders.stringLiteral(src)])));
518
525
  };
526
+ const createComponentProp = ({ name, value, }) => {
527
+ if (typeof value === 'number') {
528
+ return createNumberAttribute(name, value);
529
+ }
530
+ if (typeof value === 'boolean') {
531
+ return createBooleanAttribute(name, value);
532
+ }
533
+ return createStringAttribute(name, value);
534
+ };
535
+ const createStringSrcAttribute = (src) => {
536
+ return recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier('src'), recast.types.builders.stringLiteral(src));
537
+ };
519
538
  const createSolidElement = ({ localName, width, height, }) => {
520
539
  return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
521
540
  createNumberAttribute('width', width),
@@ -523,9 +542,17 @@ const createSolidElement = ({ localName, width, height, }) => {
523
542
  createPositionAbsoluteStyleAttribute(),
524
543
  ], true), null, []);
525
544
  };
545
+ const createComponentElement = ({ localName, props, }) => {
546
+ return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
547
+ ...props.map(createComponentProp),
548
+ createPositionAbsoluteStyleAttribute(),
549
+ ], true), null, []);
550
+ };
526
551
  const createAssetElement = ({ localName, staticFileLocalName, src, dimensions, }) => {
527
552
  return recast.types.builders.jsxElement(recast.types.builders.jsxOpeningElement(recast.types.builders.jsxIdentifier(localName), [
528
- createStaticFileSrcAttribute({ staticFileLocalName, src }),
553
+ staticFileLocalName === null
554
+ ? createStringSrcAttribute(src)
555
+ : createStaticFileSrcAttribute({ staticFileLocalName, src }),
529
556
  createPositionAbsoluteStyleAttribute(),
530
557
  ...(dimensions
531
558
  ? [
@@ -725,6 +752,41 @@ const ensureGifImport = (ast) => {
725
752
  label: '<Gif>',
726
753
  });
727
754
  };
755
+ const hasComponentLocalImport = ({ ast, importName, importPath, }) => {
756
+ var _a;
757
+ var _b, _c;
758
+ for (const importDeclaration of getImportDeclarations({
759
+ ast,
760
+ sourcePath: importPath,
761
+ })) {
762
+ for (const specifier of (_b = importDeclaration.specifiers) !== null && _b !== void 0 ? _b : []) {
763
+ if (specifier.type === 'ImportSpecifier' &&
764
+ (0, imports_1.getImportedName)(specifier) === importName) {
765
+ return (_c = (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) !== null && _c !== void 0 ? _c : importName;
766
+ }
767
+ }
768
+ }
769
+ return null;
770
+ };
771
+ const ensureComponentImport = ({ ast, componentName, importName, importPath, }) => {
772
+ const existingLocalName = hasComponentLocalImport({
773
+ ast,
774
+ importName,
775
+ importPath,
776
+ });
777
+ if (existingLocalName) {
778
+ return existingLocalName;
779
+ }
780
+ if (hasTopLevelBinding({ ast, name: componentName })) {
781
+ throw new Error(`Cannot add <${componentName}> because ${componentName} is already defined`);
782
+ }
783
+ return (0, imports_1.ensureNamedImport)({
784
+ ast,
785
+ importedName: importName,
786
+ sourcePath: importPath,
787
+ localName: componentName,
788
+ });
789
+ };
728
790
  const addElementToComponentRoot = ({ ast, exportName, element, }) => {
729
791
  var _a;
730
792
  var _b;
@@ -947,8 +1009,23 @@ const createInsertableJsxElement = ({ ast, element, }) => {
947
1009
  height: element.height,
948
1010
  });
949
1011
  }
1012
+ if (element.type === 'component') {
1013
+ const componentLocalName = ensureComponentImport({
1014
+ ast,
1015
+ componentName: element.componentName,
1016
+ importName: element.importName,
1017
+ importPath: element.importPath,
1018
+ });
1019
+ return createComponentElement({
1020
+ localName: componentLocalName,
1021
+ props: element.props,
1022
+ });
1023
+ }
950
1024
  if (element.type === 'asset') {
951
- const staticFileLocalName = ensureStaticFileImport(ast);
1025
+ if (element.srcType === 'remote' && !(0, studio_shared_1.isUrl)(element.src)) {
1026
+ throw new Error('Remote asset source must be a URL');
1027
+ }
1028
+ const staticFileLocalName = element.srcType === 'remote' ? null : ensureStaticFileImport(ast);
952
1029
  let localName;
953
1030
  if (element.assetType === 'image') {
954
1031
  localName = ensureImgImport(ast);
@@ -406,7 +406,6 @@ const getComputedStatus = (node, ast) => {
406
406
  }
407
407
  return {
408
408
  status: 'keyframed',
409
- codeValue: undefined,
410
409
  interpolationFunction: interpolation.interpolationFunction,
411
410
  keyframes: interpolation.keyframes,
412
411
  easing: interpolation.easing,
@@ -553,11 +552,11 @@ const getNestedPropStatus = (jsxElement, ast, parentKey, childKey) => {
553
552
  if (!(0, exports.isStaticValue)(propValue)) {
554
553
  return (0, exports.getComputedStatus)(propValue, ast);
555
554
  }
556
- const codeValue = (0, exports.extractStaticValue)(propValue);
557
- if (!validateStyleValue(childKey, codeValue)) {
555
+ const propStatus = (0, exports.extractStaticValue)(propValue);
556
+ if (!validateStyleValue(childKey, propStatus)) {
558
557
  return computedStatus();
559
558
  }
560
- return staticStatus(codeValue);
559
+ return staticStatus(propStatus);
561
560
  };
562
561
  const computeEffectsForJsx = ({ ast, jsxElement, effects, }) => {
563
562
  return effects.map((effect, effectIndex) => (0, can_update_effect_props_1.computeEffectPropStatus)({
@@ -255,6 +255,7 @@ const downloadRemoteAssetHandler = async ({ input, publicDir, request }) => {
255
255
  type: 'asset',
256
256
  assetType: fileType.type === 'gif' ? 'gif' : 'image',
257
257
  src: assetPath,
258
+ srcType: 'static',
258
259
  dimensions: fileType.dimensions,
259
260
  };
260
261
  return {
@@ -1,3 +1,3 @@
1
- import type { InsertJsxElementRequest, InsertJsxElementResponse } from '@remotion/studio-shared';
1
+ import { type InsertJsxElementRequest, type InsertJsxElementResponse } from '@remotion/studio-shared';
2
2
  import type { ApiHandler } from '../api-types';
3
3
  export declare const insertJsxElementHandler: ApiHandler<InsertJsxElementRequest, InsertJsxElementResponse>;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.insertJsxElementHandler = void 0;
4
4
  const renderer_1 = require("@remotion/renderer");
5
+ const studio_shared_1 = require("@remotion/studio-shared");
5
6
  const file_watcher_1 = require("../../file-watcher");
6
7
  const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
7
8
  const format_log_file_location_1 = require("../format-log-file-location");
@@ -20,7 +21,12 @@ const validateElement = (element) => {
20
21
  return;
21
22
  }
22
23
  if (element.type === 'asset') {
23
- if (!element.src || element.src.includes('\\')) {
24
+ if (element.srcType === 'remote') {
25
+ if (!(0, studio_shared_1.isUrl)(element.src)) {
26
+ throw new Error('Remote asset source must be a URL');
27
+ }
28
+ }
29
+ else if (!element.src || element.src.includes('\\')) {
24
30
  throw new Error('Asset path must be a static file path');
25
31
  }
26
32
  if (element.dimensions) {
@@ -29,6 +35,21 @@ const validateElement = (element) => {
29
35
  }
30
36
  return;
31
37
  }
38
+ if (element.type === 'component') {
39
+ if (!(0, studio_shared_1.isComponentIdentifier)(element.componentName)) {
40
+ throw new Error('Unsupported component name');
41
+ }
42
+ if (!(0, studio_shared_1.isComponentIdentifier)(element.importName)) {
43
+ throw new Error('Unsupported component import name');
44
+ }
45
+ if (!(0, studio_shared_1.isComponentImportPath)(element.importPath)) {
46
+ throw new Error('Unsupported component import path');
47
+ }
48
+ if (!(0, studio_shared_1.areComponentProps)(element.props)) {
49
+ throw new Error('Unsupported component props');
50
+ }
51
+ return;
52
+ }
32
53
  throw new Error('Unsupported element type');
33
54
  };
34
55
  const getElementLabel = (element) => {
@@ -49,6 +70,9 @@ const getElementLabel = (element) => {
49
70
  return '<Audio>';
50
71
  }
51
72
  }
73
+ if (element.type === 'component') {
74
+ return `<${element.componentName}>`;
75
+ }
52
76
  throw new Error('Unsupported element type');
53
77
  };
54
78
  const insertJsxElementHandler = ({ input: { compositionFile, compositionId, element }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
4
4
  },
5
5
  "name": "@remotion/studio-server",
6
- "version": "4.0.473",
6
+ "version": "4.0.474",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -27,11 +27,11 @@
27
27
  "@babel/parser": "7.24.1",
28
28
  "semver": "7.5.3",
29
29
  "prettier": "3.8.1",
30
- "remotion": "4.0.473",
30
+ "remotion": "4.0.474",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.473",
33
- "@remotion/renderer": "4.0.473",
34
- "@remotion/studio-shared": "4.0.473",
32
+ "@remotion/bundler": "4.0.474",
33
+ "@remotion/renderer": "4.0.474",
34
+ "@remotion/studio-shared": "4.0.474",
35
35
  "memfs": "3.4.3",
36
36
  "open": "8.4.2"
37
37
  },
@@ -39,7 +39,7 @@
39
39
  "ast-types": "0.16.1",
40
40
  "react": "19.2.3",
41
41
  "@types/semver": "7.5.3",
42
- "@remotion/eslint-config-internal": "4.0.473",
42
+ "@remotion/eslint-config-internal": "4.0.474",
43
43
  "eslint": "9.19.0",
44
44
  "@types/node": "20.12.14",
45
45
  "@typescript/native-preview": "7.0.0-dev.20260217.1"