@remotion/studio-server 4.0.437 → 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
|
@@ -26,10 +26,10 @@ const addCompletedClientRender = ({ render, remotionRoot, }) => {
|
|
|
26
26
|
const filePath = (0, resolve_output_path_1.resolveOutputPath)(remotionRoot, render.outName);
|
|
27
27
|
const { unwatch } = (0, file_watcher_1.installFileWatcher)({
|
|
28
28
|
file: filePath,
|
|
29
|
-
onChange: (
|
|
30
|
-
if (type === 'created' || type === 'deleted') {
|
|
29
|
+
onChange: (event) => {
|
|
30
|
+
if (event.type === 'created' || event.type === 'deleted') {
|
|
31
31
|
updateCompletedClientRender(render.id, {
|
|
32
|
-
deletedOutputLocation: type === 'deleted',
|
|
32
|
+
deletedOutputLocation: event.type === 'deleted',
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
},
|
|
@@ -68,7 +68,14 @@ const applyVisualControl = ({ file, transformation, changesMade, }) => {
|
|
|
68
68
|
if (change.id !== str) {
|
|
69
69
|
continue;
|
|
70
70
|
}
|
|
71
|
-
|
|
71
|
+
let parsed;
|
|
72
|
+
if (change.newValueIsUndefined) {
|
|
73
|
+
parsed = (0, parse_ast_1.parseAst)('a = undefined').program
|
|
74
|
+
.body[0].expression.right;
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
parsed = (0, parse_ast_1.parseAst)(`a = ${(0, studio_shared_1.stringifyDefaultProps)({ props: JSON.parse(change.newValueSerialized), enumPaths: change.enumPaths })}`).program.body[0].expression.right;
|
|
78
|
+
}
|
|
72
79
|
node.arguments[1] = parsed;
|
|
73
80
|
changesMade.push({
|
|
74
81
|
description: `Applied visual control ${change.id}`,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instead of running prettier on the entire file (which is slow),
|
|
3
|
+
* format only a small snippet of inline content (e.g. stringified defaultProps).
|
|
4
|
+
*
|
|
5
|
+
* @param inlineContent - The raw content to format (e.g. stringified props)
|
|
6
|
+
* @param linePrefix - Everything from the start of the line to where
|
|
7
|
+
* inlineContent will appear (used to calculate column offset and indentation)
|
|
8
|
+
* @param endOfLine - Prettier endOfLine option
|
|
9
|
+
*
|
|
10
|
+
* We wrap the content in `const __x__ = CONTENT;` and adjust printWidth
|
|
11
|
+
* so prettier makes the same line-breaking decisions as if the content
|
|
12
|
+
* were at its actual column position in the file.
|
|
13
|
+
*/
|
|
14
|
+
export declare const formatInlineContent: ({ inlineContent, linePrefix, endOfLine, }: {
|
|
15
|
+
inlineContent: string;
|
|
16
|
+
linePrefix: string;
|
|
17
|
+
endOfLine: "auto" | "lf";
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
formatted: string;
|
|
20
|
+
didFormat: boolean;
|
|
21
|
+
}>;
|
|
@@ -0,0 +1,108 @@
|
|
|
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.formatInlineContent = void 0;
|
|
37
|
+
/**
|
|
38
|
+
* Instead of running prettier on the entire file (which is slow),
|
|
39
|
+
* format only a small snippet of inline content (e.g. stringified defaultProps).
|
|
40
|
+
*
|
|
41
|
+
* @param inlineContent - The raw content to format (e.g. stringified props)
|
|
42
|
+
* @param linePrefix - Everything from the start of the line to where
|
|
43
|
+
* inlineContent will appear (used to calculate column offset and indentation)
|
|
44
|
+
* @param endOfLine - Prettier endOfLine option
|
|
45
|
+
*
|
|
46
|
+
* We wrap the content in `const __x__ = CONTENT;` and adjust printWidth
|
|
47
|
+
* so prettier makes the same line-breaking decisions as if the content
|
|
48
|
+
* were at its actual column position in the file.
|
|
49
|
+
*/
|
|
50
|
+
const formatInlineContent = async ({ inlineContent, linePrefix, endOfLine, }) => {
|
|
51
|
+
var _a;
|
|
52
|
+
var _b, _c, _d;
|
|
53
|
+
let prettier = null;
|
|
54
|
+
try {
|
|
55
|
+
prettier = await Promise.resolve().then(() => __importStar(require('prettier')));
|
|
56
|
+
}
|
|
57
|
+
catch (_e) {
|
|
58
|
+
return { formatted: inlineContent, didFormat: false };
|
|
59
|
+
}
|
|
60
|
+
const { format, resolveConfig, resolveConfigFile } = prettier;
|
|
61
|
+
const configFilePath = await resolveConfigFile();
|
|
62
|
+
if (!configFilePath) {
|
|
63
|
+
return { formatted: inlineContent, didFormat: false };
|
|
64
|
+
}
|
|
65
|
+
const prettierConfig = await resolveConfig(configFilePath);
|
|
66
|
+
if (!prettierConfig) {
|
|
67
|
+
return { formatted: inlineContent, didFormat: false };
|
|
68
|
+
}
|
|
69
|
+
const tabWidth = (_b = prettierConfig.tabWidth) !== null && _b !== void 0 ? _b : 2;
|
|
70
|
+
const baseIndent = (_c = (_a = linePrefix.match(/^(\s*)/)) === null || _a === void 0 ? void 0 : _a[1]) !== null && _c !== void 0 ? _c : '';
|
|
71
|
+
// Calculate visual column offset (tabs expand to tabWidth columns)
|
|
72
|
+
const columnOffset = [...linePrefix].reduce((col, ch) => (ch === '\t' ? col + tabWidth : col + 1), 0);
|
|
73
|
+
// Adjust printWidth so the wrapper prefix occupies the same visual
|
|
74
|
+
// width as the actual file prefix, ensuring identical line breaks.
|
|
75
|
+
const configPrintWidth = (_d = prettierConfig.printWidth) !== null && _d !== void 0 ? _d : 80;
|
|
76
|
+
const wrapperPrefix = 'const __x__ = ';
|
|
77
|
+
const effectivePrintWidth = Math.max(configPrintWidth - columnOffset + wrapperPrefix.length, 20);
|
|
78
|
+
const wrappedSource = `${wrapperPrefix}${inlineContent};\n`;
|
|
79
|
+
const formattedWrapped = await format(wrappedSource, {
|
|
80
|
+
...prettierConfig,
|
|
81
|
+
printWidth: effectivePrintWidth,
|
|
82
|
+
filepath: 'test.tsx',
|
|
83
|
+
plugins: [],
|
|
84
|
+
endOfLine,
|
|
85
|
+
});
|
|
86
|
+
// Extract the formatted value from the wrapper
|
|
87
|
+
const withoutSemicolon = formattedWrapped.replace(/;\s*$/, '');
|
|
88
|
+
let formattedProps;
|
|
89
|
+
if (withoutSemicolon.startsWith(wrapperPrefix)) {
|
|
90
|
+
formattedProps = withoutSemicolon.slice(wrapperPrefix.length);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Prettier broke the line after `=` — extract and dedent one level
|
|
94
|
+
const lines = withoutSemicolon.split('\n').slice(1);
|
|
95
|
+
const useTabs = prettierConfig.useTabs;
|
|
96
|
+
const oneIndent = useTabs ? '\t' : ' '.repeat(tabWidth);
|
|
97
|
+
formattedProps = lines
|
|
98
|
+
.map((l) => (l.startsWith(oneIndent) ? l.slice(oneIndent.length) : l))
|
|
99
|
+
.join('\n');
|
|
100
|
+
}
|
|
101
|
+
// Add base indentation to all lines except the first
|
|
102
|
+
const indentedProps = formattedProps
|
|
103
|
+
.split('\n')
|
|
104
|
+
.map((line, i) => i === 0 ? line : line.length > 0 ? baseIndent + line : line)
|
|
105
|
+
.join('\n');
|
|
106
|
+
return { formatted: indentedProps, didFormat: true };
|
|
107
|
+
};
|
|
108
|
+
exports.formatInlineContent = formatInlineContent;
|
|
@@ -0,0 +1,166 @@
|
|
|
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.readVisualControlValues = void 0;
|
|
37
|
+
const recast = __importStar(require("recast"));
|
|
38
|
+
const getStringValue = (node) => {
|
|
39
|
+
if (node.type === 'StringLiteral') {
|
|
40
|
+
return node.value;
|
|
41
|
+
}
|
|
42
|
+
if (node.type === 'TemplateLiteral') {
|
|
43
|
+
const tl = node;
|
|
44
|
+
if (tl.expressions.length > 0) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return tl.quasis[0].value.raw;
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
};
|
|
51
|
+
const evaluateExpression = (node) => {
|
|
52
|
+
switch (node.type) {
|
|
53
|
+
case 'NumericLiteral':
|
|
54
|
+
return node.value;
|
|
55
|
+
case 'StringLiteral':
|
|
56
|
+
return node.value;
|
|
57
|
+
case 'BooleanLiteral':
|
|
58
|
+
return node.value;
|
|
59
|
+
case 'NullLiteral':
|
|
60
|
+
return null;
|
|
61
|
+
case 'Identifier': {
|
|
62
|
+
const { name } = node;
|
|
63
|
+
if (name === 'undefined') {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Cannot evaluate identifier: ${name}`);
|
|
67
|
+
}
|
|
68
|
+
case 'UnaryExpression': {
|
|
69
|
+
const unary = node;
|
|
70
|
+
if (unary.operator === '-') {
|
|
71
|
+
const arg = evaluateExpression(unary.argument);
|
|
72
|
+
if (typeof arg === 'number') {
|
|
73
|
+
return -arg;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (unary.operator === '+') {
|
|
77
|
+
const arg = evaluateExpression(unary.argument);
|
|
78
|
+
if (typeof arg === 'number') {
|
|
79
|
+
return arg;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
throw new Error(`Cannot evaluate unary: ${unary.operator}`);
|
|
83
|
+
}
|
|
84
|
+
case 'ObjectExpression': {
|
|
85
|
+
const obj = {};
|
|
86
|
+
const { properties } = node;
|
|
87
|
+
for (const prop of properties) {
|
|
88
|
+
if (prop.type !== 'ObjectProperty') {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
let key = null;
|
|
92
|
+
if (prop.key.type === 'Identifier') {
|
|
93
|
+
key = prop.key.name;
|
|
94
|
+
}
|
|
95
|
+
else if (prop.key.type === 'StringLiteral') {
|
|
96
|
+
key = prop.key.value;
|
|
97
|
+
}
|
|
98
|
+
else if (prop.key.type === 'NumericLiteral') {
|
|
99
|
+
key = String(prop.key.value);
|
|
100
|
+
}
|
|
101
|
+
if (key !== null) {
|
|
102
|
+
obj[key] = evaluateExpression(prop.value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return obj;
|
|
106
|
+
}
|
|
107
|
+
case 'ArrayExpression': {
|
|
108
|
+
const { elements } = node;
|
|
109
|
+
return elements.map((el) => {
|
|
110
|
+
if (el === null) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
return evaluateExpression(el);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
case 'TemplateLiteral': {
|
|
117
|
+
const tl = node;
|
|
118
|
+
if (tl.expressions.length === 0) {
|
|
119
|
+
return tl.quasis[0].value.cooked;
|
|
120
|
+
}
|
|
121
|
+
throw new Error('Cannot evaluate template literal with expressions');
|
|
122
|
+
}
|
|
123
|
+
default:
|
|
124
|
+
throw new Error(`Cannot evaluate AST node: ${node.type}`);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const readVisualControlValues = (file) => {
|
|
128
|
+
const values = [];
|
|
129
|
+
recast.types.visit(file.program, {
|
|
130
|
+
visitCallExpression(path) {
|
|
131
|
+
const { node } = path;
|
|
132
|
+
if (node.callee.type !== 'Identifier' ||
|
|
133
|
+
node.callee.name !== 'visualControl') {
|
|
134
|
+
return this.traverse(path);
|
|
135
|
+
}
|
|
136
|
+
const firstArg = node.arguments[0];
|
|
137
|
+
const id = getStringValue(firstArg);
|
|
138
|
+
if (id === null) {
|
|
139
|
+
return this.traverse(path);
|
|
140
|
+
}
|
|
141
|
+
if (node.arguments.length < 2) {
|
|
142
|
+
return this.traverse(path);
|
|
143
|
+
}
|
|
144
|
+
const valueNode = node.arguments[1];
|
|
145
|
+
try {
|
|
146
|
+
if (valueNode.type === 'Identifier' &&
|
|
147
|
+
valueNode.name === 'undefined') {
|
|
148
|
+
values.push({ id, value: null, isUndefined: true });
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
values.push({
|
|
152
|
+
id,
|
|
153
|
+
value: evaluateExpression(valueNode),
|
|
154
|
+
isUndefined: false,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch (_a) {
|
|
159
|
+
// Skip values we can't evaluate statically
|
|
160
|
+
}
|
|
161
|
+
return this.traverse(path);
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
return values;
|
|
165
|
+
};
|
|
166
|
+
exports.readVisualControlValues = readVisualControlValues;
|
|
@@ -4,4 +4,7 @@ export declare const updateDefaultProps: ({ input, compositionId, newDefaultProp
|
|
|
4
4
|
compositionId: string;
|
|
5
5
|
newDefaultProps: Record<string, unknown>;
|
|
6
6
|
enumPaths: EnumPath[];
|
|
7
|
-
}) => Promise<
|
|
7
|
+
}) => Promise<{
|
|
8
|
+
output: string;
|
|
9
|
+
formatted: boolean;
|
|
10
|
+
}>;
|
|
@@ -36,9 +36,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.updateDefaultProps = void 0;
|
|
37
37
|
const studio_shared_1 = require("@remotion/studio-shared");
|
|
38
38
|
const recast = __importStar(require("recast"));
|
|
39
|
+
const format_inline_content_1 = require("./format-inline-content");
|
|
39
40
|
const parse_ast_1 = require("./parse-ast");
|
|
41
|
+
// Recast uses tabWidth=4 for column counting, so columns don't
|
|
42
|
+
// correspond to character indices when tabs are present.
|
|
43
|
+
// This converts a recast loc (line/column) to a character offset.
|
|
44
|
+
const RECAST_TAB_WIDTH = 4;
|
|
45
|
+
const recastLocToOffset = (input, loc) => {
|
|
46
|
+
const lines = input.split('\n');
|
|
47
|
+
let offset = 0;
|
|
48
|
+
for (let i = 0; i < loc.line - 1; i++) {
|
|
49
|
+
offset += lines[i].length + 1;
|
|
50
|
+
}
|
|
51
|
+
// Convert recast's tab-expanded column to character index
|
|
52
|
+
const line = lines[loc.line - 1];
|
|
53
|
+
let col = 0;
|
|
54
|
+
for (let i = 0; i < line.length; i++) {
|
|
55
|
+
if (col >= loc.column) {
|
|
56
|
+
return offset + i;
|
|
57
|
+
}
|
|
58
|
+
col += line[i] === '\t' ? RECAST_TAB_WIDTH : 1;
|
|
59
|
+
}
|
|
60
|
+
return offset + line.length;
|
|
61
|
+
};
|
|
40
62
|
const updateDefaultProps = async ({ input, compositionId, newDefaultProps, enumPaths, }) => {
|
|
41
63
|
const ast = (0, parse_ast_1.parseAst)(input);
|
|
64
|
+
const stringified = (0, studio_shared_1.stringifyDefaultProps)({
|
|
65
|
+
props: newDefaultProps,
|
|
66
|
+
enumPaths,
|
|
67
|
+
});
|
|
68
|
+
let replaceStart;
|
|
69
|
+
let replaceEnd;
|
|
42
70
|
recast.types.visit(ast, {
|
|
43
71
|
visitJSXElement(path) {
|
|
44
72
|
var _a, _b;
|
|
@@ -110,33 +138,34 @@ const updateDefaultProps = async ({ input, compositionId, newDefaultProps, enumP
|
|
|
110
138
|
defaultPropsValue.type !== 'TSAsExpression') {
|
|
111
139
|
throw new Error(`\`defaultProps\` prop must be a hardcoded value in the <Composition/> tag with the ID "${compositionId}".`);
|
|
112
140
|
}
|
|
113
|
-
|
|
141
|
+
// Capture source positions for direct string replacement
|
|
142
|
+
// instead of modifying the AST and serializing (avoids recast artifacts)
|
|
143
|
+
const valueLoc = defaultPropsAttr.value.loc;
|
|
144
|
+
if (!valueLoc) {
|
|
145
|
+
throw new Error('Could not determine source location of defaultProps');
|
|
146
|
+
}
|
|
147
|
+
replaceStart = recastLocToOffset(input, valueLoc.start);
|
|
148
|
+
replaceEnd = recastLocToOffset(input, valueLoc.end);
|
|
114
149
|
this.traverse(path); // Continue traversing the AST
|
|
115
150
|
},
|
|
116
151
|
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
prettier = await Promise.resolve().then(() => __importStar(require('prettier')));
|
|
120
|
-
}
|
|
121
|
-
catch (_a) {
|
|
122
|
-
throw new Error('Prettier cannot be found in the current project.');
|
|
123
|
-
}
|
|
124
|
-
const { format, resolveConfig, resolveConfigFile } = prettier;
|
|
125
|
-
const configFilePath = await resolveConfigFile();
|
|
126
|
-
if (!configFilePath) {
|
|
127
|
-
throw new Error('The Prettier config file was not found');
|
|
128
|
-
}
|
|
129
|
-
const prettierConfig = await resolveConfig(configFilePath);
|
|
130
|
-
if (!prettierConfig) {
|
|
131
|
-
throw new Error('The Prettier config file was not found. For this feature, the "prettier" package must be installed and a .prettierrc file must exist.');
|
|
152
|
+
if (replaceStart === undefined || replaceEnd === undefined) {
|
|
153
|
+
throw new Error(`Could not find defaultProps for composition "${compositionId}"`);
|
|
132
154
|
}
|
|
133
|
-
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
155
|
+
// linePrefix includes the JSX container opening brace
|
|
156
|
+
const lineStart = input.lastIndexOf('\n', replaceStart) + 1;
|
|
157
|
+
const linePrefix = input.substring(lineStart, replaceStart + 1);
|
|
158
|
+
const { formatted, didFormat } = await (0, format_inline_content_1.formatInlineContent)({
|
|
159
|
+
inlineContent: stringified,
|
|
160
|
+
linePrefix,
|
|
138
161
|
endOfLine: 'auto',
|
|
139
162
|
});
|
|
140
|
-
|
|
163
|
+
// Replace the JSX expression container in the original input
|
|
164
|
+
const output = input.substring(0, replaceStart) +
|
|
165
|
+
'{' +
|
|
166
|
+
formatted +
|
|
167
|
+
'}' +
|
|
168
|
+
input.substring(replaceEnd);
|
|
169
|
+
return { output, formatted: didFormat };
|
|
141
170
|
};
|
|
142
171
|
exports.updateDefaultProps = updateDefaultProps;
|
package/dist/file-watcher.d.ts
CHANGED
|
@@ -1,9 +1,26 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
export type FileChangeEvent = {
|
|
2
|
+
type: 'created';
|
|
3
|
+
content: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: 'deleted';
|
|
6
|
+
} | {
|
|
7
|
+
type: 'changed';
|
|
8
|
+
content: string;
|
|
8
9
|
};
|
|
10
|
+
type OnChange = (event: FileChangeEvent) => void;
|
|
11
|
+
export type FileWatcherRegistry = {
|
|
12
|
+
installFileWatcher: (options: {
|
|
13
|
+
file: string;
|
|
14
|
+
onChange: OnChange;
|
|
15
|
+
}) => {
|
|
16
|
+
exists: boolean;
|
|
17
|
+
unwatch: () => void;
|
|
18
|
+
};
|
|
19
|
+
writeFileAndNotifyFileWatchers: (file: string, content: string) => void;
|
|
20
|
+
};
|
|
21
|
+
export declare const createFileWatcherRegistry: () => FileWatcherRegistry;
|
|
22
|
+
export declare const setFileWatcherRegistry: (registry: FileWatcherRegistry) => () => void;
|
|
23
|
+
export declare const getFileWatcherRegistry: () => FileWatcherRegistry;
|
|
24
|
+
export declare const installFileWatcher: FileWatcherRegistry['installFileWatcher'];
|
|
25
|
+
export declare const writeFileAndNotifyFileWatchers: FileWatcherRegistry['writeFileAndNotifyFileWatchers'];
|
|
9
26
|
export {};
|
package/dist/file-watcher.js
CHANGED
|
@@ -1,40 +1,159 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
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
|
+
})();
|
|
5
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.installFileWatcher = void 0;
|
|
7
|
-
const node_fs_1 =
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
36
|
+
exports.writeFileAndNotifyFileWatchers = exports.installFileWatcher = exports.getFileWatcherRegistry = exports.setFileWatcherRegistry = exports.createFileWatcherRegistry = void 0;
|
|
37
|
+
const node_fs_1 = __importStar(require("node:fs"));
|
|
38
|
+
const createFileWatcherRegistry = () => {
|
|
39
|
+
const sharedWatchers = new Map();
|
|
40
|
+
const _installFileWatcher = ({ file, onChange, }) => {
|
|
41
|
+
const existing = sharedWatchers.get(file);
|
|
42
|
+
if (existing) {
|
|
43
|
+
existing.subscribers.add(onChange);
|
|
44
|
+
return {
|
|
45
|
+
exists: existing.existedBefore,
|
|
46
|
+
unwatch: () => {
|
|
47
|
+
existing.subscribers.delete(onChange);
|
|
48
|
+
if (existing.subscribers.size === 0) {
|
|
49
|
+
existing.unwatch();
|
|
50
|
+
sharedWatchers.delete(file);
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
};
|
|
17
54
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
55
|
+
const existedAtBeginning = node_fs_1.default.existsSync(file);
|
|
56
|
+
const shared = {
|
|
57
|
+
subscribers: new Set([onChange]),
|
|
58
|
+
existedBefore: existedAtBeginning,
|
|
59
|
+
lastKnownContent: null,
|
|
60
|
+
unwatch: () => {
|
|
61
|
+
node_fs_1.default.unwatchFile(file, listener);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
const listener = () => {
|
|
65
|
+
const existsNow = node_fs_1.default.existsSync(file);
|
|
66
|
+
let event = null;
|
|
67
|
+
if (!shared.existedBefore && existsNow) {
|
|
68
|
+
const content = (0, node_fs_1.readFileSync)(file, 'utf-8');
|
|
69
|
+
shared.existedBefore = true;
|
|
70
|
+
shared.lastKnownContent = content;
|
|
71
|
+
event = { type: 'created', content };
|
|
72
|
+
}
|
|
73
|
+
else if (shared.existedBefore && !existsNow) {
|
|
74
|
+
shared.existedBefore = false;
|
|
75
|
+
shared.lastKnownContent = null;
|
|
76
|
+
event = { type: 'deleted' };
|
|
77
|
+
}
|
|
78
|
+
else if (existsNow) {
|
|
79
|
+
if (typeof Deno !== 'undefined') {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const content = (0, node_fs_1.readFileSync)(file, 'utf-8');
|
|
83
|
+
if (shared.lastKnownContent !== null &&
|
|
84
|
+
content === shared.lastKnownContent) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
shared.lastKnownContent = content;
|
|
88
|
+
event = { type: 'changed', content };
|
|
89
|
+
}
|
|
90
|
+
if (!event) {
|
|
27
91
|
return;
|
|
28
92
|
}
|
|
29
|
-
|
|
93
|
+
for (const subscriber of shared.subscribers) {
|
|
94
|
+
subscriber(event);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
node_fs_1.default.watchFile(file, { interval: 100 }, listener);
|
|
98
|
+
sharedWatchers.set(file, shared);
|
|
99
|
+
return {
|
|
100
|
+
exists: existedAtBeginning,
|
|
101
|
+
unwatch: () => {
|
|
102
|
+
shared.subscribers.delete(onChange);
|
|
103
|
+
if (shared.subscribers.size === 0) {
|
|
104
|
+
shared.unwatch();
|
|
105
|
+
sharedWatchers.delete(file);
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const _writeFileAndNotifyFileWatchers = (file, content) => {
|
|
111
|
+
(0, node_fs_1.writeFileSync)(file, content);
|
|
112
|
+
const shared = sharedWatchers.get(file);
|
|
113
|
+
if (!shared) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
shared.lastKnownContent = content;
|
|
117
|
+
shared.existedBefore = true;
|
|
118
|
+
for (const subscriber of shared.subscribers) {
|
|
119
|
+
subscriber({ type: 'changed', content });
|
|
30
120
|
}
|
|
31
121
|
};
|
|
32
|
-
node_fs_1.default.watchFile(file, { interval: 100 }, listener);
|
|
33
122
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
node_fs_1.default.unwatchFile(file, listener);
|
|
37
|
-
},
|
|
123
|
+
installFileWatcher: _installFileWatcher,
|
|
124
|
+
writeFileAndNotifyFileWatchers: _writeFileAndNotifyFileWatchers,
|
|
38
125
|
};
|
|
39
126
|
};
|
|
127
|
+
exports.createFileWatcherRegistry = createFileWatcherRegistry;
|
|
128
|
+
let currentRegistry = null;
|
|
129
|
+
const setFileWatcherRegistry = (registry) => {
|
|
130
|
+
currentRegistry = registry;
|
|
131
|
+
return () => {
|
|
132
|
+
currentRegistry = null;
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
exports.setFileWatcherRegistry = setFileWatcherRegistry;
|
|
136
|
+
const getFileWatcherRegistry = () => {
|
|
137
|
+
if (!currentRegistry) {
|
|
138
|
+
throw new Error('File watcher registry not initialized');
|
|
139
|
+
}
|
|
140
|
+
return currentRegistry;
|
|
141
|
+
};
|
|
142
|
+
exports.getFileWatcherRegistry = getFileWatcherRegistry;
|
|
143
|
+
const installFileWatcher = (options) => {
|
|
144
|
+
if (!currentRegistry) {
|
|
145
|
+
return {
|
|
146
|
+
exists: false,
|
|
147
|
+
unwatch: () => { },
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return (0, exports.getFileWatcherRegistry)().installFileWatcher(options);
|
|
151
|
+
};
|
|
40
152
|
exports.installFileWatcher = installFileWatcher;
|
|
153
|
+
const writeFileAndNotifyFileWatchers = (file, content) => {
|
|
154
|
+
if (!currentRegistry) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
(0, exports.getFileWatcherRegistry)().writeFileAndNotifyFileWatchers(file, content);
|
|
158
|
+
};
|
|
159
|
+
exports.writeFileAndNotifyFileWatchers = writeFileAndNotifyFileWatchers;
|