@bejibun/core 0.1.62 → 0.1.64
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/CHANGELOG.md +64 -0
- package/README.md +551 -18
- package/builders/StorageBuilder.d.ts +14 -7
- package/builders/StorageBuilder.js +100 -19
- package/config/disk.d.ts +2 -0
- package/config/disk.js +17 -0
- package/enums/DiskDriverEnum.d.ts +5 -0
- package/enums/DiskDriverEnum.js +6 -0
- package/enums/index.d.ts +1 -0
- package/enums/index.js +1 -0
- package/exceptions/DiskException.d.ts +4 -0
- package/exceptions/DiskException.js +14 -0
- package/facades/Storage.d.ts +9 -1
- package/facades/Storage.js +20 -8
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +2 -2
- package/types/index.d.ts +1 -0
- package/types/storage.d.ts +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,70 @@ All notable changes to this project will be documented in this file.
|
|
|
3
3
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
## [v0.1.64](https://github.com/crenata/bejibun-core/compare/v0.1.61...v0.1.64) - 2025-12-25
|
|
7
|
+
|
|
8
|
+
### 🩹 Fixes
|
|
9
|
+
|
|
10
|
+
### 📖 Changes
|
|
11
|
+
#### What's New :
|
|
12
|
+
#### Storage
|
|
13
|
+
A filesystem facade, with built-in disk management including disks configuration and build disk at runtime.
|
|
14
|
+
|
|
15
|
+
- Standard Use
|
|
16
|
+
```ts
|
|
17
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
18
|
+
|
|
19
|
+
await Storage.exists("path/to/your/file.ext"); // Check if the file exists
|
|
20
|
+
await Storage.missing("path/to/your/file.ext"); // Check if the file doesn't exists
|
|
21
|
+
await Storage.get("path/to/your/file.ext"); // Get data content
|
|
22
|
+
await Storage.put("path/to/your/file.ext", "content"); // Store content to file
|
|
23
|
+
await Storage.delete("path/to/your/file.ext"); // Delete file
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
- With Specified Disk
|
|
27
|
+
```ts
|
|
28
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
29
|
+
|
|
30
|
+
await Storage.disk("public").exists("path/to/your/file.ext");
|
|
31
|
+
await Storage.disk("public").missing("path/to/your/file.ext");
|
|
32
|
+
await Storage.disk("public").get("path/to/your/file.ext");
|
|
33
|
+
await Storage.disk("public").put("path/to/your/file.ext", "content");
|
|
34
|
+
await Storage.disk("public").delete("path/to/your/file.ext");
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- New Disk at Runtime
|
|
38
|
+
```ts
|
|
39
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
40
|
+
|
|
41
|
+
await Storage.build({
|
|
42
|
+
driver: "local", // "local" | DiskDriverEnum.Local
|
|
43
|
+
root: App.Path.storagePath("custom")
|
|
44
|
+
}).exists("path/to/your/file.ext");
|
|
45
|
+
await Storage.build({
|
|
46
|
+
driver: "local",
|
|
47
|
+
root: App.Path.storagePath("custom")
|
|
48
|
+
}).missing("path/to/your/file.ext");
|
|
49
|
+
await Storage.build({
|
|
50
|
+
driver: "local",
|
|
51
|
+
root: App.Path.storagePath("custom")
|
|
52
|
+
}).get("path/to/your/file.ext");
|
|
53
|
+
await Storage.build({
|
|
54
|
+
driver: "local",
|
|
55
|
+
root: App.Path.storagePath("custom")
|
|
56
|
+
}).put("path/to/your/file.ext", "content");
|
|
57
|
+
await Storage.build({
|
|
58
|
+
driver: "local",
|
|
59
|
+
root: App.Path.storagePath("custom")
|
|
60
|
+
}).delete("path/to/your/file.ext");
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### ❤️Contributors
|
|
64
|
+
- Havea Crenata ([@crenata](https://github.com/crenata))
|
|
65
|
+
|
|
66
|
+
**Full Changelog**: https://github.com/crenata/bejibun-core/blob/master/CHANGELOG.md
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
6
70
|
## [v0.1.61](https://github.com/crenata/bejibun-core/compare/v0.1.58...v0.1.61) - 2025-12-12
|
|
7
71
|
|
|
8
72
|
### 🩹 Fixes
|
package/README.md
CHANGED
|
@@ -22,6 +22,557 @@ Install the package.
|
|
|
22
22
|
bun add @bejibun/core
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
### Available Commands
|
|
26
|
+
To see list of available commands, run.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bun ace
|
|
30
|
+
bun ace help
|
|
31
|
+
bun ace --h
|
|
32
|
+
bun ace --help
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
To see help of specific command, run :
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
bun ace help migrate:latest
|
|
39
|
+
bun ace migrate:latest --h
|
|
40
|
+
bun ace migrate:latest --help
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Database
|
|
44
|
+
|
|
45
|
+
#### Migrations
|
|
46
|
+
To fresh or drop all table and re-run the migrations, run :
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bun ace migrate:fresh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Example :
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
This will DROP ALL tables and re-run ALL migrations. Are you want to continue? (Y/N): Y
|
|
56
|
+
|
|
57
|
+
✔ Rolled back all migrations
|
|
58
|
+
✔ Batch 1 finished
|
|
59
|
+
✔ 20250929_000001_tests.ts
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
To migrate the migrations, run :
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bun ace migrate:latest
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Example :
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
✔ Batch 1 finished
|
|
72
|
+
✔ 20250929_000001_tests.ts
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
To rollback the migrations, run :
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
bun ace migrate:rollback
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Example :
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
This will ROLLBACK latest migrations. Are you want to continue? (Y/N): Y
|
|
85
|
+
|
|
86
|
+
✔ Batch 1 finished
|
|
87
|
+
✔ 20250929_000001_tests.ts
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
To see migrations status, run :
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
bun ace migrate:status
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Example :
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
✔ Completed Migrations :
|
|
100
|
+
✔ No migrations were completed.
|
|
101
|
+
|
|
102
|
+
✔ Pending Migrations :
|
|
103
|
+
✔ 20250929_000001_tests.ts
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Seeders
|
|
107
|
+
To execute seeder, run :
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
bun ace db:seed
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Example :
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
✔ Seeding finished
|
|
117
|
+
✔ 20250929_000001_seeder_test.ts
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Features
|
|
121
|
+
|
|
122
|
+
### Controllers
|
|
123
|
+
Logical processes
|
|
124
|
+
|
|
125
|
+
Example :
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
129
|
+
|
|
130
|
+
export default class HelloController extends BaseController {
|
|
131
|
+
public async hello(request: Bun.BunRequest): Promise<Response> {
|
|
132
|
+
return super.response.setData({
|
|
133
|
+
message: "Hello, world!",
|
|
134
|
+
method: request.method
|
|
135
|
+
}).send();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Exception Handler
|
|
141
|
+
Handle any incoming errors
|
|
142
|
+
|
|
143
|
+
Example :
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
import ExceptionHandler from "@bejibun/core/exceptions/ExceptionHandler";
|
|
147
|
+
|
|
148
|
+
export default class Handler extends ExceptionHandler {
|
|
149
|
+
public handle(error: any): globalThis.Response {
|
|
150
|
+
// Your code goes here
|
|
151
|
+
return super.handle(error);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Middlewares
|
|
157
|
+
Handle any request before forwarding to controller
|
|
158
|
+
|
|
159
|
+
Example :
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import type {HandlerType} from "@bejibun/core/types";
|
|
163
|
+
import Logger from "@bejibun/logger";
|
|
164
|
+
|
|
165
|
+
export default class TestMiddleware {
|
|
166
|
+
public handle(handler: HandlerType): HandlerType {
|
|
167
|
+
return async (request: Bun.BunRequest) => {
|
|
168
|
+
Logger.setContext("TestMiddleware").debug(request.url);
|
|
169
|
+
|
|
170
|
+
return handler(request);
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Usage :
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
import Router from "@bejibun/core/facades/Router";
|
|
180
|
+
import TestMiddleware from "@/app/middlewares/TestMiddleware";
|
|
181
|
+
import LoggerMiddleware from "@/app/middlewares/LoggerMiddleware";
|
|
182
|
+
|
|
183
|
+
export default Router.prefix("test")
|
|
184
|
+
.middleware(
|
|
185
|
+
new TestMiddleware(),
|
|
186
|
+
new LoggerMiddleware()
|
|
187
|
+
)
|
|
188
|
+
.group([
|
|
189
|
+
Router.get("redis", "TestController@redis"),
|
|
190
|
+
Router.get("get", "TestController@get"),
|
|
191
|
+
Router.get("detail/:id", "TestController@detail"),
|
|
192
|
+
Router.post("add", "TestController@add"),
|
|
193
|
+
Router.post("edit", "TestController@edit"),
|
|
194
|
+
Router.delete("delete/:id", "TestController@delete"),
|
|
195
|
+
Router.get("restore/:id", "TestController@restore")
|
|
196
|
+
]);
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Validators
|
|
200
|
+
Validate any incoming requests
|
|
201
|
+
|
|
202
|
+
Example :
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import type {ValidatorType} from "@bejibun/core/types/ValidatorType";
|
|
206
|
+
import BaseValidator from "@bejibun/core/bases/BaseValidator";
|
|
207
|
+
import TestModel from "@/app/models/TestModel";
|
|
208
|
+
|
|
209
|
+
export default class TestValidator extends BaseValidator {
|
|
210
|
+
public static get detail(): ValidatorType {
|
|
211
|
+
return super.validator.compile(
|
|
212
|
+
super.validator.object({
|
|
213
|
+
id: super.validator.number().min(1).exists(TestModel, "id")
|
|
214
|
+
})
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
public static get add(): ValidatorType {
|
|
219
|
+
return super.validator.compile(
|
|
220
|
+
super.validator.object({
|
|
221
|
+
name: super.validator.string()
|
|
222
|
+
})
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
public static get edit(): ValidatorType {
|
|
227
|
+
return super.validator.compile(
|
|
228
|
+
super.validator.object({
|
|
229
|
+
id: super.validator.number().min(1).exists(TestModel, "id"),
|
|
230
|
+
name: super.validator.string()
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public static get delete(): ValidatorType {
|
|
236
|
+
return super.validator.compile(
|
|
237
|
+
super.validator.object({
|
|
238
|
+
id: super.validator.number().min(1).exists(TestModel, "id")
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
public static get restore(): ValidatorType {
|
|
244
|
+
return super.validator.compile(
|
|
245
|
+
super.validator.object({
|
|
246
|
+
id: super.validator.number().min(1).exists(TestModel, "id", true)
|
|
247
|
+
})
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Usage :
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
257
|
+
import TestModel from "@/app/models/TestModel";
|
|
258
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
259
|
+
|
|
260
|
+
export default class TestController extends BaseController {
|
|
261
|
+
public async detail(request: Bun.BunRequest): Promise<Response> {
|
|
262
|
+
const body = await super.parse(request);
|
|
263
|
+
await super.validate(TestValidator.detail, body);
|
|
264
|
+
|
|
265
|
+
const test = await TestModel.findOrFail(body.id as number | string);
|
|
266
|
+
|
|
267
|
+
return super.response.setData(test).send();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Models
|
|
273
|
+
Database table model
|
|
274
|
+
|
|
275
|
+
Example :
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import BaseModel, {BaseColumns} from "@bejibun/core/bases/BaseModel";
|
|
279
|
+
import {DateTime} from "luxon";
|
|
280
|
+
|
|
281
|
+
export interface TestColumns extends BaseColumns {
|
|
282
|
+
name: string;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export default class TestModel extends BaseModel implements TestColumns {
|
|
286
|
+
public static tableName: string = "tests";
|
|
287
|
+
public static idColumn: string = "id";
|
|
288
|
+
|
|
289
|
+
declare id: bigint;
|
|
290
|
+
declare name: string;
|
|
291
|
+
declare created_at: DateTime | string;
|
|
292
|
+
declare updated_at: DateTime | string;
|
|
293
|
+
declare deleted_at: DateTime | string | null;
|
|
294
|
+
}
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
#### Fetch All
|
|
298
|
+
Example :
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
302
|
+
import TestModel from "@/app/models/TestModel";
|
|
303
|
+
|
|
304
|
+
export default class TestController extends BaseController {
|
|
305
|
+
public async get(request: Bun.BunRequest): Promise<Response> {
|
|
306
|
+
const tests = await TestModel.all();
|
|
307
|
+
|
|
308
|
+
return super.response.setData(tests).send();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
#### Find or Fail
|
|
314
|
+
Example :
|
|
315
|
+
|
|
316
|
+
```ts
|
|
317
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
318
|
+
import TestModel from "@/app/models/TestModel";
|
|
319
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
320
|
+
|
|
321
|
+
export default class TestController extends BaseController {
|
|
322
|
+
public async detail(request: Bun.BunRequest): Promise<Response> {
|
|
323
|
+
const body = await super.parse(request);
|
|
324
|
+
await super.validate(TestValidator.detail, body);
|
|
325
|
+
|
|
326
|
+
const test = await TestModel.findOrFail(body.id as number | string);
|
|
327
|
+
|
|
328
|
+
return super.response.setData(test).send();
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
#### Create
|
|
334
|
+
Example :
|
|
335
|
+
|
|
336
|
+
```ts
|
|
337
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
338
|
+
import TestModel from "@/app/models/TestModel";
|
|
339
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
340
|
+
|
|
341
|
+
export default class TestController extends BaseController {
|
|
342
|
+
public async add(request: Bun.BunRequest): Promise<Response> {
|
|
343
|
+
const body = await super.parse(request);
|
|
344
|
+
await super.validate(TestValidator.add, body);
|
|
345
|
+
|
|
346
|
+
const tests = await TestModel.create({
|
|
347
|
+
name: body.name as string
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
return super.response.setData(tests).send();
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
#### Update
|
|
356
|
+
Example :
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
360
|
+
import TestModel from "@/app/models/TestModel";
|
|
361
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
362
|
+
|
|
363
|
+
export default class TestController extends BaseController {
|
|
364
|
+
public async edit(request: Bun.BunRequest): Promise<Response> {
|
|
365
|
+
const body = await super.parse(request);
|
|
366
|
+
await super.validate(TestValidator.edit, body);
|
|
367
|
+
|
|
368
|
+
const tests = await TestModel.find(body.id as number | string)
|
|
369
|
+
.update({
|
|
370
|
+
name: body.name as string
|
|
371
|
+
});
|
|
372
|
+
|
|
373
|
+
return super.response.setData(tests).send();
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
#### Soft Delete
|
|
379
|
+
Example :
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
383
|
+
import TestModel from "@/app/models/TestModel";
|
|
384
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
385
|
+
|
|
386
|
+
export default class TestController extends BaseController {
|
|
387
|
+
public async delete(request: Bun.BunRequest): Promise<Response> {
|
|
388
|
+
const body = await super.parse(request);
|
|
389
|
+
await super.validate(TestValidator.delete, body);
|
|
390
|
+
|
|
391
|
+
const tests = await TestModel.find(body.id as number | string).delete();
|
|
392
|
+
|
|
393
|
+
return super.response.setData(tests).send();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
#### Force Delete
|
|
399
|
+
Example :
|
|
400
|
+
|
|
401
|
+
```ts
|
|
402
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
403
|
+
import TestModel from "@/app/models/TestModel";
|
|
404
|
+
import TestValidator from "@/app/validators/TestValidator";
|
|
405
|
+
|
|
406
|
+
export default class TestController extends BaseController {
|
|
407
|
+
public async delete(request: Bun.BunRequest): Promise<Response> {
|
|
408
|
+
const body = await super.parse(request);
|
|
409
|
+
await super.validate(TestValidator.delete, body);
|
|
410
|
+
|
|
411
|
+
const tests = await TestModel.find(body.id as number | string).forceDelete();
|
|
412
|
+
|
|
413
|
+
return super.response.setData(tests).send();
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### With Trashed
|
|
419
|
+
Example :
|
|
420
|
+
|
|
421
|
+
```ts
|
|
422
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
423
|
+
import TestModel from "@/app/models/TestModel";
|
|
424
|
+
|
|
425
|
+
export default class TestController extends BaseController {
|
|
426
|
+
public async get(request: Bun.BunRequest): Promise<Response> {
|
|
427
|
+
const tests = await TestModel.withTrashed();
|
|
428
|
+
|
|
429
|
+
return super.response.setData(tests).send();
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
#### Only Trashed
|
|
435
|
+
Example :
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
439
|
+
import TestModel from "@/app/models/TestModel";
|
|
440
|
+
|
|
441
|
+
export default class TestController extends BaseController {
|
|
442
|
+
public async get(request: Bun.BunRequest): Promise<Response> {
|
|
443
|
+
const tests = await TestModel.onlyTrashed();
|
|
444
|
+
|
|
445
|
+
return super.response.setData(tests).send();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
#### Restore
|
|
451
|
+
Example :
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import BaseController from "@bejibun/core/bases/BaseController";
|
|
455
|
+
import TestModel from "@/app/models/TestModel";
|
|
456
|
+
|
|
457
|
+
export default class TestController extends BaseController {
|
|
458
|
+
public async restore(request: Bun.BunRequest): Promise<Response> {
|
|
459
|
+
const body = await super.parse(request);
|
|
460
|
+
await super.validate(TestValidator.restore, body);
|
|
461
|
+
|
|
462
|
+
const tests = await TestModel.find(body.id as number | string).restore();
|
|
463
|
+
|
|
464
|
+
return super.response.setData(tests).send();
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Database
|
|
470
|
+
|
|
471
|
+
#### Migrations
|
|
472
|
+
Example :
|
|
473
|
+
|
|
474
|
+
```ts
|
|
475
|
+
import type {Knex} from "knex";
|
|
476
|
+
import TestModel from "@/app/models/TestModel";
|
|
477
|
+
|
|
478
|
+
export function up(knex: Knex): void {
|
|
479
|
+
return knex.schema.createTable(TestModel.table, (table: Knex.TableBuilder) => {
|
|
480
|
+
table.bigIncrements("id");
|
|
481
|
+
table.string("name");
|
|
482
|
+
table.timestamps(true, true);
|
|
483
|
+
table.timestamp("deleted_at");
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export function down(knex: Knex): void {
|
|
488
|
+
return knex.schema.dropTable(TestModel.table);
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
#### Seeders
|
|
493
|
+
Example :
|
|
494
|
+
|
|
495
|
+
```ts
|
|
496
|
+
import type {Knex} from "knex";
|
|
497
|
+
import TestModel from "@/app/models/TestModel";
|
|
498
|
+
|
|
499
|
+
export async function seed(knex: Knex): Promise<void> {
|
|
500
|
+
for (const name of ["Name 1", "Name 2", "Name 3"]) {
|
|
501
|
+
await TestModel.query(knex).insert({
|
|
502
|
+
name: name
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### Bootstrap
|
|
509
|
+
Any startup loads
|
|
510
|
+
|
|
511
|
+
```ts
|
|
512
|
+
import Database from "@bejibun/database";
|
|
513
|
+
import {Model} from "objection";
|
|
514
|
+
import BaseModel from "@/bases/BaseModel";
|
|
515
|
+
|
|
516
|
+
(BaseModel as any as typeof Model).knex(Database.knex());
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Storage
|
|
520
|
+
A filesystem facade, with built-in disk management including disks configuration and build disk at runtime.
|
|
521
|
+
|
|
522
|
+
- Standard Use
|
|
523
|
+
```ts
|
|
524
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
525
|
+
|
|
526
|
+
await Storage.exists("path/to/your/file.ext"); // Check if the file exists
|
|
527
|
+
await Storage.missing("path/to/your/file.ext"); // Check if the file doesn't exists
|
|
528
|
+
await Storage.get("path/to/your/file.ext"); // Get data content
|
|
529
|
+
await Storage.put("path/to/your/file.ext", "content"); // Store content to file
|
|
530
|
+
await Storage.delete("path/to/your/file.ext"); // Delete file
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
- With Specified Disk
|
|
534
|
+
```ts
|
|
535
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
536
|
+
|
|
537
|
+
await Storage.disk("public").exists("path/to/your/file.ext");
|
|
538
|
+
await Storage.disk("public").missing("path/to/your/file.ext");
|
|
539
|
+
await Storage.disk("public").get("path/to/your/file.ext");
|
|
540
|
+
await Storage.disk("public").put("path/to/your/file.ext", "content");
|
|
541
|
+
await Storage.disk("public").delete("path/to/your/file.ext");
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
- New Disk at Runtime
|
|
545
|
+
```ts
|
|
546
|
+
import Storage from "@bejibun/core/facades/Storage";
|
|
547
|
+
|
|
548
|
+
await Storage.build({
|
|
549
|
+
driver: "local", // "local" | DiskDriverEnum.Local
|
|
550
|
+
root: App.Path.storagePath("custom")
|
|
551
|
+
}).exists("path/to/your/file.ext");
|
|
552
|
+
await Storage.build({
|
|
553
|
+
driver: "local",
|
|
554
|
+
root: App.Path.storagePath("custom")
|
|
555
|
+
}).missing("path/to/your/file.ext");
|
|
556
|
+
await Storage.build({
|
|
557
|
+
driver: "local",
|
|
558
|
+
root: App.Path.storagePath("custom")
|
|
559
|
+
}).get("path/to/your/file.ext");
|
|
560
|
+
await Storage.build({
|
|
561
|
+
driver: "local",
|
|
562
|
+
root: App.Path.storagePath("custom")
|
|
563
|
+
}).put("path/to/your/file.ext", "content");
|
|
564
|
+
await Storage.build({
|
|
565
|
+
driver: "local",
|
|
566
|
+
root: App.Path.storagePath("custom")
|
|
567
|
+
}).delete("path/to/your/file.ext");
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Cors
|
|
571
|
+
Documentation : [@bejibun/cors](https://github.com/crenata/bejibun-cors/blob/master/README.md)
|
|
572
|
+
|
|
573
|
+
### Cache
|
|
574
|
+
Documentation : [@bejibun/cache](https://github.com/crenata/bejibun-cache/blob/master/README.md)
|
|
575
|
+
|
|
25
576
|
### Ace
|
|
26
577
|
Any commands for development
|
|
27
578
|
|
|
@@ -61,24 +612,6 @@ Examples:
|
|
|
61
612
|
$ bun ace migrate:latest
|
|
62
613
|
```
|
|
63
614
|
|
|
64
|
-
### Available Commands
|
|
65
|
-
To see list of available commands, run.
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
bun ace
|
|
69
|
-
bun ace help
|
|
70
|
-
bun ace --h
|
|
71
|
-
bun ace --help
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
To see help of specific command, run :
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
bun ace help migrate:latest
|
|
78
|
-
bun ace migrate:latest --h
|
|
79
|
-
bun ace migrate:latest --help
|
|
80
|
-
```
|
|
81
|
-
|
|
82
615
|
## Contributors
|
|
83
616
|
- [Havea Crenata](mailto:havea.crenata@gmail.com)
|
|
84
617
|
|
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import { StorageDisk } from "../types/storage";
|
|
1
2
|
export default class StorageBuilder {
|
|
2
|
-
protected
|
|
3
|
-
protected
|
|
4
|
-
protected
|
|
3
|
+
protected conf: Record<string, any>;
|
|
4
|
+
protected overrideDisk?: StorageDisk;
|
|
5
|
+
protected drive?: string;
|
|
5
6
|
constructor();
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
private get config();
|
|
8
|
+
private get currentDisk();
|
|
9
|
+
private get driver();
|
|
10
|
+
build(overrideDisk: StorageDisk): StorageBuilder;
|
|
11
|
+
disk(drive: string): StorageBuilder;
|
|
12
|
+
exists(filepath: string): Promise<boolean>;
|
|
13
|
+
missing(filepath: string): Promise<boolean>;
|
|
14
|
+
get(filepath: string): Promise<any>;
|
|
15
|
+
put(filepath: string, content: any): Promise<void>;
|
|
16
|
+
delete(filepath: string): Promise<void>;
|
|
10
17
|
}
|
|
@@ -1,31 +1,112 @@
|
|
|
1
1
|
import App from "@bejibun/app";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
2
|
+
import Logger from "@bejibun/logger";
|
|
3
|
+
import { defineValue, isEmpty } from "@bejibun/utils";
|
|
4
|
+
import Enum from "@bejibun/utils/facades/Enum";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import fs from "fs";
|
|
7
|
+
import DiskConfig from "../config/disk";
|
|
8
|
+
import DiskException from "../exceptions/DiskException";
|
|
9
|
+
import DiskDriverEnum from "../enums/DiskDriverEnum";
|
|
6
10
|
export default class StorageBuilder {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
11
|
+
conf;
|
|
12
|
+
overrideDisk;
|
|
13
|
+
drive;
|
|
10
14
|
constructor() {
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
const configPath = App.Path.configPath("disk.ts");
|
|
16
|
+
let config;
|
|
17
|
+
if (fs.existsSync(configPath))
|
|
18
|
+
config = require(configPath).default;
|
|
19
|
+
else
|
|
20
|
+
config = DiskConfig;
|
|
21
|
+
this.conf = config;
|
|
13
22
|
}
|
|
14
|
-
|
|
15
|
-
this.
|
|
16
|
-
|
|
23
|
+
get config() {
|
|
24
|
+
if (isEmpty(this.conf))
|
|
25
|
+
throw new DiskException("There is no config provided.");
|
|
26
|
+
return this.conf;
|
|
27
|
+
}
|
|
28
|
+
get currentDisk() {
|
|
29
|
+
return defineValue(this.overrideDisk, this.config.disks[defineValue(this.drive, this.config.default)]);
|
|
17
30
|
}
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
get driver() {
|
|
32
|
+
const driver = defineValue(this.currentDisk?.driver);
|
|
33
|
+
if (isEmpty(driver))
|
|
34
|
+
throw new DiskException(`Missing "driver" on disk config.`);
|
|
35
|
+
if (!Enum.setEnums(DiskDriverEnum).hasValue(driver))
|
|
36
|
+
throw new DiskException(`Not supported "driver" disk.`);
|
|
37
|
+
switch (driver) {
|
|
38
|
+
case DiskDriverEnum.Local:
|
|
39
|
+
if (isEmpty(this.currentDisk?.root))
|
|
40
|
+
throw new DiskException(`Missing "root" for "local" disk configuration.`);
|
|
41
|
+
break;
|
|
42
|
+
default:
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
return driver;
|
|
46
|
+
}
|
|
47
|
+
build(overrideDisk) {
|
|
48
|
+
this.overrideDisk = overrideDisk;
|
|
20
49
|
return this;
|
|
21
50
|
}
|
|
22
|
-
|
|
23
|
-
this.
|
|
51
|
+
disk(drive) {
|
|
52
|
+
this.drive = drive;
|
|
24
53
|
return this;
|
|
25
54
|
}
|
|
26
|
-
async
|
|
27
|
-
if (isEmpty(
|
|
28
|
-
|
|
29
|
-
|
|
55
|
+
async exists(filepath) {
|
|
56
|
+
if (isEmpty(filepath))
|
|
57
|
+
throw new DiskException("The file path is required.");
|
|
58
|
+
switch (this.driver) {
|
|
59
|
+
case DiskDriverEnum.Local:
|
|
60
|
+
return await Bun.file(path.resolve(this.currentDisk.root, filepath)).exists();
|
|
61
|
+
default:
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async missing(filepath) {
|
|
66
|
+
if (isEmpty(filepath))
|
|
67
|
+
throw new DiskException("The file path is required.");
|
|
68
|
+
return !await this.exists(filepath);
|
|
69
|
+
}
|
|
70
|
+
async get(filepath) {
|
|
71
|
+
if (isEmpty(filepath))
|
|
72
|
+
throw new DiskException("The file path is required.");
|
|
73
|
+
let data = null;
|
|
74
|
+
switch (this.driver) {
|
|
75
|
+
case DiskDriverEnum.Local:
|
|
76
|
+
data = await Bun.file(path.resolve(this.currentDisk.root, filepath)).text();
|
|
77
|
+
break;
|
|
78
|
+
default:
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return data;
|
|
82
|
+
}
|
|
83
|
+
async put(filepath, content) {
|
|
84
|
+
if (isEmpty(filepath))
|
|
85
|
+
throw new DiskException("The file path is required.");
|
|
86
|
+
if (isEmpty(content))
|
|
87
|
+
throw new DiskException("The content is required.");
|
|
88
|
+
try {
|
|
89
|
+
switch (this.driver) {
|
|
90
|
+
case DiskDriverEnum.Local:
|
|
91
|
+
await Bun.write(path.resolve(this.currentDisk.root, filepath), content);
|
|
92
|
+
break;
|
|
93
|
+
default:
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
Logger.setContext("Storage").error("Something went wrong when saving file.").trace(error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async delete(filepath) {
|
|
102
|
+
if (isEmpty(filepath))
|
|
103
|
+
throw new DiskException("The file path is required.");
|
|
104
|
+
switch (this.driver) {
|
|
105
|
+
case DiskDriverEnum.Local:
|
|
106
|
+
await Bun.file(path.resolve(this.currentDisk.root, filepath)).delete();
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
30
111
|
}
|
|
31
112
|
}
|
package/config/disk.d.ts
ADDED
package/config/disk.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import App from "@bejibun/app";
|
|
2
|
+
import DiskDriverEnum from "../enums/DiskDriverEnum";
|
|
3
|
+
const config = {
|
|
4
|
+
default: "local",
|
|
5
|
+
disks: {
|
|
6
|
+
local: {
|
|
7
|
+
driver: DiskDriverEnum.Local,
|
|
8
|
+
root: App.Path.storagePath("app")
|
|
9
|
+
},
|
|
10
|
+
public: {
|
|
11
|
+
driver: DiskDriverEnum.Local,
|
|
12
|
+
root: App.Path.storagePath("app/public"),
|
|
13
|
+
url: `${Bun.env.APP_URL}/storage/public`
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export default config;
|
package/enums/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../enums/DiskDriverEnum";
|
package/enums/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../enums/DiskDriverEnum";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Logger from "@bejibun/logger";
|
|
2
|
+
import { defineValue } from "@bejibun/utils";
|
|
3
|
+
export default class DiskException extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(message, code) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "DiskException";
|
|
8
|
+
this.code = defineValue(code, 503);
|
|
9
|
+
Logger.setContext(this.name).error(this.message).trace(this.stack);
|
|
10
|
+
if (Error.captureStackTrace) {
|
|
11
|
+
Error.captureStackTrace(this, DiskException);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
package/facades/Storage.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import StorageBuilder from "../builders/StorageBuilder";
|
|
2
|
+
import { StorageDisk } from "../types/storage";
|
|
1
3
|
export default class Storage {
|
|
2
|
-
static
|
|
4
|
+
static build(disk: StorageDisk): StorageBuilder;
|
|
5
|
+
static disk(disk: string): StorageBuilder;
|
|
6
|
+
static exists(path: string): Promise<boolean>;
|
|
7
|
+
static missing(path: string): Promise<boolean>;
|
|
8
|
+
static get(path: string): Promise<any>;
|
|
9
|
+
static put(path: string, content: any): Promise<void>;
|
|
10
|
+
static delete(path: string): Promise<any>;
|
|
3
11
|
}
|
package/facades/Storage.js
CHANGED
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
import { isNotEmpty } from "@bejibun/utils";
|
|
2
1
|
import StorageBuilder from "../builders/StorageBuilder";
|
|
3
2
|
export default class Storage {
|
|
4
|
-
static
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
static build(disk) {
|
|
4
|
+
return new StorageBuilder().build(disk);
|
|
5
|
+
}
|
|
6
|
+
static disk(disk) {
|
|
7
|
+
return new StorageBuilder().disk(disk);
|
|
8
|
+
}
|
|
9
|
+
static async exists(path) {
|
|
10
|
+
return await new StorageBuilder().exists(path);
|
|
11
|
+
}
|
|
12
|
+
static async missing(path) {
|
|
13
|
+
return await new StorageBuilder().missing(path);
|
|
14
|
+
}
|
|
15
|
+
static async get(path) {
|
|
16
|
+
return await new StorageBuilder().get(path);
|
|
17
|
+
}
|
|
18
|
+
static async put(path, content) {
|
|
19
|
+
return await new StorageBuilder().put(path, content);
|
|
20
|
+
}
|
|
21
|
+
static async delete(path) {
|
|
22
|
+
return await new StorageBuilder().delete(path);
|
|
11
23
|
}
|
|
12
24
|
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bejibun/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.64",
|
|
4
4
|
"author": "Havea Crenata <havea.crenata@gmail.com>",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"module": "index.js",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@bejibun/app": "^0.1.22",
|
|
13
|
-
"@bejibun/cache": "^0.1.
|
|
13
|
+
"@bejibun/cache": "^0.1.18",
|
|
14
14
|
"@bejibun/cors": "^0.1.16",
|
|
15
15
|
"@bejibun/database": "^0.1.19",
|
|
16
16
|
"@bejibun/logger": "^0.1.22",
|
package/types/index.d.ts
CHANGED