@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.
- package/dist/helpers/resolve-composition-component.d.ts +1 -1
- package/dist/helpers/resolve-composition-component.js +79 -2
- package/dist/preview-server/routes/can-update-sequence-props.js +3 -4
- package/dist/preview-server/routes/download-remote-asset.js +1 -0
- package/dist/preview-server/routes/insert-jsx-element.d.ts +1 -1
- package/dist/preview-server/routes/insert-jsx-element.js +25 -1
- package/package.json +6 -6
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
557
|
-
if (!validateStyleValue(childKey,
|
|
555
|
+
const propStatus = (0, exports.extractStaticValue)(propValue);
|
|
556
|
+
if (!validateStyleValue(childKey, propStatus)) {
|
|
558
557
|
return computedStatus();
|
|
559
558
|
}
|
|
560
|
-
return staticStatus(
|
|
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
|
|
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 (
|
|
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.
|
|
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.
|
|
30
|
+
"remotion": "4.0.474",
|
|
31
31
|
"recast": "0.23.11",
|
|
32
|
-
"@remotion/bundler": "4.0.
|
|
33
|
-
"@remotion/renderer": "4.0.
|
|
34
|
-
"@remotion/studio-shared": "4.0.
|
|
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.
|
|
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"
|