@grest-ts/file 0.0.5
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/LICENSE +21 -0
- package/dist/src/GGFile.d.ts +128 -0
- package/dist/src/GGFile.d.ts.map +1 -0
- package/dist/src/GGFile.js +187 -0
- package/dist/src/GGFile.js.map +1 -0
- package/dist/src/IsFile.d.ts +49 -0
- package/dist/src/IsFile.d.ts.map +1 -0
- package/dist/src/IsFile.js +125 -0
- package/dist/src/IsFile.js.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +4 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/tsconfig.json +17 -0
- package/dist/testkit/GGTestFile.d.ts +63 -0
- package/dist/testkit/GGTestFile.d.ts.map +1 -0
- package/dist/testkit/GGTestFile.js +156 -0
- package/dist/testkit/GGTestFile.js.map +1 -0
- package/dist/testkit/index-testkit.d.ts +2 -0
- package/dist/testkit/index-testkit.d.ts.map +1 -0
- package/dist/testkit/index-testkit.js +2 -0
- package/dist/testkit/index-testkit.js.map +1 -0
- package/dist/tsconfig.publish.tsbuildinfo +1 -0
- package/package.json +57 -0
- package/src/GGFile.ts +259 -0
- package/src/IsFile.ts +153 -0
- package/src/index.ts +4 -0
- package/src/tsconfig.json +17 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Grest Games OÜ
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified file abstraction for Grest framework.
|
|
3
|
+
* Works across HTTP (multipart), WebSocket (base64), and tests (in-memory).
|
|
4
|
+
*
|
|
5
|
+
* Single consumption: buffer()/stream()/text() can only be called once.
|
|
6
|
+
* Use clone() if multiple reads are needed.
|
|
7
|
+
*/
|
|
8
|
+
export declare abstract class GGFile {
|
|
9
|
+
abstract readonly name: string;
|
|
10
|
+
abstract readonly mimeType: string;
|
|
11
|
+
abstract readonly size: number;
|
|
12
|
+
/**
|
|
13
|
+
* Whether the file content has been consumed.
|
|
14
|
+
* Once consumed, buffer()/stream()/text() will throw.
|
|
15
|
+
*/
|
|
16
|
+
abstract readonly consumed: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Get the file content as a ReadableStream.
|
|
19
|
+
* Can only be called once per file instance.
|
|
20
|
+
* @throws Error if already consumed
|
|
21
|
+
*/
|
|
22
|
+
abstract stream(): ReadableStream<Uint8Array>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the file content as a Uint8Array.
|
|
25
|
+
* Can only be called once per file instance.
|
|
26
|
+
* @throws Error if already consumed
|
|
27
|
+
*/
|
|
28
|
+
abstract buffer(): Promise<Uint8Array>;
|
|
29
|
+
/**
|
|
30
|
+
* Get the file content as a UTF-8 string.
|
|
31
|
+
* Can only be called once per file instance.
|
|
32
|
+
* @throws Error if already consumed
|
|
33
|
+
*/
|
|
34
|
+
abstract text(): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Create a copy of this file that can be consumed independently.
|
|
37
|
+
* Only works if the file hasn't been consumed yet.
|
|
38
|
+
* @throws Error if already consumed
|
|
39
|
+
*/
|
|
40
|
+
abstract clone(): GGFile;
|
|
41
|
+
/**
|
|
42
|
+
* Create a GGFile from a Uint8Array buffer.
|
|
43
|
+
*/
|
|
44
|
+
static fromBuffer(data: Uint8Array, name: string, mimeType?: string): GGFile;
|
|
45
|
+
/**
|
|
46
|
+
* Create a GGFile from a string (encoded as UTF-8).
|
|
47
|
+
*/
|
|
48
|
+
static fromString(content: string, name: string, mimeType?: string): GGFile;
|
|
49
|
+
/**
|
|
50
|
+
* Create a GGFile from a base64-encoded string.
|
|
51
|
+
* Used for WebSocket transport where files are sent as base64.
|
|
52
|
+
*/
|
|
53
|
+
static fromBase64(base64: string, name: string, mimeType?: string): GGFile;
|
|
54
|
+
/**
|
|
55
|
+
* Convert a GGFile to base64 string.
|
|
56
|
+
* Consumes the file.
|
|
57
|
+
*/
|
|
58
|
+
static toBase64(file: GGFile): Promise<string>;
|
|
59
|
+
/**
|
|
60
|
+
* Serialize a GGFile to JSON format for WebSocket transport.
|
|
61
|
+
* Consumes the file.
|
|
62
|
+
*/
|
|
63
|
+
static toJSON(file: GGFile): Promise<GGFileJSON>;
|
|
64
|
+
/**
|
|
65
|
+
* Deserialize a GGFile from JSON format.
|
|
66
|
+
*/
|
|
67
|
+
static fromJSON(json: GGFileJSON): GGFile;
|
|
68
|
+
/**
|
|
69
|
+
* Check if a value is a serialized GGFile JSON.
|
|
70
|
+
*/
|
|
71
|
+
static isJSON(value: unknown): value is GGFileJSON;
|
|
72
|
+
/**
|
|
73
|
+
* Create a GGFile from a native browser File.
|
|
74
|
+
* Lazily reads the file content only when buffer()/stream()/text() is called.
|
|
75
|
+
*/
|
|
76
|
+
static fromBrowserFile(file: File & {
|
|
77
|
+
readonly name: string;
|
|
78
|
+
}): GGFile;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* JSON serialization format for GGFile (used in WebSocket transport).
|
|
82
|
+
*/
|
|
83
|
+
export interface GGFileJSON {
|
|
84
|
+
__ggfile: true;
|
|
85
|
+
name: string;
|
|
86
|
+
mimeType: string;
|
|
87
|
+
size: number;
|
|
88
|
+
data: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* In-memory implementation of GGFile.
|
|
92
|
+
* Used for tests and when file content is already fully buffered.
|
|
93
|
+
*/
|
|
94
|
+
export declare class BufferGGFile extends GGFile {
|
|
95
|
+
private _consumed;
|
|
96
|
+
private readonly data;
|
|
97
|
+
readonly name: string;
|
|
98
|
+
readonly mimeType: string;
|
|
99
|
+
constructor(data: Uint8Array, name: string, mimeType?: string);
|
|
100
|
+
get size(): number;
|
|
101
|
+
get consumed(): boolean;
|
|
102
|
+
protected assertNotConsumed(): void;
|
|
103
|
+
stream(): ReadableStream<Uint8Array>;
|
|
104
|
+
buffer(): Promise<Uint8Array>;
|
|
105
|
+
text(): Promise<string>;
|
|
106
|
+
clone(): GGFile;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Browser implementation of GGFile that wraps a native File/Blob.
|
|
110
|
+
* Lazily reads file content only when buffer()/stream()/text() is called.
|
|
111
|
+
*/
|
|
112
|
+
export declare class BrowserGGFile extends GGFile {
|
|
113
|
+
private readonly nativeFile;
|
|
114
|
+
private _consumed;
|
|
115
|
+
readonly name: string;
|
|
116
|
+
readonly mimeType: string;
|
|
117
|
+
readonly size: number;
|
|
118
|
+
constructor(nativeFile: File & {
|
|
119
|
+
readonly name: string;
|
|
120
|
+
});
|
|
121
|
+
get consumed(): boolean;
|
|
122
|
+
private assertNotConsumed;
|
|
123
|
+
stream(): ReadableStream<Uint8Array>;
|
|
124
|
+
buffer(): Promise<Uint8Array>;
|
|
125
|
+
text(): Promise<string>;
|
|
126
|
+
clone(): GGFile;
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=GGFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGFile.d.ts","sourceRoot":"","sources":["../../src/GGFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified file abstraction for Grest framework.
|
|
3
|
+
* Works across HTTP (multipart), WebSocket (base64), and tests (in-memory).
|
|
4
|
+
*
|
|
5
|
+
* Single consumption: buffer()/stream()/text() can only be called once.
|
|
6
|
+
* Use clone() if multiple reads are needed.
|
|
7
|
+
*/
|
|
8
|
+
export class GGFile {
|
|
9
|
+
// ==================== Static Factory Methods ====================
|
|
10
|
+
/**
|
|
11
|
+
* Create a GGFile from a Uint8Array buffer.
|
|
12
|
+
*/
|
|
13
|
+
static fromBuffer(data, name, mimeType = 'application/octet-stream') {
|
|
14
|
+
return new BufferGGFile(data, name, mimeType);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Create a GGFile from a string (encoded as UTF-8).
|
|
18
|
+
*/
|
|
19
|
+
static fromString(content, name, mimeType = 'text/plain') {
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
return new BufferGGFile(encoder.encode(content), name, mimeType);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a GGFile from a base64-encoded string.
|
|
25
|
+
* Used for WebSocket transport where files are sent as base64.
|
|
26
|
+
*/
|
|
27
|
+
static fromBase64(base64, name, mimeType = 'application/octet-stream') {
|
|
28
|
+
const binaryString = atob(base64);
|
|
29
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
30
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
31
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
32
|
+
}
|
|
33
|
+
return new BufferGGFile(bytes, name, mimeType);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Convert a GGFile to base64 string.
|
|
37
|
+
* Consumes the file.
|
|
38
|
+
*/
|
|
39
|
+
static async toBase64(file) {
|
|
40
|
+
const buffer = await file.buffer();
|
|
41
|
+
let binary = '';
|
|
42
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
43
|
+
binary += String.fromCharCode(buffer[i]);
|
|
44
|
+
}
|
|
45
|
+
return btoa(binary);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Serialize a GGFile to JSON format for WebSocket transport.
|
|
49
|
+
* Consumes the file.
|
|
50
|
+
*/
|
|
51
|
+
static async toJSON(file) {
|
|
52
|
+
return {
|
|
53
|
+
__ggfile: true,
|
|
54
|
+
name: file.name,
|
|
55
|
+
mimeType: file.mimeType,
|
|
56
|
+
size: file.size,
|
|
57
|
+
data: await GGFile.toBase64(file),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Deserialize a GGFile from JSON format.
|
|
62
|
+
*/
|
|
63
|
+
static fromJSON(json) {
|
|
64
|
+
if (!json.__ggfile) {
|
|
65
|
+
throw new Error('Invalid GGFile JSON: missing __ggfile marker');
|
|
66
|
+
}
|
|
67
|
+
return GGFile.fromBase64(json.data, json.name, json.mimeType);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if a value is a serialized GGFile JSON.
|
|
71
|
+
*/
|
|
72
|
+
static isJSON(value) {
|
|
73
|
+
return typeof value === 'object'
|
|
74
|
+
&& value !== null
|
|
75
|
+
&& '__ggfile' in value
|
|
76
|
+
&& value.__ggfile === true
|
|
77
|
+
&& 'name' in value
|
|
78
|
+
&& 'mimeType' in value
|
|
79
|
+
&& 'size' in value
|
|
80
|
+
&& 'data' in value;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a GGFile from a native browser File.
|
|
84
|
+
* Lazily reads the file content only when buffer()/stream()/text() is called.
|
|
85
|
+
*/
|
|
86
|
+
static fromBrowserFile(file) {
|
|
87
|
+
return new BrowserGGFile(file);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* In-memory implementation of GGFile.
|
|
92
|
+
* Used for tests and when file content is already fully buffered.
|
|
93
|
+
*/
|
|
94
|
+
export class BufferGGFile extends GGFile {
|
|
95
|
+
_consumed = false;
|
|
96
|
+
data;
|
|
97
|
+
name;
|
|
98
|
+
mimeType;
|
|
99
|
+
constructor(data, name, mimeType = 'application/octet-stream') {
|
|
100
|
+
super();
|
|
101
|
+
this.data = data;
|
|
102
|
+
this.name = name;
|
|
103
|
+
this.mimeType = mimeType;
|
|
104
|
+
}
|
|
105
|
+
get size() {
|
|
106
|
+
return this.data.length;
|
|
107
|
+
}
|
|
108
|
+
get consumed() {
|
|
109
|
+
return this._consumed;
|
|
110
|
+
}
|
|
111
|
+
assertNotConsumed() {
|
|
112
|
+
if (this._consumed) {
|
|
113
|
+
throw new Error(`GGFile "${this.name}" has already been consumed. Use clone() if multiple reads are needed.`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
stream() {
|
|
117
|
+
this.assertNotConsumed();
|
|
118
|
+
this._consumed = true;
|
|
119
|
+
const data = this.data;
|
|
120
|
+
return new ReadableStream({
|
|
121
|
+
start(controller) {
|
|
122
|
+
controller.enqueue(data);
|
|
123
|
+
controller.close();
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async buffer() {
|
|
128
|
+
this.assertNotConsumed();
|
|
129
|
+
this._consumed = true;
|
|
130
|
+
return this.data;
|
|
131
|
+
}
|
|
132
|
+
async text() {
|
|
133
|
+
this.assertNotConsumed();
|
|
134
|
+
this._consumed = true;
|
|
135
|
+
return new TextDecoder().decode(this.data);
|
|
136
|
+
}
|
|
137
|
+
clone() {
|
|
138
|
+
this.assertNotConsumed();
|
|
139
|
+
return new BufferGGFile(new Uint8Array(this.data), this.name, this.mimeType);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Browser implementation of GGFile that wraps a native File/Blob.
|
|
144
|
+
* Lazily reads file content only when buffer()/stream()/text() is called.
|
|
145
|
+
*/
|
|
146
|
+
export class BrowserGGFile extends GGFile {
|
|
147
|
+
nativeFile;
|
|
148
|
+
_consumed = false;
|
|
149
|
+
name;
|
|
150
|
+
mimeType;
|
|
151
|
+
size;
|
|
152
|
+
constructor(nativeFile) {
|
|
153
|
+
super();
|
|
154
|
+
this.nativeFile = nativeFile;
|
|
155
|
+
this.name = nativeFile.name;
|
|
156
|
+
this.mimeType = nativeFile.type || 'application/octet-stream';
|
|
157
|
+
this.size = nativeFile.size;
|
|
158
|
+
}
|
|
159
|
+
get consumed() {
|
|
160
|
+
return this._consumed;
|
|
161
|
+
}
|
|
162
|
+
assertNotConsumed() {
|
|
163
|
+
if (this._consumed) {
|
|
164
|
+
throw new Error(`GGFile "${this.name}" has already been consumed. Use clone() if multiple reads are needed.`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
stream() {
|
|
168
|
+
this.assertNotConsumed();
|
|
169
|
+
this._consumed = true;
|
|
170
|
+
return this.nativeFile.stream();
|
|
171
|
+
}
|
|
172
|
+
async buffer() {
|
|
173
|
+
this.assertNotConsumed();
|
|
174
|
+
this._consumed = true;
|
|
175
|
+
return new Uint8Array(await this.nativeFile.arrayBuffer());
|
|
176
|
+
}
|
|
177
|
+
async text() {
|
|
178
|
+
this.assertNotConsumed();
|
|
179
|
+
this._consumed = true;
|
|
180
|
+
return this.nativeFile.text();
|
|
181
|
+
}
|
|
182
|
+
clone() {
|
|
183
|
+
this.assertNotConsumed();
|
|
184
|
+
return new BrowserGGFile(this.nativeFile);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=GGFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGFile.js","sourceRoot":"","sources":["../../src/GGFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GGSchema, GGSchemaNonJsonDefinition, GGIssueInvalid, Opt } from "@grest-ts/schema";
|
|
2
|
+
import { GGFile } from "./GGFile";
|
|
3
|
+
/**
|
|
4
|
+
* Definition for file schema.
|
|
5
|
+
*/
|
|
6
|
+
export interface FileDef extends GGSchemaNonJsonDefinition {
|
|
7
|
+
readonly type: 'file';
|
|
8
|
+
readonly accept?: readonly string[];
|
|
9
|
+
readonly maxSize?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class FileSchema<T extends GGFile | undefined | null = GGFile> extends GGSchema<T, FileDef> {
|
|
12
|
+
static readonly typeError: GGIssueInvalid<{}>;
|
|
13
|
+
static readonly mimeTypeError: GGIssueInvalid<{
|
|
14
|
+
accept: string;
|
|
15
|
+
}>;
|
|
16
|
+
static readonly maxSizeError: GGIssueInvalid<{
|
|
17
|
+
max: number;
|
|
18
|
+
}>;
|
|
19
|
+
constructor(def: {
|
|
20
|
+
type: 'file';
|
|
21
|
+
accept?: readonly string[];
|
|
22
|
+
maxSize?: number;
|
|
23
|
+
optional?: boolean;
|
|
24
|
+
nullable?: boolean;
|
|
25
|
+
});
|
|
26
|
+
get orUndefined(): FileSchema<T | undefined> & Opt;
|
|
27
|
+
get orNull(): FileSchema<T | null>;
|
|
28
|
+
protected derive<NewT extends GGFile | undefined | null = T>(changes: Partial<FileDef>): FileSchema<NewT>;
|
|
29
|
+
accept(...types: string[]): FileSchema<T>;
|
|
30
|
+
maxSize(bytes: number): FileSchema<T>;
|
|
31
|
+
static image(opts?: {
|
|
32
|
+
maxSize?: number;
|
|
33
|
+
}): FileSchema;
|
|
34
|
+
static pdf(opts?: {
|
|
35
|
+
maxSize?: number;
|
|
36
|
+
}): FileSchema;
|
|
37
|
+
static any(opts?: {
|
|
38
|
+
maxSize?: number;
|
|
39
|
+
}): FileSchema;
|
|
40
|
+
static video(opts?: {
|
|
41
|
+
maxSize?: number;
|
|
42
|
+
}): FileSchema;
|
|
43
|
+
static audio(opts?: {
|
|
44
|
+
maxSize?: number;
|
|
45
|
+
}): FileSchema;
|
|
46
|
+
}
|
|
47
|
+
export declare const IsFile: FileSchema<GGFile>;
|
|
48
|
+
export type tFile = typeof IsFile.infer;
|
|
49
|
+
//# sourceMappingURL=IsFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IsFile.d.ts","sourceRoot":"","sources":["../../src/IsFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAE,yBAAyB,EAAsB,cAAc,EAAE,GAAG,EAAC,MAAM,kBAAkB,CAAC;AAE9G,OAAO,EAAe,MAAM,EAAC,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,OAAQ,SAAQ,yBAAyB;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC7B;AAiCD,qBAAa,UAAU,CAAC,CAAC,SAAS,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAAE,SAAQ,QAAQ,CAAC,CAAC,EAAE,OAAO,CAAC;IAE9F,gBAAuB,SAAS,qBAA2D;IAC3F,gBAAuB,aAAa;gBAAgC,MAAM;OAA+F;IACzK,gBAAuB,YAAY;aAA6B,MAAM;OAAuF;gBAEjJ,GAAG,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE;IAyCvH,IAAI,WAAW,IAAI,UAAU,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,GAAG,CAEjD;IAED,IAAI,MAAM,IAAI,UAAU,CAAC,CAAC,GAAG,IAAI,CAAC,CAEjC;IAED,SAAS,CAAC,MAAM,CAAC,IAAI,SAAS,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC;IAezG,MAAM,CAAC,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC;IAKzC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC;IAMrC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;IAKrD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;IAKnD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;IAKnD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;IAKrD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU;CAIxD;AAED,eAAO,MAAM,MAAM,oBAAiC,CAAC;AACrD,MAAM,MAAM,KAAK,GAAG,OAAO,MAAM,CAAC,KAAK,CAAC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { GGSchema, GGIssueInvalid } from "@grest-ts/schema";
|
|
2
|
+
import { BufferGGFile } from "./GGFile.js";
|
|
3
|
+
// ==================== Helper Functions ====================
|
|
4
|
+
function isGGFileLike(value) {
|
|
5
|
+
return typeof value === 'object'
|
|
6
|
+
&& value !== null
|
|
7
|
+
&& 'name' in value
|
|
8
|
+
&& 'mimeType' in value
|
|
9
|
+
&& 'size' in value
|
|
10
|
+
&& typeof value.name === 'string'
|
|
11
|
+
&& typeof value.mimeType === 'string'
|
|
12
|
+
&& typeof value.size === 'number';
|
|
13
|
+
}
|
|
14
|
+
function matchesAccept(name, mimeType, accept) {
|
|
15
|
+
if (!accept || accept.length === 0)
|
|
16
|
+
return true;
|
|
17
|
+
for (const pattern of accept) {
|
|
18
|
+
if (pattern.startsWith('.')) {
|
|
19
|
+
if (name.toLowerCase().endsWith(pattern.toLowerCase()))
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
else if (pattern === '*/*') {
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
else if (pattern.endsWith('/*')) {
|
|
26
|
+
if (mimeType.startsWith(pattern.slice(0, -1)))
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
if (mimeType === pattern)
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// ==================== FileSchema ====================
|
|
37
|
+
export class FileSchema extends GGSchema {
|
|
38
|
+
static typeError = new GGIssueInvalid("file.type", "Value must be a file");
|
|
39
|
+
static mimeTypeError = new GGIssueInvalid("file.mimeType", "File type not accepted, expected: {accept}", { accept: "Accepted types" });
|
|
40
|
+
static maxSizeError = new GGIssueInvalid("file.maxSize", "File exceeds maximum size of {max} bytes", { max: "Maximum size" });
|
|
41
|
+
constructor(def) {
|
|
42
|
+
const { accept, maxSize } = def;
|
|
43
|
+
const is = (value) => {
|
|
44
|
+
if (!isGGFileLike(value))
|
|
45
|
+
return false;
|
|
46
|
+
return matchesAccept(value.name, value.mimeType, accept) && (maxSize === undefined || value.size <= maxSize);
|
|
47
|
+
};
|
|
48
|
+
const isWithErrors = (value, issues, path) => {
|
|
49
|
+
if (!isGGFileLike(value)) {
|
|
50
|
+
return FileSchema.typeError.add(value, issues, path);
|
|
51
|
+
}
|
|
52
|
+
let valid = true;
|
|
53
|
+
if (!matchesAccept(value.name, value.mimeType, accept)) {
|
|
54
|
+
FileSchema.mimeTypeError.add(value, issues, path, { accept: accept?.join(', ') ?? '*/*' });
|
|
55
|
+
valid = false;
|
|
56
|
+
}
|
|
57
|
+
if (maxSize !== undefined && value.size > maxSize) {
|
|
58
|
+
FileSchema.maxSizeError.add(value, issues, path, { max: maxSize });
|
|
59
|
+
valid = false;
|
|
60
|
+
}
|
|
61
|
+
return valid;
|
|
62
|
+
};
|
|
63
|
+
const encodeToRaw = async (value, path) => {
|
|
64
|
+
const file = value;
|
|
65
|
+
const buffer = await file.clone().buffer();
|
|
66
|
+
const blob = new Blob([buffer], { type: file.mimeType });
|
|
67
|
+
return { path, blob, filename: file.name };
|
|
68
|
+
};
|
|
69
|
+
const decodeFromRaw = async (raw) => {
|
|
70
|
+
const buffer = await raw.blob.arrayBuffer();
|
|
71
|
+
return new BufferGGFile(new Uint8Array(buffer), raw.filename || 'file', raw.blob.type);
|
|
72
|
+
};
|
|
73
|
+
super({ ...def, hasNonJsonData: true, is, isWithErrors, encodeToRaw, decodeFromRaw });
|
|
74
|
+
}
|
|
75
|
+
// ==================== Schema Methods ====================
|
|
76
|
+
get orUndefined() {
|
|
77
|
+
return super.orUndefined;
|
|
78
|
+
}
|
|
79
|
+
get orNull() {
|
|
80
|
+
return super.orNull;
|
|
81
|
+
}
|
|
82
|
+
derive(changes) {
|
|
83
|
+
if (this.def.maxSize !== undefined && changes.maxSize !== undefined && changes.maxSize > this.def.maxSize) {
|
|
84
|
+
throw new Error(`Cannot raise maxSize from ${this.def.maxSize} to ${changes.maxSize}`);
|
|
85
|
+
}
|
|
86
|
+
return new FileSchema({
|
|
87
|
+
type: 'file',
|
|
88
|
+
accept: changes.accept ?? this.def.accept,
|
|
89
|
+
maxSize: changes.maxSize ?? this.def.maxSize,
|
|
90
|
+
optional: changes.optional ?? this.def.optional,
|
|
91
|
+
nullable: changes.nullable ?? this.def.nullable
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// ==================== File Constraints ====================
|
|
95
|
+
accept(...types) {
|
|
96
|
+
const combined = this.def.accept ? [...this.def.accept, ...types] : types;
|
|
97
|
+
return this.derive({ accept: combined });
|
|
98
|
+
}
|
|
99
|
+
maxSize(bytes) {
|
|
100
|
+
return this.derive({ maxSize: bytes });
|
|
101
|
+
}
|
|
102
|
+
// ==================== Static Shortcuts ====================
|
|
103
|
+
static image(opts) {
|
|
104
|
+
let s = new FileSchema({ type: 'file', accept: ['image/*'] });
|
|
105
|
+
return opts?.maxSize ? s.maxSize(opts.maxSize) : s;
|
|
106
|
+
}
|
|
107
|
+
static pdf(opts) {
|
|
108
|
+
let s = new FileSchema({ type: 'file', accept: ['application/pdf'] });
|
|
109
|
+
return opts?.maxSize ? s.maxSize(opts.maxSize) : s;
|
|
110
|
+
}
|
|
111
|
+
static any(opts) {
|
|
112
|
+
let s = new FileSchema({ type: 'file' });
|
|
113
|
+
return opts?.maxSize ? s.maxSize(opts.maxSize) : s;
|
|
114
|
+
}
|
|
115
|
+
static video(opts) {
|
|
116
|
+
let s = new FileSchema({ type: 'file', accept: ['video/*'] });
|
|
117
|
+
return opts?.maxSize ? s.maxSize(opts.maxSize) : s;
|
|
118
|
+
}
|
|
119
|
+
static audio(opts) {
|
|
120
|
+
let s = new FileSchema({ type: 'file', accept: ['audio/*'] });
|
|
121
|
+
return opts?.maxSize ? s.maxSize(opts.maxSize) : s;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export const IsFile = new FileSchema({ type: 'file' });
|
|
125
|
+
//# sourceMappingURL=IsFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IsFile.js","sourceRoot":"","sources":["../../src/IsFile.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AAEzB,OAAO,EAAC,YAAY,EAAE,aAAa,EAAC,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { GGFile } from "@grest-ts/file";
|
|
2
|
+
/**
|
|
3
|
+
* Test utilities for creating GGFile instances in tests.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* // Create from buffer
|
|
8
|
+
* const file = GGTestFile.fromBuffer(
|
|
9
|
+
* new Uint8Array([0x89, 0x50, 0x4E, 0x47]),
|
|
10
|
+
* 'test.png',
|
|
11
|
+
* 'image/png'
|
|
12
|
+
* );
|
|
13
|
+
*
|
|
14
|
+
* // Create from string
|
|
15
|
+
* const textFile = GGTestFile.fromString('Hello World', 'hello.txt');
|
|
16
|
+
*
|
|
17
|
+
* // Generate random test files
|
|
18
|
+
* const randomImage = GGTestFile.random(1024, 'test.png', 'image/png');
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const GGTestFile: {
|
|
22
|
+
/**
|
|
23
|
+
* Create a GGFile from a Uint8Array buffer.
|
|
24
|
+
*/
|
|
25
|
+
fromBuffer(data: Uint8Array, name: string, mimeType?: string): GGFile;
|
|
26
|
+
/**
|
|
27
|
+
* Create a GGFile from a string (encoded as UTF-8).
|
|
28
|
+
*/
|
|
29
|
+
fromString(content: string, name: string, mimeType?: string): GGFile;
|
|
30
|
+
/**
|
|
31
|
+
* Create a GGFile from a base64-encoded string.
|
|
32
|
+
*/
|
|
33
|
+
fromBase64(base64: string, name: string, mimeType?: string): GGFile;
|
|
34
|
+
/**
|
|
35
|
+
* Create a GGFile with random bytes of specified size.
|
|
36
|
+
* Useful for testing file size limits.
|
|
37
|
+
*/
|
|
38
|
+
random(size: number, name: string, mimeType?: string): GGFile;
|
|
39
|
+
/**
|
|
40
|
+
* Create a minimal valid PNG file (1x1 transparent pixel).
|
|
41
|
+
* Useful for testing image upload endpoints.
|
|
42
|
+
*/
|
|
43
|
+
png1x1(name?: string): GGFile;
|
|
44
|
+
/**
|
|
45
|
+
* Create a minimal valid JPEG file (1x1 red pixel).
|
|
46
|
+
* Useful for testing image upload endpoints.
|
|
47
|
+
*/
|
|
48
|
+
jpeg1x1(name?: string): GGFile;
|
|
49
|
+
/**
|
|
50
|
+
* Create a minimal valid PDF file.
|
|
51
|
+
* Useful for testing document upload endpoints.
|
|
52
|
+
*/
|
|
53
|
+
pdf(name?: string): GGFile;
|
|
54
|
+
/**
|
|
55
|
+
* Create a JSON file from an object.
|
|
56
|
+
*/
|
|
57
|
+
json(data: unknown, name?: string): GGFile;
|
|
58
|
+
/**
|
|
59
|
+
* Create a CSV file from rows.
|
|
60
|
+
*/
|
|
61
|
+
csv(rows: string[][], name?: string): GGFile;
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=GGTestFile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GGTestFile.d.ts","sourceRoot":"","sources":["../../testkit/GGTestFile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,gBAAgB,CAAC;AAEtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU;IACnB;;OAEG;qBACc,UAAU,QAAQ,MAAM,aAAY,MAAM,GAAgC,MAAM;IAIjG;;OAEG;wBACiB,MAAM,QAAQ,MAAM,aAAY,MAAM,GAAkB,MAAM;IAIlF;;OAEG;uBACgB,MAAM,QAAQ,MAAM,aAAY,MAAM,GAAgC,MAAM;IAI/F;;;OAGG;iBACU,MAAM,QAAQ,MAAM,aAAY,MAAM,GAAgC,MAAM;IASzF;;;OAGG;kBACU,MAAM,GAAgB,MAAM;IAgBzC;;;OAGG;mBACW,MAAM,GAAgB,MAAM;IAoC1C;;;OAGG;eACO,MAAM,GAAgB,MAAM;IA0BtC;;OAEG;eACQ,OAAO,SAAQ,MAAM,GAAiB,MAAM;IAKvD;;OAEG;cACO,MAAM,EAAE,EAAE,SAAQ,MAAM,GAAgB,MAAM;CAU3D,CAAC"}
|