Skip to content

Commit 313a645

Browse files
committed
feat(create-email): caching of fetch to fallback to when fetch fails
this is particularly useful for when the user doesn't have connectivity but has already used the starter once
1 parent 29d6bad commit 313a645

File tree

1 file changed

+61
-35
lines changed

1 file changed

+61
-35
lines changed

packages/create-email/src/index.js

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env node
22

3+
import os from 'node:os';
34
import path from 'node:path';
45
import { fileURLToPath } from 'node:url';
56
import { Command } from 'commander';
@@ -16,10 +17,27 @@ const packageJson = JSON.parse(
1617
);
1718

1819
const getLatestVersionOfTag = async (packageName, tag) => {
19-
const response = await fetch(
20-
`https://registry.npmjs.org/${packageName}/${tag}`,
20+
const cachePath = path.resolve(
21+
os.tmpdir(),
22+
`${packageName.replaceAll('/', '-')}-${tag}.json`,
2123
);
22-
const data = await response.json();
24+
let data;
25+
try {
26+
const response = await fetch(
27+
`https://registry.npmjs.org/${packageName}/${tag}`,
28+
);
29+
data = await response.json();
30+
await fse.writeFile(cachePath, JSON.stringify(data));
31+
} catch (exception) {
32+
if (fse.existsSync(cachePath)) {
33+
console.warn(
34+
`${logSymbols.warning} Failed to fetch the latest version from npm, using a cache`,
35+
);
36+
data = await fse.readJson(cachePath);
37+
} else {
38+
throw exception;
39+
}
40+
}
2341

2442
if (typeof data === 'string' && data.startsWith('version not found')) {
2543
console.error(`Tag ${tag} does not exist for ${packageName}.`);
@@ -61,38 +79,46 @@ const init = async (name, { tag }) => {
6179
fse.copySync(templatePath, resolvedProjectPath, {
6280
recursive: true,
6381
});
64-
const templatePackageJsonPath = path.resolve(
65-
resolvedProjectPath,
66-
'./package.json',
67-
);
68-
const templatePackageJson = fse.readFileSync(templatePackageJsonPath, 'utf8');
69-
fse.writeFileSync(
70-
templatePackageJsonPath,
71-
templatePackageJson
72-
.replace(
73-
'INSERT_COMPONENTS_VERSION',
74-
await getLatestVersionOfTag('@react-email/components', tag),
75-
)
76-
.replace(
77-
'INSERT_REACT_EMAIL_VERSION',
78-
await getLatestVersionOfTag('react-email', tag),
79-
),
80-
'utf8',
81-
);
82-
83-
spinner.stopAndPersist({
84-
symbol: logSymbols.success,
85-
text: 'React Email Starter files ready',
86-
});
87-
88-
// eslint-disable-next-line no-console
89-
console.info(
90-
await tree(resolvedProjectPath, 4, (dirent) => {
91-
return !path
92-
.join(dirent.parentPath, dirent.name)
93-
.includes('node_modules');
94-
}),
95-
);
82+
try {
83+
const templatePackageJsonPath = path.resolve(
84+
resolvedProjectPath,
85+
'./package.json',
86+
);
87+
const templatePackageJson = fse.readFileSync(
88+
templatePackageJsonPath,
89+
'utf8',
90+
);
91+
fse.writeFileSync(
92+
templatePackageJsonPath,
93+
templatePackageJson
94+
.replace(
95+
'INSERT_COMPONENTS_VERSION',
96+
await getLatestVersionOfTag('@react-email/components', tag),
97+
)
98+
.replace(
99+
'INSERT_REACT_EMAIL_VERSION',
100+
await getLatestVersionOfTag('react-email', tag),
101+
),
102+
'utf8',
103+
);
104+
105+
spinner.stopAndPersist({
106+
symbol: logSymbols.success,
107+
text: 'React Email Starter files ready',
108+
});
109+
110+
// eslint-disable-next-line no-console
111+
console.info(
112+
await tree(resolvedProjectPath, 4, (dirent) => {
113+
return !path
114+
.join(dirent.parentPath, dirent.name)
115+
.includes('node_modules');
116+
}),
117+
);
118+
} catch (exception) {
119+
fse.removeSync(resolvedProjectPath);
120+
throw exception;
121+
}
96122
};
97123

98124
new Command()

0 commit comments

Comments
 (0)