create-docusaurus 3.1.0 → 3.2.0
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/README.md +2 -2
- package/bin/index.js +1 -0
- package/lib/index.d.ts +5 -2
- package/lib/index.js +149 -125
- package/package.json +4 -4
- package/templates/classic/package.json +5 -5
- package/templates/classic-typescript/package.json +6 -6
- package/templates/shared/docs/tutorial-basics/create-a-blog-post.md +1 -1
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ For Docusaurus maintainers, templates can be tested with:
|
|
|
25
25
|
```bash
|
|
26
26
|
cd `git rev-parse --show-toplevel` # Back to repo root
|
|
27
27
|
rm -rf test-website
|
|
28
|
-
yarn create-docusaurus test-website classic
|
|
28
|
+
yarn create-docusaurus test-website classic --javascript
|
|
29
29
|
cd test-website
|
|
30
30
|
yarn start
|
|
31
31
|
```
|
|
@@ -37,7 +37,7 @@ Use the following to test the templates against local packages:
|
|
|
37
37
|
```bash
|
|
38
38
|
cd `git rev-parse --show-toplevel` # Back to repo root
|
|
39
39
|
rm -rf test-website-in-workspace
|
|
40
|
-
yarn create-docusaurus test-website-in-workspace classic
|
|
40
|
+
yarn create-docusaurus test-website-in-workspace classic --javascript
|
|
41
41
|
cd test-website-in-workspace
|
|
42
42
|
yarn build
|
|
43
43
|
yarn start
|
package/bin/index.js
CHANGED
|
@@ -38,6 +38,7 @@ program
|
|
|
38
38
|
'Do not run package manager immediately after scaffolding',
|
|
39
39
|
)
|
|
40
40
|
.option('-t, --typescript', 'Use the TypeScript template variant')
|
|
41
|
+
.option('-j, --javascript', 'Use the JavaScript template variant')
|
|
41
42
|
.option(
|
|
42
43
|
'-g, --git-strategy <strategy>',
|
|
43
44
|
`Only used if the template is a git repository.
|
package/lib/index.d.ts
CHANGED
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
* This source code is licensed under the MIT license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
type
|
|
7
|
+
type LanguagesOptions = {
|
|
8
|
+
javascript?: boolean;
|
|
9
|
+
typescript?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type CLIOptions = LanguagesOptions & {
|
|
8
12
|
packageManager?: PackageManager;
|
|
9
13
|
skipInstall?: boolean;
|
|
10
|
-
typescript?: boolean;
|
|
11
14
|
gitStrategy?: GitStrategy;
|
|
12
15
|
};
|
|
13
16
|
declare const lockfileNames: {
|
package/lib/index.js
CHANGED
|
@@ -12,7 +12,16 @@ import logger from '@docusaurus/logger';
|
|
|
12
12
|
import shell from 'shelljs';
|
|
13
13
|
import prompts from 'prompts';
|
|
14
14
|
import supportsColor from 'supports-color';
|
|
15
|
-
import { escapeShellArg } from '@docusaurus/utils';
|
|
15
|
+
import { escapeShellArg, askPreferredLanguage } from '@docusaurus/utils';
|
|
16
|
+
async function getLanguage(options) {
|
|
17
|
+
if (options.typescript) {
|
|
18
|
+
return 'typescript';
|
|
19
|
+
}
|
|
20
|
+
if (options.javascript) {
|
|
21
|
+
return 'javascript';
|
|
22
|
+
}
|
|
23
|
+
return askPreferredLanguage();
|
|
24
|
+
}
|
|
16
25
|
// Only used in the rare, rare case of running globally installed create +
|
|
17
26
|
// using --skip-install. We need a default name to show the tip text
|
|
18
27
|
const defaultPackageManager = 'npm';
|
|
@@ -93,9 +102,10 @@ async function readTemplates() {
|
|
|
93
102
|
// Classic should be first in list!
|
|
94
103
|
return _.sortBy(templates, (t) => t.name !== recommendedTemplate);
|
|
95
104
|
}
|
|
96
|
-
async function copyTemplate(template, dest,
|
|
105
|
+
async function copyTemplate(template, dest, language) {
|
|
97
106
|
await fs.copy(path.join(templatesDir, 'shared'), dest);
|
|
98
|
-
|
|
107
|
+
const sourcePath = language === 'typescript' ? template.tsVariantPath : template.path;
|
|
108
|
+
await fs.copy(sourcePath, dest, {
|
|
99
109
|
// Symlinks don't exist in published npm packages anymore, so this is only
|
|
100
110
|
// to prevent errors during local testing
|
|
101
111
|
filter: async (filePath) => !(await fs.lstat(filePath)).isSymbolicLink(),
|
|
@@ -117,6 +127,21 @@ function createTemplateChoices(templates) {
|
|
|
117
127
|
makeNameAndValueChoice('Local template'),
|
|
118
128
|
];
|
|
119
129
|
}
|
|
130
|
+
async function askTemplateChoice({ templates, cliOptions, }) {
|
|
131
|
+
return cliOptions.gitStrategy
|
|
132
|
+
? 'Git repository'
|
|
133
|
+
: (await prompts({
|
|
134
|
+
type: 'select',
|
|
135
|
+
name: 'template',
|
|
136
|
+
message: 'Select a template below...',
|
|
137
|
+
choices: createTemplateChoices(templates),
|
|
138
|
+
}, {
|
|
139
|
+
onCancel() {
|
|
140
|
+
logger.error('A choice is required.');
|
|
141
|
+
process.exit(1);
|
|
142
|
+
},
|
|
143
|
+
})).template;
|
|
144
|
+
}
|
|
120
145
|
function isValidGitRepoUrl(gitRepoUrl) {
|
|
121
146
|
return ['https://', 'git@'].some((item) => gitRepoUrl.startsWith(item));
|
|
122
147
|
}
|
|
@@ -175,143 +200,142 @@ async function getSiteName(reqName, rootDir) {
|
|
|
175
200
|
}));
|
|
176
201
|
return siteName;
|
|
177
202
|
}
|
|
178
|
-
async function
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
logger.error `Template name=${reqTemplate} doesn't provide the TypeScript variant.`;
|
|
203
|
+
async function createTemplateSource({ template, cliOptions, }) {
|
|
204
|
+
const language = await getLanguage(cliOptions);
|
|
205
|
+
if (language === 'typescript' && !template.tsVariantPath) {
|
|
206
|
+
logger.error `Template name=${template.name} doesn't provide a TypeScript variant.`;
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
type: 'template',
|
|
211
|
+
template,
|
|
212
|
+
language,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async function getTemplateSource({ templateName, templates, cliOptions, }) {
|
|
216
|
+
const template = templates.find((t) => t.name === templateName);
|
|
217
|
+
if (!template) {
|
|
218
|
+
logger.error('Invalid template.');
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
return createTemplateSource({ template, cliOptions });
|
|
222
|
+
}
|
|
223
|
+
// Get the template source explicitly requested by the user provided cli option
|
|
224
|
+
async function getUserProvidedSource({ reqTemplate, templates, cliOptions, }) {
|
|
225
|
+
if (isValidGitRepoUrl(reqTemplate)) {
|
|
226
|
+
if (cliOptions.gitStrategy &&
|
|
227
|
+
!gitStrategies.includes(cliOptions.gitStrategy)) {
|
|
228
|
+
logger.error `Invalid git strategy: name=${cliOptions.gitStrategy}. Value must be one of ${gitStrategies.join(', ')}.`;
|
|
205
229
|
process.exit(1);
|
|
206
230
|
}
|
|
207
231
|
return {
|
|
208
|
-
type: '
|
|
209
|
-
|
|
210
|
-
|
|
232
|
+
type: 'git',
|
|
233
|
+
url: reqTemplate,
|
|
234
|
+
strategy: cliOptions.gitStrategy ?? 'deep',
|
|
211
235
|
};
|
|
212
236
|
}
|
|
213
|
-
|
|
214
|
-
? 'Git repository'
|
|
215
|
-
: (await prompts({
|
|
216
|
-
type: 'select',
|
|
217
|
-
name: 'template',
|
|
218
|
-
message: 'Select a template below...',
|
|
219
|
-
choices: createTemplateChoices(templates),
|
|
220
|
-
}, {
|
|
221
|
-
onCancel() {
|
|
222
|
-
logger.error('A choice is required.');
|
|
223
|
-
process.exit(1);
|
|
224
|
-
},
|
|
225
|
-
})).template;
|
|
226
|
-
if (template === 'Git repository') {
|
|
227
|
-
const { gitRepoUrl } = (await prompts({
|
|
228
|
-
type: 'text',
|
|
229
|
-
name: 'gitRepoUrl',
|
|
230
|
-
validate: (url) => {
|
|
231
|
-
if (url && isValidGitRepoUrl(url)) {
|
|
232
|
-
return true;
|
|
233
|
-
}
|
|
234
|
-
return logger.red('Invalid repository URL');
|
|
235
|
-
},
|
|
236
|
-
message: logger.interpolate `Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
|
|
237
|
-
(e.g: url=${'https://github.com/ownerName/repoName.git'})`,
|
|
238
|
-
}, {
|
|
239
|
-
onCancel() {
|
|
240
|
-
logger.error('A git repo URL is required.');
|
|
241
|
-
process.exit(1);
|
|
242
|
-
},
|
|
243
|
-
}));
|
|
244
|
-
let strategy = cliOptions.gitStrategy;
|
|
245
|
-
if (!strategy) {
|
|
246
|
-
({ strategy } = (await prompts({
|
|
247
|
-
type: 'select',
|
|
248
|
-
name: 'strategy',
|
|
249
|
-
message: 'How should we clone this repo?',
|
|
250
|
-
choices: [
|
|
251
|
-
{ title: 'Deep clone: preserve full history', value: 'deep' },
|
|
252
|
-
{ title: 'Shallow clone: clone with --depth=1', value: 'shallow' },
|
|
253
|
-
{
|
|
254
|
-
title: 'Copy: do a shallow clone, but do not create a git repo',
|
|
255
|
-
value: 'copy',
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
title: 'Custom: enter your custom git clone command',
|
|
259
|
-
value: 'custom',
|
|
260
|
-
},
|
|
261
|
-
],
|
|
262
|
-
}, {
|
|
263
|
-
onCancel() {
|
|
264
|
-
logger.info `Falling back to name=${'deep'}`;
|
|
265
|
-
},
|
|
266
|
-
})));
|
|
267
|
-
}
|
|
237
|
+
if (await fs.pathExists(path.resolve(reqTemplate))) {
|
|
268
238
|
return {
|
|
269
|
-
type: '
|
|
270
|
-
|
|
271
|
-
strategy: strategy ?? 'deep',
|
|
239
|
+
type: 'local',
|
|
240
|
+
path: path.resolve(reqTemplate),
|
|
272
241
|
};
|
|
273
242
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
return
|
|
287
|
-
}
|
|
288
|
-
|
|
243
|
+
return getTemplateSource({
|
|
244
|
+
templateName: reqTemplate,
|
|
245
|
+
templates,
|
|
246
|
+
cliOptions,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
async function askGitRepositorySource({ cliOptions, }) {
|
|
250
|
+
const { gitRepoUrl } = (await prompts({
|
|
251
|
+
type: 'text',
|
|
252
|
+
name: 'gitRepoUrl',
|
|
253
|
+
validate: (url) => {
|
|
254
|
+
if (url && isValidGitRepoUrl(url)) {
|
|
255
|
+
return true;
|
|
256
|
+
}
|
|
257
|
+
return logger.red('Invalid repository URL');
|
|
258
|
+
},
|
|
259
|
+
message: logger.interpolate `Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
|
|
260
|
+
(e.g: url=${'https://github.com/ownerName/repoName.git'})`,
|
|
261
|
+
}, {
|
|
262
|
+
onCancel() {
|
|
263
|
+
logger.error('A git repo URL is required.');
|
|
264
|
+
process.exit(1);
|
|
265
|
+
},
|
|
266
|
+
}));
|
|
267
|
+
let strategy = cliOptions.gitStrategy;
|
|
268
|
+
if (!strategy) {
|
|
269
|
+
({ strategy } = (await prompts({
|
|
270
|
+
type: 'select',
|
|
271
|
+
name: 'strategy',
|
|
272
|
+
message: 'How should we clone this repo?',
|
|
273
|
+
choices: [
|
|
274
|
+
{ title: 'Deep clone: preserve full history', value: 'deep' },
|
|
275
|
+
{ title: 'Shallow clone: clone with --depth=1', value: 'shallow' },
|
|
276
|
+
{
|
|
277
|
+
title: 'Copy: do a shallow clone, but do not create a git repo',
|
|
278
|
+
value: 'copy',
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
title: 'Custom: enter your custom git clone command',
|
|
282
|
+
value: 'custom',
|
|
283
|
+
},
|
|
284
|
+
],
|
|
289
285
|
}, {
|
|
290
286
|
onCancel() {
|
|
291
|
-
logger.
|
|
292
|
-
process.exit(1);
|
|
287
|
+
logger.info `Falling back to name=${'deep'}`;
|
|
293
288
|
},
|
|
294
|
-
}));
|
|
295
|
-
return {
|
|
296
|
-
type: 'local',
|
|
297
|
-
path: templateDir,
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
let useTS = cliOptions.typescript;
|
|
301
|
-
if (!useTS && template.tsVariantPath) {
|
|
302
|
-
({ useTS } = (await prompts({
|
|
303
|
-
type: 'confirm',
|
|
304
|
-
name: 'useTS',
|
|
305
|
-
message: 'This template is available in TypeScript. Do you want to use the TS variant?',
|
|
306
|
-
initial: false,
|
|
307
289
|
})));
|
|
308
290
|
}
|
|
309
291
|
return {
|
|
310
|
-
type: '
|
|
311
|
-
|
|
312
|
-
|
|
292
|
+
type: 'git',
|
|
293
|
+
url: gitRepoUrl,
|
|
294
|
+
strategy: strategy ?? 'deep',
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
async function askLocalSource() {
|
|
298
|
+
const { templateDir } = (await prompts({
|
|
299
|
+
type: 'text',
|
|
300
|
+
name: 'templateDir',
|
|
301
|
+
validate: async (dir) => {
|
|
302
|
+
if (dir) {
|
|
303
|
+
const fullDir = path.resolve(dir);
|
|
304
|
+
if (await fs.pathExists(fullDir)) {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
return logger.red(logger.interpolate `path=${fullDir} does not exist.`);
|
|
308
|
+
}
|
|
309
|
+
return logger.red('Please enter a valid path.');
|
|
310
|
+
},
|
|
311
|
+
message: 'Enter a local folder path, relative to the current working directory.',
|
|
312
|
+
}, {
|
|
313
|
+
onCancel() {
|
|
314
|
+
logger.error('A file path is required.');
|
|
315
|
+
process.exit(1);
|
|
316
|
+
},
|
|
317
|
+
}));
|
|
318
|
+
return {
|
|
319
|
+
type: 'local',
|
|
320
|
+
path: templateDir,
|
|
313
321
|
};
|
|
314
322
|
}
|
|
323
|
+
async function getSource(reqTemplate, templates, cliOptions) {
|
|
324
|
+
if (reqTemplate) {
|
|
325
|
+
return getUserProvidedSource({ reqTemplate, templates, cliOptions });
|
|
326
|
+
}
|
|
327
|
+
const template = await askTemplateChoice({ templates, cliOptions });
|
|
328
|
+
if (template === 'Git repository') {
|
|
329
|
+
return askGitRepositorySource({ cliOptions });
|
|
330
|
+
}
|
|
331
|
+
if (template === 'Local template') {
|
|
332
|
+
return askLocalSource();
|
|
333
|
+
}
|
|
334
|
+
return createTemplateSource({
|
|
335
|
+
template,
|
|
336
|
+
cliOptions,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
315
339
|
async function updatePkg(pkgPath, obj) {
|
|
316
340
|
const pkg = (await fs.readJSON(pkgPath));
|
|
317
341
|
const newPkg = Object.assign(pkg, obj);
|
|
@@ -338,7 +362,7 @@ export default async function init(rootDir, reqName, reqTemplate, cliOptions = {
|
|
|
338
362
|
}
|
|
339
363
|
else if (source.type === 'template') {
|
|
340
364
|
try {
|
|
341
|
-
await copyTemplate(source.template, dest, source.
|
|
365
|
+
await copyTemplate(source.template, dest, source.language);
|
|
342
366
|
}
|
|
343
367
|
catch (err) {
|
|
344
368
|
logger.error `Copying Docusaurus template name=${source.template.name} failed!`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-docusaurus",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"description": "Create Docusaurus apps easily.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"license": "MIT",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@docusaurus/logger": "3.
|
|
26
|
-
"@docusaurus/utils": "3.
|
|
25
|
+
"@docusaurus/logger": "3.2.0",
|
|
26
|
+
"@docusaurus/utils": "3.2.0",
|
|
27
27
|
"commander": "^5.1.0",
|
|
28
28
|
"fs-extra": "^11.1.1",
|
|
29
29
|
"lodash": "^4.17.21",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"engines": {
|
|
40
40
|
"node": ">=18.0"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "5af143651b26b39761361acd96e9c5be7ba0cb25"
|
|
43
43
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-2-classic-template",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"docusaurus": "docusaurus",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"write-heading-ids": "docusaurus write-heading-ids"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@docusaurus/core": "3.
|
|
18
|
-
"@docusaurus/preset-classic": "3.
|
|
17
|
+
"@docusaurus/core": "3.2.0",
|
|
18
|
+
"@docusaurus/preset-classic": "3.2.0",
|
|
19
19
|
"@mdx-js/react": "^3.0.0",
|
|
20
20
|
"clsx": "^2.0.0",
|
|
21
21
|
"prism-react-renderer": "^2.3.0",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"react-dom": "^18.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@docusaurus/module-type-aliases": "3.
|
|
27
|
-
"@docusaurus/types": "3.
|
|
26
|
+
"@docusaurus/module-type-aliases": "3.2.0",
|
|
27
|
+
"@docusaurus/types": "3.2.0"
|
|
28
28
|
},
|
|
29
29
|
"browserslist": {
|
|
30
30
|
"production": [
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-2-classic-typescript-template",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"docusaurus": "docusaurus",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"typecheck": "tsc"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@docusaurus/core": "3.
|
|
19
|
-
"@docusaurus/preset-classic": "3.
|
|
18
|
+
"@docusaurus/core": "3.2.0",
|
|
19
|
+
"@docusaurus/preset-classic": "3.2.0",
|
|
20
20
|
"@mdx-js/react": "^3.0.0",
|
|
21
21
|
"clsx": "^2.0.0",
|
|
22
22
|
"prism-react-renderer": "^2.3.0",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"react-dom": "^18.0.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@docusaurus/module-type-aliases": "3.
|
|
28
|
-
"@docusaurus/tsconfig": "3.
|
|
29
|
-
"@docusaurus/types": "3.
|
|
27
|
+
"@docusaurus/module-type-aliases": "3.2.0",
|
|
28
|
+
"@docusaurus/tsconfig": "3.2.0",
|
|
29
|
+
"@docusaurus/types": "3.2.0",
|
|
30
30
|
"typescript": "~5.2.2"
|
|
31
31
|
},
|
|
32
32
|
"browserslist": {
|
|
@@ -28,7 +28,7 @@ tags: [greetings]
|
|
|
28
28
|
|
|
29
29
|
Congratulations, you have made your first post!
|
|
30
30
|
|
|
31
|
-
Feel free to play around and edit this post as much you like.
|
|
31
|
+
Feel free to play around and edit this post as much as you like.
|
|
32
32
|
```
|
|
33
33
|
|
|
34
34
|
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|