-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathtransform.js
127 lines (104 loc) · 3.31 KB
/
transform.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const crypto = require('crypto')
const fs = require('fs-extra')
const path = require('path')
const mime = require('mime')
const baseEncodeTables = {
26: 'abcdefghijklmnopqrstuvwxyz',
32: '123456789abcdefghjkmnpqrstuvwxyz', // no 0lio
36: '0123456789abcdefghijklmnopqrstuvwxyz',
49: 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', // no lIO
52: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
58: '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ', // no 0lIO
62: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
64: '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_'
}
function encodeBufferToBase (buffer, base) {
const encodeTable = baseEncodeTables[base]
if (!encodeTable) throw new Error('Unknown encoding base' + base)
const readLength = buffer.length
const Big = require('big.js')
Big.RM = Big.DP = 0
let b = new Big(0)
for (let i = readLength - 1; i >= 0; i--) {
b = b.times(256).plus(buffer[i])
}
let output = ''
while (b.gt(0)) {
output = encodeTable[b.mod(base)] + output
b = b.div(base)
}
Big.DP = 20
Big.RM = 1
return output
}
function hash (contents, hashName, digestType, maxLength) {
hashName = hashName || 'md5'
maxLength = maxLength || 128
const hasher = crypto.createHash(hashName).update(contents)
if (
digestType === 'base26' ||
digestType === 'base32' ||
digestType === 'base36' ||
digestType === 'base49' ||
digestType === 'base52' ||
digestType === 'base58' ||
digestType === 'base62' ||
digestType === 'base64'
) {
return encodeBufferToBase(hasher.digest(), digestType.substr(4)).substr(
0,
maxLength
)
} else {
return hasher.digest(digestType || 'hex').substr(0, maxLength)
}
}
function transform (rootPath, filePath, opts) {
let url = opts.name
let ext = 'bin'
let basename = 'file'
let directory = ''
const outputPath = opts.outputPath
const publicPath = opts.publicPath.replace(/\/$/, '')
const context =
opts.context[0] === '/' ? opts.context.substr(1) : opts.context
const limit = opts.limit
const contextPath = path.resolve(rootPath, context)
if (!fs.existsSync(filePath)) {
throw new Error('File does not exist')
}
const parsed = path.parse(filePath)
if (parsed.ext) {
ext = parsed.ext.substr(1)
}
let basePath
if (parsed.dir) {
basename = parsed.name
basePath = parsed.dir + path.sep
}
directory = path
.relative(contextPath, basePath + '_')
.replace(/\\/g, '/')
.replace(/\.\.(\/)?/g, '_$1')
directory = directory.substr(0, directory.length - 1)
url = url
.replace(/\[ext\]/gi, () => ext)
.replace(/\[name\]/gi, () => basename)
.replace(/\[path\]/gi, () => directory)
const contents = fs.readFileSync(filePath)
if (contents.length < limit) {
const src = Buffer.from(contents)
const mimetype = mime.getType(filePath) || ''
return `data:${mimetype};base64,${src.toString('base64')}`
}
url = url.replace(
/\[(?:([^:]+):)?hash(?::([a-z]+\d*))?(?::(\d+))?\]/gi,
(_, hashType, digestType, maxLength) =>
hash(contents, hashType, digestType, parseInt(maxLength, 10))
)
if (outputPath !== null) {
fs.copySync(filePath, path.join(rootPath, outputPath, url.split('?')[0]))
}
return publicPath + '/' + url
}
module.exports = transform