@remotion/studio-server 4.0.431 → 4.0.432

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.
@@ -0,0 +1,13 @@
1
+ import { type EnumPath } from '@remotion/studio-shared';
2
+ import type { namedTypes } from 'ast-types';
3
+ import type { ExpressionKind } from 'ast-types/lib/gen/kinds';
4
+ export declare const parseValueExpression: (value: unknown, enumPaths: EnumPath[]) => ExpressionKind;
5
+ export declare const updateNestedProp: ({ node, parentKey, childKey, value, enumPaths, defaultValue, isDefault, }: {
6
+ node: namedTypes.JSXOpeningElement;
7
+ parentKey: string;
8
+ childKey: string;
9
+ value: unknown;
10
+ enumPaths: EnumPath[];
11
+ defaultValue: unknown;
12
+ isDefault: boolean;
13
+ }) => string;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.updateNestedProp = exports.parseValueExpression = void 0;
37
+ const studio_shared_1 = require("@remotion/studio-shared");
38
+ const recast = __importStar(require("recast"));
39
+ const parse_ast_1 = require("./parse-ast");
40
+ const b = recast.types.builders;
41
+ const parseValueExpression = (value, enumPaths) => {
42
+ return (0, parse_ast_1.parseAst)(`a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: value, enumPaths })}`)
43
+ .program.body[0].expression.right;
44
+ };
45
+ exports.parseValueExpression = parseValueExpression;
46
+ const findJsxAttribute = (attributes, name) => {
47
+ const attrIndex = attributes.findIndex((a) => {
48
+ if (a.type === 'JSXSpreadAttribute') {
49
+ return false;
50
+ }
51
+ if (a.name.type === 'JSXNamespacedName') {
52
+ return false;
53
+ }
54
+ return a.name.name === name;
55
+ });
56
+ const found = attrIndex !== -1 ? attributes[attrIndex] : undefined;
57
+ return {
58
+ attrIndex,
59
+ attr: found && found.type === 'JSXAttribute'
60
+ ? found
61
+ : undefined,
62
+ };
63
+ };
64
+ const findObjectProperty = (objExpr, propertyName) => {
65
+ const propIndex = objExpr.properties.findIndex((p) => p.type === 'ObjectProperty' &&
66
+ ((p.key.type === 'Identifier' &&
67
+ p.key.name ===
68
+ propertyName) ||
69
+ (p.key.type === 'StringLiteral' &&
70
+ p.key
71
+ .value === propertyName)));
72
+ return {
73
+ propIndex,
74
+ prop: propIndex !== -1
75
+ ? objExpr.properties[propIndex]
76
+ : undefined,
77
+ };
78
+ };
79
+ const getObjectExpression = (attr) => {
80
+ const { value } = attr;
81
+ if (!value || value.type !== 'JSXExpressionContainer') {
82
+ return null;
83
+ }
84
+ const container = value;
85
+ if (container.expression.type !== 'ObjectExpression') {
86
+ return null;
87
+ }
88
+ return container.expression;
89
+ };
90
+ const getOldValueString = ({ attr, childKey, defaultValue, }) => {
91
+ if (attr) {
92
+ const objExpr = getObjectExpression(attr);
93
+ if (objExpr) {
94
+ const { prop } = findObjectProperty(objExpr, childKey);
95
+ if (prop) {
96
+ return recast.print(prop.value).code;
97
+ }
98
+ }
99
+ }
100
+ if (defaultValue !== null) {
101
+ return JSON.stringify(defaultValue);
102
+ }
103
+ return '';
104
+ };
105
+ const removeNestedProp = ({ attr, attrIndex, attributes, childKey, }) => {
106
+ if (!attr) {
107
+ return;
108
+ }
109
+ const objExpr = getObjectExpression(attr);
110
+ if (!objExpr) {
111
+ return;
112
+ }
113
+ const { propIndex } = findObjectProperty(objExpr, childKey);
114
+ if (propIndex !== -1) {
115
+ objExpr.properties.splice(propIndex, 1);
116
+ }
117
+ if (objExpr.properties.length === 0 && attrIndex !== -1) {
118
+ attributes.splice(attrIndex, 1);
119
+ }
120
+ };
121
+ const setNestedProp = ({ attr, attributes, parentKey, childKey, value, enumPaths, }) => {
122
+ const parsedValue = (0, exports.parseValueExpression)(value, enumPaths);
123
+ if (attr) {
124
+ const objExpr = getObjectExpression(attr);
125
+ if (objExpr) {
126
+ const { prop } = findObjectProperty(objExpr, childKey);
127
+ if (prop) {
128
+ prop.value = parsedValue;
129
+ }
130
+ else {
131
+ objExpr.properties.push(b.objectProperty(b.identifier(childKey), parsedValue));
132
+ }
133
+ }
134
+ }
135
+ else {
136
+ const objExpr = b.objectExpression([
137
+ b.objectProperty(b.identifier(childKey), parsedValue),
138
+ ]);
139
+ const newAttr = b.jsxAttribute(b.jsxIdentifier(parentKey), b.jsxExpressionContainer(objExpr));
140
+ attributes.push(newAttr);
141
+ }
142
+ };
143
+ const updateNestedProp = ({ node, parentKey, childKey, value, enumPaths, defaultValue, isDefault, }) => {
144
+ if (!node.attributes) {
145
+ node.attributes = [];
146
+ }
147
+ const { attributes } = node;
148
+ const { attrIndex, attr } = findJsxAttribute(attributes, parentKey);
149
+ const oldValueString = getOldValueString({ attr, childKey, defaultValue });
150
+ if (isDefault) {
151
+ removeNestedProp({ attr, attrIndex, attributes, childKey });
152
+ }
153
+ else {
154
+ setNestedProp({ attr, attributes, parentKey, childKey, value, enumPaths });
155
+ }
156
+ return oldValueString;
157
+ };
158
+ exports.updateNestedProp = updateNestedProp;
@@ -1,4 +1,4 @@
1
- import { type EnumPath } from '@remotion/studio-shared';
1
+ import type { EnumPath } from '@remotion/studio-shared';
2
2
  export declare const updateSequenceProps: ({ input, targetLine, key, value, enumPaths, defaultValue, }: {
3
3
  input: string;
4
4
  targetLine: number;
@@ -34,15 +34,20 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.updateSequenceProps = void 0;
37
- const studio_shared_1 = require("@remotion/studio-shared");
38
37
  const recast = __importStar(require("recast"));
39
38
  const parse_ast_1 = require("./parse-ast");
39
+ const update_nested_prop_1 = require("./update-nested-prop");
40
+ const b = recast.types.builders;
40
41
  const updateSequenceProps = async ({ input, targetLine, key, value, enumPaths, defaultValue, }) => {
41
42
  const ast = (0, parse_ast_1.parseAst)(input);
42
43
  let found = false;
43
44
  let oldValueString = '';
44
45
  const isDefault = defaultValue !== null &&
45
46
  JSON.stringify(value) === JSON.stringify(defaultValue);
47
+ const dotIndex = key.indexOf('.');
48
+ const isNested = dotIndex !== -1;
49
+ const parentKey = isNested ? key.slice(0, dotIndex) : key;
50
+ const childKey = isNested ? key.slice(dotIndex + 1) : '';
46
51
  recast.types.visit(ast, {
47
52
  visitJSXOpeningElement(path) {
48
53
  var _a, _b;
@@ -50,6 +55,19 @@ const updateSequenceProps = async ({ input, targetLine, key, value, enumPaths, d
50
55
  if (!node.loc || node.loc.start.line !== targetLine) {
51
56
  return this.traverse(path);
52
57
  }
58
+ if (isNested) {
59
+ oldValueString = (0, update_nested_prop_1.updateNestedProp)({
60
+ node,
61
+ parentKey,
62
+ childKey,
63
+ value,
64
+ enumPaths,
65
+ defaultValue,
66
+ isDefault,
67
+ });
68
+ found = true;
69
+ return this.traverse(path);
70
+ }
53
71
  const attrIndex = (_a = node.attributes) === null || _a === void 0 ? void 0 : _a.findIndex((a) => {
54
72
  if (a.type === 'JSXSpreadAttribute') {
55
73
  return false;
@@ -84,13 +102,10 @@ const updateSequenceProps = async ({ input, targetLine, key, value, enumPaths, d
84
102
  found = true;
85
103
  return this.traverse(path);
86
104
  }
87
- const parsed = (0, parse_ast_1.parseAst)(`a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: value, enumPaths })}`)
88
- .program.body[0].expression.right;
89
- const newValue = value === true
90
- ? null
91
- : recast.types.builders.jsxExpressionContainer(parsed);
105
+ const parsed = (0, update_nested_prop_1.parseValueExpression)(value, enumPaths);
106
+ const newValue = value === true ? null : b.jsxExpressionContainer(parsed);
92
107
  if (!attr || attr.type === 'JSXSpreadAttribute') {
93
- const newAttr = recast.types.builders.jsxAttribute(recast.types.builders.jsxIdentifier(key), newValue);
108
+ const newAttr = b.jsxAttribute(b.jsxIdentifier(key), newValue);
94
109
  if (!node.attributes) {
95
110
  node.attributes = [];
96
111
  }
@@ -165,6 +165,37 @@ const findJsxElementAtLine = (ast, targetLine) => {
165
165
  });
166
166
  return found;
167
167
  };
168
+ const getNestedPropStatus = (jsxElement, parentKey, childKey) => {
169
+ const attr = jsxElement.attributes.find((a) => a.type !== 'JSXSpreadAttribute' &&
170
+ a.name.type !== 'JSXNamespacedName' &&
171
+ a.name.name === parentKey);
172
+ if (!attr || !attr.value) {
173
+ // Parent attribute doesn't exist, nested prop can be added
174
+ return { canUpdate: true, codeValue: undefined };
175
+ }
176
+ if (attr.value.type !== 'JSXExpressionContainer') {
177
+ return { canUpdate: false, reason: 'computed' };
178
+ }
179
+ const { expression } = attr.value;
180
+ if (expression.type === 'JSXEmptyExpression' ||
181
+ expression.type !== 'ObjectExpression') {
182
+ // Parent is not an object literal (e.g. style={myStyles})
183
+ return { canUpdate: false, reason: 'computed' };
184
+ }
185
+ const objExpr = expression;
186
+ const prop = objExpr.properties.find((p) => p.type === 'ObjectProperty' &&
187
+ ((p.key.type === 'Identifier' && p.key.name === childKey) ||
188
+ (p.key.type === 'StringLiteral' && p.key.value === childKey)));
189
+ if (!prop) {
190
+ // Property not set in the object, can be added
191
+ return { canUpdate: true, codeValue: undefined };
192
+ }
193
+ const propValue = prop.value;
194
+ if (!(0, exports.isStaticValue)(propValue)) {
195
+ return { canUpdate: false, reason: 'computed' };
196
+ }
197
+ return { canUpdate: true, codeValue: (0, exports.extractStaticValue)(propValue) };
198
+ };
168
199
  const computeSequencePropsStatus = ({ fileName, line, keys, remotionRoot, }) => {
169
200
  try {
170
201
  const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
@@ -181,7 +212,11 @@ const computeSequencePropsStatus = ({ fileName, line, keys, remotionRoot, }) =>
181
212
  const allProps = getPropsStatus(jsxElement);
182
213
  const filteredProps = {};
183
214
  for (const key of keys) {
184
- if (key in allProps) {
215
+ const dotIndex = key.indexOf('.');
216
+ if (dotIndex !== -1) {
217
+ filteredProps[key] = getNestedPropStatus(jsxElement, key.slice(0, dotIndex), key.slice(dotIndex + 1));
218
+ }
219
+ else if (key in allProps) {
185
220
  filteredProps[key] = allProps[key];
186
221
  }
187
222
  else {
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.431",
6
+ "version": "4.0.432",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "sideEffects": false,
@@ -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.431",
30
+ "remotion": "4.0.432",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.431",
33
- "@remotion/renderer": "4.0.431",
34
- "@remotion/studio-shared": "4.0.431",
32
+ "@remotion/bundler": "4.0.432",
33
+ "@remotion/renderer": "4.0.432",
34
+ "@remotion/studio-shared": "4.0.432",
35
35
  "memfs": "3.4.3",
36
36
  "source-map": "0.7.3",
37
37
  "open": "^8.4.2"
@@ -41,10 +41,10 @@
41
41
  "react": "19.2.3",
42
42
  "@babel/types": "7.24.0",
43
43
  "@types/semver": "^7.3.4",
44
- "@remotion/eslint-config-internal": "4.0.431",
44
+ "@remotion/eslint-config-internal": "4.0.432",
45
45
  "eslint": "9.19.0",
46
46
  "@types/node": "20.12.14",
47
- "@typescript/native-preview": "7.0.0-dev.20260217.1"
47
+ "@typescript/native-preview": "7.0.0-dev.20260301.1"
48
48
  },
49
49
  "exports": {
50
50
  ".": "./dist/index.js",
@@ -1,8 +0,0 @@
1
- import type { File } from '@babel/types';
2
- import { type ApplyComponentVisualControlCodemod } from '@remotion/studio-shared';
3
- import type { ApplyCodeModReturnType, Change } from './recast-mods';
4
- export declare const applyComponentVisualControl: ({ file, transformation, changesMade, }: {
5
- file: File;
6
- transformation: ApplyComponentVisualControlCodemod;
7
- changesMade: Change[];
8
- }) => ApplyCodeModReturnType;
@@ -1,92 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.applyComponentVisualControl = void 0;
37
- const studio_shared_1 = require("@remotion/studio-shared");
38
- const recast = __importStar(require("recast"));
39
- const parse_ast_1 = require("./parse-ast");
40
- const applyComponentVisualControl = ({ file, transformation, changesMade, }) => {
41
- recast.types.visit(file.program, {
42
- visitJSXOpeningElement(path) {
43
- var _a;
44
- const { node } = path;
45
- if (node.name.type !== 'JSXIdentifier' ||
46
- node.name.name !== transformation.componentName) {
47
- return this.traverse(path);
48
- }
49
- if (((_a = node.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== transformation.line) {
50
- return this.traverse(path);
51
- }
52
- const attributes = node.attributes;
53
- if (!attributes) {
54
- return this.traverse(path);
55
- }
56
- for (const change of transformation.changes) {
57
- const parsed = (0, parse_ast_1.parseAst)(`a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: JSON.parse(change.newValueSerialized), enumPaths: change.enumPaths })}`).program.body[0].expression.right;
58
- const existingAttr = attributes.find((attr) => attr.type === 'JSXAttribute' &&
59
- attr.name.type === 'JSXIdentifier' &&
60
- attr.name.name === change.propName);
61
- if (existingAttr && existingAttr.type === 'JSXAttribute') {
62
- existingAttr.value = {
63
- type: 'JSXExpressionContainer',
64
- expression: parsed,
65
- };
66
- changesMade.push({
67
- description: `Updated prop ${change.propName} on ${transformation.componentName}`,
68
- });
69
- }
70
- else {
71
- attributes.push({
72
- type: 'JSXAttribute',
73
- name: {
74
- type: 'JSXIdentifier',
75
- name: change.propName,
76
- },
77
- value: {
78
- type: 'JSXExpressionContainer',
79
- expression: parsed,
80
- },
81
- });
82
- changesMade.push({
83
- description: `Added prop ${change.propName} to ${transformation.componentName}`,
84
- });
85
- }
86
- }
87
- return false;
88
- },
89
- });
90
- return { newAst: file, changesMade };
91
- };
92
- exports.applyComponentVisualControl = applyComponentVisualControl;
@@ -1,3 +0,0 @@
1
- import type { ApplyComponentVisualControlRequest, ApplyComponentVisualControlResponse } from '@remotion/studio-shared';
2
- import type { ApiHandler } from '../api-types';
3
- export declare const applyComponentVisualControlHandler: ApiHandler<ApplyComponentVisualControlRequest, ApplyComponentVisualControlResponse>;
@@ -1,38 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.applyComponentVisualControlHandler = void 0;
7
- const node_fs_1 = require("node:fs");
8
- const node_path_1 = __importDefault(require("node:path"));
9
- const parse_ast_1 = require("../../codemods/parse-ast");
10
- const recast_mods_1 = require("../../codemods/recast-mods");
11
- const applyComponentVisualControlHandler = ({ input: { fileName, componentName, line, column, changes }, remotionRoot }) => {
12
- const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
13
- const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
14
- if (fileRelativeToRoot.startsWith('..')) {
15
- throw new Error('Cannot apply component visual control change to a file outside the project');
16
- }
17
- const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
18
- const ast = (0, parse_ast_1.parseAst)(fileContents);
19
- const { newAst, changesMade } = (0, recast_mods_1.applyCodemod)({
20
- file: ast,
21
- codeMod: {
22
- type: 'apply-component-visual-control',
23
- componentName,
24
- line,
25
- column,
26
- changes,
27
- },
28
- });
29
- if (changesMade.length === 0) {
30
- throw new Error('No changes were made to the file');
31
- }
32
- const output = (0, parse_ast_1.serializeAst)(newAst);
33
- (0, node_fs_1.writeFileSync)(absolutePath, output);
34
- return Promise.resolve({
35
- success: true,
36
- });
37
- };
38
- exports.applyComponentVisualControlHandler = applyComponentVisualControlHandler;