-
Notifications
You must be signed in to change notification settings - Fork 238
Expand file tree
/
Copy pathFormatHandler.ts
More file actions
205 lines (190 loc) · 5.79 KB
/
FormatHandler.ts
File metadata and controls
205 lines (190 loc) · 5.79 KB
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/**
* Definition of file format. Contains format defined constants like mime type and names
*/
export interface IFormatDefinition {
/** Format description (long name) for displaying to the user. */
name: string;
/** Short, "formal" name for displaying to the user, and for
* differentiating between files of identical MIME types.
* If your file is different from others of the same MIME type,
* then this string should be used to differentiate it. */
format: string;
/** File extension. */
extension: string;
/** MIME type. */
mime: string;
/** Category for grouping formats. */
category?: Array<string> | string
}
export interface FileFormat extends IFormatDefinition {
/** Whether conversion **from** this format is supported. */
from: boolean;
/** Whether conversion **to** this format is supported. */
to: boolean;
/** Format identifier for the handler's internal reference. */
internal: string;
/** (Optional) Whether the format is lossless in this context. Defaults to `false`. */
lossless?: boolean;
}
/**
* Class containing format definition and method used to produce FileFormat
* that can be supported by handlers.
*/
export class FormatDefinition implements IFormatDefinition {
public readonly name: string;
public readonly format: string;
public readonly extension: string;
public readonly mime: string;
public readonly category?: string[] | string;
constructor(
name: string,
format: string,
extension: string,
mime: string,
category?: string[] | string
) {
this.name = name
this.format = format
this.extension = extension
this.mime = mime
this.category = category
}
/**
* Returns `FileFormat` object that uses this format definition
* and specified options
* @param ref Format identifier for the handler's internal reference.
* @param from Whether conversion **from** this format is supported.
* @param to Whether conversion **to** this format is supported.
* @param lossless (Optional) Whether the format is lossless in this context. Defaults to `false`.
* @param override Format definition values to override
* @returns
*/
supported(ref: string, from: boolean, to: boolean, lossless?: boolean, override: Partial<IFormatDefinition> = {}): FileFormat {
return {
...this,
...override,
internal: ref,
from: from,
to: to,
lossless: lossless ?? false
}
}
/**
* Returns a builder to fluently create FileFormat.
* Builder can be used to create FileFormat based on this format definition
*/
builder(ref: string) {
const def = this;
const builder = {
// FileFormat fields
name: def.name,
format: def.format,
extension: def.extension,
mime: def.mime,
category: def.category,
internal: ref,
from: false,
to: false,
lossless: false,
allowFrom(value: boolean = true) {
this.from = value;
return this;
},
allowTo(value: boolean = true) {
this.to = value;
return this;
},
markLossless(value: boolean = true) {
this.lossless = value;
return this;
},
named(name: string) {
this.name = name;
return this;
},
withFormat(format: string) {
this.format = format;
return this;
},
withExt(ext: string) {
this.extension = ext;
return this;
},
withMime(mimetype: string) {
this.mime = mimetype;
return this;
},
/**
* Replaces format category
*/
withCategory(category: string[] | string | undefined) {
this.category = category
return this
},
override(values: Partial<IFormatDefinition>) {
Object.assign(this, values);
return this;
},
};
return builder as FileFormat & typeof builder;
}
}
export interface FileData {
/** File name with extension. */
name: string;
/**
* File contents in bytes.
*
* **Please note:** _handlers_ are responsible for ensuring the lifetime
* and consistency of this buffer. If you're not sure that your handler
* won't modify it, wrap it in `new Uint8Array()`.
*/
readonly bytes: Uint8Array;
}
/**
* Establishes a common interface for converting between file formats.
* Often a "wrapper" for existing tools.
*/
export interface FormatHandler {
/** Name of the tool being wrapped (e.g. "FFmpeg"). */
name: string;
/** List of supported input/output {@link FileFormat}s. */
supportedFormats?: FileFormat[];
/** Whether the handler supports input of any type.
* Conversion using this handler will be performed only if no other direct conversion is found.
*/
supportAnyInput?: boolean;
/**
* Whether the handler is ready for use. Should be set in {@link init}.
* If true, {@link doConvert} is expected to work.
*/
ready: boolean;
/**
* Initializes the handler if necessary.
* Should set {@link ready} to true.
*/
init: () => Promise<void>;
/**
* Performs the actual file conversion.
* @param inputFiles Array of {@link FileData} entries, one per input file.
* @param inputFormat Input {@link FileFormat}, the same for all inputs.
* @param outputFormat Output {@link FileFormat}, the same for all outputs.
* @param args Optional arguments as a string array.
* Can be used to perform recursion with different settings.
* @returns Array of {@link FileData} entries, one per generated output file.
*/
doConvert: (
inputFiles: FileData[],
inputFormat: FileFormat,
outputFormat: FileFormat,
args?: string[]
) => Promise<FileData[]>;
}
export class ConvertPathNode {
public handler: FormatHandler;
public format: FileFormat;
constructor(handler: FormatHandler, format: FileFormat) {
this.handler = handler;
this.format = format;
}
}