@jrmc/adonis-attachment 5.0.0-beta.3 → 5.0.0-beta.6
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/build/providers/attachment_provider.d.ts.map +1 -1
- package/build/providers/attachment_provider.js +9 -1
- package/build/services/regenerate_service.js +3 -3
- package/build/src/adapters/lock.d.ts +9 -0
- package/build/src/adapters/lock.d.ts.map +1 -0
- package/build/src/adapters/lock.js +21 -0
- package/build/src/adapters/poppler.js +0 -1
- package/build/src/attachment_manager.d.ts +7 -3
- package/build/src/attachment_manager.d.ts.map +1 -1
- package/build/src/attachment_manager.js +15 -50
- package/build/src/attachments/attachment.d.ts +9 -4
- package/build/src/attachments/attachment.d.ts.map +1 -1
- package/build/src/attachments/attachment.js +53 -9
- package/build/src/attachments/attachment_base.d.ts +11 -2
- package/build/src/attachments/attachment_base.d.ts.map +1 -1
- package/build/src/attachments/attachment_base.js +60 -3
- package/build/src/controllers/attachments_controller.d.ts.map +1 -1
- package/build/src/controllers/attachments_controller.js +21 -12
- package/build/src/services/attachment/attachment_detachment_service.d.ts +19 -0
- package/build/src/services/attachment/attachment_detachment_service.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_detachment_service.js +66 -0
- package/build/src/services/attachment/attachment_persister_service.d.ts +22 -0
- package/build/src/services/attachment/attachment_persister_service.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_persister_service.js +95 -0
- package/build/src/services/attachment/attachment_recorder_service.d.ts +68 -0
- package/build/src/services/attachment/attachment_recorder_service.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_recorder_service.js +121 -0
- package/build/src/services/attachment/attachment_transaction_service.d.ts +26 -0
- package/build/src/services/attachment/attachment_transaction_service.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_transaction_service.js +46 -0
- package/build/src/services/attachment/attachment_utils.d.ts +35 -0
- package/build/src/services/attachment/attachment_utils.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_utils.js +71 -0
- package/build/src/services/attachment/attachment_variant_service.d.ts +17 -0
- package/build/src/services/attachment/attachment_variant_service.d.ts.map +1 -0
- package/build/src/services/attachment/attachment_variant_service.js +72 -0
- package/build/src/services/attachment/index.d.ts +15 -0
- package/build/src/services/attachment/index.d.ts.map +1 -0
- package/build/src/services/attachment/index.js +15 -0
- package/build/src/services/attachment_service.d.ts +8 -0
- package/build/src/services/attachment_service.d.ts.map +1 -0
- package/build/src/services/attachment_service.js +7 -0
- package/build/src/services/variant/{variant_generator.d.ts → variant_generator_service.d.ts} +8 -2
- package/build/src/services/variant/variant_generator_service.d.ts.map +1 -0
- package/build/src/services/variant/{variant_generator.js → variant_generator_service.js} +7 -1
- package/build/src/services/variant/{variant_persister.d.ts → variant_persister_service.d.ts} +8 -2
- package/build/src/services/variant/variant_persister_service.d.ts.map +1 -0
- package/build/src/services/variant/{variant_persister.js → variant_persister_service.js} +7 -1
- package/build/src/services/variant/{variant_purger.d.ts → variant_purger_service.d.ts} +7 -1
- package/build/src/services/variant/variant_purger_service.d.ts.map +1 -0
- package/build/src/services/variant/{variant_purger.js → variant_purger_service.js} +6 -0
- package/build/src/services/variant_service.d.ts +6 -0
- package/build/src/services/variant_service.d.ts.map +1 -1
- package/build/src/services/variant_service.js +13 -7
- package/build/src/types/attachment.d.ts +12 -3
- package/build/src/types/attachment.d.ts.map +1 -1
- package/build/src/types/config.d.ts +2 -1
- package/build/src/types/config.d.ts.map +1 -1
- package/build/src/types/index.d.ts +6 -0
- package/build/src/types/index.d.ts.map +1 -1
- package/build/src/types/index.js +6 -0
- package/build/src/types/lock.d.ts +14 -0
- package/build/src/types/lock.d.ts.map +1 -0
- package/build/src/types/lock.js +7 -0
- package/build/src/types/metadata.d.ts +6 -0
- package/build/src/types/metadata.d.ts.map +1 -1
- package/build/src/types/metadata.js +6 -0
- package/build/src/types/regenerate.d.ts +6 -0
- package/build/src/types/regenerate.d.ts.map +1 -1
- package/build/src/types/regenerate.js +6 -0
- package/build/src/types/service.d.ts +7 -1
- package/build/src/types/service.d.ts.map +1 -1
- package/build/src/types/service.js +6 -0
- package/build/src/utils/hooks.js +5 -5
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +32 -23
- package/build/src/services/record_with_attachment.d.ts +0 -33
- package/build/src/services/record_with_attachment.d.ts.map +0 -1
- package/build/src/services/record_with_attachment.js +0 -316
- package/build/src/services/variant/variant_generator.d.ts.map +0 -1
- package/build/src/services/variant/variant_persister.d.ts.map +0 -1
- package/build/src/services/variant/variant_purger.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_provider.d.ts","sourceRoot":"","sources":["../../providers/attachment_provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"attachment_provider.d.ts","sourceRoot":"","sources":["../../providers/attachment_provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAM/D,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAiB,iBAAiB;QAChC,iBAAiB,EAAE,iBAAiB,CAAA;KACrC;CACF;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,MAAM;QACd,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,KAAK,CAAA;KACzC;CACF;AAED,MAAM,CAAC,OAAO,OAAO,kBAAkB;;IAGzB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IA4BF,IAAI;CAQX"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { configProvider } from '@adonisjs/core';
|
|
8
8
|
import { RuntimeException } from '@poppinss/utils';
|
|
9
|
+
import { verrou } from '../src/adapters/lock.js';
|
|
9
10
|
export default class AttachmentProvider {
|
|
10
11
|
app;
|
|
11
12
|
#manager = null;
|
|
@@ -18,7 +19,14 @@ export default class AttachmentProvider {
|
|
|
18
19
|
const attachmentConfig = this.app.config.get('attachment');
|
|
19
20
|
const config = await configProvider.resolve(this.app, attachmentConfig);
|
|
20
21
|
const drive = await this.app.container.make('drive.manager');
|
|
21
|
-
|
|
22
|
+
let lock;
|
|
23
|
+
try {
|
|
24
|
+
const lockManager = await this.app.container.make('lock.manager');
|
|
25
|
+
lock = verrou(lockManager);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
lock = verrou();
|
|
29
|
+
}
|
|
22
30
|
if (!config) {
|
|
23
31
|
throw new RuntimeException('Invalid config exported from "config/attachment.ts" file. Make sure to use the defineConfig method');
|
|
24
32
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { AttachmentRecordService } from '../src/services/attachment/index.js';
|
|
2
2
|
export default class RegenerateService {
|
|
3
3
|
#Model;
|
|
4
4
|
#row;
|
|
@@ -15,13 +15,13 @@ export default class RegenerateService {
|
|
|
15
15
|
}
|
|
16
16
|
async run() {
|
|
17
17
|
if (this.#row) {
|
|
18
|
-
const record = new
|
|
18
|
+
const record = new AttachmentRecordService(this.#row);
|
|
19
19
|
return record.regenerateVariants(this.#options);
|
|
20
20
|
}
|
|
21
21
|
else if (this.#Model) {
|
|
22
22
|
const entities = await this.#Model.all();
|
|
23
23
|
return Promise.all(entities.map(async (entity) => {
|
|
24
|
-
const record = new
|
|
24
|
+
const record = new AttachmentRecordService(entity);
|
|
25
25
|
return record.regenerateVariants(this.#options);
|
|
26
26
|
}));
|
|
27
27
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import type { LockService } from '../types/lock.js';
|
|
8
|
+
export declare const verrou: (lock?: LockService) => LockService;
|
|
9
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../../src/adapters/lock.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKnD,eAAO,MAAM,MAAM,UAAW,WAAW,KAAG,WAW3C,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { Verrou } from '@verrou/core';
|
|
8
|
+
import { memoryStore } from '@verrou/core/drivers/memory';
|
|
9
|
+
export const verrou = (lock) => {
|
|
10
|
+
if (lock) {
|
|
11
|
+
return lock;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
return new Verrou({
|
|
15
|
+
default: 'memory',
|
|
16
|
+
stores: {
|
|
17
|
+
memory: { driver: memoryStore() }
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -85,7 +85,6 @@ export default class Poppler {
|
|
|
85
85
|
if (metadata['creationdate']) {
|
|
86
86
|
const dateStr = metadata['creationdate'];
|
|
87
87
|
const date = DateTime.fromFormat(dateStr, 'EEE MMM dd HH:mm:ss yyyy z', { zone: 'UTC' });
|
|
88
|
-
console.log('Parsed date:', date.toISO());
|
|
89
88
|
if (date.isValid) {
|
|
90
89
|
creationDate = date.toFormat('yyyy-MM-dd\'T\'HH:mm:ss');
|
|
91
90
|
}
|
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
6
|
*/
|
|
7
7
|
import type { DriveService, SignedURLOptions } from '@adonisjs/drive/types';
|
|
8
|
-
import type { LockService } from '@adonisjs/lock/types';
|
|
9
8
|
import type { MultipartFile } from '@adonisjs/core/bodyparser';
|
|
9
|
+
import type { LockService } from './types/lock.js';
|
|
10
10
|
import type { AttachmentAttributes, AttachmentBase, Attachment as AttachmentType } from './types/attachment.js';
|
|
11
11
|
import type { ResolvedAttachmentConfig } from './define_config.js';
|
|
12
12
|
import { DeferQueue } from '@poppinss/defer';
|
|
@@ -14,7 +14,6 @@ import Converter from './converters/converter.js';
|
|
|
14
14
|
export declare class AttachmentManager<KnownConverters extends Record<string, Converter>> {
|
|
15
15
|
#private;
|
|
16
16
|
queue: DeferQueue;
|
|
17
|
-
lock: LockService;
|
|
18
17
|
constructor(config: ResolvedAttachmentConfig<KnownConverters>, drive: DriveService, lock: LockService);
|
|
19
18
|
createFromDbResponse(response?: string | JSON): AttachmentType | null;
|
|
20
19
|
createFromFile(input: MultipartFile): Promise<AttachmentType>;
|
|
@@ -25,6 +24,10 @@ export declare class AttachmentManager<KnownConverters extends Record<string, Co
|
|
|
25
24
|
getVariant(variantName: string): import("./types/attachment.js").Variant | null;
|
|
26
25
|
getUrl(variantName?: string): Promise<string>;
|
|
27
26
|
getSignedUrl(variantNameOrOptions?: string | SignedURLOptions, signedUrlOptions?: SignedURLOptions): Promise<string>;
|
|
27
|
+
preComputeUrl(): Promise<void>;
|
|
28
|
+
moveFileForDelete(): Promise<void>;
|
|
29
|
+
rollbackMoveFileForDelete(): Promise<void>;
|
|
30
|
+
remove(): Promise<void>;
|
|
28
31
|
toObject(): AttachmentAttributes;
|
|
29
32
|
})[]>;
|
|
30
33
|
createFromPath(input: string, name?: string): Promise<AttachmentType>;
|
|
@@ -32,11 +35,12 @@ export declare class AttachmentManager<KnownConverters extends Record<string, Co
|
|
|
32
35
|
createFromBase64(input: string, name?: string): Promise<AttachmentType>;
|
|
33
36
|
createFromUrl(input: URL, name?: string): Promise<AttachmentType>;
|
|
34
37
|
createFromStream(stream: NodeJS.ReadableStream, name?: string): Promise<AttachmentType>;
|
|
35
|
-
getConverter(key: string): Promise<void | Converter>;
|
|
36
38
|
computeUrl(attachment: AttachmentType | AttachmentBase, signedUrlOptions?: SignedURLOptions): Promise<void>;
|
|
37
39
|
preComputeUrl(attachment: AttachmentType): Promise<void>;
|
|
38
40
|
write(attachment: AttachmentBase): Promise<void>;
|
|
39
41
|
remove(attachment: AttachmentBase): Promise<void>;
|
|
42
|
+
get lock(): LockService;
|
|
40
43
|
getConfig(): ResolvedAttachmentConfig<KnownConverters>;
|
|
44
|
+
getConverter(key: string): Promise<void | Converter>;
|
|
41
45
|
}
|
|
42
46
|
//# sourceMappingURL=attachment_manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_manager.d.ts","sourceRoot":"","sources":["../../src/attachment_manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"attachment_manager.d.ts","sourceRoot":"","sources":["../../src/attachment_manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EACV,oBAAoB,EACpB,cAAc,EACd,UAAU,IAAI,cAAc,EAC7B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAA;AAGlE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAG5C,OAAO,SAAS,MAAM,2BAA2B,CAAA;AAQjD,qBAAa,iBAAiB,CAAC,eAAe,SAAS,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC;;IAC9E,KAAK,aAAA;gBAKO,MAAM,EAAE,wBAAwB,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW;IAUrG,oBAAoB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAiBvC,cAAc,CAAC,KAAK,EAAE,aAAa;IAgBnC,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE;;;;;;;;;;;;;IAIvC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAiB3C,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAgB7C,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAW7C,aAAa,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM;IAMvC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,IAAI,CAAC,EAAE,MAAM;IAM7D,UAAU,CACd,UAAU,EAAE,cAAc,GAAG,cAAc,EAC3C,gBAAgB,CAAC,EAAE,gBAAgB;IAK/B,aAAa,CAAC,UAAU,EAAE,cAAc;IAIxC,KAAK,CAAC,UAAU,EAAE,cAAc;IAUhC,MAAM,CAAC,UAAU,EAAE,cAAc;IAMvC,IAAI,IAAI,gBAEP;IAED,SAAS;IAIH,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,SAAS,CAAC;CAuB3D"}
|
|
@@ -17,10 +17,10 @@ export class AttachmentManager {
|
|
|
17
17
|
queue;
|
|
18
18
|
#config;
|
|
19
19
|
#drive;
|
|
20
|
-
lock;
|
|
20
|
+
#lock;
|
|
21
21
|
constructor(config, drive, lock) {
|
|
22
22
|
this.#drive = drive;
|
|
23
|
-
this
|
|
23
|
+
this.#lock = lock;
|
|
24
24
|
this.#config = config;
|
|
25
25
|
const concurrency = this.#config.queue?.concurrency || 1;
|
|
26
26
|
this.queue = new DeferQueue({ concurrency });
|
|
@@ -96,71 +96,36 @@ export class AttachmentManager {
|
|
|
96
96
|
const tmpPath = await streamToTempFile(stream);
|
|
97
97
|
return this.createFromPath(tmpPath, name || path.basename(tmpPath));
|
|
98
98
|
}
|
|
99
|
-
async getConverter(key) {
|
|
100
|
-
if (this.#config.converters) {
|
|
101
|
-
return this.#config.converters[key];
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
99
|
async computeUrl(attachment, signedUrlOptions) {
|
|
105
|
-
|
|
106
|
-
const fileVisibility = await disk.getVisibility(attachment.path);
|
|
107
|
-
if (fileVisibility === 'private') {
|
|
108
|
-
attachment.url = await attachment.getSignedUrl(signedUrlOptions);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
attachment.url = await attachment.getUrl();
|
|
112
|
-
}
|
|
100
|
+
await attachment.computeUrl(signedUrlOptions);
|
|
113
101
|
}
|
|
114
102
|
async preComputeUrl(attachment) {
|
|
115
|
-
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
await this.computeUrl(attachment);
|
|
119
|
-
if (attachment instanceof Attachment && attachment.variants) {
|
|
120
|
-
for (const key in attachment.variants) {
|
|
121
|
-
if (Object.prototype.hasOwnProperty.call(attachment.variants, key)) {
|
|
122
|
-
await this.computeUrl(attachment.variants[key]);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
103
|
+
await attachment.preComputeUrl();
|
|
126
104
|
}
|
|
127
105
|
async write(attachment) {
|
|
128
|
-
const destinationPath = attachment.path;
|
|
129
106
|
if (attachment.options?.meta) {
|
|
130
107
|
attachment.meta = await ExifAdapter.exif(attachment.input, this.#config);
|
|
131
108
|
}
|
|
132
109
|
else {
|
|
133
110
|
attachment.meta = undefined;
|
|
134
111
|
}
|
|
135
|
-
|
|
136
|
-
await attachment.getDisk().put(destinationPath, attachment.input);
|
|
137
|
-
}
|
|
138
|
-
else if (attachment.input) {
|
|
139
|
-
await attachment.getDisk().copyFromFs(attachment.input, destinationPath);
|
|
140
|
-
}
|
|
112
|
+
await attachment.put();
|
|
141
113
|
}
|
|
142
114
|
async remove(attachment) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await attachment.getDisk().deleteAll(variantPath); // not compatible Minio, necessary for fs as not to leave an empty directory
|
|
149
|
-
for (const key in attachment.variants) {
|
|
150
|
-
if (Object.prototype.hasOwnProperty.call(attachment.variants, key)) {
|
|
151
|
-
await attachment.getDisk().delete(attachment.variants[key].path);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
if (attachment.originalPath) {
|
|
158
|
-
await attachment.getDisk().delete(attachment.originalPath);
|
|
159
|
-
}
|
|
115
|
+
await attachment.remove();
|
|
116
|
+
}
|
|
117
|
+
// getters
|
|
118
|
+
get lock() {
|
|
119
|
+
return this.#lock;
|
|
160
120
|
}
|
|
161
121
|
getConfig() {
|
|
162
122
|
return this.#config;
|
|
163
123
|
}
|
|
124
|
+
async getConverter(key) {
|
|
125
|
+
if (this.#config.converters) {
|
|
126
|
+
return this.#config.converters[key];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
164
129
|
// private methods
|
|
165
130
|
#configureAttachment(attachment) {
|
|
166
131
|
if (this.#config.meta !== undefined) {
|
|
@@ -9,14 +9,11 @@ import type { AttachmentAttributes, Attachment as AttachmentInterface, LucidOpti
|
|
|
9
9
|
import type { Input } from '../types/input.js';
|
|
10
10
|
import { AttachmentBase } from './attachment_base.js';
|
|
11
11
|
import { Variant } from './variant_attachment.js';
|
|
12
|
+
import { LucidRow } from '@adonisjs/lucid/types/model';
|
|
12
13
|
export declare class Attachment extends AttachmentBase implements AttachmentInterface {
|
|
13
14
|
originalName: string;
|
|
14
15
|
variants?: Variant[];
|
|
15
16
|
constructor(drive: DriveService, attributes: AttachmentAttributes, input?: Input);
|
|
16
|
-
/**
|
|
17
|
-
* Getters
|
|
18
|
-
*/
|
|
19
|
-
get name(): string;
|
|
20
17
|
/**
|
|
21
18
|
* Methods
|
|
22
19
|
*/
|
|
@@ -25,6 +22,14 @@ export declare class Attachment extends AttachmentBase implements AttachmentInte
|
|
|
25
22
|
getUrl(variantName?: string): Promise<string>;
|
|
26
23
|
getSignedUrl(variantNameOrOptions?: string | SignedURLOptions, signedUrlOptions?: SignedURLOptions): Promise<string>;
|
|
27
24
|
setOptions(options: LucidOptions): this;
|
|
25
|
+
/**
|
|
26
|
+
* Actions
|
|
27
|
+
*/
|
|
28
|
+
preComputeUrl(): Promise<void>;
|
|
29
|
+
makeName(record?: LucidRow, attributeName?: string): Promise<this>;
|
|
30
|
+
moveFileForDelete(): Promise<void>;
|
|
31
|
+
rollbackMoveFileForDelete(): Promise<void>;
|
|
32
|
+
remove(): Promise<void>;
|
|
28
33
|
/**
|
|
29
34
|
*
|
|
30
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../../src/attachments/attachment.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,IAAI,mBAAmB,EACjC,YAAY,EACb,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"attachment.d.ts","sourceRoot":"","sources":["../../../src/attachments/attachment.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EACV,oBAAoB,EACpB,UAAU,IAAI,mBAAmB,EACjC,YAAY,EACb,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAA;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAEtD,qBAAa,UAAW,SAAQ,cAAe,YAAW,mBAAmB;IAC3E,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;gBAER,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,oBAAoB,EAAE,KAAK,CAAC,EAAE,KAAK;IAehF;;OAEG;IAEG,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBhE,UAAU,CAAC,WAAW,EAAE,MAAM;IAIxB,MAAM,CAAC,WAAW,CAAC,EAAE,MAAM;IAe3B,YAAY,CAChB,oBAAoB,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAChD,gBAAgB,CAAC,EAAE,gBAAgB;IAyBrC,UAAU,CAAC,OAAO,EAAE,YAAY;IAkBhC;;OAEG;IAEG,aAAa;IAiBb,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM;IAIlD,iBAAiB;IAWjB,yBAAyB;IAWzB,MAAM;IAkBZ;;OAEG;IAEH,QAAQ,IAAI,oBAAoB;IAUhC,MAAM,IAAI,MAAM;CAsCjB"}
|
|
@@ -22,15 +22,6 @@ export class Attachment extends AttachmentBase {
|
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Getters
|
|
27
|
-
*/
|
|
28
|
-
get name() {
|
|
29
|
-
if (this.options && this.options.rename === false) {
|
|
30
|
-
return this.originalName;
|
|
31
|
-
}
|
|
32
|
-
return super.name;
|
|
33
|
-
}
|
|
34
25
|
/**
|
|
35
26
|
* Methods
|
|
36
27
|
*/
|
|
@@ -107,6 +98,59 @@ export class Attachment extends AttachmentBase {
|
|
|
107
98
|
}
|
|
108
99
|
return this;
|
|
109
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Actions
|
|
103
|
+
*/
|
|
104
|
+
async preComputeUrl() {
|
|
105
|
+
if (this.options?.preComputeUrl === false) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
await this.computeUrl();
|
|
109
|
+
if (this.variants) {
|
|
110
|
+
for (const key in this.variants) {
|
|
111
|
+
if (Object.prototype.hasOwnProperty.call(this.variants, key)) {
|
|
112
|
+
await this.computeUrl(this.variants[key]);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async makeName(record, attributeName) {
|
|
118
|
+
return super.makeName(record, attributeName, this.originalName);
|
|
119
|
+
}
|
|
120
|
+
async moveFileForDelete() {
|
|
121
|
+
if (this.options && this.options.rename !== true) {
|
|
122
|
+
const originalPath = this.path;
|
|
123
|
+
this.name = `${this.name}.trash`;
|
|
124
|
+
const trashPath = this.path;
|
|
125
|
+
this.originalPath = trashPath;
|
|
126
|
+
await this.getDisk().move(originalPath, trashPath);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async rollbackMoveFileForDelete() {
|
|
130
|
+
if (this.options && this.options.rename !== true) {
|
|
131
|
+
const trashPath = this.path;
|
|
132
|
+
this.name = this.name.replace('.trash', '');
|
|
133
|
+
const originalPath = this.path;
|
|
134
|
+
this.originalPath = originalPath;
|
|
135
|
+
await this.getDisk().move(trashPath, originalPath);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async remove() {
|
|
139
|
+
await super.remove();
|
|
140
|
+
if (this.variants) {
|
|
141
|
+
const variantPath = this.variants[0].folder;
|
|
142
|
+
try {
|
|
143
|
+
await this.getDisk().deleteAll(variantPath); // not compatible Minio, necessary for fs as not to leave an empty directory
|
|
144
|
+
}
|
|
145
|
+
catch (error) {
|
|
146
|
+
for (const key in this.variants) {
|
|
147
|
+
if (Object.prototype.hasOwnProperty.call(this.variants, key)) {
|
|
148
|
+
this.variants[key].remove();
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
110
154
|
/**
|
|
111
155
|
*
|
|
112
156
|
*/
|
|
@@ -21,9 +21,10 @@ export declare class AttachmentBase implements AttachmentBaseInterface {
|
|
|
21
21
|
options: LucidOptions;
|
|
22
22
|
constructor(drive: DriveService, attributes: AttachmentBaseAttributes, input?: Input);
|
|
23
23
|
/**
|
|
24
|
-
* Getters
|
|
24
|
+
* Getters / Setters
|
|
25
25
|
*/
|
|
26
26
|
get name(): string;
|
|
27
|
+
set name(name: string);
|
|
27
28
|
get folder(): string | undefined;
|
|
28
29
|
get path(): string;
|
|
29
30
|
/**
|
|
@@ -38,7 +39,15 @@ export declare class AttachmentBase implements AttachmentBaseInterface {
|
|
|
38
39
|
getKeyId(): string | undefined;
|
|
39
40
|
setKeyId(keyId: string): this;
|
|
40
41
|
setOptions(options: LucidOptions): this;
|
|
41
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Actions
|
|
44
|
+
*/
|
|
45
|
+
computeUrl(signedUrlOptions?: SignedURLOptions): Promise<void>;
|
|
46
|
+
preComputeUrl(): Promise<void>;
|
|
47
|
+
makeName(record?: LucidRow, attributeName?: string, originalName?: string): Promise<this>;
|
|
48
|
+
makeFolder(record?: LucidRow): Promise<this>;
|
|
49
|
+
put(): Promise<void>;
|
|
50
|
+
remove(): Promise<void>;
|
|
42
51
|
/**
|
|
43
52
|
*
|
|
44
53
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachment_base.d.ts","sourceRoot":"","sources":["../../../src/attachments/attachment_base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,wBAAwB,EACxB,cAAc,IAAI,uBAAuB,EAC1C,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAOpD,qBAAa,cAAe,YAAW,uBAAuB;;IAC5D,KAAK,EAAE,YAAY,CAAA;IAEnB,KAAK,CAAC,EAAE,KAAK,CAAA;IAMb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ,OAAO,EAAE,YAAY,CAAA;gBAET,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,KAAK;IAsBpF;;OAEG;IAEH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAW/B;IAED,IAAI,IAAI,IAAI,MAAM,CAMjB;IAED;;OAEG;IAEH,OAAO;IAIP,QAAQ;IAIF,SAAS;IAKf,SAAS;IAIT,MAAM;IAIN,YAAY,CAAC,gBAAgB,CAAC,EAAE,gBAAgB;IAIhD,QAAQ;IAIR,QAAQ,CAAC,KAAK,EAAE,MAAM;IAKtB,UAAU,CAAC,OAAO,EAAE,YAAY;IAQhC,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ;IAwB5B;;OAEG;IAEH,QAAQ,IAAI,wBAAwB;IAYpC,MAAM,IAAI,MAAM;CAUjB"}
|
|
1
|
+
{"version":3,"file":"attachment_base.d.ts","sourceRoot":"","sources":["../../../src/attachments/attachment_base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAC3E,OAAO,KAAK,EACV,YAAY,EACZ,wBAAwB,EACxB,cAAc,IAAI,uBAAuB,EAC1C,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAOpD,qBAAa,cAAe,YAAW,uBAAuB;;IAC5D,KAAK,EAAE,YAAY,CAAA;IAEnB,KAAK,CAAC,EAAE,KAAK,CAAA;IAMb,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,CAAA;IAEZ,OAAO,EAAE,YAAY,CAAA;gBAET,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,wBAAwB,EAAE,KAAK,CAAC,EAAE,KAAK;IAsBpF;;OAEG;IAEH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,MAAM,EAEpB;IAED,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAW/B;IAED,IAAI,IAAI,IAAI,MAAM,CAMjB;IAED;;OAEG;IAEH,OAAO;IAIP,QAAQ;IAIF,SAAS;IAKf,SAAS;IAIT,MAAM;IAIN,YAAY,CAAC,gBAAgB,CAAC,EAAE,gBAAgB;IAIhD,QAAQ;IAIR,QAAQ,CAAC,KAAK,EAAE,MAAM;IAKtB,UAAU,CAAC,OAAO,EAAE,YAAY;IAQhC;;OAEG;IAEG,UAAU,CAAC,gBAAgB,CAAC,EAAE,gBAAgB;IAW9C,aAAa;IAQb,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAwBzE,UAAU,CAAC,MAAM,CAAC,EAAE,QAAQ;IAwB5B,GAAG;IAQH,MAAM;IASZ;;OAEG;IAEH,QAAQ,IAAI,wBAAwB;IAYpC,MAAM,IAAI,MAAM;CAUjB"}
|
|
@@ -41,11 +41,14 @@ export class AttachmentBase {
|
|
|
41
41
|
this.drive = drive;
|
|
42
42
|
}
|
|
43
43
|
/**
|
|
44
|
-
* Getters
|
|
44
|
+
* Getters / Setters
|
|
45
45
|
*/
|
|
46
46
|
get name() {
|
|
47
47
|
return this.#name;
|
|
48
48
|
}
|
|
49
|
+
set name(name) {
|
|
50
|
+
this.#name = name;
|
|
51
|
+
}
|
|
49
52
|
get folder() {
|
|
50
53
|
if (this.#folder) {
|
|
51
54
|
return this.#folder;
|
|
@@ -99,9 +102,49 @@ export class AttachmentBase {
|
|
|
99
102
|
};
|
|
100
103
|
return this;
|
|
101
104
|
}
|
|
102
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Actions
|
|
107
|
+
*/
|
|
108
|
+
async computeUrl(signedUrlOptions) {
|
|
109
|
+
const disk = this.getDisk();
|
|
110
|
+
const fileVisibility = await disk.getVisibility(this.path);
|
|
111
|
+
if (fileVisibility === 'private') {
|
|
112
|
+
this.url = await this.getSignedUrl(signedUrlOptions);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
this.url = await this.getUrl();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async preComputeUrl() {
|
|
119
|
+
if (this.options?.preComputeUrl === false) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
await this.computeUrl();
|
|
123
|
+
}
|
|
124
|
+
async makeName(record, attributeName, originalName) {
|
|
125
|
+
if (typeof this.options.rename === 'function' && record) {
|
|
126
|
+
this.#name = (await this.options.rename(record, attributeName, originalName));
|
|
127
|
+
}
|
|
128
|
+
else if (originalName && this.options.rename === false) {
|
|
129
|
+
this.#name = originalName;
|
|
130
|
+
}
|
|
131
|
+
if (this.#name && record) {
|
|
132
|
+
const parameters = extractPathParameters(this.#name);
|
|
133
|
+
if (parameters) {
|
|
134
|
+
parameters.forEach((parameter) => {
|
|
135
|
+
const attribute = record.$attributes[parameter];
|
|
136
|
+
if (typeof attribute === 'string') {
|
|
137
|
+
const name = string.slug(string.noCase(string.escapeHTML(attribute.toLowerCase())));
|
|
138
|
+
this.#name = this.#name?.replace(`:${parameter}`, name);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
async makeFolder(record) {
|
|
103
146
|
if (typeof this.options.folder === 'function' && record) {
|
|
104
|
-
this.#folder = this.options.folder(record);
|
|
147
|
+
this.#folder = (await this.options.folder(record));
|
|
105
148
|
}
|
|
106
149
|
else if (this.options.folder) {
|
|
107
150
|
this.#folder = this.options.folder;
|
|
@@ -120,6 +163,20 @@ export class AttachmentBase {
|
|
|
120
163
|
}
|
|
121
164
|
return this;
|
|
122
165
|
}
|
|
166
|
+
async put() {
|
|
167
|
+
if (Buffer.isBuffer(this.input)) {
|
|
168
|
+
await this.getDisk().put(this.path, this.input);
|
|
169
|
+
}
|
|
170
|
+
else if (this.input) {
|
|
171
|
+
await this.getDisk().copyFromFs(this.input, this.path);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async remove() {
|
|
175
|
+
await this.getDisk().delete(this.path);
|
|
176
|
+
if (this.originalPath) {
|
|
177
|
+
await this.getDisk().delete(this.originalPath);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
123
180
|
/**
|
|
124
181
|
*
|
|
125
182
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"attachments_controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/attachments_controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAoBtD,MAAM,CAAC,OAAO,OAAO,qBAAqB;IAElC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,WAAW;
|
|
1
|
+
{"version":3,"file":"attachments_controller.d.ts","sourceRoot":"","sources":["../../../src/controllers/attachments_controller.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAoBtD,MAAM,CAAC,OAAO,OAAO,qBAAqB;IAElC,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,WAAW;CA0GhD"}
|
|
@@ -3,8 +3,8 @@ import { Readable } from 'node:stream';
|
|
|
3
3
|
import encryption from '@adonisjs/core/services/encryption';
|
|
4
4
|
import db from '@adonisjs/lucid/services/db';
|
|
5
5
|
import { attachmentManager } from '@jrmc/adonis-attachment';
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import VariantGeneratorService from '../services/variant/variant_generator_service.js';
|
|
7
|
+
import VariantPersisterService from '../services/variant/variant_persister_service.js';
|
|
8
8
|
export default class AttachmentsController {
|
|
9
9
|
async handle({ request, response }) {
|
|
10
10
|
const { key } = request.params();
|
|
@@ -56,37 +56,46 @@ export default class AttachmentsController {
|
|
|
56
56
|
*/
|
|
57
57
|
if (!variant && format) {
|
|
58
58
|
const converter = (await attachmentManager.getConverter(format));
|
|
59
|
-
variant = await (new
|
|
59
|
+
variant = await (new VariantGeneratorService()).generateVariant({
|
|
60
60
|
key: format,
|
|
61
61
|
attachment: currentAttachment,
|
|
62
62
|
converter
|
|
63
63
|
});
|
|
64
64
|
if (variant) {
|
|
65
|
-
const variantPersister = new
|
|
65
|
+
const variantPersister = new VariantPersisterService({
|
|
66
66
|
id: data.id,
|
|
67
67
|
modelTable: data.model,
|
|
68
68
|
attributeName: data.attribute,
|
|
69
69
|
multiple
|
|
70
70
|
});
|
|
71
|
-
|
|
71
|
+
const attachmentsOrCurrent = attachments.length ? attachments : [currentAttachment];
|
|
72
|
+
await variantPersister.persist({ attachments: attachmentsOrCurrent, variants: [variant] });
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
/*
|
|
75
76
|
* 5. Get the stream
|
|
76
77
|
*/
|
|
77
|
-
let
|
|
78
|
+
let stream;
|
|
78
79
|
let mimeType;
|
|
79
80
|
if (variant) {
|
|
80
|
-
|
|
81
|
+
stream = await variant.getStream();
|
|
81
82
|
mimeType = variant.mimeType;
|
|
82
83
|
}
|
|
83
|
-
else {
|
|
84
|
-
|
|
84
|
+
else if (currentAttachment) {
|
|
85
|
+
stream = await currentAttachment.getStream();
|
|
85
86
|
mimeType = currentAttachment.mimeType;
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
/*
|
|
89
|
+
* 6. Return the stream
|
|
90
|
+
*/
|
|
91
|
+
if (stream && mimeType) {
|
|
92
|
+
const readable = Readable.from(stream);
|
|
93
|
+
response.header('Content-Type', mimeType);
|
|
94
|
+
response.stream(readable);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return response.notFound();
|
|
98
|
+
}
|
|
90
99
|
});
|
|
91
100
|
}
|
|
92
101
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import type { RecordWithAttachment as RecordWithAttachmentImplementation } from '../../types/service.js';
|
|
8
|
+
export declare class AttachmentDetachmentService {
|
|
9
|
+
#private;
|
|
10
|
+
/**
|
|
11
|
+
* Detach dirty attachments (mark for deletion)
|
|
12
|
+
*/
|
|
13
|
+
detach(record: RecordWithAttachmentImplementation): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Detach all attachments (mark all for deletion)
|
|
16
|
+
*/
|
|
17
|
+
detachAll(record: RecordWithAttachmentImplementation): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=attachment_detachment_service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment_detachment_service.d.ts","sourceRoot":"","sources":["../../../../src/services/attachment/attachment_detachment_service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,oBAAoB,IAAI,kCAAkC,EAAE,MAAM,wBAAwB,CAAA;AAIxG,qBAAa,2BAA2B;;IACtC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,kCAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCvE;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,kCAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;CA+B3E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { AttachmentUtils } from './attachment_utils.js';
|
|
8
|
+
export class AttachmentDetachmentService {
|
|
9
|
+
/**
|
|
10
|
+
* Detach dirty attachments (mark for deletion)
|
|
11
|
+
*/
|
|
12
|
+
async detach(record) {
|
|
13
|
+
const attachmentAttributeNames = AttachmentUtils.getDirtyAttributeNamesOfAttachment(record.row);
|
|
14
|
+
await Promise.allSettled(attachmentAttributeNames.map(async (name) => {
|
|
15
|
+
let attachments = [];
|
|
16
|
+
const options = AttachmentUtils.getOptionsByAttributeName(record.row, name);
|
|
17
|
+
if (record.row.$dirty[name] === null) {
|
|
18
|
+
attachments = AttachmentUtils.getOriginalAttachmentsByAttributeName(record.row, name);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const originalAttachments = AttachmentUtils.getOriginalAttachmentsByAttributeName(record.row, name);
|
|
22
|
+
const newAttachments = AttachmentUtils.getAttachmentsByAttributeName(record.row, name);
|
|
23
|
+
/**
|
|
24
|
+
* Clean Attachments changed
|
|
25
|
+
*/
|
|
26
|
+
for (let i = 0; i < originalAttachments.length; i++) {
|
|
27
|
+
if (newAttachments.includes(originalAttachments[i])) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* If there was an existing file, then we must get rid of it
|
|
32
|
+
*/
|
|
33
|
+
if (originalAttachments[i]) {
|
|
34
|
+
originalAttachments[i].setOptions(options);
|
|
35
|
+
attachments.push(originalAttachments[i]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
await this.#moveForDeletion(attachments);
|
|
40
|
+
await this.#markForDeletion(attachments, record);
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Detach all attachments (mark all for deletion)
|
|
45
|
+
*/
|
|
46
|
+
async detachAll(record) {
|
|
47
|
+
const attachmentAttributeNames = AttachmentUtils.getAttributeNamesOfAttachment(record.row);
|
|
48
|
+
await Promise.allSettled(attachmentAttributeNames.map((name) => {
|
|
49
|
+
const options = AttachmentUtils.getOptionsByAttributeName(record.row, name);
|
|
50
|
+
const attachments = AttachmentUtils.getAttachmentsByAttributeName(record.row, name);
|
|
51
|
+
for (let i = 0; i < attachments.length; i++) {
|
|
52
|
+
attachments[i].setOptions(options);
|
|
53
|
+
}
|
|
54
|
+
this.#markForDeletion(attachments, record);
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Mark attachments for deletion by adding them to detached array
|
|
59
|
+
*/
|
|
60
|
+
async #markForDeletion(attachments, record) {
|
|
61
|
+
await Promise.allSettled(attachments.map((attachment) => record.row.$attachments.detached.push(attachment)));
|
|
62
|
+
}
|
|
63
|
+
async #moveForDeletion(attachments) {
|
|
64
|
+
await Promise.allSettled(attachments.map((attachment) => attachment.moveFileForDelete()));
|
|
65
|
+
}
|
|
66
|
+
}
|