umberto 6.1.2 → 7.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 (55) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/hexo-config.json +14 -19
  3. package/package.json +15 -21
  4. package/scripts/filter/after-post-render/time-end.js +5 -6
  5. package/scripts/utils/getreportissuewidgeturl.js +1 -1
  6. package/scripts/utils/logcrossprojectreference.js +3 -3
  7. package/scripts/utils/parselinks.js +12 -6
  8. package/src/api-builder/classes/description-parser.js +2 -2
  9. package/src/api-builder/utils/findtargetdoclet.js +2 -2
  10. package/src/data-converter/converters/typedoc/abstractparser.js +54 -50
  11. package/src/data-converter/converters/typedoc/accessorparser.js +7 -5
  12. package/src/data-converter/converters/typedoc/classparser.js +5 -3
  13. package/src/data-converter/converters/typedoc/computedpropertyparser.js +4 -3
  14. package/src/data-converter/converters/typedoc/constantparser.js +5 -3
  15. package/src/data-converter/converters/typedoc/constructorparser.js +4 -3
  16. package/src/data-converter/converters/typedoc/errorparser.js +4 -10
  17. package/src/data-converter/converters/typedoc/eventparser.js +4 -10
  18. package/src/data-converter/converters/typedoc/functionparser.js +5 -3
  19. package/src/data-converter/converters/typedoc/interfaceparser.js +5 -3
  20. package/src/data-converter/converters/typedoc/methodparser.js +6 -4
  21. package/src/data-converter/converters/typedoc/moduleparser.js +9 -3
  22. package/src/data-converter/converters/typedoc/propertyparser.js +7 -28
  23. package/src/data-converter/converters/typedoc/referenceparser.js +41 -0
  24. package/src/data-converter/converters/typedoc/reflectionkind.js +34 -0
  25. package/src/data-converter/converters/typedoc/typedoc.ts +215 -214
  26. package/src/data-converter/converters/typedoc/typedocconverter.js +130 -99
  27. package/src/data-converter/converters/typedoc/typeparser.js +10 -6
  28. package/src/data-converter/converters/typedoc2umberto.js +9 -3
  29. package/src/helpers/snippets.js +7 -6
  30. package/src/hexo/get-repo-urls.js +4 -5
  31. package/src/hexo-manager.js +16 -12
  32. package/src/index.js +4 -4
  33. package/src/sdk-builder/get-sdk-sources.js +3 -2
  34. package/src/tasks/build-documentation.js +2 -62
  35. package/src/tasks/cache-files.js +2 -2
  36. package/src/tasks/copy-files.js +4 -3
  37. package/src/tasks/copy-project-icons.js +10 -18
  38. package/src/tasks/create-sitemap-index.js +40 -0
  39. package/src/tasks/create-sitemap-step.js +106 -0
  40. package/src/tasks/create-sitemap.js +50 -29
  41. package/src/tasks/create-sym-links.js +7 -7
  42. package/src/tasks/get-project-config.js +3 -2
  43. package/src/tasks/overwrite-api-guides.js +2 -2
  44. package/src/tasks/read-doc-sources.js +2 -2
  45. package/src/tasks/validate-links.js +8 -5
  46. package/src/tasks/watcher.js +19 -16
  47. package/src/tasks/write-html-files.js +11 -26
  48. package/src/template/template-collection.js +1 -1
  49. package/themes/umberto/layout/gloria/_api-docs/_mixin/_type.pug +9 -0
  50. package/themes/umberto/layout/umberto/_api-docs/_mixin/_type.pug +9 -0
  51. package/themes/umberto/src/gloria/js/_codeswitcherbuttons.js +2 -2
  52. package/themes/umberto/src/gloria/js/app.js +0 -5
  53. package/themes/umberto/src/umberto/js/_codeswitcherbuttons.js +2 -2
  54. package/themes/umberto/src/umberto/js/app.js +0 -5
  55. package/src/helpers/copy-file.js +0 -34
@@ -7,14 +7,15 @@
7
7
 
8
8
  const fs = require( 'fs' );
9
9
  const upath = require( 'upath' );
10
- const glob = require( 'glob' );
10
+ const { globSync } = require( 'glob' );
11
11
  const cheerio = require( 'cheerio' );
12
12
 
13
13
  const SDK_SELECTOR = 'meta[name="sdk-samples"]';
14
14
 
15
15
  module.exports = sourcePath => {
16
16
  const files = [];
17
- const filePaths = glob.sync( upath.join( sourcePath, '*.html' ) );
17
+ const filePaths = globSync( upath.join( sourcePath, '*.html' ) ).map( path => upath.normalize( path ) );
18
+
18
19
  for ( const filePath of filePaths ) {
19
20
  const content = fs.readFileSync( filePath, { encoding: 'utf8' } );
20
21
  const $ = cheerio.load( content, null, false );
@@ -22,11 +22,10 @@ const cacheFiles = require( './cache-files' );
22
22
  const overwriteApiGuides = require( './overwrite-api-guides' );
23
23
  const cacheDir = upath.join( __dirname, '../../temp/cache' );
24
24
  const validateLinks = require( './validate-links' );
25
- const createSitemap = require( './create-sitemap' );
25
+ const createSitemapStep = require( './create-sitemap-step' );
26
26
  const buildSnippets = require( './build-snippets' );
27
27
  const copyProjectIcons = require( './copy-project-icons' );
28
28
  const executeHooks = require( './execute-hooks' );
29
- const chalk = require( 'chalk' );
30
29
  const umbertoVersion = require( '../../package.json' ).version;
31
30
 
32
31
  const parseLink = require( '../../scripts/utils/parselinks' );
@@ -56,7 +55,6 @@ const getFilePatternsToProcess = require( '../helpers/get-file-patterns-to-proce
56
55
  * @param {Object} options.snippetOptions Additional options passed to snippetAdapter.
57
56
  * @param {Boolean} options.skipValidation Skip validating links.
58
57
  * @param {Boolean} options.skipGuides Skip processing guides. Useful for checking the layout changes.
59
- * @param {Boolean} options.skipSitemap Skip generating sitemap file. Useful when doing partial build.
60
58
  * @param {Boolean} options.verbose Provide more details during building documentation.
61
59
  * @param {Boolean} [options.watch] Flag which indicates that hexo should watch files.
62
60
  * @param {Array.<String>} [options.guides] An array containing names of guides that will be processed by Umberto. Useful when building
@@ -77,7 +75,6 @@ module.exports = options => {
77
75
  snippetOptions = {},
78
76
  skipValidation = false,
79
77
  skipGuides = false,
80
- skipSitemap = false,
81
78
  watch = false,
82
79
  verbose = false,
83
80
  guides = []
@@ -224,68 +221,11 @@ module.exports = options => {
224
221
  publicDir: hexoManager.getPublicDir()
225
222
  } );
226
223
  } )
227
- // Create sitemap.xml file.
228
224
  .then( async () => {
229
- let hostname;
230
- let dst = '';
231
225
  const projectConfigs = await getProjectConfigs( rootPath, projectPaths );
232
- const config = mainConfig.isSingleProject && projectConfigs && projectConfigs.length > 0 ?
233
- projectConfigs[ 0 ] : {};
234
- const sitemapConfig = mainConfig.sitemap ? mainConfig.sitemap : config.sitemap;
235
-
236
- // If available, use sitemap config from umberto-main.json.
237
- // Use sitemap config from umberto.json otherwise.
238
- if ( sitemapConfig && mainConfig.isSingleProject ) {
239
- hostname = sitemapConfig.hostname;
240
- dst = upath.join( config.slug, config.version );
241
- } else if ( sitemapConfig ) {
242
- hostname = sitemapConfig.hostname;
243
- } else {
244
- if ( verbose ) {
245
- console.log( chalk.yellow( 'Warning: ' ), 'Not enough data to create a sitemap.xml file.' );
246
- }
247
-
248
- return Promise.resolve();
249
- }
250
-
251
- // Get urls to be excluded from the sitemap.
252
- // Use excluded urls both from umberto-main.json and umberto.json.
253
- const excludedUrls = [];
254
-
255
- if ( mainConfig.sitemap && mainConfig.sitemap.excluded ) {
256
- excludedUrls.push( ...mainConfig.sitemap.excluded );
257
- }
258
-
259
- for ( const currentConfig of projectConfigs ) {
260
- if ( currentConfig.sitemap && currentConfig.sitemap.excluded ) {
261
- excludedUrls.push( ...currentConfig.sitemap.excluded );
262
- }
263
- }
264
226
 
265
- // Get extra sitemap settings per url. At the moment it's just custom priority for urls.
266
- // Use both umberto-main.json and umberto.json.
267
- const extraUrlSettings = [];
268
-
269
- if ( mainConfig.sitemap && mainConfig.sitemap.extraUrlSettings ) {
270
- extraUrlSettings.push( ...mainConfig.sitemap.extraUrlSettings );
271
- }
272
-
273
- for ( const currentConfig of projectConfigs ) {
274
- if ( currentConfig.sitemap && currentConfig.sitemap.extraUrlSettings ) {
275
- extraUrlSettings.push( ...currentConfig.sitemap.extraUrlSettings );
276
- }
277
- }
278
-
279
- if ( skipSitemap ) {
280
- return Promise.resolve();
281
- }
282
-
283
- return createSitemap( 'build/docs', hostname, dst, {
284
- excluded: excludedUrls,
285
- extraUrlSettings
286
- } );
227
+ return createSitemapStep( { projectConfigs, verbose, mainConfig } );
287
228
  } )
288
-
289
229
  .then( async () => {
290
230
  const configs = await getProjectConfigs( rootPath, projectPaths );
291
231
 
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const glob = require( 'glob' );
9
+ const { globSync } = require( 'glob' );
10
10
  const fs = require( 'fs-extra' );
11
11
 
12
12
  /**
@@ -17,7 +17,7 @@ const fs = require( 'fs-extra' );
17
17
  * @returns {boolean}
18
18
  */
19
19
  module.exports = ( src, dst ) => {
20
- const sourcePaths = glob.sync( upath.join( src, '**', '*' ) );
20
+ const sourcePaths = globSync( upath.join( src, '**', '*' ) ).map( path => upath.normalize( path ) );
21
21
  let result = false;
22
22
 
23
23
  for ( const p of sourcePaths ) {
@@ -7,7 +7,7 @@
7
7
 
8
8
  const upath = require( 'upath' );
9
9
  const fs = require( 'fs-extra' );
10
- const glob = require( 'glob' );
10
+ const { globSync } = require( 'glob' );
11
11
  const globToRegexp = require( '../helpers/glob-to-regexp' );
12
12
 
13
13
  /**
@@ -64,10 +64,11 @@ module.exports = ( src, dst, options = {} ) => {
64
64
  // If the `src` is a path to a directory, copy files from the directory.
65
65
  const sourceGlobPath = upath.join( src, '**/*' );
66
66
 
67
- let sourceFilePaths = glob.sync( sourceGlobPath, {
67
+ let sourceFilePaths = globSync( sourceGlobPath, {
68
68
  ignore: ignored.map( ignoredPath => upath.join( src, ignoredPath ) ),
69
69
  nodir: true
70
- } );
70
+ } )
71
+ .map( path => upath.normalize( path ) );
71
72
 
72
73
  // If the `match` is an array, remove files that should not be processed.
73
74
  if ( match ) {
@@ -6,37 +6,29 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const mkdirp = require( 'mkdirp' );
10
- const copyFile = require( '../helpers/copy-file' );
9
+ const fs = require( 'fs-extra' );
11
10
 
12
11
  /**
13
- * @returns {Promise}
12
+ * @returns {Promise<void>}
14
13
  */
15
- module.exports = function copyProjectIcons( projectGlobals, buildDirectory ) {
14
+ module.exports = async function copyProjectIcons( projectGlobals, buildDirectory ) {
16
15
  const availableProjects = Object.keys( projectGlobals ).filter( projectName => projectName !== 'common' );
17
16
 
18
- let promise = Promise.resolve();
19
-
20
17
  for ( const project of availableProjects ) {
21
18
  const projectDetails = projectGlobals[ project ];
22
19
  const destinationIconsPath = upath.join( buildDirectory, projectDetails.BASE_PATH, 'assets', 'icons' );
23
20
 
24
- promise = promise.then( () => mkdirp( destinationIconsPath ) );
25
-
26
21
  for ( const [ sourceFile, destinationName ] of projectDetails._icons ) {
27
22
  const fullSourcePath = upath.join( projectDetails.config.projectRootPath, 'node_modules', sourceFile );
28
23
  const fullDestinationPath = upath.join( destinationIconsPath, destinationName );
29
24
 
30
- promise = promise.then( () => {
31
- return copyFile( fullSourcePath, fullDestinationPath )
32
- .catch( () => {
33
- console.warn(
34
- `⚠️ The "${ sourceFile }" icon cannot be copied because it does not exist in "${ fullSourcePath }".`
35
- );
36
- } );
37
- } );
25
+ try {
26
+ await fs.copy( fullSourcePath, fullDestinationPath );
27
+ } catch ( error ) {
28
+ console.warn(
29
+ `⚠️ The "${ sourceFile }" icon cannot be copied because it does not exist in "${ fullSourcePath }".`
30
+ );
31
+ }
38
32
  }
39
33
  }
40
-
41
- return promise;
42
34
  };
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md.
4
+ */
5
+
6
+ const upath = require( 'upath' );
7
+ const fs = require( 'fs/promises' );
8
+
9
+ const XMLNS_STRINGS = [
10
+ 'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"',
11
+ 'xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"',
12
+ 'xmlns:xhtml="http://www.w3.org/1999/xhtml"',
13
+ 'xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"',
14
+ 'xmlns:video="http://www.google.com/schemas/sitemap-video/1.1"'
15
+ ];
16
+
17
+ /**
18
+ * Creates a sitemap.xml file and saves it to build directory.
19
+ *
20
+ * @param {Object} options
21
+ * @param {String} options.buildPath Path to the build directory.
22
+ * @param {String} options.hostname Hostname of the website where the documentation will be hosted.
23
+ * @param {Array.<string>} options.sitemapPaths Paths to generated sitemap files.
24
+ * @returns {Promise}
25
+ */
26
+ module.exports = ( { buildPath, hostname, sitemapPaths } ) => {
27
+ const sitemapPath = upath.resolve( upath.join( buildPath, 'sitemap.xml' ) );
28
+ const sitemapIndexContent = [
29
+ '<?xml version="1.0" encoding="UTF-8"?>',
30
+ `<sitemapindex ${ XMLNS_STRINGS.join( ' ' ) }>`,
31
+ ...sitemapPaths.map( sitemapPath => ( [
32
+ '<sitemap>',
33
+ `<loc>${ upath.join( hostname, sitemapPath.split( buildPath ).pop() ) }</loc>`,
34
+ '</sitemap>'
35
+ ] ) ),
36
+ '</sitemapindex>'
37
+ ].flat().join( '' );
38
+
39
+ return fs.writeFile( sitemapPath, sitemapIndexContent, 'utf8' );
40
+ };
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md.
4
+ */
5
+
6
+ const { styleText } = require( 'util' );
7
+ const createSitemap = require( './create-sitemap' );
8
+ const createSitemapIndex = require( './create-sitemap-index' );
9
+
10
+ const BUILD_PATH = 'build/docs';
11
+
12
+ /**
13
+ * This build step handles sitemap building.
14
+ *
15
+ * @param {Object} options
16
+ * @param {Object} options.mainConfig
17
+ * @param {Object} options.projectConfigs
18
+ * @param {Object} options.verbose
19
+ */
20
+ module.exports = async function createSitemapStep( { mainConfig, projectConfigs, verbose } ) {
21
+ if ( mainConfig.isSingleProject ) {
22
+ // If available, use sitemap config from umberto-main.json.
23
+ // Use sitemap config from umberto.json otherwise.
24
+ const config = projectConfigs && projectConfigs.length > 0 ? projectConfigs[ 0 ] : {};
25
+ const sitemapConfig = mainConfig.sitemap ? mainConfig.sitemap : config.sitemap;
26
+
27
+ if ( !sitemapConfig ) {
28
+ return missingSitemapWarning( verbose );
29
+ }
30
+
31
+ if ( !sitemapConfig.enabled ) {
32
+ if ( verbose ) {
33
+ console.log(
34
+ styleText( 'yellow', 'Warning: ' ),
35
+ 'To enable generating a sitemap.xml file, add the "enabled: true" property to "sitemap" configuration.'
36
+ );
37
+ }
38
+
39
+ return;
40
+ }
41
+
42
+ return createSitemap( {
43
+ buildPath: BUILD_PATH,
44
+ projectSlug: config.slug,
45
+ projectVersion: config.version,
46
+ hostname: sitemapConfig.hostname,
47
+ excluded: sitemapConfig.excluded || []
48
+ } );
49
+ }
50
+
51
+ if ( !mainConfig.sitemap ) {
52
+ return missingSitemapWarning( verbose );
53
+ }
54
+
55
+ const { hostname } = mainConfig.sitemap;
56
+
57
+ const promises = projectConfigs.map( projectConfig => {
58
+ const excluded = [];
59
+
60
+ if ( mainConfig.sitemap?.excluded ) {
61
+ excluded.push( ...mainConfig.sitemap.excluded );
62
+ }
63
+
64
+ if ( projectConfig.sitemap?.excluded ) {
65
+ excluded.push( ...projectConfig.sitemap.excluded );
66
+ }
67
+
68
+ return createSitemap( {
69
+ hostname,
70
+ projectSlug: projectConfig.slug,
71
+ projectVersion: projectConfig.version,
72
+ buildPath: BUILD_PATH,
73
+ excluded
74
+ } );
75
+ } );
76
+
77
+ const sitemapPaths = await Promise.all( promises );
78
+
79
+ // Generate the sitemap index only if all projects are being built.
80
+ if ( !mainConfig.ignoredProjects.length ) {
81
+ // To collect the HTML files from the build root directory.
82
+ const rootSitemap = await createSitemap( {
83
+ buildPath: BUILD_PATH,
84
+ hostname,
85
+ excluded: mainConfig.sitemap?.excluded || [],
86
+ fileName: 'sitemap-root.xml'
87
+ } );
88
+
89
+ await createSitemapIndex( {
90
+ buildPath: BUILD_PATH,
91
+ hostname,
92
+ sitemapPaths: [
93
+ rootSitemap,
94
+ ...sitemapPaths
95
+ ]
96
+ } );
97
+ }
98
+ };
99
+
100
+ function missingSitemapWarning( verbose ) {
101
+ if ( !verbose ) {
102
+ return;
103
+ }
104
+
105
+ console.log( styleText( 'yellow', 'Warning: ' ), 'Not enough data to create a sitemap.xml file.' );
106
+ }
@@ -5,53 +5,64 @@
5
5
 
6
6
  'use strict';
7
7
 
8
+ const fs = require( 'fs' );
9
+ const { globSync } = require( 'glob' );
8
10
  const upath = require( 'upath' );
9
- const glob = require( 'glob' );
11
+ const { URL } = require( 'url' );
10
12
  const { SitemapStream, streamToPromise } = require( 'sitemap' );
11
- const fs = require( 'fs' );
12
13
 
13
14
  /**
14
15
  * Creates a sitemap.xml file and saves it to build directory.
15
16
  *
16
- * @param {String} buildPath Path to the build directory.
17
- * @param {String} hostname Hostname of the website where the documentation will be hosted.
18
- * @param {String} dst Additional path in the build directory where to save the sitemap.xml.
19
- * @param {Object} options Additional options.
20
- * @param {Array.<String>} options.excludedUrls An array of urls to be excluded from the sitemap.
21
- * @param {Array.<Object>} options.extraUrlSettings An array of config objects per url. Currently used to set custom priority per url.
22
- * @returns {Promise}
17
+ * @param {Object} options
18
+ * @param {String} options.fileName
19
+ * @param {String} options.projectSlug
20
+ * @param {String} options.projectVersion
21
+ * @param {String} options.buildPath Path to the build directory.
22
+ * @param {String} options.hostname Hostname of the website where the documentation will be hosted.
23
+ * @param {Array.<String>} options.excluded An array of urls to be excluded from the sitemap.
24
+ * @returns {Promise.<string>} Path to the generated sitemap.
23
25
  */
24
- module.exports = ( buildPath, hostname, dst = '', options = {} ) => {
25
- const pattern = upath.join( buildPath, '**', '*.html' );
26
- const pathsToFiles = glob.sync( pattern );
27
- const sitemap = new SitemapStream( {
26
+ module.exports = options => {
27
+ const {
28
+ fileName = 'sitemap.xml',
29
+ projectSlug,
30
+ projectVersion,
31
+ buildPath,
28
32
  hostname,
33
+ excluded = []
34
+ } = options;
35
+
36
+ // The `sitemap` package expects that `hostname` will not include subdirectories.
37
+ // Let's split it and glue the destination URL manually.
38
+ const { origin, pathname } = new URL( hostname );
39
+
40
+ const { pattern, sitemapPath } = getSitemapData( { buildPath, projectSlug, fileName } );
41
+ const sitemap = new SitemapStream( {
42
+ hostname: origin,
29
43
  cacheTime: 600000
30
44
  } );
31
45
 
32
- for ( const filePath of pathsToFiles ) {
33
- const urlForSitemap = filePath.replace( buildPath, 'docs' ).replace( /(\/[^/]+\/)[^/]+\//, '$1latest/' );
34
- const excludedUrls = options.excluded || [];
35
- const extraUrlSettings = options.extraUrlSettings || [];
46
+ const pathToFiles = globSync( pattern ).map( path => upath.normalize( path ) );
47
+
48
+ for ( const filePath of pathToFiles ) {
49
+ let urlForSitemap = filePath.replace( buildPath, upath.normalizeTrim( pathname ) );
50
+
51
+ if ( projectVersion ) {
52
+ urlForSitemap = urlForSitemap.replace( `/${ projectVersion }/`, '/latest/' );
53
+ }
36
54
 
37
55
  if ( filePath.endsWith( '404.html' ) ) {
38
56
  continue;
39
57
  }
40
58
 
41
- if ( excludedUrls.find( excluded => filePath.includes( excluded ) ) ) {
59
+ if ( excluded.find( excluded => filePath.includes( excluded ) ) ) {
42
60
  continue;
43
61
  }
44
62
 
45
- const extraUrlSetting = extraUrlSettings.find( setting => filePath.includes( setting.url ) );
46
- const sitemapItem = {
63
+ sitemap.write( {
47
64
  url: urlForSitemap
48
- };
49
-
50
- if ( extraUrlSetting && extraUrlSetting.priority ) {
51
- sitemapItem.priority = Math.min( extraUrlSetting.priority, 1.0 );
52
- }
53
-
54
- sitemap.write( sitemapItem );
65
+ } );
55
66
  }
56
67
 
57
68
  sitemap.end();
@@ -59,13 +70,23 @@ module.exports = ( buildPath, hostname, dst = '', options = {} ) => {
59
70
  return streamToPromise( sitemap )
60
71
  .then( data => {
61
72
  return new Promise( ( resolve, reject ) => {
62
- fs.writeFile( upath.resolve( upath.join( buildPath, dst, 'sitemap.xml' ) ), data.toString(), err => {
73
+ fs.writeFile( sitemapPath, data.toString(), err => {
63
74
  if ( err ) {
64
75
  return reject( err );
65
76
  }
66
77
 
67
- return resolve();
78
+ return resolve( sitemapPath );
68
79
  } );
69
80
  } );
70
81
  } );
71
82
  };
83
+
84
+ function getSitemapData( { buildPath, projectSlug, fileName } ) {
85
+ return {
86
+ pattern: projectSlug ? upath.join( buildPath, projectSlug, '**', '*.html' ) : upath.join( buildPath, '*.html' ),
87
+
88
+ sitemapPath: upath.resolve(
89
+ projectSlug ? upath.join( buildPath, projectSlug, fileName ) : upath.join( buildPath, fileName )
90
+ )
91
+ };
92
+ }
@@ -5,10 +5,10 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const getProjectConfig = require( './get-project-config' );
9
- const upath = require( 'upath' );
8
+ const { styleText } = require( 'util' );
10
9
  const fs = require( 'fs' );
11
- const chalk = require( 'chalk' );
10
+ const upath = require( 'upath' );
11
+ const getProjectConfig = require( './get-project-config' );
12
12
 
13
13
  module.exports = async ( {
14
14
  mainConfig,
@@ -34,16 +34,16 @@ module.exports = async ( {
34
34
 
35
35
  return Promise.resolve();
36
36
 
37
- function createSymbolicLink( config ) {
38
- const destinationPath = upath.join( rootPath, 'build', 'docs', config.slug, 'latest' );
37
+ function createSymbolicLink( { slug, name, version } ) {
38
+ const destinationPath = upath.join( rootPath, 'build', 'docs', slug, 'latest' );
39
39
 
40
40
  if ( !fs.existsSync( destinationPath ) ) {
41
41
  // The 3rd argument to the fs.symlinkSync() method is the link type and it is only available
42
42
  // on Windows (it is ignored on other platforms). Creating a symlink to a directory with link
43
43
  // type = 'dir' requires admin privileges on Windows. The only way to create a directory symlink
44
44
  // without admin privileges on Windows is to use the 'junction' link type.
45
- fs.symlinkSync( config.version, destinationPath, 'junction' );
46
- console.log( `Symlink for ${ chalk.cyanBright( config.name ) } ${ chalk.magentaBright( './' + config.version ) } - created. ` );
45
+ fs.symlinkSync( version, destinationPath, 'junction' );
46
+ console.log( `Symlink for ${ styleText( 'cyanBright', name ) } ${ styleText( 'magentaBright', './' + version ) } - created.` );
47
47
  }
48
48
  }
49
49
  };
@@ -7,7 +7,7 @@
7
7
 
8
8
  const upath = require( 'upath' );
9
9
  const fs = require( 'fs' );
10
- const glob = require( 'glob' );
10
+ const { globSync } = require( 'glob' );
11
11
  const importModule = require( '../helpers/import-module' );
12
12
 
13
13
  const cache = new Map();
@@ -369,7 +369,8 @@ function getPackagesPathsInfo( rootPath, slug, directory ) {
369
369
  // CKEditor 5 can have packages that do not start with `ckeditor5-` prefix.
370
370
  const slugOrRegExp = slug === 'ckeditor5' ? /ckeditor5?-/ : `${ slug }-`;
371
371
 
372
- return glob.sync( upath.resolve( rootPath, directory ) )
372
+ return globSync( upath.resolve( rootPath, directory ) )
373
+ .map( p => upath.normalize( p ) )
373
374
  .map( p => {
374
375
  const relativePath = p.replace( rootPath + '/', '' );
375
376
 
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const glob = require( 'glob' );
9
+ const { globSync } = require( 'glob' );
10
10
  const fs = require( 'fs-extra' );
11
11
 
12
12
  /**
@@ -17,7 +17,7 @@ const fs = require( 'fs-extra' );
17
17
  * @param dst
18
18
  */
19
19
  module.exports = ( src, dst ) => {
20
- const sourcePaths = glob.sync( upath.join( src, '**', '*' ) );
20
+ const sourcePaths = globSync( upath.join( src, '**', '*' ) ).map( path => upath.normalize( path ) );
21
21
 
22
22
  for ( const p of sourcePaths ) {
23
23
  const strippedPath = p.replace( src, '' );
@@ -7,7 +7,7 @@
7
7
 
8
8
  const upath = require( 'upath' );
9
9
  const fs = require( 'fs' );
10
- const glob = require( 'glob' );
10
+ const { globSync } = require( 'glob' );
11
11
  const DOC_FORMATS = require( '../helpers/doc-formats' );
12
12
 
13
13
  /**
@@ -18,7 +18,7 @@ const DOC_FORMATS = require( '../helpers/doc-formats' );
18
18
  * @returns {Array}
19
19
  */
20
20
  module.exports = ( sourcePath, type ) => {
21
- const fileNames = glob.sync( upath.join( sourcePath, `**/*.${ DOC_FORMATS[ type ] }` ) );
21
+ const fileNames = globSync( upath.join( sourcePath, `**/*.${ DOC_FORMATS[ type ] }` ) ).map( path => upath.normalize( path ) );
22
22
  const files = [];
23
23
 
24
24
  for ( const fileName of fileNames ) {
@@ -5,15 +5,15 @@
5
5
 
6
6
  'use strict';
7
7
 
8
+ const { styleText } = require( 'util' );
8
9
  const upath = require( 'upath' );
9
10
  const fs = require( 'fs-extra' );
10
- const glob = require( 'glob' );
11
- const chalk = require( 'chalk' );
11
+ const { globSync } = require( 'glob' );
12
12
  const { parseDocument } = require( 'htmlparser2' );
13
13
 
14
14
  module.exports = ( buildPath, options = {} ) => {
15
15
  const pattern = upath.join( buildPath, '**', '*' );
16
- let pathsToFiles = glob.sync( pattern );
16
+ let pathsToFiles = globSync( pattern ).map( path => upath.normalize( path ) );
17
17
 
18
18
  const links = new Set();
19
19
 
@@ -108,10 +108,13 @@ module.exports = ( buildPath, options = {} ) => {
108
108
 
109
109
  if ( invalidHrefs.size ) {
110
110
  process.exitCode = 1;
111
- console.log( `${ chalk.red( 'Error: ' ) }Invalid internal links in ${ chalk.magenta( filePath.replace( buildPath, '' ) ) }:` );
111
+ console.log(
112
+ styleText( 'red', 'Error: ' ) +
113
+ `Invalid internal links in ${ styleText( 'magenta', filePath.replace( buildPath, '' ) ) }:`
114
+ );
112
115
 
113
116
  for ( const url of invalidHrefs ) {
114
- console.log( chalk.gray( ` * '${ url.href }' - ${ url.text.replace( /\s+/g, ' ' ) }` ) );
117
+ console.log( styleText( 'gray', ` * '${ url.href }' - ${ url.text.replace( /\s+/g, ' ' ) }` ) );
115
118
  }
116
119
  }
117
120
  }
@@ -5,24 +5,27 @@
5
5
 
6
6
  'use strict';
7
7
 
8
+ const { styleText } = require( 'util' );
8
9
  const upath = require( 'upath' );
9
- const cpx = require( 'cpx' );
10
- const chalk = require( 'chalk' );
10
+ const chokidar = require( 'chokidar' );
11
+ const { copy } = require( 'fs-extra' );
11
12
 
12
- module.exports = hexoManager => new Promise( resolve => {
13
- console.log( chalk.yellow( 'Umberto is in watch mode press CTRL+C to exit.' ) );
14
- const originPaths = hexoManager.getOriginPaths();
13
+ module.exports = function watchMd( hexoManager ) {
14
+ console.log( styleText( 'yellow', 'Umberto is in watch mode press CTRL+C to exit.' ) );
15
15
 
16
- for ( const item of originPaths ) {
17
- const path1 = upath.join( item.originPath, '*.md' );
18
- const path2 = upath.join( item.originPath, '**', '*.md' );
19
-
20
- cpx.watch( path1, item.dstPath, { initialCopy: false } );
21
- cpx.watch( path2, item.dstPath, { initialCopy: false } );
16
+ for ( const { originPath, dstPath } of hexoManager.getOriginPaths() ) {
17
+ chokidar
18
+ .watch( originPath, {
19
+ ignoreInitial: true,
20
+ ignored: ( path, stats ) => stats?.isFile() && !path.endsWith( '.md' )
21
+ } )
22
+ .on( 'add', file => copyFile( originPath, dstPath, file ) )
23
+ .on( 'change', file => copyFile( originPath, dstPath, file ) );
22
24
  }
25
+ };
26
+
27
+ function copyFile( originPath, dstPath, file ) {
28
+ const dest = upath.join( dstPath, upath.relative( originPath, file ) );
23
29
 
24
- process.on( 'SIGINT', function() {
25
- resolve();
26
- process.exit();
27
- } );
28
- } );
30
+ return copy( file, dest );
31
+ }