template-replacement 3.3.2 → 3.4.0
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/.editorconfig +8 -0
- package/.oxfmtrc.jsonc +7 -0
- package/.oxlintrc.json +3 -0
- package/README.md +39 -9
- package/core/base.ts +54 -55
- package/core/general.ts +37 -9
- package/core/sign.ts +43 -8
- package/dispatcher/general.ts +2 -1
- package/dispatcher/sign.ts +2 -1
- package/dispatcher/workerGeneral.ts +1 -1
- package/dispatcher/workerSign.ts +1 -1
- package/dist/base-DQz39fXI.js +249 -0
- package/dist/index-oILo_kXG.js +46 -0
- package/dist/main/general.js +1373 -1401
- package/dist/main/sign.js +1559 -1573
- package/dist/replace/general.js +281 -306
- package/dist/replace/sign.js +304 -315
- package/download/index.ts +13 -13
- package/download/stream.ts +29 -28
- package/eslint.config.ts +28 -0
- package/fileSystem/db/index.ts +25 -25
- package/fileSystem/db/indexedDBCache.ts +142 -124
- package/fileSystem/index.ts +5 -8
- package/fileSystem/interface.ts +4 -5
- package/fileSystem/opfs/index.ts +40 -36
- package/helper/index.ts +144 -116
- package/index.ts +9 -17
- package/office/zip.ts +106 -97
- package/package.json +17 -11
- package/replace/base.ts +203 -214
- package/replace/general.ts +44 -19
- package/replace/image.ts +88 -86
- package/replace/interface.ts +29 -24
- package/replace/paramsData.ts +108 -96
- package/replace/sign.ts +79 -43
- package/task/urlDownloadTask.ts +54 -63
- package/temp/index.ts +139 -131
- package/temp/interface.ts +8 -8
- package/tsconfig.json +1 -1
- package/vite.config.ts +11 -14
- package/worker/child/agency.ts +49 -41
- package/worker/child/base.ts +125 -89
- package/worker/child/general.ts +2 -3
- package/worker/child/sign.ts +4 -4
- package/worker/index.ts +52 -51
- package/worker/interface.ts +9 -6
- package/worker/main/general.ts +5 -5
- package/worker/main/index.ts +191 -66
- package/worker/main/sign.ts +5 -5
- package/worker/type.ts +16 -15
- package/dist/assets/template_replacement_core_wasm_bg.wasm +0 -0
- package/dist/assets/template_replacement_sign_core_wasm_bg.wasm +0 -0
- package/dist/base-BuKBOMgk.js +0 -269
- package/dist/general.d.ts +0 -1
- package/dist/index-tFDVIkZX.js +0 -46
- package/dist/sign.d.ts +0 -1
package/helper/index.ts
CHANGED
|
@@ -2,159 +2,187 @@ import urlDownloadTask from '../task/urlDownloadTask'
|
|
|
2
2
|
import { fileTypeFromBuffer } from 'file-type'
|
|
3
3
|
|
|
4
4
|
export function urlSuffix(url: string): string {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
url = url.split('?')[0]
|
|
6
|
+
if (url.lastIndexOf('.') === -1) {
|
|
7
|
+
return ''
|
|
8
|
+
}
|
|
9
|
+
return url.substring(url.lastIndexOf('.') + 1)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export function getFileNameFromUrl(url: string): string
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
export function getFileNameFromUrl(url: string): string {
|
|
13
|
+
url = url.split('?')[0]
|
|
14
|
+
const pathParts = url.split('/')
|
|
15
|
+
return pathParts[pathParts.length - 1]
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
export const enum fileTypes
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
export const enum fileTypes {
|
|
19
|
+
word = 'word',
|
|
20
|
+
excel = 'excel',
|
|
21
|
+
unknown = 'unknown',
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export const officeMIMETypes: Record<string, fileTypes> = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
//docx
|
|
26
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': fileTypes.word,
|
|
27
|
+
//dotx
|
|
28
|
+
'application/vnd.openxmlformats-officedocument.wordprocessingml.template': fileTypes.word,
|
|
29
|
+
//xlsx
|
|
30
|
+
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': fileTypes.excel,
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export const officeSuffixTypes: Record<string, fileTypes> = {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
docx: fileTypes.word,
|
|
35
|
+
dotx: fileTypes.word,
|
|
36
|
+
xlsx: fileTypes.excel,
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export function fileType(file: File): fileTypes {
|
|
40
|
-
|
|
40
|
+
return officeMIMETypes[file.type] ?? fileTypes.unknown
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export function fileTypeByName(name: string): fileTypes {
|
|
44
|
-
|
|
44
|
+
return officeSuffixTypes[urlSuffix(name)] ?? fileTypes.unknown
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
export async function fileTypeByBuffer(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return officeMIMETypes[type.mime]
|
|
47
|
+
export async function fileTypeByBuffer(
|
|
48
|
+
buffer: Uint8Array | ArrayBuffer | Blob,
|
|
49
|
+
): Promise<fileTypes> {
|
|
50
|
+
if (buffer instanceof Blob) {
|
|
51
|
+
if (buffer.type && officeMIMETypes[buffer.type]) {
|
|
52
|
+
return officeMIMETypes[buffer.type]
|
|
54
53
|
}
|
|
55
|
-
|
|
54
|
+
buffer = await buffer.arrayBuffer()
|
|
55
|
+
}
|
|
56
|
+
const type = await fileTypeFromBuffer(buffer)
|
|
57
|
+
|
|
58
|
+
if (type && officeMIMETypes[type.mime]) {
|
|
59
|
+
return officeMIMETypes[type.mime]
|
|
60
|
+
}
|
|
61
|
+
return fileTypes.unknown
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
export function generateId(): string {
|
|
59
|
-
|
|
65
|
+
return crypto.randomUUID()
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
export type fileArrayBufferData = {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export async function filesReaderArrayBuffer(files: File[]): Promise<fileArrayBufferData[]> {
|
|
68
|
-
const awaits = []
|
|
69
|
-
for (const file of files) {
|
|
70
|
-
awaits.push(new Promise(async (resolve, reject) => {
|
|
71
|
-
try {
|
|
72
|
-
resolve({
|
|
73
|
-
name: file.name,
|
|
74
|
-
buffer: await file.arrayBuffer()
|
|
75
|
-
} as fileArrayBufferData)
|
|
76
|
-
} catch (error) {
|
|
77
|
-
reject(error)
|
|
78
|
-
}
|
|
79
|
-
}))
|
|
80
|
-
}
|
|
81
|
-
return (await Promise.all(awaits)) as fileArrayBufferData[]
|
|
69
|
+
name: string
|
|
70
|
+
buffer: ArrayBuffer
|
|
82
71
|
}
|
|
83
72
|
|
|
73
|
+
export function filesReaderArrayBuffer(
|
|
74
|
+
files: File[],
|
|
75
|
+
): Promise<fileArrayBufferData[]> {
|
|
76
|
+
const awaits: Promise<fileArrayBufferData>[] = []
|
|
77
|
+
for (const file of files) {
|
|
78
|
+
awaits.push(
|
|
79
|
+
new Promise((resolve, reject) => {
|
|
80
|
+
try {
|
|
81
|
+
file
|
|
82
|
+
.arrayBuffer()
|
|
83
|
+
.then((buffer) => {
|
|
84
|
+
resolve({
|
|
85
|
+
name: file.name,
|
|
86
|
+
buffer,
|
|
87
|
+
})
|
|
88
|
+
})
|
|
89
|
+
.catch(reject)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
reject(error)
|
|
92
|
+
}
|
|
93
|
+
}),
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
return Promise.all(awaits)
|
|
97
|
+
}
|
|
84
98
|
|
|
85
99
|
export type fileBase64Data = {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export async function filesReaderBase64(files: File[]): Promise<fileBase64Data[]> {
|
|
91
|
-
const awaits = []
|
|
92
|
-
for (const file of files) {
|
|
93
|
-
awaits.push(new Promise((resolve, reject) => {
|
|
94
|
-
const fileReader = new FileReader()
|
|
95
|
-
fileReader.onload = function(e) {
|
|
96
|
-
let base64 = e.target?.result as string
|
|
97
|
-
if (!base64) {
|
|
98
|
-
resolve({
|
|
99
|
-
name: file.name,
|
|
100
|
-
base64: ''
|
|
101
|
-
})
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
const index = base64.indexOf(",")
|
|
105
|
-
if (index != -1) {
|
|
106
|
-
base64 = base64.slice(index + 1)
|
|
107
|
-
}
|
|
108
|
-
resolve({
|
|
109
|
-
name: file.name,
|
|
110
|
-
base64: base64
|
|
111
|
-
})
|
|
112
|
-
}
|
|
113
|
-
fileReader.onerror = function (e) {
|
|
114
|
-
reject(e)
|
|
115
|
-
}
|
|
116
|
-
fileReader.readAsDataURL(file)
|
|
117
|
-
}))
|
|
118
|
-
}
|
|
119
|
-
return await Promise.all(awaits) as fileBase64Data[]
|
|
100
|
+
name: string
|
|
101
|
+
base64: string
|
|
120
102
|
}
|
|
121
103
|
|
|
122
|
-
export function
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
104
|
+
export function filesReaderBase64(files: File[]): Promise<fileBase64Data[]> {
|
|
105
|
+
const awaits: Promise<fileBase64Data>[] = []
|
|
106
|
+
for (const file of files) {
|
|
107
|
+
awaits.push(
|
|
108
|
+
new Promise((resolve, reject) => {
|
|
109
|
+
const fileReader = new FileReader()
|
|
110
|
+
fileReader.onload = function (e) {
|
|
111
|
+
let base64 = e.target?.result as string
|
|
112
|
+
if (!base64) {
|
|
113
|
+
resolve({
|
|
114
|
+
name: file.name,
|
|
115
|
+
base64: '',
|
|
116
|
+
})
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
const index = base64.indexOf(',')
|
|
120
|
+
if (index != -1) {
|
|
121
|
+
base64 = base64.slice(index + 1)
|
|
122
|
+
}
|
|
123
|
+
resolve({
|
|
124
|
+
name: file.name,
|
|
125
|
+
base64: base64,
|
|
126
|
+
})
|
|
130
127
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
128
|
+
fileReader.onerror = function (e) {
|
|
129
|
+
reject(e)
|
|
130
|
+
}
|
|
131
|
+
fileReader.readAsDataURL(file)
|
|
132
|
+
}),
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
return Promise.all(awaits)
|
|
136
|
+
}
|
|
135
137
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
export function base64ToBlob(base64: string): Blob {
|
|
139
|
+
const arr = base64.split(',')
|
|
140
|
+
let mime
|
|
141
|
+
if (arr.length > 1) {
|
|
142
|
+
const m: RegExpMatchArray | null = arr[0].match(/:(.*?);/)
|
|
143
|
+
if (m?.length) {
|
|
144
|
+
mime = m[1]
|
|
145
|
+
base64 = arr[1]
|
|
140
146
|
}
|
|
141
|
-
|
|
147
|
+
}
|
|
148
|
+
if (!mime) {
|
|
149
|
+
mime = 'application/octet-stream'
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const byteCharacters = atob(base64)
|
|
153
|
+
const byteArray = new Uint8Array(byteCharacters.length)
|
|
154
|
+
for (let i = 0; i < byteCharacters.length; i++) {
|
|
155
|
+
byteArray[i] = byteCharacters.charCodeAt(i)
|
|
156
|
+
}
|
|
157
|
+
return new Blob([byteArray], { type: mime })
|
|
142
158
|
}
|
|
143
159
|
|
|
144
160
|
//urls提取为文件二进制数据
|
|
145
|
-
export
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
export function urlsToFileBlobs(
|
|
162
|
+
urls: string[],
|
|
163
|
+
onDownloadProgress?: (progressEvent: unknown) => void,
|
|
164
|
+
): Promise<(Blob | undefined)[]> {
|
|
165
|
+
const task = new urlDownloadTask(urls)
|
|
166
|
+
if (onDownloadProgress) {
|
|
167
|
+
task.onDownloadProgress(onDownloadProgress)
|
|
168
|
+
}
|
|
169
|
+
return task.start()
|
|
151
170
|
}
|
|
152
171
|
|
|
153
172
|
export function splitArrayIntoChunks<T>(array: T[], chunkSize: number): T[][] {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
173
|
+
const result: T[][] = []
|
|
174
|
+
for (let i = 0; i < array.length; i += chunkSize) {
|
|
175
|
+
const chunk = array.slice(i, i + chunkSize)
|
|
176
|
+
result.push(chunk)
|
|
177
|
+
}
|
|
178
|
+
return result
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 字符串SHA-1哈希值
|
|
182
|
+
export async function hashString(str: string): Promise<string> {
|
|
183
|
+
const encoder = new TextEncoder()
|
|
184
|
+
const data = encoder.encode(str)
|
|
185
|
+
const hashBuffer = await window.crypto.subtle.digest('SHA-1', data)
|
|
186
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer))
|
|
187
|
+
return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('')
|
|
188
|
+
}
|
package/index.ts
CHANGED
|
@@ -4,23 +4,15 @@ import workerGeneral from './dispatcher/workerGeneral'
|
|
|
4
4
|
import workerSign from './dispatcher/workerSign'
|
|
5
5
|
import ReplaceInterface from './replace/interface'
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
return general()
|
|
9
|
-
}
|
|
7
|
+
export const General = general
|
|
10
8
|
|
|
11
|
-
export
|
|
12
|
-
return sign()
|
|
13
|
-
}
|
|
9
|
+
export const Sign = sign
|
|
14
10
|
|
|
15
|
-
export
|
|
16
|
-
return workerGeneral(concurrency)
|
|
17
|
-
}
|
|
11
|
+
export const WorkerGeneral = workerGeneral
|
|
18
12
|
|
|
19
|
-
export
|
|
20
|
-
return workerSign(concurrency)
|
|
21
|
-
}
|
|
13
|
+
export const WorkerSign = workerSign
|
|
22
14
|
|
|
23
|
-
type signFun = (data:
|
|
15
|
+
type signFun = (data: unknown) => Promise<string>
|
|
24
16
|
|
|
25
17
|
export default (concurrency?: number, signFn?: signFun): ReplaceInterface => {
|
|
26
18
|
let res = undefined
|
|
@@ -28,16 +20,16 @@ export default (concurrency?: number, signFn?: signFun): ReplaceInterface => {
|
|
|
28
20
|
if (signFn) {
|
|
29
21
|
res = workerSign(concurrency)
|
|
30
22
|
res.sign = signFn
|
|
31
|
-
}else{
|
|
23
|
+
} else {
|
|
32
24
|
res = workerGeneral(concurrency)
|
|
33
25
|
}
|
|
34
|
-
}else {
|
|
26
|
+
} else {
|
|
35
27
|
if (signFn) {
|
|
36
28
|
res = sign()
|
|
37
29
|
res.sign = signFn
|
|
38
|
-
}else{
|
|
30
|
+
} else {
|
|
39
31
|
res = general()
|
|
40
32
|
}
|
|
41
33
|
}
|
|
42
34
|
return res
|
|
43
|
-
}
|
|
35
|
+
}
|
package/office/zip.ts
CHANGED
|
@@ -1,116 +1,125 @@
|
|
|
1
1
|
import { stream } from '../download'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
FlateError,
|
|
4
|
+
unzip,
|
|
5
|
+
Unzipped,
|
|
6
|
+
zip,
|
|
7
|
+
strToU8,
|
|
8
|
+
AsyncZipOptions,
|
|
9
|
+
Zip as fflateZip,
|
|
10
|
+
ZipDeflate,
|
|
11
|
+
} from 'fflate'
|
|
3
12
|
|
|
4
|
-
type InputType = string|Uint8Array|ArrayBuffer|Blob
|
|
13
|
+
type InputType = string | Uint8Array | ArrayBuffer | Blob
|
|
5
14
|
|
|
6
15
|
export default class Zip {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
16
|
+
name: string = ''
|
|
17
|
+
fileBlob?: Blob
|
|
18
|
+
private _unzipData?: Unzipped
|
|
19
|
+
private _lastUpdateTime: number = 0
|
|
11
20
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
this.name = (file as File)?.name ?? ''
|
|
17
|
-
this.fileBlob = file
|
|
21
|
+
constructor(file?: Blob) {
|
|
22
|
+
if (!file) {
|
|
23
|
+
return
|
|
18
24
|
}
|
|
25
|
+
this.name = (file as File)?.name ?? ''
|
|
26
|
+
this.fileBlob = file
|
|
27
|
+
}
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
29
|
+
getFileBlob(): Blob | undefined {
|
|
30
|
+
return this.fileBlob
|
|
31
|
+
}
|
|
23
32
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
} catch (e) {
|
|
40
|
-
console.warn(e)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
if (!this._unzipData) {
|
|
44
|
-
this._unzipData = {}
|
|
33
|
+
async fileZip(): Promise<Unzipped> {
|
|
34
|
+
if (!this._unzipData) {
|
|
35
|
+
try {
|
|
36
|
+
const blob = this.getFileBlob()
|
|
37
|
+
if (blob) {
|
|
38
|
+
const arrayBuffer = await blob.arrayBuffer()
|
|
39
|
+
this._unzipData = await new Promise((resolve, reject) => {
|
|
40
|
+
unzip(
|
|
41
|
+
new Uint8Array(arrayBuffer),
|
|
42
|
+
(err: FlateError | null, data: Unzipped) => {
|
|
43
|
+
resolve(data)
|
|
44
|
+
},
|
|
45
|
+
)
|
|
46
|
+
})
|
|
45
47
|
}
|
|
46
|
-
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.warn(e)
|
|
50
|
+
}
|
|
47
51
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const fileZip = await this.fileZip()
|
|
51
|
-
switch (true) {
|
|
52
|
-
case data instanceof Blob:
|
|
53
|
-
data = new Uint8Array(await data.arrayBuffer())
|
|
54
|
-
break
|
|
55
|
-
case data instanceof Uint8Array:
|
|
56
|
-
break
|
|
57
|
-
case data instanceof ArrayBuffer:
|
|
58
|
-
data = new Uint8Array(data)
|
|
59
|
-
break
|
|
60
|
-
case data instanceof String:
|
|
61
|
-
data = strToU8(data as string)
|
|
62
|
-
break
|
|
63
|
-
default:
|
|
64
|
-
throw new Error('Invalid data type')
|
|
65
|
-
}
|
|
66
|
-
fileZip[path] = data as Uint8Array
|
|
67
|
-
this._lastUpdateTime = (new Date()).getTime()
|
|
52
|
+
if (!this._unzipData) {
|
|
53
|
+
this._unzipData = {}
|
|
68
54
|
}
|
|
55
|
+
return this._unzipData
|
|
56
|
+
}
|
|
69
57
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
58
|
+
async setZipData(path: string, data: InputType): Promise<void> {
|
|
59
|
+
const fileZip = await this.fileZip()
|
|
60
|
+
switch (true) {
|
|
61
|
+
case data instanceof Blob:
|
|
62
|
+
data = new Uint8Array(await data.arrayBuffer())
|
|
63
|
+
break
|
|
64
|
+
case data instanceof Uint8Array:
|
|
65
|
+
break
|
|
66
|
+
case data instanceof ArrayBuffer:
|
|
67
|
+
data = new Uint8Array(data)
|
|
68
|
+
break
|
|
69
|
+
case data instanceof String:
|
|
70
|
+
data = strToU8(data as string)
|
|
71
|
+
break
|
|
72
|
+
default:
|
|
73
|
+
throw new Error('Invalid data type')
|
|
83
74
|
}
|
|
75
|
+
fileZip[path] = data as Uint8Array
|
|
76
|
+
this._lastUpdateTime = new Date().getTime()
|
|
77
|
+
}
|
|
84
78
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
async generate(options: AsyncZipOptions): Promise<Blob | undefined> {
|
|
80
|
+
const data = await this.fileZip()
|
|
81
|
+
if (!Object.keys(data).length) {
|
|
82
|
+
return undefined
|
|
83
|
+
}
|
|
84
|
+
return await new Promise((resolve, reject) => {
|
|
85
|
+
zip(data, options, (err: FlateError | null, data: Uint8Array) => {
|
|
86
|
+
if (err) {
|
|
87
|
+
return reject(err)
|
|
89
88
|
}
|
|
89
|
+
resolve(new Blob([data as BlobPart]))
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
}
|
|
90
93
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
async download(fileName: string): Promise<void> {
|
|
95
|
+
const data = await this.fileZip()
|
|
96
|
+
if (!Object.keys(data).length) {
|
|
97
|
+
return
|
|
98
|
+
}
|
|
94
99
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
downloadStream.abort(err)
|
|
99
|
-
return
|
|
100
|
-
}
|
|
101
|
-
downloadStream.write(dat)
|
|
102
|
-
if (final) {
|
|
103
|
-
downloadStream.close()
|
|
104
|
-
}
|
|
105
|
-
})
|
|
100
|
+
if (fileName == undefined) {
|
|
101
|
+
fileName = this.name
|
|
102
|
+
}
|
|
106
103
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
const downloadStream = stream(fileName)
|
|
105
|
+
const zip = new fflateZip((err, dat, final) => {
|
|
106
|
+
if (err) {
|
|
107
|
+
downloadStream.abort(err)
|
|
108
|
+
return
|
|
109
|
+
}
|
|
110
|
+
downloadStream.write(dat)
|
|
111
|
+
if (final) {
|
|
112
|
+
downloadStream.close()
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
for (const key in data) {
|
|
117
|
+
const deflate = new ZipDeflate(key, {
|
|
118
|
+
level: 9,
|
|
119
|
+
})
|
|
120
|
+
zip.add(deflate)
|
|
121
|
+
deflate.push(data[key], true)
|
|
115
122
|
}
|
|
116
|
-
|
|
123
|
+
zip.end()
|
|
124
|
+
}
|
|
125
|
+
}
|
package/package.json
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "template-replacement",
|
|
3
3
|
"description": "模板文件替换",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.4.0",
|
|
5
5
|
"author": "fushiliang <994301536@qq.com>",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "index.ts",
|
|
8
8
|
"license": "Apache 2.0",
|
|
9
9
|
"scripts": {
|
|
10
|
-
"build": "
|
|
10
|
+
"build": "vite build --config vite.config.ts",
|
|
11
|
+
"lint": "npx oxlint && npx eslint"
|
|
11
12
|
},
|
|
12
13
|
"dependencies": {
|
|
13
|
-
"
|
|
14
|
-
"axios": "^1.13.1",
|
|
14
|
+
"axios": "^1.13.2",
|
|
15
15
|
"fflate": "^0.8.2",
|
|
16
16
|
"file-type": "^19.6.0",
|
|
17
17
|
"streamsaver": "^2.0.6",
|
|
18
|
-
"template-replacement-core-wasm": "^1.
|
|
19
|
-
"template-replacement-sign-core-wasm": "^1.
|
|
20
|
-
"vite-plugin-wasm-pack": "^0.1.12"
|
|
18
|
+
"template-replacement-core-wasm": "^1.7.2",
|
|
19
|
+
"template-replacement-sign-core-wasm": "^1.7.2"
|
|
21
20
|
},
|
|
22
21
|
"devDependencies": {
|
|
23
|
-
"
|
|
22
|
+
"@rollup/pluginutils": "^5.3.0",
|
|
23
|
+
"@types/streamsaver": "^2.0.5",
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
25
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
26
|
+
"eslint": "^9.39.2",
|
|
27
|
+
"eslint-plugin-oxlint": "^1.33.0",
|
|
28
|
+
"oxfmt": "^0.16.0",
|
|
29
|
+
"oxlint": "^1.33.0",
|
|
30
|
+
"terser": "^5.44.1",
|
|
24
31
|
"typescript": "^5.9.3",
|
|
25
|
-
"vite": "^7.
|
|
26
|
-
"vite-plugin-dts": "^4.5.4"
|
|
32
|
+
"vite": "^7.3.0"
|
|
27
33
|
},
|
|
28
34
|
"keywords": [
|
|
29
35
|
"template-replacement"
|
|
30
36
|
]
|
|
31
|
-
}
|
|
37
|
+
}
|