@antora/ui-loader 3.2.0-alpha.1 → 3.2.0-alpha.10
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 +6 -7
- package/lib/file.js +84 -11
- package/lib/load-ui.js +105 -143
- package/package.json +15 -11
package/lib/constants.js
CHANGED
|
@@ -3,14 +3,13 @@
|
|
|
3
3
|
module.exports = Object.freeze({
|
|
4
4
|
UI_CACHE_FOLDER: 'ui',
|
|
5
5
|
UI_DESC_FILENAME: 'ui.yml',
|
|
6
|
-
UI_SRC_GLOB: '
|
|
6
|
+
UI_SRC_GLOB: '**/!(*~)',
|
|
7
7
|
UI_SRC_OPTS: {
|
|
8
|
+
braceExpansion: false,
|
|
8
9
|
dot: true,
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
nounique: true,
|
|
14
|
-
strict: false,
|
|
10
|
+
ignore: ['.git'],
|
|
11
|
+
objectMode: true,
|
|
12
|
+
onlyFiles: false,
|
|
13
|
+
unique: false,
|
|
15
14
|
},
|
|
16
15
|
})
|
package/lib/file.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const {
|
|
3
|
+
const { constants: fsc } = require('node:fs')
|
|
4
|
+
const { posix: path } = require('node:path')
|
|
5
|
+
const { Readable } = require('node:stream')
|
|
5
6
|
const Vinyl = require('vinyl')
|
|
6
7
|
|
|
7
8
|
const DEFAULT_FILE_MODE = 0o100666 & ~process.umask()
|
|
9
|
+
const invariably = { true: () => true, false: () => false }
|
|
8
10
|
|
|
9
11
|
class File extends Vinyl {
|
|
10
12
|
get path () {
|
|
@@ -27,21 +29,92 @@ class File extends Vinyl {
|
|
|
27
29
|
class MemoryFile extends File {
|
|
28
30
|
constructor (file) {
|
|
29
31
|
const contents = file.contents || Buffer.alloc(0)
|
|
30
|
-
const stat =
|
|
32
|
+
const stat = {
|
|
33
|
+
mode: DEFAULT_FILE_MODE,
|
|
34
|
+
size: contents.length,
|
|
35
|
+
isDirectory: invariably.false,
|
|
36
|
+
isFile: invariably.true,
|
|
37
|
+
isSymbolicLink: invariably.false,
|
|
38
|
+
}
|
|
31
39
|
super(Object.assign({}, file, { contents, stat }))
|
|
32
40
|
}
|
|
33
41
|
}
|
|
34
42
|
|
|
35
|
-
class
|
|
36
|
-
constructor (
|
|
37
|
-
super({ objectMode: true })
|
|
38
|
-
this.
|
|
43
|
+
class ZipReadable extends Readable {
|
|
44
|
+
constructor (zipFile, options = {}) {
|
|
45
|
+
super({ objectMode: true, highWaterMark: 1 })
|
|
46
|
+
if ((this._closeable = (this._zipFile = zipFile).reader.fd != null) && !zipFile.autoClose) {
|
|
47
|
+
throw new Error('ZipReadable requires file-based ZipFile to be initialized with autoClose:true option')
|
|
48
|
+
}
|
|
49
|
+
if (!zipFile.lazyEntries) {
|
|
50
|
+
throw new Error('ZipReadable requires ZipFile to be initialized with lazyEntries:true option')
|
|
51
|
+
}
|
|
52
|
+
if ((this._startPath = options.startPath) && (this._startPath = path.join('/', this._startPath + '/')) !== '/') {
|
|
53
|
+
this._startPath = this._startPath.slice(1)
|
|
54
|
+
} else {
|
|
55
|
+
this._startPath = undefined
|
|
56
|
+
}
|
|
57
|
+
this._init()
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
_init () {
|
|
61
|
+
const zipFile = this._zipFile
|
|
62
|
+
zipFile
|
|
63
|
+
.on('entry', (entry) => {
|
|
64
|
+
const mode = this.getFileMode(entry)
|
|
65
|
+
if ((mode & fsc.S_IFMT) === fsc.S_IFDIR) return zipFile.readEntry()
|
|
66
|
+
let path_ = entry.fileName
|
|
67
|
+
if (this._startPath) {
|
|
68
|
+
if (path_.length < this._startPath.length || !path_.startsWith(this._startPath)) return zipFile.readEntry()
|
|
69
|
+
path_ = path_.slice(this._startPath.length)
|
|
70
|
+
}
|
|
71
|
+
const isLink = (mode & fsc.S_IFMT) === fsc.S_IFLNK
|
|
72
|
+
const stat = {
|
|
73
|
+
mode,
|
|
74
|
+
mtime: entry.getLastModDate(),
|
|
75
|
+
size: entry.uncompressedSize,
|
|
76
|
+
isDirectory: invariably.false,
|
|
77
|
+
isFile: invariably[!isLink],
|
|
78
|
+
isSymbolicLink: invariably[isLink],
|
|
79
|
+
}
|
|
80
|
+
const file = { path: path_, stat }
|
|
81
|
+
if (stat.size === 0) {
|
|
82
|
+
file.contents = Buffer.alloc(0)
|
|
83
|
+
this.push(new File(file))
|
|
84
|
+
} else {
|
|
85
|
+
zipFile.openReadStream(entry, (readErr, readStream) => {
|
|
86
|
+
if (readErr) {
|
|
87
|
+
zipFile.close()
|
|
88
|
+
this.emit('error', readErr)
|
|
89
|
+
return
|
|
90
|
+
}
|
|
91
|
+
if (isLink) {
|
|
92
|
+
const buffer = []
|
|
93
|
+
readStream
|
|
94
|
+
.on('data', (chunk) => buffer.push(chunk))
|
|
95
|
+
.on('error', (readStreamErr) => this.emit('error', readStreamErr))
|
|
96
|
+
.on('end', () => {
|
|
97
|
+
file.symlink = (buffer.length === 1 ? buffer[0] : Buffer.concat(buffer)).toString()
|
|
98
|
+
this.push(new File(file))
|
|
99
|
+
})
|
|
100
|
+
} else {
|
|
101
|
+
file.contents = readStream
|
|
102
|
+
this.push(new File(file))
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
.on(this._closeable ? 'close' : 'end', () => zipFile.emittedError || this.push(null))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
_read (_n) {
|
|
111
|
+
this._zipFile.readEntry()
|
|
39
112
|
}
|
|
40
113
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
114
|
+
getFileMode ({ externalFileAttributes }) {
|
|
115
|
+
const attr = externalFileAttributes >> 16 || 33188
|
|
116
|
+
return [448, 56, 7].map((mask) => attr & mask).reduce((a, b) => a + b, attr & fsc.S_IFMT)
|
|
44
117
|
}
|
|
45
118
|
}
|
|
46
119
|
|
|
47
|
-
module.exports = { File, MemoryFile,
|
|
120
|
+
module.exports = { File, MemoryFile, ZipReadable }
|
package/lib/load-ui.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const { compile: bracesToGroup } = require('braces')
|
|
4
|
-
const { createHash } = require('crypto')
|
|
4
|
+
const { createHash } = require('node:crypto')
|
|
5
5
|
const expandPath = require('@antora/expand-path-helper')
|
|
6
|
-
const { File, MemoryFile,
|
|
7
|
-
const { promises: fsp } = require('fs')
|
|
6
|
+
const { File, MemoryFile, ZipReadable } = require('./file')
|
|
7
|
+
const { promises: fsp } = require('node:fs')
|
|
8
8
|
const { concat: get } = require('simple-get')
|
|
9
9
|
const getCacheDir = require('cache-directory')
|
|
10
|
-
const globStream = require('glob
|
|
11
|
-
const
|
|
10
|
+
const { globStream } = require('fast-glob')
|
|
11
|
+
const { inspect } = require('node:util')
|
|
12
|
+
const invariably = { false: () => false, void: () => undefined }
|
|
13
|
+
const ospath = require('node:path')
|
|
12
14
|
const { posix: path } = ospath
|
|
13
15
|
const picomatch = require('picomatch')
|
|
14
16
|
const posixify = ospath.sep === '\\' ? (p) => p.replace(/\\/g, '/') : undefined
|
|
15
|
-
const { pipeline,
|
|
17
|
+
const { pipeline, PassThrough, Writable } = require('node:stream')
|
|
18
|
+
const drain = () => new Writable({ objectMode: true, write: (_chunk, _enc, next) => next() })
|
|
16
19
|
const forEach = (write, final) => new Writable({ objectMode: true, write, final })
|
|
17
|
-
const
|
|
20
|
+
const through = () => new PassThrough({ objectMode: true })
|
|
18
21
|
const UiCatalog = require('./ui-catalog')
|
|
19
22
|
const yaml = require('js-yaml')
|
|
20
|
-
const
|
|
23
|
+
const yauzl = require('yauzl')
|
|
21
24
|
|
|
22
25
|
const STATIC_FILE_MATCHER_OPTS = {
|
|
23
26
|
expandRange: (begin, end, step, opts) => bracesToGroup(opts ? `{${begin}..${end}..${step}}` : `{${begin}..${end}}`),
|
|
@@ -82,9 +85,9 @@ async function loadUi (playbook) {
|
|
|
82
85
|
return fetch && bundle.snapshot
|
|
83
86
|
? downloadBundle(bundleUrl, cachePath, createAgent(bundleUrl, playbook.network || {}))
|
|
84
87
|
: fsp.stat(cachePath).then(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
+
(stat) => new File({ path: cachePath, stat }),
|
|
89
|
+
() => downloadBundle(bundleUrl, cachePath, createAgent(bundleUrl, playbook.network || {}))
|
|
90
|
+
)
|
|
88
91
|
})
|
|
89
92
|
} else {
|
|
90
93
|
const localPath = expandPath(bundleUrl, { dot: startDir })
|
|
@@ -103,20 +106,15 @@ async function loadUi (playbook) {
|
|
|
103
106
|
new Promise((resolve, reject) =>
|
|
104
107
|
bundleFile.isDirectory()
|
|
105
108
|
? srcFs(ospath.join(bundleFile.path, bundle.startPath || '', '.')).then(resolve, reject)
|
|
106
|
-
:
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.pipe(bufferizeContents())
|
|
111
|
-
.on('error', reject)
|
|
112
|
-
.pipe(collectFiles(resolve))
|
|
109
|
+
: srcZip(bundleFile.path, { startPath: bundle.startPath })
|
|
110
|
+
.on('error', (err) => reject(Object.assign(err, { message: `not a valid zip file; ${err.message}` })))
|
|
111
|
+
.pipe(bufferizeContentsAndCollectFiles(resolve))
|
|
112
|
+
.on('error', reject)
|
|
113
113
|
).catch((err) => {
|
|
114
|
-
const
|
|
114
|
+
const msg =
|
|
115
115
|
`Failed to read UI ${bundleFile.isDirectory() ? 'directory' : 'bundle'}: ` +
|
|
116
|
-
|
|
117
|
-
)
|
|
118
|
-
errWrapper.stack += `\nCaused by: ${err.stack || 'unknown'}`
|
|
119
|
-
throw errWrapper
|
|
116
|
+
(bundleUrl === bundleFile.path ? bundleUrl : `${bundleFile.path} (resolved from url: ${bundleUrl})`)
|
|
117
|
+
throw transformError(err, msg)
|
|
120
118
|
})
|
|
121
119
|
),
|
|
122
120
|
srcSupplementalFiles(supplementalFilesSpec, startDir),
|
|
@@ -175,13 +173,12 @@ function createAgent (url, { httpProxy, httpsProxy, noProxy }) {
|
|
|
175
173
|
function downloadBundle (url, to, agent) {
|
|
176
174
|
return new Promise((resolve, reject) => {
|
|
177
175
|
get({ url, agent }, (err, response, contents) => {
|
|
178
|
-
if (err) reject(err)
|
|
176
|
+
if (err) return reject(err)
|
|
179
177
|
if (response.statusCode !== 200) {
|
|
180
178
|
const message = `Response code ${response.statusCode} (${response.statusMessage})`
|
|
181
179
|
return reject(Object.assign(new Error(message), { name: 'HTTPError' }))
|
|
182
180
|
}
|
|
183
|
-
|
|
184
|
-
.pipe(vzip.src())
|
|
181
|
+
srcZip(contents, { testOnly: true })
|
|
185
182
|
.on('error', (err) =>
|
|
186
183
|
reject(Object.assign(err, { message: `not a valid zip file; ${err.message}`, summary: 'Invalid UI bundle' }))
|
|
187
184
|
)
|
|
@@ -189,110 +186,52 @@ function downloadBundle (url, to, agent) {
|
|
|
189
186
|
fsp
|
|
190
187
|
.mkdir(ospath.dirname(to), { recursive: true })
|
|
191
188
|
.then(() => fsp.writeFile(to, contents))
|
|
192
|
-
.then(() => resolve(new File({ path: to, stat: { isDirectory:
|
|
189
|
+
.then(() => resolve(new File({ path: to, stat: { isDirectory: invariably.false } })))
|
|
193
190
|
)
|
|
194
191
|
})
|
|
195
192
|
}).catch((err) => {
|
|
196
|
-
const errWrapper =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
})
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function selectFilesStartingFrom (startPath) {
|
|
203
|
-
if (!startPath || (startPath = path.join('/', startPath + '/')) === '/') {
|
|
204
|
-
return map((file, _, next) => {
|
|
205
|
-
if (file.isNull()) {
|
|
206
|
-
next()
|
|
207
|
-
} else {
|
|
208
|
-
next(
|
|
209
|
-
null,
|
|
210
|
-
new File({ path: posixify ? posixify(file.path) : file.path, contents: file.contents, stat: file.stat })
|
|
211
|
-
)
|
|
212
|
-
}
|
|
213
|
-
})
|
|
214
|
-
} else {
|
|
215
|
-
startPath = startPath.substr(1)
|
|
216
|
-
const startPathOffset = startPath.length
|
|
217
|
-
return map((file, _, next) => {
|
|
218
|
-
if (file.isNull()) {
|
|
219
|
-
next()
|
|
220
|
-
} else {
|
|
221
|
-
const path_ = posixify ? posixify(file.path) : file.path
|
|
222
|
-
if (path_.length > startPathOffset && path_.startsWith(startPath)) {
|
|
223
|
-
next(null, new File({ path: path_.substr(startPathOffset), contents: file.contents, stat: file.stat }))
|
|
224
|
-
} else {
|
|
225
|
-
next()
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
})
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function bufferizeContents () {
|
|
233
|
-
return map((file, _, next) => {
|
|
234
|
-
// NOTE gulp-vinyl-zip automatically converts the contents of an empty file to a Buffer
|
|
235
|
-
if (file.isStream()) {
|
|
236
|
-
const buffer = []
|
|
237
|
-
pipeline(
|
|
238
|
-
file.contents,
|
|
239
|
-
forEach((chunk, _, done) => buffer.push(chunk) && done()),
|
|
240
|
-
(err) => (err ? next(err) : next(null, Object.assign(file, { contents: Buffer.concat(buffer) })))
|
|
241
|
-
)
|
|
242
|
-
} else {
|
|
243
|
-
next(null, file)
|
|
193
|
+
const errWrapper = transformError(err, `${err.summary || 'Failed to download UI bundle'}: ${url}`)
|
|
194
|
+
if (err.code === 'ECONNRESET' || (err.message || '').toLowerCase() === 'request timed out') {
|
|
195
|
+
Object.defineProperty(errWrapper, 'recoverable', { value: true })
|
|
244
196
|
}
|
|
197
|
+
throw errWrapper
|
|
245
198
|
})
|
|
246
199
|
}
|
|
247
200
|
|
|
248
|
-
function collectFiles (resolve, files = new Map()) {
|
|
249
|
-
return forEach(
|
|
250
|
-
(file, _, done) => {
|
|
251
|
-
files.set(file.path, file)
|
|
252
|
-
done()
|
|
253
|
-
},
|
|
254
|
-
(done) => done() || resolve(files)
|
|
255
|
-
)
|
|
256
|
-
}
|
|
257
|
-
|
|
258
201
|
function srcSupplementalFiles (filesSpec, startDir) {
|
|
259
202
|
if (!filesSpec) return new Map()
|
|
260
203
|
let cwd
|
|
261
204
|
return (
|
|
262
205
|
Array.isArray(filesSpec)
|
|
263
206
|
? Promise.all(
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
207
|
+
filesSpec.reduce((accum, { path: path_, contents: contents_ }) => {
|
|
208
|
+
if (!path_) return accum
|
|
209
|
+
if (contents_) {
|
|
210
|
+
if (~contents_.indexOf('\n') || !EXT_RX.test(contents_)) {
|
|
211
|
+
accum.push(new MemoryFile({ path: path_, contents: Buffer.from(contents_) }))
|
|
212
|
+
} else {
|
|
213
|
+
contents_ = expandPath(contents_, { dot: startDir })
|
|
214
|
+
accum.push(
|
|
215
|
+
fsp
|
|
216
|
+
.stat(contents_)
|
|
217
|
+
.then((stat) =>
|
|
218
|
+
fsp.readFile(contents_).then((contents) => new File({ path: path_, contents, stat }))
|
|
219
|
+
)
|
|
220
|
+
)
|
|
221
|
+
}
|
|
270
222
|
} else {
|
|
271
|
-
|
|
272
|
-
accum.push(
|
|
273
|
-
fsp
|
|
274
|
-
.stat(contents_)
|
|
275
|
-
.then((stat) =>
|
|
276
|
-
fsp.readFile(contents_).then((contents) => new File({ path: path_, contents, stat }))
|
|
277
|
-
)
|
|
278
|
-
)
|
|
223
|
+
accum.push(new MemoryFile({ path: path_ }))
|
|
279
224
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return accum
|
|
284
|
-
}, [])
|
|
285
|
-
).then((files) => files.reduce((accum, file) => accum.set(file.path, file) && accum, new Map()))
|
|
225
|
+
return accum
|
|
226
|
+
}, [])
|
|
227
|
+
).then((files) => files.reduce((accum, file) => accum.set(file.path, file) && accum, new Map()))
|
|
286
228
|
: fsp.access((cwd = expandPath(filesSpec, { dot: startDir }))).then(() => srcFs(cwd))
|
|
287
229
|
).catch((err) => {
|
|
288
230
|
const dir = cwd ? filesSpec + (filesSpec === cwd ? '' : ` (resolved to ${cwd})`) : undefined
|
|
289
231
|
if (err.code === 'ENOENT' && err.path === cwd) {
|
|
290
232
|
throw new Error(`Specified ui.supplemental_files directory does not exist: ${dir}`)
|
|
291
|
-
} else {
|
|
292
|
-
const errWrapper = new Error(`Failed to read ui.supplemental_files ${cwd ? `directory: ${dir}` : 'entry'}`)
|
|
293
|
-
errWrapper.stack += `\nCaused by: ${err.stack || 'unknown'}`
|
|
294
|
-
throw errWrapper
|
|
295
233
|
}
|
|
234
|
+
throw transformError(err, `Failed to read ui.supplemental_files ${cwd ? `directory: ${dir}` : 'entry'}`)
|
|
296
235
|
})
|
|
297
236
|
}
|
|
298
237
|
|
|
@@ -307,12 +246,11 @@ function loadConfig (files, outputDir) {
|
|
|
307
246
|
files.delete(UI_DESC_FILENAME)
|
|
308
247
|
const config = camelCaseKeys(yaml.load(configFile.contents.toString()))
|
|
309
248
|
const staticFiles = config.staticFiles
|
|
310
|
-
if (staticFiles
|
|
249
|
+
if (staticFiles?.length) config.isStaticFile = picomatch(staticFiles, STATIC_FILE_MATCHER_OPTS)
|
|
311
250
|
if (outputDir !== undefined) config.outputDir = outputDir
|
|
312
251
|
return config
|
|
313
|
-
} else {
|
|
314
|
-
return { outputDir }
|
|
315
252
|
}
|
|
253
|
+
return { outputDir }
|
|
316
254
|
}
|
|
317
255
|
|
|
318
256
|
function camelCaseKeys (o) {
|
|
@@ -326,7 +264,7 @@ function camelCaseKeys (o) {
|
|
|
326
264
|
}
|
|
327
265
|
|
|
328
266
|
function classifyFile (file, config) {
|
|
329
|
-
if (config.isStaticFile && config.isStaticFile(file.path)) {
|
|
267
|
+
if (typeof config.isStaticFile === 'function' && config.isStaticFile(file.path)) {
|
|
330
268
|
file.type = 'static'
|
|
331
269
|
file.out = resolveOut(file, '')
|
|
332
270
|
} else if (file.isDot()) {
|
|
@@ -353,17 +291,15 @@ function resolveOut (file, outputDir = '_') {
|
|
|
353
291
|
}
|
|
354
292
|
|
|
355
293
|
function srcFs (cwd) {
|
|
356
|
-
return new Promise((resolve, reject,
|
|
294
|
+
return new Promise((resolve, reject, files = new Map()) =>
|
|
357
295
|
pipeline(
|
|
358
|
-
globStream(UI_SRC_GLOB, Object.assign({
|
|
359
|
-
forEach(({ path:
|
|
360
|
-
if ((
|
|
361
|
-
const
|
|
362
|
-
const relpath =
|
|
363
|
-
|
|
296
|
+
globStream(UI_SRC_GLOB, Object.assign({ cwd }, UI_SRC_OPTS)),
|
|
297
|
+
forEach(({ path: relpath, dirent }, _, done) => {
|
|
298
|
+
if (dirent.isDirectory()) return done()
|
|
299
|
+
const relpathPosix = relpath
|
|
300
|
+
const abspath = posixify ? ospath.join(cwd, (relpath = ospath.normalize(relpath))) : cwd + '/' + relpath
|
|
301
|
+
fsp.stat(abspath).then(
|
|
364
302
|
(stat) => {
|
|
365
|
-
if (stat.isDirectory()) return done() // detects directories that slipped through cache check
|
|
366
|
-
const relpathPosix = posixify ? posixify(relpath) : relpath
|
|
367
303
|
fsp.readFile(abspath).then(
|
|
368
304
|
(contents) => {
|
|
369
305
|
files.set(relpathPosix, new File({ cwd, path: relpathPosix, contents, stat, local: true }))
|
|
@@ -374,16 +310,18 @@ function srcFs (cwd) {
|
|
|
374
310
|
}
|
|
375
311
|
)
|
|
376
312
|
},
|
|
377
|
-
(statErr) =>
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
313
|
+
(statErr) =>
|
|
314
|
+
dirent.isSymbolicLink()
|
|
315
|
+
? fsp
|
|
316
|
+
.readlink(abspath)
|
|
317
|
+
.then(
|
|
318
|
+
(symlink) =>
|
|
319
|
+
(statErr.code === 'ELOOP' ? 'ELOOP: symbolic link cycle, ' : 'ENOENT: broken symbolic link, ') +
|
|
320
|
+
`${relpath} -> ${symlink}`,
|
|
321
|
+
() => statErr.message.replace(`'${abspath}'`, relpath)
|
|
322
|
+
)
|
|
323
|
+
.then((message) => done(Object.assign(statErr, { message })))
|
|
324
|
+
: done(Object.assign(statErr, { message: statErr.message.replace(`'${abspath}'`, relpath) }))
|
|
387
325
|
)
|
|
388
326
|
}),
|
|
389
327
|
(err) => (err ? reject(err) : resolve(files))
|
|
@@ -391,18 +329,42 @@ function srcFs (cwd) {
|
|
|
391
329
|
)
|
|
392
330
|
}
|
|
393
331
|
|
|
394
|
-
function
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
.then((symlink) => {
|
|
402
|
-
throw Object.assign(statErr, { symlink })
|
|
403
|
-
})
|
|
404
|
-
)
|
|
332
|
+
function srcZip (file, options = {}) {
|
|
333
|
+
const result = options.testOnly
|
|
334
|
+
? forEach((file_, _, done) => (file_.isStream() ? pipeline(file_.contents, through(), drain(), done) : done()))
|
|
335
|
+
: through()
|
|
336
|
+
yauzl[file instanceof Buffer ? 'fromBuffer' : 'open'](file, { lazyEntries: true }, (err, zipFile) => {
|
|
337
|
+
if (err) return result.emit('error', err)
|
|
338
|
+
new ZipReadable(zipFile, options).pipe(result)
|
|
405
339
|
})
|
|
340
|
+
return result
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function bufferizeContentsAndCollectFiles (resolve, files = new Map()) {
|
|
344
|
+
return forEach(
|
|
345
|
+
(file, _, done) => {
|
|
346
|
+
if (file.isStream()) {
|
|
347
|
+
const buffer = []
|
|
348
|
+
file.contents
|
|
349
|
+
.on('data', (chunk) => buffer.push(chunk))
|
|
350
|
+
.on('end', () => {
|
|
351
|
+
file.contents = buffer.length === 1 ? buffer[0] : Buffer.concat(buffer)
|
|
352
|
+
files.set(file.path, file)
|
|
353
|
+
done()
|
|
354
|
+
})
|
|
355
|
+
} else {
|
|
356
|
+
files.set(file.path, file)
|
|
357
|
+
done()
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
(done) => done() || resolve(files)
|
|
361
|
+
)
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function transformError (err, msg) {
|
|
365
|
+
const errWrapper = new Error(msg)
|
|
366
|
+
errWrapper.stack += `\nCaused by: ${err.stack ? inspect(err).replace(/^Error \[(.+)\](?=: )/, '$1') : err}`
|
|
367
|
+
return errWrapper
|
|
406
368
|
}
|
|
407
369
|
|
|
408
370
|
module.exports = loadUi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antora/ui-loader",
|
|
3
|
-
"version": "3.2.0-alpha.
|
|
3
|
+
"version": "3.2.0-alpha.10",
|
|
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)",
|
|
@@ -11,7 +11,11 @@
|
|
|
11
11
|
"Guillaume Grossetie <g.grossetie@gmail.com>"
|
|
12
12
|
],
|
|
13
13
|
"homepage": "https://antora.org",
|
|
14
|
-
"repository":
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://gitlab.com/antora/antora.git",
|
|
17
|
+
"directory": "packages/ui-loader"
|
|
18
|
+
},
|
|
15
19
|
"bugs": {
|
|
16
20
|
"url": "https://gitlab.com/antora/antora/issues"
|
|
17
21
|
},
|
|
@@ -25,20 +29,20 @@
|
|
|
25
29
|
"#constants": "./lib/constants.js"
|
|
26
30
|
},
|
|
27
31
|
"dependencies": {
|
|
28
|
-
"@antora/expand-path-helper": "~
|
|
32
|
+
"@antora/expand-path-helper": "~3.0",
|
|
29
33
|
"braces": "~3.0",
|
|
30
34
|
"cache-directory": "~2.0",
|
|
31
|
-
"glob
|
|
32
|
-
"
|
|
33
|
-
"hpagent": "~1.1",
|
|
35
|
+
"fast-glob": "~3.3",
|
|
36
|
+
"hpagent": "~1.2",
|
|
34
37
|
"js-yaml": "~4.1",
|
|
35
|
-
"picomatch": "~
|
|
38
|
+
"picomatch": "~4.0",
|
|
36
39
|
"should-proxy": "~1.0",
|
|
37
40
|
"simple-get": "~4.0",
|
|
38
|
-
"vinyl": "~
|
|
41
|
+
"vinyl": "~3.0",
|
|
42
|
+
"yauzl": "~3.1"
|
|
39
43
|
},
|
|
40
44
|
"engines": {
|
|
41
|
-
"node": ">=
|
|
45
|
+
"node": ">=18.0.0"
|
|
42
46
|
},
|
|
43
47
|
"files": [
|
|
44
48
|
"lib/"
|
|
@@ -54,7 +58,7 @@
|
|
|
54
58
|
],
|
|
55
59
|
"scripts": {
|
|
56
60
|
"test": "_mocha",
|
|
57
|
-
"prepublishOnly": "
|
|
58
|
-
"postpublish": "
|
|
61
|
+
"prepublishOnly": "npx -y downdoc@latest --prepublish",
|
|
62
|
+
"postpublish": "npx -y downdoc@latest --postpublish"
|
|
59
63
|
}
|
|
60
64
|
}
|