@remotion/studio-server 4.0.461 → 4.0.463
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-effect-props/update-effect-props.d.ts +52 -0
- package/dist/codemods/update-effect-props/update-effect-props.js +229 -0
- package/dist/preview-server/api-routes.js +2 -0
- package/dist/preview-server/jsx-element-not-found-at-location-error.d.ts +3 -0
- package/dist/preview-server/jsx-element-not-found-at-location-error.js +10 -0
- package/dist/preview-server/project-info.js +27 -0
- package/dist/preview-server/routes/can-update-effect-props.d.ts +20 -0
- package/dist/preview-server/routes/can-update-effect-props.js +146 -0
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +21 -3
- package/dist/preview-server/routes/can-update-sequence-props.js +64 -13
- package/dist/preview-server/routes/log-updates/format-effect-prop-change.d.ts +10 -0
- package/dist/preview-server/routes/log-updates/format-effect-prop-change.js +51 -0
- package/dist/preview-server/routes/log-updates/log-effect-update.d.ts +14 -0
- package/dist/preview-server/routes/log-updates/log-effect-update.js +23 -0
- package/dist/preview-server/routes/save-effect-props.d.ts +3 -0
- package/dist/preview-server/routes/save-effect-props.js +108 -0
- package/dist/preview-server/routes/save-props-mutex.d.ts +1 -0
- package/dist/preview-server/routes/save-props-mutex.js +11 -0
- package/dist/preview-server/routes/save-sequence-props.d.ts +2 -3
- package/dist/preview-server/routes/save-sequence-props.js +10 -9
- package/dist/preview-server/routes/subscribe-to-sequence-props.js +4 -3
- package/dist/preview-server/routes/unsubscribe-from-sequence-props.js +4 -2
- package/dist/preview-server/sequence-props-watchers.d.ts +7 -3
- package/dist/preview-server/sequence-props-watchers.js +51 -22
- package/dist/preview-server/undo-stack.d.ts +3 -1
- package/package.json +6 -7
- package/dist/codemods/get-all-schema-keys.d.ts +0 -2
- package/dist/codemods/get-all-schema-keys.js +0 -8
- package/dist/codemods/jsx-sequence-context.d.ts +0 -11
- package/dist/codemods/jsx-sequence-context.js +0 -68
- package/dist/codemods/update-sequence-props.d.ts +0 -35
- package/dist/codemods/update-sequence-props.js +0 -228
- package/dist/preview-server/routes/log-update.d.ts +0 -29
- package/dist/preview-server/routes/log-update.js +0 -109
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ArrayExpression, CallExpression, JSXAttribute } from '@babel/types';
|
|
2
|
+
import type { SequenceNodePath } from 'remotion';
|
|
3
|
+
export type EffectPropUpdate = {
|
|
4
|
+
key: string;
|
|
5
|
+
value: unknown;
|
|
6
|
+
defaultValue: unknown | null;
|
|
7
|
+
};
|
|
8
|
+
export type UpdateEffectPropsResult = {
|
|
9
|
+
output: string;
|
|
10
|
+
formatted: boolean;
|
|
11
|
+
oldValueString: string;
|
|
12
|
+
logLine: number;
|
|
13
|
+
effectCallee: string;
|
|
14
|
+
};
|
|
15
|
+
export type EffectArrayElement = {
|
|
16
|
+
kind: 'call';
|
|
17
|
+
callee: string;
|
|
18
|
+
node: CallExpression;
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'unsupported';
|
|
21
|
+
reason: 'not-call-expression' | 'spread';
|
|
22
|
+
};
|
|
23
|
+
export declare const enumerateEffectArrayElements: (arr: ArrayExpression) => EffectArrayElement[];
|
|
24
|
+
export declare const findEffectCallExpression: ({ attr, effectIndex, }: {
|
|
25
|
+
attr: JSXAttribute;
|
|
26
|
+
effectIndex: number;
|
|
27
|
+
}) => {
|
|
28
|
+
kind: "ok";
|
|
29
|
+
call: CallExpression;
|
|
30
|
+
callee: string;
|
|
31
|
+
} | {
|
|
32
|
+
kind: "error";
|
|
33
|
+
reason: "not-call-expression" | "not-found";
|
|
34
|
+
};
|
|
35
|
+
export declare const updateEffectPropsAst: ({ input, sequenceNodePath, effectIndex, update, }: {
|
|
36
|
+
input: string;
|
|
37
|
+
sequenceNodePath: SequenceNodePath;
|
|
38
|
+
effectIndex: number;
|
|
39
|
+
update: EffectPropUpdate;
|
|
40
|
+
}) => {
|
|
41
|
+
serialized: string;
|
|
42
|
+
oldValueString: string;
|
|
43
|
+
logLine: number;
|
|
44
|
+
effectCallee: string;
|
|
45
|
+
};
|
|
46
|
+
export declare const updateEffectProps: ({ input, sequenceNodePath, effectIndex, update, prettierConfigOverride, }: {
|
|
47
|
+
input: string;
|
|
48
|
+
sequenceNodePath: SequenceNodePath;
|
|
49
|
+
effectIndex: number;
|
|
50
|
+
update: EffectPropUpdate;
|
|
51
|
+
prettierConfigOverride?: Record<string, unknown> | null | undefined;
|
|
52
|
+
}) => Promise<UpdateEffectPropsResult>;
|
|
@@ -0,0 +1,229 @@
|
|
|
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.updateEffectProps = exports.updateEffectPropsAst = exports.findEffectCallExpression = exports.enumerateEffectArrayElements = void 0;
|
|
37
|
+
const studio_shared_1 = require("@remotion/studio-shared");
|
|
38
|
+
const recast = __importStar(require("recast"));
|
|
39
|
+
const can_update_sequence_props_1 = require("../../preview-server/routes/can-update-sequence-props");
|
|
40
|
+
const format_file_content_1 = require("../format-file-content");
|
|
41
|
+
const parse_ast_1 = require("../parse-ast");
|
|
42
|
+
const b = recast.types.builders;
|
|
43
|
+
const parseValueExpression = (value) => {
|
|
44
|
+
const code = `a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: value, enumPaths: [] })}`;
|
|
45
|
+
const ast = (0, parse_ast_1.parseAst)(code);
|
|
46
|
+
const stmt = ast.program.body[0];
|
|
47
|
+
if (stmt.type !== 'ExpressionStatement' ||
|
|
48
|
+
stmt.expression.type !== 'AssignmentExpression') {
|
|
49
|
+
throw new Error('Failed to parse effect prop value expression');
|
|
50
|
+
}
|
|
51
|
+
return stmt.expression.right;
|
|
52
|
+
};
|
|
53
|
+
const findExperimentalEffectsAttr = (attrs) => {
|
|
54
|
+
for (const attr of attrs) {
|
|
55
|
+
if (attr.type !== 'JSXAttribute') {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
const a = attr;
|
|
59
|
+
if (a.name.type === 'JSXIdentifier' &&
|
|
60
|
+
a.name.name === '_experimentalEffects') {
|
|
61
|
+
return a;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return null;
|
|
65
|
+
};
|
|
66
|
+
const getCalleeName = (call) => {
|
|
67
|
+
const { callee } = call;
|
|
68
|
+
if (callee.type === 'Identifier') {
|
|
69
|
+
return callee.name;
|
|
70
|
+
}
|
|
71
|
+
if (callee.type === 'MemberExpression' &&
|
|
72
|
+
!callee.computed &&
|
|
73
|
+
callee.property.type === 'Identifier') {
|
|
74
|
+
return callee.property.name;
|
|
75
|
+
}
|
|
76
|
+
return null;
|
|
77
|
+
};
|
|
78
|
+
const enumerateEffectArrayElements = (arr) => {
|
|
79
|
+
const out = [];
|
|
80
|
+
for (const el of arr.elements) {
|
|
81
|
+
if (el === null) {
|
|
82
|
+
out.push({ kind: 'unsupported', reason: 'not-call-expression' });
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (el.type === 'SpreadElement') {
|
|
86
|
+
out.push({ kind: 'unsupported', reason: 'spread' });
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (el.type !== 'CallExpression') {
|
|
90
|
+
out.push({ kind: 'unsupported', reason: 'not-call-expression' });
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const call = el;
|
|
94
|
+
const callee = getCalleeName(call);
|
|
95
|
+
if (callee === null) {
|
|
96
|
+
out.push({ kind: 'unsupported', reason: 'not-call-expression' });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
out.push({ kind: 'call', callee, node: call });
|
|
100
|
+
}
|
|
101
|
+
return out;
|
|
102
|
+
};
|
|
103
|
+
exports.enumerateEffectArrayElements = enumerateEffectArrayElements;
|
|
104
|
+
const findEffectCallExpression = ({ attr, effectIndex, }) => {
|
|
105
|
+
if (!attr.value || attr.value.type !== 'JSXExpressionContainer') {
|
|
106
|
+
return { kind: 'error', reason: 'not-call-expression' };
|
|
107
|
+
}
|
|
108
|
+
const expr = attr.value.expression;
|
|
109
|
+
if (expr.type !== 'ArrayExpression') {
|
|
110
|
+
return { kind: 'error', reason: 'not-call-expression' };
|
|
111
|
+
}
|
|
112
|
+
const elements = (0, exports.enumerateEffectArrayElements)(expr);
|
|
113
|
+
if (effectIndex < 0 || effectIndex >= elements.length) {
|
|
114
|
+
return { kind: 'error', reason: 'not-found' };
|
|
115
|
+
}
|
|
116
|
+
const target = elements[effectIndex];
|
|
117
|
+
if (target.kind !== 'call') {
|
|
118
|
+
return { kind: 'error', reason: 'not-call-expression' };
|
|
119
|
+
}
|
|
120
|
+
return { kind: 'ok', call: target.node, callee: target.callee };
|
|
121
|
+
};
|
|
122
|
+
exports.findEffectCallExpression = findEffectCallExpression;
|
|
123
|
+
const findObjectProperty = (objExpr, propertyName) => {
|
|
124
|
+
const propIndex = objExpr.properties.findIndex((p) => p.type === 'ObjectProperty' &&
|
|
125
|
+
((p.key.type === 'Identifier' && p.key.name === propertyName) ||
|
|
126
|
+
(p.key.type === 'StringLiteral' &&
|
|
127
|
+
p.key.value === propertyName)));
|
|
128
|
+
return {
|
|
129
|
+
propIndex,
|
|
130
|
+
prop: propIndex !== -1
|
|
131
|
+
? objExpr.properties[propIndex]
|
|
132
|
+
: undefined,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
const updateEffectPropsAst = ({ input, sequenceNodePath, effectIndex, update, }) => {
|
|
136
|
+
var _a, _b, _c, _d;
|
|
137
|
+
var _e, _f, _g, _h, _j;
|
|
138
|
+
const ast = (0, parse_ast_1.parseAst)(input);
|
|
139
|
+
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath);
|
|
140
|
+
if (!jsx) {
|
|
141
|
+
throw new Error('Could not find a JSX element at the specified location to update effects');
|
|
142
|
+
}
|
|
143
|
+
const attr = findExperimentalEffectsAttr((_e = jsx.attributes) !== null && _e !== void 0 ? _e : []);
|
|
144
|
+
if (!attr) {
|
|
145
|
+
throw new Error('Could not find _experimentalEffects on the target JSX element');
|
|
146
|
+
}
|
|
147
|
+
const found = (0, exports.findEffectCallExpression)({
|
|
148
|
+
attr,
|
|
149
|
+
effectIndex,
|
|
150
|
+
});
|
|
151
|
+
if (found.kind === 'error') {
|
|
152
|
+
throw new Error(`Cannot update effect prop: ${found.reason}`);
|
|
153
|
+
}
|
|
154
|
+
const { call, callee: effectCallee } = found;
|
|
155
|
+
const isDefault = update.defaultValue !== null &&
|
|
156
|
+
JSON.stringify(update.value) === JSON.stringify(update.defaultValue);
|
|
157
|
+
let objExpr;
|
|
158
|
+
if (call.arguments.length === 0) {
|
|
159
|
+
if (isDefault) {
|
|
160
|
+
return {
|
|
161
|
+
serialized: (0, parse_ast_1.serializeAst)(ast),
|
|
162
|
+
oldValueString: '',
|
|
163
|
+
logLine: (_g = (_f = (_a = call.loc) === null || _a === void 0 ? void 0 : _a.start.line) !== null && _f !== void 0 ? _f : (_b = jsx.loc) === null || _b === void 0 ? void 0 : _b.start.line) !== null && _g !== void 0 ? _g : 1,
|
|
164
|
+
effectCallee,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
objExpr = b.objectExpression([]);
|
|
168
|
+
call.arguments.push(objExpr);
|
|
169
|
+
}
|
|
170
|
+
else if (call.arguments[0].type !== 'ObjectExpression') {
|
|
171
|
+
throw new Error('Cannot update effect prop: computed');
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
objExpr = call.arguments[0];
|
|
175
|
+
}
|
|
176
|
+
const { prop } = findObjectProperty(objExpr, update.key);
|
|
177
|
+
let oldValueString = '';
|
|
178
|
+
if (prop) {
|
|
179
|
+
oldValueString = recast.print(prop.value).code;
|
|
180
|
+
}
|
|
181
|
+
else if (update.defaultValue !== null) {
|
|
182
|
+
oldValueString = JSON.stringify(update.defaultValue);
|
|
183
|
+
}
|
|
184
|
+
if (isDefault) {
|
|
185
|
+
if (prop) {
|
|
186
|
+
const idx = objExpr.properties.indexOf(prop);
|
|
187
|
+
if (idx !== -1) {
|
|
188
|
+
objExpr.properties.splice(idx, 1);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
const newValueExpr = parseValueExpression(update.value);
|
|
194
|
+
if (prop) {
|
|
195
|
+
prop.value = newValueExpr;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
objExpr.properties.push(b.objectProperty(b.identifier(update.key), newValueExpr));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const logLine = (_j = (_h = (_c = call.loc) === null || _c === void 0 ? void 0 : _c.start.line) !== null && _h !== void 0 ? _h : (_d = jsx.loc) === null || _d === void 0 ? void 0 : _d.start.line) !== null && _j !== void 0 ? _j : 1;
|
|
202
|
+
return {
|
|
203
|
+
serialized: (0, parse_ast_1.serializeAst)(ast),
|
|
204
|
+
oldValueString,
|
|
205
|
+
logLine,
|
|
206
|
+
effectCallee,
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
exports.updateEffectPropsAst = updateEffectPropsAst;
|
|
210
|
+
const updateEffectProps = async ({ input, sequenceNodePath, effectIndex, update, prettierConfigOverride, }) => {
|
|
211
|
+
const { serialized, oldValueString, logLine, effectCallee } = (0, exports.updateEffectPropsAst)({
|
|
212
|
+
input,
|
|
213
|
+
sequenceNodePath,
|
|
214
|
+
effectIndex,
|
|
215
|
+
update,
|
|
216
|
+
});
|
|
217
|
+
const { output, formatted } = await (0, format_file_content_1.formatFileContent)({
|
|
218
|
+
input: serialized,
|
|
219
|
+
prettierConfigOverride,
|
|
220
|
+
});
|
|
221
|
+
return {
|
|
222
|
+
output,
|
|
223
|
+
oldValueString,
|
|
224
|
+
formatted,
|
|
225
|
+
logLine,
|
|
226
|
+
effectCallee,
|
|
227
|
+
};
|
|
228
|
+
};
|
|
229
|
+
exports.updateEffectProps = updateEffectProps;
|
|
@@ -14,6 +14,7 @@ const project_info_1 = require("./routes/project-info");
|
|
|
14
14
|
const redo_1 = require("./routes/redo");
|
|
15
15
|
const remove_render_1 = require("./routes/remove-render");
|
|
16
16
|
const restart_studio_1 = require("./routes/restart-studio");
|
|
17
|
+
const save_effect_props_1 = require("./routes/save-effect-props");
|
|
17
18
|
const save_sequence_props_1 = require("./routes/save-sequence-props");
|
|
18
19
|
const subscribe_to_default_props_1 = require("./routes/subscribe-to-default-props");
|
|
19
20
|
const subscribe_to_file_existence_1 = require("./routes/subscribe-to-file-existence");
|
|
@@ -39,6 +40,7 @@ exports.allApiRoutes = {
|
|
|
39
40
|
'/api/subscribe-to-sequence-props': subscribe_to_sequence_props_1.subscribeToSequenceProps,
|
|
40
41
|
'/api/unsubscribe-from-sequence-props': unsubscribe_from_sequence_props_1.unsubscribeFromSequenceProps,
|
|
41
42
|
'/api/save-sequence-props': save_sequence_props_1.saveSequencePropsHandler,
|
|
43
|
+
'/api/save-effect-props': save_effect_props_1.saveEffectPropsHandler,
|
|
42
44
|
'/api/delete-jsx-node': delete_jsx_node_1.deleteJsxNodeHandler,
|
|
43
45
|
'/api/duplicate-jsx-node': duplicate_jsx_node_1.duplicateJsxNodeHandler,
|
|
44
46
|
'/api/update-available': update_available_1.handleUpdate,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.JsxElementNotFoundAtLocationError = void 0;
|
|
4
|
+
class JsxElementNotFoundAtLocationError extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super('Cannot compute sequence props status: Could not find a JSX element at the specified location');
|
|
7
|
+
this.name = 'JsxElementNotFoundAtLocationError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.JsxElementNotFoundAtLocationError = JsxElementNotFoundAtLocationError;
|
|
@@ -6,8 +6,35 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.getProjectInfo = void 0;
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const getRootFileFromEntryPoint = (entryPoint) => {
|
|
10
|
+
const entryBase = node_path_1.default.basename(entryPoint, node_path_1.default.extname(entryPoint));
|
|
11
|
+
if (!entryBase.endsWith('-entry')) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const stem = entryBase.slice(0, -'-entry'.length);
|
|
15
|
+
const pascalCase = stem
|
|
16
|
+
.split('-')
|
|
17
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
18
|
+
.join('');
|
|
19
|
+
const rootName = `${pascalCase}Root`;
|
|
20
|
+
const entryDir = node_path_1.default.dirname(entryPoint);
|
|
21
|
+
for (const ext of ['.tsx', '.ts', '.jsx', '.js']) {
|
|
22
|
+
const candidate = node_path_1.default.join(entryDir, rootName + ext);
|
|
23
|
+
if ((0, node_fs_1.existsSync)(candidate)) {
|
|
24
|
+
return candidate;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
};
|
|
9
29
|
const getProjectInfo = (remotionRoot, entryPoint) => {
|
|
10
30
|
var _a;
|
|
31
|
+
const rootFileFromEntryPoint = getRootFileFromEntryPoint(entryPoint);
|
|
32
|
+
if (rootFileFromEntryPoint) {
|
|
33
|
+
return Promise.resolve({
|
|
34
|
+
rootFile: rootFileFromEntryPoint,
|
|
35
|
+
relativeRootFile: node_path_1.default.relative(remotionRoot, rootFileFromEntryPoint),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
11
38
|
const knownPaths = [
|
|
12
39
|
'src/Root.tsx',
|
|
13
40
|
'src/Root.jsx',
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JSXOpeningElement } from '@babel/types';
|
|
2
|
+
import type { CanUpdateEffectPropsResponse, SequenceNodePath, SequenceSchema } from 'remotion';
|
|
3
|
+
export declare const computeEffectPropStatus: ({ jsx, effectIndex, keys, }: {
|
|
4
|
+
jsx: JSXOpeningElement;
|
|
5
|
+
effectIndex: number;
|
|
6
|
+
keys: string[];
|
|
7
|
+
}) => CanUpdateEffectPropsResponse;
|
|
8
|
+
export declare const computeEffectPropsStatusesFromContent: ({ fileContents, sequenceNodePath, effects, keysFor, }: {
|
|
9
|
+
fileContents: string;
|
|
10
|
+
sequenceNodePath: SequenceNodePath;
|
|
11
|
+
effects: SequenceSchema[];
|
|
12
|
+
keysFor: (effect: SequenceSchema) => string[];
|
|
13
|
+
}) => CanUpdateEffectPropsResponse[];
|
|
14
|
+
export declare const computeEffectPropsStatusesFromFile: ({ fileName, sequenceNodePath, effects, keysFor, remotionRoot, }: {
|
|
15
|
+
fileName: string;
|
|
16
|
+
sequenceNodePath: SequenceNodePath;
|
|
17
|
+
effects: SequenceSchema[];
|
|
18
|
+
keysFor: (effect: SequenceSchema) => string[];
|
|
19
|
+
remotionRoot: string;
|
|
20
|
+
}) => CanUpdateEffectPropsResponse[];
|
|
@@ -0,0 +1,146 @@
|
|
|
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.computeEffectPropsStatusesFromFile = exports.computeEffectPropsStatusesFromContent = exports.computeEffectPropStatus = 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 update_effect_props_1 = require("../../codemods/update-effect-props/update-effect-props");
|
|
11
|
+
const can_update_sequence_props_1 = require("./can-update-sequence-props");
|
|
12
|
+
const findExperimentalEffectsAttr = (jsx) => {
|
|
13
|
+
for (const attr of jsx.attributes) {
|
|
14
|
+
if (attr.type !== 'JSXAttribute') {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
if (attr.name.type === 'JSXIdentifier' &&
|
|
18
|
+
attr.name.name === '_experimentalEffects') {
|
|
19
|
+
return attr;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
};
|
|
24
|
+
const getEffectsArrayElements = (attr) => {
|
|
25
|
+
if (!attr || !attr.value || attr.value.type !== 'JSXExpressionContainer') {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const expr = attr.value.expression;
|
|
29
|
+
if (expr.type !== 'ArrayExpression') {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return (0, update_effect_props_1.enumerateEffectArrayElements)(expr);
|
|
33
|
+
};
|
|
34
|
+
const getPropsFromObjectExpression = ({ objExpr, keys, }) => {
|
|
35
|
+
const out = {};
|
|
36
|
+
for (const key of keys) {
|
|
37
|
+
const prop = objExpr.properties.find((p) => p.type === 'ObjectProperty' &&
|
|
38
|
+
((p.key.type === 'Identifier' && p.key.name === key) ||
|
|
39
|
+
(p.key.type === 'StringLiteral' &&
|
|
40
|
+
p.key.value === key)));
|
|
41
|
+
if (!prop) {
|
|
42
|
+
out[key] = { canUpdate: true, codeValue: undefined };
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const valueExpr = prop.value;
|
|
46
|
+
if (!(0, can_update_sequence_props_1.isStaticValue)(valueExpr)) {
|
|
47
|
+
out[key] = { canUpdate: false, reason: 'computed' };
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
out[key] = {
|
|
51
|
+
canUpdate: true,
|
|
52
|
+
codeValue: (0, can_update_sequence_props_1.extractStaticValue)(valueExpr),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return out;
|
|
56
|
+
};
|
|
57
|
+
const computeEffectPropStatus = ({ jsx, effectIndex, keys, }) => {
|
|
58
|
+
const attr = findExperimentalEffectsAttr(jsx);
|
|
59
|
+
const elements = getEffectsArrayElements(attr);
|
|
60
|
+
if (!elements) {
|
|
61
|
+
return {
|
|
62
|
+
canUpdate: false,
|
|
63
|
+
effectIndex,
|
|
64
|
+
reason: 'not-found',
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (effectIndex < 0 || effectIndex >= elements.length) {
|
|
68
|
+
return {
|
|
69
|
+
canUpdate: false,
|
|
70
|
+
effectIndex,
|
|
71
|
+
reason: 'not-found',
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const target = elements[effectIndex];
|
|
75
|
+
if (target.kind !== 'call') {
|
|
76
|
+
return {
|
|
77
|
+
canUpdate: false,
|
|
78
|
+
effectIndex,
|
|
79
|
+
reason: 'not-call-expression',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const call = target.node;
|
|
83
|
+
if (call.arguments.length === 0) {
|
|
84
|
+
const emptyProps = {};
|
|
85
|
+
for (const key of keys) {
|
|
86
|
+
emptyProps[key] = { canUpdate: true, codeValue: undefined };
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
canUpdate: true,
|
|
90
|
+
callee: target.callee,
|
|
91
|
+
effectIndex,
|
|
92
|
+
props: emptyProps,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const firstArg = call.arguments[0];
|
|
96
|
+
if (firstArg.type !== 'ObjectExpression') {
|
|
97
|
+
return {
|
|
98
|
+
canUpdate: false,
|
|
99
|
+
effectIndex,
|
|
100
|
+
reason: 'computed',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const resolvedProps = getPropsFromObjectExpression({
|
|
104
|
+
objExpr: firstArg,
|
|
105
|
+
keys,
|
|
106
|
+
});
|
|
107
|
+
return {
|
|
108
|
+
canUpdate: true,
|
|
109
|
+
effectIndex,
|
|
110
|
+
callee: target.callee,
|
|
111
|
+
props: resolvedProps,
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
exports.computeEffectPropStatus = computeEffectPropStatus;
|
|
115
|
+
const computeEffectPropsStatusesFromContent = ({ fileContents, sequenceNodePath, effects, keysFor, }) => {
|
|
116
|
+
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
117
|
+
const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath);
|
|
118
|
+
if (!jsx) {
|
|
119
|
+
return effects.map((_effect, effectIndex) => ({
|
|
120
|
+
canUpdate: false,
|
|
121
|
+
effectIndex,
|
|
122
|
+
reason: 'not-found',
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
return effects.map((effect, effectIndex) => (0, exports.computeEffectPropStatus)({
|
|
126
|
+
jsx,
|
|
127
|
+
effectIndex,
|
|
128
|
+
keys: keysFor(effect),
|
|
129
|
+
}));
|
|
130
|
+
};
|
|
131
|
+
exports.computeEffectPropsStatusesFromContent = computeEffectPropsStatusesFromContent;
|
|
132
|
+
const computeEffectPropsStatusesFromFile = ({ fileName, sequenceNodePath, effects, keysFor, remotionRoot, }) => {
|
|
133
|
+
const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
|
|
134
|
+
const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
|
|
135
|
+
if (fileRelativeToRoot.startsWith('..')) {
|
|
136
|
+
throw new Error('Cannot read a file outside the project');
|
|
137
|
+
}
|
|
138
|
+
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
139
|
+
return (0, exports.computeEffectPropsStatusesFromContent)({
|
|
140
|
+
fileContents,
|
|
141
|
+
sequenceNodePath,
|
|
142
|
+
effects,
|
|
143
|
+
keysFor,
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
exports.computeEffectPropsStatusesFromFile = computeEffectPropsStatusesFromFile;
|
|
@@ -2,20 +2,38 @@ import type { Expression, File, JSXOpeningElement } from '@babel/types';
|
|
|
2
2
|
import type { SubscribeToSequencePropsResponse } from '@remotion/studio-shared';
|
|
3
3
|
import type { CanUpdateSequencePropsResponseTrue } from 'remotion';
|
|
4
4
|
import type { SequenceNodePath } from 'remotion';
|
|
5
|
+
import type { CanUpdateSequencePropStatus } from 'remotion';
|
|
5
6
|
export declare const isStaticValue: (node: Expression) => boolean;
|
|
6
7
|
export declare const extractStaticValue: (node: Expression) => unknown;
|
|
7
8
|
export declare const findJsxElementAtNodePath: (ast: File, nodePath: SequenceNodePath) => JSXOpeningElement | null;
|
|
8
9
|
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const computeSequencePropsStatus: ({ fileName, nodePath, keys, remotionRoot, }: {
|
|
10
|
+
export declare const computeSequencePropsOnlyStatus: ({ fileName, nodePath, keys, remotionRoot, }: {
|
|
11
11
|
fileName: string;
|
|
12
12
|
nodePath: SequenceNodePath;
|
|
13
13
|
keys: string[];
|
|
14
14
|
remotionRoot: string;
|
|
15
|
+
}) => {
|
|
16
|
+
canUpdate: true;
|
|
17
|
+
props: Record<string, CanUpdateSequencePropStatus>;
|
|
18
|
+
};
|
|
19
|
+
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, keys, effects, }: {
|
|
20
|
+
fileContents: string;
|
|
21
|
+
nodePath: SequenceNodePath;
|
|
22
|
+
keys: string[];
|
|
23
|
+
effects: string[][];
|
|
24
|
+
}) => CanUpdateSequencePropsResponseTrue;
|
|
25
|
+
export declare const computeSequencePropsStatus: ({ fileName, nodePath, keys, effects, remotionRoot, }: {
|
|
26
|
+
fileName: string;
|
|
27
|
+
nodePath: SequenceNodePath;
|
|
28
|
+
keys: string[];
|
|
29
|
+
effects: string[][];
|
|
30
|
+
remotionRoot: string;
|
|
15
31
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
16
|
-
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, keys, remotionRoot, }: {
|
|
32
|
+
export declare const computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, keys, effects, remotionRoot, logLevel, }: {
|
|
17
33
|
fileName: string;
|
|
18
34
|
line: number;
|
|
19
35
|
keys: string[];
|
|
36
|
+
effects: string[][];
|
|
20
37
|
remotionRoot: string;
|
|
38
|
+
logLevel: "error" | "info" | "trace" | "verbose" | "warn";
|
|
21
39
|
}) => SubscribeToSequencePropsResponse;
|