@remotion/studio-server 4.0.438 → 4.0.439
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/client-render-queue.js +3 -3
- package/dist/codemods/apply-visual-control.js +8 -1
- package/dist/codemods/format-inline-content.d.ts +21 -0
- package/dist/codemods/format-inline-content.js +108 -0
- package/dist/codemods/read-visual-control-values.d.ts +7 -0
- package/dist/codemods/read-visual-control-values.js +166 -0
- package/dist/codemods/update-default-props.d.ts +4 -1
- package/dist/codemods/update-default-props.js +51 -22
- package/dist/file-watcher.d.ts +24 -7
- package/dist/file-watcher.js +148 -29
- package/dist/index.d.ts +5 -2
- package/dist/index.js +3 -0
- package/dist/preview-server/api-routes.js +8 -2
- package/dist/preview-server/default-props-watchers.js +12 -17
- package/dist/preview-server/file-existence-watchers.js +3 -3
- package/dist/preview-server/hot-middleware/index.js +1 -15
- package/dist/preview-server/live-events.d.ts +6 -1
- package/dist/preview-server/live-events.js +12 -2
- package/dist/preview-server/routes/apply-codemod.js +2 -1
- package/dist/preview-server/routes/apply-visual-control-change.js +103 -5
- package/dist/preview-server/routes/can-update-default-props.d.ts +10 -3
- package/dist/preview-server/routes/can-update-default-props.js +138 -13
- package/dist/preview-server/routes/can-update-sequence-props.js +4 -0
- package/dist/preview-server/routes/log-update.d.ts +8 -0
- package/dist/preview-server/routes/log-update.js +60 -27
- package/dist/preview-server/routes/save-sequence-props.js +47 -5
- package/dist/preview-server/routes/update-default-props.js +41 -4
- package/dist/preview-server/sequence-props-watchers.js +4 -9
- package/dist/preview-server/start-server.js +15 -1
- package/dist/preview-server/undo-stack.d.ts +24 -4
- package/dist/preview-server/undo-stack.js +75 -11
- package/dist/preview-server/watch-ignore-next-change.d.ts +3 -0
- package/dist/preview-server/watch-ignore-next-change.js +12 -0
- package/dist/start-studio.js +3 -0
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -56,13 +56,16 @@ export declare const StudioServerInternals: {
|
|
|
56
56
|
getMaxTimelineTracks: () => number;
|
|
57
57
|
setMaxTimelineTracks: (maxTracks: number) => void;
|
|
58
58
|
getLatestRemotionVersion: () => Promise<any>;
|
|
59
|
-
installFileWatcher: (
|
|
59
|
+
installFileWatcher: (options: {
|
|
60
60
|
file: string;
|
|
61
|
-
onChange: (
|
|
61
|
+
onChange: (event: import("./file-watcher").FileChangeEvent) => void;
|
|
62
62
|
}) => {
|
|
63
63
|
exists: boolean;
|
|
64
64
|
unwatch: () => void;
|
|
65
65
|
};
|
|
66
|
+
writeFileAndNotifyFileWatchers: (file: string, content: string) => void;
|
|
67
|
+
createFileWatcherRegistry: () => import("./file-watcher").FileWatcherRegistry;
|
|
68
|
+
setFileWatcherRegistry: (registry: import("./file-watcher").FileWatcherRegistry) => () => void;
|
|
66
69
|
AnsiDiff: typeof AnsiDiff;
|
|
67
70
|
formatBytes: (number: number, options?: (Intl.NumberFormatOptions & {
|
|
68
71
|
locale: string;
|
package/dist/index.js
CHANGED
|
@@ -26,6 +26,9 @@ exports.StudioServerInternals = {
|
|
|
26
26
|
setMaxTimelineTracks: max_timeline_tracks_1.setMaxTimelineTracks,
|
|
27
27
|
getLatestRemotionVersion: get_latest_remotion_version_1.getLatestRemotionVersion,
|
|
28
28
|
installFileWatcher: file_watcher_1.installFileWatcher,
|
|
29
|
+
writeFileAndNotifyFileWatchers: file_watcher_1.writeFileAndNotifyFileWatchers,
|
|
30
|
+
createFileWatcherRegistry: file_watcher_1.createFileWatcherRegistry,
|
|
31
|
+
setFileWatcherRegistry: file_watcher_1.setFileWatcherRegistry,
|
|
29
32
|
AnsiDiff: ansi_diff_1.AnsiDiff,
|
|
30
33
|
formatBytes: studio_shared_1.formatBytes,
|
|
31
34
|
parseAndApplyCodemod: duplicate_composition_1.parseAndApplyCodemod,
|
|
@@ -4,17 +4,20 @@ exports.allApiRoutes = void 0;
|
|
|
4
4
|
const add_render_1 = require("./routes/add-render");
|
|
5
5
|
const apply_codemod_1 = require("./routes/apply-codemod");
|
|
6
6
|
const apply_visual_control_change_1 = require("./routes/apply-visual-control-change");
|
|
7
|
-
const can_update_default_props_1 = require("./routes/can-update-default-props");
|
|
8
7
|
const cancel_render_1 = require("./routes/cancel-render");
|
|
9
8
|
const delete_static_file_1 = require("./routes/delete-static-file");
|
|
10
9
|
const install_dependency_1 = require("./routes/install-dependency");
|
|
11
10
|
const open_in_file_explorer_1 = require("./routes/open-in-file-explorer");
|
|
12
11
|
const project_info_1 = require("./routes/project-info");
|
|
12
|
+
const redo_1 = require("./routes/redo");
|
|
13
13
|
const remove_render_1 = require("./routes/remove-render");
|
|
14
14
|
const restart_studio_1 = require("./routes/restart-studio");
|
|
15
15
|
const save_sequence_props_1 = require("./routes/save-sequence-props");
|
|
16
|
+
const subscribe_to_default_props_1 = require("./routes/subscribe-to-default-props");
|
|
16
17
|
const subscribe_to_file_existence_1 = require("./routes/subscribe-to-file-existence");
|
|
17
18
|
const subscribe_to_sequence_props_1 = require("./routes/subscribe-to-sequence-props");
|
|
19
|
+
const undo_1 = require("./routes/undo");
|
|
20
|
+
const unsubscribe_from_default_props_1 = require("./routes/unsubscribe-from-default-props");
|
|
18
21
|
const unsubscribe_from_file_existence_1 = require("./routes/unsubscribe-from-file-existence");
|
|
19
22
|
const unsubscribe_from_sequence_props_1 = require("./routes/unsubscribe-from-sequence-props");
|
|
20
23
|
const update_available_1 = require("./routes/update-available");
|
|
@@ -29,7 +32,8 @@ exports.allApiRoutes = {
|
|
|
29
32
|
'/api/update-default-props': update_default_props_1.updateDefaultPropsHandler,
|
|
30
33
|
'/api/apply-visual-control-change': apply_visual_control_change_1.applyVisualControlHandler,
|
|
31
34
|
'/api/apply-codemod': apply_codemod_1.applyCodemodHandler,
|
|
32
|
-
'/api/
|
|
35
|
+
'/api/subscribe-to-default-props': subscribe_to_default_props_1.subscribeToDefaultProps,
|
|
36
|
+
'/api/unsubscribe-from-default-props': unsubscribe_from_default_props_1.unsubscribeFromDefaultProps,
|
|
33
37
|
'/api/subscribe-to-sequence-props': subscribe_to_sequence_props_1.subscribeToSequenceProps,
|
|
34
38
|
'/api/unsubscribe-from-sequence-props': unsubscribe_from_sequence_props_1.unsubscribeFromSequenceProps,
|
|
35
39
|
'/api/save-sequence-props': save_sequence_props_1.saveSequencePropsHandler,
|
|
@@ -38,4 +42,6 @@ exports.allApiRoutes = {
|
|
|
38
42
|
'/api/delete-static-file': delete_static_file_1.deleteStaticFileHandler,
|
|
39
43
|
'/api/restart-studio': restart_studio_1.handleRestartStudio,
|
|
40
44
|
'/api/install-package': install_dependency_1.handleInstallPackage,
|
|
45
|
+
'/api/undo': undo_1.undoHandler,
|
|
46
|
+
'/api/redo': redo_1.redoHandler,
|
|
41
47
|
};
|
|
@@ -17,8 +17,8 @@ const ensureGlobalWatcher = (rootFile) => {
|
|
|
17
17
|
}
|
|
18
18
|
const { unwatch } = (0, file_watcher_1.installFileWatcher)({
|
|
19
19
|
file: rootFile,
|
|
20
|
-
onChange: (
|
|
21
|
-
if (type === 'deleted') {
|
|
20
|
+
onChange: (event) => {
|
|
21
|
+
if (event.type === 'deleted') {
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
24
|
if (!watcherConfig) {
|
|
@@ -30,21 +30,16 @@ const ensureGlobalWatcher = (rootFile) => {
|
|
|
30
30
|
continue;
|
|
31
31
|
}
|
|
32
32
|
const clientIds = [...subscriptions[compositionId]];
|
|
33
|
-
(0, can_update_default_props_1.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
for (const cId of clientIds) {
|
|
45
|
-
listener.sendEventToClientId(cId, event);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
33
|
+
const newResult = (0, can_update_default_props_1.computeCanUpdateDefaultPropsFromContent)(event.content, compositionId);
|
|
34
|
+
(0, live_events_1.waitForLiveEventsListener)().then((listener) => {
|
|
35
|
+
const updateEvent = {
|
|
36
|
+
type: 'default-props-updatable-changed',
|
|
37
|
+
compositionId,
|
|
38
|
+
result: newResult,
|
|
39
|
+
};
|
|
40
|
+
for (const cId of clientIds) {
|
|
41
|
+
listener.sendEventToClientId(cId, updateEvent);
|
|
42
|
+
}
|
|
48
43
|
});
|
|
49
44
|
}
|
|
50
45
|
},
|
|
@@ -12,8 +12,8 @@ const subscribeToFileExistenceWatchers = ({ file: relativeFile, remotionRoot, cl
|
|
|
12
12
|
const file = node_path_1.default.resolve(remotionRoot, relativeFile);
|
|
13
13
|
const { unwatch, exists } = (0, file_watcher_1.installFileWatcher)({
|
|
14
14
|
file,
|
|
15
|
-
onChange: (
|
|
16
|
-
if (type === 'created') {
|
|
15
|
+
onChange: (event) => {
|
|
16
|
+
if (event.type === 'created') {
|
|
17
17
|
(0, live_events_1.waitForLiveEventsListener)().then((listener) => {
|
|
18
18
|
listener.sendEventToClient({
|
|
19
19
|
type: 'watched-file-undeleted',
|
|
@@ -22,7 +22,7 @@ const subscribeToFileExistenceWatchers = ({ file: relativeFile, remotionRoot, cl
|
|
|
22
22
|
});
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
-
if (type === 'deleted') {
|
|
25
|
+
if (event.type === 'deleted') {
|
|
26
26
|
(0, live_events_1.waitForLiveEventsListener)().then((listener) => {
|
|
27
27
|
listener.sendEventToClient({
|
|
28
28
|
type: 'watched-file-deleted',
|
|
@@ -9,7 +9,6 @@ exports.webpackHotMiddleware = void 0;
|
|
|
9
9
|
const node_url_1 = require("node:url");
|
|
10
10
|
const renderer_1 = require("@remotion/renderer");
|
|
11
11
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
12
|
-
const hmr_suppression_1 = require("../hmr-suppression");
|
|
13
12
|
const pathMatch = function (url, path) {
|
|
14
13
|
try {
|
|
15
14
|
return (0, node_url_1.parse)(url).pathname === path;
|
|
@@ -21,16 +20,9 @@ const pathMatch = function (url, path) {
|
|
|
21
20
|
const webpackHotMiddleware = (compiler, logLevel) => {
|
|
22
21
|
const eventStream = createEventStream(studio_shared_1.hotMiddlewareOptions.heartbeat);
|
|
23
22
|
let latestStats = null;
|
|
24
|
-
let currentBuildSuppressed = false;
|
|
25
23
|
compiler.hooks.invalid.tap('remotion', onInvalid);
|
|
26
24
|
compiler.hooks.done.tap('remotion', onDone);
|
|
27
|
-
function onInvalid(
|
|
28
|
-
if ((0, hmr_suppression_1.shouldSuppressHmr)(filename)) {
|
|
29
|
-
currentBuildSuppressed = true;
|
|
30
|
-
latestStats = null;
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
currentBuildSuppressed = false;
|
|
25
|
+
function onInvalid() {
|
|
34
26
|
latestStats = null;
|
|
35
27
|
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, 'Building...');
|
|
36
28
|
eventStream === null || eventStream === void 0 ? void 0 : eventStream.publish({
|
|
@@ -40,12 +32,6 @@ const webpackHotMiddleware = (compiler, logLevel) => {
|
|
|
40
32
|
function onDone(statsResult) {
|
|
41
33
|
// Keep hold of latest stats so they can be propagated to new clients
|
|
42
34
|
latestStats = statsResult;
|
|
43
|
-
if (currentBuildSuppressed) {
|
|
44
|
-
// Still send the "built" event so the client hash stays in sync,
|
|
45
|
-
// but skip the "building" spinner. This avoids accumulating
|
|
46
|
-
// a large HMR delta for the next real build.
|
|
47
|
-
currentBuildSuppressed = false;
|
|
48
|
-
}
|
|
49
35
|
publishStats('built', latestStats, eventStream);
|
|
50
36
|
}
|
|
51
37
|
const middleware = function (req, res, next) {
|
|
@@ -2,9 +2,14 @@ import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
|
2
2
|
import type { EventSourceEvent } from '@remotion/studio-shared';
|
|
3
3
|
export type LiveEventsServer = {
|
|
4
4
|
sendEventToClient: (event: EventSourceEvent) => void;
|
|
5
|
+
sendEventToClientId: (clientId: string, event: EventSourceEvent) => void;
|
|
5
6
|
router: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
6
7
|
closeConnections: () => Promise<void>;
|
|
7
8
|
};
|
|
8
|
-
export
|
|
9
|
+
export type InitialUndoRedoState = {
|
|
10
|
+
undoFile: string | null;
|
|
11
|
+
redoFile: string | null;
|
|
12
|
+
};
|
|
13
|
+
export declare const makeLiveEventsRouter: (logLevel: "error" | "info" | "trace" | "verbose" | "warn", getInitialUndoRedoState: () => InitialUndoRedoState) => LiveEventsServer;
|
|
9
14
|
export declare const waitForLiveEventsListener: () => Promise<LiveEventsServer>;
|
|
10
15
|
export declare const setLiveEventsListener: (listener: LiveEventsServer) => () => void;
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.setLiveEventsListener = exports.waitForLiveEventsListener = exports.makeLiveEventsRouter = void 0;
|
|
4
4
|
const server_ready_1 = require("../server-ready");
|
|
5
|
+
const default_props_watchers_1 = require("./default-props-watchers");
|
|
5
6
|
const file_existence_watchers_1 = require("./file-existence-watchers");
|
|
6
7
|
const sequence_props_watchers_1 = require("./sequence-props-watchers");
|
|
7
8
|
const serializeMessage = (message) => {
|
|
8
9
|
return `data: ${JSON.stringify(message)}\n\n`;
|
|
9
10
|
};
|
|
10
11
|
let printPortMessageTimeout = null;
|
|
11
|
-
const makeLiveEventsRouter = (logLevel) => {
|
|
12
|
+
const makeLiveEventsRouter = (logLevel, getInitialUndoRedoState) => {
|
|
12
13
|
let clients = [];
|
|
13
14
|
const router = (request, response) => {
|
|
14
15
|
const headers = {
|
|
@@ -23,7 +24,8 @@ const makeLiveEventsRouter = (logLevel) => {
|
|
|
23
24
|
return Promise.resolve();
|
|
24
25
|
}
|
|
25
26
|
const clientId = String(Math.random());
|
|
26
|
-
|
|
27
|
+
const { undoFile, redoFile } = getInitialUndoRedoState();
|
|
28
|
+
response.write(serializeMessage({ type: 'init', clientId, undoFile, redoFile }));
|
|
27
29
|
const newClient = {
|
|
28
30
|
id: clientId,
|
|
29
31
|
response,
|
|
@@ -33,6 +35,7 @@ const makeLiveEventsRouter = (logLevel) => {
|
|
|
33
35
|
clearTimeout(printPortMessageTimeout);
|
|
34
36
|
}
|
|
35
37
|
request.on('close', () => {
|
|
38
|
+
(0, default_props_watchers_1.unsubscribeClientDefaultPropsWatchers)(clientId);
|
|
36
39
|
(0, file_existence_watchers_1.unsubscribeClientFileExistenceWatchers)(clientId);
|
|
37
40
|
(0, sequence_props_watchers_1.unsubscribeClientSequencePropsWatchers)(clientId);
|
|
38
41
|
clients = clients.filter((client) => client.id !== clientId);
|
|
@@ -53,8 +56,15 @@ const makeLiveEventsRouter = (logLevel) => {
|
|
|
53
56
|
client.response.write(serializeMessage(event));
|
|
54
57
|
});
|
|
55
58
|
};
|
|
59
|
+
const sendEventToClientId = (clientId, event) => {
|
|
60
|
+
const client = clients.find((c) => c.id === clientId);
|
|
61
|
+
if (client) {
|
|
62
|
+
client.response.write(serializeMessage(event));
|
|
63
|
+
}
|
|
64
|
+
};
|
|
56
65
|
return {
|
|
57
66
|
sendEventToClient,
|
|
67
|
+
sendEventToClientId,
|
|
58
68
|
router,
|
|
59
69
|
closeConnections: () => {
|
|
60
70
|
return Promise.all(clients.map((client) => {
|
|
@@ -5,6 +5,7 @@ const node_fs_1 = require("node:fs");
|
|
|
5
5
|
const renderer_1 = require("@remotion/renderer");
|
|
6
6
|
const duplicate_composition_1 = require("../../codemods/duplicate-composition");
|
|
7
7
|
const simple_diff_1 = require("../../codemods/simple-diff");
|
|
8
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
8
9
|
const project_info_1 = require("../project-info");
|
|
9
10
|
const can_update_default_props_1 = require("./can-update-default-props");
|
|
10
11
|
const applyCodemodHandler = async ({ input: { codemod, dryRun }, logLevel, remotionRoot, entryPoint }) => {
|
|
@@ -26,7 +27,7 @@ const applyCodemodHandler = async ({ input: { codemod, dryRun }, logLevel, remot
|
|
|
26
27
|
newLines: formatted.split('\n'),
|
|
27
28
|
});
|
|
28
29
|
if (!dryRun) {
|
|
29
|
-
(0,
|
|
30
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(projectInfo.rootFile, formatted);
|
|
30
31
|
const end = Date.now() - time;
|
|
31
32
|
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, renderer_1.RenderInternals.chalk.blue(`Edited root file in ${end}ms`));
|
|
32
33
|
}
|
|
@@ -1,4 +1,37 @@
|
|
|
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
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
@@ -6,9 +39,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
39
|
exports.applyVisualControlHandler = void 0;
|
|
7
40
|
const node_fs_1 = require("node:fs");
|
|
8
41
|
const node_path_1 = __importDefault(require("node:path"));
|
|
42
|
+
const renderer_1 = require("@remotion/renderer");
|
|
9
43
|
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
10
44
|
const recast_mods_1 = require("../../codemods/recast-mods");
|
|
11
|
-
const
|
|
45
|
+
const file_watcher_1 = require("../../file-watcher");
|
|
46
|
+
const make_link_1 = require("../../hyperlinks/make-link");
|
|
47
|
+
const live_events_1 = require("../live-events");
|
|
48
|
+
const undo_stack_1 = require("../undo-stack");
|
|
49
|
+
const watch_ignore_next_change_1 = require("../watch-ignore-next-change");
|
|
50
|
+
const log_update_1 = require("./log-update");
|
|
51
|
+
const applyVisualControlHandler = async ({ input: { fileName, changes }, remotionRoot, logLevel }) => {
|
|
52
|
+
renderer_1.RenderInternals.Log.trace({ indent: false, logLevel }, `[apply-visual-control] Received request for ${fileName} with ${changes.length} changes`);
|
|
12
53
|
const absolutePath = node_path_1.default.resolve(remotionRoot, fileName);
|
|
13
54
|
const fileRelativeToRoot = node_path_1.default.relative(remotionRoot, absolutePath);
|
|
14
55
|
if (fileRelativeToRoot.startsWith('..')) {
|
|
@@ -26,10 +67,67 @@ const applyVisualControlHandler = ({ input: { fileName, changes }, remotionRoot
|
|
|
26
67
|
if (changesMade.length === 0) {
|
|
27
68
|
throw new Error('No changes were made to the file');
|
|
28
69
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
70
|
+
let output = (0, parse_ast_1.serializeAst)(newAst);
|
|
71
|
+
let formatted = false;
|
|
72
|
+
try {
|
|
73
|
+
const prettier = await Promise.resolve().then(() => __importStar(require('prettier')));
|
|
74
|
+
const { format, resolveConfig, resolveConfigFile } = prettier;
|
|
75
|
+
const configFilePath = await resolveConfigFile();
|
|
76
|
+
if (configFilePath) {
|
|
77
|
+
const prettierConfig = await resolveConfig(configFilePath);
|
|
78
|
+
if (prettierConfig) {
|
|
79
|
+
output = await format(output, {
|
|
80
|
+
...prettierConfig,
|
|
81
|
+
filepath: 'test.tsx',
|
|
82
|
+
plugins: [],
|
|
83
|
+
endOfLine: 'auto',
|
|
84
|
+
});
|
|
85
|
+
formatted = true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
catch (_a) {
|
|
90
|
+
// Prettier not available, use unformatted output
|
|
91
|
+
}
|
|
92
|
+
(0, undo_stack_1.pushToUndoStack)({
|
|
93
|
+
filePath: absolutePath,
|
|
94
|
+
oldContents: fileContents,
|
|
95
|
+
logLevel,
|
|
96
|
+
remotionRoot,
|
|
97
|
+
description: {
|
|
98
|
+
undoMessage: 'Undid visual control change',
|
|
99
|
+
redoMessage: 'Redid visual control change',
|
|
100
|
+
},
|
|
101
|
+
entryType: 'visual-control',
|
|
33
102
|
});
|
|
103
|
+
(0, undo_stack_1.suppressUndoStackInvalidation)(absolutePath);
|
|
104
|
+
(0, watch_ignore_next_change_1.suppressBundlerUpdateForFile)(absolutePath);
|
|
105
|
+
(0, file_watcher_1.writeFileAndNotifyFileWatchers)(absolutePath, output);
|
|
106
|
+
(0, live_events_1.waitForLiveEventsListener)().then((listener) => {
|
|
107
|
+
listener.sendEventToClient({
|
|
108
|
+
type: 'visual-control-values-changed',
|
|
109
|
+
values: changes.map((change) => ({
|
|
110
|
+
id: change.id,
|
|
111
|
+
value: change.newValueIsUndefined
|
|
112
|
+
? null
|
|
113
|
+
: JSON.parse(change.newValueSerialized),
|
|
114
|
+
isUndefined: change.newValueIsUndefined,
|
|
115
|
+
})),
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
const locationLabel = `${fileRelativeToRoot}`;
|
|
119
|
+
const fileLink = (0, make_link_1.makeHyperlink)({
|
|
120
|
+
url: `file://${absolutePath}`,
|
|
121
|
+
text: locationLabel,
|
|
122
|
+
fallback: locationLabel,
|
|
123
|
+
});
|
|
124
|
+
renderer_1.RenderInternals.Log.info({ indent: false, logLevel }, `${renderer_1.RenderInternals.chalk.blueBright(`${fileLink}:`)} Applied visual control changes`);
|
|
125
|
+
if (!formatted) {
|
|
126
|
+
(0, log_update_1.warnAboutPrettierOnce)(logLevel);
|
|
127
|
+
}
|
|
128
|
+
(0, undo_stack_1.printUndoHint)(logLevel);
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
|
+
};
|
|
34
132
|
};
|
|
35
133
|
exports.applyVisualControlHandler = applyVisualControlHandler;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { ApiHandler } from '../api-types';
|
|
1
|
+
import type { CanUpdateDefaultPropsResponse } from '@remotion/studio-shared';
|
|
3
2
|
export declare const checkIfTypeScriptFile: (file: string) => void;
|
|
4
|
-
export declare const
|
|
3
|
+
export declare const computeCanUpdateDefaultPropsFromContent: (content: string, compositionId: string) => CanUpdateDefaultPropsResponse;
|
|
4
|
+
export declare const computeCanUpdateDefaultProps: ({ compositionId, remotionRoot, entryPoint, }: {
|
|
5
|
+
compositionId: string;
|
|
6
|
+
remotionRoot: string;
|
|
7
|
+
entryPoint: string;
|
|
8
|
+
}) => Promise<{
|
|
9
|
+
result: CanUpdateDefaultPropsResponse;
|
|
10
|
+
rootFile: string | null;
|
|
11
|
+
}>;
|
|
@@ -1,9 +1,44 @@
|
|
|
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
36
|
+
exports.computeCanUpdateDefaultProps = exports.computeCanUpdateDefaultPropsFromContent = exports.checkIfTypeScriptFile = void 0;
|
|
4
37
|
const node_fs_1 = require("node:fs");
|
|
5
|
-
const
|
|
38
|
+
const recast = __importStar(require("recast"));
|
|
39
|
+
const parse_ast_1 = require("../../codemods/parse-ast");
|
|
6
40
|
const project_info_1 = require("../project-info");
|
|
41
|
+
const can_update_sequence_props_1 = require("./can-update-sequence-props");
|
|
7
42
|
const checkIfTypeScriptFile = (file) => {
|
|
8
43
|
if (!file.endsWith('.tsx') &&
|
|
9
44
|
!file.endsWith('.ts') &&
|
|
@@ -13,28 +48,118 @@ const checkIfTypeScriptFile = (file) => {
|
|
|
13
48
|
}
|
|
14
49
|
};
|
|
15
50
|
exports.checkIfTypeScriptFile = checkIfTypeScriptFile;
|
|
16
|
-
const
|
|
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
|
+
const value = (0, can_update_sequence_props_1.extractStaticValue)(expression);
|
|
111
|
+
if (value !== null &&
|
|
112
|
+
typeof value === 'object' &&
|
|
113
|
+
!Array.isArray(value)) {
|
|
114
|
+
result = value;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
this.traverse(path);
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
121
|
+
};
|
|
122
|
+
const computeCanUpdateDefaultPropsFromContent = (content, compositionId) => {
|
|
123
|
+
try {
|
|
124
|
+
const currentDefaultProps = extractDefaultPropsFromSource(content, compositionId);
|
|
125
|
+
if (currentDefaultProps === null) {
|
|
126
|
+
throw new Error(`Could not find or extract defaultProps for composition "${compositionId}"`);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
canUpdate: true,
|
|
130
|
+
currentDefaultProps,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
return {
|
|
135
|
+
canUpdate: false,
|
|
136
|
+
reason: err.message,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
exports.computeCanUpdateDefaultPropsFromContent = computeCanUpdateDefaultPropsFromContent;
|
|
141
|
+
const computeCanUpdateDefaultProps = async ({ compositionId, remotionRoot, entryPoint, }) => {
|
|
17
142
|
try {
|
|
18
143
|
const projectInfo = await (0, project_info_1.getProjectInfo)(remotionRoot, entryPoint);
|
|
19
144
|
if (!projectInfo.rootFile) {
|
|
20
145
|
throw new Error('Cannot find root file in project');
|
|
21
146
|
}
|
|
22
147
|
(0, exports.checkIfTypeScriptFile)(projectInfo.rootFile);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
input: (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8'),
|
|
26
|
-
newDefaultProps: {},
|
|
27
|
-
enumPaths: [],
|
|
28
|
-
});
|
|
148
|
+
const input = (0, node_fs_1.readFileSync)(projectInfo.rootFile, 'utf-8');
|
|
149
|
+
const result = (0, exports.computeCanUpdateDefaultPropsFromContent)(input, compositionId);
|
|
29
150
|
return {
|
|
30
|
-
|
|
151
|
+
result,
|
|
152
|
+
rootFile: projectInfo.rootFile,
|
|
31
153
|
};
|
|
32
154
|
}
|
|
33
155
|
catch (err) {
|
|
34
156
|
return {
|
|
35
|
-
|
|
36
|
-
|
|
157
|
+
result: {
|
|
158
|
+
canUpdate: false,
|
|
159
|
+
reason: err.message,
|
|
160
|
+
},
|
|
161
|
+
rootFile: null,
|
|
37
162
|
};
|
|
38
163
|
}
|
|
39
164
|
};
|
|
40
|
-
exports.
|
|
165
|
+
exports.computeCanUpdateDefaultProps = computeCanUpdateDefaultProps;
|
|
@@ -52,6 +52,8 @@ const isStaticValue = (node) => {
|
|
|
52
52
|
return ((node.operator === '-' ||
|
|
53
53
|
node.operator === '+') &&
|
|
54
54
|
node.argument.type === 'NumericLiteral');
|
|
55
|
+
case 'TSAsExpression':
|
|
56
|
+
return (0, exports.isStaticValue)(node.expression);
|
|
55
57
|
case 'ArrayExpression':
|
|
56
58
|
return node.elements.every((el) => el !== null && el.type !== 'SpreadElement' && (0, exports.isStaticValue)(el));
|
|
57
59
|
case 'ObjectExpression':
|
|
@@ -78,6 +80,8 @@ const extractStaticValue = (node) => {
|
|
|
78
80
|
}
|
|
79
81
|
return undefined;
|
|
80
82
|
}
|
|
83
|
+
case 'TSAsExpression':
|
|
84
|
+
return (0, exports.extractStaticValue)(node.expression);
|
|
81
85
|
case 'ArrayExpression':
|
|
82
86
|
return node.elements.map((el) => {
|
|
83
87
|
if (el === null || el.type === 'SpreadElement') {
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export declare const warnAboutPrettierOnce: (logLevel: "error" | "info" | "trace" | "verbose" | "warn") => void;
|
|
2
|
+
export declare const normalizeQuotes: (str: string) => string;
|
|
3
|
+
export declare const formatPropChange: ({ key, oldValueString, newValueString, defaultValueString, }: {
|
|
4
|
+
key: string;
|
|
5
|
+
oldValueString: string;
|
|
6
|
+
newValueString: string;
|
|
7
|
+
defaultValueString: string | null;
|
|
8
|
+
}) => string;
|
|
1
9
|
export declare const logUpdate: ({ absolutePath, fileRelativeToRoot, key, oldValueString, newValueString, defaultValueString, formatted, logLevel, }: {
|
|
2
10
|
absolutePath: string;
|
|
3
11
|
fileRelativeToRoot: string;
|