@remotion/studio-server 4.0.501 → 4.0.502
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-inline-caption-patches.d.ts +1 -11
- package/dist/codemods/update-inline-caption-patches.js +2 -183
- package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +2 -35
- package/dist/codemods/update-sequence-props/update-sequence-props.js +7 -720
- package/dist/helpers/resolve-composition-component.js +18 -6
- package/dist/preview-server/element-install-state.d.ts +16 -0
- package/dist/preview-server/element-install-state.js +43 -1
- package/dist/preview-server/handler.js +1 -1
- package/dist/preview-server/parse-body.d.ts +6 -1
- package/dist/preview-server/parse-body.js +60 -9
- package/dist/preview-server/routes/can-update-default-props.d.ts +1 -1
- package/dist/preview-server/routes/can-update-default-props.js +5 -132
- package/dist/preview-server/routes/can-update-sequence-props.d.ts +3 -2
- package/dist/preview-server/routes/can-update-sequence-props.js +51 -9
- package/dist/preview-server/routes/insert-element.js +5 -5
- package/dist/preview-server/routes/insert-jsx-element.js +5 -5
- package/dist/preview-server/sequence-props-watchers.js +2 -1
- package/dist/preview-server/studio-protocol/handle-discovery.d.ts +11 -0
- package/dist/preview-server/studio-protocol/handle-discovery.js +99 -0
- package/dist/preview-server/studio-protocol/handle-install.d.ts +10 -0
- package/dist/preview-server/studio-protocol/handle-install.js +139 -0
- package/dist/preview-server/studio-protocol/origin-policy.d.ts +10 -0
- package/dist/preview-server/studio-protocol/origin-policy.js +40 -0
- package/dist/preview-server/studio-protocol/protocol-response.d.ts +7 -0
- package/dist/preview-server/studio-protocol/protocol-response.js +13 -0
- package/dist/routes.js +14 -154
- package/package.json +9 -8
|
@@ -248,9 +248,6 @@ const findReExportTargets = ({ ast, exportName, }) => {
|
|
|
248
248
|
visitExportNamedDeclaration(astPath) {
|
|
249
249
|
var _a;
|
|
250
250
|
const node = astPath.node;
|
|
251
|
-
if (typeof ((_a = node.source) === null || _a === void 0 ? void 0 : _a.value) !== 'string') {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
251
|
for (const specifier of node.specifiers) {
|
|
255
252
|
if (specifier.type !== 'ExportSpecifier') {
|
|
256
253
|
continue;
|
|
@@ -263,6 +260,18 @@ const findReExportTargets = ({ ast, exportName, }) => {
|
|
|
263
260
|
if (!localName) {
|
|
264
261
|
continue;
|
|
265
262
|
}
|
|
263
|
+
// Support barrel files that import a component and export it in a
|
|
264
|
+
// separate declaration. See https://github.com/remotion-dev/remotion/issues/9172.
|
|
265
|
+
if (typeof ((_a = node.source) === null || _a === void 0 ? void 0 : _a.value) !== 'string') {
|
|
266
|
+
const importTarget = findImportTarget({
|
|
267
|
+
ast,
|
|
268
|
+
componentName: localName,
|
|
269
|
+
});
|
|
270
|
+
if (importTarget) {
|
|
271
|
+
targets.push(importTarget);
|
|
272
|
+
}
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
266
275
|
targets.push({
|
|
267
276
|
importPath: node.source.value,
|
|
268
277
|
exportName: localName === 'default' ? 'default' : localName,
|
|
@@ -314,6 +323,9 @@ const locationFromNode = (node) => {
|
|
|
314
323
|
};
|
|
315
324
|
const findLocalSymbolLocation = ({ ast, name, }) => {
|
|
316
325
|
let location = null;
|
|
326
|
+
// Recast can omit the declaration location for exported functions and
|
|
327
|
+
// classes, including components resolved through barrel files. The identifier
|
|
328
|
+
// keeps its location. See https://github.com/remotion-dev/remotion/issues/9172.
|
|
317
329
|
recast.types.visit(ast, {
|
|
318
330
|
visitVariableDeclarator(astPath) {
|
|
319
331
|
if (location) {
|
|
@@ -321,7 +333,7 @@ const findLocalSymbolLocation = ({ ast, name, }) => {
|
|
|
321
333
|
}
|
|
322
334
|
const { node } = astPath;
|
|
323
335
|
if (node.id.type === 'Identifier' && node.id.name === name) {
|
|
324
|
-
location = locationFromNode(node);
|
|
336
|
+
location = locationFromNode(node.id);
|
|
325
337
|
return false;
|
|
326
338
|
}
|
|
327
339
|
this.traverse(astPath);
|
|
@@ -334,7 +346,7 @@ const findLocalSymbolLocation = ({ ast, name, }) => {
|
|
|
334
346
|
}
|
|
335
347
|
const { node } = astPath;
|
|
336
348
|
if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
|
|
337
|
-
location = locationFromNode(node);
|
|
349
|
+
location = locationFromNode(node.id);
|
|
338
350
|
return false;
|
|
339
351
|
}
|
|
340
352
|
this.traverse(astPath);
|
|
@@ -347,7 +359,7 @@ const findLocalSymbolLocation = ({ ast, name, }) => {
|
|
|
347
359
|
}
|
|
348
360
|
const { node } = astPath;
|
|
349
361
|
if (((_a = node.id) === null || _a === void 0 ? void 0 : _a.name) === name) {
|
|
350
|
-
location = locationFromNode(node);
|
|
362
|
+
location = locationFromNode(node.id);
|
|
351
363
|
return false;
|
|
352
364
|
}
|
|
353
365
|
this.traverse(astPath);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const ELEMENT_INSTALL_TARGET_MAX_AGE = 5000;
|
|
2
|
+
export declare const STUDIO_PROTOCOL_TARGET_MAX_AGE = 4000;
|
|
2
3
|
export type ElementInstallTarget = {
|
|
3
4
|
requestId: string | null;
|
|
4
5
|
clientId: string;
|
|
@@ -10,6 +11,21 @@ export type ElementInstallTarget = {
|
|
|
10
11
|
studioUrl: string;
|
|
11
12
|
updatedAt: number;
|
|
12
13
|
};
|
|
14
|
+
type StudioProtocolTarget = {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly target: ElementInstallTarget;
|
|
17
|
+
readonly expiresAt: number;
|
|
18
|
+
};
|
|
13
19
|
export declare const updateElementInstallTarget: (newTarget: Omit<ElementInstallTarget, "updatedAt">) => void;
|
|
20
|
+
export declare const getElementInstallTargetByClientId: (clientId: string) => ElementInstallTarget | null;
|
|
14
21
|
export declare const getElementInstallTarget: (requestId: string | null) => ElementInstallTarget | null;
|
|
22
|
+
export declare const issueStudioProtocolTarget: ({ now, target, }: {
|
|
23
|
+
readonly now: number;
|
|
24
|
+
readonly target: ElementInstallTarget;
|
|
25
|
+
}) => StudioProtocolTarget;
|
|
26
|
+
export declare const consumeStudioProtocolTarget: ({ now, targetId, }: {
|
|
27
|
+
readonly now: number;
|
|
28
|
+
readonly targetId: string;
|
|
29
|
+
}) => ElementInstallTarget | null;
|
|
15
30
|
export declare const clearElementInstallStateForTests: () => void;
|
|
31
|
+
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.clearElementInstallStateForTests = exports.getElementInstallTarget = exports.updateElementInstallTarget = exports.ELEMENT_INSTALL_TARGET_MAX_AGE = void 0;
|
|
3
|
+
exports.clearElementInstallStateForTests = exports.consumeStudioProtocolTarget = exports.issueStudioProtocolTarget = exports.getElementInstallTarget = exports.getElementInstallTargetByClientId = exports.updateElementInstallTarget = exports.STUDIO_PROTOCOL_TARGET_MAX_AGE = exports.ELEMENT_INSTALL_TARGET_MAX_AGE = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
4
5
|
exports.ELEMENT_INSTALL_TARGET_MAX_AGE = 5000;
|
|
6
|
+
exports.STUDIO_PROTOCOL_TARGET_MAX_AGE = 4000;
|
|
5
7
|
const targetsByClientId = new Map();
|
|
8
|
+
const studioProtocolTargets = new Map();
|
|
6
9
|
const compareTargets = (a, b) => {
|
|
7
10
|
var _a, _b;
|
|
8
11
|
const aFocusedAt = (_a = a.lastFocusedAt) !== null && _a !== void 0 ? _a : 0;
|
|
@@ -19,6 +22,11 @@ const updateElementInstallTarget = (newTarget) => {
|
|
|
19
22
|
});
|
|
20
23
|
};
|
|
21
24
|
exports.updateElementInstallTarget = updateElementInstallTarget;
|
|
25
|
+
const getElementInstallTargetByClientId = (clientId) => {
|
|
26
|
+
var _a;
|
|
27
|
+
return (_a = targetsByClientId.get(clientId)) !== null && _a !== void 0 ? _a : null;
|
|
28
|
+
};
|
|
29
|
+
exports.getElementInstallTargetByClientId = getElementInstallTargetByClientId;
|
|
22
30
|
const getElementInstallTarget = (requestId) => {
|
|
23
31
|
const now = Date.now();
|
|
24
32
|
let bestTarget = null;
|
|
@@ -37,7 +45,41 @@ const getElementInstallTarget = (requestId) => {
|
|
|
37
45
|
return bestTarget;
|
|
38
46
|
};
|
|
39
47
|
exports.getElementInstallTarget = getElementInstallTarget;
|
|
48
|
+
const issueStudioProtocolTarget = ({ now, target, }) => {
|
|
49
|
+
for (const [id, existing] of studioProtocolTargets) {
|
|
50
|
+
if (existing.expiresAt <= now) {
|
|
51
|
+
studioProtocolTargets.delete(id);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const issued = {
|
|
55
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
56
|
+
target: { ...target },
|
|
57
|
+
expiresAt: now + exports.STUDIO_PROTOCOL_TARGET_MAX_AGE,
|
|
58
|
+
};
|
|
59
|
+
studioProtocolTargets.set(issued.id, issued);
|
|
60
|
+
return issued;
|
|
61
|
+
};
|
|
62
|
+
exports.issueStudioProtocolTarget = issueStudioProtocolTarget;
|
|
63
|
+
const consumeStudioProtocolTarget = ({ now, targetId, }) => {
|
|
64
|
+
const issued = studioProtocolTargets.get(targetId);
|
|
65
|
+
studioProtocolTargets.delete(targetId);
|
|
66
|
+
if (issued === undefined || issued.expiresAt <= now) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
const current = (0, exports.getElementInstallTargetByClientId)(issued.target.clientId);
|
|
70
|
+
if (current === null ||
|
|
71
|
+
now - current.updatedAt >= exports.ELEMENT_INSTALL_TARGET_MAX_AGE ||
|
|
72
|
+
!current.canInstall ||
|
|
73
|
+
current.readOnly ||
|
|
74
|
+
current.compositionFile !== issued.target.compositionFile ||
|
|
75
|
+
current.compositionId !== issued.target.compositionId) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
return issued.target;
|
|
79
|
+
};
|
|
80
|
+
exports.consumeStudioProtocolTarget = consumeStudioProtocolTarget;
|
|
40
81
|
const clearElementInstallStateForTests = () => {
|
|
41
82
|
targetsByClientId.clear();
|
|
83
|
+
studioProtocolTargets.clear();
|
|
42
84
|
};
|
|
43
85
|
exports.clearElementInstallStateForTests = clearElementInstallStateForTests;
|
|
@@ -13,7 +13,7 @@ const handleRequest = async ({ remotionRoot, request, response, entryPoint, hand
|
|
|
13
13
|
response.setHeader('content-type', 'application/json');
|
|
14
14
|
response.writeHead(200);
|
|
15
15
|
try {
|
|
16
|
-
const body = (await (0, parse_body_1.parseRequestBody)(request));
|
|
16
|
+
const body = (await (0, parse_body_1.parseRequestBody)(request, { maxBytes: null }));
|
|
17
17
|
const outputData = await handler({
|
|
18
18
|
entryPoint,
|
|
19
19
|
remotionRoot,
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'node:http';
|
|
2
|
-
export declare
|
|
2
|
+
export declare class RequestBodyTooLargeError extends Error {
|
|
3
|
+
constructor(maxBytes: number);
|
|
4
|
+
}
|
|
5
|
+
export declare const parseRequestBody: (req: IncomingMessage, { maxBytes, }: {
|
|
6
|
+
readonly maxBytes: number | null;
|
|
7
|
+
}) => Promise<unknown>;
|
|
@@ -1,15 +1,66 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseRequestBody = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
exports.parseRequestBody = exports.RequestBodyTooLargeError = void 0;
|
|
4
|
+
class RequestBodyTooLargeError extends Error {
|
|
5
|
+
constructor(maxBytes) {
|
|
6
|
+
super(`Request body exceeds the limit of ${maxBytes} bytes`);
|
|
7
|
+
this.name = 'RequestBodyTooLargeError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.RequestBodyTooLargeError = RequestBodyTooLargeError;
|
|
11
|
+
const parseRequestBody = async (req, { maxBytes, }) => {
|
|
12
|
+
const body = await new Promise((resolve, reject) => {
|
|
13
|
+
const decoder = new TextDecoder();
|
|
14
|
+
const encoder = new TextEncoder();
|
|
6
15
|
let data = '';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
let receivedBytes = 0;
|
|
17
|
+
let settled = false;
|
|
18
|
+
const cleanup = () => {
|
|
19
|
+
req.off('aborted', onAborted);
|
|
20
|
+
req.off('data', onData);
|
|
21
|
+
req.off('end', onEnd);
|
|
22
|
+
req.off('error', onError);
|
|
23
|
+
};
|
|
24
|
+
const rejectOnce = (error) => {
|
|
25
|
+
if (settled) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
settled = true;
|
|
29
|
+
cleanup();
|
|
30
|
+
reject(error);
|
|
31
|
+
};
|
|
32
|
+
const onAborted = () => rejectOnce(new Error('Request body was aborted'));
|
|
33
|
+
const onData = (chunk) => {
|
|
34
|
+
receivedBytes +=
|
|
35
|
+
typeof chunk === 'string'
|
|
36
|
+
? encoder.encode(chunk).byteLength
|
|
37
|
+
: chunk.byteLength;
|
|
38
|
+
if (maxBytes !== null && receivedBytes > maxBytes) {
|
|
39
|
+
rejectOnce(new RequestBodyTooLargeError(maxBytes));
|
|
40
|
+
// Discard the rest without buffering it. Keep request stream errors from
|
|
41
|
+
// becoming unhandled after the parser listeners have been removed.
|
|
42
|
+
req.on('error', () => undefined);
|
|
43
|
+
req.resume();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
data +=
|
|
47
|
+
typeof chunk === 'string'
|
|
48
|
+
? decoder.decode() + chunk
|
|
49
|
+
: decoder.decode(chunk, { stream: true });
|
|
50
|
+
};
|
|
51
|
+
const onEnd = () => {
|
|
52
|
+
if (settled) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
settled = true;
|
|
56
|
+
cleanup();
|
|
57
|
+
resolve(data + decoder.decode());
|
|
58
|
+
};
|
|
59
|
+
const onError = (error) => rejectOnce(error);
|
|
60
|
+
req.on('aborted', onAborted);
|
|
61
|
+
req.on('data', onData);
|
|
62
|
+
req.on('end', onEnd);
|
|
63
|
+
req.on('error', onError);
|
|
13
64
|
});
|
|
14
65
|
return JSON.parse(body);
|
|
15
66
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanUpdateDefaultPropsResponse } from '@remotion/studio-shared';
|
|
2
|
+
export { computeCanUpdateDefaultPropsFromContent } from '@remotion/studio-codemods';
|
|
2
3
|
export declare const checkIfTypeScriptFile: (file: string) => void;
|
|
3
|
-
export declare const computeCanUpdateDefaultPropsFromContent: (content: string, compositionId: string) => CanUpdateDefaultPropsResponse;
|
|
4
4
|
export declare const computeCanUpdateDefaultProps: ({ compositionId, remotionRoot, entryPoint, }: {
|
|
5
5
|
compositionId: string;
|
|
6
6
|
remotionRoot: string;
|
|
@@ -1,44 +1,11 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.computeCanUpdateDefaultProps = exports.
|
|
3
|
+
exports.computeCanUpdateDefaultProps = exports.checkIfTypeScriptFile = exports.computeCanUpdateDefaultPropsFromContent = void 0;
|
|
37
4
|
const node_fs_1 = require("node:fs");
|
|
38
|
-
const
|
|
39
|
-
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
5
|
+
const studio_codemods_1 = require("@remotion/studio-codemods");
|
|
40
6
|
const project_info_1 = require("../project-info");
|
|
41
|
-
const
|
|
7
|
+
const studio_codemods_2 = require("@remotion/studio-codemods");
|
|
8
|
+
Object.defineProperty(exports, "computeCanUpdateDefaultPropsFromContent", { enumerable: true, get: function () { return studio_codemods_2.computeCanUpdateDefaultPropsFromContent; } });
|
|
42
9
|
const checkIfTypeScriptFile = (file) => {
|
|
43
10
|
if (!file.endsWith('.tsx') &&
|
|
44
11
|
!file.endsWith('.ts') &&
|
|
@@ -48,100 +15,6 @@ const checkIfTypeScriptFile = (file) => {
|
|
|
48
15
|
}
|
|
49
16
|
};
|
|
50
17
|
exports.checkIfTypeScriptFile = checkIfTypeScriptFile;
|
|
51
|
-
const extractDefaultPropsFromSource = (input, compositionId) => {
|
|
52
|
-
const ast = (0, parse_ast_1.parseAst)(input);
|
|
53
|
-
let result = null;
|
|
54
|
-
recast.types.visit(ast, {
|
|
55
|
-
visitJSXElement(path) {
|
|
56
|
-
var _a;
|
|
57
|
-
const { openingElement } = path.node;
|
|
58
|
-
const openingName = openingElement.name;
|
|
59
|
-
if (openingName.type !== 'JSXIdentifier' &&
|
|
60
|
-
openingName.type !== 'JSXNamespacedName') {
|
|
61
|
-
this.traverse(path);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (openingName.name !== 'Composition' && openingName.name !== 'Still') {
|
|
65
|
-
this.traverse(path);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
if (!((_a = openingElement.attributes) === null || _a === void 0 ? void 0 : _a.some((attr) => {
|
|
69
|
-
if (attr.type === 'JSXSpreadAttribute') {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
if (!attr.value) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
if (attr.value.type === 'JSXElement') {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (attr.value.type === 'JSXExpressionContainer') {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (attr.value.type === 'JSXFragment') {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
return attr.name.name === 'id' && attr.value.value === compositionId;
|
|
85
|
-
}))) {
|
|
86
|
-
this.traverse(path);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const defaultPropsAttr = openingElement.attributes.find((attr) => {
|
|
90
|
-
if (attr.type === 'JSXSpreadAttribute') {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
return attr.name.name === 'defaultProps';
|
|
94
|
-
});
|
|
95
|
-
if (!defaultPropsAttr || defaultPropsAttr.type === 'JSXSpreadAttribute') {
|
|
96
|
-
this.traverse(path);
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
if (!defaultPropsAttr.value ||
|
|
100
|
-
defaultPropsAttr.value.type !== 'JSXExpressionContainer') {
|
|
101
|
-
this.traverse(path);
|
|
102
|
-
return;
|
|
103
|
-
}
|
|
104
|
-
const { expression } = defaultPropsAttr.value;
|
|
105
|
-
if (expression.type === 'JSXEmptyExpression') {
|
|
106
|
-
this.traverse(path);
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
if ((0, can_update_sequence_props_1.isStaticValue)(expression, {
|
|
110
|
-
allowSpecialValues: true,
|
|
111
|
-
})) {
|
|
112
|
-
const value = (0, can_update_sequence_props_1.extractStaticValue)(expression, {
|
|
113
|
-
allowSpecialValues: true,
|
|
114
|
-
});
|
|
115
|
-
if (value !== null &&
|
|
116
|
-
typeof value === 'object' &&
|
|
117
|
-
!Array.isArray(value)) {
|
|
118
|
-
result = value;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
this.traverse(path);
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
return result;
|
|
125
|
-
};
|
|
126
|
-
const computeCanUpdateDefaultPropsFromContent = (content, compositionId) => {
|
|
127
|
-
try {
|
|
128
|
-
const currentDefaultProps = extractDefaultPropsFromSource(content, compositionId);
|
|
129
|
-
if (currentDefaultProps === null) {
|
|
130
|
-
throw new Error(`Could not find or extract defaultProps for composition "${compositionId}"`);
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
canUpdate: true,
|
|
134
|
-
currentDefaultProps,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
catch (err) {
|
|
138
|
-
return {
|
|
139
|
-
canUpdate: false,
|
|
140
|
-
reason: err.message,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
exports.computeCanUpdateDefaultPropsFromContent = computeCanUpdateDefaultPropsFromContent;
|
|
145
18
|
const computeCanUpdateDefaultProps = async ({ compositionId, remotionRoot, entryPoint, }) => {
|
|
146
19
|
try {
|
|
147
20
|
const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
|
|
@@ -150,7 +23,7 @@ const computeCanUpdateDefaultProps = async ({ compositionId, remotionRoot, entry
|
|
|
150
23
|
}
|
|
151
24
|
(0, exports.checkIfTypeScriptFile)(projectInfo.rootFile);
|
|
152
25
|
const input = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
|
|
153
|
-
const result = (0,
|
|
26
|
+
const result = (0, studio_codemods_1.computeCanUpdateDefaultPropsFromContent)(input, compositionId);
|
|
154
27
|
return {
|
|
155
28
|
result,
|
|
156
29
|
rootFile: projectInfo.rootFile,
|
|
@@ -22,7 +22,7 @@ export declare const getStaticJsxChildrenAttribute: (jsxElement: JSXOpeningEleme
|
|
|
22
22
|
export declare const hasJsxChildrenAttribute: (jsxElement: JSXOpeningElement) => boolean;
|
|
23
23
|
export declare const getStaticJsxTextContent: (jsxElement: JSXElement) => StaticJsxTextContent | null;
|
|
24
24
|
export declare const findNodePathForJsxElement: (ast: File, target: JSXOpeningElement) => SequenceNodePath | null;
|
|
25
|
-
export declare const lineColumnToNodePath: (ast: File, targetLine: number) => SequenceNodePath | null;
|
|
25
|
+
export declare const lineColumnToNodePath: (ast: File, targetLine: number, targetColumn?: number | undefined, fileContents?: string | undefined) => SequenceNodePath | null;
|
|
26
26
|
export declare const computeSequencePropsStatusFromContent: ({ fileContents, nodePath, componentIdentity, keys, assetKeys, effects, videoConfigValues, }: {
|
|
27
27
|
fileContents: string;
|
|
28
28
|
nodePath: SequenceNodePath;
|
|
@@ -42,9 +42,10 @@ export declare const computeSequencePropsStatus: ({ fileName, nodePath, componen
|
|
|
42
42
|
remotionRoot: string;
|
|
43
43
|
videoConfigValues: VideoConfigValues | null;
|
|
44
44
|
}) => CanUpdateSequencePropsResponseTrue;
|
|
45
|
-
export declare const
|
|
45
|
+
export declare const computeSequencePropsStatusFromFilenameByLocation: ({ fileName, line, column, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, videoConfigValues, }: {
|
|
46
46
|
fileName: string;
|
|
47
47
|
line: number;
|
|
48
|
+
column: number;
|
|
48
49
|
componentIdentity: string | null;
|
|
49
50
|
keys: string[];
|
|
50
51
|
assetKeys?: string[] | undefined;
|
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.computeSequencePropsStatusFromFilenameByLocation = exports.computeSequencePropsStatus = exports.computeSequencePropsStatusFromContent = exports.lineColumnToNodePath = exports.findNodePathForJsxElement = exports.getStaticJsxTextContent = exports.hasJsxChildrenAttribute = exports.getStaticJsxChildrenAttribute = exports.findJsxElementNodeAtNodePath = exports.findJsxElementAtNodePath = exports.findJsxElementPathAtNodePath = exports.getComputedStatus = exports.extractStaticValue = exports.isStaticValue = void 0;
|
|
37
37
|
const node_fs_1 = require("node:fs");
|
|
38
38
|
const renderer_1 = require("@remotion/renderer");
|
|
39
39
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
@@ -642,19 +642,51 @@ const findNodePathForJsxElement = (ast, target) => {
|
|
|
642
642
|
return foundPath;
|
|
643
643
|
};
|
|
644
644
|
exports.findNodePathForJsxElement = findNodePathForJsxElement;
|
|
645
|
-
const
|
|
646
|
-
|
|
645
|
+
const RECAST_TAB_WIDTH = 4;
|
|
646
|
+
const sourceColumnToRecastColumn = ({ fileContents, line, column, }) => {
|
|
647
|
+
const sourceLine = fileContents.split('\n')[line - 1];
|
|
648
|
+
if (sourceLine === undefined) {
|
|
649
|
+
return column;
|
|
650
|
+
}
|
|
651
|
+
let recastColumn = 0;
|
|
652
|
+
for (let index = 0; index < column; index++) {
|
|
653
|
+
if (sourceLine[index] === '\t') {
|
|
654
|
+
recastColumn += RECAST_TAB_WIDTH - (recastColumn % RECAST_TAB_WIDTH);
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
recastColumn++;
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
return recastColumn;
|
|
661
|
+
};
|
|
662
|
+
const lineColumnToNodePath = (ast, targetLine, targetColumn, fileContents) => {
|
|
663
|
+
var _a;
|
|
664
|
+
const lineMatches = [];
|
|
665
|
+
const exactMatches = [];
|
|
666
|
+
const recastTargetColumn = targetColumn === undefined || fileContents === undefined
|
|
667
|
+
? targetColumn
|
|
668
|
+
: sourceColumnToRecastColumn({
|
|
669
|
+
fileContents,
|
|
670
|
+
line: targetLine,
|
|
671
|
+
column: targetColumn,
|
|
672
|
+
});
|
|
647
673
|
recast.types.visit(ast, {
|
|
648
674
|
visitJSXOpeningElement(p) {
|
|
649
675
|
const { node } = p;
|
|
650
676
|
if (node.loc && node.loc.start.line === targetLine) {
|
|
651
|
-
|
|
652
|
-
|
|
677
|
+
const nodePath = getNodePathForRecastPath(p, ast);
|
|
678
|
+
lineMatches.push(nodePath);
|
|
679
|
+
if (node.loc.start.column === recastTargetColumn) {
|
|
680
|
+
exactMatches.push(nodePath);
|
|
681
|
+
}
|
|
653
682
|
}
|
|
654
683
|
return this.traverse(p);
|
|
655
684
|
},
|
|
656
685
|
});
|
|
657
|
-
|
|
686
|
+
if (exactMatches.length === 1) {
|
|
687
|
+
return exactMatches[0];
|
|
688
|
+
}
|
|
689
|
+
return (_a = lineMatches.at(-1)) !== null && _a !== void 0 ? _a : null;
|
|
658
690
|
};
|
|
659
691
|
exports.lineColumnToNodePath = lineColumnToNodePath;
|
|
660
692
|
const PIXEL_VALUE_REGEX = /^-?\d+(\.\d+)?px$/;
|
|
@@ -944,7 +976,7 @@ const computeSequencePropsStatus = ({ fileName, nodePath, componentIdentity, key
|
|
|
944
976
|
});
|
|
945
977
|
};
|
|
946
978
|
exports.computeSequencePropsStatus = computeSequencePropsStatus;
|
|
947
|
-
const
|
|
979
|
+
const computeSequencePropsStatusFromFilenameByLocation = ({ fileName, line, column, componentIdentity, keys, assetKeys = [], effects, remotionRoot, logLevel, videoConfigValues, }) => {
|
|
948
980
|
try {
|
|
949
981
|
const { absolutePath } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
|
|
950
982
|
remotionRoot,
|
|
@@ -953,7 +985,7 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
|
|
|
953
985
|
});
|
|
954
986
|
const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
|
|
955
987
|
const ast = (0, parse_ast_1.parseAst)(fileContents);
|
|
956
|
-
const resolvedNodePath = (0, exports.lineColumnToNodePath)(ast, line);
|
|
988
|
+
const resolvedNodePath = (0, exports.lineColumnToNodePath)(ast, line, column, fileContents);
|
|
957
989
|
if (!resolvedNodePath) {
|
|
958
990
|
return {
|
|
959
991
|
status: {
|
|
@@ -985,6 +1017,16 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
|
|
|
985
1017
|
};
|
|
986
1018
|
}
|
|
987
1019
|
catch (err) {
|
|
1020
|
+
if (err instanceof jsx_component_identity_1.JsxElementIdentityMismatchError ||
|
|
1021
|
+
err instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError) {
|
|
1022
|
+
return {
|
|
1023
|
+
status: {
|
|
1024
|
+
canUpdate: false,
|
|
1025
|
+
reason: 'not-found',
|
|
1026
|
+
},
|
|
1027
|
+
success: false,
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
988
1030
|
renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, err);
|
|
989
1031
|
return {
|
|
990
1032
|
status: {
|
|
@@ -995,4 +1037,4 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
|
|
|
995
1037
|
};
|
|
996
1038
|
}
|
|
997
1039
|
};
|
|
998
|
-
exports.
|
|
1040
|
+
exports.computeSequencePropsStatusFromFilenameByLocation = computeSequencePropsStatusFromFilenameByLocation;
|
|
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.insertElementHandler = void 0;
|
|
7
7
|
const node_fs_1 = require("node:fs");
|
|
8
8
|
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const drag_and_drop_1 = require("@remotion/drag-and-drop");
|
|
10
9
|
const renderer_1 = require("@remotion/renderer");
|
|
10
|
+
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
11
11
|
const file_watcher_1 = require("../../file-watcher");
|
|
12
12
|
const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
|
|
13
13
|
const format_log_file_location_1 = require("../format-log-file-location");
|
|
@@ -56,7 +56,7 @@ const validateDimensions = (dimensions) => {
|
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
const validateElement = (element) => {
|
|
59
|
-
if (
|
|
59
|
+
if (studio_protocol_1.StudioProtocolInternals.makeElementFileNameFromSlug(element.slug) === null) {
|
|
60
60
|
throw new Error('Element slug must produce a safe lowercase .tsx file name');
|
|
61
61
|
}
|
|
62
62
|
if (typeof element.sourceCode !== 'string' ||
|
|
@@ -64,7 +64,7 @@ const validateElement = (element) => {
|
|
|
64
64
|
element.sourceCode.length > 200000) {
|
|
65
65
|
throw new Error('Unsupported Element source code');
|
|
66
66
|
}
|
|
67
|
-
if (
|
|
67
|
+
if (studio_protocol_1.StudioProtocolInternals.getElementComponentNameFromSourceCode(element.sourceCode) === null) {
|
|
68
68
|
throw new Error('Element source must export exactly one named component');
|
|
69
69
|
}
|
|
70
70
|
validateDimensions(element.dimensions);
|
|
@@ -77,7 +77,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
77
77
|
(!Number.isInteger(from) || !Number.isFinite(from) || from < 0)) {
|
|
78
78
|
throw new Error('from must be a non-negative integer');
|
|
79
79
|
}
|
|
80
|
-
const componentName =
|
|
80
|
+
const componentName = studio_protocol_1.StudioProtocolInternals.getElementComponentNameFromSourceCode(element.sourceCode);
|
|
81
81
|
if (componentName === null) {
|
|
82
82
|
throw new Error('Element source must export exactly one named component');
|
|
83
83
|
}
|
|
@@ -90,7 +90,7 @@ const insertElementHandler = ({ input: { compositionFile, compositionId, element
|
|
|
90
90
|
if (!location.canAddSequence) {
|
|
91
91
|
throw new Error('Cannot insert Element into this composition component');
|
|
92
92
|
}
|
|
93
|
-
const derivedElementFileName =
|
|
93
|
+
const derivedElementFileName = studio_protocol_1.StudioProtocolInternals.makeElementFileNameFromSlug(element.slug);
|
|
94
94
|
if (derivedElementFileName === null) {
|
|
95
95
|
throw new Error('Element slug must produce a safe lowercase .tsx file name');
|
|
96
96
|
}
|
|
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.insertJsxElementHandler = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
const drag_and_drop_1 = require("@remotion/drag-and-drop");
|
|
9
8
|
const renderer_1 = require("@remotion/renderer");
|
|
9
|
+
const studio_protocol_1 = require("@remotion/studio-protocol");
|
|
10
10
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
11
11
|
const file_watcher_1 = require("../../file-watcher");
|
|
12
12
|
const resolve_composition_component_1 = require("../../helpers/resolve-composition-component");
|
|
@@ -79,16 +79,16 @@ const validateElement = (element, remotionRoot) => {
|
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
81
|
if (element.type === 'component') {
|
|
82
|
-
if (!
|
|
82
|
+
if (!studio_protocol_1.StudioProtocolInternals.isComponentIdentifier(element.componentName)) {
|
|
83
83
|
throw new Error('Unsupported component name');
|
|
84
84
|
}
|
|
85
|
-
if (!
|
|
85
|
+
if (!studio_protocol_1.StudioProtocolInternals.isComponentIdentifier(element.importName)) {
|
|
86
86
|
throw new Error('Unsupported component import name');
|
|
87
87
|
}
|
|
88
|
-
if (!
|
|
88
|
+
if (!studio_protocol_1.StudioProtocolInternals.isComponentImportPath(element.importPath)) {
|
|
89
89
|
throw new Error('Unsupported component import path');
|
|
90
90
|
}
|
|
91
|
-
if (!
|
|
91
|
+
if (!studio_protocol_1.StudioProtocolInternals.areComponentProps(element.props)) {
|
|
92
92
|
throw new Error('Unsupported component props');
|
|
93
93
|
}
|
|
94
94
|
return;
|
|
@@ -85,9 +85,10 @@ const getSequencePropsStatus = ({ fileName, line, column, preferredNodePath, com
|
|
|
85
85
|
};
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
|
-
const status = (0, can_update_sequence_props_1.
|
|
88
|
+
const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromFilenameByLocation)({
|
|
89
89
|
fileName,
|
|
90
90
|
line,
|
|
91
|
+
column,
|
|
91
92
|
componentIdentity,
|
|
92
93
|
keys,
|
|
93
94
|
assetKeys,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { GitSource } from '@remotion/studio-shared';
|
|
3
|
+
import type { LiveEventsServer } from '../live-events';
|
|
4
|
+
export declare const ELEMENT_INSTALL_TARGET_RESPONSE_WAIT = 250;
|
|
5
|
+
export declare const handleStudioProtocolDiscovery: ({ gitSource, liveEventsServer, remotionRoot, request, response, }: {
|
|
6
|
+
readonly gitSource: GitSource | null;
|
|
7
|
+
readonly liveEventsServer: LiveEventsServer;
|
|
8
|
+
readonly remotionRoot: string;
|
|
9
|
+
readonly request: IncomingMessage;
|
|
10
|
+
readonly response: ServerResponse<IncomingMessage>;
|
|
11
|
+
}) => Promise<void>;
|