@antora/ui-loader 3.0.0-beta.2 → 3.0.0-beta.3
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/constants.js +1 -1
- package/lib/load-ui.js +65 -42
- package/package.json +5 -5
package/lib/constants.js
CHANGED
package/lib/load-ui.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
const { compile: bracesToGroup } = require('braces')
|
|
3
4
|
const camelCaseKeys = require('camelcase-keys')
|
|
4
5
|
const concat = require('simple-concat')
|
|
5
6
|
const { createHash } = require('crypto')
|
|
@@ -8,17 +9,25 @@ const { File, MemoryFile, ReadableFile } = require('./file')
|
|
|
8
9
|
const { promises: fsp } = require('fs')
|
|
9
10
|
const { concat: get } = require('simple-get')
|
|
10
11
|
const getCacheDir = require('cache-directory')
|
|
11
|
-
const
|
|
12
|
+
const globStream = require('glob-stream')
|
|
12
13
|
const ospath = require('path')
|
|
13
14
|
const { posix: path } = ospath
|
|
15
|
+
const picomatch = require('picomatch')
|
|
14
16
|
const posixify = ospath.sep === '\\' ? (p) => p.replace(/\\/g, '/') : undefined
|
|
15
|
-
const { Transform } = require('stream')
|
|
17
|
+
const { pipeline, Transform } = require('stream')
|
|
16
18
|
const map = (transform, flush = undefined) => new Transform({ objectMode: true, transform, flush })
|
|
17
19
|
const UiCatalog = require('./ui-catalog')
|
|
18
20
|
const yaml = require('js-yaml')
|
|
19
|
-
const vfs = require('vinyl-fs')
|
|
20
21
|
const vzip = require('gulp-vinyl-zip')
|
|
21
22
|
|
|
23
|
+
const STATIC_FILE_MATCHER_OPTS = {
|
|
24
|
+
expandRange: (begin, end, step, opts) => bracesToGroup(opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`),
|
|
25
|
+
fastpaths: false,
|
|
26
|
+
nobracket: true,
|
|
27
|
+
noquantifiers: true,
|
|
28
|
+
regex: false,
|
|
29
|
+
strictSlashes: true,
|
|
30
|
+
}
|
|
22
31
|
const { UI_CACHE_FOLDER, UI_DESC_FILENAME, UI_SRC_GLOB, UI_SRC_OPTS } = require('./constants')
|
|
23
32
|
const URI_SCHEME_RX = /^https?:\/\//
|
|
24
33
|
const EXT_RX = /\.[a-z]{2,3}$/
|
|
@@ -94,11 +103,7 @@ async function loadUi (playbook) {
|
|
|
94
103
|
resolveBundle.then((bundleFile) =>
|
|
95
104
|
new Promise((resolve, reject) =>
|
|
96
105
|
bundleFile.isDirectory()
|
|
97
|
-
?
|
|
98
|
-
.src(UI_SRC_GLOB, Object.assign({ cwd: bundleFile.path }, UI_SRC_OPTS))
|
|
99
|
-
.on('error', reject)
|
|
100
|
-
.pipe(relativizeFiles())
|
|
101
|
-
.pipe(collectFiles(resolve))
|
|
106
|
+
? srcFs(bundleFile.path).then(resolve, reject)
|
|
102
107
|
: vzip
|
|
103
108
|
.src(bundleFile.path)
|
|
104
109
|
.on('error', (err) => reject(Object.assign(err, { message: `not a valid zip file; ${err.message}` })))
|
|
@@ -280,16 +285,7 @@ function srcSupplementalFiles (filesSpec, startDir) {
|
|
|
280
285
|
const cwd = expandPath(filesSpec, { dot: startDir })
|
|
281
286
|
return fsp
|
|
282
287
|
.access(cwd)
|
|
283
|
-
.then(
|
|
284
|
-
() =>
|
|
285
|
-
new Promise((resolve, reject) =>
|
|
286
|
-
vfs
|
|
287
|
-
.src(UI_SRC_GLOB, Object.assign({ cwd, dot: true }, UI_SRC_OPTS))
|
|
288
|
-
.on('error', reject)
|
|
289
|
-
.pipe(relativizeFiles())
|
|
290
|
-
.pipe(collectFiles(resolve))
|
|
291
|
-
)
|
|
292
|
-
)
|
|
288
|
+
.then(() => srcFs(cwd))
|
|
293
289
|
.catch((err) => {
|
|
294
290
|
// Q: should we skip unreadable files?
|
|
295
291
|
throw Object.assign(err, { message: `problem encountered while reading ui.supplemental_files: ${err.message}` })
|
|
@@ -297,17 +293,6 @@ function srcSupplementalFiles (filesSpec, startDir) {
|
|
|
297
293
|
}
|
|
298
294
|
}
|
|
299
295
|
|
|
300
|
-
function relativizeFiles () {
|
|
301
|
-
return map((file, _, next) => {
|
|
302
|
-
if (file.isNull()) {
|
|
303
|
-
next()
|
|
304
|
-
} else {
|
|
305
|
-
const path_ = posixify ? posixify(file.relative) : file.relative
|
|
306
|
-
next(null, new File({ cwd: file.cwd, path: path_, contents: file.contents, stat: file.stat, local: true }))
|
|
307
|
-
}
|
|
308
|
-
})
|
|
309
|
-
}
|
|
310
|
-
|
|
311
296
|
function mergeFiles (files, supplementalFiles) {
|
|
312
297
|
if (supplementalFiles.size) supplementalFiles.forEach((file) => files.set(file.path, file))
|
|
313
298
|
return files
|
|
@@ -318,15 +303,9 @@ function loadConfig (files, outputDir) {
|
|
|
318
303
|
if (configFile) {
|
|
319
304
|
files.delete(UI_DESC_FILENAME)
|
|
320
305
|
const config = camelCaseKeys(yaml.load(configFile.contents.toString()), { deep: true })
|
|
321
|
-
if (outputDir !== undefined) config.outputDir = outputDir
|
|
322
306
|
const staticFiles = config.staticFiles
|
|
323
|
-
if (staticFiles)
|
|
324
|
-
|
|
325
|
-
config.staticFiles = [staticFiles]
|
|
326
|
-
} else if (staticFiles.length === 0) {
|
|
327
|
-
delete config.staticFiles
|
|
328
|
-
}
|
|
329
|
-
}
|
|
307
|
+
if (staticFiles && staticFiles.length) config.isStaticFile = picomatch(staticFiles, STATIC_FILE_MATCHER_OPTS)
|
|
308
|
+
if (outputDir !== undefined) config.outputDir = outputDir
|
|
330
309
|
return config
|
|
331
310
|
} else {
|
|
332
311
|
return { outputDir }
|
|
@@ -334,7 +313,7 @@ function loadConfig (files, outputDir) {
|
|
|
334
313
|
}
|
|
335
314
|
|
|
336
315
|
function classifyFile (file, config) {
|
|
337
|
-
if (config.
|
|
316
|
+
if (config.isStaticFile && config.isStaticFile(file.path)) {
|
|
338
317
|
file.type = 'static'
|
|
339
318
|
file.out = resolveOut(file, '')
|
|
340
319
|
} else if (file.isDot()) {
|
|
@@ -345,10 +324,6 @@ function classifyFile (file, config) {
|
|
|
345
324
|
return file
|
|
346
325
|
}
|
|
347
326
|
|
|
348
|
-
function isStaticFile (file, staticFiles) {
|
|
349
|
-
return minimatchAll(file.path, staticFiles)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
327
|
function resolveType (file) {
|
|
353
328
|
const firstPathSegment = file.path.split('/', 1)[0]
|
|
354
329
|
if (firstPathSegment === 'layouts') return 'layout'
|
|
@@ -364,4 +339,52 @@ function resolveOut (file, outputDir = '_') {
|
|
|
364
339
|
return { dirname, basename, path: path.join(dirname, basename) }
|
|
365
340
|
}
|
|
366
341
|
|
|
342
|
+
function srcFs (cwd) {
|
|
343
|
+
return new Promise((resolve, reject, cache = {}, files = new Map()) =>
|
|
344
|
+
pipeline(
|
|
345
|
+
globStream(UI_SRC_GLOB, Object.assign({ cache, cwd }, UI_SRC_OPTS)),
|
|
346
|
+
map(({ path: abspathPosix }, _, next) => {
|
|
347
|
+
const abspath = posixify ? ospath.normalize(abspathPosix) : abspathPosix
|
|
348
|
+
const relpath = abspath.substr(cwd.length + 1)
|
|
349
|
+
symlinkAwareStat(abspath).then(
|
|
350
|
+
(stat) => {
|
|
351
|
+
if (stat.isDirectory()) return next()
|
|
352
|
+
fsp.readFile(abspath).then(
|
|
353
|
+
(contents) => {
|
|
354
|
+
const path_ = posixify ? posixify(relpath) : relpath
|
|
355
|
+
files.set(path_, new File({ cwd, path: path_, contents, stat, local: true }))
|
|
356
|
+
next()
|
|
357
|
+
},
|
|
358
|
+
(readErr) => {
|
|
359
|
+
next(Object.assign(readErr, { message: readErr.message.replace(`'${abspath}'`, relpath) }))
|
|
360
|
+
}
|
|
361
|
+
)
|
|
362
|
+
},
|
|
363
|
+
(statErr) => {
|
|
364
|
+
if (statErr.symlink) {
|
|
365
|
+
statErr.message =
|
|
366
|
+
statErr.code === 'ELOOP'
|
|
367
|
+
? `Symbolic link cycle detected at ${relpath}`
|
|
368
|
+
: `Broken symbolic link detected at ${relpath}`
|
|
369
|
+
} else {
|
|
370
|
+
statErr.message = statErr.message.replace(`'${abspath}'`, relpath)
|
|
371
|
+
}
|
|
372
|
+
next(statErr)
|
|
373
|
+
}
|
|
374
|
+
)
|
|
375
|
+
}),
|
|
376
|
+
(err) => (err ? reject(err) : resolve(files))
|
|
377
|
+
)
|
|
378
|
+
)
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
function symlinkAwareStat (path_) {
|
|
382
|
+
return fsp.lstat(path_).then((lstat) => {
|
|
383
|
+
if (!lstat.isSymbolicLink()) return lstat
|
|
384
|
+
return fsp.stat(path_).catch((statErr) => {
|
|
385
|
+
throw Object.assign(statErr, { symlink: true })
|
|
386
|
+
})
|
|
387
|
+
})
|
|
388
|
+
}
|
|
389
|
+
|
|
367
390
|
module.exports = loadUi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/ui-loader",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.3",
|
|
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)",
|
|
@@ -18,17 +18,17 @@
|
|
|
18
18
|
"main": "lib/index.js",
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@antora/expand-path-helper": "~2.0",
|
|
21
|
+
"braces": "~3.0",
|
|
21
22
|
"cache-directory": "~2.0",
|
|
22
23
|
"camelcase-keys": "~7.0",
|
|
23
24
|
"gulp-vinyl-zip": "~2.5",
|
|
24
25
|
"hpagent": "~0.1.0",
|
|
25
26
|
"js-yaml": "~4.1",
|
|
26
|
-
"
|
|
27
|
+
"picomatch": "~2.3",
|
|
27
28
|
"should-proxy": "~1.0",
|
|
28
29
|
"simple-concat": "~1.0",
|
|
29
30
|
"simple-get": "~4.0",
|
|
30
|
-
"vinyl": "~2.2"
|
|
31
|
-
"vinyl-fs": "~3.0"
|
|
31
|
+
"vinyl": "~2.2"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=12.21.0"
|
|
@@ -45,5 +45,5 @@
|
|
|
45
45
|
"static site",
|
|
46
46
|
"web publishing"
|
|
47
47
|
],
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "45da95a2e2dea538379d2d9f42013d2208fb86c3"
|
|
49
49
|
}
|