@remotion/studio-server 4.0.430 → 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.430",
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.429",
30
+ "remotion": "4.0.432",
31
31
  "recast": "0.23.11",
32
- "@remotion/bundler": "4.0.429",
33
- "@remotion/renderer": "4.0.429",
34
- "@remotion/studio-shared": "4.0.429",
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.429",
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,64 +0,0 @@
1
- 'use strict';
2
- var __importDefault =
3
- (this && this.__importDefault) ||
4
- function (mod) {
5
- return mod && mod.__esModule ? mod : {default: mod};
6
- };
7
- Object.defineProperty(exports, '__esModule', {value: true});
8
- const bun_test_1 = require('bun:test');
9
- const node_fs_1 = __importDefault(require('node:fs'));
10
- const node_os_1 = __importDefault(require('node:os'));
11
- const node_path_1 = __importDefault(require('node:path'));
12
- const get_package_manager_1 = require('../get-package-manager');
13
- (0, bun_test_1.describe)('getPackageManager multiple lockfiles', () => {
14
- let tempDir;
15
- (0, bun_test_1.beforeEach)(() => {
16
- tempDir = node_fs_1.default.mkdtempSync(
17
- node_path_1.default.join(node_os_1.default.tmpdir(), 'remotion-test-'),
18
- );
19
- });
20
- (0, bun_test_1.afterEach)(() => {
21
- node_fs_1.default.rmSync(tempDir, {recursive: true, force: true});
22
- });
23
- (0, bun_test_1.test)(
24
- 'should not throw error when multiple lockfiles are detected',
25
- () => {
26
- node_fs_1.default.writeFileSync(
27
- node_path_1.default.join(tempDir, 'package-lock.json'),
28
- '{}',
29
- );
30
- node_fs_1.default.writeFileSync(
31
- node_path_1.default.join(tempDir, 'bun.lock'),
32
- '',
33
- );
34
- // Should not throw
35
- const manager = (0, get_package_manager_1.getPackageManager)(
36
- tempDir,
37
- undefined,
38
- 0,
39
- );
40
- // Should return one of them (usually the first one in the list, which is npm)
41
- (0, bun_test_1.expect)(manager).not.toBe('unknown');
42
- if (typeof manager !== 'string') {
43
- (0, bun_test_1.expect)(['npm', 'bun']).toContain(manager.manager);
44
- }
45
- },
46
- );
47
- (0, bun_test_1.test)(
48
- 'should return npm if only package-lock.json exists',
49
- () => {
50
- node_fs_1.default.writeFileSync(
51
- node_path_1.default.join(tempDir, 'package-lock.json'),
52
- '{}',
53
- );
54
- const manager = (0, get_package_manager_1.getPackageManager)(
55
- tempDir,
56
- undefined,
57
- 0,
58
- );
59
- if (typeof manager !== 'string') {
60
- (0, bun_test_1.expect)(manager.manager).toBe('npm');
61
- }
62
- },
63
- );
64
- });