@aepstore-dev/contracts 1.1.0 → 1.2.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/gen/upload.ts +147 -28
- package/package.json +1 -1
- package/proto/upload.proto +112 -26
package/gen/upload.ts
CHANGED
|
@@ -10,84 +10,203 @@ import { Observable } from "rxjs";
|
|
|
10
10
|
|
|
11
11
|
export const protobufPackage = "upload.v1";
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Determines the object key prefix (and future ACL/privacy policy).
|
|
15
|
+
* ATTACHMENT = paid product deliverable (private; presigned GET only after purchase).
|
|
16
|
+
* MEDIA / AVATAR / BANNER = preview assets.
|
|
17
|
+
*/
|
|
18
|
+
export enum UploadKind {
|
|
19
|
+
UPLOAD_KIND_UNSPECIFIED = 0,
|
|
20
|
+
UPLOAD_KIND_ATTACHMENT = 1,
|
|
21
|
+
UPLOAD_KIND_MEDIA = 2,
|
|
22
|
+
UPLOAD_KIND_AVATAR = 3,
|
|
23
|
+
UPLOAD_KIND_BANNER = 4,
|
|
24
|
+
UNRECOGNIZED = -1,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface Ok {
|
|
28
|
+
ok: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface CreateMultipartUploadRequest {
|
|
32
|
+
fileName: string;
|
|
16
33
|
mimeType: string;
|
|
17
|
-
|
|
18
|
-
|
|
34
|
+
fileSize: number;
|
|
35
|
+
kind: UploadKind;
|
|
36
|
+
/** user initiating, for key namespacing + audit */
|
|
37
|
+
ownerId: string;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CreateMultipartUploadResponse {
|
|
41
|
+
/** S3 multipart UploadId */
|
|
19
42
|
uploadId: string;
|
|
43
|
+
/** object key this service generated */
|
|
44
|
+
fileKey: string;
|
|
45
|
+
/** recommended part size (bytes) the client should slice with */
|
|
46
|
+
partSize: number;
|
|
47
|
+
/** number of parts for file_size at part_size */
|
|
48
|
+
partCount: number;
|
|
20
49
|
}
|
|
21
50
|
|
|
22
|
-
export interface
|
|
23
|
-
|
|
24
|
-
success: boolean;
|
|
25
|
-
message: string;
|
|
51
|
+
export interface SignPartRequest {
|
|
52
|
+
fileKey: string;
|
|
26
53
|
uploadId: string;
|
|
54
|
+
/** 1-based */
|
|
55
|
+
partNumber: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface SignPartResponse {
|
|
59
|
+
/** presigned PUT URL for this single part */
|
|
60
|
+
url: string;
|
|
61
|
+
expiresIn: number;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export interface CompletedPart {
|
|
65
|
+
partNumber: number;
|
|
66
|
+
/** ETag the client received in the S3 PUT response header for this part */
|
|
67
|
+
etag: string;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface CompleteMultipartUploadRequest {
|
|
71
|
+
fileKey: string;
|
|
72
|
+
uploadId: string;
|
|
73
|
+
parts: CompletedPart[];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface CompleteMultipartUploadResponse {
|
|
77
|
+
fileKey: string;
|
|
78
|
+
/** final object location (internal reference) */
|
|
79
|
+
location: string;
|
|
27
80
|
fileSize: number;
|
|
28
81
|
}
|
|
29
82
|
|
|
30
|
-
export interface
|
|
83
|
+
export interface AbortMultipartUploadRequest {
|
|
84
|
+
fileKey: string;
|
|
31
85
|
uploadId: string;
|
|
32
86
|
}
|
|
33
87
|
|
|
34
|
-
export interface
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
88
|
+
export interface CreateUploadUrlRequest {
|
|
89
|
+
fileName: string;
|
|
90
|
+
mimeType: string;
|
|
91
|
+
kind: UploadKind;
|
|
92
|
+
ownerId: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface CreateUploadUrlResponse {
|
|
96
|
+
/** presigned PUT URL (client PUTs the whole file) */
|
|
97
|
+
url: string;
|
|
98
|
+
fileKey: string;
|
|
99
|
+
expiresIn: number;
|
|
38
100
|
}
|
|
39
101
|
|
|
40
102
|
export interface SignedUrlRequest {
|
|
41
103
|
fileKey: string;
|
|
104
|
+
/** optional, default 3600 */
|
|
42
105
|
expiresIn: number;
|
|
106
|
+
/** optional: forces Content-Disposition attachment filename */
|
|
107
|
+
downloadFileName: string;
|
|
43
108
|
}
|
|
44
109
|
|
|
45
110
|
export interface SignedUrlResponse {
|
|
46
111
|
signedUrl: string;
|
|
47
|
-
|
|
48
|
-
|
|
112
|
+
expiresIn: number;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface DeleteObjectRequest {
|
|
116
|
+
fileKey: string;
|
|
49
117
|
}
|
|
50
118
|
|
|
51
119
|
export const UPLOAD_V1_PACKAGE_NAME = "upload.v1";
|
|
52
120
|
|
|
53
121
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
122
|
+
* Thin signing service. File bytes NEVER pass through this service — clients
|
|
123
|
+
* upload/download directly to/from S3 (Yandex Object Storage) using presigned
|
|
124
|
+
* URLs this service mints. Memory/bandwidth flat regardless of file size.
|
|
125
|
+
*
|
|
126
|
+
* Large files (product deliverables, up to ~1GB) use the multipart flow:
|
|
127
|
+
* CreateMultipartUpload → (SignPart × N, client PUTs each part to S3) →
|
|
128
|
+
* CompleteMultipartUpload (or AbortMultipartUpload on failure)
|
|
129
|
+
*
|
|
130
|
+
* Small files (preview images, avatars) use the single-PUT flow: CreateUploadUrl.
|
|
131
|
+
*
|
|
132
|
+
* Downloads are gated elsewhere (products-service verifies purchase, then calls
|
|
133
|
+
* GenerateSignedUrl). This service does not know about purchases.
|
|
56
134
|
*/
|
|
57
135
|
|
|
58
136
|
export interface UploadServiceClient {
|
|
59
|
-
|
|
137
|
+
createMultipartUpload(request: CreateMultipartUploadRequest): Observable<CreateMultipartUploadResponse>;
|
|
138
|
+
|
|
139
|
+
signPart(request: SignPartRequest): Observable<SignPartResponse>;
|
|
140
|
+
|
|
141
|
+
completeMultipartUpload(request: CompleteMultipartUploadRequest): Observable<CompleteMultipartUploadResponse>;
|
|
142
|
+
|
|
143
|
+
abortMultipartUpload(request: AbortMultipartUploadRequest): Observable<Ok>;
|
|
60
144
|
|
|
61
|
-
|
|
145
|
+
createUploadUrl(request: CreateUploadUrlRequest): Observable<CreateUploadUrlResponse>;
|
|
62
146
|
|
|
63
147
|
generateSignedUrl(request: SignedUrlRequest): Observable<SignedUrlResponse>;
|
|
148
|
+
|
|
149
|
+
deleteObject(request: DeleteObjectRequest): Observable<Ok>;
|
|
64
150
|
}
|
|
65
151
|
|
|
66
152
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
153
|
+
* Thin signing service. File bytes NEVER pass through this service — clients
|
|
154
|
+
* upload/download directly to/from S3 (Yandex Object Storage) using presigned
|
|
155
|
+
* URLs this service mints. Memory/bandwidth flat regardless of file size.
|
|
156
|
+
*
|
|
157
|
+
* Large files (product deliverables, up to ~1GB) use the multipart flow:
|
|
158
|
+
* CreateMultipartUpload → (SignPart × N, client PUTs each part to S3) →
|
|
159
|
+
* CompleteMultipartUpload (or AbortMultipartUpload on failure)
|
|
160
|
+
*
|
|
161
|
+
* Small files (preview images, avatars) use the single-PUT flow: CreateUploadUrl.
|
|
162
|
+
*
|
|
163
|
+
* Downloads are gated elsewhere (products-service verifies purchase, then calls
|
|
164
|
+
* GenerateSignedUrl). This service does not know about purchases.
|
|
69
165
|
*/
|
|
70
166
|
|
|
71
167
|
export interface UploadServiceController {
|
|
72
|
-
|
|
168
|
+
createMultipartUpload(
|
|
169
|
+
request: CreateMultipartUploadRequest,
|
|
170
|
+
): Promise<CreateMultipartUploadResponse> | Observable<CreateMultipartUploadResponse> | CreateMultipartUploadResponse;
|
|
171
|
+
|
|
172
|
+
signPart(request: SignPartRequest): Promise<SignPartResponse> | Observable<SignPartResponse> | SignPartResponse;
|
|
173
|
+
|
|
174
|
+
completeMultipartUpload(
|
|
175
|
+
request: CompleteMultipartUploadRequest,
|
|
176
|
+
):
|
|
177
|
+
| Promise<CompleteMultipartUploadResponse>
|
|
178
|
+
| Observable<CompleteMultipartUploadResponse>
|
|
179
|
+
| CompleteMultipartUploadResponse;
|
|
73
180
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
181
|
+
abortMultipartUpload(request: AbortMultipartUploadRequest): Promise<Ok> | Observable<Ok> | Ok;
|
|
182
|
+
|
|
183
|
+
createUploadUrl(
|
|
184
|
+
request: CreateUploadUrlRequest,
|
|
185
|
+
): Promise<CreateUploadUrlResponse> | Observable<CreateUploadUrlResponse> | CreateUploadUrlResponse;
|
|
77
186
|
|
|
78
187
|
generateSignedUrl(
|
|
79
188
|
request: SignedUrlRequest,
|
|
80
189
|
): Promise<SignedUrlResponse> | Observable<SignedUrlResponse> | SignedUrlResponse;
|
|
190
|
+
|
|
191
|
+
deleteObject(request: DeleteObjectRequest): Promise<Ok> | Observable<Ok> | Ok;
|
|
81
192
|
}
|
|
82
193
|
|
|
83
194
|
export function UploadServiceControllerMethods() {
|
|
84
195
|
return function (constructor: Function) {
|
|
85
|
-
const grpcMethods: string[] = [
|
|
196
|
+
const grpcMethods: string[] = [
|
|
197
|
+
"createMultipartUpload",
|
|
198
|
+
"signPart",
|
|
199
|
+
"completeMultipartUpload",
|
|
200
|
+
"abortMultipartUpload",
|
|
201
|
+
"createUploadUrl",
|
|
202
|
+
"generateSignedUrl",
|
|
203
|
+
"deleteObject",
|
|
204
|
+
];
|
|
86
205
|
for (const method of grpcMethods) {
|
|
87
206
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
88
207
|
GrpcMethod("UploadService", method)(constructor.prototype[method], method, descriptor);
|
|
89
208
|
}
|
|
90
|
-
const grpcStreamMethods: string[] = [
|
|
209
|
+
const grpcStreamMethods: string[] = [];
|
|
91
210
|
for (const method of grpcStreamMethods) {
|
|
92
211
|
const descriptor: any = Reflect.getOwnPropertyDescriptor(constructor.prototype, method);
|
|
93
212
|
GrpcStreamMethod("UploadService", method)(constructor.prototype[method], method, descriptor);
|
package/package.json
CHANGED
package/proto/upload.proto
CHANGED
|
@@ -2,48 +2,134 @@ syntax = "proto3";
|
|
|
2
2
|
|
|
3
3
|
package upload.v1;
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
//
|
|
5
|
+
// Thin signing service. File bytes NEVER pass through this service — clients
|
|
6
|
+
// upload/download directly to/from S3 (Yandex Object Storage) using presigned
|
|
7
|
+
// URLs this service mints. Memory/bandwidth flat regardless of file size.
|
|
8
|
+
//
|
|
9
|
+
// Large files (product deliverables, up to ~1GB) use the multipart flow:
|
|
10
|
+
// CreateMultipartUpload → (SignPart × N, client PUTs each part to S3) →
|
|
11
|
+
// CompleteMultipartUpload (or AbortMultipartUpload on failure)
|
|
12
|
+
//
|
|
13
|
+
// Small files (preview images, avatars) use the single-PUT flow: CreateUploadUrl.
|
|
14
|
+
//
|
|
15
|
+
// Downloads are gated elsewhere (products-service verifies purchase, then calls
|
|
16
|
+
// GenerateSignedUrl). This service does not know about purchases.
|
|
7
17
|
service UploadService {
|
|
8
|
-
rpc
|
|
9
|
-
rpc
|
|
18
|
+
rpc CreateMultipartUpload(CreateMultipartUploadRequest) returns (CreateMultipartUploadResponse);
|
|
19
|
+
rpc SignPart(SignPartRequest) returns (SignPartResponse);
|
|
20
|
+
rpc CompleteMultipartUpload(CompleteMultipartUploadRequest) returns (CompleteMultipartUploadResponse);
|
|
21
|
+
rpc AbortMultipartUpload(AbortMultipartUploadRequest) returns (Ok);
|
|
22
|
+
|
|
23
|
+
rpc CreateUploadUrl(CreateUploadUrlRequest) returns (CreateUploadUrlResponse);
|
|
24
|
+
|
|
10
25
|
rpc GenerateSignedUrl(SignedUrlRequest) returns (SignedUrlResponse);
|
|
26
|
+
|
|
27
|
+
rpc DeleteObject(DeleteObjectRequest) returns (Ok);
|
|
11
28
|
}
|
|
12
29
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
30
|
+
// Determines the object key prefix (and future ACL/privacy policy).
|
|
31
|
+
// ATTACHMENT = paid product deliverable (private; presigned GET only after purchase).
|
|
32
|
+
// MEDIA / AVATAR / BANNER = preview assets.
|
|
33
|
+
enum UploadKind {
|
|
34
|
+
UPLOAD_KIND_UNSPECIFIED = 0;
|
|
35
|
+
UPLOAD_KIND_ATTACHMENT = 1;
|
|
36
|
+
UPLOAD_KIND_MEDIA = 2;
|
|
37
|
+
UPLOAD_KIND_AVATAR = 3;
|
|
38
|
+
UPLOAD_KIND_BANNER = 4;
|
|
20
39
|
}
|
|
21
40
|
|
|
22
|
-
message
|
|
23
|
-
|
|
24
|
-
bool success = 2;
|
|
25
|
-
string message = 3;
|
|
26
|
-
string upload_id = 4;
|
|
27
|
-
int64 file_size = 5;
|
|
41
|
+
message Ok {
|
|
42
|
+
bool ok = 1;
|
|
28
43
|
}
|
|
29
44
|
|
|
30
|
-
|
|
31
|
-
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
// Multipart upload (large files)
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
|
|
49
|
+
message CreateMultipartUploadRequest {
|
|
50
|
+
string file_name = 1;
|
|
51
|
+
string mime_type = 2;
|
|
52
|
+
int64 file_size = 3;
|
|
53
|
+
UploadKind kind = 4;
|
|
54
|
+
string owner_id = 5; // user initiating, for key namespacing + audit
|
|
32
55
|
}
|
|
33
56
|
|
|
34
|
-
message
|
|
35
|
-
string
|
|
36
|
-
|
|
37
|
-
|
|
57
|
+
message CreateMultipartUploadResponse {
|
|
58
|
+
string upload_id = 1; // S3 multipart UploadId
|
|
59
|
+
string file_key = 2; // object key this service generated
|
|
60
|
+
int64 part_size = 3; // recommended part size (bytes) the client should slice with
|
|
61
|
+
int32 part_count = 4; // number of parts for file_size at part_size
|
|
38
62
|
}
|
|
39
63
|
|
|
40
|
-
message
|
|
64
|
+
message SignPartRequest {
|
|
41
65
|
string file_key = 1;
|
|
66
|
+
string upload_id = 2;
|
|
67
|
+
int32 part_number = 3; // 1-based
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
message SignPartResponse {
|
|
71
|
+
string url = 1; // presigned PUT URL for this single part
|
|
42
72
|
int32 expires_in = 2;
|
|
43
73
|
}
|
|
44
74
|
|
|
75
|
+
message CompletedPart {
|
|
76
|
+
int32 part_number = 1;
|
|
77
|
+
string etag = 2; // ETag the client received in the S3 PUT response header for this part
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
message CompleteMultipartUploadRequest {
|
|
81
|
+
string file_key = 1;
|
|
82
|
+
string upload_id = 2;
|
|
83
|
+
repeated CompletedPart parts = 3;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
message CompleteMultipartUploadResponse {
|
|
87
|
+
string file_key = 1;
|
|
88
|
+
string location = 2; // final object location (internal reference)
|
|
89
|
+
int64 file_size = 3;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
message AbortMultipartUploadRequest {
|
|
93
|
+
string file_key = 1;
|
|
94
|
+
string upload_id = 2;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Single-PUT upload (small files)
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
message CreateUploadUrlRequest {
|
|
102
|
+
string file_name = 1;
|
|
103
|
+
string mime_type = 2;
|
|
104
|
+
UploadKind kind = 3;
|
|
105
|
+
string owner_id = 4;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
message CreateUploadUrlResponse {
|
|
109
|
+
string url = 1; // presigned PUT URL (client PUTs the whole file)
|
|
110
|
+
string file_key = 2;
|
|
111
|
+
int32 expires_in = 3;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ---------------------------------------------------------------------------
|
|
115
|
+
// Download
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
message SignedUrlRequest {
|
|
119
|
+
string file_key = 1;
|
|
120
|
+
int32 expires_in = 2; // optional, default 3600
|
|
121
|
+
string download_file_name = 3; // optional: forces Content-Disposition attachment filename
|
|
122
|
+
}
|
|
123
|
+
|
|
45
124
|
message SignedUrlResponse {
|
|
46
125
|
string signed_url = 1;
|
|
47
|
-
|
|
48
|
-
|
|
126
|
+
int32 expires_in = 2;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Cleanup
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
|
|
133
|
+
message DeleteObjectRequest {
|
|
134
|
+
string file_key = 1;
|
|
49
135
|
}
|