@antora/content-classifier 3.1.9 → 3.1.11
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/lib/classify-content.js +54 -32
- package/lib/content-catalog.js +213 -149
- package/lib/util/resolve-resource.js +1 -3
- package/lib/util/summarize-file-location.js +1 -1
- package/lib/util/version-compare-desc.js +11 -19
- package/package.json +11 -7
package/lib/classify-content.js
CHANGED
|
@@ -10,50 +10,66 @@ const summarizeFileLocation = require('./util/summarize-file-location')
|
|
|
10
10
|
*
|
|
11
11
|
* @memberof content-classifier
|
|
12
12
|
*
|
|
13
|
-
* @param {Object} playbook - The configuration object for Antora.
|
|
13
|
+
* @param {Object} playbook - The configuration object for Antora. See ContentCatalog constructor for relevant keys.
|
|
14
14
|
* @param {Object} playbook.site - Site-related configuration data.
|
|
15
15
|
* @param {String} playbook.site.startPage - The start page for the site; redirects from base URL.
|
|
16
|
-
* @param {Object} playbook.urls - URL settings for the site.
|
|
17
|
-
* @param {String} playbook.urls.htmlExtensionStyle - The style to use when computing page URLs.
|
|
18
16
|
* @param {Object} aggregate - The raw aggregate of virtual file objects to be classified.
|
|
19
17
|
* @param {Object} [siteAsciiDocConfig={}] - Site-wide AsciiDoc processor configuration options.
|
|
20
|
-
* @
|
|
18
|
+
* @param {Function} [onComponentsRegistered] - A function (optionally async) to invoke after components are
|
|
19
|
+
* registered. Must return an instance of ContentCatalog. If async, this function will also return a Promise.
|
|
20
|
+
*
|
|
21
|
+
* @returns {ContentCatalog} A structured catalog of content components, versions, and virtual content files.
|
|
21
22
|
*/
|
|
22
|
-
function classifyContent (playbook, aggregate, siteAsciiDocConfig = {}) {
|
|
23
|
-
const
|
|
24
|
-
aggregate
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
23
|
+
function classifyContent (playbook, aggregate, siteAsciiDocConfig = {}, onComponentsRegistered = undefined) {
|
|
24
|
+
const siteStartPage = playbook.site.startPage
|
|
25
|
+
let contentCatalog = registerComponentVersions(new ContentCatalog(playbook), aggregate, siteAsciiDocConfig)
|
|
26
|
+
return typeof onComponentsRegistered === 'function' &&
|
|
27
|
+
(contentCatalog = onComponentsRegistered(contentCatalog)) instanceof Promise
|
|
28
|
+
? contentCatalog.then((contentCatalogValue) => addFilesAndRegisterStartPages(contentCatalogValue, siteStartPage))
|
|
29
|
+
: addFilesAndRegisterStartPages(contentCatalog, siteStartPage)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function registerComponentVersions (contentCatalog, aggregate, siteAsciiDocConfig) {
|
|
33
|
+
for (const componentVersionBucket of aggregate) {
|
|
34
|
+
// advance files, nav, and startPage to component version to be used in later phase
|
|
35
|
+
const { name, version, files, nav, startPage, ...data } = Object.assign(componentVersionBucket, {
|
|
36
|
+
asciidoc: resolveAsciiDocConfig(siteAsciiDocConfig, componentVersionBucket),
|
|
37
|
+
})
|
|
38
|
+
Object.assign(contentCatalog.registerComponentVersion(name, version, data), { files, nav, startPage })
|
|
39
|
+
}
|
|
40
|
+
return contentCatalog
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function addFilesAndRegisterStartPages (contentCatalog, siteStartPage) {
|
|
44
|
+
for (const { versions: componentVersions } of contentCatalog.getComponents()) {
|
|
45
|
+
for (const componentVersion of componentVersions) {
|
|
46
|
+
const { name: component, version, files = [], nav, startPage } = componentVersion
|
|
39
47
|
const navResolved = nav && (nav.resolved = new Set())
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
for (let file, i = 0, len = files.length; i < len; i++) {
|
|
49
|
+
allocateSrc((file = files[i]), component, version, nav) && contentCatalog.addFile(file, componentVersion)
|
|
50
|
+
files[i] = undefined // free memory
|
|
51
|
+
}
|
|
42
52
|
if (navResolved && nav.length > navResolved.size && new Set(nav).size > navResolved.size) {
|
|
43
53
|
const loc = summarizeFileLocation({ path: 'antora.yml', src: { origin: nav.origin } })
|
|
44
54
|
for (const filepath of nav) {
|
|
45
55
|
if (navResolved.has(filepath)) continue
|
|
46
|
-
logger.warn('Could not resolve nav entry for %s@%s defined in %s: %s', version,
|
|
56
|
+
logger.warn('Could not resolve nav entry for %s@%s defined in %s: %s', version, component, loc, filepath)
|
|
47
57
|
}
|
|
48
58
|
}
|
|
49
|
-
contentCatalog.registerComponentVersionStartPage(
|
|
50
|
-
}
|
|
51
|
-
|
|
59
|
+
contentCatalog.registerComponentVersionStartPage(component, componentVersion, startPage)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
contentCatalog.registerSiteStartPage(siteStartPage)
|
|
52
63
|
return contentCatalog
|
|
53
64
|
}
|
|
54
65
|
|
|
55
66
|
function allocateSrc (file, component, version, nav) {
|
|
56
|
-
const extname = file.src
|
|
67
|
+
const { extname, family } = file.src
|
|
68
|
+
if (family && family !== 'nav') {
|
|
69
|
+
Object.assign(file.src, { component, version })
|
|
70
|
+
file.src.moduleRootPath ??= calculateRootPath(file.src.relative.split('/').length)
|
|
71
|
+
return true
|
|
72
|
+
}
|
|
57
73
|
const filepath = file.path
|
|
58
74
|
const pathSegments = filepath.split('/')
|
|
59
75
|
let navInfo
|
|
@@ -140,13 +156,19 @@ function getNavInfo (filepath, nav) {
|
|
|
140
156
|
if (~index) return nav.resolved.add(filepath) && { index }
|
|
141
157
|
}
|
|
142
158
|
|
|
143
|
-
function resolveAsciiDocConfig (siteAsciiDocConfig, { asciidoc, origins = [] }) {
|
|
144
|
-
const scopedAttributes =
|
|
159
|
+
function resolveAsciiDocConfig (siteAsciiDocConfig, { name, version, asciidoc, origins = [] }) {
|
|
160
|
+
const scopedAttributes = asciidoc?.attributes
|
|
145
161
|
if (scopedAttributes) {
|
|
146
|
-
const initial = siteAsciiDocConfig.attributes
|
|
162
|
+
const initial = Object.assign({}, siteAsciiDocConfig.attributes)
|
|
163
|
+
initial['antora-component-name'] = name
|
|
164
|
+
initial['antora-component-version'] = version
|
|
147
165
|
const mdc = { file: { path: 'antora.yml', origin: origins[origins.length - 1] } }
|
|
148
166
|
const attributes = collateAsciiDocAttributes(scopedAttributes, { initial, mdc, merge: true })
|
|
149
|
-
if (attributes !== initial)
|
|
167
|
+
if (attributes !== initial) {
|
|
168
|
+
delete attributes['antora-component-name']
|
|
169
|
+
delete attributes['antora-component-version']
|
|
170
|
+
return Object.assign({}, siteAsciiDocConfig, { attributes })
|
|
171
|
+
}
|
|
150
172
|
}
|
|
151
173
|
return siteAsciiDocConfig
|
|
152
174
|
}
|
package/lib/content-catalog.js
CHANGED
|
@@ -5,13 +5,12 @@ const invariably = { void: () => undefined }
|
|
|
5
5
|
const logger = require('./logger')
|
|
6
6
|
const { lookup: resolveMimeType } = require('./mime-types-with-asciidoc')
|
|
7
7
|
const parseResourceId = require('./util/parse-resource-id')
|
|
8
|
-
const { posix: path } = require('path')
|
|
8
|
+
const { posix: path } = require('node:path')
|
|
9
9
|
const resolveResource = require('./util/resolve-resource')
|
|
10
10
|
const summarizeFileLocation = require('./util/summarize-file-location')
|
|
11
11
|
const versionCompare = require('./util/version-compare-desc')
|
|
12
12
|
|
|
13
13
|
const { ROOT_INDEX_ALIAS_ID, ROOT_INDEX_PAGE_ID } = require('./constants')
|
|
14
|
-
const SPACE_RX = / /g
|
|
15
14
|
const LOG_WRAP = '\n '
|
|
16
15
|
|
|
17
16
|
const $components = Symbol('components')
|
|
@@ -24,17 +23,17 @@ class ContentCatalog {
|
|
|
24
23
|
const urls = playbook.urls || {}
|
|
25
24
|
this.htmlUrlExtensionStyle = urls.htmlExtensionStyle || 'default'
|
|
26
25
|
this.urlRedirectFacility = urls.redirectFacility || 'static'
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
29
|
-
if (this.
|
|
30
|
-
this.
|
|
26
|
+
this.latestVersionSegment = urls.latestVersionSegment
|
|
27
|
+
this.latestPrereleaseVersionSegment = urls.latestPrereleaseVersionSegment
|
|
28
|
+
if (this.latestVersionSegment == null && this.latestPrereleaseVersionSegment == null) {
|
|
29
|
+
this.latestVersionSegmentStrategy = undefined
|
|
31
30
|
} else {
|
|
32
|
-
this.
|
|
33
|
-
if (this.
|
|
34
|
-
if (!this.
|
|
35
|
-
if (!this.
|
|
36
|
-
this.
|
|
37
|
-
if (!this.
|
|
31
|
+
this.latestVersionSegmentStrategy = urls.latestVersionSegmentStrategy || 'replace'
|
|
32
|
+
if (this.latestVersionSegmentStrategy === 'redirect:from') {
|
|
33
|
+
if (!this.latestVersionSegment) this.latestVersionSegment = undefined
|
|
34
|
+
if (!this.latestPrereleaseVersionSegment) {
|
|
35
|
+
this.latestPrereleaseVersionSegment = undefined
|
|
36
|
+
if (!this.latestVersionSegment) this.latestVersionSegmentStrategy = undefined
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
}
|
|
@@ -43,6 +42,8 @@ class ContentCatalog {
|
|
|
43
42
|
/**
|
|
44
43
|
* Registers a new component version with the content catalog. Also registers the component if it does not yet exist.
|
|
45
44
|
*
|
|
45
|
+
* Must be followed by a call to registerComponentVersionStartPage to finalize object.
|
|
46
|
+
*
|
|
46
47
|
* @param {String} name - The name of the component to which this component version belongs.
|
|
47
48
|
* @param {String} version - The version of the component to register.
|
|
48
49
|
* @param {Object} [descriptor={}] - The configuration data for the component version.
|
|
@@ -59,8 +60,9 @@ class ContentCatalog {
|
|
|
59
60
|
* @returns {Object} The constructed component version object.
|
|
60
61
|
*/
|
|
61
62
|
registerComponentVersion (name, version, descriptor = {}) {
|
|
62
|
-
const { asciidoc, displayVersion, prerelease, startPage: startPageSpec, title } = descriptor
|
|
63
|
+
const { asciidoc, displayVersion, prerelease, startPage: startPageSpec, title, versionSegment } = descriptor
|
|
63
64
|
const componentVersion = { displayVersion: displayVersion || version || 'default', title: title || name, version }
|
|
65
|
+
if (versionSegment != null) componentVersion.versionSegment = versionSegment
|
|
64
66
|
Object.defineProperty(componentVersion, 'name', { value: name, enumerable: true })
|
|
65
67
|
if (prerelease) {
|
|
66
68
|
componentVersion.prerelease = prerelease
|
|
@@ -84,10 +86,10 @@ class ContentCatalog {
|
|
|
84
86
|
let lastVerdict
|
|
85
87
|
const insertIdx = version
|
|
86
88
|
? componentVersions.findIndex(({ version: candidateVersion, prerelease: candidatePrerelease }) => {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
return (lastVerdict = versionCompare(candidateVersion, version)) > 1
|
|
90
|
+
? !!prerelease === !!candidatePrerelease
|
|
91
|
+
: lastVerdict > 0 || (lastVerdict < -1 && prerelease && !candidatePrerelease)
|
|
92
|
+
})
|
|
91
93
|
: prerelease
|
|
92
94
|
? -1
|
|
93
95
|
: ~(~componentVersions.findIndex(({ prerelease: candidatePrerelease }) => !candidatePrerelease) || -1)
|
|
@@ -129,51 +131,50 @@ class ContentCatalog {
|
|
|
129
131
|
)
|
|
130
132
|
}
|
|
131
133
|
if (startPageSpec) {
|
|
134
|
+
// @deprecated use separate call to register start page for component version
|
|
132
135
|
this.registerComponentVersionStartPage(name, componentVersion, startPageSpec === true ? undefined : startPageSpec)
|
|
133
136
|
}
|
|
134
137
|
return componentVersion
|
|
135
138
|
}
|
|
136
139
|
|
|
137
|
-
addFile (file) {
|
|
140
|
+
addFile (file, componentVersion) {
|
|
138
141
|
const src = file.src
|
|
139
|
-
let family = src
|
|
142
|
+
let { component, version, family } = src
|
|
140
143
|
let filesForFamily = this[$files].get(family)
|
|
141
144
|
if (!filesForFamily) this[$files].set(family, (filesForFamily = new Map()))
|
|
142
145
|
const key = generateKey(src)
|
|
143
146
|
if (filesForFamily.has(key)) {
|
|
144
147
|
if (family === 'alias') {
|
|
145
148
|
throw new Error(`Duplicate alias: ${generateResourceSpec(src)}`)
|
|
146
|
-
} else {
|
|
147
|
-
const details = [filesForFamily.get(key), file]
|
|
148
|
-
.map((it, idx) => `${idx + 1}: ${summarizeFileLocation(it)}`)
|
|
149
|
-
.join(LOG_WRAP)
|
|
150
|
-
if (family === 'nav') {
|
|
151
|
-
throw new Error(`Duplicate nav in ${src.version}@${src.component}: ${file.path}${LOG_WRAP}${details}`)
|
|
152
|
-
} else {
|
|
153
|
-
throw new Error(`Duplicate ${family}: ${generateResourceSpec(src)}${LOG_WRAP}${details}`)
|
|
154
|
-
}
|
|
155
149
|
}
|
|
150
|
+
const details = [filesForFamily.get(key), file]
|
|
151
|
+
.map((it, idx) => `${idx + 1}: ${summarizeFileLocation(it)}`)
|
|
152
|
+
.join(LOG_WRAP)
|
|
153
|
+
if (family === 'nav') {
|
|
154
|
+
throw new Error(`Duplicate nav file: ${file.path} in ${version}@${component}${LOG_WRAP}${details}`)
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`Duplicate ${family}: ${generateResourceSpec(src)}${LOG_WRAP}${details}`)
|
|
156
157
|
}
|
|
157
|
-
// NOTE: if the
|
|
158
|
-
// another option is to assume that if the file is not a vinyl object, the src likely needs to be prepared
|
|
158
|
+
// NOTE: assume that if the file is not a vinyl object, the src likely needs to be prepared
|
|
159
159
|
// a vinyl object is one indication the file was created and prepared by the content aggregator
|
|
160
|
-
//if
|
|
161
|
-
//if (!File.isVinyl(file)) file = new File(file)
|
|
160
|
+
// an alternate approach would be to call prepareSrc if the path property is not set
|
|
162
161
|
if (!File.isVinyl(file)) {
|
|
163
162
|
prepareSrc(src)
|
|
164
163
|
file = new File(file)
|
|
165
164
|
}
|
|
166
165
|
if (family === 'alias') {
|
|
167
|
-
src.mediaType = 'text/asciidoc'
|
|
168
166
|
file.mediaType = 'text/html'
|
|
169
167
|
// NOTE: an alias masquerades as the target file
|
|
170
168
|
family = file.rel.src.family
|
|
171
|
-
//
|
|
169
|
+
// NOTE: short circuit in case of splat alias (alias -> alias)
|
|
170
|
+
if (family === 'alias' && file.pub?.splat) return filesForFamily.set(key, file) && file
|
|
171
|
+
src.mediaType = 'text/asciidoc'
|
|
172
172
|
} else if (!(file.mediaType = src.mediaType) && !('mediaType' in src)) {
|
|
173
|
+
// QUESTION: should we preserve the mediaType property on file if already defined?
|
|
173
174
|
file.mediaType = src.mediaType = resolveMimeType(src.extname) || (family === 'page' ? 'text/asciidoc' : undefined)
|
|
174
175
|
}
|
|
175
176
|
let publishable
|
|
176
|
-
let
|
|
177
|
+
let activeVersionSegment
|
|
177
178
|
if (file.out) {
|
|
178
179
|
publishable = true
|
|
179
180
|
} else if ('out' in file) {
|
|
@@ -183,15 +184,24 @@ class ContentCatalog {
|
|
|
183
184
|
('/' + src.relative).indexOf('/_') < 0
|
|
184
185
|
) {
|
|
185
186
|
publishable = true
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
if (componentVersion == null) componentVersion = this.getComponentVersion(component, version) || { version }
|
|
188
|
+
activeVersionSegment =
|
|
189
|
+
'activeVersionSegment' in componentVersion
|
|
190
|
+
? componentVersion.activeVersionSegment
|
|
191
|
+
: computeVersionSegment.call(this, componentVersion)
|
|
192
|
+
file.out = computeOut(src, family, activeVersionSegment, this.htmlUrlExtensionStyle)
|
|
188
193
|
}
|
|
189
194
|
if (!file.pub && (publishable || family === 'nav')) {
|
|
190
|
-
if (
|
|
191
|
-
|
|
195
|
+
if (activeVersionSegment == null) {
|
|
196
|
+
if (componentVersion == null) componentVersion = this.getComponentVersion(component, version) || { version }
|
|
197
|
+
activeVersionSegment =
|
|
198
|
+
'activeVersionSegment' in componentVersion
|
|
199
|
+
? componentVersion.activeVersionSegment
|
|
200
|
+
: computeVersionSegment.call(this, componentVersion)
|
|
201
|
+
}
|
|
202
|
+
file.pub = computePub(src, file.out, family, activeVersionSegment, this.htmlUrlExtensionStyle)
|
|
192
203
|
}
|
|
193
|
-
filesForFamily.set(key, file)
|
|
194
|
-
return file
|
|
204
|
+
return filesForFamily.set(key, file) && file
|
|
195
205
|
}
|
|
196
206
|
|
|
197
207
|
removeFile (file) {
|
|
@@ -234,7 +244,7 @@ class ContentCatalog {
|
|
|
234
244
|
}
|
|
235
245
|
|
|
236
246
|
getComponentVersion (component, version) {
|
|
237
|
-
return (component.versions ||
|
|
247
|
+
return (component.versions || this.getComponent(component)?.versions || []).find(
|
|
238
248
|
({ version: candidate }) => candidate === version
|
|
239
249
|
)
|
|
240
250
|
}
|
|
@@ -262,45 +272,54 @@ class ContentCatalog {
|
|
|
262
272
|
const accum = []
|
|
263
273
|
for (const candidate of candidates.values()) filter(candidate) && accum.push(candidate)
|
|
264
274
|
return accum
|
|
265
|
-
} else {
|
|
266
|
-
return [...candidates.values()]
|
|
267
275
|
}
|
|
276
|
+
return [...candidates.values()]
|
|
268
277
|
}
|
|
269
278
|
|
|
270
279
|
// TODO add `follow` argument to control whether alias is followed
|
|
271
280
|
getSiteStartPage () {
|
|
272
|
-
|
|
281
|
+
let file
|
|
282
|
+
if ((file = this.getById(ROOT_INDEX_PAGE_ID))) return file
|
|
283
|
+
if ((file = this.getById(ROOT_INDEX_ALIAS_ID))) return file.rel
|
|
284
|
+
const rootComponent = this.getComponent('ROOT')
|
|
285
|
+
if (!rootComponent) return
|
|
286
|
+
const version = rootComponent.versions.find(({ activeVersionSegment }) => activeVersionSegment === '')?.version
|
|
287
|
+
if (!version) return
|
|
288
|
+
if ((file = this.getById(Object.assign({}, ROOT_INDEX_PAGE_ID, { version })))) return file
|
|
289
|
+
if ((file = this.getById(Object.assign({}, ROOT_INDEX_ALIAS_ID, { version })))) return file.rel
|
|
273
290
|
}
|
|
274
291
|
|
|
275
292
|
registerComponentVersionStartPage (name, componentVersion, startPageSpec = undefined) {
|
|
293
|
+
const component = name
|
|
276
294
|
let version = componentVersion.version
|
|
277
295
|
if (version == null) {
|
|
278
296
|
// QUESTION: should we warn or throw error if component version cannot be found?
|
|
279
|
-
if (!(componentVersion = this.getComponentVersion(
|
|
297
|
+
if (!(componentVersion = this.getComponentVersion(component, componentVersion))) return
|
|
280
298
|
version = componentVersion.version
|
|
281
299
|
}
|
|
300
|
+
const activeVersionSegment = computeVersionSegment.call(this, componentVersion)
|
|
282
301
|
let startPage
|
|
283
302
|
let startPageSrc
|
|
284
|
-
const indexPageId = Object.assign({}, ROOT_INDEX_PAGE_ID, { component
|
|
303
|
+
const indexPageId = Object.assign({}, ROOT_INDEX_PAGE_ID, { component, version })
|
|
285
304
|
if (startPageSpec) {
|
|
286
305
|
if (
|
|
287
306
|
(startPage = this.resolvePage(startPageSpec, indexPageId)) &&
|
|
288
|
-
(startPageSrc = startPage.src).component ===
|
|
307
|
+
(startPageSrc = startPage.src).component === component &&
|
|
289
308
|
startPageSrc.version === version
|
|
290
309
|
) {
|
|
291
310
|
if (!this.getById(indexPageId)) {
|
|
292
|
-
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component
|
|
311
|
+
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component, version })
|
|
293
312
|
const indexAlias = this.getById(indexAliasId)
|
|
294
313
|
indexAlias
|
|
295
314
|
? indexAlias.synthetic && Object.assign(indexAlias, { rel: startPage })
|
|
296
|
-
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true })
|
|
315
|
+
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true }, componentVersion)
|
|
297
316
|
}
|
|
298
317
|
} else {
|
|
299
318
|
// TODO pass componentVersion as logObject
|
|
300
319
|
logger.warn(
|
|
301
320
|
'Start page specified for %s@%s %s: %s',
|
|
302
321
|
version,
|
|
303
|
-
|
|
322
|
+
component,
|
|
304
323
|
startPage === false ? 'has invalid syntax' : 'not found',
|
|
305
324
|
startPageSpec
|
|
306
325
|
)
|
|
@@ -311,25 +330,34 @@ class ContentCatalog {
|
|
|
311
330
|
}
|
|
312
331
|
if (startPage) {
|
|
313
332
|
componentVersion.url = startPage.pub.url
|
|
314
|
-
} else {
|
|
333
|
+
} else if (!componentVersion.url) {
|
|
315
334
|
// QUESTION: should we warn if the default start page cannot be found?
|
|
316
|
-
const versionSegment = computeVersionSegment.call(this, name, version)
|
|
317
335
|
componentVersion.url = computePub(
|
|
318
336
|
(startPageSrc = prepareSrc(Object.assign({}, indexPageId, { family: 'page' }))),
|
|
319
|
-
computeOut(startPageSrc, startPageSrc.family,
|
|
337
|
+
computeOut(startPageSrc, startPageSrc.family, activeVersionSegment, this.htmlUrlExtensionStyle),
|
|
320
338
|
startPageSrc.family,
|
|
321
|
-
|
|
339
|
+
activeVersionSegment,
|
|
322
340
|
this.htmlUrlExtensionStyle
|
|
323
341
|
).url
|
|
324
342
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
343
|
+
Object.defineProperties(componentVersion, {
|
|
344
|
+
activeVersionSegment:
|
|
345
|
+
activeVersionSegment === version
|
|
346
|
+
? { configurable: true, enumerable: false, get: getVersion }
|
|
347
|
+
: { configurable: true, enumerable: false, value: activeVersionSegment },
|
|
348
|
+
files: {
|
|
349
|
+
configurable: true,
|
|
350
|
+
enumerable: false,
|
|
351
|
+
get: getComponentVersionFiles.bind(this, { component, version }),
|
|
352
|
+
},
|
|
353
|
+
startPage: {
|
|
354
|
+
configurable: true,
|
|
355
|
+
enumerable: false,
|
|
356
|
+
get: getComponentVersionStartPage.bind(this, { component, version }),
|
|
357
|
+
},
|
|
358
|
+
})
|
|
359
|
+
addSymbolicVersionAlias.call(this, componentVersion)
|
|
360
|
+
return startPage
|
|
333
361
|
}
|
|
334
362
|
|
|
335
363
|
registerSiteStartPage (startPageSpec) {
|
|
@@ -337,12 +365,13 @@ class ContentCatalog {
|
|
|
337
365
|
const rel = this.resolvePage(startPageSpec)
|
|
338
366
|
if (rel) {
|
|
339
367
|
if (this.getById(ROOT_INDEX_PAGE_ID)) return
|
|
368
|
+
if (rel.pub.url === (this.htmlUrlExtensionStyle === 'default' ? '/index.html' : '/')) return
|
|
340
369
|
const rootIndexAlias = this.getById(ROOT_INDEX_ALIAS_ID)
|
|
341
370
|
if (rootIndexAlias) return rootIndexAlias.synthetic ? Object.assign(rootIndexAlias, { rel }) : undefined
|
|
342
|
-
if (rel.pub.url === (this.htmlUrlExtensionStyle === 'default' ? '/index.html' : '/')) return
|
|
343
371
|
const src = Object.assign({}, ROOT_INDEX_ALIAS_ID)
|
|
344
372
|
return this.addFile({ src, rel, synthetic: true }, { version: src.version })
|
|
345
|
-
}
|
|
373
|
+
}
|
|
374
|
+
if (rel === false) {
|
|
346
375
|
logger.warn('Start page specified for site has invalid syntax: %s', startPageSpec)
|
|
347
376
|
} else if (startPageSpec.lastIndexOf(':') > startPageSpec.indexOf(':')) {
|
|
348
377
|
logger.warn('Start page specified for site not found: %s', startPageSpec)
|
|
@@ -359,18 +388,23 @@ class ContentCatalog {
|
|
|
359
388
|
// QUESTION should we throw an error if alias is invalid?
|
|
360
389
|
if (!src || (inferredSpec && src.relative === '.adoc')) return
|
|
361
390
|
const component = this.getComponent(src.component)
|
|
391
|
+
let componentVersion
|
|
362
392
|
if (component) {
|
|
363
393
|
// NOTE version is not set when alias specifies a component, but not a version
|
|
364
|
-
if (src.version == null)
|
|
394
|
+
if (src.version == null) {
|
|
395
|
+
src.version = (componentVersion = component.latest).version
|
|
396
|
+
} else {
|
|
397
|
+
componentVersion = this.getComponentVersion(component, src.version)
|
|
398
|
+
}
|
|
365
399
|
const existingPage = this.getById(src)
|
|
366
400
|
if (existingPage) {
|
|
367
401
|
throw new Error(
|
|
368
402
|
existingPage === target
|
|
369
403
|
? `Page cannot define alias that references itself: ${generateResourceSpec(src)}` +
|
|
370
|
-
|
|
404
|
+
` (specified as: ${spec})${LOG_WRAP}source: ${summarizeFileLocation(existingPage)}`
|
|
371
405
|
: `Page alias cannot reference an existing page: ${generateResourceSpec(src)} (specified as: ${spec})` +
|
|
372
|
-
|
|
373
|
-
|
|
406
|
+
`${LOG_WRAP}source: ${summarizeFileLocation(target)}` +
|
|
407
|
+
`${LOG_WRAP}existing page: ${summarizeFileLocation(existingPage)}`
|
|
374
408
|
)
|
|
375
409
|
}
|
|
376
410
|
} else if (src.version == null) {
|
|
@@ -386,33 +420,77 @@ class ContentCatalog {
|
|
|
386
420
|
)
|
|
387
421
|
}
|
|
388
422
|
// NOTE the redirect producer will populate contents when the redirect facility is 'static'
|
|
389
|
-
const alias = this.addFile({ src, rel: target })
|
|
423
|
+
const alias = this.addFile({ src, rel: target }, componentVersion)
|
|
390
424
|
// NOTE record the first alias this target claims as the preferred one
|
|
391
425
|
if (!target.rel) target.rel = alias
|
|
392
426
|
return alias
|
|
393
427
|
}
|
|
394
428
|
|
|
395
429
|
/**
|
|
396
|
-
*
|
|
430
|
+
* Adds a splat (directory) alias from the specified version segment in one component to the specified
|
|
431
|
+
* version segment in the same or different component.
|
|
397
432
|
*
|
|
398
|
-
*
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
433
|
+
* @returns {File} The virtual file that represents the splat alias.
|
|
434
|
+
*/
|
|
435
|
+
addSplatAlias (from, to) {
|
|
436
|
+
if (!from.versionSegment) throw new Error('cannot map splat alias from empty version segment')
|
|
437
|
+
const family = 'alias'
|
|
438
|
+
const baseSrc = { module: 'ROOT', family, relative: '', basename: '', stem: '', extname: '' }
|
|
439
|
+
const basePub = { splat: true }
|
|
440
|
+
const { component: fromComponent = to.component, versionSegment: fromVersionSegment } = from
|
|
441
|
+
const fromSrc = Object.assign({ component: fromComponent, version: fromVersionSegment }, baseSrc)
|
|
442
|
+
const fromPub = Object.assign(computePub(fromSrc, computeOut(fromSrc, family, fromVersionSegment), family), basePub)
|
|
443
|
+
const { component: toComponent, version: toVersion } = to
|
|
444
|
+
const toVersionSegment =
|
|
445
|
+
to.versionSegment ?? this.getComponentVersion(toComponent, toVersion)?.activeVersionSegment ?? toVersion
|
|
446
|
+
const toSrc = Object.assign({ component: toComponent, version: toVersion ?? toVersionSegment }, baseSrc)
|
|
447
|
+
const toPub = Object.assign(computePub(toSrc, computeOut(toSrc, family, toVersionSegment), family), basePub)
|
|
448
|
+
return this.addFile({ pub: fromPub, src: fromSrc, rel: { pub: toPub, src: toSrc } })
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Attempts to resolve a page reference within the given context to a page in the catalog.
|
|
453
|
+
*
|
|
454
|
+
* Parses the specified page reference (i.e., page ID spec) into a partial page ID, expands it
|
|
455
|
+
* using the provided context, then attempts to locate a file in the page family with that page ID
|
|
456
|
+
* in this catalog. The family segment is optional.
|
|
404
457
|
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
458
|
+
* If a component is specified, but no version, the latest version of the component stored in the
|
|
459
|
+
* catalog is used. If a page cannot be resolved, the search is attempted again for an "alias". If
|
|
460
|
+
* neither a page or alias can be resolved, the function returns undefined. If the syntax of the
|
|
461
|
+
* reference is invalid, this function throws an error.
|
|
408
462
|
*
|
|
409
|
-
* @
|
|
410
|
-
*
|
|
463
|
+
* @param {String} spec - The contextual page reference (e.g., version@component:module:topic/page.adoc).
|
|
464
|
+
* @param {Object} [context={}] - The context to use to qualify the page reference.
|
|
465
|
+
*
|
|
466
|
+
* @returns {File} The virtual file to which the contextual page reference resolves, or undefined
|
|
467
|
+
* if the file cannot be resolved.
|
|
411
468
|
*/
|
|
412
469
|
resolvePage (spec, context = {}) {
|
|
413
470
|
return this.resolveResource(spec, context, 'page', ['page'])
|
|
414
471
|
}
|
|
415
472
|
|
|
473
|
+
/**
|
|
474
|
+
* Attempts to resolve a resource reference within the given context to a file in the catalog.
|
|
475
|
+
*
|
|
476
|
+
* Parses the specified resource reference (i.e., resource ID spec) into a partial resource ID,
|
|
477
|
+
* expands it using the provided context, then attempts to locate a file with that resource ID in
|
|
478
|
+
* this catalog.
|
|
479
|
+
*
|
|
480
|
+
* If a component is specified, but no version, the latest version of the component stored in the
|
|
481
|
+
* catalog is used. If a defaultFamily is not specified, the family must be specified either by
|
|
482
|
+
* the reference or the context. If permittedFamilies are stated, the family must resolve to a
|
|
483
|
+
* family in this list. If a file cannot be resolved, the function returns undefined. If the
|
|
484
|
+
* syntax of the reference is invalid, this function throws an error.
|
|
485
|
+
*
|
|
486
|
+
* @param {String} spec - The contextual resource reference (e.g., version@component:module:image$topic/image.png).
|
|
487
|
+
* @param {Object} [context={}] - The context to use to qualify the resource reference.
|
|
488
|
+
* @param {String} [defaultFamily=undefined] - The default family to use if one is not provided.
|
|
489
|
+
* @param {Array<String>} [permittedFamilies=undefined] - A list of families that are permitted.
|
|
490
|
+
*
|
|
491
|
+
* @returns {File} The virtual file to which the contextual resource reference resolves, or
|
|
492
|
+
* undefined if the file cannot be resolved.
|
|
493
|
+
*/
|
|
416
494
|
resolveResource (spec, context = {}, defaultFamily = undefined, permittedFamilies = undefined) {
|
|
417
495
|
return resolveResource(spec, this, context, defaultFamily, permittedFamilies)
|
|
418
496
|
}
|
|
@@ -454,32 +532,28 @@ function generateResourceSpec ({ component, version, module: module_, family, re
|
|
|
454
532
|
|
|
455
533
|
function prepareSrc (src) {
|
|
456
534
|
let { basename, extname, stem } = src
|
|
457
|
-
let update
|
|
458
535
|
if (basename == null) {
|
|
459
|
-
|
|
460
|
-
basename = path.basename(src.relative)
|
|
536
|
+
basename = src.basename = path.basename(src.relative)
|
|
461
537
|
}
|
|
462
538
|
if (stem == null) {
|
|
463
|
-
update = true
|
|
464
539
|
if (extname == null) {
|
|
465
540
|
if (~(extname = basename.lastIndexOf('.'))) {
|
|
466
|
-
stem = basename.substr(0, extname)
|
|
467
|
-
extname = basename.substr(extname)
|
|
541
|
+
src.stem = basename.substr(0, extname)
|
|
542
|
+
src.extname = basename.substr(extname)
|
|
468
543
|
} else {
|
|
469
|
-
stem = basename
|
|
470
|
-
extname = ''
|
|
544
|
+
src.stem = basename
|
|
545
|
+
src.extname = ''
|
|
471
546
|
}
|
|
472
547
|
} else {
|
|
473
|
-
stem = basename.substr(0, basename.length - extname.length)
|
|
548
|
+
src.stem = basename.substr(0, basename.length - extname.length)
|
|
474
549
|
}
|
|
475
550
|
} else if (extname == null) {
|
|
476
|
-
|
|
477
|
-
extname = basename.substr(stem.length)
|
|
551
|
+
src.extname = basename.substr(stem.length)
|
|
478
552
|
}
|
|
479
|
-
return
|
|
553
|
+
return src
|
|
480
554
|
}
|
|
481
555
|
|
|
482
|
-
function computeOut (src, family,
|
|
556
|
+
function computeOut (src, family, versionSegment, htmlUrlExtensionStyle) {
|
|
483
557
|
let { component, module: module_, basename, extname, relative, stem } = src
|
|
484
558
|
if (component === 'ROOT') component = ''
|
|
485
559
|
if (module_ === 'ROOT') module_ = ''
|
|
@@ -499,7 +573,7 @@ function computeOut (src, family, version, htmlUrlExtensionStyle) {
|
|
|
499
573
|
familyPathSegment = '_attachments'
|
|
500
574
|
}
|
|
501
575
|
|
|
502
|
-
const modulePath = path.join(component,
|
|
576
|
+
const modulePath = path.join(component, versionSegment, module_)
|
|
503
577
|
const dirname = path.join(modulePath, familyPathSegment, path.dirname(relative), indexifyPathSegment)
|
|
504
578
|
const path_ = path.join(dirname, basename)
|
|
505
579
|
const moduleRootPath = path.relative(dirname, modulePath) || '.'
|
|
@@ -508,13 +582,13 @@ function computeOut (src, family, version, htmlUrlExtensionStyle) {
|
|
|
508
582
|
return { dirname, basename, path: path_, moduleRootPath, rootPath }
|
|
509
583
|
}
|
|
510
584
|
|
|
511
|
-
function computePub (src, out, family,
|
|
585
|
+
function computePub (src, out, family, versionSegment, htmlUrlExtensionStyle) {
|
|
512
586
|
const pub = {}
|
|
513
587
|
let url
|
|
514
588
|
if (family === 'nav') {
|
|
515
589
|
const component = src.component || 'ROOT'
|
|
516
590
|
const urlSegments = component === 'ROOT' ? [] : [component]
|
|
517
|
-
if (
|
|
591
|
+
if (versionSegment) urlSegments.push(versionSegment)
|
|
518
592
|
const module_ = src.module || 'ROOT'
|
|
519
593
|
if (module_ !== 'ROOT') urlSegments.push(module_)
|
|
520
594
|
if (urlSegments.length) urlSegments.push('')
|
|
@@ -533,71 +607,61 @@ function computePub (src, out, family, version, htmlUrlExtensionStyle) {
|
|
|
533
607
|
urlSegments[lastUrlSegmentIdx] = ''
|
|
534
608
|
}
|
|
535
609
|
url = '/' + urlSegments.join('/')
|
|
536
|
-
} else {
|
|
537
|
-
|
|
538
|
-
if (family === 'alias' && !src.relative) pub.splat = true
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
pub.url = ~url.indexOf(' ') ? url.replace(SPACE_RX, '%20') : url
|
|
542
|
-
|
|
543
|
-
if (out) {
|
|
544
|
-
pub.moduleRootPath = out.moduleRootPath
|
|
545
|
-
pub.rootPath = out.rootPath
|
|
610
|
+
} else if ((url = '/' + out.path) === '/.') {
|
|
611
|
+
url = '/'
|
|
546
612
|
}
|
|
613
|
+
pub.url = ~url.indexOf(' ') ? url.replaceAll(' ', '%20') : url
|
|
614
|
+
return out ? Object.assign(pub, { moduleRootPath: out.moduleRootPath, rootPath: out.rootPath }) : pub
|
|
615
|
+
}
|
|
547
616
|
|
|
548
|
-
|
|
617
|
+
function addSymbolicVersionAlias (componentVersion) {
|
|
618
|
+
const { name: component, version } = componentVersion
|
|
619
|
+
const originalVersionSegment = computeVersionSegment.call(this, componentVersion, 'original')
|
|
620
|
+
const symbolicVersionSegment = computeVersionSegment.call(this, componentVersion, 'alias')
|
|
621
|
+
if (symbolicVersionSegment === originalVersionSegment || symbolicVersionSegment == null) return
|
|
622
|
+
const originalVersionSrc = { component, version, versionSegment: originalVersionSegment }
|
|
623
|
+
const symbolicVersionSrc = { component, version, versionSegment: symbolicVersionSegment }
|
|
624
|
+
return this.latestVersionSegmentStrategy === 'redirect:to'
|
|
625
|
+
? this.addSplatAlias(originalVersionSrc, symbolicVersionSrc)
|
|
626
|
+
: this.addSplatAlias(symbolicVersionSrc, originalVersionSrc)
|
|
549
627
|
}
|
|
550
628
|
|
|
551
|
-
function computeVersionSegment (
|
|
629
|
+
function computeVersionSegment (componentVersion, mode) {
|
|
630
|
+
const version = componentVersion.version
|
|
552
631
|
// special designation for master version is @deprecated; special designation scheduled to be removed in Antora 4
|
|
553
|
-
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
556
|
-
|
|
632
|
+
const normalizedVersion = version && version !== 'master' ? version : ''
|
|
633
|
+
const { versionSegment = normalizedVersion } = componentVersion
|
|
634
|
+
if (mode === 'original') return versionSegment
|
|
635
|
+
const strategy = this.latestVersionSegmentStrategy
|
|
636
|
+
if (!versionSegment) {
|
|
637
|
+
if (!mode) return ''
|
|
557
638
|
if (strategy === 'redirect:to') return
|
|
558
639
|
}
|
|
559
|
-
if (strategy === 'redirect:to' || strategy === (mode
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
const segment =
|
|
640
|
+
if (strategy === 'redirect:to' || strategy === (mode ? 'redirect:from' : 'replace')) {
|
|
641
|
+
let component
|
|
642
|
+
if ((component = 'name' in componentVersion && this.getComponent(componentVersion.name))) {
|
|
643
|
+
const latestSegment =
|
|
564
644
|
componentVersion === component.latest
|
|
565
|
-
? this.
|
|
645
|
+
? this.latestVersionSegment
|
|
566
646
|
: componentVersion === component.latestPrerelease
|
|
567
|
-
? this.
|
|
647
|
+
? this.latestPrereleaseVersionSegment
|
|
568
648
|
: undefined
|
|
569
|
-
return
|
|
649
|
+
return latestSegment == null ? versionSegment : latestSegment
|
|
570
650
|
}
|
|
571
651
|
}
|
|
572
|
-
return
|
|
652
|
+
return versionSegment
|
|
573
653
|
}
|
|
574
654
|
|
|
575
|
-
function
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
family
|
|
586
|
-
),
|
|
587
|
-
}
|
|
588
|
-
const originalVersionAliasSrc = Object.assign({}, baseVersionAliasSrc, { version })
|
|
589
|
-
const originalVersionSegment = computeVersionSegment(component, version, 'original')
|
|
590
|
-
const originalVersionAlias = {
|
|
591
|
-
src: originalVersionAliasSrc,
|
|
592
|
-
pub: computePub(
|
|
593
|
-
originalVersionAliasSrc,
|
|
594
|
-
computeOut(originalVersionAliasSrc, family, originalVersionSegment),
|
|
595
|
-
family
|
|
596
|
-
),
|
|
597
|
-
}
|
|
598
|
-
return strategy === 'redirect:to'
|
|
599
|
-
? Object.assign(originalVersionAlias, { out: undefined, rel: symbolicVersionAlias })
|
|
600
|
-
: Object.assign(symbolicVersionAlias, { out: undefined, rel: originalVersionAlias })
|
|
655
|
+
function getComponentVersionFiles (componentVersionId) {
|
|
656
|
+
return this.findBy(componentVersionId)
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
function getComponentVersionStartPage (componentVersionId) {
|
|
660
|
+
return this.resolvePage('index.adoc', componentVersionId)
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
function getVersion () {
|
|
664
|
+
return this.version
|
|
601
665
|
}
|
|
602
666
|
|
|
603
667
|
module.exports = ContentCatalog
|
|
@@ -26,7 +26,6 @@ const parseResourceId = require('./parse-resource-id')
|
|
|
26
26
|
*/
|
|
27
27
|
function resolveResource (spec, catalog, ctx = {}, defaultFamily = undefined, permittedFamilies = undefined) {
|
|
28
28
|
const id = parseResourceId(spec, ctx, defaultFamily, permittedFamilies)
|
|
29
|
-
|
|
30
29
|
if (!id || !id.family) return false
|
|
31
30
|
if (id.version == null) {
|
|
32
31
|
const component = catalog.getComponent(id.component)
|
|
@@ -34,10 +33,9 @@ function resolveResource (spec, catalog, ctx = {}, defaultFamily = undefined, pe
|
|
|
34
33
|
id.version = component.latest.version
|
|
35
34
|
}
|
|
36
35
|
if (!id.module) id.module = 'ROOT'
|
|
37
|
-
|
|
38
36
|
return (
|
|
39
37
|
catalog.getById(id) ||
|
|
40
|
-
(id.family === 'page' ?
|
|
38
|
+
(id.family === 'page' ? catalog.getById(Object.assign({}, id, { family: 'alias' }))?.rel : undefined)
|
|
41
39
|
)
|
|
42
40
|
}
|
|
43
41
|
|
|
@@ -24,11 +24,8 @@ function versionCompareDesc (a, b) {
|
|
|
24
24
|
if (a && b) {
|
|
25
25
|
const semverA = resolveSemver(a)
|
|
26
26
|
const semverB = resolveSemver(b)
|
|
27
|
-
if (semverA)
|
|
28
|
-
|
|
29
|
-
} else {
|
|
30
|
-
return semverB ? -1 : -2 * a.localeCompare(b, 'en', { numeric: true })
|
|
31
|
-
}
|
|
27
|
+
if (semverA) return semverB ? -semverCompare(semverA, semverB) : 1
|
|
28
|
+
return semverB ? -1 : -2 * a.localeCompare(b, 'en', { numeric: true })
|
|
32
29
|
}
|
|
33
30
|
return a ? 1 : -1
|
|
34
31
|
}
|
|
@@ -64,23 +61,18 @@ function semverCompare (a, b) {
|
|
|
64
61
|
const numsA = a.split('.')
|
|
65
62
|
const numsB = b.split('.')
|
|
66
63
|
for (let i = 0; i < 3; i++) {
|
|
67
|
-
const numA = Number(numsA[i]
|
|
68
|
-
const numB = Number(numsB[i]
|
|
69
|
-
if (numA > numB)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return -1
|
|
73
|
-
} else if (isNaN(
|
|
74
|
-
if (!isNaN(numB)) return -1
|
|
75
|
-
} else if (isNaN(numB)) {
|
|
64
|
+
const numA = Number(numsA[i] ?? 0)
|
|
65
|
+
const numB = Number(numsB[i] ?? 0)
|
|
66
|
+
if (numA > numB) return 1
|
|
67
|
+
if (numB > numA) return -1
|
|
68
|
+
if (Number.isNaN(numA)) {
|
|
69
|
+
if (!Number.isNaN(numB)) return -1
|
|
70
|
+
} else if (Number.isNaN(numB)) {
|
|
76
71
|
return 1
|
|
77
72
|
}
|
|
78
73
|
}
|
|
79
|
-
if (preA == null)
|
|
80
|
-
|
|
81
|
-
} else {
|
|
82
|
-
return preB == null ? -1 : preA.localeCompare(preB, 'en', { numeric: true })
|
|
83
|
-
}
|
|
74
|
+
if (preA == null) return preB == null ? 0 : 1
|
|
75
|
+
return preB == null ? -1 : preA.localeCompare(preB, 'en', { numeric: true })
|
|
84
76
|
}
|
|
85
77
|
|
|
86
78
|
module.exports = versionCompareDesc
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-classifier",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.11",
|
|
4
4
|
"description": "Organizes aggregated content into a virtual file catalog for use in an Antora documentation pipeline.",
|
|
5
5
|
"license": "MPL-2.0",
|
|
6
6
|
"author": "OpenDevise Inc. (https://opendevise.com)",
|
|
@@ -10,7 +10,11 @@
|
|
|
10
10
|
"Hubert SABLONNIÈRE <hubert.sablonniere@gmail.com>"
|
|
11
11
|
],
|
|
12
12
|
"homepage": "https://antora.org",
|
|
13
|
-
"repository":
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://gitlab.com/antora/antora.git",
|
|
16
|
+
"directory": "packages/content-classifier"
|
|
17
|
+
},
|
|
14
18
|
"bugs": {
|
|
15
19
|
"url": "https://gitlab.com/antora/antora/issues"
|
|
16
20
|
},
|
|
@@ -27,13 +31,13 @@
|
|
|
27
31
|
"#constants": "./lib/constants.js"
|
|
28
32
|
},
|
|
29
33
|
"dependencies": {
|
|
30
|
-
"@antora/asciidoc-loader": "3.1.
|
|
31
|
-
"@antora/logger": "3.1.
|
|
34
|
+
"@antora/asciidoc-loader": "3.1.11",
|
|
35
|
+
"@antora/logger": "3.1.11",
|
|
32
36
|
"mime-types": "~2.1",
|
|
33
37
|
"vinyl": "~3.0"
|
|
34
38
|
},
|
|
35
39
|
"engines": {
|
|
36
|
-
"node": ">=
|
|
40
|
+
"node": ">=18.0.0"
|
|
37
41
|
},
|
|
38
42
|
"files": [
|
|
39
43
|
"lib/"
|
|
@@ -48,7 +52,7 @@
|
|
|
48
52
|
],
|
|
49
53
|
"scripts": {
|
|
50
54
|
"test": "_mocha",
|
|
51
|
-
"prepublishOnly": "npx -y downdoc --prepublish",
|
|
52
|
-
"postpublish": "npx -y downdoc --postpublish"
|
|
55
|
+
"prepublishOnly": "npx -y downdoc@latest --prepublish",
|
|
56
|
+
"postpublish": "npx -y downdoc@latest --postpublish"
|
|
53
57
|
}
|
|
54
58
|
}
|