@antora/content-classifier 3.0.0-alpha.9 → 3.0.0-beta.4

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  The Content Classifier is a component in Antora responsible for organizing aggregated content into a virtual file catalog for use in an Antora documentation pipeline.
4
4
 
5
5
  [Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents.
6
- Its site generator pipeline aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
6
+ Its site generator aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
7
7
 
8
8
  ## Copyright and License
9
9
 
package/lib/constants.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = Object.freeze({
4
- START_ALIAS_ID: Object.freeze({ component: '', version: '', module: '', family: 'alias', relative: 'index.adoc' }),
5
- START_PAGE_ID: Object.freeze({ component: '', version: '', module: '', family: 'page', relative: 'index.adoc' }),
4
+ ROOT_INDEX_ALIAS_ID: { component: 'ROOT', version: '', module: 'ROOT', family: 'alias', relative: 'index.adoc' },
5
+ ROOT_INDEX_PAGE_ID: { component: 'ROOT', version: '', module: 'ROOT', family: 'page', relative: 'index.adoc' },
6
6
  })
@@ -9,7 +9,7 @@ const { posix: path } = require('path')
9
9
  const resolveResource = require('./util/resolve-resource')
10
10
  const versionCompare = require('./util/version-compare-desc')
11
11
 
12
- const { START_ALIAS_ID, START_PAGE_ID } = require('./constants')
12
+ const { ROOT_INDEX_ALIAS_ID, ROOT_INDEX_PAGE_ID } = require('./constants')
13
13
  const SPACE_RX = / /g
14
14
 
15
15
  const $components = Symbol('components')
@@ -169,11 +169,11 @@ class ContentCatalog {
169
169
  ('/' + src.relative).indexOf('/_') < 0
170
170
  ) {
171
171
  publishable = true
172
- versionSegment = computeVersionSegment.bind(this)(src.component, src.version)
172
+ versionSegment = computeVersionSegment.call(this, src.component, src.version)
173
173
  file.out = computeOut(src, family, versionSegment, this.htmlUrlExtensionStyle)
174
174
  }
175
175
  if (!file.pub && (publishable || family === 'nav')) {
176
- if (versionSegment == null) versionSegment = computeVersionSegment.bind(this)(src.component, src.version)
176
+ if (versionSegment == null) versionSegment = computeVersionSegment.call(this, src.component, src.version)
177
177
  file.pub = computePub(src, file.out, family, versionSegment, this.htmlUrlExtensionStyle)
178
178
  }
179
179
  filesForFamily.set(key, file)
@@ -249,7 +249,7 @@ class ContentCatalog {
249
249
 
250
250
  // TODO add `follow` argument to control whether alias is followed
251
251
  getSiteStartPage () {
252
- return this.getById(START_PAGE_ID) || (this.getById(START_ALIAS_ID) || {}).rel
252
+ return this.getById(ROOT_INDEX_PAGE_ID) || (this.getById(ROOT_INDEX_ALIAS_ID) || {}).rel
253
253
  }
254
254
 
255
255
  registerComponentVersionStartPage (name, componentVersion, startPageSpec = undefined) {
@@ -261,15 +261,19 @@ class ContentCatalog {
261
261
  }
262
262
  let startPage
263
263
  let startPageSrc
264
- const indexPageId = { component: name, version, module: 'ROOT', family: 'page', relative: 'index.adoc' }
264
+ const indexPageId = Object.assign({}, ROOT_INDEX_PAGE_ID, { component: name, version })
265
265
  if (startPageSpec) {
266
266
  if (
267
267
  (startPage = this.resolvePage(startPageSpec, indexPageId)) &&
268
268
  (startPageSrc = startPage.src).component === name &&
269
269
  startPageSrc.version === version
270
270
  ) {
271
- if ((startPageSrc.module !== 'ROOT' || startPageSrc.relative !== 'index.adoc') && !this.getById(indexPageId)) {
272
- this.addFile({ src: Object.assign({}, indexPageId, { family: 'alias' }), rel: startPage })
271
+ if (!this.getById(indexPageId)) {
272
+ const indexAliasId = Object.assign({}, ROOT_INDEX_ALIAS_ID, { component: name, version })
273
+ const indexAlias = this.getById(indexAliasId)
274
+ indexAlias
275
+ ? indexAlias.synthetic && Object.assign(indexAlias, { rel: startPage })
276
+ : this.addFile({ src: indexAliasId, rel: startPage, synthetic: true })
273
277
  }
274
278
  } else {
275
279
  // TODO pass componentVersion as logObject
@@ -289,7 +293,7 @@ class ContentCatalog {
289
293
  componentVersion.url = startPage.pub.url
290
294
  } else {
291
295
  // QUESTION: should we warn if the default start page cannot be found?
292
- const versionSegment = computeVersionSegment.bind(this)(name, version)
296
+ const versionSegment = computeVersionSegment.call(this, name, version)
293
297
  componentVersion.url = computePub(
294
298
  (startPageSrc = prepareSrc(Object.assign({}, indexPageId, { family: 'page' }))),
295
299
  computeOut(startPageSrc, startPageSrc.family, versionSegment, this.htmlUrlExtensionStyle),
@@ -302,7 +306,7 @@ class ContentCatalog {
302
306
  const symbolicVersionAlias = createSymbolicVersionAlias(
303
307
  name,
304
308
  version,
305
- computeVersionSegment.bind(this)(name, version, 'alias'),
309
+ computeVersionSegment.call(this, name, version, 'alias'),
306
310
  this.latestVersionUrlSegmentStrategy
307
311
  )
308
312
  if (symbolicVersionAlias) this.addFile(symbolicVersionAlias)
@@ -312,7 +316,10 @@ class ContentCatalog {
312
316
  if (!startPageSpec) return
313
317
  const rel = this.resolvePage(startPageSpec)
314
318
  if (rel) {
315
- return this.addFile({ src: Object.assign({}, START_ALIAS_ID), rel })
319
+ if (this.getById(ROOT_INDEX_PAGE_ID)) return
320
+ const indexAlias = this.getById(ROOT_INDEX_ALIAS_ID)
321
+ if (indexAlias) return indexAlias.synthetic ? Object.assign(indexAlias, { rel }) : undefined
322
+ return this.addFile({ src: Object.assign({}, ROOT_INDEX_ALIAS_ID), rel, synthetic: true })
316
323
  } else if (rel === false) {
317
324
  logger.warn('Start page specified for site has invalid syntax: %s', startPageSpec)
318
325
  } else if (~startPageSpec.indexOf(':')) {
@@ -367,9 +374,10 @@ class ContentCatalog {
367
374
  *
368
375
  * Parses the specified contextual page ID spec into a page ID object, then attempts to lookup a
369
376
  * file with this page ID in the catalog. If a component is specified, but not a version, the
370
- * latest version of the component stored in the catalog is used. If a file cannot be resolved,
371
- * the function returns undefined. If the spec does not match the page ID syntax, this function
372
- * throws an error.
377
+ * latest version of the component stored in the catalog is used. If a page cannot be resolved,
378
+ * the search is attempted again for an "alias". If neither a page or alias can be resolved, the
379
+ * function returns undefined. If the spec does not match the page ID syntax, this function throws
380
+ * an error.
373
381
  *
374
382
  * @param {String} spec - The contextual page ID spec (e.g., version@component:module:topic/page.adoc).
375
383
  * @param {ContentCatalog} catalog - The content catalog in which to resolve the page file.
@@ -450,6 +458,7 @@ function prepareSrc (src) {
450
458
 
451
459
  function computeOut (src, family, version, htmlUrlExtensionStyle) {
452
460
  let { component, module: module_, basename, extname, relative, stem } = src
461
+ if (component === 'ROOT') component = ''
453
462
  if (module_ === 'ROOT') module_ = ''
454
463
  let indexifyPathSegment = ''
455
464
  let familyPathSegment = ''
@@ -480,8 +489,11 @@ function computePub (src, out, family, version, htmlUrlExtensionStyle) {
480
489
  const pub = {}
481
490
  let url
482
491
  if (family === 'nav') {
483
- const urlSegments = version ? [src.component, version] : [src.component]
484
- if (src.module && src.module !== 'ROOT') urlSegments.push(src.module)
492
+ const component = src.component || 'ROOT'
493
+ const urlSegments = component === 'ROOT' ? [] : [component]
494
+ if (version) urlSegments.push(version)
495
+ const module_ = src.module || 'ROOT'
496
+ if (module_ !== 'ROOT') urlSegments.push(module_)
485
497
  // an artificial URL used for resolving page references in navigation model
486
498
  url = '/' + urlSegments.join('/') + '/'
487
499
  pub.moduleRootPath = '.'
@@ -56,9 +56,16 @@ function parseResourceId (spec, ctx = {}, defaultFamily = 'page', permittedFamil
56
56
  }
57
57
 
58
58
  if (~relative.indexOf('/')) {
59
- relative = relative
60
- .split('/')
61
- .filter((it) => it && it !== '.' && it !== '..')
59
+ const relativeSegments = relative.split('/')
60
+ let from
61
+ if (relativeSegments[0] === '.' && (from = ctx.relative)) {
62
+ relativeSegments[0] = from.substr(0, (from.lastIndexOf('/') + 1 || 1) - 1)
63
+ }
64
+ relative = relativeSegments
65
+ .reduce((accum, segment) => {
66
+ segment === '..' ? accum.pop() : (segment || '.') !== '.' && accum.push(segment)
67
+ return accum
68
+ }, [])
62
69
  .join('/')
63
70
  }
64
71
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/content-classifier",
3
- "version": "3.0.0-alpha.9",
3
+ "version": "3.0.0-beta.4",
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)",
@@ -16,12 +16,12 @@
16
16
  },
17
17
  "main": "lib/index.js",
18
18
  "dependencies": {
19
- "@antora/logger": "3.0.0-alpha.9",
19
+ "@antora/logger": "3.0.0-beta.4",
20
20
  "mime-types": "~2.1",
21
21
  "vinyl": "~2.2"
22
22
  },
23
23
  "engines": {
24
- "node": ">=10.17.0"
24
+ "node": ">=12.21.0"
25
25
  },
26
26
  "files": [
27
27
  "lib/"
@@ -34,5 +34,6 @@
34
34
  "static site",
35
35
  "web publishing"
36
36
  ],
37
- "gitHead": "a504d6889819b548e8a5416a7194cbb6f9a93e93"
37
+ "gitHead": "8a142499e9f1a9e0631777796e06dd6c010d3a90",
38
+ "readmeFilename": "README.md"
38
39
  }