template-replacement 3.0.8

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.
Files changed (47) hide show
  1. package/.workflow/publish_to_npmjs.yml +26 -0
  2. package/core/base.ts +54 -0
  3. package/core/general.ts +13 -0
  4. package/core/sign.ts +13 -0
  5. package/db/index.ts +5 -0
  6. package/db/indexedDBCache.ts +129 -0
  7. package/dispatcher/general.ts +6 -0
  8. package/dispatcher/sign.ts +6 -0
  9. package/dispatcher/workerGeneral.ts +7 -0
  10. package/dispatcher/workerSign.ts +7 -0
  11. package/dist/assets/template_replacement_core_wasm_bg.wasm +0 -0
  12. package/dist/assets/template_replacement_sign_core_wasm_bg.wasm +0 -0
  13. package/dist/base-CC-6cmrq.js +189 -0
  14. package/dist/general.d.ts +1 -0
  15. package/dist/index-BkwrGCka.js +61 -0
  16. package/dist/main/general.js +4543 -0
  17. package/dist/main/sign.js +4566 -0
  18. package/dist/replace/general.js +424 -0
  19. package/dist/replace/sign.js +428 -0
  20. package/dist/sign.d.ts +1 -0
  21. package/download/index.ts +22 -0
  22. package/download/stream.ts +38 -0
  23. package/helper/index.ts +162 -0
  24. package/index.ts +21 -0
  25. package/office/zip.ts +116 -0
  26. package/package.json +33 -0
  27. package/replace/base.ts +124 -0
  28. package/replace/general.ts +14 -0
  29. package/replace/image.ts +116 -0
  30. package/replace/interface.ts +29 -0
  31. package/replace/paramsData.ts +117 -0
  32. package/replace/sign.ts +31 -0
  33. package/task/urlDownloadTask.ts +67 -0
  34. package/temp/index.ts +157 -0
  35. package/temp/interface.ts +18 -0
  36. package/tsconfig.json +108 -0
  37. package/vite.config.ts +36 -0
  38. package/worker/child/agency.ts +78 -0
  39. package/worker/child/base.ts +89 -0
  40. package/worker/child/general.ts +5 -0
  41. package/worker/child/sign.ts +9 -0
  42. package/worker/index.ts +65 -0
  43. package/worker/interface.ts +11 -0
  44. package/worker/main/general.ts +8 -0
  45. package/worker/main/index.ts +176 -0
  46. package/worker/main/sign.ts +8 -0
  47. package/worker/type.ts +24 -0
package/dist/sign.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,22 @@
1
+ import streamClass from "./stream"
2
+
3
+ function download(fileName: string, blob: Blob): void {
4
+ const href = window.URL.createObjectURL(blob)
5
+ const a = document.createElement('a')
6
+ a.href = href
7
+ a.target = 'target'
8
+ a.download = fileName
9
+ document.body.appendChild(a)
10
+ a.click();
11
+ document.body.removeChild(a)
12
+ window.URL.revokeObjectURL(href)
13
+ }
14
+
15
+ export default (fileName: string, blob: Blob): void => {
16
+ download(fileName, blob)
17
+ }
18
+
19
+ //流式下载
20
+ export function stream(fileName: string, size?: number): streamClass {
21
+ return new streamClass(fileName, size)
22
+ }
@@ -0,0 +1,38 @@
1
+ import streamSaver from "streamsaver"
2
+
3
+ export function setMitm(mitm: string) {
4
+ streamSaver.mitm = mitm
5
+ }
6
+
7
+ export default class Stream {
8
+ tasks: Promise<any>[] = []
9
+ writer: WritableStreamDefaultWriter<any>
10
+ fileStream: WritableStream
11
+
12
+ constructor(fileName: string, size?: number) {
13
+ this.fileStream = streamSaver.createWriteStream(fileName, {
14
+ size
15
+ })
16
+ this.writer = this.fileStream.getWriter()
17
+ }
18
+
19
+ async write(chunk: any): Promise<void> {
20
+ const a = this.writer.write(chunk)
21
+ this.tasks.push(a)
22
+ const res = await a
23
+ return res
24
+ }
25
+
26
+ async close(): Promise<void> {
27
+ if (this.tasks.length) {
28
+ await Promise.all(this.tasks)
29
+ }
30
+ const res = await this.writer.close()
31
+ this.writer.releaseLock()
32
+ return res
33
+ }
34
+
35
+ async abort(reason?: any): Promise<void> {
36
+ return await this.fileStream.abort(reason)
37
+ }
38
+ }
@@ -0,0 +1,162 @@
1
+ import { nanoid } from 'nanoid'
2
+ import urlDownloadTask from '../task/urlDownloadTask'
3
+ import { fileTypeFromBuffer } from 'file-type'
4
+
5
+ export function urlSuffix(url: string): string {
6
+ url = url.split('?')[0]
7
+ if (url.lastIndexOf('.') === -1) {
8
+ return ''
9
+ }
10
+ return url.substring(url.lastIndexOf('.') + 1)
11
+ }
12
+
13
+ export function getFileNameFromUrl(url: string): string {
14
+ url = url.split('?')[0]
15
+ const pathParts = url.split('/')
16
+ return pathParts[pathParts.length - 1]
17
+ }
18
+
19
+ export const enum fileTypes {
20
+ word = 'word',
21
+ excel = 'excel',
22
+ unknown = 'unknown',
23
+ }
24
+
25
+ export const officeMIMETypes: Record<string, fileTypes> = {
26
+ //docx
27
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document': fileTypes.word,
28
+ //dotx
29
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template': fileTypes.word,
30
+ //xlsx
31
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': fileTypes.excel,
32
+ }
33
+
34
+ export const officeSuffixTypes: Record<string, fileTypes> = {
35
+ 'docx': fileTypes.word,
36
+ 'dotx': fileTypes.word,
37
+ 'xlsx': fileTypes.excel,
38
+ }
39
+
40
+ export function fileType(file: File): fileTypes {
41
+ return officeMIMETypes[file.type] ?? fileTypes.unknown
42
+ }
43
+
44
+ export function fileTypeByName(name: string): fileTypes {
45
+ return officeSuffixTypes[urlSuffix(name)] ?? fileTypes.unknown
46
+ }
47
+
48
+ export async function fileTypeByBuffer(buffer: Uint8Array|ArrayBuffer|Blob): Promise<fileTypes> {
49
+ if (buffer instanceof Blob) {
50
+ buffer = await buffer.arrayBuffer()
51
+ }
52
+ const type = await fileTypeFromBuffer(buffer)
53
+ if (type && officeMIMETypes[type.mime]) {
54
+ return officeMIMETypes[type.mime]
55
+ }
56
+ return fileTypes.unknown
57
+ }
58
+
59
+ export function generateId(): string {
60
+ return nanoid()
61
+ }
62
+
63
+ export type fileArrayBufferData = {
64
+ name: string
65
+ buffer: ArrayBuffer
66
+ }
67
+
68
+ export async function filesReaderArrayBuffer(files: File[]): Promise<fileArrayBufferData[]> {
69
+ const awaits = []
70
+ files.forEach
71
+ for (const file of files) {
72
+ awaits.push(new Promise(async (resolve, reject) => {
73
+ try {
74
+ resolve({
75
+ name: file.name,
76
+ buffer: await file.arrayBuffer()
77
+ } as fileArrayBufferData)
78
+ } catch (error) {
79
+ reject(error)
80
+ }
81
+ }))
82
+ }
83
+ return (await Promise.all(awaits)) as fileArrayBufferData[]
84
+ }
85
+
86
+
87
+ export type fileBase64Data = {
88
+ name: string
89
+ base64: string
90
+ }
91
+
92
+ export async function filesReaderBase64(files: File[]): Promise<fileBase64Data[]> {
93
+ const awaits = []
94
+ for (const file of files) {
95
+ awaits.push(new Promise((resolve, reject) => {
96
+ const fileReader = new FileReader()
97
+ fileReader.onload = function(e) {
98
+ let base64 = e.target?.result as string
99
+ if (!base64) {
100
+ resolve({
101
+ name: file.name,
102
+ base64: ''
103
+ })
104
+ return
105
+ }
106
+ const index = base64.indexOf(",")
107
+ if (index != -1) {
108
+ base64 = base64.slice(index + 1)
109
+ }
110
+ resolve({
111
+ name: file.name,
112
+ base64: base64
113
+ })
114
+ }
115
+ fileReader.onerror = function (e) {
116
+ reject(e)
117
+ }
118
+ fileReader.readAsDataURL(file)
119
+ }))
120
+ }
121
+ return await Promise.all(awaits) as fileBase64Data[]
122
+ }
123
+
124
+ export function base64ToBlob(base64: string): Blob {
125
+ const arr = base64.split(',')
126
+ let mime
127
+ if (arr.length > 1) {
128
+ const m: RegExpMatchArray | null = arr[0].match(/:(.*?);/)
129
+ if (m?.length) {
130
+ mime = m[1]
131
+ base64 = arr[1]
132
+ }
133
+ }
134
+ if (!mime) {
135
+ mime = 'application/octet-stream'
136
+ }
137
+
138
+ const byteCharacters = atob(base64)
139
+ const byteArray = new Uint8Array(byteCharacters.length)
140
+ for (let i = 0; i < byteCharacters.length; i++) {
141
+ byteArray[i] = byteCharacters.charCodeAt(i)
142
+ }
143
+ return new Blob([byteArray], { type: mime })
144
+ }
145
+
146
+ //urls提取为文件二进制数据
147
+ export async function urlsToFileBlobs(urls: string[], onDownloadProgress?: (progressEvent: any) => void): Promise<(Blob|undefined)[]> {
148
+ const task = new urlDownloadTask(urls)
149
+ if(onDownloadProgress) {
150
+ task.onDownloadProgress(onDownloadProgress)
151
+ }
152
+ return await task.start()
153
+ }
154
+
155
+ export function splitArrayIntoChunks<T>(array: T[], chunkSize: number): T[][] {
156
+ const result: T[][] = []
157
+ for (let i = 0; i < array.length; i += chunkSize) {
158
+ const chunk = array.slice(i, i + chunkSize)
159
+ result.push(chunk)
160
+ }
161
+ return result
162
+ }
package/index.ts ADDED
@@ -0,0 +1,21 @@
1
+ import general from './dispatcher/general'
2
+ import sign from './dispatcher/sign'
3
+ import workerGeneral from './dispatcher/workerGeneral'
4
+ import workerSign from './dispatcher/workerSign'
5
+ import ReplaceInterface from './replace/interface'
6
+
7
+ export function General(): ReplaceInterface {
8
+ return general()
9
+ }
10
+
11
+ export function Sign(): ReplaceInterface {
12
+ return sign()
13
+ }
14
+
15
+ export function WorkerGeneral(concurrency?: number): ReplaceInterface {
16
+ return workerGeneral(concurrency)
17
+ }
18
+
19
+ export function WorkerSign(concurrency?: number): ReplaceInterface {
20
+ return workerSign(concurrency)
21
+ }
package/office/zip.ts ADDED
@@ -0,0 +1,116 @@
1
+ import { stream } from '../download'
2
+ import { FlateError, unzip, Unzipped, zip, strToU8, AsyncZipOptions, Zip as fflateZip, ZipDeflate } from 'fflate'
3
+
4
+ type InputType = string|Uint8Array|ArrayBuffer|Blob
5
+
6
+ export default class Zip {
7
+ name: string = ''
8
+ fileBlob?: Blob
9
+ _unzipData?: Unzipped
10
+ _lastUpdateTime: number = 0;
11
+
12
+ constructor(file?: Blob) {
13
+ if (!file) {
14
+ return
15
+ }
16
+ this.name = (file as File)?.name ?? ''
17
+ this.fileBlob = file
18
+ }
19
+
20
+ getFileBlob(): Blob|undefined {
21
+ return this.fileBlob
22
+ }
23
+
24
+ async fileZip(): Promise<Unzipped> {
25
+ if (!this._unzipData) {
26
+ try {
27
+ const blob = this.getFileBlob()
28
+ if (blob) {
29
+ const arrayBuffer = await blob.arrayBuffer()
30
+ this._unzipData = await new Promise(async (resolve, reject) => {
31
+ unzip(new Uint8Array(arrayBuffer), (err: FlateError | null, data: Unzipped) => {
32
+ if (err) {
33
+ return reject(err)
34
+ }
35
+ resolve(data)
36
+ })
37
+ })
38
+ }
39
+ } catch (e) {
40
+ console.warn(e)
41
+ }
42
+ }
43
+ if (!this._unzipData) {
44
+ this._unzipData = {}
45
+ }
46
+ return this._unzipData
47
+ }
48
+
49
+ async setZipData(path: string, data: InputType): Promise<void> {
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()
68
+ }
69
+
70
+ async generate(options: AsyncZipOptions): Promise<Blob|undefined> {
71
+ const data = await this.fileZip()
72
+ if (!Object.keys(data).length) {
73
+ return undefined
74
+ }
75
+ return await new Promise(async (resolve, reject) => {
76
+ zip(data, options, (err: FlateError | null, data: Uint8Array) => {
77
+ if (err) {
78
+ return reject(err)
79
+ }
80
+ resolve(new Blob([data]))
81
+ })
82
+ })
83
+ }
84
+
85
+ async download(fileName: string): Promise<void> {
86
+ const data = await this.fileZip()
87
+ if (!Object.keys(data).length) {
88
+ return
89
+ }
90
+
91
+ if (fileName == undefined) {
92
+ fileName = this.name
93
+ }
94
+
95
+ const downloadStream = stream(fileName)
96
+ const zip = new fflateZip((err, dat, final) => {
97
+ if (err) {
98
+ downloadStream.abort(err)
99
+ return
100
+ }
101
+ downloadStream.write(dat)
102
+ if (final) {
103
+ downloadStream.close()
104
+ }
105
+ })
106
+
107
+ for (const key in data) {
108
+ const deflate = new ZipDeflate(key, {
109
+ level: 9
110
+ });
111
+ zip.add(deflate)
112
+ deflate.push(data[key], true);
113
+ }
114
+ zip.end()
115
+ }
116
+ }
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "template-replacement",
3
+ "description": "模板文件替换",
4
+ "version": "3.0.8",
5
+ "author": "fushiliang <994301536@qq.com>",
6
+ "license": "ISC",
7
+ "type": "module",
8
+ "main": "index.ts",
9
+ "scripts": {
10
+ "build": "npx vite build --config vite.config.ts"
11
+ },
12
+ "dependencies": {
13
+ "@types/crypto-js": "^4.2.2",
14
+ "@types/streamsaver": "^2.0.5",
15
+ "axios": "^1.7.9",
16
+ "fflate": "^0.8.2",
17
+ "file-type": "^19.6.0",
18
+ "nanoid": "^4.0.2",
19
+ "streamsaver": "^2.0.6",
20
+ "template-replacement-core-wasm": "^1.0.0",
21
+ "template-replacement-sign-core-wasm": "^1.0.1",
22
+ "vite-plugin-wasm-pack": "^0.1.12"
23
+ },
24
+ "devDependencies": {
25
+ "@types/js-md5": "^0.7.2",
26
+ "typescript": "^5.7.3",
27
+ "vite": "^6.1.0",
28
+ "vite-plugin-dts": "^4.5.0"
29
+ },
30
+ "keywords": [
31
+ "template-replacement"
32
+ ]
33
+ }
@@ -0,0 +1,124 @@
1
+ import Interface, { media } from './interface';
2
+ import { Interface as CoreInterface } from '../core/base';
3
+ import paramsData from './paramsData';
4
+ import Temp from '../temp';
5
+ import { fileTypes } from '../helper';
6
+
7
+ export default class Base implements Interface{
8
+ #files: Temp[] = []
9
+ #core: CoreInterface
10
+
11
+ constructor(core: CoreInterface) {
12
+ this.#core = core
13
+ }
14
+
15
+ addTempFile(tempFile: Temp){
16
+ this.#files.push(tempFile)
17
+ }
18
+
19
+ clear(): void {
20
+ this.#files.length = 0
21
+ }
22
+
23
+ async extractVariables(files: Temp[] | undefined): Promise<Record<string, string[]>> {
24
+ if (!files) {
25
+ files = this.#files
26
+ }
27
+ const data: Record<string, string[]> = {}
28
+ const tasks = []
29
+ for (const file of files) {
30
+ tasks.push(new Promise<void>(async (resolve, reject) => {
31
+ const buffer = await file.getBuffer()
32
+ if (buffer && (await file.type()) !== fileTypes.unknown) {
33
+ data[file.name] = await this.#core.extract_one_file_variable_names(buffer)
34
+ }
35
+ resolve()
36
+ }))
37
+ }
38
+ await Promise.all(tasks)
39
+ return data
40
+ }
41
+
42
+ async extractMedias(files: Temp[] | undefined): Promise<Record<string, media[]>> {
43
+ if (!files) {
44
+ files = this.#files
45
+ }
46
+ const data: Record<string, media[]> = {}
47
+ const tasks = []
48
+ for (const file of files) {
49
+ tasks.push(new Promise<void>(async (resolve, reject) => {
50
+ const buffer = await file.getBuffer()
51
+ if (buffer && (await file.type()) !== fileTypes.unknown) {
52
+ let medias = await this.#core.extract_one_file_medias(buffer)
53
+ data[file.name] = []
54
+ if (medias && Array.isArray(medias)) {
55
+ medias.forEach(m => {
56
+ if (m.id && m.data) {
57
+ data[file.name].push({
58
+ id: m.id,
59
+ data: new Uint8Array(m.data)
60
+ })
61
+ }
62
+ })
63
+ }
64
+ }
65
+ resolve()
66
+ }))
67
+ }
68
+ await Promise.all(tasks)
69
+ return data
70
+ }
71
+
72
+ async handle(paramsData: paramsData, files: Uint8Array[]): Promise<Uint8Array[]> {
73
+ return []
74
+ }
75
+
76
+ async sign(data: any): Promise<string> {
77
+ return ""
78
+ }
79
+
80
+ async execute(params: paramsData, files: Temp[] | undefined): Promise<Record<string, Uint8Array>> {
81
+ if (!files) {
82
+ files = this.#files
83
+ }
84
+
85
+ const fileData: { names: string[], uint8Arrays: Uint8Array[] } = {
86
+ names: [],
87
+ uint8Arrays: [],
88
+ }
89
+
90
+ const tasks = []
91
+ for (const file of files) {
92
+ tasks.push(new Promise<Uint8Array|undefined>(async (resolve, reject) => {
93
+ resolve(file.getBuffer())
94
+ }))
95
+ }
96
+ await Promise.all(tasks)
97
+
98
+ for (const file of files) {
99
+ if (file.uint8Array) {
100
+ fileData.names.push(file.name)
101
+ fileData.uint8Arrays.push(file.uint8Array)
102
+ }
103
+ }
104
+
105
+ if(!fileData.uint8Arrays.length) {
106
+ return {}
107
+ }
108
+
109
+ const res = await this.handle(params, fileData.uint8Arrays)
110
+ const finishStatusCount = {
111
+ success: 0,
112
+ total: fileData.uint8Arrays.length
113
+ } //完成状态统计
114
+ const resData: Record<string, Uint8Array> = {}
115
+
116
+ res.forEach((file, i) => {
117
+ if (file.length) {
118
+ resData[fileData.names[i]] = file
119
+ finishStatusCount.success++
120
+ }
121
+ })
122
+ return resData
123
+ }
124
+ }
@@ -0,0 +1,14 @@
1
+ import Base from './base';
2
+ import core, { replace_batch } from '../core/general'
3
+ import paramsData from './paramsData';
4
+
5
+ export default class General extends Base {
6
+ constructor() {
7
+ super(core())
8
+ }
9
+
10
+ async handle(paramsData: paramsData, files: Uint8Array[]): Promise<Uint8Array[]> {
11
+ const [params, mediaBuffers] = await paramsData.toReplaceParams()
12
+ return replace_batch(params, mediaBuffers, files)
13
+ }
14
+ }
@@ -0,0 +1,116 @@
1
+ // import { add_media } from "template-replacement-core-wasm"
2
+
3
+ export function pxToEMU(px: number): number {
4
+ return px * (914400 / 96)
5
+ }
6
+
7
+ export function cmToEMU(cm: number): number {
8
+ return cm * 914400
9
+ }
10
+
11
+ export enum textWrapTypes {
12
+ embed = "Embed",//嵌入型
13
+ belowText = "BelowText",//嵌于文字下方
14
+ aboveText = "AboveText",//嵌于文字上方
15
+ }
16
+
17
+ function getFileExtension(filename: string): string {
18
+ const ext = filename.split('.').pop()
19
+ if (ext === undefined) {
20
+ return ''
21
+ }
22
+ return '.' + ext
23
+ }
24
+
25
+ // async function generateId(file: Blob): Promise<string> {
26
+ // const buffer = await file.arrayBuffer()
27
+ // return await add_media(new Uint8Array(buffer))
28
+ // }
29
+
30
+ export type extent = {
31
+ cy: number,
32
+ cx: number,
33
+ }
34
+
35
+ //图片替换
36
+ export default class image {
37
+ file: Blob
38
+ relationship = 'image'
39
+ id?: string
40
+
41
+ wpExtent?: extent //图片宽高
42
+ textWrap = textWrapTypes.embed //文字环绕
43
+
44
+ awaitInitQueue?: Function[] = []
45
+
46
+ constructor(file: Blob) {
47
+ if (file instanceof Blob) {
48
+ this.file = file
49
+ this.init()
50
+ } else {
51
+ throw new Error("不支持的数据类型");
52
+ }
53
+ }
54
+
55
+ async init(): Promise<void> {
56
+ this.awaitInitQueue = []
57
+ await this.getExtent()
58
+ for (const resolve of this.awaitInitQueue) {
59
+ resolve()
60
+ }
61
+ delete this.awaitInitQueue
62
+ }
63
+
64
+ // async generateId(): Promise<string> {
65
+ // this.id = await generateId(this.file)
66
+ // return this.id
67
+ // }
68
+
69
+ async awaitInit(): Promise<void> {
70
+ if (this.awaitInitQueue) {
71
+ await new Promise(resolve => {
72
+ this.awaitInitQueue?.push(resolve)
73
+ })
74
+ }
75
+ }
76
+
77
+ async getExtent(): Promise<extent> {
78
+ if (!this.wpExtent) {
79
+ const bitmap = await createImageBitmap(this.file)
80
+ !this.wpExtent && this.setPxExtent(bitmap.width, bitmap.height)
81
+ bitmap.close()
82
+ }
83
+ return this.wpExtent as extent
84
+ }
85
+
86
+ //设置图片范围(像素)
87
+ setPxExtent(width: number, height: number): void {
88
+ this.wpExtent = {
89
+ cy: pxToEMU(height),
90
+ cx: pxToEMU(width),
91
+ }
92
+ }
93
+
94
+ //设置图片范围(厘米)
95
+ setCmExtent(width: number, height: number): void {
96
+ this.wpExtent = {
97
+ cy: cmToEMU(height),
98
+ cx: cmToEMU(width),
99
+ }
100
+ }
101
+
102
+ async outJson(): Promise<Record<string, any>> {
103
+ await this.awaitInit()
104
+ const data: Record<string, any> = {}
105
+ for (const key in this) {
106
+ data[key] = this[key]
107
+ }
108
+ return data
109
+ }
110
+
111
+ setPropertys(data: Record<string, any>) {
112
+ for (const key in data) {
113
+ this[key as keyof image] = data[key]
114
+ }
115
+ }
116
+ }
@@ -0,0 +1,29 @@
1
+ import paramsData from "./paramsData"
2
+ import Temp from "../temp"
3
+
4
+ export type media = {
5
+ id: string,
6
+ data: Uint8Array
7
+ }
8
+
9
+ export default interface ReplaceInterface {
10
+
11
+ //添加模板文件
12
+ addTempFile(tempFile: Temp): void
13
+
14
+ //清空文件和链接
15
+ clear(): void
16
+
17
+ //提取变量
18
+ extractVariables(files: Temp[] | undefined): Promise<Record<string, string[]>>
19
+
20
+ //提取媒体
21
+ extractMedias(files: Temp[] | undefined): Promise<Record<string, media[]>>
22
+
23
+ //签名方法
24
+ sign(data: any): Promise<string>
25
+
26
+ //执行替换任务
27
+ execute(params: paramsData, files: Temp[] | undefined): Promise<Record<string, Uint8Array>>
28
+
29
+ }