umberto 7.0.0 → 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.
- package/CHANGELOG.md +9 -0
- package/hexo-config.json +14 -19
- package/package.json +15 -21
- package/scripts/filter/after-post-render/time-end.js +5 -6
- package/scripts/utils/getreportissuewidgeturl.js +1 -1
- package/scripts/utils/logcrossprojectreference.js +3 -3
- package/scripts/utils/parselinks.js +12 -6
- package/src/api-builder/classes/description-parser.js +2 -2
- package/src/helpers/snippets.js +7 -6
- package/src/hexo/get-repo-urls.js +4 -5
- package/src/hexo-manager.js +16 -12
- package/src/index.js +4 -4
- package/src/sdk-builder/get-sdk-sources.js +3 -2
- package/src/tasks/build-documentation.js +2 -62
- package/src/tasks/cache-files.js +2 -2
- package/src/tasks/copy-files.js +4 -3
- package/src/tasks/copy-project-icons.js +10 -18
- package/src/tasks/create-sitemap-index.js +40 -0
- package/src/tasks/create-sitemap-step.js +106 -0
- package/src/tasks/create-sitemap.js +50 -29
- package/src/tasks/create-sym-links.js +7 -7
- package/src/tasks/get-project-config.js +3 -2
- package/src/tasks/overwrite-api-guides.js +2 -2
- package/src/tasks/read-doc-sources.js +2 -2
- package/src/tasks/validate-links.js +8 -5
- package/src/tasks/watcher.js +19 -16
- package/src/tasks/write-html-files.js +11 -26
- package/src/template/template-collection.js +1 -1
- package/themes/umberto/src/gloria/js/app.js +0 -5
- package/themes/umberto/src/umberto/js/app.js +0 -5
- package/src/helpers/copy-file.js +0 -34
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [7.0.1](https://github.com/cksource/umberto/compare/v7.0.0...v7.0.1) (2025-05-14)
|
|
5
|
+
|
|
6
|
+
### Other changes
|
|
7
|
+
|
|
8
|
+
* Updated the project dependencies. Closes [#1253](https://github.com/cksource/umberto/issues/1253). ([commit](https://github.com/cksource/umberto/commit/28d74364207ab055ad76c2857d58cccb1866559b))
|
|
9
|
+
* Removed dependencies that can be replaced with native APIs or other already used dependencies. ([commit](https://github.com/cksource/umberto/commit/28d74364207ab055ad76c2857d58cccb1866559b))
|
|
10
|
+
* Sitemaps will be generated separately for each project. Closes [#1254](https://github.com/cksource/umberto/issues/1254). ([commit](https://github.com/cksource/umberto/commit/7968755b2a4b1c23768a9420292eb1d168b898b3))
|
|
11
|
+
|
|
12
|
+
|
|
4
13
|
## [7.0.0](https://github.com/cksource/umberto/compare/v6.1.2...v7.0.0) (2025-05-05)
|
|
5
14
|
|
|
6
15
|
### BREAKING CHANGES
|
package/hexo-config.json
CHANGED
|
@@ -15,16 +15,11 @@
|
|
|
15
15
|
"pug": {
|
|
16
16
|
"pretty": true
|
|
17
17
|
},
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
},
|
|
24
|
-
"markdown_it_plus": {
|
|
25
|
-
"highlight": false,
|
|
26
|
-
"html": true,
|
|
27
|
-
"breaks": true,
|
|
18
|
+
"syntax_highlighter": "",
|
|
19
|
+
"markdown_it_plus": {
|
|
20
|
+
"highlight": false,
|
|
21
|
+
"html": true,
|
|
22
|
+
"breaks": true,
|
|
28
23
|
"linkify": false,
|
|
29
24
|
"plugins": [
|
|
30
25
|
{
|
|
@@ -42,19 +37,19 @@
|
|
|
42
37
|
"plugin": {
|
|
43
38
|
"name": "markdown-it-expand-tabs",
|
|
44
39
|
"enable": true,
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
"options": {
|
|
41
|
+
"tabWidth": 4
|
|
47
42
|
}
|
|
48
43
|
}
|
|
49
44
|
}
|
|
50
45
|
]
|
|
51
46
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
"skip_render": [
|
|
48
|
+
"**/*.css",
|
|
49
|
+
"**/*.scss",
|
|
50
|
+
"**/*.html",
|
|
51
|
+
"**/*.json",
|
|
52
|
+
"**/*.js",
|
|
53
|
+
"**/*.txt"
|
|
59
54
|
]
|
|
60
55
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umberto",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"description": "CKSource Documentation builder",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -15,42 +15,36 @@
|
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@babel/core": "^7.18.10",
|
|
18
|
-
"@babel/polyfill": "^7.12.1",
|
|
19
18
|
"@babel/preset-env": "^7.18.10",
|
|
20
19
|
"@ckeditor/jsdoc-plugins": "^43.0.0",
|
|
21
|
-
"babel-loader": "^
|
|
22
|
-
"chalk": "^4.1.0",
|
|
20
|
+
"babel-loader": "^10.0.0",
|
|
23
21
|
"cheerio": "^1.0.0",
|
|
24
|
-
"cpx": "^1.5.0",
|
|
25
|
-
"del": "^6.1.1",
|
|
26
|
-
"element-closest": "^3.0.2",
|
|
27
22
|
"escape-string-regexp": "^4.0.0",
|
|
28
23
|
"fs-extra": "^11.0.0",
|
|
29
|
-
"fuse.js": "^
|
|
30
|
-
"glob": "^
|
|
31
|
-
"hexo": "^
|
|
32
|
-
"hexo-generator-archive": "^
|
|
33
|
-
"hexo-generator-category": "^
|
|
34
|
-
"hexo-generator-index": "^
|
|
35
|
-
"hexo-generator-tag": "^
|
|
24
|
+
"fuse.js": "^7.1.0",
|
|
25
|
+
"glob": "^11.0.2",
|
|
26
|
+
"hexo": "^7.3.0",
|
|
27
|
+
"hexo-generator-archive": "^2.0.0",
|
|
28
|
+
"hexo-generator-category": "^2.0.0",
|
|
29
|
+
"hexo-generator-index": "^4.0.0",
|
|
30
|
+
"hexo-generator-tag": "^2.0.0",
|
|
36
31
|
"hexo-render-pug": "^2.1.4",
|
|
37
32
|
"hexo-renderer-markdown-it-plus": "^1.0.5",
|
|
38
33
|
"htmlparser2": "^10.0.0",
|
|
39
34
|
"javascript-stringify": "^2.1.0",
|
|
40
|
-
"jquery": "~3.
|
|
35
|
+
"jquery": "~3.7.1",
|
|
41
36
|
"js-beautify": "^1.14.4",
|
|
42
37
|
"lodash": "^4.17.21",
|
|
43
|
-
"markdown-it": "^
|
|
38
|
+
"markdown-it": "^14.1.0",
|
|
44
39
|
"markdown-it-expand-tabs": "^1.0.13",
|
|
45
40
|
"markdown-it-toc-and-anchor": "^4.2.0",
|
|
46
41
|
"medium-zoom": "^1.0.6",
|
|
47
|
-
"minimatch": "^
|
|
48
|
-
"mkdirp": "^1.0.4",
|
|
42
|
+
"minimatch": "^10.0.1",
|
|
49
43
|
"moment": "^2.29.4",
|
|
50
|
-
"nyc": "^
|
|
44
|
+
"nyc": "^17.1.0",
|
|
51
45
|
"pug": "^3.0.2",
|
|
52
46
|
"sass": "^1.54.0",
|
|
53
|
-
"sitemap": "^
|
|
47
|
+
"sitemap": "^8.0.0",
|
|
54
48
|
"tippy.js": "^6.3.7",
|
|
55
49
|
"tree-model": "^1.0.7",
|
|
56
50
|
"upath": "^2.0.1",
|
|
@@ -79,6 +73,6 @@
|
|
|
79
73
|
"packages/**"
|
|
80
74
|
],
|
|
81
75
|
"hexo": {
|
|
82
|
-
"version": "
|
|
76
|
+
"version": "7.3.0"
|
|
83
77
|
}
|
|
84
78
|
}
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const chalk = require( 'chalk' );
|
|
8
|
+
const { format, styleText } = require( 'util' );
|
|
10
9
|
|
|
11
10
|
hexo.extend.filter.register( 'after_post_render', page => {
|
|
12
11
|
if ( !hexo.projectGlobals.common || !hexo.projectGlobals.common.verbose ) {
|
|
@@ -17,11 +16,11 @@ hexo.extend.filter.register( 'after_post_render', page => {
|
|
|
17
16
|
// Log only pages, which generates for longer than 1 second.
|
|
18
17
|
if ( time[ 0 ] > 1 ) {
|
|
19
18
|
console.log(
|
|
20
|
-
|
|
19
|
+
format(
|
|
21
20
|
'Page: %s was processed in: %s.%ss.',
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
styleText( 'cyanBright', page.source ),
|
|
22
|
+
styleText( 'yellow', time[ 0 ] ),
|
|
23
|
+
styleText( 'yellow', time[ 1 ] )
|
|
25
24
|
)
|
|
26
25
|
);
|
|
27
26
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const { styleText } = require( 'util' );
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Logs an error message about a cross-project reference found in the parsed expression.
|
|
@@ -19,8 +19,8 @@ const chalk = require( 'chalk' );
|
|
|
19
19
|
module.exports = function logCrossProjectReference( { expression, source } ) {
|
|
20
20
|
process.exitCode = 1;
|
|
21
21
|
|
|
22
|
-
const message = `${
|
|
23
|
-
const messageLocation = source ? ` in ${
|
|
22
|
+
const message = `${ styleText( 'red', 'Error:' ) } Failed while convert ${ styleText( 'cyanBright', expression ) } tag`;
|
|
23
|
+
const messageLocation = source ? ` in ${ styleText( 'magentaBright', source ) }.` : '.';
|
|
24
24
|
const messageDescription = ' Cross-project references are not supported.';
|
|
25
25
|
|
|
26
26
|
console.log( message + messageLocation + messageDescription );
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
const { styleText } = require( 'util' );
|
|
8
9
|
const upath = require( 'upath' );
|
|
9
10
|
const splitLongname = require( '../../src/helpers/split-longname' );
|
|
10
|
-
const chalk = require( 'chalk' );
|
|
11
11
|
|
|
12
12
|
const LINK_REGEXP = /\\?{(?:@linkapi|@link|@linksdk|@linkexample)\s+[^{]+?({[^}]+})?[^{}]*\\?}/g;
|
|
13
13
|
|
|
@@ -127,7 +127,7 @@ function linkToApi( str, data, hexo, { relativeUrlHelper, isSilentError } ) {
|
|
|
127
127
|
value: str,
|
|
128
128
|
source: data.source,
|
|
129
129
|
isSilent: isSilentError,
|
|
130
|
-
description: `Project ${
|
|
130
|
+
description: `Project ${ styleText( 'redBright', data.projectName ) } is not defined.`
|
|
131
131
|
} );
|
|
132
132
|
}
|
|
133
133
|
|
|
@@ -343,10 +343,16 @@ function onError( { value, source, isSilent, description } ) {
|
|
|
343
343
|
if ( !isSilent ) {
|
|
344
344
|
process.exitCode = 1;
|
|
345
345
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
346
|
+
const message = [
|
|
347
|
+
styleText( 'red', 'Error:' ),
|
|
348
|
+
`Failed to convert ${ styleText( 'cyanBright', value ) } tag`,
|
|
349
|
+
source && `in ${ styleText( 'magentaBright', source ) }`,
|
|
350
|
+
description && `because ${ styleText( 'italic', description ) }`
|
|
351
|
+
]
|
|
352
|
+
.filter( Boolean )
|
|
353
|
+
.join( ' ' );
|
|
354
|
+
|
|
355
|
+
console.log( message );
|
|
350
356
|
}
|
|
351
357
|
|
|
352
358
|
return value;
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
const { styleText } = require( 'util' );
|
|
8
9
|
const cheerio = require( 'cheerio' );
|
|
9
10
|
const splitLongname = require( '../../helpers/split-longname' );
|
|
10
|
-
const chalk = require( 'chalk' );
|
|
11
11
|
const macroReplacer = require( '../../tasks/macro-replacer' );
|
|
12
12
|
const findTargetDoclet = require( '../utils/findtargetdoclet' );
|
|
13
13
|
const { hasDedicatedApiPages, LONG_NAME_LABEL_REGEXP, LONG_NAME_MEMBER_SEPARATOR_REGEXP } = require( '../utils/utils' );
|
|
@@ -283,7 +283,7 @@ module.exports = class DescriptionParser {
|
|
|
283
283
|
replaceToPhrase = `<a href="${ href }">${ linkContent }</a>`;
|
|
284
284
|
} else {
|
|
285
285
|
console.log(
|
|
286
|
-
`${
|
|
286
|
+
`${ styleText( 'yellow', 'Warning:' ) } Invalid link in API docs: ${ styleText( 'gray', fullMatch ) }.`,
|
|
287
287
|
'There is no doclet of the link target.'
|
|
288
288
|
);
|
|
289
289
|
|
package/src/helpers/snippets.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
|
-
const
|
|
9
|
+
const { globSync } = require( 'glob' );
|
|
10
10
|
|
|
11
11
|
const utils = {
|
|
12
12
|
/**
|
|
@@ -36,14 +36,15 @@ const utils = {
|
|
|
36
36
|
* @returns {SnippetSource}
|
|
37
37
|
*/
|
|
38
38
|
getSnippetSourcePaths( basePath, snippetName ) {
|
|
39
|
-
const snippetPaths = glob.sync( upath.join( basePath, snippetName + '.*' ) );
|
|
40
39
|
const files = {};
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
globSync( upath.join( basePath, snippetName + '.*' ) )
|
|
42
|
+
.map( path => upath.normalize( path ) )
|
|
43
|
+
.forEach( singlePath => {
|
|
44
|
+
const fileExtension = upath.extname( singlePath ).slice( 1 );
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
files[ fileExtension ] = singlePath;
|
|
47
|
+
} );
|
|
47
48
|
|
|
48
49
|
return files;
|
|
49
50
|
},
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
|
-
const
|
|
9
|
+
const { globSync } = require( 'glob' );
|
|
10
10
|
|
|
11
11
|
module.exports = ( {
|
|
12
12
|
rootPath,
|
|
@@ -18,10 +18,9 @@ module.exports = ( {
|
|
|
18
18
|
|
|
19
19
|
for ( const item of packages ) {
|
|
20
20
|
const packageRepoUrl = getRepoUrl( upath.join( rootPath, item.path ) );
|
|
21
|
-
|
|
22
|
-
.map( p =>
|
|
23
|
-
|
|
24
|
-
} )
|
|
21
|
+
globSync( upath.join( rootPath, item.path, 'docs', '**', '*.md' ) )
|
|
22
|
+
.map( p => upath.normalize( p ) )
|
|
23
|
+
.map( p => p.replace( upath.join( rootPath, item.path, 'docs' ), '' ) )
|
|
25
24
|
.forEach( p => {
|
|
26
25
|
guidesToRepos[ p ] = packageRepoUrl;
|
|
27
26
|
} );
|
package/src/hexo-manager.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
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
|
|
11
|
+
const { globSync } = require( 'glob' );
|
|
11
12
|
const Hexo = require( '../hexo-shim' );
|
|
13
|
+
const getHexoConfig = require( './tasks/get-hexo-config' );
|
|
12
14
|
const extendConfig = require( './hexo/filter/extend-config' );
|
|
13
|
-
const chalk = require( 'chalk' );
|
|
14
|
-
const glob = require( 'glob' );
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* Class used to initialize and control hexo.
|
|
@@ -106,7 +106,9 @@ class HexoManager {
|
|
|
106
106
|
return this.hexo.exit();
|
|
107
107
|
} )
|
|
108
108
|
.catch( err => {
|
|
109
|
-
console.log(
|
|
109
|
+
console.log(
|
|
110
|
+
`${ styleText( 'red', 'Error:' ) } ${ styleText( 'redBright', 'There was something wrong during hexo generation.' ) }`
|
|
111
|
+
);
|
|
110
112
|
this.hexo.exit( err );
|
|
111
113
|
|
|
112
114
|
throw err;
|
|
@@ -132,14 +134,16 @@ class HexoManager {
|
|
|
132
134
|
|
|
133
135
|
cleanSymLinks() {
|
|
134
136
|
const rootPath = this.config.public_dir;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
137
|
+
globSync( upath.join( rootPath, '**', 'latest' ) )
|
|
138
|
+
.concat( globSync( upath.join( rootPath, 'latest' ) ) )
|
|
139
|
+
.map( p => upath.normalize( p ) )
|
|
140
|
+
.forEach( p => {
|
|
141
|
+
const stat = fs.lstatSync( p );
|
|
142
|
+
|
|
143
|
+
if ( stat.isSymbolicLink() ) {
|
|
144
|
+
fs.unlinkSync( p );
|
|
145
|
+
}
|
|
146
|
+
} );
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
/**
|
package/src/index.js
CHANGED
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
+
const { styleText } = require( 'util' );
|
|
8
9
|
const path = require( 'path' );
|
|
9
|
-
const chalk = require( 'chalk' );
|
|
10
10
|
const compileSass = require( './tasks/compile-sass' );
|
|
11
11
|
const runWebpack = require( './tasks/run-webpack' );
|
|
12
12
|
const copyAssets = require( './tasks/copy-assets' );
|
|
@@ -38,7 +38,7 @@ module.exports = {
|
|
|
38
38
|
|
|
39
39
|
await buildAndWatch( options );
|
|
40
40
|
} catch ( err ) {
|
|
41
|
-
console.error(
|
|
41
|
+
console.error( styleText( 'redBright', `Building documentation failed: ${ err.stack }` ) );
|
|
42
42
|
process.exitCode = 1;
|
|
43
43
|
|
|
44
44
|
throw err;
|
|
@@ -55,7 +55,7 @@ module.exports = {
|
|
|
55
55
|
try {
|
|
56
56
|
await buildAndWatch( options );
|
|
57
57
|
} catch ( err ) {
|
|
58
|
-
console.error(
|
|
58
|
+
console.error( styleText( 'redBright', `Building documentation failed: ${ err.stack }` ) );
|
|
59
59
|
process.exitCode = 1;
|
|
60
60
|
|
|
61
61
|
throw err;
|
|
@@ -93,7 +93,7 @@ async function buildAndWatch( options ) {
|
|
|
93
93
|
|
|
94
94
|
const [ time ] = process.hrtime( timer );
|
|
95
95
|
|
|
96
|
-
console.log(
|
|
96
|
+
console.log( styleText( 'greenBright', `Building documentation complete in ${ Math.floor( time / 60 ) }m ${ time % 60 }s.` ) );
|
|
97
97
|
|
|
98
98
|
if ( options.watch ) {
|
|
99
99
|
return watcher( hexoManager );
|
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
|
|
8
8
|
const fs = require( 'fs' );
|
|
9
9
|
const upath = require( 'upath' );
|
|
10
|
-
const
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
package/src/tasks/cache-files.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
|
-
const
|
|
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 =
|
|
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 ) {
|
package/src/tasks/copy-files.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
9
|
const fs = require( 'fs-extra' );
|
|
10
|
-
const
|
|
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 =
|
|
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
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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 {
|
|
17
|
-
* @param {String}
|
|
18
|
-
* @param {String}
|
|
19
|
-
* @param {
|
|
20
|
-
* @param {
|
|
21
|
-
* @param {
|
|
22
|
-
* @
|
|
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 =
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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 (
|
|
59
|
+
if ( excluded.find( excluded => filePath.includes( excluded ) ) ) {
|
|
42
60
|
continue;
|
|
43
61
|
}
|
|
44
62
|
|
|
45
|
-
|
|
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(
|
|
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
|
|
9
|
-
const upath = require( 'upath' );
|
|
8
|
+
const { styleText } = require( 'util' );
|
|
10
9
|
const fs = require( 'fs' );
|
|
11
|
-
const
|
|
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(
|
|
38
|
-
const destinationPath = upath.join( rootPath, 'build', 'docs',
|
|
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(
|
|
46
|
-
console.log( `Symlink for ${
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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(
|
|
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(
|
|
117
|
+
console.log( styleText( 'gray', ` * '${ url.href }' - ${ url.text.replace( /\s+/g, ' ' ) }` ) );
|
|
115
118
|
}
|
|
116
119
|
}
|
|
117
120
|
}
|
package/src/tasks/watcher.js
CHANGED
|
@@ -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
|
|
10
|
-
const
|
|
10
|
+
const chokidar = require( 'chokidar' );
|
|
11
|
+
const { copy } = require( 'fs-extra' );
|
|
11
12
|
|
|
12
|
-
module.exports =
|
|
13
|
-
console.log(
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
25
|
-
|
|
26
|
-
process.exit();
|
|
27
|
-
} );
|
|
28
|
-
} );
|
|
30
|
+
return copy( file, dest );
|
|
31
|
+
}
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const fs = require( 'fs' );
|
|
9
|
-
const mkdirp = require( 'mkdirp' );
|
|
8
|
+
const fs = require( 'fs-extra' );
|
|
10
9
|
const upath = require( 'upath' );
|
|
11
10
|
|
|
12
11
|
/**
|
|
@@ -14,29 +13,15 @@ const upath = require( 'upath' );
|
|
|
14
13
|
*
|
|
15
14
|
* @param {Array.<HtmlFile>} files HtmlFile objects containing content to be written to .html files to file system.
|
|
16
15
|
* @param {String} destinationDir Additional destination path. Additional because files already have its own path.
|
|
17
|
-
* @returns {Promise}
|
|
16
|
+
* @returns {Promise<void>}
|
|
18
17
|
*/
|
|
19
|
-
module.exports = ( files, destinationDir = '.' ) => {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
fs.writeFile( upath.join( fileDir, file.basename ), file.content, err => {
|
|
29
|
-
if ( err ) {
|
|
30
|
-
return reject( err );
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return resolve();
|
|
34
|
-
} );
|
|
35
|
-
} );
|
|
36
|
-
} );
|
|
37
|
-
|
|
38
|
-
promises.push( promise );
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return Promise.all( promises );
|
|
18
|
+
module.exports = async ( files, destinationDir = '.' ) => {
|
|
19
|
+
const writePromises = files.map( file =>
|
|
20
|
+
fs.outputFile(
|
|
21
|
+
upath.join( destinationDir, file.dirname, file.basename ),
|
|
22
|
+
file.content
|
|
23
|
+
)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
return Promise.all( writePromises );
|
|
42
27
|
};
|
|
@@ -15,7 +15,7 @@ const splitLongname = require( '../helpers/split-longname' );
|
|
|
15
15
|
const extractLongname = require( '../helpers/extract-longname' );
|
|
16
16
|
const getApiInfoboxTooltip = require( '../helpers/get-api-infobox-tooltip' );
|
|
17
17
|
const capitalize = require( '../helpers/capitalize' );
|
|
18
|
-
const relative_url = require( 'hexo/
|
|
18
|
+
const relative_url = require( 'hexo/dist/plugins/helper/relative_url' ); // eslint-disable-line camelcase
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Provides pug templates and adds various helpers to them.
|
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// Polyfill for `window.Symbol`.
|
|
7
|
-
import '@babel/polyfill';
|
|
8
|
-
// Polyfill for `Element.closest()`.
|
|
9
|
-
import 'element-closest/browser';
|
|
10
|
-
|
|
11
6
|
import $ from 'jquery';
|
|
12
7
|
import { setupPrism } from './_prism';
|
|
13
8
|
import { enableCollapsables, hideTogglers } from './_collapsables';
|
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
* For licensing, see LICENSE.md.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
// Polyfill for `window.Symbol`.
|
|
7
|
-
import '@babel/polyfill';
|
|
8
|
-
// Polyfill for `Element.closest()`.
|
|
9
|
-
import 'element-closest/browser';
|
|
10
|
-
|
|
11
6
|
import $ from 'jquery';
|
|
12
7
|
import { setupPrism } from './_prism';
|
|
13
8
|
import { enableCollapsables, hideTogglers } from './_collapsables';
|
package/src/helpers/copy-file.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
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
|
-
'use strict';
|
|
7
|
-
|
|
8
|
-
const fs = require( 'fs' );
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Copies a specified file from the `source` path to the `destination` path.
|
|
12
|
-
*
|
|
13
|
-
* @param {String} source
|
|
14
|
-
* @param {String} destination
|
|
15
|
-
* @return {Promise}
|
|
16
|
-
*/
|
|
17
|
-
module.exports = function copyFile( source, destination ) {
|
|
18
|
-
return new Promise( ( resolve, reject ) => {
|
|
19
|
-
const readStream = fs.createReadStream( source );
|
|
20
|
-
|
|
21
|
-
// In order to catch an error if `source` points to non-existing file, we need to wait for
|
|
22
|
-
// the `#open` event emitted by the read readStream.
|
|
23
|
-
readStream.on( 'open', () => {
|
|
24
|
-
const writeStream = fs.createWriteStream( destination );
|
|
25
|
-
|
|
26
|
-
readStream.pipe( writeStream );
|
|
27
|
-
|
|
28
|
-
writeStream.on( 'error', reject );
|
|
29
|
-
writeStream.on( 'finish', resolve );
|
|
30
|
-
} );
|
|
31
|
-
|
|
32
|
-
readStream.on( 'error', reject );
|
|
33
|
-
} );
|
|
34
|
-
};
|