create-docusaurus 2.0.0-beta.9 → 2.0.1
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/bin/index.js +43 -41
- package/lib/index.d.ts +16 -5
- package/lib/index.js +348 -156
- package/package.json +18 -18
- package/templates/classic/docusaurus.config.js +17 -3
- package/templates/classic/package.json +14 -11
- package/templates/classic/src/components/{HomepageFeatures.js → HomepageFeatures/index.js} +5 -5
- package/templates/classic/src/components/{HomepageFeatures.module.css → HomepageFeatures/styles.module.css} +0 -0
- package/templates/classic/src/css/custom.css +18 -16
- package/templates/classic/src/pages/index.js +3 -2
- package/templates/classic/src/pages/index.module.css +1 -1
- package/templates/classic-typescript/package.json +14 -14
- package/templates/classic-typescript/src/components/{HomepageFeatures.tsx → HomepageFeatures/index.tsx} +7 -13
- package/templates/classic-typescript/src/pages/index.tsx +3 -2
- package/templates/facebook/.eslintrc.js +10 -4
- package/templates/facebook/.prettierrc +1 -1
- package/templates/facebook/.stylelintrc.js +1 -1
- package/templates/facebook/README.md +9 -1
- package/templates/facebook/babel.config.js +1 -1
- package/templates/facebook/docusaurus.config.js +22 -14
- package/templates/facebook/package.json +24 -24
- package/templates/facebook/sidebars.js +1 -1
- package/templates/facebook/src/css/custom.css +17 -13
- package/templates/facebook/src/pages/index.js +1 -1
- package/templates/facebook/src/pages/styles.module.css +2 -2
- package/templates/facebook/static/img/meta_opensource_logo.svg +1 -0
- package/templates/facebook/static/img/meta_opensource_logo_negative.svg +1 -0
- package/templates/shared/README.md +9 -1
- package/templates/shared/docs/intro.md +19 -7
- package/templates/shared/docs/tutorial-basics/_category_.json +5 -1
- package/templates/shared/docs/tutorial-basics/create-a-blog-post.md +1 -1
- package/templates/shared/docs/tutorial-basics/create-a-document.md +6 -6
- package/templates/shared/docs/tutorial-basics/create-a-page.md +5 -5
- package/templates/shared/docs/tutorial-basics/deploy-your-site.md +1 -1
- package/templates/shared/docs/tutorial-basics/markdown-features.mdx +3 -1
- package/templates/shared/docs/tutorial-extras/_category_.json +4 -1
- package/templates/shared/docs/tutorial-extras/img/docsVersionDropdown.png +0 -0
- package/templates/shared/docs/tutorial-extras/img/localeDropdown.png +0 -0
- package/templates/shared/docs/tutorial-extras/manage-docs-versions.md +1 -1
- package/templates/shared/docs/tutorial-extras/translate-your-site.md +2 -2
- package/templates/shared/static/img/undraw_docusaurus_mountain.svg +1 -0
- package/templates/shared/static/img/undraw_docusaurus_react.svg +1 -0
- package/templates/shared/static/img/undraw_docusaurus_tree.svg +40 -1
- package/lib/.tsbuildinfo +0 -1
- package/src/index.ts +0 -289
- package/templates/facebook/static/img/oss_logo.png +0 -0
- package/templates/shared/static/img/tutorial/docsVersionDropdown.png +0 -0
- package/templates/shared/static/img/tutorial/localeDropdown.png +0 -0
- package/tsconfig.json +0 -11
package/lib/index.js
CHANGED
|
@@ -1,235 +1,427 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
4
3
|
*
|
|
5
4
|
* This source code is licensed under the MIT license found in the
|
|
6
5
|
* LICENSE file in the root directory of this source tree.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
7
|
+
import fs from 'fs-extra';
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import path from 'path';
|
|
10
|
+
import _ from 'lodash';
|
|
11
|
+
import logger from '@docusaurus/logger';
|
|
12
|
+
import shell from 'shelljs';
|
|
13
|
+
import prompts from 'prompts';
|
|
14
|
+
import supportsColor from 'supports-color';
|
|
15
|
+
import { escapeShellArg } from '@docusaurus/utils';
|
|
16
|
+
// Only used in the rare, rare case of running globally installed create +
|
|
17
|
+
// using --skip-install. We need a default name to show the tip text
|
|
18
|
+
const defaultPackageManager = 'npm';
|
|
19
|
+
const lockfileNames = {
|
|
20
|
+
npm: 'package-lock.json',
|
|
21
|
+
yarn: 'yarn.lock',
|
|
22
|
+
pnpm: 'pnpm-lock.yaml',
|
|
23
|
+
};
|
|
24
|
+
const packageManagers = Object.keys(lockfileNames);
|
|
25
|
+
async function findPackageManagerFromLockFile(rootDir) {
|
|
26
|
+
for (const packageManager of packageManagers) {
|
|
27
|
+
const lockFilePath = path.join(rootDir, lockfileNames[packageManager]);
|
|
28
|
+
if (await fs.pathExists(lockFilePath)) {
|
|
29
|
+
return packageManager;
|
|
30
|
+
}
|
|
27
31
|
}
|
|
32
|
+
return undefined;
|
|
28
33
|
}
|
|
29
|
-
function
|
|
30
|
-
return
|
|
34
|
+
function findPackageManagerFromUserAgent() {
|
|
35
|
+
return packageManagers.find((packageManager) => process.env.npm_config_user_agent?.startsWith(packageManager));
|
|
31
36
|
}
|
|
32
|
-
async function
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
async function askForPackageManagerChoice() {
|
|
38
|
+
const hasYarn = shell.exec('yarn --version', { silent: true }).code === 0;
|
|
39
|
+
const hasPnpm = shell.exec('pnpm --version', { silent: true }).code === 0;
|
|
40
|
+
if (!hasYarn && !hasPnpm) {
|
|
41
|
+
return 'npm';
|
|
42
|
+
}
|
|
43
|
+
const choices = ['npm', hasYarn && 'yarn', hasPnpm && 'pnpm']
|
|
44
|
+
.filter((p) => Boolean(p))
|
|
45
|
+
.map((p) => ({ title: p, value: p }));
|
|
46
|
+
return ((await prompts({
|
|
47
|
+
type: 'select',
|
|
48
|
+
name: 'packageManager',
|
|
49
|
+
message: 'Select a package manager...',
|
|
50
|
+
choices,
|
|
51
|
+
}, {
|
|
52
|
+
onCancel() {
|
|
53
|
+
logger.info `Falling back to name=${defaultPackageManager}`;
|
|
54
|
+
},
|
|
55
|
+
})).packageManager ?? defaultPackageManager);
|
|
37
56
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
.
|
|
57
|
+
async function getPackageManager(dest, { packageManager, skipInstall }) {
|
|
58
|
+
if (packageManager && !packageManagers.includes(packageManager)) {
|
|
59
|
+
throw new Error(`Invalid package manager choice ${packageManager}. Must be one of ${packageManagers.join(', ')}`);
|
|
60
|
+
}
|
|
61
|
+
return (
|
|
62
|
+
// If dest already contains a lockfile (e.g. if using a local template), we
|
|
63
|
+
// always use that instead
|
|
64
|
+
(await findPackageManagerFromLockFile(dest)) ??
|
|
65
|
+
packageManager ??
|
|
66
|
+
(await findPackageManagerFromLockFile('.')) ??
|
|
67
|
+
findPackageManagerFromUserAgent() ??
|
|
68
|
+
// This only happens if the user has a global installation in PATH
|
|
69
|
+
(skipInstall ? defaultPackageManager : askForPackageManagerChoice()));
|
|
70
|
+
}
|
|
71
|
+
const recommendedTemplate = 'classic';
|
|
72
|
+
const typeScriptTemplateSuffix = '-typescript';
|
|
73
|
+
const templatesDir = fileURLToPath(new URL('../templates', import.meta.url));
|
|
74
|
+
async function readTemplates() {
|
|
75
|
+
const dirContents = await fs.readdir(templatesDir);
|
|
76
|
+
const templates = await Promise.all(dirContents
|
|
41
77
|
.filter((d) => !d.startsWith('.') &&
|
|
42
78
|
!d.startsWith('README') &&
|
|
43
|
-
!d.endsWith(
|
|
44
|
-
d !== 'shared')
|
|
79
|
+
!d.endsWith(typeScriptTemplateSuffix) &&
|
|
80
|
+
d !== 'shared')
|
|
81
|
+
.map(async (name) => {
|
|
82
|
+
const tsVariantPath = path.join(templatesDir, `${name}${typeScriptTemplateSuffix}`);
|
|
83
|
+
return {
|
|
84
|
+
name,
|
|
85
|
+
path: path.join(templatesDir, name),
|
|
86
|
+
tsVariantPath: (await fs.pathExists(tsVariantPath))
|
|
87
|
+
? tsVariantPath
|
|
88
|
+
: undefined,
|
|
89
|
+
};
|
|
90
|
+
}));
|
|
45
91
|
// Classic should be first in list!
|
|
46
|
-
return
|
|
92
|
+
return _.sortBy(templates, (t) => t.name !== recommendedTemplate);
|
|
93
|
+
}
|
|
94
|
+
async function copyTemplate(template, dest, typescript) {
|
|
95
|
+
await fs.copy(path.join(templatesDir, 'shared'), dest);
|
|
96
|
+
// TypeScript variants will copy duplicate resources like CSS & config from
|
|
97
|
+
// base template
|
|
98
|
+
if (typescript) {
|
|
99
|
+
await fs.copy(template.path, dest, {
|
|
100
|
+
filter: async (filePath) => (await fs.stat(filePath)).isDirectory() ||
|
|
101
|
+
path.extname(filePath) === '.css' ||
|
|
102
|
+
path.basename(filePath) === 'docusaurus.config.js',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
await fs.copy(typescript ? template.tsVariantPath : template.path, dest, {
|
|
106
|
+
// Symlinks don't exist in published npm packages anymore, so this is only
|
|
107
|
+
// to prevent errors during local testing
|
|
108
|
+
filter: async (filePath) => !(await fs.lstat(filePath)).isSymbolicLink(),
|
|
109
|
+
});
|
|
47
110
|
}
|
|
48
111
|
function createTemplateChoices(templates) {
|
|
49
112
|
function makeNameAndValueChoice(value) {
|
|
50
|
-
|
|
113
|
+
if (typeof value === 'string') {
|
|
114
|
+
return { title: value, value };
|
|
115
|
+
}
|
|
116
|
+
const title = value.name === recommendedTemplate
|
|
117
|
+
? `${value.name} (recommended)`
|
|
118
|
+
: value.name;
|
|
51
119
|
return { title, value };
|
|
52
120
|
}
|
|
53
121
|
return [
|
|
54
122
|
...templates.map((template) => makeNameAndValueChoice(template)),
|
|
55
123
|
makeNameAndValueChoice('Git repository'),
|
|
124
|
+
makeNameAndValueChoice('Local template'),
|
|
56
125
|
];
|
|
57
126
|
}
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
return template.replace(TypeScriptTemplateSuffix, '');
|
|
61
|
-
}
|
|
62
|
-
return undefined;
|
|
127
|
+
function isValidGitRepoUrl(gitRepoUrl) {
|
|
128
|
+
return ['https://', 'git@'].some((item) => gitRepoUrl.startsWith(item));
|
|
63
129
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
130
|
+
const gitStrategies = ['deep', 'shallow', 'copy', 'custom'];
|
|
131
|
+
async function getGitCommand(gitStrategy) {
|
|
132
|
+
switch (gitStrategy) {
|
|
133
|
+
case 'shallow':
|
|
134
|
+
case 'copy':
|
|
135
|
+
return 'git clone --recursive --depth 1';
|
|
136
|
+
case 'custom': {
|
|
137
|
+
const { command } = (await prompts({
|
|
138
|
+
type: 'text',
|
|
139
|
+
name: 'command',
|
|
140
|
+
message: 'Write your own git clone command. The repository URL and destination directory will be supplied. E.g. "git clone --depth 10"',
|
|
141
|
+
}, {
|
|
142
|
+
onCancel() {
|
|
143
|
+
logger.info `Falling back to code=${'git clone'}`;
|
|
144
|
+
},
|
|
145
|
+
}));
|
|
146
|
+
return command ?? 'git clone';
|
|
147
|
+
}
|
|
148
|
+
case 'deep':
|
|
149
|
+
default:
|
|
150
|
+
return 'git clone';
|
|
75
151
|
}
|
|
76
|
-
await fs_extra_1.default.copy(path_1.default.resolve(templatesDir, template), dest, {
|
|
77
|
-
// Symlinks don't exist in published NPM packages anymore, so this is only to prevent errors during local testing
|
|
78
|
-
filter: (filePath) => !fs_extra_1.default.lstatSync(filePath).isSymbolicLink(),
|
|
79
|
-
});
|
|
80
152
|
}
|
|
81
|
-
async function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
name: 'name',
|
|
92
|
-
message: 'What should we name this site?',
|
|
93
|
-
initial: 'website',
|
|
94
|
-
});
|
|
95
|
-
name = prompt.name;
|
|
153
|
+
async function getSiteName(reqName, rootDir) {
|
|
154
|
+
async function validateSiteName(siteName) {
|
|
155
|
+
if (!siteName) {
|
|
156
|
+
return 'A website name is required.';
|
|
157
|
+
}
|
|
158
|
+
const dest = path.resolve(rootDir, siteName);
|
|
159
|
+
if (await fs.pathExists(dest)) {
|
|
160
|
+
return logger.interpolate `Directory already exists at path=${dest}!`;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
96
163
|
}
|
|
97
|
-
if (
|
|
98
|
-
|
|
164
|
+
if (reqName) {
|
|
165
|
+
const res = validateSiteName(reqName);
|
|
166
|
+
if (typeof res === 'string') {
|
|
167
|
+
throw new Error(res);
|
|
168
|
+
}
|
|
169
|
+
return reqName;
|
|
99
170
|
}
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
171
|
+
const { siteName } = (await prompts({
|
|
172
|
+
type: 'text',
|
|
173
|
+
name: 'siteName',
|
|
174
|
+
message: 'What should we name this site?',
|
|
175
|
+
initial: 'website',
|
|
176
|
+
validate: validateSiteName,
|
|
177
|
+
}, {
|
|
178
|
+
onCancel() {
|
|
179
|
+
logger.error('A website name is required.');
|
|
180
|
+
process.exit(1);
|
|
181
|
+
},
|
|
182
|
+
}));
|
|
183
|
+
return siteName;
|
|
184
|
+
}
|
|
185
|
+
async function getSource(reqTemplate, templates, cliOptions) {
|
|
186
|
+
if (reqTemplate) {
|
|
187
|
+
if (isValidGitRepoUrl(reqTemplate)) {
|
|
188
|
+
if (cliOptions.gitStrategy &&
|
|
189
|
+
!gitStrategies.includes(cliOptions.gitStrategy)) {
|
|
190
|
+
logger.error `Invalid git strategy: name=${cliOptions.gitStrategy}. Value must be one of ${gitStrategies.join(', ')}.`;
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
type: 'git',
|
|
195
|
+
url: reqTemplate,
|
|
196
|
+
strategy: cliOptions.gitStrategy ?? 'deep',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
else if (await fs.pathExists(path.resolve(reqTemplate))) {
|
|
200
|
+
return {
|
|
201
|
+
type: 'local',
|
|
202
|
+
path: path.resolve(reqTemplate),
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
const template = templates.find((t) => t.name === reqTemplate);
|
|
206
|
+
if (!template) {
|
|
207
|
+
logger.error('Invalid template.');
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
if (cliOptions.typescript && !template.tsVariantPath) {
|
|
211
|
+
logger.error `Template name=${reqTemplate} doesn't provide the TypeScript variant.`;
|
|
212
|
+
process.exit(1);
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
type: 'template',
|
|
216
|
+
template,
|
|
217
|
+
typescript: cliOptions.typescript ?? false,
|
|
218
|
+
};
|
|
103
219
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (!template) {
|
|
108
|
-
const templatePrompt = await (0, prompts_1.default)({
|
|
220
|
+
const template = cliOptions.gitStrategy
|
|
221
|
+
? 'Git repository'
|
|
222
|
+
: (await prompts({
|
|
109
223
|
type: 'select',
|
|
110
224
|
name: 'template',
|
|
111
225
|
message: 'Select a template below...',
|
|
112
226
|
choices: createTemplateChoices(templates),
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
message: 'This template is available in TypeScript. Do you want to use the TS variant?',
|
|
120
|
-
initial: false,
|
|
121
|
-
});
|
|
122
|
-
useTS = tsPrompt.useTS;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
// If user choose Git repository, we'll prompt for the url.
|
|
227
|
+
}, {
|
|
228
|
+
onCancel() {
|
|
229
|
+
logger.error('A choice is required.');
|
|
230
|
+
process.exit(1);
|
|
231
|
+
},
|
|
232
|
+
})).template;
|
|
126
233
|
if (template === 'Git repository') {
|
|
127
|
-
const
|
|
234
|
+
const { gitRepoUrl } = (await prompts({
|
|
128
235
|
type: 'text',
|
|
129
236
|
name: 'gitRepoUrl',
|
|
130
237
|
validate: (url) => {
|
|
131
238
|
if (url && isValidGitRepoUrl(url)) {
|
|
132
239
|
return true;
|
|
133
240
|
}
|
|
134
|
-
return
|
|
241
|
+
return logger.red('Invalid repository URL');
|
|
135
242
|
},
|
|
136
|
-
message:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
243
|
+
message: logger.interpolate `Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
|
|
244
|
+
(e.g: url=${'https://github.com/ownerName/repoName.git'})`,
|
|
245
|
+
}, {
|
|
246
|
+
onCancel() {
|
|
247
|
+
logger.error('A git repo URL is required.');
|
|
248
|
+
process.exit(1);
|
|
249
|
+
},
|
|
250
|
+
}));
|
|
251
|
+
let strategy = cliOptions.gitStrategy;
|
|
252
|
+
if (!strategy) {
|
|
253
|
+
({ strategy } = (await prompts({
|
|
254
|
+
type: 'select',
|
|
255
|
+
name: 'strategy',
|
|
256
|
+
message: 'How should we clone this repo?',
|
|
257
|
+
choices: [
|
|
258
|
+
{ title: 'Deep clone: preserve full history', value: 'deep' },
|
|
259
|
+
{ title: 'Shallow clone: clone with --depth=1', value: 'shallow' },
|
|
260
|
+
{
|
|
261
|
+
title: 'Copy: do a shallow clone, but do not create a git repo',
|
|
262
|
+
value: 'copy',
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
title: 'Custom: enter your custom git clone command',
|
|
266
|
+
value: 'custom',
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
}, {
|
|
270
|
+
onCancel() {
|
|
271
|
+
logger.info `Falling back to name=${'deep'}`;
|
|
272
|
+
},
|
|
273
|
+
})));
|
|
274
|
+
}
|
|
275
|
+
return {
|
|
276
|
+
type: 'git',
|
|
277
|
+
url: gitRepoUrl,
|
|
278
|
+
strategy: strategy ?? 'deep',
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
else if (template === 'Local template') {
|
|
282
|
+
const { templateDir } = (await prompts({
|
|
283
|
+
type: 'text',
|
|
284
|
+
name: 'templateDir',
|
|
285
|
+
validate: async (dir) => {
|
|
286
|
+
if (dir) {
|
|
287
|
+
const fullDir = path.resolve(dir);
|
|
288
|
+
if (await fs.pathExists(fullDir)) {
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
return logger.red(logger.interpolate `path=${fullDir} does not exist.`);
|
|
292
|
+
}
|
|
293
|
+
return logger.red('Please enter a valid path.');
|
|
294
|
+
},
|
|
295
|
+
message: 'Enter a local folder path, relative to the current working directory.',
|
|
296
|
+
}, {
|
|
297
|
+
onCancel() {
|
|
298
|
+
logger.error('A file path is required.');
|
|
299
|
+
process.exit(1);
|
|
300
|
+
},
|
|
301
|
+
}));
|
|
302
|
+
return {
|
|
303
|
+
type: 'local',
|
|
304
|
+
path: templateDir,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
let useTS = cliOptions.typescript;
|
|
308
|
+
if (!useTS && template.tsVariantPath) {
|
|
309
|
+
({ useTS } = (await prompts({
|
|
310
|
+
type: 'confirm',
|
|
311
|
+
name: 'useTS',
|
|
312
|
+
message: 'This template is available in TypeScript. Do you want to use the TS variant?',
|
|
313
|
+
initial: false,
|
|
314
|
+
})));
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
type: 'template',
|
|
318
|
+
template,
|
|
319
|
+
typescript: useTS ?? false,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
async function updatePkg(pkgPath, obj) {
|
|
323
|
+
const pkg = (await fs.readJSON(pkgPath));
|
|
324
|
+
const newPkg = Object.assign(pkg, obj);
|
|
325
|
+
await fs.outputFile(pkgPath, `${JSON.stringify(newPkg, null, 2)}\n`);
|
|
326
|
+
}
|
|
327
|
+
export default async function init(rootDir, reqName, reqTemplate, cliOptions = {}) {
|
|
328
|
+
const templates = await readTemplates();
|
|
329
|
+
const siteName = await getSiteName(reqName, rootDir);
|
|
330
|
+
const dest = path.resolve(rootDir, siteName);
|
|
331
|
+
const source = await getSource(reqTemplate, templates, cliOptions);
|
|
332
|
+
logger.info('Creating new Docusaurus project...');
|
|
333
|
+
if (source.type === 'git') {
|
|
334
|
+
const gitCommand = await getGitCommand(source.strategy);
|
|
335
|
+
const gitCloneCommand = `${gitCommand} ${escapeShellArg(source.url)} ${escapeShellArg(dest)}`;
|
|
336
|
+
if (shell.exec(gitCloneCommand).code !== 0) {
|
|
337
|
+
logger.error `Cloning Git template failed!`;
|
|
338
|
+
process.exit(1);
|
|
339
|
+
}
|
|
340
|
+
if (source.strategy === 'copy') {
|
|
341
|
+
await fs.remove(path.join(dest, '.git'));
|
|
157
342
|
}
|
|
343
|
+
}
|
|
344
|
+
else if (source.type === 'template') {
|
|
158
345
|
try {
|
|
159
|
-
await copyTemplate(
|
|
346
|
+
await copyTemplate(source.template, dest, source.typescript);
|
|
160
347
|
}
|
|
161
348
|
catch (err) {
|
|
162
|
-
|
|
349
|
+
logger.error `Copying Docusaurus template name=${source.template.name} failed!`;
|
|
163
350
|
throw err;
|
|
164
351
|
}
|
|
165
352
|
}
|
|
166
353
|
else {
|
|
167
|
-
|
|
354
|
+
try {
|
|
355
|
+
await fs.copy(source.path, dest);
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
logger.error `Copying local template path=${source.path} failed!`;
|
|
359
|
+
throw err;
|
|
360
|
+
}
|
|
168
361
|
}
|
|
169
362
|
// Update package.json info.
|
|
170
363
|
try {
|
|
171
|
-
await updatePkg(
|
|
172
|
-
name:
|
|
364
|
+
await updatePkg(path.join(dest, 'package.json'), {
|
|
365
|
+
name: _.kebabCase(siteName),
|
|
173
366
|
version: '0.0.0',
|
|
174
367
|
private: true,
|
|
175
368
|
});
|
|
176
369
|
}
|
|
177
370
|
catch (err) {
|
|
178
|
-
|
|
371
|
+
logger.error('Failed to update package.json.');
|
|
179
372
|
throw err;
|
|
180
373
|
}
|
|
181
374
|
// We need to rename the gitignore file to .gitignore
|
|
182
|
-
if (!
|
|
183
|
-
|
|
184
|
-
await
|
|
375
|
+
if (!(await fs.pathExists(path.join(dest, '.gitignore'))) &&
|
|
376
|
+
(await fs.pathExists(path.join(dest, 'gitignore')))) {
|
|
377
|
+
await fs.move(path.join(dest, 'gitignore'), path.join(dest, '.gitignore'));
|
|
185
378
|
}
|
|
186
|
-
if (
|
|
187
|
-
|
|
379
|
+
if (await fs.pathExists(path.join(dest, 'gitignore'))) {
|
|
380
|
+
await fs.remove(path.join(dest, 'gitignore'));
|
|
188
381
|
}
|
|
189
|
-
|
|
382
|
+
// Display the most elegant way to cd.
|
|
383
|
+
const cdpath = path.relative('.', dest);
|
|
384
|
+
const pkgManager = await getPackageManager(dest, cliOptions);
|
|
190
385
|
if (!cliOptions.skipInstall) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
env
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
},
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
386
|
+
shell.cd(dest);
|
|
387
|
+
logger.info `Installing dependencies with name=${pkgManager}...`;
|
|
388
|
+
if (shell.exec(pkgManager === 'yarn' ? 'yarn' : `${pkgManager} install --color always`, {
|
|
389
|
+
env: {
|
|
390
|
+
...process.env,
|
|
391
|
+
// Force coloring the output, since the command is invoked by
|
|
392
|
+
// shelljs, which is not an interactive shell
|
|
393
|
+
...(supportsColor.stdout ? { FORCE_COLOR: '1' } : {}),
|
|
394
|
+
},
|
|
395
|
+
}).code !== 0) {
|
|
396
|
+
logger.error('Dependency installation failed.');
|
|
397
|
+
logger.info `The site directory has already been created, and you can retry by typing:
|
|
398
|
+
|
|
399
|
+
code=${`cd ${cdpath}`}
|
|
400
|
+
code=${`${pkgManager} install`}`;
|
|
401
|
+
process.exit(0);
|
|
204
402
|
}
|
|
205
403
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
? name
|
|
210
|
-
: path_1.default.relative(process.cwd(), name);
|
|
211
|
-
console.log(`
|
|
212
|
-
Successfully created "${chalk_1.default.cyan(cdpath)}".
|
|
213
|
-
Inside that directory, you can run several commands:
|
|
404
|
+
const useNpm = pkgManager === 'npm';
|
|
405
|
+
logger.success `Created name=${cdpath}.`;
|
|
406
|
+
logger.info `Inside that directory, you can run several commands:
|
|
214
407
|
|
|
215
|
-
|
|
408
|
+
code=${`${pkgManager} start`}
|
|
216
409
|
Starts the development server.
|
|
217
410
|
|
|
218
|
-
|
|
411
|
+
code=${`${pkgManager} ${useNpm ? 'run ' : ''}build`}
|
|
219
412
|
Bundles your website into static files for production.
|
|
220
413
|
|
|
221
|
-
|
|
414
|
+
code=${`${pkgManager} ${useNpm ? 'run ' : ''}serve`}
|
|
222
415
|
Serves the built website locally.
|
|
223
416
|
|
|
224
|
-
|
|
417
|
+
code=${`${pkgManager} deploy`}
|
|
225
418
|
Publishes the website to GitHub pages.
|
|
226
419
|
|
|
227
420
|
We recommend that you begin by typing:
|
|
228
421
|
|
|
229
|
-
|
|
230
|
-
|
|
422
|
+
code=${`cd ${cdpath}`}
|
|
423
|
+
code=${`${pkgManager} start`}
|
|
231
424
|
|
|
232
425
|
Happy building awesome websites!
|
|
233
|
-
|
|
426
|
+
`;
|
|
234
427
|
}
|
|
235
|
-
exports.default = init;
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-docusaurus",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Create Docusaurus apps easily.",
|
|
5
|
+
"type": "module",
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "https://github.com/facebook/docusaurus.git",
|
|
@@ -12,32 +13,31 @@
|
|
|
12
13
|
},
|
|
13
14
|
"scripts": {
|
|
14
15
|
"create-docusaurus": "create-docusaurus",
|
|
15
|
-
"build": "tsc",
|
|
16
|
-
"watch": "tsc --watch"
|
|
17
|
-
},
|
|
18
|
-
"bin": {
|
|
19
|
-
"create-docusaurus": "bin/index.js"
|
|
16
|
+
"build": "tsc --build",
|
|
17
|
+
"watch": "tsc --build --watch"
|
|
20
18
|
},
|
|
19
|
+
"bin": "bin/index.js",
|
|
21
20
|
"publishConfig": {
|
|
22
21
|
"access": "public"
|
|
23
22
|
},
|
|
24
23
|
"license": "MIT",
|
|
25
24
|
"dependencies": {
|
|
26
|
-
"
|
|
25
|
+
"@docusaurus/logger": "2.0.1",
|
|
26
|
+
"@docusaurus/utils": "2.0.1",
|
|
27
27
|
"commander": "^5.1.0",
|
|
28
|
-
"fs-extra": "^10.
|
|
29
|
-
"lodash": "^4.17.
|
|
30
|
-
"prompts": "^2.4.
|
|
31
|
-
"semver": "^7.3.
|
|
32
|
-
"shelljs": "^0.8.
|
|
33
|
-
"supports-color": "^
|
|
34
|
-
"tslib": "^2.
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=14"
|
|
28
|
+
"fs-extra": "^10.1.0",
|
|
29
|
+
"lodash": "^4.17.21",
|
|
30
|
+
"prompts": "^2.4.2",
|
|
31
|
+
"semver": "^7.3.7",
|
|
32
|
+
"shelljs": "^0.8.5",
|
|
33
|
+
"supports-color": "^9.2.2",
|
|
34
|
+
"tslib": "^2.4.0"
|
|
38
35
|
},
|
|
39
36
|
"devDependencies": {
|
|
40
37
|
"@types/supports-color": "^8.1.1"
|
|
41
38
|
},
|
|
42
|
-
"
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=16.14"
|
|
41
|
+
},
|
|
42
|
+
"gitHead": "1ddee1c29cabf9bb52e4d78af6ebfaaabb1bc1f9"
|
|
43
43
|
}
|