@remotion/studio-server 4.0.506 → 4.0.507

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 (44) hide show
  1. package/dist/codemods/effect-param-expression.js +2 -0
  2. package/dist/codemods/update-keyframes/update-keyframes.js +2 -0
  3. package/dist/helpers/coding-agent-registry.d.ts +35 -0
  4. package/dist/helpers/coding-agent-registry.js +447 -22
  5. package/dist/helpers/editor-registry.d.ts +1 -0
  6. package/dist/helpers/editor-registry.js +31 -3
  7. package/dist/helpers/open-in-editor.js +5 -5
  8. package/dist/helpers/parse-keyframe-easing-expression.js +3 -0
  9. package/dist/helpers/resolve-editor.d.ts +2 -0
  10. package/dist/helpers/resolve-editor.js +4 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/preview-server/api-routes.js +5 -4
  13. package/dist/preview-server/handler.d.ts +1 -1
  14. package/dist/preview-server/routes/add-render.js +2 -0
  15. package/dist/preview-server/routes/can-update-sequence-props.js +28 -5
  16. package/dist/preview-server/routes/copy-render-output-to-asset.d.ts +3 -0
  17. package/dist/preview-server/routes/copy-render-output-to-asset.js +58 -0
  18. package/dist/preview-server/routes/default-coding-agent.d.ts +2 -6
  19. package/dist/preview-server/routes/default-coding-agent.js +17 -88
  20. package/dist/preview-server/routes/default-editor.d.ts +1 -6
  21. package/dist/preview-server/routes/default-editor.js +13 -113
  22. package/dist/preview-server/routes/open-in-editor.js +1 -1
  23. package/dist/preview-server/routes/update-config.d.ts +7 -0
  24. package/dist/preview-server/routes/update-config.js +188 -0
  25. package/dist/preview-server/start-server.d.ts +1 -1
  26. package/dist/preview-server/studio-protocol/handle-discovery.js +3 -4
  27. package/dist/preview-server/studio-protocol/handle-install.js +1 -1
  28. package/dist/preview-server/studio-protocol/handle-license-key.js +2 -2
  29. package/dist/preview-server/studio-protocol/origin-policy.d.ts +2 -5
  30. package/dist/preview-server/studio-protocol/origin-policy.js +6 -30
  31. package/dist/routes.d.ts +1 -1
  32. package/dist/routes.js +0 -1
  33. package/dist/start-studio.d.ts +1 -1
  34. package/package.json +8 -8
  35. package/web/coding-agent-icons/claude-code.png +0 -0
  36. package/web/coding-agent-icons/codex.png +0 -0
  37. package/web/coding-agent-icons/copilot.png +0 -0
  38. package/web/coding-agent-icons/cursor.png +0 -0
  39. package/dist/preview-server/routes/delete-effect-keyframe.d.ts +0 -3
  40. package/dist/preview-server/routes/delete-effect-keyframe.js +0 -89
  41. package/dist/preview-server/routes/delete-sequence-keyframe.d.ts +0 -3
  42. package/dist/preview-server/routes/delete-sequence-keyframe.js +0 -82
  43. package/dist/preview-server/routes/save-props-mutex.d.ts +0 -1
  44. package/dist/preview-server/routes/save-props-mutex.js +0 -11
@@ -1,73 +1,7 @@
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.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");
3
+ exports.getDefaultEditorInfoHandler = void 0;
42
4
  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
5
  const getDefaultEditorInfoHandler = async ({ getDefaultEditor }) => {
72
6
  const installedEditors = await (0, editor_registry_1.getAvailableEditors)();
73
7
  const configuredEditor = getDefaultEditor();
@@ -77,55 +11,21 @@ const getDefaultEditorInfoHandler = async ({ getDefaultEditor }) => {
77
11
  return {
78
12
  defaultEditor: typeof configuredEditor === 'object' ? 'custom' : configuredEditor,
79
13
  installedEditors: [
80
- ...installedEditors.map(({ id, name }) => ({ id, name })),
14
+ ...installedEditors.map(({ id, name, nameWithType }) => ({
15
+ id,
16
+ name,
17
+ nameWithType,
18
+ })),
81
19
  ...(customEditor
82
- ? [{ id: 'custom', name: customEditor.name }]
20
+ ? [
21
+ {
22
+ id: 'custom',
23
+ name: customEditor.name,
24
+ nameWithType: customEditor.name,
25
+ },
26
+ ]
83
27
  : []),
84
28
  ],
85
29
  };
86
30
  };
87
31
  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;
@@ -16,7 +16,7 @@ const getEditorName = async ({ getDefaultEditor, logLevel, }) => {
16
16
  logLevel,
17
17
  preferredEditor: null,
18
18
  });
19
- return (_a = editor === null || editor === void 0 ? void 0 : editor.name) !== null && _a !== void 0 ? _a : null;
19
+ return (_a = editor === null || editor === void 0 ? void 0 : editor.nameWithType) !== null && _a !== void 0 ? _a : null;
20
20
  };
21
21
  exports.getEditorName = getEditorName;
22
22
  const openInEditorHandler = async ({ input, remotionRoot, logLevel, getDefaultEditor }) => {
@@ -0,0 +1,7 @@
1
+ import { type ConfigUpdate, type UpdateConfigRequest, type UpdateConfigResponse } from '@remotion/studio-shared';
2
+ import type { ApiHandler } from '../api-types';
3
+ export declare const updateConfigFile: ({ configContents, updates, }: {
4
+ readonly configContents: string;
5
+ readonly updates: ConfigUpdate[];
6
+ }) => string;
7
+ export declare const updateConfigHandler: ApiHandler<UpdateConfigRequest, UpdateConfigResponse>;
@@ -0,0 +1,188 @@
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.updateConfigHandler = exports.updateConfigFile = void 0;
37
+ const node_fs_1 = require("node:fs");
38
+ const renderer_1 = require("@remotion/renderer");
39
+ const studio_shared_1 = require("@remotion/studio-shared");
40
+ const recast = __importStar(require("recast"));
41
+ const parse_ast_1 = require("../../codemods/parse-ast");
42
+ const file_watcher_1 = require("../../file-watcher");
43
+ const editor_registry_1 = require("../../helpers/editor-registry");
44
+ const validSetterName = /^set[A-Z][A-Za-z0-9]*$/;
45
+ const isConfigValue = (value) => {
46
+ if (value === null ||
47
+ typeof value === 'string' ||
48
+ typeof value === 'boolean') {
49
+ return true;
50
+ }
51
+ if (typeof value === 'number') {
52
+ return Number.isFinite(value);
53
+ }
54
+ if (Array.isArray(value)) {
55
+ return value.every(isConfigValue);
56
+ }
57
+ if (typeof value === 'object') {
58
+ if (Object.getPrototypeOf(value) !== Object.prototype &&
59
+ Object.getPrototypeOf(value) !== null) {
60
+ return false;
61
+ }
62
+ return Object.values(value).every(isConfigValue);
63
+ }
64
+ return false;
65
+ };
66
+ const validateUpdates = (updates) => {
67
+ if (!Array.isArray(updates) || updates.length === 0) {
68
+ return 'At least one config update is required.';
69
+ }
70
+ const setters = new Set();
71
+ for (const update of updates) {
72
+ if (typeof update !== 'object' || update === null) {
73
+ return 'Each config update must be an object.';
74
+ }
75
+ const { setter, type } = update;
76
+ if (typeof setter !== 'string' ||
77
+ !validSetterName.test(setter) ||
78
+ !(setter in studio_shared_1.configMethodLifecycles)) {
79
+ return `Invalid config setter: ${JSON.stringify(setter)}.`;
80
+ }
81
+ if (setters.has(setter)) {
82
+ return `The config setter ${setter} was specified more than once.`;
83
+ }
84
+ setters.add(setter);
85
+ if (type === 'delete') {
86
+ continue;
87
+ }
88
+ if (type !== 'set' ||
89
+ !('value' in update) ||
90
+ !isConfigValue(update.value)) {
91
+ return `Invalid value for Config.${setter}().`;
92
+ }
93
+ }
94
+ return null;
95
+ };
96
+ const updateConfigFile = ({ configContents, updates, }) => {
97
+ const setters = new Set(updates.map(({ setter }) => setter));
98
+ const ast = (0, parse_ast_1.parseAst)(configContents);
99
+ recast.types.visit(ast.program, {
100
+ visitExpressionStatement(path) {
101
+ const { expression } = path.node;
102
+ if (expression.type === 'CallExpression' &&
103
+ expression.callee.type === 'MemberExpression' &&
104
+ !expression.callee.computed &&
105
+ expression.callee.object.type === 'Identifier' &&
106
+ expression.callee.object.name === 'Config' &&
107
+ expression.callee.property.type === 'Identifier' &&
108
+ setters.has(expression.callee.property.name)) {
109
+ path.prune();
110
+ return false;
111
+ }
112
+ this.traverse(path);
113
+ },
114
+ });
115
+ let updatedConfig = recast.print(ast, { lineTerminator: '\n' }).code;
116
+ for (const update of updates) {
117
+ if (update.type === 'delete') {
118
+ continue;
119
+ }
120
+ const serializedValue = JSON.stringify(update.value)
121
+ .replaceAll('\u2028', '\\u2028')
122
+ .replaceAll('\u2029', '\\u2029');
123
+ const statement = (0, parse_ast_1.parseAst)(`Config.${update.setter}(${serializedValue});`)
124
+ .program.body[0];
125
+ const separator = updatedConfig.endsWith('\n') ? '' : '\n';
126
+ updatedConfig += `${separator}${recast.prettyPrint(statement, {
127
+ lineTerminator: '\n',
128
+ quote: 'single',
129
+ useTabs: true,
130
+ }).code}\n`;
131
+ }
132
+ return updatedConfig;
133
+ };
134
+ exports.updateConfigFile = updateConfigFile;
135
+ const updateConfigHandler = async ({ input, configFile }) => {
136
+ if (configFile === null || configFile === undefined) {
137
+ return {
138
+ success: false,
139
+ reason: 'No Remotion config file was loaded.',
140
+ };
141
+ }
142
+ const validationError = validateUpdates(input.updates);
143
+ if (validationError !== null) {
144
+ return { success: false, reason: validationError };
145
+ }
146
+ for (const update of input.updates) {
147
+ if (update.type === 'delete') {
148
+ continue;
149
+ }
150
+ if (update.setter === 'setDefaultCodingAgent' &&
151
+ (typeof update.value !== 'string' ||
152
+ !renderer_1.defaultCodingAgentIds.includes(update.value))) {
153
+ return {
154
+ success: false,
155
+ reason: `Unknown coding agent: ${JSON.stringify(update.value)}`,
156
+ };
157
+ }
158
+ if (update.setter === 'setDefaultEditor') {
159
+ if (typeof update.value !== 'string' ||
160
+ !renderer_1.defaultEditorIds.includes(update.value)) {
161
+ return {
162
+ success: false,
163
+ reason: `Unknown editor: ${JSON.stringify(update.value)}`,
164
+ };
165
+ }
166
+ const installedEditors = await (0, editor_registry_1.getAvailableEditors)();
167
+ if (!installedEditors.some(({ id }) => id === update.value)) {
168
+ return {
169
+ success: false,
170
+ reason: 'The selected editor is not installed.',
171
+ };
172
+ }
173
+ }
174
+ if (update.setter === 'setPublicLicenseKey' &&
175
+ (typeof update.value !== 'string' ||
176
+ (update.value !== 'free-license' &&
177
+ !update.value.startsWith('rm_pub_')))) {
178
+ return {
179
+ success: false,
180
+ reason: 'The public license key must start with "rm_pub_" or be "free-license".',
181
+ };
182
+ }
183
+ }
184
+ const configContents = (0, node_fs_1.readFileSync)(configFile, 'utf8');
185
+ (0, file_watcher_1.writeFileAndNotifyFileWatchers)(configFile, (0, exports.updateConfigFile)({ configContents, updates: input.updates }), input.clientId);
186
+ return { success: true };
187
+ };
188
+ exports.updateConfigHandler = updateConfigHandler;
@@ -42,7 +42,7 @@ export declare const startServer: (options: {
42
42
  forceNew: boolean;
43
43
  rspack: boolean;
44
44
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
45
- getDefaultCodingAgent: () => "claude-code" | "codex" | "cursor" | "github-copilot" | null;
45
+ getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
46
46
  getDefaultEditor: () => DefaultEditor | null;
47
47
  configFile: string | null;
48
48
  }) => Promise<StartServerResult>;
@@ -43,7 +43,7 @@ const getProject = ({ gitSource, remotionRoot, }) => (0, studio_shared_1.getProj
43
43
  resolvedRemotionRoot: remotionRoot,
44
44
  });
45
45
  const handleStudioProtocolDiscovery = ({ gitSource, liveEventsServer, remotionRoot, request, response, }) => {
46
- (0, origin_policy_1.setStudioProtocolCorsHeaders)({ licenseKey: false, request, response });
46
+ (0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
47
47
  const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request.headers.origin);
48
48
  if (requestOrigin === null) {
49
49
  (0, protocol_response_1.writeStudioProtocolError)({
@@ -77,12 +77,11 @@ const handleStudioProtocolDiscovery = ({ gitSource, liveEventsServer, remotionRo
77
77
  purpose: 'install-element',
78
78
  target: installTarget,
79
79
  });
80
- const licenseKeyOrigin = (0, origin_policy_1.getAllowedLicenseKeyOrigin)(request.headers.origin);
81
- const issuedLicenseKeyTarget = target === null || licenseKeyOrigin === null
80
+ const issuedLicenseKeyTarget = target === null
82
81
  ? null
83
82
  : (0, element_install_state_1.issueStudioProtocolTarget)({
84
83
  now,
85
- origin: licenseKeyOrigin,
84
+ origin: requestOrigin,
86
85
  purpose: 'set-license-key',
87
86
  target,
88
87
  });
@@ -45,7 +45,7 @@ const deliverElementInstall = ({ element, focusStudioTab, liveEventsServer, orig
45
45
  return delivered;
46
46
  };
47
47
  const handleStudioProtocolInstall = async ({ focusStudioTab, liveEventsServer, request, response, }) => {
48
- (0, origin_policy_1.setStudioProtocolCorsHeaders)({ licenseKey: false, request, response });
48
+ (0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
49
49
  const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request.headers.origin);
50
50
  if (requestOrigin === null) {
51
51
  (0, protocol_response_1.writeStudioProtocolError)({
@@ -16,8 +16,8 @@ const studioProtocolLicenseKeyRequestSchema = zod_1.z.object({
16
16
  });
17
17
  const MAX_STUDIO_PROTOCOL_LICENSE_KEY_BODY_SIZE = 4096;
18
18
  const handleStudioProtocolLicenseKey = async ({ configFile, focusStudioTab, liveEventsServer, request, response, }) => {
19
- (0, origin_policy_1.setStudioProtocolCorsHeaders)({ licenseKey: true, request, response });
20
- const requestOrigin = (0, origin_policy_1.getAllowedLicenseKeyOrigin)(request.headers.origin);
19
+ (0, origin_policy_1.setStudioProtocolCorsHeaders)({ request, response });
20
+ const requestOrigin = (0, origin_policy_1.getAllowedStudioProtocolOrigin)(request.headers.origin);
21
21
  if (requestOrigin === null) {
22
22
  (0, protocol_response_1.writeStudioProtocolError)({
23
23
  code: 'unsupported-origin',
@@ -1,13 +1,10 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
2
  export declare const getAllowedStudioProtocolOrigin: (origin: string | undefined) => string | null;
3
- export declare const getAllowedLicenseKeyOrigin: (origin: string | undefined) => string | null;
4
- export declare const setStudioProtocolCorsHeaders: ({ licenseKey, request, response, }: {
5
- readonly licenseKey: boolean;
3
+ export declare const setStudioProtocolCorsHeaders: ({ request, response, }: {
6
4
  readonly request: IncomingMessage;
7
5
  readonly response: ServerResponse<IncomingMessage>;
8
6
  }) => void;
9
- export declare const handleStudioProtocolOptions: ({ licenseKey, request, response, }: {
10
- readonly licenseKey: boolean;
7
+ export declare const handleStudioProtocolOptions: ({ request, response, }: {
11
8
  readonly request: IncomingMessage;
12
9
  readonly response: ServerResponse<IncomingMessage>;
13
10
  }) => Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.handleStudioProtocolOptions = exports.setStudioProtocolCorsHeaders = exports.getAllowedLicenseKeyOrigin = exports.getAllowedStudioProtocolOrigin = void 0;
3
+ exports.handleStudioProtocolOptions = exports.setStudioProtocolCorsHeaders = exports.getAllowedStudioProtocolOrigin = void 0;
4
4
  const isLoopbackHttp = (url) => url.protocol === 'http:' &&
5
5
  (url.hostname === 'localhost' || url.hostname === '127.0.0.1');
6
6
  const getAllowedStudioProtocolOrigin = (origin) => {
@@ -19,30 +19,8 @@ const getAllowedStudioProtocolOrigin = (origin) => {
19
19
  }
20
20
  };
21
21
  exports.getAllowedStudioProtocolOrigin = getAllowedStudioProtocolOrigin;
22
- const getAllowedLicenseKeyOrigin = (origin) => {
23
- if (!origin) {
24
- return null;
25
- }
26
- try {
27
- const url = new URL(origin);
28
- if (isLoopbackHttp(url)) {
29
- return url.origin;
30
- }
31
- if (url.origin === 'https://remotion.pro' ||
32
- url.origin === 'https://www.remotion.pro') {
33
- return url.origin;
34
- }
35
- return null;
36
- }
37
- catch (_a) {
38
- return null;
39
- }
40
- };
41
- exports.getAllowedLicenseKeyOrigin = getAllowedLicenseKeyOrigin;
42
- const setStudioProtocolCorsHeaders = ({ licenseKey, request, response, }) => {
43
- const origin = licenseKey
44
- ? (0, exports.getAllowedLicenseKeyOrigin)(request.headers.origin)
45
- : (0, exports.getAllowedStudioProtocolOrigin)(request.headers.origin);
22
+ const setStudioProtocolCorsHeaders = ({ request, response, }) => {
23
+ const origin = (0, exports.getAllowedStudioProtocolOrigin)(request.headers.origin);
46
24
  if (origin === null) {
47
25
  return;
48
26
  }
@@ -54,11 +32,9 @@ const setStudioProtocolCorsHeaders = ({ licenseKey, request, response, }) => {
54
32
  response.setHeader('Access-Control-Allow-Private-Network', 'true');
55
33
  };
56
34
  exports.setStudioProtocolCorsHeaders = setStudioProtocolCorsHeaders;
57
- const handleStudioProtocolOptions = ({ licenseKey, request, response, }) => {
58
- (0, exports.setStudioProtocolCorsHeaders)({ licenseKey, request, response });
59
- const origin = licenseKey
60
- ? (0, exports.getAllowedLicenseKeyOrigin)(request.headers.origin)
61
- : (0, exports.getAllowedStudioProtocolOrigin)(request.headers.origin);
35
+ const handleStudioProtocolOptions = ({ request, response, }) => {
36
+ (0, exports.setStudioProtocolCorsHeaders)({ request, response });
37
+ const origin = (0, exports.getAllowedStudioProtocolOrigin)(request.headers.origin);
62
38
  response.writeHead(origin === null ? 403 : 204);
63
39
  response.end();
64
40
  return Promise.resolve();
package/dist/routes.d.ts CHANGED
@@ -27,7 +27,7 @@ export declare const handleRoutes: ({ staticHash, staticHashPrefix, outputHash,
27
27
  getPreviewSampleRate: () => number | null;
28
28
  enableCrossSiteIsolation: boolean;
29
29
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
30
- getDefaultCodingAgent: () => "claude-code" | "codex" | "cursor" | "github-copilot" | null;
30
+ getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
31
31
  getDefaultEditor: () => DefaultEditor | null;
32
32
  configFile: string | null;
33
33
  }) => Promise<void>;
package/dist/routes.js CHANGED
@@ -284,7 +284,6 @@ const handleRoutes = ({ staticHash, staticHashPrefix, outputHash, outputHashPref
284
284
  url.pathname === '/api/studio-protocol/license-key') {
285
285
  if (request.method === 'OPTIONS') {
286
286
  return (0, origin_policy_1.handleStudioProtocolOptions)({
287
- licenseKey: url.pathname === '/api/studio-protocol/license-key',
288
287
  request,
289
288
  response,
290
289
  });
@@ -36,7 +36,7 @@ export declare const startStudio: ({ browserArgs, browserFlag, shouldOpenBrowser
36
36
  forceNew: boolean;
37
37
  rspack: boolean;
38
38
  getStudioRuntimeConfig: () => StudioRuntimeConfig;
39
- getDefaultCodingAgent: () => "claude-code" | "codex" | "cursor" | "github-copilot" | null;
39
+ getDefaultCodingAgent: () => "claude-code" | "codex" | "copilot" | "cursor" | null;
40
40
  getDefaultEditor: () => DefaultEditor | null;
41
41
  configFile: string | null;
42
42
  }) => Promise<StartStudioResult>;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/studio-server"
4
4
  },
5
5
  "name": "@remotion/studio-server",
6
- "version": "4.0.506",
6
+ "version": "4.0.507",
7
7
  "description": "Run a Remotion Studio with a server backend",
8
8
  "main": "dist",
9
9
  "scripts": {
@@ -23,7 +23,7 @@
23
23
  "access": "public"
24
24
  },
25
25
  "dependencies": {
26
- "@remotion/studio-protocol": "4.0.506",
26
+ "@remotion/studio-protocol": "4.0.507",
27
27
  "@babel/types": "7.24.0",
28
28
  "@babel/parser": "7.24.1",
29
29
  "@svgr/core": "8.1.0",
@@ -32,12 +32,12 @@
32
32
  "semver": "7.5.3",
33
33
  "zod": "4.4.3",
34
34
  "prettier": "3.8.1",
35
- "remotion": "4.0.506",
35
+ "remotion": "4.0.507",
36
36
  "recast": "0.23.11",
37
- "@remotion/bundler": "4.0.506",
38
- "@remotion/renderer": "4.0.506",
39
- "@remotion/studio-codemods": "4.0.506",
40
- "@remotion/studio-shared": "4.0.506",
37
+ "@remotion/bundler": "4.0.507",
38
+ "@remotion/renderer": "4.0.507",
39
+ "@remotion/studio-codemods": "4.0.507",
40
+ "@remotion/studio-shared": "4.0.507",
41
41
  "memfs": "3.4.3",
42
42
  "open": "8.4.2"
43
43
  },
@@ -45,7 +45,7 @@
45
45
  "ast-types": "0.16.1",
46
46
  "react": "19.2.3",
47
47
  "@types/semver": "7.5.3",
48
- "@remotion/eslint-config-internal": "4.0.506",
48
+ "@remotion/eslint-config-internal": "4.0.507",
49
49
  "eslint": "9.19.0",
50
50
  "@types/node": "20.12.14",
51
51
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
Binary file
@@ -1,3 +0,0 @@
1
- import type { DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse } from '@remotion/studio-shared';
2
- import type { ApiHandler } from '../api-types';
3
- export declare const deleteEffectKeyframeHandler: ApiHandler<DeleteEffectKeyframeRequest, DeleteEffectKeyframeResponse>;
@@ -1,89 +0,0 @@
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;
@@ -1,3 +0,0 @@
1
- import type { DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse } from '@remotion/studio-shared';
2
- import type { ApiHandler } from '../api-types';
3
- export declare const deleteSequenceKeyframeHandler: ApiHandler<DeleteSequenceKeyframeRequest, DeleteSequenceKeyframeResponse>;