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.
Files changed (49) hide show
  1. package/bin/index.js +43 -41
  2. package/lib/index.d.ts +16 -5
  3. package/lib/index.js +348 -156
  4. package/package.json +18 -18
  5. package/templates/classic/docusaurus.config.js +17 -3
  6. package/templates/classic/package.json +14 -11
  7. package/templates/classic/src/components/{HomepageFeatures.js → HomepageFeatures/index.js} +5 -5
  8. package/templates/classic/src/components/{HomepageFeatures.module.css → HomepageFeatures/styles.module.css} +0 -0
  9. package/templates/classic/src/css/custom.css +18 -16
  10. package/templates/classic/src/pages/index.js +3 -2
  11. package/templates/classic/src/pages/index.module.css +1 -1
  12. package/templates/classic-typescript/package.json +14 -14
  13. package/templates/classic-typescript/src/components/{HomepageFeatures.tsx → HomepageFeatures/index.tsx} +7 -13
  14. package/templates/classic-typescript/src/pages/index.tsx +3 -2
  15. package/templates/facebook/.eslintrc.js +10 -4
  16. package/templates/facebook/.prettierrc +1 -1
  17. package/templates/facebook/.stylelintrc.js +1 -1
  18. package/templates/facebook/README.md +9 -1
  19. package/templates/facebook/babel.config.js +1 -1
  20. package/templates/facebook/docusaurus.config.js +22 -14
  21. package/templates/facebook/package.json +24 -24
  22. package/templates/facebook/sidebars.js +1 -1
  23. package/templates/facebook/src/css/custom.css +17 -13
  24. package/templates/facebook/src/pages/index.js +1 -1
  25. package/templates/facebook/src/pages/styles.module.css +2 -2
  26. package/templates/facebook/static/img/meta_opensource_logo.svg +1 -0
  27. package/templates/facebook/static/img/meta_opensource_logo_negative.svg +1 -0
  28. package/templates/shared/README.md +9 -1
  29. package/templates/shared/docs/intro.md +19 -7
  30. package/templates/shared/docs/tutorial-basics/_category_.json +5 -1
  31. package/templates/shared/docs/tutorial-basics/create-a-blog-post.md +1 -1
  32. package/templates/shared/docs/tutorial-basics/create-a-document.md +6 -6
  33. package/templates/shared/docs/tutorial-basics/create-a-page.md +5 -5
  34. package/templates/shared/docs/tutorial-basics/deploy-your-site.md +1 -1
  35. package/templates/shared/docs/tutorial-basics/markdown-features.mdx +3 -1
  36. package/templates/shared/docs/tutorial-extras/_category_.json +4 -1
  37. package/templates/shared/docs/tutorial-extras/img/docsVersionDropdown.png +0 -0
  38. package/templates/shared/docs/tutorial-extras/img/localeDropdown.png +0 -0
  39. package/templates/shared/docs/tutorial-extras/manage-docs-versions.md +1 -1
  40. package/templates/shared/docs/tutorial-extras/translate-your-site.md +2 -2
  41. package/templates/shared/static/img/undraw_docusaurus_mountain.svg +1 -0
  42. package/templates/shared/static/img/undraw_docusaurus_react.svg +1 -0
  43. package/templates/shared/static/img/undraw_docusaurus_tree.svg +40 -1
  44. package/lib/.tsbuildinfo +0 -1
  45. package/src/index.ts +0 -289
  46. package/templates/facebook/static/img/oss_logo.png +0 -0
  47. package/templates/shared/static/img/tutorial/docsVersionDropdown.png +0 -0
  48. package/templates/shared/static/img/tutorial/localeDropdown.png +0 -0
  49. 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
- Object.defineProperty(exports, "__esModule", { value: true });
9
- const tslib_1 = require("tslib");
10
- const chalk_1 = (0, tslib_1.__importDefault)(require("chalk"));
11
- const fs_extra_1 = (0, tslib_1.__importDefault)(require("fs-extra"));
12
- const child_process_1 = require("child_process");
13
- const prompts_1 = (0, tslib_1.__importDefault)(require("prompts"));
14
- const path_1 = (0, tslib_1.__importDefault)(require("path"));
15
- const shelljs_1 = (0, tslib_1.__importDefault)(require("shelljs"));
16
- const lodash_1 = require("lodash");
17
- const supports_color_1 = (0, tslib_1.__importDefault)(require("supports-color"));
18
- const RecommendedTemplate = 'classic';
19
- const TypeScriptTemplateSuffix = '-typescript';
20
- function hasYarn() {
21
- try {
22
- (0, child_process_1.execSync)('yarnpkg --version', { stdio: 'ignore' });
23
- return true;
24
- }
25
- catch (e) {
26
- return false;
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 isValidGitRepoUrl(gitRepoUrl) {
30
- return ['https://', 'git@'].some((item) => gitRepoUrl.startsWith(item));
34
+ function findPackageManagerFromUserAgent() {
35
+ return packageManagers.find((packageManager) => process.env.npm_config_user_agent?.startsWith(packageManager));
31
36
  }
32
- async function updatePkg(pkgPath, obj) {
33
- const content = await fs_extra_1.default.readFile(pkgPath, 'utf-8');
34
- const pkg = JSON.parse(content);
35
- const newPkg = Object.assign(pkg, obj);
36
- await fs_extra_1.default.outputFile(pkgPath, JSON.stringify(newPkg, null, 2));
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 readTemplates(templatesDir) {
39
- const templates = fs_extra_1.default
40
- .readdirSync(templatesDir)
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(TypeScriptTemplateSuffix) &&
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 (0, lodash_1.sortBy)(templates, (t) => t !== RecommendedTemplate);
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
- const title = value === RecommendedTemplate ? `${value} (recommended)` : value;
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 getTypeScriptBaseTemplate(template) {
59
- if (template.endsWith(TypeScriptTemplateSuffix)) {
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
- async function copyTemplate(templatesDir, template, dest) {
65
- await fs_extra_1.default.copy(path_1.default.resolve(templatesDir, 'shared'), dest);
66
- // TypeScript variants will copy duplicate resources like CSS & config from base template
67
- const tsBaseTemplate = getTypeScriptBaseTemplate(template);
68
- if (tsBaseTemplate) {
69
- const tsBaseTemplatePath = path_1.default.resolve(templatesDir, tsBaseTemplate);
70
- await fs_extra_1.default.copy(tsBaseTemplatePath, dest, {
71
- filter: (filePath) => fs_extra_1.default.statSync(filePath).isDirectory() ||
72
- path_1.default.extname(filePath) === '.css' ||
73
- path_1.default.basename(filePath) === 'docusaurus.config.js',
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 init(rootDir, siteName, reqTemplate, cliOptions = {}) {
82
- const useYarn = cliOptions.useNpm ? false : hasYarn();
83
- const templatesDir = path_1.default.resolve(__dirname, '../templates');
84
- const templates = readTemplates(templatesDir);
85
- const hasTS = (templateName) => fs_extra_1.default.pathExistsSync(path_1.default.resolve(templatesDir, `${templateName}${TypeScriptTemplateSuffix}`));
86
- let name = siteName;
87
- // Prompt if siteName is not passed from CLI.
88
- if (!name) {
89
- const prompt = await (0, prompts_1.default)({
90
- type: 'text',
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 (!name) {
98
- throw new Error(chalk_1.default.red('A website name is required.'));
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 dest = path_1.default.resolve(rootDir, name);
101
- if (fs_extra_1.default.existsSync(dest)) {
102
- throw new Error(`Directory already exists at "${dest}"!`);
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
- let template = reqTemplate;
105
- let useTS = cliOptions.typescript;
106
- // Prompt if template is not provided from CLI.
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
- template = templatePrompt.template;
115
- if (template && !useTS && hasTS(template)) {
116
- const tsPrompt = await (0, prompts_1.default)({
117
- type: 'confirm',
118
- name: 'useTS',
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 repoPrompt = await (0, prompts_1.default)({
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 chalk_1.default.red(`Invalid repository URL`);
241
+ return logger.red('Invalid repository URL');
135
242
  },
136
- message: 'Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.\n(e.g: https://github.com/ownerName/repoName.git)',
137
- });
138
- template = repoPrompt.gitRepoUrl;
139
- }
140
- console.log(`
141
- ${chalk_1.default.cyan('Creating new Docusaurus project...')}
142
- `);
143
- if (template && isValidGitRepoUrl(template)) {
144
- console.log(`Cloning Git template ${chalk_1.default.cyan(template)}...`);
145
- if (shelljs_1.default.exec(`git clone --recursive ${template} ${dest}`, { silent: true })
146
- .code !== 0) {
147
- throw new Error(chalk_1.default.red(`Cloning Git template ${template} failed!`));
148
- }
149
- }
150
- else if (template && templates.includes(template)) {
151
- // Docusaurus templates.
152
- if (useTS) {
153
- if (!hasTS(template)) {
154
- throw new Error(`Template ${template} doesn't provide the Typescript variant.`);
155
- }
156
- template = `${template}${TypeScriptTemplateSuffix}`;
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(templatesDir, template, dest);
346
+ await copyTemplate(source.template, dest, source.typescript);
160
347
  }
161
348
  catch (err) {
162
- console.log(`Copying Docusaurus template ${chalk_1.default.cyan(template)} failed!`);
349
+ logger.error `Copying Docusaurus template name=${source.template.name} failed!`;
163
350
  throw err;
164
351
  }
165
352
  }
166
353
  else {
167
- throw new Error('Invalid template.');
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(path_1.default.join(dest, 'package.json'), {
172
- name: (0, lodash_1.kebabCase)(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
- console.log(chalk_1.default.red('Failed to update package.json.'));
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 (!fs_extra_1.default.pathExistsSync(path_1.default.join(dest, '.gitignore')) &&
183
- fs_extra_1.default.pathExistsSync(path_1.default.join(dest, 'gitignore'))) {
184
- await fs_extra_1.default.move(path_1.default.join(dest, 'gitignore'), path_1.default.join(dest, '.gitignore'));
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 (fs_extra_1.default.pathExistsSync(path_1.default.join(dest, 'gitignore'))) {
187
- fs_extra_1.default.removeSync(path_1.default.join(dest, 'gitignore'));
379
+ if (await fs.pathExists(path.join(dest, 'gitignore'))) {
380
+ await fs.remove(path.join(dest, 'gitignore'));
188
381
  }
189
- const pkgManager = useYarn ? 'yarn' : 'npm';
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
- console.log(`Installing dependencies with ${chalk_1.default.cyan(pkgManager)}...`);
192
- try {
193
- // Use force coloring the output, since the command is invoked by shelljs, which is not the interactive shell
194
- shelljs_1.default.exec(`cd "${name}" && ${useYarn ? 'yarn' : 'npm install --color always'}`, {
195
- env: {
196
- ...process.env,
197
- ...(supports_color_1.default.stdout ? { FORCE_COLOR: '1' } : {}),
198
- },
199
- });
200
- }
201
- catch (err) {
202
- console.log(chalk_1.default.red('Installation failed.'));
203
- throw err;
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
- console.log();
207
- // Display the most elegant way to cd.
208
- const cdpath = path_1.default.join(process.cwd(), name) === dest
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
- ${chalk_1.default.cyan(`${pkgManager} start`)}
408
+ code=${`${pkgManager} start`}
216
409
  Starts the development server.
217
410
 
218
- ${chalk_1.default.cyan(`${pkgManager} ${useYarn ? '' : 'run '}build`)}
411
+ code=${`${pkgManager} ${useNpm ? 'run ' : ''}build`}
219
412
  Bundles your website into static files for production.
220
413
 
221
- ${chalk_1.default.cyan(`${pkgManager} ${useYarn ? '' : 'run '}serve`)}
414
+ code=${`${pkgManager} ${useNpm ? 'run ' : ''}serve`}
222
415
  Serves the built website locally.
223
416
 
224
- ${chalk_1.default.cyan(`${pkgManager} deploy`)}
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
- ${chalk_1.default.cyan('cd')} ${cdpath}
230
- ${chalk_1.default.cyan(`${pkgManager} start`)}
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.0-beta.9",
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
- "chalk": "^4.1.2",
25
+ "@docusaurus/logger": "2.0.1",
26
+ "@docusaurus/utils": "2.0.1",
27
27
  "commander": "^5.1.0",
28
- "fs-extra": "^10.0.0",
29
- "lodash": "^4.17.20",
30
- "prompts": "^2.4.1",
31
- "semver": "^7.3.4",
32
- "shelljs": "^0.8.4",
33
- "supports-color": "^8.1.1",
34
- "tslib": "^2.3.1"
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
- "gitHead": "8a491fc29ad002f90e97f5b5fe4178ac8fa0c4d7"
39
+ "engines": {
40
+ "node": ">=16.14"
41
+ },
42
+ "gitHead": "1ddee1c29cabf9bb52e4d78af6ebfaaabb1bc1f9"
43
43
  }