@remotion/studio-server 4.0.501 → 4.0.503

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.
Files changed (70) hide show
  1. package/dist/codemods/update-inline-caption-patches.d.ts +1 -11
  2. package/dist/codemods/update-inline-caption-patches.js +2 -183
  3. package/dist/codemods/update-sequence-props/update-sequence-props.d.ts +2 -35
  4. package/dist/codemods/update-sequence-props/update-sequence-props.js +7 -720
  5. package/dist/detect-outdated-remotion-skills.d.ts +25 -0
  6. package/dist/detect-outdated-remotion-skills.js +73 -0
  7. package/dist/helpers/custom-editor.d.ts +37 -0
  8. package/dist/helpers/custom-editor.js +167 -0
  9. package/dist/helpers/editor-registry.d.ts +18 -0
  10. package/dist/helpers/editor-registry.js +500 -0
  11. package/dist/helpers/open-in-editor.d.ts +3 -4
  12. package/dist/helpers/open-in-editor.js +5 -75
  13. package/dist/helpers/resolve-composition-component.js +18 -6
  14. package/dist/helpers/resolve-editor.d.ts +27 -0
  15. package/dist/helpers/resolve-editor.js +90 -0
  16. package/dist/helpers/resolve-file-inside-project.d.ts +2 -0
  17. package/dist/helpers/resolve-file-inside-project.js +5 -2
  18. package/dist/index.d.ts +17 -1
  19. package/dist/index.js +9 -1
  20. package/dist/preview-server/api-routes.js +6 -1
  21. package/dist/preview-server/api-types.d.ts +2 -1
  22. package/dist/preview-server/element-install-state.d.ts +19 -0
  23. package/dist/preview-server/element-install-state.js +46 -1
  24. package/dist/preview-server/handler.d.ts +3 -1
  25. package/dist/preview-server/handler.js +3 -2
  26. package/dist/preview-server/parse-body.d.ts +6 -1
  27. package/dist/preview-server/parse-body.js +60 -9
  28. package/dist/preview-server/routes/can-update-default-props.d.ts +1 -1
  29. package/dist/preview-server/routes/can-update-default-props.js +5 -132
  30. package/dist/preview-server/routes/can-update-sequence-props.d.ts +3 -2
  31. package/dist/preview-server/routes/can-update-sequence-props.js +52 -9
  32. package/dist/preview-server/routes/default-editor.d.ts +8 -0
  33. package/dist/preview-server/routes/default-editor.js +131 -0
  34. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +3 -0
  35. package/dist/preview-server/routes/delete-effect-keyframe.js +89 -0
  36. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +3 -0
  37. package/dist/preview-server/routes/delete-sequence-keyframe.js +82 -0
  38. package/dist/preview-server/routes/element-install-plan.d.ts +32 -0
  39. package/dist/preview-server/routes/element-install-plan.js +122 -0
  40. package/dist/preview-server/routes/insert-element.d.ts +1 -1
  41. package/dist/preview-server/routes/insert-element.js +68 -107
  42. package/dist/preview-server/routes/insert-jsx-element.js +5 -5
  43. package/dist/preview-server/routes/open-in-editor.d.ts +5 -1
  44. package/dist/preview-server/routes/open-in-editor.js +42 -12
  45. package/dist/preview-server/routes/prepare-element-install.d.ts +3 -0
  46. package/dist/preview-server/routes/prepare-element-install.js +25 -0
  47. package/dist/preview-server/routes/safe-element-install-path.d.ts +9 -0
  48. package/dist/preview-server/routes/safe-element-install-path.js +58 -0
  49. package/dist/preview-server/routes/save-props-mutex.d.ts +1 -0
  50. package/dist/preview-server/routes/save-props-mutex.js +11 -0
  51. package/dist/preview-server/sequence-props-watchers.js +2 -1
  52. package/dist/preview-server/start-server.d.ts +2 -0
  53. package/dist/preview-server/start-server.js +1 -0
  54. package/dist/preview-server/studio-protocol/handle-discovery.d.ts +11 -0
  55. package/dist/preview-server/studio-protocol/handle-discovery.js +106 -0
  56. package/dist/preview-server/studio-protocol/handle-install.d.ts +10 -0
  57. package/dist/preview-server/studio-protocol/handle-install.js +147 -0
  58. package/dist/preview-server/studio-protocol/origin-policy.d.ts +11 -0
  59. package/dist/preview-server/studio-protocol/origin-policy.js +43 -0
  60. package/dist/preview-server/studio-protocol/protocol-response.d.ts +7 -0
  61. package/dist/preview-server/studio-protocol/protocol-response.js +13 -0
  62. package/dist/preview-server/update-available.d.ts +6 -0
  63. package/dist/preview-server/update-available.js +30 -4
  64. package/dist/remotion-skill-names.d.ts +2 -0
  65. package/dist/remotion-skill-names.js +16 -0
  66. package/dist/routes.d.ts +3 -1
  67. package/dist/routes.js +19 -157
  68. package/dist/start-studio.d.ts +3 -1
  69. package/dist/start-studio.js +2 -1
  70. package/package.json +9 -8
@@ -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.computeCanUpdateDefaultPropsFromContent = exports.checkIfTypeScriptFile = void 0;
3
+ exports.computeCanUpdateDefaultProps = exports.checkIfTypeScriptFile = exports.computeCanUpdateDefaultPropsFromContent = void 0;
37
4
  const node_fs_1 = require("node:fs");
38
- const recast = __importStar(require("recast"));
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 can_update_sequence_props_1 = require("./can-update-sequence-props");
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, exports.computeCanUpdateDefaultPropsFromContent)(input, compositionId);
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 computeSequencePropsStatusFromFilenameByLine: ({ fileName, line, componentIdentity, keys, assetKeys, effects, remotionRoot, logLevel, videoConfigValues, }: {
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.computeSequencePropsStatusFromFilenameByLine = 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;
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 lineColumnToNodePath = (ast, targetLine) => {
646
- let foundPath = null;
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
- foundPath = getNodePathForRecastPath(p, ast);
652
- return false;
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
- return foundPath;
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 computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componentIdentity, keys, assetKeys = [], effects, remotionRoot, logLevel, videoConfigValues, }) => {
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,17 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
985
1017
  };
986
1018
  }
987
1019
  catch (err) {
1020
+ if (err instanceof resolve_file_inside_project_1.FileOutsideProjectError ||
1021
+ err instanceof jsx_component_identity_1.JsxElementIdentityMismatchError ||
1022
+ err instanceof jsx_element_not_found_at_location_error_1.JsxElementNotFoundAtLocationError) {
1023
+ return {
1024
+ status: {
1025
+ canUpdate: false,
1026
+ reason: 'not-found',
1027
+ },
1028
+ success: false,
1029
+ };
1030
+ }
988
1031
  renderer_1.RenderInternals.Log.error({ indent: false, logLevel }, err);
989
1032
  return {
990
1033
  status: {
@@ -995,4 +1038,4 @@ const computeSequencePropsStatusFromFilenameByLine = ({ fileName, line, componen
995
1038
  };
996
1039
  }
997
1040
  };
998
- exports.computeSequencePropsStatusFromFilenameByLine = computeSequencePropsStatusFromFilenameByLine;
1041
+ exports.computeSequencePropsStatusFromFilenameByLocation = computeSequencePropsStatusFromFilenameByLocation;
@@ -0,0 +1,8 @@
1
+ import type { GetDefaultEditorInfoRequest, GetDefaultEditorInfoResponse, UpdateDefaultEditorRequest, UpdateDefaultEditorResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const updateDefaultEditorInConfig: ({ configContents, defaultEditor, }: {
4
+ configContents: string;
5
+ defaultEditor: "cursor" | "sublime-text" | "vscode" | "vscodium" | "webstorm" | "windsurf" | "zed" | null;
6
+ }) => string;
7
+ export declare const getDefaultEditorInfoHandler: ApiHandler<GetDefaultEditorInfoRequest, GetDefaultEditorInfoResponse>;
8
+ export declare const updateDefaultEditorHandler: ApiHandler<UpdateDefaultEditorRequest, UpdateDefaultEditorResponse>;
@@ -0,0 +1,131 @@
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.updateDefaultEditorHandler = exports.getDefaultEditorInfoHandler = exports.updateDefaultEditorInConfig = void 0;
37
+ const node_fs_1 = require("node:fs");
38
+ const renderer_1 = require("@remotion/renderer");
39
+ const recast = __importStar(require("recast"));
40
+ const parse_ast_1 = require("../../codemods/parse-ast");
41
+ const file_watcher_1 = require("../../file-watcher");
42
+ const editor_registry_1 = require("../../helpers/editor-registry");
43
+ const updateDefaultEditorInConfig = ({ configContents, defaultEditor, }) => {
44
+ const ast = (0, parse_ast_1.parseAst)(configContents);
45
+ recast.types.visit(ast.program, {
46
+ visitExpressionStatement(path) {
47
+ const { expression } = path.node;
48
+ if (expression.type === 'CallExpression' &&
49
+ expression.callee.type === 'MemberExpression' &&
50
+ !expression.callee.computed &&
51
+ expression.callee.object.type === 'Identifier' &&
52
+ expression.callee.object.name === 'Config' &&
53
+ expression.callee.property.type === 'Identifier' &&
54
+ expression.callee.property.name === 'setDefaultEditor') {
55
+ path.prune();
56
+ return false;
57
+ }
58
+ this.traverse(path);
59
+ },
60
+ });
61
+ const configWithoutExistingCalls = recast.print(ast, {
62
+ lineTerminator: '\n',
63
+ }).code;
64
+ if (defaultEditor === null) {
65
+ return configWithoutExistingCalls;
66
+ }
67
+ const separator = configWithoutExistingCalls.endsWith('\n') ? '' : '\n';
68
+ return `${configWithoutExistingCalls}${separator}Config.setDefaultEditor('${defaultEditor}');\n`;
69
+ };
70
+ exports.updateDefaultEditorInConfig = updateDefaultEditorInConfig;
71
+ const getDefaultEditorInfoHandler = async ({ getDefaultEditor }) => {
72
+ const installedEditors = await (0, editor_registry_1.getAvailableEditors)();
73
+ const configuredEditor = getDefaultEditor();
74
+ const customEditor = configuredEditor && typeof configuredEditor === 'object'
75
+ ? configuredEditor
76
+ : null;
77
+ return {
78
+ defaultEditor: typeof configuredEditor === 'object' ? 'custom' : configuredEditor,
79
+ installedEditors: [
80
+ ...installedEditors.map(({ id, name }) => ({ id, name })),
81
+ ...(customEditor
82
+ ? [{ id: 'custom', name: customEditor.name }]
83
+ : []),
84
+ ],
85
+ };
86
+ };
87
+ exports.getDefaultEditorInfoHandler = getDefaultEditorInfoHandler;
88
+ const updateDefaultEditorHandler = async ({ input, configFile, getDefaultEditor }) => {
89
+ if (configFile === null || configFile === undefined) {
90
+ return {
91
+ success: false,
92
+ reason: 'No Remotion config file was loaded.',
93
+ };
94
+ }
95
+ if (input.defaultEditor === 'custom') {
96
+ const configuredEditor = getDefaultEditor();
97
+ if (!configuredEditor || typeof configuredEditor !== 'object') {
98
+ return {
99
+ success: false,
100
+ reason: 'No custom editor is configured.',
101
+ };
102
+ }
103
+ // The browser only knows the opaque "custom" ID. Keeping the existing
104
+ // config call untouched avoids exposing or rewriting its executable and
105
+ // arguments, which may have come from environment variables.
106
+ return { success: true };
107
+ }
108
+ if (input.defaultEditor !== null &&
109
+ !renderer_1.defaultEditorIds.includes(input.defaultEditor)) {
110
+ return {
111
+ success: false,
112
+ reason: `Unknown editor: ${input.defaultEditor}`,
113
+ };
114
+ }
115
+ if (input.defaultEditor !== null) {
116
+ const installedEditors = await (0, editor_registry_1.getAvailableEditors)();
117
+ if (!installedEditors.some(({ id }) => id === input.defaultEditor)) {
118
+ return {
119
+ success: false,
120
+ reason: 'The selected editor is not installed.',
121
+ };
122
+ }
123
+ }
124
+ const configContents = (0, node_fs_1.readFileSync)(configFile, 'utf8');
125
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(configFile, (0, exports.updateDefaultEditorInConfig)({
126
+ configContents,
127
+ defaultEditor: input.defaultEditor,
128
+ }), undefined);
129
+ return { success: true };
130
+ };
131
+ exports.updateDefaultEditorHandler = updateDefaultEditorHandler;
@@ -0,0 +1,3 @@
1
+ import type { DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const deleteEffectKeyframeHandler: ApiHandler<DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse>;
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteEffectKeyframeHandler = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const renderer_1 = require("@remotion/renderer");
6
+ const studio_shared_1 = require("@remotion/studio-shared");
7
+ const parse_ast_1 = require("../../codemods/parse-ast");
8
+ const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
9
+ const file_watcher_1 = require("../../file-watcher");
10
+ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
11
+ const undo_stack_1 = require("../undo-stack");
12
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
13
+ const can_update_effect_props_1 = require("./can-update-effect-props");
14
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
15
+ const log_effect_update_1 = require("./log-updates/log-effect-update");
16
+ const save_props_mutex_1 = require("./save-props-mutex");
17
+ const deleteEffectKeyframeHandler = ({ input: { fileName, sequenceNodePath, effectIndex, key, frame, schema, clientId, }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
18
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-effect-keyframe] Received request for fileName="${fileName}" effectIndex=${effectIndex} key="${key}" frame=${frame}`);
19
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
20
+ remotionRoot,
21
+ fileName,
22
+ action: 'modify',
23
+ });
24
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
25
+ const { output, oldValueStrings, newValueStrings, formatted, logLine, effectCallee, } = await (0, update_keyframes_1.updateEffectKeyframes)({
26
+ input: fileContents,
27
+ sequenceNodePath: sequenceNodePath.nodePath,
28
+ effectIndex,
29
+ updates: [
30
+ {
31
+ key,
32
+ operation: {
33
+ type: 'remove',
34
+ frame,
35
+ },
36
+ },
37
+ ],
38
+ });
39
+ const oldValueString = oldValueStrings[0];
40
+ const newValueString = newValueStrings[0];
41
+ const undoPropChange = `${key} keyframe restored at frame ${frame}`;
42
+ const redoPropChange = `${key} keyframe deleted at frame ${frame}`;
43
+ (0, undo_stack_1.pushToUndoStack)({
44
+ filePath: absolutePath,
45
+ oldContents: fileContents,
46
+ newContents: null,
47
+ logLevel,
48
+ remotionRoot,
49
+ logLine,
50
+ description: {
51
+ undoMessage: `↩️ ${undoPropChange}`,
52
+ redoMessage: `↪️ ${redoPropChange}`,
53
+ },
54
+ entryType: 'effect-props',
55
+ suppressHmrOnFileRestore: true,
56
+ });
57
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
58
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
59
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
60
+ (0, log_effect_update_1.logEffectUpdate)({
61
+ fileRelativeToRoot,
62
+ line: logLine,
63
+ effectName: effectCallee,
64
+ propKey: key,
65
+ oldValueString,
66
+ newValueString,
67
+ defaultValueString: null,
68
+ formatted,
69
+ logLevel,
70
+ removedProps: [],
71
+ addedProps: [],
72
+ });
73
+ (0, undo_stack_1.printUndoHint)(logLevel);
74
+ const ast = (0, parse_ast_1.parseAst)((0, node_fs_1.readFileSync)(absolutePath, 'utf-8'));
75
+ const jsx = (0, can_update_sequence_props_1.findJsxElementAtNodePath)(ast, sequenceNodePath.nodePath);
76
+ if (!jsx) {
77
+ return {
78
+ canUpdate: false,
79
+ effectIndex,
80
+ reason: 'not-found',
81
+ };
82
+ }
83
+ return (0, can_update_effect_props_1.computeEffectPropStatus)({
84
+ jsx,
85
+ effectIndex,
86
+ keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
87
+ });
88
+ });
89
+ exports.deleteEffectKeyframeHandler = deleteEffectKeyframeHandler;
@@ -0,0 +1,3 @@
1
+ import type { DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const deleteSequenceKeyframeHandler: ApiHandler<DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deleteSequenceKeyframeHandler = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const renderer_1 = require("@remotion/renderer");
6
+ const studio_shared_1 = require("@remotion/studio-shared");
7
+ const update_keyframes_1 = require("../../codemods/update-keyframes/update-keyframes");
8
+ const file_watcher_1 = require("../../file-watcher");
9
+ const resolve_file_inside_project_1 = require("../../helpers/resolve-file-inside-project");
10
+ const undo_stack_1 = require("../undo-stack");
11
+ const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
12
+ const can_update_sequence_props_1 = require("./can-update-sequence-props");
13
+ const log_update_1 = require("./log-updates/log-update");
14
+ const save_props_mutex_1 = require("./save-props-mutex");
15
+ const deleteSequenceKeyframeHandler = ({ input: { fileName, nodePath, key, frame, schema, clientId }, remotionRoot, logLevel, }) => (0, save_props_mutex_1.withSavePropsLock)(async () => {
16
+ renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[delete-sequence-keyframe] Received request for fileName="${fileName}" key="${key}" frame=${frame}`);
17
+ const { absolutePath, fileRelativeToRoot } = (0, resolve_file_inside_project_1.resolveFileInsideProject)({
18
+ remotionRoot,
19
+ fileName,
20
+ action: 'modify',
21
+ });
22
+ const fileContents = (0, node_fs_1.readFileSync)(absolutePath, 'utf-8');
23
+ const { output, oldValueStrings, newValueStrings, formatted, logLine } = await (0, update_keyframes_1.updateSequenceKeyframes)({
24
+ input: fileContents,
25
+ nodePath: nodePath.nodePath,
26
+ updates: [
27
+ {
28
+ key,
29
+ operation: {
30
+ type: 'remove',
31
+ frame,
32
+ },
33
+ },
34
+ ],
35
+ });
36
+ const oldValueString = oldValueStrings[0];
37
+ const newValueString = newValueStrings[0];
38
+ const undoPropChange = `${key} keyframe restored at frame ${frame}`;
39
+ const redoPropChange = `${key} keyframe deleted at frame ${frame}`;
40
+ (0, undo_stack_1.pushToUndoStack)({
41
+ filePath: absolutePath,
42
+ oldContents: fileContents,
43
+ newContents: null,
44
+ logLevel,
45
+ remotionRoot,
46
+ logLine,
47
+ description: {
48
+ undoMessage: `↩️ ${undoPropChange}`,
49
+ redoMessage: `↪️ ${redoPropChange}`,
50
+ },
51
+ entryType: 'sequence-props',
52
+ suppressHmrOnFileRestore: true,
53
+ });
54
+ (0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
55
+ (0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
56
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output, clientId);
57
+ (0, log_update_1.logUpdate)({
58
+ fileRelativeToRoot,
59
+ line: logLine,
60
+ key,
61
+ oldValueString,
62
+ newValueString,
63
+ defaultValueString: null,
64
+ formatted,
65
+ logLevel,
66
+ removedProps: [],
67
+ addedProps: [],
68
+ });
69
+ (0, undo_stack_1.printUndoHint)(logLevel);
70
+ const status = (0, can_update_sequence_props_1.computeSequencePropsStatusFromContent)({
71
+ fileContents: output,
72
+ keys: (0, studio_shared_1.getAllSchemaKeys)(schema),
73
+ nodePath: nodePath.nodePath,
74
+ effects: [],
75
+ });
76
+ return {
77
+ canUpdate: true,
78
+ props: status.props,
79
+ results: [{ fileName, nodePath, props: status.props }],
80
+ };
81
+ });
82
+ exports.deleteSequenceKeyframeHandler = deleteSequenceKeyframeHandler;
@@ -0,0 +1,32 @@
1
+ import type { ElementInstallExpectedFileState, PrepareElementInstallRequest } from '@remotion/studio-shared';
2
+ export declare const normalizeElementSourceForComparison: (source: string) => string;
3
+ export declare const getElementSourceHash: (source: string) => string;
4
+ export declare const validateElementInstallPosition: (position: import("@remotion/studio-shared").InsertableCompositionElementPosition | null) => void;
5
+ export declare const validateElementForInstallation: (element: {
6
+ dependencies: string[];
7
+ slug: string;
8
+ displayName: string;
9
+ sourceCode: string;
10
+ dimensions: import("@remotion/studio-protocol").ComponentDimensions | null;
11
+ }) => void;
12
+ export declare const makeRelativeElementImportPath: ({ fromFile, toFile, }: {
13
+ fromFile: string;
14
+ toFile: string;
15
+ }) => string;
16
+ export declare const getElementInstallPlan: ({ compositionFile, compositionId, element, remotionRoot, }: PrepareElementInstallRequest & {
17
+ remotionRoot: string;
18
+ }) => Promise<{
19
+ componentName: string;
20
+ elementFileExists: boolean;
21
+ elementFileName: string;
22
+ existingElementSource: string | null;
23
+ expectedFileState: ElementInstallExpectedFileState;
24
+ filePath: string;
25
+ importPath: string;
26
+ location: import("../../helpers/resolve-composition-component").ResolvedCompositionComponentWithFile;
27
+ safePaths: {
28
+ compositionFileName: string;
29
+ elementFileName: string;
30
+ remotionRoot: string;
31
+ };
32
+ }>;