@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.
- package/dist/codemods/update-nested-prop.d.ts +13 -0
- package/dist/codemods/update-nested-prop.js +158 -0
- package/dist/codemods/update-sequence-props.d.ts +1 -1
- package/dist/codemods/update-sequence-props.js +22 -7
- package/dist/preview-server/routes/can-update-sequence-props.js +36 -1
- package/package.json +7 -7
- package/dist/preview-server/__tests__/multiple-lockfiles.test.d.ts +0 -1
- package/dist/preview-server/__tests__/multiple-lockfiles.test.js +0 -64
|
@@ -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;
|
|
@@ -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,
|
|
88
|
-
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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.
|
|
30
|
+
"remotion": "4.0.432",
|
|
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.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.
|
|
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.
|
|
47
|
+
"@typescript/native-preview": "7.0.0-dev.20260301.1"
|
|
48
48
|
},
|
|
49
49
|
"exports": {
|
|
50
50
|
".": "./dist/index.js",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -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
|
-
});
|