@23blocks/block-files 3.0.0 → 3.0.1
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/README.md +264 -0
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# @23blocks/block-files
|
|
2
|
+
|
|
3
|
+
Files block for the 23blocks SDK - file uploads, storage, and entity attachments.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@23blocks/block-files)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @23blocks/block-files @23blocks/transport-http
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Overview
|
|
15
|
+
|
|
16
|
+
This package provides file management functionality including:
|
|
17
|
+
|
|
18
|
+
- **Storage Files** - Direct file uploads and management
|
|
19
|
+
- **Entity Files** - Attach files to other entities
|
|
20
|
+
- **File Schemas** - Define file requirements and validations
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { createHttpTransport } from '@23blocks/transport-http';
|
|
26
|
+
import { createFilesBlock } from '@23blocks/block-files';
|
|
27
|
+
|
|
28
|
+
const transport = createHttpTransport({
|
|
29
|
+
baseUrl: 'https://api.yourapp.com',
|
|
30
|
+
headers: () => {
|
|
31
|
+
const token = localStorage.getItem('access_token');
|
|
32
|
+
return token ? { Authorization: `Bearer ${token}` } : {};
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const files = createFilesBlock(transport, {
|
|
37
|
+
apiKey: 'your-api-key',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// List files
|
|
41
|
+
const { data: fileList } = await files.storageFiles.list({ limit: 20 });
|
|
42
|
+
|
|
43
|
+
fileList.forEach((file) => {
|
|
44
|
+
console.log(file.filename, file.size, file.url);
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Services
|
|
49
|
+
|
|
50
|
+
### storageFiles - File Storage
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
// List files
|
|
54
|
+
const { data: fileList, meta } = await files.storageFiles.list({
|
|
55
|
+
limit: 20,
|
|
56
|
+
folder: 'images',
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// Get file by ID
|
|
60
|
+
const file = await files.storageFiles.get('file-id');
|
|
61
|
+
|
|
62
|
+
// Upload file
|
|
63
|
+
const newFile = await files.storageFiles.upload({
|
|
64
|
+
file: fileBlob,
|
|
65
|
+
filename: 'document.pdf',
|
|
66
|
+
folder: 'documents',
|
|
67
|
+
contentType: 'application/pdf',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Create file record (for external URLs)
|
|
71
|
+
const fileRecord = await files.storageFiles.create({
|
|
72
|
+
filename: 'external-image.jpg',
|
|
73
|
+
url: 'https://example.com/image.jpg',
|
|
74
|
+
contentType: 'image/jpeg',
|
|
75
|
+
size: 12345,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Update file metadata
|
|
79
|
+
const updated = await files.storageFiles.update('file-id', {
|
|
80
|
+
filename: 'renamed-document.pdf',
|
|
81
|
+
folder: 'archived',
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Delete file
|
|
85
|
+
await files.storageFiles.delete('file-id');
|
|
86
|
+
|
|
87
|
+
// Get download URL
|
|
88
|
+
const downloadUrl = await files.storageFiles.getDownloadUrl('file-id');
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### entityFiles - Entity Attachments
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// List files attached to an entity
|
|
95
|
+
const { data: attachments } = await files.entityFiles.list({
|
|
96
|
+
entityType: 'product',
|
|
97
|
+
entityId: 'product-123',
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Attach file to entity
|
|
101
|
+
const attachment = await files.entityFiles.attach({
|
|
102
|
+
entityType: 'product',
|
|
103
|
+
entityId: 'product-123',
|
|
104
|
+
fileId: 'file-id',
|
|
105
|
+
position: 1,
|
|
106
|
+
label: 'Main Image',
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Update attachment
|
|
110
|
+
const updated = await files.entityFiles.update('attachment-id', {
|
|
111
|
+
position: 2,
|
|
112
|
+
label: 'Secondary Image',
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Reorder files
|
|
116
|
+
await files.entityFiles.reorder({
|
|
117
|
+
entityType: 'product',
|
|
118
|
+
entityId: 'product-123',
|
|
119
|
+
fileIds: ['file-1', 'file-2', 'file-3'],
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Remove attachment
|
|
123
|
+
await files.entityFiles.delete('attachment-id');
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### fileSchemas - File Schemas
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// List file schemas
|
|
130
|
+
const { data: schemas } = await files.fileSchemas.list();
|
|
131
|
+
|
|
132
|
+
// Get schema by ID
|
|
133
|
+
const schema = await files.fileSchemas.get('schema-id');
|
|
134
|
+
|
|
135
|
+
// Create file schema
|
|
136
|
+
const newSchema = await files.fileSchemas.create({
|
|
137
|
+
name: 'Product Images',
|
|
138
|
+
entityType: 'product',
|
|
139
|
+
allowedTypes: ['image/jpeg', 'image/png', 'image/webp'],
|
|
140
|
+
maxSize: 5 * 1024 * 1024, // 5MB
|
|
141
|
+
maxFiles: 10,
|
|
142
|
+
required: true,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Update schema
|
|
146
|
+
const updated = await files.fileSchemas.update('schema-id', {
|
|
147
|
+
maxFiles: 20,
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// Delete schema
|
|
151
|
+
await files.fileSchemas.delete('schema-id');
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Types
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import type {
|
|
158
|
+
StorageFile,
|
|
159
|
+
EntityFile,
|
|
160
|
+
FileSchema,
|
|
161
|
+
CreateStorageFileRequest,
|
|
162
|
+
UploadFileRequest,
|
|
163
|
+
AttachFileRequest,
|
|
164
|
+
CreateFileSchemaRequest,
|
|
165
|
+
ListStorageFilesParams,
|
|
166
|
+
} from '@23blocks/block-files';
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### StorageFile
|
|
170
|
+
|
|
171
|
+
| Property | Type | Description |
|
|
172
|
+
|----------|------|-------------|
|
|
173
|
+
| `id` | `string` | File ID |
|
|
174
|
+
| `uniqueId` | `string` | Unique identifier |
|
|
175
|
+
| `filename` | `string` | Original filename |
|
|
176
|
+
| `contentType` | `string` | MIME type |
|
|
177
|
+
| `size` | `number` | File size in bytes |
|
|
178
|
+
| `url` | `string` | Public URL |
|
|
179
|
+
| `folder` | `string` | Storage folder |
|
|
180
|
+
| `createdAt` | `Date` | Upload timestamp |
|
|
181
|
+
|
|
182
|
+
### EntityFile
|
|
183
|
+
|
|
184
|
+
| Property | Type | Description |
|
|
185
|
+
|----------|------|-------------|
|
|
186
|
+
| `id` | `string` | Attachment ID |
|
|
187
|
+
| `entityType` | `string` | Type of parent entity |
|
|
188
|
+
| `entityId` | `string` | Parent entity ID |
|
|
189
|
+
| `fileId` | `string` | Attached file ID |
|
|
190
|
+
| `position` | `number` | Display order |
|
|
191
|
+
| `label` | `string` | Display label |
|
|
192
|
+
| `file` | `StorageFile` | File details |
|
|
193
|
+
|
|
194
|
+
### FileSchema
|
|
195
|
+
|
|
196
|
+
| Property | Type | Description |
|
|
197
|
+
|----------|------|-------------|
|
|
198
|
+
| `id` | `string` | Schema ID |
|
|
199
|
+
| `name` | `string` | Schema name |
|
|
200
|
+
| `entityType` | `string` | Entity type this applies to |
|
|
201
|
+
| `allowedTypes` | `string[]` | Allowed MIME types |
|
|
202
|
+
| `maxSize` | `number` | Max file size in bytes |
|
|
203
|
+
| `maxFiles` | `number` | Max number of files |
|
|
204
|
+
| `required` | `boolean` | Whether files are required |
|
|
205
|
+
|
|
206
|
+
## Error Handling
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
import { isBlockErrorException, ErrorCodes } from '@23blocks/contracts';
|
|
210
|
+
|
|
211
|
+
try {
|
|
212
|
+
await files.storageFiles.upload({ file: largeFile, filename: 'huge.zip' });
|
|
213
|
+
} catch (error) {
|
|
214
|
+
if (isBlockErrorException(error)) {
|
|
215
|
+
switch (error.code) {
|
|
216
|
+
case ErrorCodes.VALIDATION_ERROR:
|
|
217
|
+
console.log('File too large or invalid type');
|
|
218
|
+
break;
|
|
219
|
+
case ErrorCodes.FORBIDDEN:
|
|
220
|
+
console.log('Not authorized to upload files');
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Advanced Usage
|
|
228
|
+
|
|
229
|
+
### Uploading with Progress
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
// Use FormData for browser uploads with progress
|
|
233
|
+
async function uploadWithProgress(file: File, onProgress: (percent: number) => void) {
|
|
234
|
+
const formData = new FormData();
|
|
235
|
+
formData.append('file', file);
|
|
236
|
+
formData.append('filename', file.name);
|
|
237
|
+
|
|
238
|
+
return new Promise((resolve, reject) => {
|
|
239
|
+
const xhr = new XMLHttpRequest();
|
|
240
|
+
xhr.upload.onprogress = (e) => {
|
|
241
|
+
if (e.lengthComputable) {
|
|
242
|
+
onProgress((e.loaded / e.total) * 100);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
xhr.onload = () => resolve(JSON.parse(xhr.response));
|
|
246
|
+
xhr.onerror = () => reject(new Error('Upload failed'));
|
|
247
|
+
xhr.open('POST', 'https://api.yourapp.com/files');
|
|
248
|
+
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
|
|
249
|
+
xhr.send(formData);
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Related Packages
|
|
255
|
+
|
|
256
|
+
- [`@23blocks/block-content`](https://www.npmjs.com/package/@23blocks/block-content) - Content management
|
|
257
|
+
- [`@23blocks/block-products`](https://www.npmjs.com/package/@23blocks/block-products) - Product images
|
|
258
|
+
- [`@23blocks/angular`](https://www.npmjs.com/package/@23blocks/angular) - Angular integration
|
|
259
|
+
- [`@23blocks/react`](https://www.npmjs.com/package/@23blocks/react) - React integration
|
|
260
|
+
- [`@23blocks/sdk`](https://www.npmjs.com/package/@23blocks/sdk) - Full SDK package
|
|
261
|
+
|
|
262
|
+
## License
|
|
263
|
+
|
|
264
|
+
MIT - Copyright (c) 2024 23blocks
|
package/package.json
CHANGED