@antora/content-classifier 3.2.0-alpha.9 → 3.2.0-rc.2
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, create = true) {
|
|
146
147
|
const src = file.src
|
|
147
|
-
|
|
148
|
-
let filesForFamily
|
|
149
|
-
if (!filesForFamily) this[$files].set(family, (filesForFamily = new Map()))
|
|
148
|
+
const family = src.family
|
|
149
|
+
let filesForFamily
|
|
150
|
+
if (!(filesForFamily = this[$files].get(family))) 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,64 +157,77 @@ 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
|
}
|
|
163
|
-
|
|
164
|
+
filesForFamily.set(key, create ? (file = this.createFile(file)) : file)
|
|
165
|
+
return file
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
createFile (file) {
|
|
169
|
+
const src = file.src
|
|
170
|
+
let { componentVersion, family } = src
|
|
171
|
+
if (componentVersion) delete src.componentVersion
|
|
172
|
+
// NOTE: assume that if the file is not a vinyl object, the src likely needs to be inflated
|
|
164
173
|
// a vinyl object is one indication the file was created and prepared by the content aggregator
|
|
165
|
-
// an alternate approach would be to call prepareSrc if the path property is not set
|
|
166
174
|
if (!File.isVinyl(file)) {
|
|
167
|
-
|
|
175
|
+
if (typeof file.contents === 'string') file.contents = Buffer.from(file.contents)
|
|
176
|
+
inflateSrc(src)
|
|
168
177
|
file = new File(file)
|
|
169
178
|
}
|
|
179
|
+
Object.defineProperty(file, 'created', { configurable: true, writable: true, value: true })
|
|
170
180
|
if (family === 'alias') {
|
|
171
181
|
file.mediaType = 'text/html'
|
|
172
|
-
// NOTE: an alias masquerades as the target file
|
|
173
|
-
family = file.rel.src.family
|
|
174
182
|
// NOTE: short circuit in case of splat alias (alias -> alias)
|
|
175
|
-
if (family === 'alias' && file.pub?.splat) return
|
|
183
|
+
if (file.rel.src.family === 'alias' && file.pub?.splat) return file
|
|
184
|
+
// NOTE the effective family of an alias is a page, which redirects to the target file
|
|
185
|
+
family = 'page'
|
|
176
186
|
src.mediaType = 'text/asciidoc'
|
|
177
187
|
} else if (!(file.mediaType = src.mediaType) && !('mediaType' in src)) {
|
|
178
188
|
// QUESTION: should we preserve the mediaType property on file if already defined?
|
|
179
|
-
file.mediaType = src.mediaType =
|
|
189
|
+
file.mediaType = src.mediaType = src.extname
|
|
190
|
+
? resolveMimeType(src.extname) || (family === 'page' ? 'text/asciidoc' : undefined)
|
|
191
|
+
: 'text/plain'
|
|
180
192
|
}
|
|
181
|
-
let
|
|
182
|
-
let
|
|
193
|
+
let activeVersionSegment = false
|
|
194
|
+
let publishable, referenceable
|
|
183
195
|
if (file.out) {
|
|
184
196
|
publishable = true
|
|
185
197
|
} else if ('out' in file) {
|
|
186
198
|
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
|
-
) {
|
|
199
|
+
} else if (!file.private && this.publishableFamilies.has(family)) {
|
|
192
200
|
publishable = true
|
|
193
|
-
|
|
201
|
+
componentVersion ??= this.getComponentVersion(src.component, src.version) || { version: src.version }
|
|
194
202
|
activeVersionSegment =
|
|
195
203
|
'activeVersionSegment' in componentVersion
|
|
196
204
|
? componentVersion.activeVersionSegment
|
|
197
205
|
: computeVersionSegment.call(this, componentVersion)
|
|
198
|
-
file.out = computeOut(src, family, activeVersionSegment
|
|
206
|
+
file.out = computeOut.call(this, src, family, activeVersionSegment)
|
|
207
|
+
}
|
|
208
|
+
if (!file.pub) {
|
|
209
|
+
if ('pub' in file) {
|
|
210
|
+
delete file.pub
|
|
211
|
+
} else if (publishable || family === 'nav') {
|
|
212
|
+
referenceable = true
|
|
213
|
+
}
|
|
199
214
|
}
|
|
200
|
-
if (
|
|
201
|
-
if (activeVersionSegment
|
|
202
|
-
|
|
215
|
+
if (referenceable) {
|
|
216
|
+
if (activeVersionSegment === false) {
|
|
217
|
+
componentVersion ??= this.getComponentVersion(src.component, src.version) || { version: src.version }
|
|
203
218
|
activeVersionSegment =
|
|
204
219
|
'activeVersionSegment' in componentVersion
|
|
205
220
|
? componentVersion.activeVersionSegment
|
|
206
221
|
: computeVersionSegment.call(this, componentVersion)
|
|
207
222
|
}
|
|
208
|
-
file.pub = computePub(src, file.out, family, activeVersionSegment
|
|
223
|
+
file.pub = computePub.call(this, src, file.out, family, activeVersionSegment)
|
|
209
224
|
}
|
|
210
|
-
return
|
|
225
|
+
return file
|
|
211
226
|
}
|
|
212
227
|
|
|
213
228
|
removeFile (file) {
|
|
214
229
|
const src = file.src
|
|
215
|
-
|
|
216
|
-
return filesForFamily ? filesForFamily.delete(generateKey(src)) : false
|
|
230
|
+
return this[$files].get(src.family)?.delete(generateKey(src)) || false
|
|
217
231
|
}
|
|
218
232
|
|
|
219
233
|
findBy (criteria) {
|
|
@@ -263,21 +277,27 @@ class ContentCatalog {
|
|
|
263
277
|
return this.getComponents().sort((a, b) => a[property].localeCompare(b[property]))
|
|
264
278
|
}
|
|
265
279
|
|
|
266
|
-
getFiles () {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
for (const
|
|
280
|
+
getFiles (filter) {
|
|
281
|
+
const files = []
|
|
282
|
+
if (filter) {
|
|
283
|
+
for (const filesForFamily of this[$files].values()) {
|
|
284
|
+
for (const candidate of filesForFamily.values()) filter(candidate) && files.push(candidate)
|
|
285
|
+
}
|
|
286
|
+
} else {
|
|
287
|
+
for (const filesForFamily of this[$files].values()) {
|
|
288
|
+
for (const file of filesForFamily.values()) files.push(file)
|
|
289
|
+
}
|
|
270
290
|
}
|
|
271
|
-
return
|
|
291
|
+
return files
|
|
272
292
|
}
|
|
273
293
|
|
|
274
294
|
getPages (filter) {
|
|
275
295
|
const candidates = this[$files].get('page')
|
|
276
296
|
if (!candidates) return []
|
|
277
297
|
if (filter) {
|
|
278
|
-
const
|
|
279
|
-
for (const candidate of candidates.values()) filter(candidate) &&
|
|
280
|
-
return
|
|
298
|
+
const pages = []
|
|
299
|
+
for (const candidate of candidates.values()) filter(candidate) && pages.push(candidate)
|
|
300
|
+
return pages
|
|
281
301
|
}
|
|
282
302
|
return [...candidates.values()]
|
|
283
303
|
}
|
|
@@ -295,17 +315,14 @@ class ContentCatalog {
|
|
|
295
315
|
if ((file = this.getById(Object.assign({}, ROOT_INDEX_ALIAS_ID, { version })))) return file.rel
|
|
296
316
|
}
|
|
297
317
|
|
|
298
|
-
registerComponentVersionStartPage (
|
|
299
|
-
|
|
300
|
-
let version = componentVersion.version
|
|
301
|
-
if (version == null) {
|
|
318
|
+
registerComponentVersionStartPage (component, componentVersion, startPageSpec = undefined) {
|
|
319
|
+
if (componentVersion.constructor === String) {
|
|
302
320
|
// QUESTION: should we warn or throw error if component version cannot be found?
|
|
303
321
|
if (!(componentVersion = this.getComponentVersion(component, componentVersion))) return
|
|
304
|
-
version = componentVersion.version
|
|
305
322
|
}
|
|
323
|
+
const version = componentVersion.version
|
|
306
324
|
const activeVersionSegment = computeVersionSegment.call(this, componentVersion)
|
|
307
|
-
let startPage
|
|
308
|
-
let startPageSrc
|
|
325
|
+
let startPage, startPageSrc
|
|
309
326
|
const indexPageId = Object.assign({}, ROOT_INDEX_PAGE_ID, { component, version })
|
|
310
327
|
if (startPageSpec) {
|
|
311
328
|
if (
|
|
@@ -314,11 +331,11 @@ class ContentCatalog {
|
|
|
314
331
|
startPageSrc.version === version
|
|
315
332
|
) {
|
|
316
333
|
if (!this.getById(indexPageId)) {
|
|
317
|
-
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component, version })
|
|
334
|
+
const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component, version, componentVersion })
|
|
318
335
|
const indexAlias = this.getById(indexAliasId)
|
|
319
336
|
indexAlias
|
|
320
337
|
? indexAlias.synthetic && Object.assign(indexAlias, { rel: startPage })
|
|
321
|
-
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true }
|
|
338
|
+
: this.addFile({ src: indexAliasId, rel: startPage, synthetic: true })
|
|
322
339
|
}
|
|
323
340
|
} else {
|
|
324
341
|
// TODO pass componentVersion as logObject
|
|
@@ -337,20 +354,21 @@ class ContentCatalog {
|
|
|
337
354
|
if (startPage) {
|
|
338
355
|
componentVersion.url = startPage.pub.url
|
|
339
356
|
} else if (!componentVersion.url) {
|
|
357
|
+
startPageSrc = inflateSrc(Object.assign({}, indexPageId, { family: 'page' }))
|
|
340
358
|
// QUESTION: should we warn if the default start page cannot be found?
|
|
341
|
-
componentVersion.url = computePub(
|
|
342
|
-
|
|
343
|
-
|
|
359
|
+
componentVersion.url = computePub.call(
|
|
360
|
+
this,
|
|
361
|
+
startPageSrc,
|
|
362
|
+
computeOut.call(this, startPageSrc, startPageSrc.family, activeVersionSegment),
|
|
344
363
|
startPageSrc.family,
|
|
345
|
-
activeVersionSegment
|
|
346
|
-
this.htmlUrlExtensionStyle
|
|
364
|
+
activeVersionSegment
|
|
347
365
|
).url
|
|
348
366
|
}
|
|
349
367
|
Object.defineProperties(componentVersion, {
|
|
350
368
|
activeVersionSegment:
|
|
351
369
|
activeVersionSegment === version
|
|
352
|
-
? { configurable: true,
|
|
353
|
-
: { configurable: true,
|
|
370
|
+
? { configurable: true, get: getVersion }
|
|
371
|
+
: { configurable: true, value: activeVersionSegment },
|
|
354
372
|
files: {
|
|
355
373
|
configurable: true,
|
|
356
374
|
enumerable: false,
|
|
@@ -375,7 +393,7 @@ class ContentCatalog {
|
|
|
375
393
|
const rootIndexAlias = this.getById(ROOT_INDEX_ALIAS_ID)
|
|
376
394
|
if (rootIndexAlias) return rootIndexAlias.synthetic ? Object.assign(rootIndexAlias, { rel }) : undefined
|
|
377
395
|
const src = Object.assign({}, ROOT_INDEX_ALIAS_ID)
|
|
378
|
-
return this.addFile({ src, rel, synthetic: true }
|
|
396
|
+
return this.addFile({ src, rel, synthetic: true })
|
|
379
397
|
}
|
|
380
398
|
if (rel === false) {
|
|
381
399
|
logger.warn('Start page specified for site has invalid syntax: %s', startPageSpec)
|
|
@@ -394,14 +412,9 @@ class ContentCatalog {
|
|
|
394
412
|
// QUESTION should we throw an error if alias is invalid?
|
|
395
413
|
if (!src || (inferredSpec && src.relative === '.adoc')) return
|
|
396
414
|
const component = this.getComponent(src.component)
|
|
397
|
-
let componentVersion
|
|
398
415
|
if (component) {
|
|
399
416
|
// 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
|
-
}
|
|
417
|
+
src.version ??= (src.componentVersion = component.latest).version
|
|
405
418
|
const existingPage = this.getById(src)
|
|
406
419
|
if (existingPage) {
|
|
407
420
|
throw new Error(
|
|
@@ -426,7 +439,7 @@ class ContentCatalog {
|
|
|
426
439
|
)
|
|
427
440
|
}
|
|
428
441
|
// NOTE the redirect producer will populate contents when the redirect facility is 'static'
|
|
429
|
-
const alias = this.addFile({ src, rel: target }
|
|
442
|
+
const alias = this.addFile({ src, rel: target })
|
|
430
443
|
// NOTE record the first alias this target claims as the preferred one
|
|
431
444
|
if (!target.rel) target.rel = alias
|
|
432
445
|
return alias
|
|
@@ -445,12 +458,18 @@ class ContentCatalog {
|
|
|
445
458
|
const basePub = { splat: true }
|
|
446
459
|
const { component: fromComponent = to.component, versionSegment: fromVersionSegment } = from
|
|
447
460
|
const fromSrc = Object.assign({ component: fromComponent, version: fromVersionSegment }, baseSrc)
|
|
448
|
-
const fromPub = Object.assign(
|
|
461
|
+
const fromPub = Object.assign(
|
|
462
|
+
computePub.call(this, fromSrc, computeOut.call(this, fromSrc, family, fromVersionSegment), family),
|
|
463
|
+
basePub
|
|
464
|
+
)
|
|
449
465
|
const { component: toComponent, version: toVersion } = to
|
|
450
466
|
const toVersionSegment =
|
|
451
467
|
to.versionSegment ?? this.getComponentVersion(toComponent, toVersion)?.activeVersionSegment ?? toVersion
|
|
452
468
|
const toSrc = Object.assign({ component: toComponent, version: toVersion ?? toVersionSegment }, baseSrc)
|
|
453
|
-
const toPub = Object.assign(
|
|
469
|
+
const toPub = Object.assign(
|
|
470
|
+
computePub.call(this, toSrc, computeOut.call(this, toSrc, family, toVersionSegment), family),
|
|
471
|
+
basePub
|
|
472
|
+
)
|
|
454
473
|
return this.addFile({ pub: fromPub, src: fromSrc, rel: { pub: toPub, src: toSrc } })
|
|
455
474
|
}
|
|
456
475
|
|
|
@@ -536,7 +555,7 @@ function generateResourceSpec ({ component, version, module: module_, family, re
|
|
|
536
555
|
)
|
|
537
556
|
}
|
|
538
557
|
|
|
539
|
-
function
|
|
558
|
+
function inflateSrc (src) {
|
|
540
559
|
let { basename, extname, stem } = src
|
|
541
560
|
if (basename == null) {
|
|
542
561
|
basename = src.basename = path.basename(src.relative)
|
|
@@ -544,22 +563,22 @@ function prepareSrc (src) {
|
|
|
544
563
|
if (stem == null) {
|
|
545
564
|
if (extname == null) {
|
|
546
565
|
if (~(extname = basename.lastIndexOf('.'))) {
|
|
547
|
-
src.stem = basename.
|
|
548
|
-
src.extname = basename.
|
|
566
|
+
src.stem = basename.substring(0, extname)
|
|
567
|
+
src.extname = basename.substring(extname)
|
|
549
568
|
} else {
|
|
550
569
|
src.stem = basename
|
|
551
570
|
src.extname = ''
|
|
552
571
|
}
|
|
553
572
|
} else {
|
|
554
|
-
src.stem = basename.
|
|
573
|
+
src.stem = basename.substring(0, basename.length - extname.length)
|
|
555
574
|
}
|
|
556
575
|
} else if (extname == null) {
|
|
557
|
-
src.extname = basename.
|
|
576
|
+
src.extname = basename.substring(stem.length)
|
|
558
577
|
}
|
|
559
578
|
return src
|
|
560
579
|
}
|
|
561
580
|
|
|
562
|
-
function computeOut (src, family, versionSegment
|
|
581
|
+
function computeOut (src, family, versionSegment) {
|
|
563
582
|
let { component, module: module_, basename, extname, relative, stem } = src
|
|
564
583
|
if (component === 'ROOT') component = ''
|
|
565
584
|
if (module_ === 'ROOT') module_ = ''
|
|
@@ -567,16 +586,14 @@ function computeOut (src, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
567
586
|
let familyPathSegment = ''
|
|
568
587
|
|
|
569
588
|
if (family === 'page') {
|
|
570
|
-
if (stem !== 'index' && htmlUrlExtensionStyle === 'indexify') {
|
|
589
|
+
if (stem !== 'index' && this.htmlUrlExtensionStyle === 'indexify') {
|
|
571
590
|
basename = 'index.html'
|
|
572
591
|
indexifyPathSegment = stem
|
|
573
592
|
} else if (extname === '.adoc') {
|
|
574
593
|
basename = stem + '.html'
|
|
575
594
|
}
|
|
576
|
-
} else if (family
|
|
577
|
-
familyPathSegment = '
|
|
578
|
-
} else if (family === 'attachment') {
|
|
579
|
-
familyPathSegment = '_attachments'
|
|
595
|
+
} else if (this.publishableFamilies.has(family)) {
|
|
596
|
+
familyPathSegment = '_' + family + 's'
|
|
580
597
|
}
|
|
581
598
|
|
|
582
599
|
const modulePath = path.join(component, versionSegment, module_)
|
|
@@ -588,7 +605,7 @@ function computeOut (src, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
588
605
|
return { dirname, basename, path: path_, moduleRootPath, rootPath }
|
|
589
606
|
}
|
|
590
607
|
|
|
591
|
-
function computePub (src, out, family, versionSegment
|
|
608
|
+
function computePub (src, out, family, versionSegment) {
|
|
592
609
|
const pub = {}
|
|
593
610
|
let url
|
|
594
611
|
if (family === 'nav') {
|
|
@@ -604,12 +621,12 @@ function computePub (src, out, family, versionSegment, htmlUrlExtensionStyle) {
|
|
|
604
621
|
} else if (family === 'page') {
|
|
605
622
|
const urlSegments = out.path.split('/')
|
|
606
623
|
const lastUrlSegmentIdx = urlSegments.length - 1
|
|
607
|
-
if (htmlUrlExtensionStyle === 'drop') {
|
|
624
|
+
if (this.htmlUrlExtensionStyle === 'drop') {
|
|
608
625
|
// drop just the .html extension or, if the filename is index.html, the whole segment
|
|
609
626
|
const lastUrlSegment = urlSegments[lastUrlSegmentIdx]
|
|
610
627
|
urlSegments[lastUrlSegmentIdx] =
|
|
611
|
-
lastUrlSegment === 'index.html' ? '' : lastUrlSegment.
|
|
612
|
-
} else if (htmlUrlExtensionStyle === 'indexify') {
|
|
628
|
+
lastUrlSegment === 'index.html' ? '' : lastUrlSegment.substring(0, lastUrlSegment.length - 5)
|
|
629
|
+
} else if (this.htmlUrlExtensionStyle === 'indexify') {
|
|
613
630
|
urlSegments[lastUrlSegmentIdx] = ''
|
|
614
631
|
}
|
|
615
632
|
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.2",
|
|
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.2",
|
|
35
|
+
"@antora/logger": "3.2.0-rc.2",
|
|
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
|
}
|