@jrmc/adonis-attachment 2.4.0 → 2.4.2

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.
@@ -9,17 +9,16 @@ import type { MultipartFile } from '@adonisjs/core/bodyparser';
9
9
  import type { AttachmentBase, Attachment as AttachmentType } from './types/attachment.js';
10
10
  import type { ResolvedAttachmentConfig } from './types/config.js';
11
11
  import { DeferQueue } from '@poppinss/defer';
12
- import { Attachment } from './attachments/attachment.js';
13
12
  import Converter from './converters/converter.js';
14
13
  export declare class AttachmentManager {
15
14
  #private;
16
15
  queue: DeferQueue;
17
16
  constructor(config: ResolvedAttachmentConfig, drive: DriveService);
18
17
  getConfig(): ResolvedAttachmentConfig;
19
- createFromDbResponse(response: any): Attachment | null;
20
- createFromFile(file: MultipartFile): Promise<Attachment>;
21
- createFromBuffer(buffer: Buffer, name?: string): Promise<Attachment>;
22
- createFromBase64(data: string, name?: string): Promise<Attachment>;
18
+ createFromDbResponse(response: any): AttachmentType | null;
19
+ createFromFile(file: MultipartFile): Promise<AttachmentType>;
20
+ createFromBuffer(buffer: Buffer, name?: string): Promise<AttachmentType>;
21
+ createFromBase64(data: string, name?: string): Promise<AttachmentType>;
23
22
  getConverter(key: string): Promise<void | Converter>;
24
23
  computeUrl(attachment: AttachmentType | AttachmentBase, signedUrlOptions?: SignedURLOptions): Promise<void>;
25
24
  preComputeUrl(attachment: AttachmentType): Promise<void>;
@@ -33,7 +33,8 @@ export class AttachmentManager {
33
33
  throw new errors.E_CANNOT_CREATE_ATTACHMENT([attribute]);
34
34
  }
35
35
  });
36
- return new Attachment(this.#drive, attributes);
36
+ const attachment = new Attachment(this.#drive, attributes);
37
+ return this.#configureAttachment(attachment);
37
38
  }
38
39
  async createFromFile(file) {
39
40
  const attributes = {
@@ -45,14 +46,16 @@ export class AttachmentManager {
45
46
  if (!file.tmpPath) {
46
47
  throw new errors.ENOENT();
47
48
  }
48
- return new Attachment(this.#drive, attributes, file.tmpPath);
49
+ const attachment = new Attachment(this.#drive, attributes, file.tmpPath);
50
+ return this.#configureAttachment(attachment);
49
51
  }
50
52
  async createFromBuffer(buffer, name) {
51
53
  if (!Buffer.isBuffer(buffer)) {
52
54
  throw new errors.E_ISNOT_BUFFER();
53
55
  }
54
56
  const attributes = await createAttachmentAttributes(buffer, name);
55
- return new Attachment(this.#drive, attributes, buffer);
57
+ const attachment = new Attachment(this.#drive, attributes, buffer);
58
+ return this.#configureAttachment(attachment);
56
59
  }
57
60
  async createFromBase64(data, name) {
58
61
  const base64Data = data.replace(/^data:([A-Za-z-+\/]+);base64,/, '');
@@ -111,8 +114,7 @@ export class AttachmentManager {
111
114
  }
112
115
  async delete(attachment) {
113
116
  if (attachment.path) {
114
- const filePath = attachment.path;
115
- await attachment.getDisk().delete(filePath);
117
+ await attachment.getDisk().delete(attachment.path);
116
118
  if (attachment instanceof Attachment) {
117
119
  if (attachment.variants) {
118
120
  const variantPath = attachment.variants[0].folder;
@@ -120,5 +122,21 @@ export class AttachmentManager {
120
122
  }
121
123
  }
122
124
  }
125
+ if (attachment.originalPath) {
126
+ await attachment.getDisk().delete(attachment.originalPath);
127
+ }
128
+ }
129
+ // private methods
130
+ #configureAttachment(attachment) {
131
+ if (this.#config.meta !== undefined) {
132
+ attachment.setOptions({ meta: this.#config.meta });
133
+ }
134
+ if (this.#config.rename !== undefined) {
135
+ attachment.setOptions({ rename: this.#config.rename });
136
+ }
137
+ if (this.#config.preComputeUrl !== undefined) {
138
+ attachment.setOptions({ preComputeUrl: this.#config.preComputeUrl });
139
+ }
140
+ return attachment;
123
141
  }
124
142
  }
@@ -13,11 +13,21 @@ export declare class Attachment extends AttachmentBase implements AttachmentInte
13
13
  originalName: string;
14
14
  variants?: Variant[];
15
15
  constructor(drive: DriveService, attributes: AttachmentAttributes, input?: Input);
16
+ /**
17
+ * Getters
18
+ */
19
+ get name(): string;
20
+ /**
21
+ * Methods
22
+ */
16
23
  createVariant(key: string, input: Input): Promise<Variant>;
17
24
  getVariant(variantName: string): Variant | undefined;
18
25
  getUrl(variantName?: string): Promise<string>;
19
26
  getSignedUrl(variantNameOrOptions?: string | SignedURLOptions, signedUrlOptions?: SignedURLOptions): Promise<string>;
20
27
  setOptions(options: LucidOptions): this;
28
+ /**
29
+ *
30
+ */
21
31
  toObject(): AttachmentAttributes;
22
32
  toJSON(): Object;
23
33
  }
@@ -22,6 +22,18 @@ 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
+ /**
35
+ * Methods
36
+ */
25
37
  async createVariant(key, input) {
26
38
  const attributes = {
27
39
  ...(await createAttachmentAttributes(input)),
@@ -72,13 +84,6 @@ export class Attachment extends AttachmentBase {
72
84
  ...this.options,
73
85
  ...options,
74
86
  };
75
- if (!this.path) {
76
- if (!this.options.rename) {
77
- this.name = this.originalName;
78
- }
79
- this.folder = this.options.folder;
80
- this.path = path.join(this.folder, this.name);
81
- }
82
87
  if (this.variants) {
83
88
  this.variants.forEach((v) => {
84
89
  v.setOptions({
@@ -89,6 +94,9 @@ export class Attachment extends AttachmentBase {
89
94
  }
90
95
  return this;
91
96
  }
97
+ /**
98
+ *
99
+ */
92
100
  toObject() {
93
101
  const variants = this.variants?.map((v) => v.toObject());
94
102
  return {
@@ -103,7 +111,7 @@ export class Attachment extends AttachmentBase {
103
111
  originalName: this.originalName,
104
112
  size: this.size,
105
113
  extname: this.extname,
106
- mimetype: this.mimeType,
114
+ mimeType: this.mimeType,
107
115
  meta: this.meta,
108
116
  };
109
117
  if (this.variants) {
@@ -111,7 +119,7 @@ export class Attachment extends AttachmentBase {
111
119
  data[v.key] = {
112
120
  name: v.name,
113
121
  extname: v.extname,
114
- mimetype: v.mimeType,
122
+ mimeType: v.mimeType,
115
123
  meta: v.meta,
116
124
  size: v.size,
117
125
  };
@@ -8,22 +8,33 @@ import type { DriveService, SignedURLOptions } from '@adonisjs/drive/types';
8
8
  import type { LucidOptions, AttachmentBaseAttributes, AttachmentBase as AttachmentBaseInterface } from '../types/attachment.js';
9
9
  import type { Exif, Input } from '../types/input.js';
10
10
  export declare class AttachmentBase implements AttachmentBaseInterface {
11
+ #private;
11
12
  drive: DriveService;
12
13
  input?: Input;
13
- name: string;
14
14
  size: number;
15
15
  extname: string;
16
16
  mimeType: string;
17
17
  meta?: Exif;
18
- folder?: string;
19
- path?: string;
18
+ originalPath?: string;
20
19
  url?: string;
21
20
  options?: LucidOptions;
22
21
  constructor(drive: DriveService, attributes: AttachmentBaseAttributes, input?: Input);
22
+ /**
23
+ * Getters
24
+ */
25
+ get name(): string;
26
+ get folder(): string | undefined;
27
+ get path(): string;
28
+ /**
29
+ * Methods
30
+ */
23
31
  getDisk(): import("flydrive").Disk;
24
32
  getUrl(): Promise<string>;
25
33
  getSignedUrl(signedUrlOptions?: SignedURLOptions): Promise<string>;
26
34
  setOptions(options: LucidOptions): this;
35
+ /**
36
+ *
37
+ */
27
38
  toObject(): AttachmentBaseAttributes;
28
39
  toJSON(): Object;
29
40
  }
@@ -4,18 +4,19 @@
4
4
  * @license MIT
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
+ import path from 'node:path';
7
8
  import { cuid } from '@adonisjs/core/helpers';
8
9
  import { defaultOptionsDecorator } from '../utils/default_values.js';
9
10
  export class AttachmentBase {
10
11
  drive;
11
12
  input;
12
- name;
13
+ #name;
14
+ #folder;
13
15
  size;
14
16
  extname;
15
17
  mimeType;
16
18
  meta;
17
- folder;
18
- path;
19
+ originalPath;
19
20
  url;
20
21
  options;
21
22
  constructor(drive, attributes, input) {
@@ -24,17 +25,35 @@ export class AttachmentBase {
24
25
  this.meta = attributes.meta;
25
26
  this.extname = attributes.extname;
26
27
  this.mimeType = attributes.mimeType;
27
- this.folder = attributes.folder;
28
- this.path = attributes.path;
29
- this.options = defaultOptionsDecorator;
30
- this.drive = drive;
28
+ this.originalPath = attributes.path;
29
+ this.#folder = attributes.folder;
31
30
  if (attributes.name) {
32
- this.name = attributes.name;
31
+ this.#name = attributes.name;
33
32
  }
34
33
  else {
35
- this.name = `${cuid()}.${this.extname}`;
34
+ this.#name = `${cuid()}.${this.extname}`;
35
+ }
36
+ this.options = defaultOptionsDecorator;
37
+ this.drive = drive;
38
+ }
39
+ /**
40
+ * Getters
41
+ */
42
+ get name() {
43
+ return this.#name;
44
+ }
45
+ get folder() {
46
+ if (this.options) {
47
+ return this.options?.folder;
36
48
  }
49
+ return this.#folder;
50
+ }
51
+ get path() {
52
+ return path.join(this.folder, this.name);
37
53
  }
54
+ /**
55
+ * Methods
56
+ */
38
57
  getDisk() {
39
58
  return this.drive.use(this.options?.disk);
40
59
  }
@@ -51,6 +70,9 @@ export class AttachmentBase {
51
70
  };
52
71
  return this;
53
72
  }
73
+ /**
74
+ *
75
+ */
54
76
  toObject() {
55
77
  return {
56
78
  name: this.name,
@@ -9,8 +9,15 @@ import type { VariantAttributes, Variant as VariantInterface } from '../types/at
9
9
  import type { Input } from '../types/input.js';
10
10
  import { AttachmentBase } from './attachment_base.js';
11
11
  export declare class Variant extends AttachmentBase implements VariantInterface {
12
+ #private;
12
13
  key: string;
13
- folder: string;
14
14
  constructor(drive: DriveService, attributes: VariantAttributes, input?: Input);
15
+ /**
16
+ * Getters
17
+ */
18
+ get folder(): string;
19
+ /**
20
+ *
21
+ */
15
22
  toObject(): VariantAttributes;
16
23
  }
@@ -4,17 +4,24 @@
4
4
  * @license MIT
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
- import path from 'node:path';
8
7
  import { AttachmentBase } from './attachment_base.js';
9
8
  export class Variant extends AttachmentBase {
10
9
  key;
11
- folder;
10
+ #folder;
12
11
  constructor(drive, attributes, input) {
13
12
  super(drive, attributes, input);
14
13
  this.key = attributes.key;
15
- this.folder = attributes.folder;
16
- this.path = path.join(this.folder, this.name);
14
+ this.#folder = attributes.folder;
17
15
  }
16
+ /**
17
+ * Getters
18
+ */
19
+ get folder() {
20
+ return this.#folder;
21
+ }
22
+ /**
23
+ *
24
+ */
18
25
  toObject() {
19
26
  return {
20
27
  key: this.key,
@@ -12,23 +12,6 @@ export const attachment = (options) => {
12
12
  if (!target[optionsSym]) {
13
13
  target[optionsSym] = {};
14
14
  }
15
- const defaultConfig = attachmentManager.getConfig();
16
- const defaultOptions = {
17
- meta: defaultConfig.meta !== undefined ? defaultConfig.meta : defaultOptionsDecorator.meta,
18
- rename: defaultConfig.rename !== undefined ? defaultConfig.rename : defaultOptionsDecorator.rename,
19
- preComputeUrl: defaultConfig.preComputeUrl !== undefined
20
- ? defaultConfig.preComputeUrl
21
- : defaultOptionsDecorator.preComputeUrl,
22
- };
23
- if (!options || options?.meta === undefined) {
24
- options.meta = defaultOptions.meta;
25
- }
26
- if (!options || options?.rename === undefined) {
27
- options.rename = defaultOptions.rename;
28
- }
29
- if (!options || options?.preComputeUrl === undefined) {
30
- options.preComputeUrl = defaultOptions.preComputeUrl;
31
- }
32
15
  target[optionsSym][attributeName] = options;
33
16
  const Model = target.constructor;
34
17
  Model.boot();
@@ -40,7 +23,16 @@ export const attachment = (options) => {
40
23
  consume: (value) => {
41
24
  if (value) {
42
25
  const attachment = attachmentManager.createFromDbResponse(value);
43
- attachment?.setOptions({ disk, folder, variants, meta, rename });
26
+ attachment?.setOptions({ disk, folder, variants });
27
+ if (options && options?.meta !== undefined) {
28
+ attachment?.setOptions({ meta: options.meta });
29
+ }
30
+ if (options && options?.rename !== undefined) {
31
+ attachment?.setOptions({ rename: options.rename });
32
+ }
33
+ if (options && options?.preComputeUrl !== undefined) {
34
+ attachment?.setOptions({ preComputeUrl: options.preComputeUrl });
35
+ }
44
36
  return attachment;
45
37
  }
46
38
  else {
@@ -12,12 +12,13 @@ export type AttachmentBase = {
12
12
  drive: DriveService;
13
13
  input?: Input;
14
14
  name: string;
15
+ folder?: string;
16
+ path?: string;
15
17
  size: number;
16
18
  extname: string;
17
19
  mimeType: string;
18
20
  meta?: Exif;
19
- folder?: string;
20
- path?: string;
21
+ originalPath?: string;
21
22
  url?: string;
22
23
  options?: LucidOptions;
23
24
  getDisk(): Disk;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jrmc/adonis-attachment",
3
- "version": "2.4.0",
3
+ "version": "2.4.2",
4
4
  "type": "module",
5
5
  "description": "Turn any field on your Lucid model to an attachment data type",
6
6
  "engines": {