@antora/content-classifier 3.2.0-alpha.9 → 3.2.0-rc.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/lib/classify-content.js
CHANGED
|
@@ -4,6 +4,7 @@ const ContentCatalog = require('./content-catalog')
|
|
|
4
4
|
const collateAsciiDocAttributes = require('@antora/asciidoc-loader/config/collate-asciidoc-attributes')
|
|
5
5
|
const logger = require('./logger')
|
|
6
6
|
const summarizeFileLocation = require('./util/summarize-file-location')
|
|
7
|
+
const families = { attachments: true, examples: true, images: true, pages: true, partials: true }
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Organizes the raw aggregate of virtual files into a {ContentCatalog}.
|
|
@@ -45,9 +46,21 @@ function addFilesAndRegisterStartPages (contentCatalog, siteStartPage) {
|
|
|
45
46
|
for (const componentVersion of componentVersions) {
|
|
46
47
|
const { name: component, version, files = [], nav, startPage } = componentVersion
|
|
47
48
|
const navResolved = nav && (nav.resolved = new Set())
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const rootFiles = []
|
|
50
|
+
for (let file, i = 0; (file = files[i]); i++) {
|
|
50
51
|
files[i] = undefined // free memory
|
|
52
|
+
const outcome = allocateSrc(file, component, version, componentVersion, nav)
|
|
53
|
+
if (outcome) {
|
|
54
|
+
contentCatalog.addFile(file)
|
|
55
|
+
} else if (outcome == null) {
|
|
56
|
+
rootFiles.push(file)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (rootFiles.length) {
|
|
60
|
+
for (let file, i = 0; (file = rootFiles[i]); i++) {
|
|
61
|
+
if (file.src.origin.hasModulesDir) continue
|
|
62
|
+
allocateSrc(file, component, version, componentVersion, null, true) && contentCatalog.addFile(file)
|
|
63
|
+
}
|
|
51
64
|
}
|
|
52
65
|
if (navResolved && nav.length > navResolved.size && new Set(nav).size > navResolved.size) {
|
|
53
66
|
const loc = summarizeFileLocation({ path: 'antora.yml', src: { origin: nav.origin } })
|
|
@@ -63,21 +76,24 @@ function addFilesAndRegisterStartPages (contentCatalog, siteStartPage) {
|
|
|
63
76
|
return contentCatalog
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
function allocateSrc (file, component, version, nav) {
|
|
67
|
-
const { extname, family } = file.src
|
|
79
|
+
function allocateSrc (file, component, version, componentVersion, nav, implicitRoot) {
|
|
80
|
+
const { extname, family, origin } = file.src
|
|
68
81
|
if (family && family !== 'nav') {
|
|
69
|
-
Object.assign(file.src, { component, version })
|
|
82
|
+
Object.assign(file.src, { component, version, componentVersion })
|
|
83
|
+
if (!('private' in file) && ~('/' + file.src.relative).indexOf('/_')) file.private = true
|
|
70
84
|
file.src.moduleRootPath ??= calculateRootPath(file.src.relative.split('/').length)
|
|
71
85
|
return true
|
|
72
86
|
}
|
|
73
87
|
const filepath = file.path
|
|
74
|
-
const pathSegments = filepath.split('/')
|
|
88
|
+
const pathSegments = implicitRoot ? ['modules', 'ROOT'].concat(filepath.split('/')) : filepath.split('/')
|
|
89
|
+
const inModules = pathSegments[0] === 'modules'
|
|
90
|
+
if (!implicitRoot && origin) origin.hasModulesDir ||= inModules
|
|
75
91
|
let navInfo
|
|
76
92
|
if (nav && (navInfo = getNavInfo(filepath, nav))) {
|
|
77
|
-
if (extname !== '.adoc') return // ignore file
|
|
93
|
+
if (extname !== '.adoc') return false // ignore file
|
|
78
94
|
file.nav = navInfo
|
|
79
95
|
file.src.family = 'nav'
|
|
80
|
-
if (
|
|
96
|
+
if (inModules && pathSegments.length > 2) {
|
|
81
97
|
file.src.module = pathSegments[1]
|
|
82
98
|
// relative to modules/<module>
|
|
83
99
|
file.src.relative = pathSegments.slice(2).join('/')
|
|
@@ -86,7 +102,7 @@ function allocateSrc (file, component, version, nav) {
|
|
|
86
102
|
// relative to content source root
|
|
87
103
|
file.src.relative = filepath
|
|
88
104
|
}
|
|
89
|
-
} else if (
|
|
105
|
+
} else if (inModules) {
|
|
90
106
|
let familyFolder = pathSegments[2]
|
|
91
107
|
switch (familyFolder) {
|
|
92
108
|
case 'pages':
|
|
@@ -100,45 +116,47 @@ function allocateSrc (file, component, version, nav) {
|
|
|
100
116
|
// relative to modules/<module>/pages
|
|
101
117
|
file.src.relative = pathSegments.slice(3).join('/')
|
|
102
118
|
} else {
|
|
103
|
-
return // ignore file
|
|
119
|
+
return false // ignore file
|
|
104
120
|
}
|
|
105
121
|
break
|
|
106
122
|
case 'assets':
|
|
107
123
|
switch ((familyFolder = pathSegments[3])) {
|
|
108
124
|
case 'attachments':
|
|
109
125
|
case 'images':
|
|
110
|
-
if (!extname) return // ignore file
|
|
111
|
-
file.src.family = familyFolder.
|
|
126
|
+
if (!extname && familyFolder === 'images') return false // ignore file
|
|
127
|
+
file.src.family = familyFolder.substring(0, familyFolder.length - 1)
|
|
112
128
|
// relative to modules/<module>/assets/<family>s
|
|
113
129
|
file.src.relative = pathSegments.slice(4).join('/')
|
|
114
130
|
break
|
|
115
131
|
default:
|
|
116
|
-
return // ignore file
|
|
132
|
+
return false // ignore file
|
|
117
133
|
}
|
|
118
134
|
break
|
|
119
|
-
case 'attachments':
|
|
120
135
|
case 'images':
|
|
121
|
-
if (!extname) return
|
|
122
|
-
file.src.family = familyFolder.
|
|
136
|
+
if (!extname) return false
|
|
137
|
+
file.src.family = familyFolder.substring(0, familyFolder.length - 1)
|
|
123
138
|
// relative to modules/<module>/<family>s
|
|
124
139
|
file.src.relative = pathSegments.slice(3).join('/')
|
|
125
140
|
break
|
|
141
|
+
case 'attachments':
|
|
126
142
|
case 'examples':
|
|
127
143
|
case 'partials':
|
|
128
|
-
file.src.family = familyFolder.
|
|
144
|
+
file.src.family = familyFolder.substring(0, familyFolder.length - 1)
|
|
129
145
|
// relative to modules/<module>/<family>s
|
|
130
146
|
file.src.relative = pathSegments.slice(3).join('/')
|
|
131
147
|
break
|
|
132
148
|
default:
|
|
133
|
-
return // ignore file
|
|
149
|
+
return false // ignore file
|
|
134
150
|
}
|
|
135
151
|
file.src.module = pathSegments[1]
|
|
136
152
|
file.src.moduleRootPath = calculateRootPath(pathSegments.length - 3)
|
|
153
|
+
if (!('private' in file) && ~('/' + file.src.relative).indexOf('/_')) file.private = true
|
|
154
|
+
} else if (origin && pathSegments[0] in families) {
|
|
155
|
+
return // defer file
|
|
137
156
|
} else {
|
|
138
|
-
return // ignore file
|
|
157
|
+
return false // ignore file
|
|
139
158
|
}
|
|
140
|
-
file.src
|
|
141
|
-
file.src.version = version
|
|
159
|
+
Object.assign(file.src, { component, version, componentVersion })
|
|
142
160
|
return true
|
|
143
161
|
}
|
|
144
162
|
|
|
@@ -152,7 +170,7 @@ function allocateSrc (file, component, version, nav) {
|
|
|
152
170
|
* index, if this file is a navigation file, or undefined if it's not.
|
|
153
171
|
*/
|
|
154
172
|
function getNavInfo (filepath, nav) {
|
|
155
|
-
const index = nav.
|
|
173
|
+
const index = nav.indexOf(filepath)
|
|
156
174
|
if (~index) return nav.resolved.add(filepath) && { index }
|
|
157
175
|
}
|
|
158
176
|
|
package/lib/content-catalog.js
CHANGED
|
@@ -20,6 +20,7 @@ class ContentCatalog {
|
|
|
20
20
|
constructor (playbook = {}) {
|
|
21
21
|
this[$components] = new Map()
|
|
22
22
|
this[$files] = new Map()
|
|
23
|
+
this.publishableFamilies = new Set(['page', 'image', 'attachment'])
|
|
23
24
|
const urls = playbook.urls || {}
|
|
24
25
|
this.htmlUrlExtensionStyle = urls.htmlExtensionStyle || 'default'
|
|
25
26
|
this.urlRedirectFacility = urls.redirectFacility || 'static'
|
|
@@ -142,11 +143,11 @@ class ContentCatalog {
|
|
|
142
143
|
return componentVersion
|
|
143
144
|
}
|
|
144
145
|
|
|
145
|
-
addFile (file
|
|
146
|
+
addFile (file) {
|
|
146
147
|
const src = file.src
|
|
147
|
-
|
|
148
|
-
let filesForFamily
|
|
149
|
-
if (
|
|
148
|
+
const family = src.family
|
|
149
|
+
let filesForFamily
|
|
150
|
+
if ((filesForFamily = this[$files].get(family)) == null) this[$files].set(family, (filesForFamily = new Map()))
|
|
150
151
|
const key = generateKey(src)
|
|
151
152
|
if (filesForFamily.has(key)) {
|
|
152
153
|
if (family === 'alias') {
|
|
@@ -156,58 +157,73 @@ class ContentCatalog {
|
|
|
156
157
|
.map((it, idx) => `${idx + 1}: ${summarizeFileLocation(it)}`)
|
|
157
158
|
.join(LOG_WRAP)
|
|
158
159
|
if (family === 'nav') {
|
|
159
|
-
throw new Error(`Duplicate nav file: ${file.path} in ${version}@${component}${LOG_WRAP}${details}`)
|
|
160
|
+
throw new Error(`Duplicate nav file: ${file.path} in ${src.version}@${src.component}${LOG_WRAP}${details}`)
|
|
160
161
|
}
|
|
161
162
|
throw new Error(`Duplicate ${family}: ${generateResourceSpec(src)}${LOG_WRAP}${details}`)
|
|
162
163
|
}
|
|
164
|
+
if (!(file.created && File.isVinyl(file))) file = this.createFile(file)
|
|
165
|
+
filesForFamily.set(key, file)
|
|
166
|
+
return file
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
createFile (file) {
|
|
170
|
+
const src = file.src
|
|
171
|
+
let { componentVersion, family } = src
|
|
172
|
+
if (componentVersion) delete src.componentVersion
|
|
163
173
|
// NOTE: assume that if the file is not a vinyl object, the src likely needs to be prepared
|
|
164
174
|
// a vinyl object is one indication the file was created and prepared by the content aggregator
|
|
165
|
-
// an alternate approach would be to call
|
|
175
|
+
// an alternate approach would be to call inflateSrc if the path property is not set
|
|
166
176
|
if (!File.isVinyl(file)) {
|
|
167
|
-
|
|
177
|
+
inflateSrc(src)
|
|
168
178
|
file = new File(file)
|
|
169
179
|
}
|
|
180
|
+
Object.defineProperty(file, 'created', { configurable: true, writable: true, value: true })
|
|
170
181
|
if (family === 'alias') {
|
|
171
182
|
file.mediaType = 'text/html'
|
|
172
|
-
// NOTE: an alias masquerades as the target file
|
|
173
|
-
family = file.rel.src.family
|
|
174
183
|
// NOTE: short circuit in case of splat alias (alias -> alias)
|
|
175
|
-
if (family === 'alias' && file.pub?.splat) return
|
|
184
|
+
if (file.rel.src.family === 'alias' && file.pub?.splat) return file
|
|
185
|
+
// NOTE the effective family of an alias is a page, which redirects to the target file
|
|
186
|
+
family = 'page'
|
|
176
187
|
src.mediaType = 'text/asciidoc'
|
|
177
188
|
} else if (!(file.mediaType = src.mediaType) && !('mediaType' in src)) {
|
|
178
189
|
// QUESTION: should we preserve the mediaType property on file if already defined?
|
|
179
|
-
file.mediaType = src.mediaType =
|
|
190
|
+
file.mediaType = src.mediaType = src.extname
|
|
191
|
+
? resolveMimeType(src.extname) || (family === 'page' ? 'text/asciidoc' : undefined)
|
|
192
|
+
: 'text/plain'
|
|
180
193
|
}
|
|
181
|
-
let
|
|
182
|
-
let
|
|
194
|
+
let activeVersionSegment = false
|
|
195
|
+
let publishable, referenceable
|
|
183
196
|
if (file.out) {
|
|
184
197
|
publishable = true
|
|
185
198
|
} else if ('out' in file) {
|
|
186
199
|
delete file.out
|
|
187
|
-
} else if (
|
|
188
|
-
!file.private &&
|
|
189
|
-
(family === 'page' || family === 'image' || family === 'attachment') &&
|
|
190
|
-
(file.private === false || ('/' + src.relative).indexOf('/_') < 0)
|
|
191
|
-
) {
|
|
200
|
+
} else if (!file.private && this.publishableFamilies.has(family)) {
|
|
192
201
|
publishable = true
|
|
193
|
-
|
|
202
|
+
componentVersion ??= this.getComponentVersion(src.component, src.version) || { version: src.version }
|
|
194
203
|
activeVersionSegment =
|
|
195
204
|
'activeVersionSegment' in componentVersion
|
|
196
205
|
? componentVersion.activeVersionSegment
|
|
197
206
|
: computeVersionSegment.call(this, componentVersion)
|
|
198
|
-
file.out = computeOut(src, family, activeVersionSegment
|
|
207
|
+
file.out = computeOut.call(this, src, family, activeVersionSegment)
|
|
208
|
+
}
|
|
209
|
+
if (!file.pub) {
|
|
210
|
+
if ('pub' in file) {
|
|
211
|
+
delete file.pub
|
|
212
|
+
} else if (publishable || family === 'nav') {
|
|
213
|
+
referenceable = true
|
|
214
|
+
}
|
|
199
215
|
}
|
|
200
|
-
if (
|
|
201
|
-
if (activeVersionSegment
|
|
202
|
-
|
|
216
|
+
if (referenceable) {
|
|
217
|
+
if (activeVersionSegment === false) {
|
|
218
|
+
componentVersion ??= this.getComponentVersion(src.component, src.version) || { version: src.version }
|
|
203
219
|
activeVersionSegment =
|
|
204
220
|
'activeVersionSegment' in componentVersion
|
|
205
221
|
? componentVersion.activeVersionSegment
|
|
206
222
|
: computeVersionSegment.call(this, componentVersion)
|
|
207
223
|
}
|
|
208
|
-
file.pub = computePub(src, file.out, family, activeVersionSegment
|
|
224
|
+
file.pub = computePub.call(this, src, file.out, family, activeVersionSegment)
|
|
209
225
|
}
|
|
210
|
-
return
|
|
226
|
+
return file
|
|
211
227
|
}
|
|
212
228
|
|
|
213
229
|
removeFile (file) {
|
|
@@ -263,21 +279,27 @@ class ContentCatalog {
|
|
|
263
279
|
return this.getComponents().sort((a, b) => a[property].localeCompare(b[property]))
|
|
264
280
|
}
|
|
265
281
|
|
|
266
|
-
getFiles () {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
for (const
|
|
282
|
+
getFiles (filter) {
|
|
283
|
+
const files = []
|
|
284
|
+
if (filter) {
|
|
285
|
+
for (const filesForFamily of this[$files].values()) {
|
|
286
|
+
for (const candidate of filesForFamily.values()) filter(candidate) && files.push(candidate)
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
for (const filesForFamily of this[$files].values()) {
|
|
290
|
+
for (const file of filesForFamily.values()) files.push(file)
|
|
291
|
+
}
|
|
270
292
|
}
|
|
271
|
-
return
|
|
293
|
+
return files
|
|
272
294
|
}
|
|
273
295
|
|
|
274
296
|
getPages (filter) {
|
|
275
297
|
const candidates = this[$files].get('page')
|
|
276
298
|
if (!candidates) return []
|
|
277
299
|
if (filter) {
|
|
278
|
-
const
|
|
279
|
-
for (const candidate of candidates.values()) filter(candidate) &&
|
|
280
|
-
return
|
|
300
|
+
const pages = []
|
|
301
|
+
for (const candidate of candidates.values()) filter(candidate) && pages.push(candidate)
|
|
302
|
+
return pages
|
|
281
303
|
}
|
|
282
304
|
return [...candidates.values()]
|
|
283
305
|
}
|
|
@@ -295,17 +317,14 @@ class ContentCatalog {
|
|
|
295
317
|
if ((file = this.getById(Object.assign({}, ROOT_INDEX_ALIAS_ID, { version })))) return file.rel
|
|
296
318
|
}
|
|
297
319
|
|
|
298
|
-
registerComponentVersionStartPage (
|
|
299
|
-
|
|
300
|
-
let version = componentVersion.version
|
|
301
|
-
if (version == null) {
|
|
320
|
+
registerComponentVersionStartPage (component, componentVersion, startPageSpec = undefined) {
|
|
321
|
+
if (componentVersion.constructor === String) {
|
|
302
322
|
// QUESTION: should we warn or throw error if component version cannot be found?
|
|
303
323
|
if (!(componentVersion = this.getComponentVersion(component, componentVersion))) return
|
|
304
|
-
version = componentVersion.version
|
|
305
324
|
}
|
|
325
|
+
const version = componentVersion.version
|
|
306
326
|
const activeVersionSegment = computeVersionSegment.call(this, componentVersion)
|
|
307
|
-
let startPage
|
|
308
|
-
let startPageSrc
|
|
327
|
+
let startPage, startPageSrc
|
|
309
328
|
const indexPageId = Object.assign({}, ROOT_INDEX_PAGE_ID, { component, version })
|
|
310
329
|
if (startPageSpec) {
|
|
311
330
|
if (
|
|
@@ -314,11 +333,11 @@ class ContentCatalog {
|
|
|
314
333
|
startPageSrc.version === version
|
|
315
334
|
) {
|
|
316
335
|
if (!this.getById(indexPageId)) {
|
|
317
|
-
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component, version })
|
|
336
|
+
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component, version, componentVersion })
|
|
318
337
|
const indexAlias = this.getById(indexAliasId)
|
|
319
338
|
indexAlias
|
|
320
339
|
? indexAlias.synthetic && Object.assign(indexAlias, { rel: startPage })
|
|
321
|
-
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true }
|
|
340
|
+
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true })
|
|
322
341
|
}
|
|
323
342
|
} else {
|
|
324
343
|
// TODO pass componentVersion as logObject
|
|
@@ -337,20 +356,21 @@ class ContentCatalog {
|
|
|
337
356
|
if (startPage) {
|
|
338
357
|
componentVersion.url = startPage.pub.url
|
|
339
358
|
} else if (!componentVersion.url) {
|
|
359
|
+
startPageSrc = inflateSrc(Object.assign({}, indexPageId, { family: 'page' }))
|
|
340
360
|
// QUESTION: should we warn if the default start page cannot be found?
|
|
341
|
-
componentVersion.url = computePub(
|
|
342
|
-
|
|
343
|
-
|
|
361
|
+
componentVersion.url = computePub.call(
|
|
362
|
+
this,
|
|
363
|
+
startPageSrc,
|
|
364
|
+
computeOut.call(this, startPageSrc, startPageSrc.family, activeVersionSegment),
|
|
344
365
|
startPageSrc.family,
|
|
345
|
-
activeVersionSegment
|
|
346
|
-
this.htmlUrlExtensionStyle
|
|
366
|
+
activeVersionSegment
|
|
347
367
|
).url
|
|
348
368
|
}
|
|
349
369
|
Object.defineProperties(componentVersion, {
|
|
350
370
|
activeVersionSegment:
|
|
351
371
|
activeVersionSegment === version
|
|
352
|
-
? { configurable: true,
|
|
353
|
-
: { configurable: true,
|
|
372
|
+
? { configurable: true, get: getVersion }
|
|
373
|
+
: { configurable: true, value: activeVersionSegment },
|
|
354
374
|
files: {
|
|
355
375
|
configurable: true,
|
|
356
376
|
enumerable: false,
|
|
@@ -375,7 +395,7 @@ class ContentCatalog {
|
|
|
375
395
|
const rootIndexAlias = this.getById(ROOT_INDEX_ALIAS_ID)
|
|
376
396
|
if (rootIndexAlias) return rootIndexAlias.synthetic ? Object.assign(rootIndexAlias, { rel }) : undefined
|
|
377
397
|
const src = Object.assign({}, ROOT_INDEX_ALIAS_ID)
|
|
378
|
-
return this.addFile({ src, rel, synthetic: true }
|
|
398
|
+
return this.addFile({ src, rel, synthetic: true })
|
|
379
399
|
}
|
|
380
400
|
if (rel === false) {
|
|
381
401
|
logger.warn('Start page specified for site has invalid syntax: %s', startPageSpec)
|
|
@@ -394,14 +414,9 @@ class ContentCatalog {
|
|
|
394
414
|
// QUESTION should we throw an error if alias is invalid?
|
|
395
415
|
if (!src || (inferredSpec && src.relative === '.adoc')) return
|
|
396
416
|
const component = this.getComponent(src.component)
|
|
397
|
-
let componentVersion
|
|
398
417
|
if (component) {
|
|
399
418
|
// NOTE version is not set when alias specifies a component, but not a version
|
|
400
|
-
|
|
401
|
-
src.version = (componentVersion = component.latest).version
|
|
402
|
-
} else {
|
|
403
|
-
componentVersion = this.getComponentVersion(component, src.version)
|
|
404
|
-
}
|
|
419
|
+
src.version ??= (src.componentVersion = component.latest).version
|
|
405
420
|
const existingPage = this.getById(src)
|
|
406
421
|
if (existingPage) {
|
|
407
422
|
throw new Error(
|
|
@@ -426,7 +441,7 @@ class ContentCatalog {
|
|
|
426
441
|
)
|
|
427
442
|
}
|
|
428
443
|
// NOTE the redirect producer will populate contents when the redirect facility is 'static'
|
|
429
|
-
const alias = this.addFile({ src, rel: target }
|
|
444
|
+
const alias = this.addFile({ src, rel: target })
|
|
430
445
|
// NOTE record the first alias this target claims as the preferred one
|
|
431
446
|
if (!target.rel) target.rel = alias
|
|
432
447
|
return alias
|
|
@@ -445,12 +460,18 @@ class ContentCatalog {
|
|
|
445
460
|
const basePub = { splat: true }
|
|
446
461
|
const { component: fromComponent = to.component, versionSegment: fromVersionSegment } = from
|
|
447
462
|
const fromSrc = Object.assign({ component: fromComponent, version: fromVersionSegment }, baseSrc)
|
|
448
|
-
const fromPub = Object.assign(
|
|
463
|
+
const fromPub = Object.assign(
|
|
464
|
+
computePub.call(this, fromSrc, computeOut.call(this, fromSrc, family, fromVersionSegment), family),
|
|
465
|
+
basePub
|
|
466
|
+
)
|
|
449
467
|
const { component: toComponent, version: toVersion } = to
|
|
450
468
|
const toVersionSegment =
|
|
451
469
|
to.versionSegment ?? this.getComponentVersion(toComponent, toVersion)?.activeVersionSegment ?? toVersion
|
|
452
470
|
const toSrc = Object.assign({ component: toComponent, version: toVersion ?? toVersionSegment }, baseSrc)
|
|
453
|
-
const toPub = Object.assign(
|
|
471
|
+
const toPub = Object.assign(
|
|
472
|
+
computePub.call(this, toSrc, computeOut.call(this, toSrc, family, toVersionSegment), family),
|
|
473
|
+
basePub
|
|
474
|
+
)
|
|
454
475
|
return this.addFile({ pub: fromPub, src: fromSrc, rel: { pub: toPub, src: toSrc } })
|
|
455
476
|
}
|
|
456
477
|
|
|
@@ -536,7 +557,7 @@ function generateResourceSpec ({ component, version, module: module_, family, re
|
|
|
536
557
|
)
|
|
537
558
|
}
|
|
538
559
|
|
|
539
|
-
function
|
|
560
|
+
function inflateSrc (src) {
|
|
540
561
|
let { basename, extname, stem } = src
|
|
541
562
|
if (basename == null) {
|
|
542
563
|
basename = src.basename = path.basename(src.relative)
|
|
@@ -544,22 +565,22 @@ function prepareSrc (src) {
|
|
|
544
565
|
if (stem == null) {
|
|
545
566
|
if (extname == null) {
|
|
546
567
|
if (~(extname = basename.lastIndexOf('.'))) {
|
|
547
|
-
src.stem = basename.
|
|
548
|
-
src.extname = basename.
|
|
568
|
+
src.stem = basename.substring(0, extname)
|
|
569
|
+
src.extname = basename.substring(extname)
|
|
549
570
|
} else {
|
|
550
571
|
src.stem = basename
|
|
551
572
|
src.extname = ''
|
|
552
573
|
}
|
|
553
574
|
} else {
|
|
554
|
-
src.stem = basename.
|
|
575
|
+
src.stem = basename.substring(0, basename.length - extname.length)
|
|
555
576
|
}
|
|
556
577
|
} else if (extname == null) {
|
|
557
|
-
src.extname = basename.
|
|
578
|
+
src.extname = basename.substring(stem.length)
|
|
558
579
|
}
|
|
559
580
|
return src
|
|
560
581
|
}
|
|
561
582
|
|
|
562
|
-
function computeOut (src, family, versionSegment
|
|
583
|
+
function computeOut (src, family, versionSegment) {
|
|
563
584
|
let { component, module: module_, basename, extname, relative, stem } = src
|
|
564
585
|
if (component === 'ROOT') component = ''
|
|
565
586
|
if (module_ === 'ROOT') module_ = ''
|
|
@@ -567,16 +588,14 @@ function computeOut (src, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
567
588
|
let familyPathSegment = ''
|
|
568
589
|
|
|
569
590
|
if (family === 'page') {
|
|
570
|
-
if (stem !== 'index' && htmlUrlExtensionStyle === 'indexify') {
|
|
591
|
+
if (stem !== 'index' && this.htmlUrlExtensionStyle === 'indexify') {
|
|
571
592
|
basename = 'index.html'
|
|
572
593
|
indexifyPathSegment = stem
|
|
573
594
|
} else if (extname === '.adoc') {
|
|
574
595
|
basename = stem + '.html'
|
|
575
596
|
}
|
|
576
|
-
} else if (family
|
|
577
|
-
familyPathSegment = '
|
|
578
|
-
} else if (family === 'attachment') {
|
|
579
|
-
familyPathSegment = '_attachments'
|
|
597
|
+
} else if (this.publishableFamilies.has(family)) {
|
|
598
|
+
familyPathSegment = '_' + family + 's'
|
|
580
599
|
}
|
|
581
600
|
|
|
582
601
|
const modulePath = path.join(component, versionSegment, module_)
|
|
@@ -588,7 +607,7 @@ function computeOut (src, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
588
607
|
return { dirname, basename, path: path_, moduleRootPath, rootPath }
|
|
589
608
|
}
|
|
590
609
|
|
|
591
|
-
function computePub (src, out, family, versionSegment
|
|
610
|
+
function computePub (src, out, family, versionSegment) {
|
|
592
611
|
const pub = {}
|
|
593
612
|
let url
|
|
594
613
|
if (family === 'nav') {
|
|
@@ -604,12 +623,12 @@ function computePub (src, out, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
604
623
|
} else if (family === 'page') {
|
|
605
624
|
const urlSegments = out.path.split('/')
|
|
606
625
|
const lastUrlSegmentIdx = urlSegments.length - 1
|
|
607
|
-
if (htmlUrlExtensionStyle === 'drop') {
|
|
626
|
+
if (this.htmlUrlExtensionStyle === 'drop') {
|
|
608
627
|
// drop just the .html extension or, if the filename is index.html, the whole segment
|
|
609
628
|
const lastUrlSegment = urlSegments[lastUrlSegmentIdx]
|
|
610
629
|
urlSegments[lastUrlSegmentIdx] =
|
|
611
|
-
lastUrlSegment === 'index.html' ? '' : lastUrlSegment.
|
|
612
|
-
} else if (htmlUrlExtensionStyle === 'indexify') {
|
|
630
|
+
lastUrlSegment === 'index.html' ? '' : lastUrlSegment.substring(0, lastUrlSegment.length - 5)
|
|
631
|
+
} else if (this.htmlUrlExtensionStyle === 'indexify') {
|
|
613
632
|
urlSegments[lastUrlSegmentIdx] = ''
|
|
614
633
|
}
|
|
615
634
|
url = '/' + urlSegments.join('/')
|
|
@@ -59,7 +59,7 @@ function parseResourceId (spec, ctx = {}, defaultFamily = 'page', permittedFamil
|
|
|
59
59
|
const relativeSegments = relative.split('/')
|
|
60
60
|
let from
|
|
61
61
|
if (relativeSegments[0] === '.' && (from = ctx.relative)) {
|
|
62
|
-
relativeSegments[0] = from.
|
|
62
|
+
relativeSegments[0] = from.substring(0, (from.lastIndexOf('/') + 1 || 1) - 1)
|
|
63
63
|
}
|
|
64
64
|
relative = relativeSegments
|
|
65
65
|
.reduce((accum, segment) => {
|
|
@@ -26,7 +26,7 @@ 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
|
-
if (!id
|
|
29
|
+
if (!id?.family) return false
|
|
30
30
|
if (id.version == null) {
|
|
31
31
|
const component = catalog.getComponent(id.component)
|
|
32
32
|
if (!component) return
|
|
@@ -33,7 +33,7 @@ function versionCompareDesc (a, b) {
|
|
|
33
33
|
function resolveSemver (str) {
|
|
34
34
|
const chr0 = str.charAt()
|
|
35
35
|
if (chr0 === 'v') {
|
|
36
|
-
if (isDigit(str.charAt(1)) && (str = str.
|
|
36
|
+
if (isDigit(str.charAt(1)) && (str = str.substring(1)) && (~str.indexOf('.') || isDigit(str.charAt()))) {
|
|
37
37
|
return str
|
|
38
38
|
}
|
|
39
39
|
} else if (isDigit(chr0) && (~str.indexOf('.') || isInteger(Number(str)))) {
|
|
@@ -51,12 +51,12 @@ function semverCompare (a, b) {
|
|
|
51
51
|
const preOffsetA = a.indexOf('-')
|
|
52
52
|
const preOffsetB = b.indexOf('-')
|
|
53
53
|
if (~preOffsetA) {
|
|
54
|
-
preA = a.
|
|
55
|
-
a = a.
|
|
54
|
+
preA = a.substring(preOffsetA + 1)
|
|
55
|
+
a = a.substring(0, preOffsetA)
|
|
56
56
|
}
|
|
57
57
|
if (~preOffsetB) {
|
|
58
|
-
preB = b.
|
|
59
|
-
b = b.
|
|
58
|
+
preB = b.substring(preOffsetB + 1)
|
|
59
|
+
b = b.substring(0, preOffsetB)
|
|
60
60
|
}
|
|
61
61
|
const numsA = a.split('.')
|
|
62
62
|
const numsB = b.split('.')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/content-classifier",
|
|
3
|
-
"version": "3.2.0-
|
|
3
|
+
"version": "3.2.0-rc.1",
|
|
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)",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"#constants": "./lib/constants.js"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@antora/asciidoc-loader": "3.2.0-
|
|
35
|
-
"@antora/logger": "3.2.0-
|
|
36
|
-
"mime-types": "~
|
|
34
|
+
"@antora/asciidoc-loader": "3.2.0-rc.1",
|
|
35
|
+
"@antora/logger": "3.2.0-rc.1",
|
|
36
|
+
"mime-types": "~3.0",
|
|
37
37
|
"vinyl": "~3.0"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
40
|
-
"node": ">=
|
|
40
|
+
"node": ">=20.0.0"
|
|
41
41
|
},
|
|
42
42
|
"files": [
|
|
43
43
|
"lib/"
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"web publishing"
|
|
52
52
|
],
|
|
53
53
|
"scripts": {
|
|
54
|
-
"test": "
|
|
54
|
+
"test": "node --test",
|
|
55
55
|
"prepublishOnly": "npx -y downdoc@latest --prepublish",
|
|
56
56
|
"postpublish": "npx -y downdoc@latest --postpublish"
|
|
57
57
|
}
|