@antora/ui-loader 3.0.0-alpha.7 → 3.0.0-beta.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/README.md CHANGED
@@ -4,7 +4,7 @@ The UI Loader is a component in Antora responsible for downloading and caching t
4
4
  The UI files are combined with the content files at the end of the Antora documentation pipeline to produce a complete site.
5
5
 
6
6
  [Antora](https://antora.org) is a modular static site generator designed for creating documentation sites from AsciiDoc documents.
7
- Its site generator pipeline aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
7
+ Its site generator aggregates documents from versioned content repositories and processes them using [Asciidoctor](https://asciidoctor.org).
8
8
 
9
9
  ## Copyright and License
10
10
 
package/lib/constants.js CHANGED
@@ -1,7 +1,17 @@
1
1
  'use strict'
2
2
 
3
3
  module.exports = Object.freeze({
4
- SUPPLEMENTAL_FILES_GLOB: '**/*',
5
4
  UI_CACHE_FOLDER: 'ui',
6
5
  UI_DESC_FILENAME: 'ui.yml',
6
+ UI_SRC_GLOB: '**/*[!~]',
7
+ UI_SRC_OPTS: {
8
+ dot: true,
9
+ follow: true,
10
+ ignore: ['.git/**'],
11
+ nomount: true,
12
+ nosort: true,
13
+ nounique: true,
14
+ removeBOM: false,
15
+ uniqueBy: (m) => m,
16
+ },
7
17
  })
package/lib/file.js CHANGED
@@ -18,6 +18,10 @@ class File extends Vinyl {
18
18
  get relative () {
19
19
  return this.history[this.history.length - 1]
20
20
  }
21
+
22
+ isDot () {
23
+ return ('/' + this.history[this.history.length - 1]).indexOf('/.') > -1
24
+ }
21
25
  }
22
26
 
23
27
  class MemoryFile extends File {
package/lib/load-ui.js CHANGED
@@ -19,7 +19,7 @@ const yaml = require('js-yaml')
19
19
  const vfs = require('vinyl-fs')
20
20
  const vzip = require('gulp-vinyl-zip')
21
21
 
22
- const { UI_CACHE_FOLDER, UI_DESC_FILENAME, SUPPLEMENTAL_FILES_GLOB } = require('./constants')
22
+ const { UI_CACHE_FOLDER, UI_DESC_FILENAME, UI_SRC_GLOB, UI_SRC_OPTS } = require('./constants')
23
23
  const URI_SCHEME_RX = /^https?:\/\//
24
24
  const EXT_RX = /\.[a-z]{2,3}$/
25
25
 
@@ -48,7 +48,7 @@ const EXT_RX = /\.[a-z]{2,3}$/
48
48
  * @param {String} [playbook.network.noProxy=undefined] - The list of domains and IPs that should not be proxied.
49
49
  * @param {Object} playbook.ui - The UI configuration object for Antora.
50
50
  * @param {String} playbook.ui.bundle - The UI bundle configuration.
51
- * @param {String} playbook.ui.bundle.url - The path (relative or absolute) or URI
51
+ * @param {String} playbook.ui.bundle.url - The path (relative or absolute) or URL
52
52
  * of the UI bundle to use.
53
53
  * @param {String} [playbook.ui.bundle.startPath=''] - The path inside the bundle from
54
54
  * which to start reading files.
@@ -73,29 +73,29 @@ async function loadUi (playbook) {
73
73
  const cachePath = ospath.join(absCacheDir, `${sha1(bundleUrl)}.zip`)
74
74
  return fetch && bundle.snapshot
75
75
  ? downloadBundle(bundleUrl, cachePath, createAgent(bundleUrl, playbook.network || {}))
76
- : fsp
77
- .stat(cachePath)
78
- .then((stat) => new File({ path: cachePath, stat }))
79
- .catch(() => downloadBundle(bundleUrl, cachePath, createAgent(bundleUrl, playbook.network || {})))
76
+ : fsp.stat(cachePath).then(
77
+ (stat) => new File({ path: cachePath, stat }),
78
+ () => downloadBundle(bundleUrl, cachePath, createAgent(bundleUrl, playbook.network || {}))
79
+ )
80
80
  })
81
81
  } else {
82
- const localPath = expandPath(bundleUrl, '~+', startDir)
83
- resolveBundle = fsp
84
- .stat(localPath)
85
- .then((stat) => new File({ path: localPath, stat }))
86
- .catch(() => {
82
+ const localPath = expandPath(bundleUrl, { dot: startDir })
83
+ resolveBundle = fsp.stat(localPath).then(
84
+ (stat) => new File({ path: localPath, stat }),
85
+ () => {
87
86
  throw new Error(
88
87
  `Specified UI ${path.extname(localPath) ? 'bundle' : 'directory'} does not exist: ` +
89
88
  (bundleUrl === localPath ? bundleUrl : `${localPath} (resolved from url: ${bundleUrl})`)
90
89
  )
91
- })
90
+ }
91
+ )
92
92
  }
93
93
  const files = await Promise.all([
94
94
  resolveBundle.then((bundleFile) =>
95
95
  new Promise((resolve, reject) =>
96
96
  bundleFile.isDirectory()
97
97
  ? vfs
98
- .src('**/*', { cwd: bundleFile.path, removeBOM: false })
98
+ .src(UI_SRC_GLOB, Object.assign({ cwd: bundleFile.path }, UI_SRC_OPTS))
99
99
  .on('error', reject)
100
100
  .pipe(relativizeFiles())
101
101
  .pipe(collectFiles(resolve))
@@ -147,28 +147,24 @@ function ensureCacheDir (customCacheDir, startDir) {
147
147
  const baseCacheDir =
148
148
  customCacheDir == null
149
149
  ? getCacheDir('antora' + (process.env.NODE_ENV === 'test' ? '-test' : '')) || ospath.resolve('.antora/cache')
150
- : expandPath(customCacheDir, '~+', startDir)
150
+ : expandPath(customCacheDir, { dot: startDir })
151
151
  const cacheDir = ospath.join(baseCacheDir, UI_CACHE_FOLDER)
152
- return fsp
153
- .mkdir(cacheDir, { recursive: true })
154
- .then(() => cacheDir)
155
- .catch((err) => {
152
+ return fsp.mkdir(cacheDir, { recursive: true }).then(
153
+ () => cacheDir,
154
+ (err) => {
156
155
  throw Object.assign(err, { message: `Failed to create UI cache directory: ${cacheDir}; ${err.message}` })
157
- })
156
+ }
157
+ )
158
158
  }
159
159
 
160
160
  function createAgent (url, { httpProxy, httpsProxy, noProxy }) {
161
- if (httpsProxy || httpProxy) {
161
+ if ((httpsProxy || httpProxy) && noProxy !== '*') {
162
162
  const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent')
163
+ const shouldProxy = require('should-proxy')
163
164
  const proxy = url.startsWith('https:')
164
- ? { ProxyAgent: HttpsProxyAgent, url: httpsProxy }
165
- : { ProxyAgent: HttpProxyAgent, url: httpProxy }
166
- if (proxy.url && require('should-proxy')(url, { no_proxy: noProxy })) {
167
- // see https://github.com/delvedor/hpagent/issues/18
168
- const { protocol, hostname, port, username, password } = new URL(proxy.url)
169
- const proxyUrl = { protocol, hostname, port, username: username || null, password: password || null }
170
- return new proxy.ProxyAgent({ proxy: proxyUrl })
171
- }
165
+ ? { Agent: HttpsProxyAgent, url: httpsProxy }
166
+ : { Agent: HttpProxyAgent, url: httpProxy }
167
+ if (proxy.url && shouldProxy(url, { no_proxy: noProxy })) return new proxy.Agent({ proxy: proxy.url })
172
168
  }
173
169
  }
174
170
 
@@ -235,11 +231,10 @@ function bufferizeContents () {
235
231
  if (file.isStream()) {
236
232
  concat(file.contents, (err, contents) => {
237
233
  if (err) return next(err)
238
- file.stat.size = (file.contents = contents).length
234
+ file.contents = contents
239
235
  next(null, file)
240
236
  })
241
237
  } else {
242
- file.stat.size = file.contents.length
243
238
  next(null, file)
244
239
  }
245
240
  })
@@ -268,7 +263,7 @@ function srcSupplementalFiles (filesSpec, startDir) {
268
263
  if (~contents_.indexOf('\n') || !EXT_RX.test(contents_)) {
269
264
  accum.push(new MemoryFile({ path: path_, contents: Buffer.from(contents_) }))
270
265
  } else {
271
- contents_ = expandPath(contents_, '~+', startDir)
266
+ contents_ = expandPath(contents_, { dot: startDir })
272
267
  accum.push(
273
268
  fsp
274
269
  .stat(contents_)
@@ -282,14 +277,14 @@ function srcSupplementalFiles (filesSpec, startDir) {
282
277
  }, [])
283
278
  ).then((files) => files.reduce((accum, file) => accum.set(file.path, file) && accum, new Map()))
284
279
  } else {
285
- const cwd = expandPath(filesSpec, '~+', startDir)
280
+ const cwd = expandPath(filesSpec, { dot: startDir })
286
281
  return fsp
287
282
  .access(cwd)
288
283
  .then(
289
284
  () =>
290
285
  new Promise((resolve, reject) =>
291
286
  vfs
292
- .src(SUPPLEMENTAL_FILES_GLOB, { cwd, dot: true, removeBOM: false })
287
+ .src(UI_SRC_GLOB, Object.assign({ cwd, dot: true }, UI_SRC_OPTS))
293
288
  .on('error', reject)
294
289
  .pipe(relativizeFiles())
295
290
  .pipe(collectFiles(resolve))
@@ -342,11 +337,10 @@ function classifyFile (file, config) {
342
337
  if (config.staticFiles && isStaticFile(file, config.staticFiles)) {
343
338
  file.type = 'static'
344
339
  file.out = resolveOut(file, '')
345
- } else if (file.local && ~('/' + file.relative).indexOf('/.')) {
340
+ } else if (file.isDot()) {
346
341
  file = undefined
347
- } else {
348
- file.type = resolveType(file)
349
- if (file.type === 'asset') file.out = resolveOut(file, config.outputDir)
342
+ } else if ((file.type = resolveType(file)) === 'asset') {
343
+ file.out = resolveOut(file, config.outputDir)
350
344
  }
351
345
  return file
352
346
  }
@@ -357,15 +351,10 @@ function isStaticFile (file, staticFiles) {
357
351
 
358
352
  function resolveType (file) {
359
353
  const firstPathSegment = file.path.split('/', 1)[0]
360
- if (firstPathSegment === 'layouts') {
361
- return 'layout'
362
- } else if (firstPathSegment === 'helpers') {
363
- return 'helper'
364
- } else if (firstPathSegment === 'partials') {
365
- return 'partial'
366
- } else {
367
- return 'asset'
368
- }
354
+ if (firstPathSegment === 'layouts') return 'layout'
355
+ if (firstPathSegment === 'helpers') return 'helper'
356
+ if (firstPathSegment === 'partials') return 'partial'
357
+ return 'asset'
369
358
  }
370
359
 
371
360
  function resolveOut (file, outputDir = '_') {
package/lib/ui-catalog.js CHANGED
@@ -8,23 +8,27 @@ class UiCatalog {
8
8
  }
9
9
 
10
10
  getFiles () {
11
- return [...this[$files].values()]
11
+ const accum = []
12
+ for (const filesForType of this[$files].values()) {
13
+ for (const file of filesForType.values()) accum.push(file)
14
+ }
15
+ return accum
12
16
  }
13
17
 
14
18
  addFile (file) {
15
- const key = generateKey(file)
16
- if (this[$files].has(key)) {
19
+ let filesForType = this[$files].get(file.type)
20
+ if (!filesForType) this[$files].set(file.type, (filesForType = new Map()))
21
+ const key = file.path
22
+ if (filesForType.has(key)) {
17
23
  throw new Error('Duplicate file')
18
24
  }
19
- this[$files].set(key, file)
25
+ filesForType.set(key, file)
26
+ return file
20
27
  }
21
28
 
22
29
  findByType (type) {
23
- const accum = []
24
- for (const candidate of this[$files].values()) {
25
- if (candidate.type === type) accum.push(candidate)
26
- }
27
- return accum
30
+ const filesForType = this[$files].get(type)
31
+ return filesForType ? [...filesForType.values()] : []
28
32
  }
29
33
  }
30
34
 
@@ -33,8 +37,4 @@ class UiCatalog {
33
37
  */
34
38
  UiCatalog.prototype.getAll = UiCatalog.prototype.getFiles
35
39
 
36
- function generateKey ({ type, path }) {
37
- return type + '$' + path
38
- }
39
-
40
40
  module.exports = UiCatalog
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antora/ui-loader",
3
- "version": "3.0.0-alpha.7",
3
+ "version": "3.0.0-beta.2",
4
4
  "description": "Downloads a UI bundle, if necessary, and loads the files into a UI catalog for use in an Antora documentation pipeline.",
5
5
  "license": "MPL-2.0",
6
6
  "author": "OpenDevise Inc. (https://opendevise.com)",
@@ -17,10 +17,10 @@
17
17
  },
18
18
  "main": "lib/index.js",
19
19
  "dependencies": {
20
- "@antora/expand-path-helper": "~1.0",
20
+ "@antora/expand-path-helper": "~2.0",
21
21
  "cache-directory": "~2.0",
22
- "camelcase-keys": "~6.2",
23
- "gulp-vinyl-zip": "~2.2",
22
+ "camelcase-keys": "~7.0",
23
+ "gulp-vinyl-zip": "~2.5",
24
24
  "hpagent": "~0.1.0",
25
25
  "js-yaml": "~4.1",
26
26
  "minimatch-all": "~1.1",
@@ -31,7 +31,7 @@
31
31
  "vinyl-fs": "~3.0"
32
32
  },
33
33
  "engines": {
34
- "node": ">=10.17.0"
34
+ "node": ">=12.21.0"
35
35
  },
36
36
  "files": [
37
37
  "lib/"
@@ -45,5 +45,5 @@
45
45
  "static site",
46
46
  "web publishing"
47
47
  ],
48
- "gitHead": "fbd597b3680474f2083cda8a7facf1e2848c08e0"
48
+ "gitHead": "5cd3f9cc70622e465cb44daf1aa2035ed5a35f54"
49
49
  }