react-email 4.2.7 → 4.2.9
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/CHANGELOG.md +12 -0
- package/dist/index.js +22 -11
- package/package.json +2 -3
- package/src/utils/preview/hot-reloading/__snapshots__/create-dependency-graph.spec.ts.snap +68 -0
- package/src/utils/preview/hot-reloading/create-dependency-graph.spec.ts +116 -182
- package/src/utils/preview/hot-reloading/create-dependency-graph.ts +26 -8
- package/src/utils/preview/hot-reloading/test/dependency-graph/inner/data-to-import.json +1 -0
- package/src/utils/preview/hot-reloading/test/dependency-graph/inner/file-a.ts +5 -0
- package/src/utils/preview/hot-reloading/test/dependency-graph/inner/file-b.ts +5 -0
- package/src/utils/preview/hot-reloading/test/dependency-graph/inner/general-importing-file.ts +9 -0
- package/src/utils/preview/hot-reloading/test/dependency-graph/inner/outer-dependency.ts +3 -0
- package/src/utils/preview/hot-reloading/test/dependency-graph/outer.ts +5 -0
- package/src/utils/preview/start-dev-server.ts +4 -2
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -106,7 +106,7 @@ import prompts from "prompts";
|
|
|
106
106
|
// package.json
|
|
107
107
|
var package_default = {
|
|
108
108
|
name: "react-email",
|
|
109
|
-
version: "4.2.
|
|
109
|
+
version: "4.2.9",
|
|
110
110
|
description: "A live preview of your emails right in your browser.",
|
|
111
111
|
bin: {
|
|
112
112
|
email: "./dist/index.js"
|
|
@@ -135,7 +135,6 @@ var package_default = {
|
|
|
135
135
|
dependencies: {
|
|
136
136
|
"@babel/parser": "^7.27.0",
|
|
137
137
|
"@babel/traverse": "^7.27.0",
|
|
138
|
-
chalk: "^5.0.0",
|
|
139
138
|
chokidar: "^4.0.3",
|
|
140
139
|
commander: "^13.0.0",
|
|
141
140
|
debounce: "^2.0.0",
|
|
@@ -758,17 +757,27 @@ var createDependencyGraph = async (directory) => {
|
|
|
758
757
|
}
|
|
759
758
|
},
|
|
760
759
|
{
|
|
760
|
+
/**
|
|
761
|
+
* Resolves all modules that depend on the specified module, directly or indirectly.
|
|
762
|
+
*
|
|
763
|
+
* @param pathToModule - The path to the module whose dependents we want to find
|
|
764
|
+
* @returns An array of paths to all modules that depend on the specified module
|
|
765
|
+
*/
|
|
761
766
|
resolveDependentsOf: function resolveDependentsOf(pathToModule) {
|
|
762
|
-
const
|
|
763
|
-
const
|
|
764
|
-
|
|
767
|
+
const dependentPaths = /* @__PURE__ */ new Set();
|
|
768
|
+
const stack = [pathToModule];
|
|
769
|
+
while (stack.length > 0) {
|
|
770
|
+
const currentPath = stack.pop();
|
|
771
|
+
const moduleEntry = graph[currentPath];
|
|
772
|
+
if (!moduleEntry) continue;
|
|
765
773
|
for (const dependentPath of moduleEntry.dependentPaths) {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
dependentPaths.
|
|
774
|
+
if (dependentPaths.has(dependentPath) || dependentPath === pathToModule)
|
|
775
|
+
continue;
|
|
776
|
+
dependentPaths.add(dependentPath);
|
|
777
|
+
stack.push(dependentPath);
|
|
769
778
|
}
|
|
770
779
|
}
|
|
771
|
-
return dependentPaths;
|
|
780
|
+
return [...dependentPaths.values()];
|
|
772
781
|
}
|
|
773
782
|
}
|
|
774
783
|
];
|
|
@@ -861,7 +870,7 @@ var setupHotreloading = async (devServer2, emailDirRelativePath) => {
|
|
|
861
870
|
import http from "node:http";
|
|
862
871
|
import path9 from "node:path";
|
|
863
872
|
import url2 from "node:url";
|
|
864
|
-
import
|
|
873
|
+
import { styleText } from "node:util";
|
|
865
874
|
import { createJiti as createJiti2 } from "jiti";
|
|
866
875
|
import logSymbols3 from "log-symbols";
|
|
867
876
|
import ora2 from "ora";
|
|
@@ -970,7 +979,9 @@ var startDevServer = async (emailsDirRelativePath, staticBaseDirRelativePath, po
|
|
|
970
979
|
});
|
|
971
980
|
const { portAlreadyInUse } = await safeAsyncServerListen(devServer, port);
|
|
972
981
|
if (!portAlreadyInUse) {
|
|
973
|
-
console.log(
|
|
982
|
+
console.log(
|
|
983
|
+
styleText("greenBright", ` React Email ${package_default.version}`)
|
|
984
|
+
);
|
|
974
985
|
console.log(` Running preview at: http://localhost:${port}
|
|
975
986
|
`);
|
|
976
987
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-email",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.9",
|
|
4
4
|
"description": "A live preview of your emails right in your browser.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"email": "./dist/index.js"
|
|
@@ -22,7 +22,6 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@babel/parser": "^7.27.0",
|
|
24
24
|
"@babel/traverse": "^7.27.0",
|
|
25
|
-
"chalk": "^5.0.0",
|
|
26
25
|
"chokidar": "^4.0.3",
|
|
27
26
|
"commander": "^13.0.0",
|
|
28
27
|
"debounce": "^2.0.0",
|
|
@@ -48,7 +47,7 @@
|
|
|
48
47
|
"react-dom": "19.0.0",
|
|
49
48
|
"tsup": "8.4.0",
|
|
50
49
|
"typescript": "5.8.3",
|
|
51
|
-
"@react-email/components": "0.
|
|
50
|
+
"@react-email/components": "0.5.2"
|
|
52
51
|
},
|
|
53
52
|
"scripts": {
|
|
54
53
|
"build": "tsup-node",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`createDependencyGraph() > should have the right initial value for the dependency graph 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"../outer.ts": {
|
|
6
|
+
"dependencyPaths": [
|
|
7
|
+
"outer-dependency.ts",
|
|
8
|
+
],
|
|
9
|
+
"dependentPaths": [
|
|
10
|
+
"general-importing-file.ts",
|
|
11
|
+
],
|
|
12
|
+
"moduleDependencies": [],
|
|
13
|
+
"path": "../outer.ts",
|
|
14
|
+
},
|
|
15
|
+
"data-to-import.json": {
|
|
16
|
+
"dependencyPaths": [],
|
|
17
|
+
"dependentPaths": [
|
|
18
|
+
"general-importing-file.ts",
|
|
19
|
+
],
|
|
20
|
+
"moduleDependencies": [],
|
|
21
|
+
"path": "data-to-import.json",
|
|
22
|
+
},
|
|
23
|
+
"file-a.ts": {
|
|
24
|
+
"dependencyPaths": [
|
|
25
|
+
"file-b.ts",
|
|
26
|
+
],
|
|
27
|
+
"dependentPaths": [
|
|
28
|
+
"file-b.ts",
|
|
29
|
+
"general-importing-file.ts",
|
|
30
|
+
],
|
|
31
|
+
"moduleDependencies": [],
|
|
32
|
+
"path": "file-a.ts",
|
|
33
|
+
},
|
|
34
|
+
"file-b.ts": {
|
|
35
|
+
"dependencyPaths": [
|
|
36
|
+
"file-a.ts",
|
|
37
|
+
],
|
|
38
|
+
"dependentPaths": [
|
|
39
|
+
"file-a.ts",
|
|
40
|
+
"general-importing-file.ts",
|
|
41
|
+
],
|
|
42
|
+
"moduleDependencies": [],
|
|
43
|
+
"path": "file-b.ts",
|
|
44
|
+
},
|
|
45
|
+
"general-importing-file.ts": {
|
|
46
|
+
"dependencyPaths": [
|
|
47
|
+
"../outer.ts",
|
|
48
|
+
"data-to-import.json",
|
|
49
|
+
"file-a.ts",
|
|
50
|
+
"file-b.ts",
|
|
51
|
+
],
|
|
52
|
+
"dependentPaths": [],
|
|
53
|
+
"moduleDependencies": [
|
|
54
|
+
"node:os",
|
|
55
|
+
"node:path",
|
|
56
|
+
],
|
|
57
|
+
"path": "general-importing-file.ts",
|
|
58
|
+
},
|
|
59
|
+
"outer-dependency.ts": {
|
|
60
|
+
"dependencyPaths": [],
|
|
61
|
+
"dependentPaths": [
|
|
62
|
+
"../outer.ts",
|
|
63
|
+
],
|
|
64
|
+
"moduleDependencies": [],
|
|
65
|
+
"path": "outer-dependency.ts",
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
@@ -5,9 +5,11 @@ import {
|
|
|
5
5
|
type DependencyGraph,
|
|
6
6
|
} from './create-dependency-graph.js';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const testingDiretctory = path.join(__dirname, './test/dependency-graph/inner');
|
|
9
|
+
|
|
10
|
+
const pathToTemporaryFile = path.join(
|
|
11
|
+
testingDiretctory,
|
|
12
|
+
'./.temporary-file.ts',
|
|
11
13
|
);
|
|
12
14
|
|
|
13
15
|
vi.mock('@babel/traverse', async () => {
|
|
@@ -15,198 +17,130 @@ vi.mock('@babel/traverse', async () => {
|
|
|
15
17
|
return { default: traverse };
|
|
16
18
|
});
|
|
17
19
|
|
|
18
|
-
|
|
19
|
-
if (existsSync(
|
|
20
|
-
await fs.rm(
|
|
20
|
+
describe('createDependencyGraph()', async () => {
|
|
21
|
+
if (existsSync(pathToTemporaryFile)) {
|
|
22
|
+
await fs.rm(pathToTemporaryFile);
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
const [dependencyGraph, updateDependencyGraph] =
|
|
24
|
-
await createDependencyGraph(
|
|
25
|
+
const [dependencyGraph, updateDependencyGraph, { resolveDependentsOf }] =
|
|
26
|
+
await createDependencyGraph(testingDiretctory);
|
|
25
27
|
|
|
26
28
|
const toAbsolute = (relativePath: string) => {
|
|
27
|
-
return path.resolve(
|
|
29
|
+
return path.resolve(testingDiretctory, relativePath);
|
|
28
30
|
};
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
dependencyPaths: module.dependencyPaths.map((p) => toAbsolute(p)),
|
|
38
|
-
dependentPaths: module.dependentPaths.map((p) => toAbsolute(p)),
|
|
39
|
-
moduleDependencies: module.moduleDependencies,
|
|
40
|
-
},
|
|
41
|
-
];
|
|
42
|
-
}),
|
|
43
|
-
);
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const initialDependencyGraph = convertPathsToAbsolute({
|
|
47
|
-
'create-dependency-graph.ts': {
|
|
48
|
-
path: 'create-dependency-graph.ts',
|
|
49
|
-
dependencyPaths: ['get-imported-modules.ts', 'resolve-path-aliases.ts'],
|
|
50
|
-
dependentPaths: [
|
|
51
|
-
'create-dependency-graph.spec.ts',
|
|
52
|
-
'setup-hot-reloading.ts',
|
|
53
|
-
],
|
|
54
|
-
moduleDependencies: ['node:fs', 'node:path', 'chokidar/handler.js'],
|
|
55
|
-
},
|
|
56
|
-
'create-dependency-graph.spec.ts': {
|
|
57
|
-
path: 'create-dependency-graph.spec.ts',
|
|
58
|
-
dependencyPaths: ['create-dependency-graph.ts'],
|
|
59
|
-
dependentPaths: [],
|
|
60
|
-
moduleDependencies: ['node:fs', 'node:path'],
|
|
61
|
-
},
|
|
62
|
-
'./test/some-file.ts': {
|
|
63
|
-
dependencyPaths: [],
|
|
64
|
-
dependentPaths: [],
|
|
65
|
-
moduleDependencies: [],
|
|
66
|
-
path: '/home/gabriel/Projects/Resend/react-email/packages/react-email/src/cli/utils/preview/hot-reloading/test/some-file.ts',
|
|
32
|
+
it.sequential(
|
|
33
|
+
'should resolve dependents when there are circular dependencies',
|
|
34
|
+
async () => {
|
|
35
|
+
expect(resolveDependentsOf(toAbsolute('file-a.ts'))).toEqual([
|
|
36
|
+
toAbsolute('file-b.ts'),
|
|
37
|
+
toAbsolute('general-importing-file.ts'),
|
|
38
|
+
]);
|
|
67
39
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
it.sequential(
|
|
43
|
+
'should have the right initial value for the dependency graph',
|
|
44
|
+
() => {
|
|
45
|
+
const relativePathDependencyGraph = Object.fromEntries(
|
|
46
|
+
Object.entries(dependencyGraph).map(([key, value]) => {
|
|
47
|
+
return [
|
|
48
|
+
path.relative(testingDiretctory, key),
|
|
49
|
+
{
|
|
50
|
+
path: path.relative(testingDiretctory, value.path),
|
|
51
|
+
dependentPaths: value.dependentPaths.map((p) =>
|
|
52
|
+
path.relative(testingDiretctory, p),
|
|
53
|
+
),
|
|
54
|
+
dependencyPaths: value.dependencyPaths.map((p) =>
|
|
55
|
+
path.relative(testingDiretctory, p),
|
|
56
|
+
),
|
|
57
|
+
moduleDependencies: value.moduleDependencies,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}),
|
|
61
|
+
);
|
|
62
|
+
expect(relativePathDependencyGraph).toMatchSnapshot();
|
|
91
63
|
},
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
it.sequential('should work when adding a new file', async () => {
|
|
67
|
+
await fs.writeFile(
|
|
68
|
+
pathToTemporaryFile,
|
|
69
|
+
`
|
|
70
|
+
import {} from './file-a';
|
|
71
|
+
import {} from './file-b';
|
|
72
|
+
import {} from './general-importing-file';
|
|
73
|
+
`,
|
|
74
|
+
'utf8',
|
|
75
|
+
);
|
|
76
|
+
await updateDependencyGraph('add', pathToTemporaryFile);
|
|
77
|
+
expect(dependencyGraph[pathToTemporaryFile]).toEqual({
|
|
78
|
+
path: pathToTemporaryFile,
|
|
95
79
|
dependentPaths: [],
|
|
96
|
-
moduleDependencies: ['node:fs'],
|
|
97
|
-
},
|
|
98
|
-
'setup-hot-reloading.ts': {
|
|
99
|
-
path: 'setup-hot-reloading.ts',
|
|
100
80
|
dependencyPaths: [
|
|
101
|
-
'
|
|
102
|
-
'
|
|
81
|
+
toAbsolute('file-a.ts'),
|
|
82
|
+
toAbsolute('file-b.ts'),
|
|
83
|
+
toAbsolute('general-importing-file.ts'),
|
|
103
84
|
],
|
|
104
|
-
dependentPaths: [],
|
|
105
|
-
moduleDependencies: [
|
|
106
|
-
'node:http',
|
|
107
|
-
'node:path',
|
|
108
|
-
'chokidar',
|
|
109
|
-
'debounce',
|
|
110
|
-
'socket.io',
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
'../../types/hot-reload-event.ts': {
|
|
114
|
-
dependencyPaths: [],
|
|
115
|
-
dependentPaths: ['../../types/hot-reload-change.ts'],
|
|
116
|
-
moduleDependencies: ['chokidar/handler.js'],
|
|
117
|
-
path: '../../types/hot-reload-event.ts',
|
|
118
|
-
},
|
|
119
|
-
'../../types/hot-reload-change.ts': {
|
|
120
|
-
path: '../../types/hot-reload-change.ts',
|
|
121
|
-
dependencyPaths: ['../../types/hot-reload-event.ts'],
|
|
122
|
-
dependentPaths: ['setup-hot-reloading.ts'],
|
|
123
85
|
moduleDependencies: [],
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
dependencyGraph
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
import {} from './setup-hot-reloading';
|
|
136
|
-
import {} from './get-imported-modules';
|
|
137
|
-
import {} from './create-dependency-graph.ts';
|
|
138
|
-
`,
|
|
139
|
-
'utf8',
|
|
140
|
-
);
|
|
141
|
-
await updateDependencyGraph('add', pathToFileForTestingDependencyGraph);
|
|
142
|
-
expect(
|
|
143
|
-
dependencyGraph[pathToFileForTestingDependencyGraph],
|
|
144
|
-
'added file to have proper dependency paths',
|
|
145
|
-
).toEqual({
|
|
146
|
-
path: pathToFileForTestingDependencyGraph,
|
|
147
|
-
dependentPaths: [],
|
|
148
|
-
dependencyPaths: [
|
|
149
|
-
toAbsolute('setup-hot-reloading.ts'),
|
|
150
|
-
toAbsolute('get-imported-modules.ts'),
|
|
151
|
-
toAbsolute('create-dependency-graph.ts'),
|
|
152
|
-
],
|
|
153
|
-
moduleDependencies: [],
|
|
154
|
-
} satisfies DependencyGraph[number]);
|
|
155
|
-
expect(
|
|
156
|
-
dependencyGraph[toAbsolute('setup-hot-reloading.ts')]?.dependentPaths,
|
|
157
|
-
).toContain(pathToFileForTestingDependencyGraph);
|
|
158
|
-
expect(
|
|
159
|
-
dependencyGraph[toAbsolute('get-imported-modules.ts')]?.dependentPaths,
|
|
160
|
-
).toContain(pathToFileForTestingDependencyGraph);
|
|
161
|
-
expect(
|
|
162
|
-
dependencyGraph[toAbsolute('create-dependency-graph.ts')]?.dependentPaths,
|
|
163
|
-
).toContain(pathToFileForTestingDependencyGraph);
|
|
86
|
+
} satisfies DependencyGraph[number]);
|
|
87
|
+
expect(dependencyGraph[toAbsolute('file-a.ts')]?.dependentPaths).toContain(
|
|
88
|
+
pathToTemporaryFile,
|
|
89
|
+
);
|
|
90
|
+
expect(dependencyGraph[toAbsolute('file-b.ts')]?.dependentPaths).toContain(
|
|
91
|
+
pathToTemporaryFile,
|
|
92
|
+
);
|
|
93
|
+
expect(
|
|
94
|
+
dependencyGraph[toAbsolute('general-importing-file.ts')]?.dependentPaths,
|
|
95
|
+
).toContain(pathToTemporaryFile);
|
|
96
|
+
});
|
|
164
97
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
import {} from './
|
|
98
|
+
it.sequential('should work when updating a file', async () => {
|
|
99
|
+
await fs.writeFile(
|
|
100
|
+
pathToTemporaryFile,
|
|
101
|
+
`
|
|
102
|
+
import {} from './file-a';
|
|
103
|
+
import {} from './file-b';
|
|
170
104
|
`,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
]
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
dependencyGraph[toAbsolute('create-dependency-graph.ts')]?.dependentPaths,
|
|
195
|
-
).toContain(pathToFileForTestingDependencyGraph);
|
|
105
|
+
'utf8',
|
|
106
|
+
);
|
|
107
|
+
await updateDependencyGraph('change', pathToTemporaryFile);
|
|
108
|
+
expect(
|
|
109
|
+
dependencyGraph[pathToTemporaryFile],
|
|
110
|
+
'changed file to have updated dependencyPaths',
|
|
111
|
+
).toEqual({
|
|
112
|
+
path: pathToTemporaryFile,
|
|
113
|
+
dependentPaths: [],
|
|
114
|
+
dependencyPaths: [toAbsolute('file-a.ts'), toAbsolute('file-b.ts')],
|
|
115
|
+
moduleDependencies: [],
|
|
116
|
+
} satisfies DependencyGraph[number]);
|
|
117
|
+
expect(dependencyGraph[toAbsolute('file-a.ts')]?.dependentPaths).toContain(
|
|
118
|
+
pathToTemporaryFile,
|
|
119
|
+
);
|
|
120
|
+
expect(dependencyGraph[toAbsolute('file-b.ts')]?.dependentPaths).toContain(
|
|
121
|
+
pathToTemporaryFile,
|
|
122
|
+
);
|
|
123
|
+
expect(
|
|
124
|
+
dependencyGraph[toAbsolute('general-importing-file.ts')]?.dependentPaths,
|
|
125
|
+
'when removing dependency on a file, the dependency should have its dependents updated to not have the testing file again',
|
|
126
|
+
).not.toContain(pathToTemporaryFile);
|
|
127
|
+
});
|
|
196
128
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
129
|
+
it.sequential('should work when unlinking a file', async () => {
|
|
130
|
+
await fs.rm(pathToTemporaryFile);
|
|
131
|
+
await updateDependencyGraph('unlink', pathToTemporaryFile);
|
|
132
|
+
expect(dependencyGraph[pathToTemporaryFile]).toBeUndefined();
|
|
133
|
+
expect(
|
|
134
|
+
dependencyGraph[toAbsolute('file-a.ts')]?.dependentPaths,
|
|
135
|
+
"should remove itself from dependents once it's unlinked",
|
|
136
|
+
).not.toContain(pathToTemporaryFile);
|
|
137
|
+
expect(
|
|
138
|
+
dependencyGraph[toAbsolute('file-b.ts')]?.dependentPaths,
|
|
139
|
+
"should remove itself from dependents once it's unlinked",
|
|
140
|
+
).not.toContain(pathToTemporaryFile);
|
|
141
|
+
expect(
|
|
142
|
+
dependencyGraph[toAbsolute('general-importing-file.ts')]?.dependentPaths,
|
|
143
|
+
"should remove itself from dependents once it's unlinked",
|
|
144
|
+
).not.toContain(pathToTemporaryFile);
|
|
145
|
+
});
|
|
212
146
|
});
|
|
@@ -306,19 +306,37 @@ export const createDependencyGraph = async (directory: string) => {
|
|
|
306
306
|
}
|
|
307
307
|
},
|
|
308
308
|
{
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
/**
|
|
310
|
+
* Resolves all modules that depend on the specified module, directly or indirectly.
|
|
311
|
+
*
|
|
312
|
+
* @param pathToModule - The path to the module whose dependents we want to find
|
|
313
|
+
* @returns An array of paths to all modules that depend on the specified module
|
|
314
|
+
*/
|
|
315
|
+
resolveDependentsOf: function resolveDependentsOf(
|
|
316
|
+
pathToModule: string,
|
|
317
|
+
): string[] {
|
|
318
|
+
const dependentPaths = new Set<string>();
|
|
319
|
+
const stack: string[] = [pathToModule];
|
|
320
|
+
|
|
321
|
+
while (stack.length > 0) {
|
|
322
|
+
const currentPath = stack.pop()!;
|
|
323
|
+
const moduleEntry = graph[currentPath];
|
|
324
|
+
|
|
325
|
+
if (!moduleEntry) continue;
|
|
312
326
|
|
|
313
|
-
if (moduleEntry) {
|
|
314
327
|
for (const dependentPath of moduleEntry.dependentPaths) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
328
|
+
if (
|
|
329
|
+
dependentPaths.has(dependentPath) ||
|
|
330
|
+
dependentPath === pathToModule
|
|
331
|
+
)
|
|
332
|
+
continue;
|
|
333
|
+
|
|
334
|
+
dependentPaths.add(dependentPath);
|
|
335
|
+
stack.push(dependentPath);
|
|
318
336
|
}
|
|
319
337
|
}
|
|
320
338
|
|
|
321
|
-
return dependentPaths;
|
|
339
|
+
return [...dependentPaths.values()];
|
|
322
340
|
},
|
|
323
341
|
},
|
|
324
342
|
] as const;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** biome-ignore-all lint/correctness/noUnusedImports: used in testing */
|
|
2
|
+
/** biome-ignore-all lint/complexity/noUselessEmptyExport: used in testing */
|
|
3
|
+
|
|
4
|
+
import _os from 'node:os';
|
|
5
|
+
import _path from 'node:path';
|
|
6
|
+
import * as _outer from '../outer';
|
|
7
|
+
import _json from './data-to-import.json';
|
|
8
|
+
import * as _a from './file-a';
|
|
9
|
+
import * as _b from './file-b';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import http from 'node:http';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import url from 'node:url';
|
|
4
|
-
import
|
|
4
|
+
import { styleText } from 'node:util';
|
|
5
5
|
import { createJiti } from 'jiti';
|
|
6
6
|
import logSymbols from 'log-symbols';
|
|
7
7
|
import ora from 'ora';
|
|
@@ -85,7 +85,9 @@ export const startDevServer = async (
|
|
|
85
85
|
if (!portAlreadyInUse) {
|
|
86
86
|
// this errors when linting but doesn't on the editor so ignore the warning on this
|
|
87
87
|
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access */
|
|
88
|
-
console.log(
|
|
88
|
+
console.log(
|
|
89
|
+
styleText('greenBright', ` React Email ${packageJson.version}`),
|
|
90
|
+
);
|
|
89
91
|
console.log(` Running preview at: http://localhost:${port}\n`);
|
|
90
92
|
} else {
|
|
91
93
|
const nextPortToTry = port + 1;
|