@jrmc/adonis-attachment 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin/test.d.ts +1 -0
- package/build/bin/test.js +34 -0
- package/build/providers/attachment_provider.d.ts +1 -1
- package/build/src/adapters/exif.d.ts +7 -1
- package/build/src/adapters/exif.js +8 -5
- package/build/src/attachment_manager.d.ts +3 -0
- package/build/src/attachment_manager.js +20 -3
- package/build/src/errors.d.ts +18 -14
- package/build/src/errors.js +4 -0
- package/build/src/mixins/attachmentable.d.ts +127 -112
- package/build/src/mixins/attachmentable.js +2 -2
- package/build/src/utils/helpers.d.ts +2 -0
- package/build/src/utils/helpers.js +35 -1
- package/build/tests/attachment-manager.spec.d.ts +7 -0
- package/build/tests/attachment-manager.spec.js +234 -0
- package/build/tests/attachment.spec.d.ts +7 -0
- package/build/tests/attachment.spec.js +16 -0
- package/build/tests/commands.spec.d.ts +7 -0
- package/build/tests/commands.spec.js +58 -0
- package/build/tests/fixtures/converters/image_converter.d.ts +12 -0
- package/build/tests/fixtures/converters/image_converter.js +12 -0
- package/build/tests/fixtures/factories/user.d.ts +8 -0
- package/build/tests/fixtures/factories/user.js +19 -0
- package/build/tests/fixtures/factories/user_with_variants.d.ts +8 -0
- package/build/tests/fixtures/factories/user_with_variants.js +19 -0
- package/build/tests/fixtures/migrations/create_users_table.d.ts +12 -0
- package/build/tests/fixtures/migrations/create_users_table.js +23 -0
- package/build/tests/fixtures/models/user.d.ts +466 -0
- package/build/tests/fixtures/models/user.js +36 -0
- package/build/tests/fixtures/models/user_with_variants.d.ts +465 -0
- package/build/tests/fixtures/models/user_with_variants.js +33 -0
- package/build/tests/helpers/app.d.ts +29 -0
- package/build/tests/helpers/app.js +104 -0
- package/build/tests/helpers/index.d.ts +7 -0
- package/build/tests/helpers/index.js +7 -0
- package/build/tests/options.spec.d.ts +7 -0
- package/build/tests/options.spec.js +126 -0
- package/build/tests/variants.spec.d.ts +7 -0
- package/build/tests/variants.spec.js +21 -0
- package/package.json +39 -14
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import https from 'node:https';
|
|
8
|
+
import { readFile } from 'node:fs/promises';
|
|
9
|
+
import { test } from '@japa/runner';
|
|
10
|
+
import app from '@adonisjs/core/services/app';
|
|
11
|
+
import drive from '@adonisjs/drive/services/main';
|
|
12
|
+
import { MultipartFileFactory } from '@adonisjs/core/factories/bodyparser';
|
|
13
|
+
import { UserFactory } from './fixtures/factories/user.js';
|
|
14
|
+
import { attachmentManager } from '../index.js';
|
|
15
|
+
test.group('attachment-manager', () => {
|
|
16
|
+
test('save method - should result in noop when attachment is created from db response', async ({ assert, }) => {
|
|
17
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
18
|
+
const attachment = attachmentManager.createFromDbResponse(JSON.stringify({
|
|
19
|
+
size: 1440,
|
|
20
|
+
name: 'foo123.jpg',
|
|
21
|
+
originalName: 'foo.jpg',
|
|
22
|
+
extname: 'jpg',
|
|
23
|
+
mimeType: 'image/jpg',
|
|
24
|
+
}));
|
|
25
|
+
assert.equal(attachment?.originalName, 'foo.jpg');
|
|
26
|
+
});
|
|
27
|
+
test('Attachment - should be null when db response is null', async ({ assert }) => {
|
|
28
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
29
|
+
const attachment = attachmentManager.createFromDbResponse(null);
|
|
30
|
+
assert.isNull(attachment);
|
|
31
|
+
});
|
|
32
|
+
test('Attachment path default is uploads', async ({ assert }) => {
|
|
33
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
34
|
+
const attachment = attachmentManager.createFromDbResponse(JSON.stringify({
|
|
35
|
+
size: 1440,
|
|
36
|
+
name: 'foo.jpg',
|
|
37
|
+
extname: 'jpg',
|
|
38
|
+
mimeType: 'image/jpg',
|
|
39
|
+
}));
|
|
40
|
+
assert.equal(attachment?.path, 'uploads/foo.jpg');
|
|
41
|
+
});
|
|
42
|
+
test('Attachment path - should be custom', async ({ assert }) => {
|
|
43
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
44
|
+
const attachment = attachmentManager.createFromDbResponse(JSON.stringify({
|
|
45
|
+
size: 1440,
|
|
46
|
+
name: 'foo.jpg',
|
|
47
|
+
extname: 'jpg',
|
|
48
|
+
mimeType: 'image/jpg',
|
|
49
|
+
}));
|
|
50
|
+
attachment?.setOptions({ folder: 'avatar' });
|
|
51
|
+
assert.equal(attachment?.path, 'avatar/foo.jpg');
|
|
52
|
+
});
|
|
53
|
+
test('Attachment get url', async ({ assert, cleanup }) => {
|
|
54
|
+
drive.fake('fs');
|
|
55
|
+
cleanup(() => drive.restore('fs'));
|
|
56
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
57
|
+
const attachment = attachmentManager.createFromDbResponse(JSON.stringify({
|
|
58
|
+
size: 1440,
|
|
59
|
+
name: 'foo.jpg',
|
|
60
|
+
extname: 'jpg',
|
|
61
|
+
mimeType: 'image/jpg',
|
|
62
|
+
}));
|
|
63
|
+
attachment?.setOptions({ folder: 'avatars' });
|
|
64
|
+
const url = await attachment?.getUrl();
|
|
65
|
+
const signedUrl = await attachment?.getSignedUrl();
|
|
66
|
+
assert.match(url, /\/drive\/fakes\/avatars\/foo\.jpg/);
|
|
67
|
+
assert.match(signedUrl, /\/drive\/fakes\/signed\/avatars\/foo\.jpg/);
|
|
68
|
+
});
|
|
69
|
+
test('Precompute file url', async ({ assert, cleanup }) => {
|
|
70
|
+
drive.fake('fs');
|
|
71
|
+
cleanup(() => drive.restore('fs'));
|
|
72
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
73
|
+
const attachment = attachmentManager.createFromDbResponse(JSON.stringify({
|
|
74
|
+
size: 1440,
|
|
75
|
+
name: 'foo.jpg',
|
|
76
|
+
extname: 'jpg',
|
|
77
|
+
mimeType: 'image/jpg',
|
|
78
|
+
}));
|
|
79
|
+
attachment?.setOptions({ preComputeUrl: true, folder: 'avatars' });
|
|
80
|
+
await attachmentManager.preComputeUrl(attachment);
|
|
81
|
+
assert.match(attachment?.url, /\/drive\/fakes\/avatars\/foo\.jpg/);
|
|
82
|
+
});
|
|
83
|
+
test('with base64 (prefix)', async ({ assert }) => {
|
|
84
|
+
const avatar = await attachmentManager.createFromBase64('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=', 'avatar.png');
|
|
85
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
86
|
+
const data = await user.serialize();
|
|
87
|
+
assert.deepEqual(data.avatar, {
|
|
88
|
+
extname: 'png',
|
|
89
|
+
meta: {
|
|
90
|
+
dimension: {
|
|
91
|
+
height: 24,
|
|
92
|
+
width: 24,
|
|
93
|
+
},
|
|
94
|
+
host: 'www.inkscape.org',
|
|
95
|
+
},
|
|
96
|
+
mimeType: 'image/png',
|
|
97
|
+
name: data.avatar.name,
|
|
98
|
+
originalName: 'avatar.png',
|
|
99
|
+
size: 965,
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
test('with base64 (no prefix)', async ({ assert }) => {
|
|
103
|
+
const avatar = await attachmentManager.createFromBase64('iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAApgAAAKYB3X3/OAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAANCSURBVEiJtZZPbBtFFMZ/M7ubXdtdb1xSFyeilBapySVU8h8OoFaooFSqiihIVIpQBKci6KEg9Q6H9kovIHoCIVQJJCKE1ENFjnAgcaSGC6rEnxBwA04Tx43t2FnvDAfjkNibxgHxnWb2e/u992bee7tCa00YFsffekFY+nUzFtjW0LrvjRXrCDIAaPLlW0nHL0SsZtVoaF98mLrx3pdhOqLtYPHChahZcYYO7KvPFxvRl5XPp1sN3adWiD1ZAqD6XYK1b/dvE5IWryTt2udLFedwc1+9kLp+vbbpoDh+6TklxBeAi9TL0taeWpdmZzQDry0AcO+jQ12RyohqqoYoo8RDwJrU+qXkjWtfi8Xxt58BdQuwQs9qC/afLwCw8tnQbqYAPsgxE1S6F3EAIXux2oQFKm0ihMsOF71dHYx+f3NND68ghCu1YIoePPQN1pGRABkJ6Bus96CutRZMydTl+TvuiRW1m3n0eDl0vRPcEysqdXn+jsQPsrHMquGeXEaY4Yk4wxWcY5V/9scqOMOVUFthatyTy8QyqwZ+kDURKoMWxNKr2EeqVKcTNOajqKoBgOE28U4tdQl5p5bwCw7BWquaZSzAPlwjlithJtp3pTImSqQRrb2Z8PHGigD4RZuNX6JYj6wj7O4TFLbCO/Mn/m8R+h6rYSUb3ekokRY6f/YukArN979jcW+V/S8g0eT/N3VN3kTqWbQ428m9/8k0P/1aIhF36PccEl6EhOcAUCrXKZXXWS3XKd2vc/TRBG9O5ELC17MmWubD2nKhUKZa26Ba2+D3P+4/MNCFwg59oWVeYhkzgN/JDR8deKBoD7Y+ljEjGZ0sosXVTvbc6RHirr2reNy1OXd6pJsQ+gqjk8VWFYmHrwBzW/n+uMPFiRwHB2I7ih8ciHFxIkd/3Omk5tCDV1t+2nNu5sxxpDFNx+huNhVT3/zMDz8usXC3ddaHBj1GHj/As08fwTS7Kt1HBTmyN29vdwAw+/wbwLVOJ3uAD1wi/dUH7Qei66PfyuRj4Ik9is+hglfbkbfR3cnZm7chlUWLdwmprtCohX4HUtlOcQjLYCu+fzGJH2QRKvP3UNz8bWk1qMxjGTOMThZ3kvgLI5AzFfo379UAAAAASUVORK5CYII=', 'avatar.png');
|
|
104
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
105
|
+
const data = await user.serialize();
|
|
106
|
+
assert.deepEqual(data.avatar, {
|
|
107
|
+
extname: 'png',
|
|
108
|
+
meta: {
|
|
109
|
+
dimension: {
|
|
110
|
+
height: 24,
|
|
111
|
+
width: 24,
|
|
112
|
+
},
|
|
113
|
+
host: 'www.inkscape.org',
|
|
114
|
+
},
|
|
115
|
+
mimeType: 'image/png',
|
|
116
|
+
name: data.avatar.name,
|
|
117
|
+
originalName: 'avatar.png',
|
|
118
|
+
size: 965,
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
test('with buffer', async ({ assert }) => {
|
|
122
|
+
const buffer = await readFile(app.makePath('../fixtures/images/img.jpg'));
|
|
123
|
+
const avatar = await attachmentManager.createFromBuffer(buffer, 'avatar.jpg');
|
|
124
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
125
|
+
const data = await user.serialize();
|
|
126
|
+
assert.deepEqual(data.avatar, {
|
|
127
|
+
extname: 'jpg',
|
|
128
|
+
meta: {
|
|
129
|
+
dimension: {
|
|
130
|
+
height: 1313,
|
|
131
|
+
width: 1920,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
mimeType: 'image/jpeg',
|
|
135
|
+
name: data.avatar.name,
|
|
136
|
+
originalName: 'avatar.jpg',
|
|
137
|
+
size: 122851,
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
test('with file', async ({ assert }) => {
|
|
141
|
+
const file = new MultipartFileFactory()
|
|
142
|
+
.merge({
|
|
143
|
+
size: 4000000,
|
|
144
|
+
extname: 'jpg',
|
|
145
|
+
type: 'image',
|
|
146
|
+
subtype: 'jpeg',
|
|
147
|
+
})
|
|
148
|
+
.create();
|
|
149
|
+
file.tmpPath = app.makePath('../fixtures/images/img.jpg');
|
|
150
|
+
const avatar = await attachmentManager.createFromFile(file);
|
|
151
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
152
|
+
const data = await user.serialize();
|
|
153
|
+
assert.deepEqual(data.avatar, {
|
|
154
|
+
extname: 'jpg',
|
|
155
|
+
meta: {
|
|
156
|
+
dimension: {
|
|
157
|
+
height: 1313,
|
|
158
|
+
width: 1920,
|
|
159
|
+
},
|
|
160
|
+
},
|
|
161
|
+
mimeType: 'image/jpeg',
|
|
162
|
+
name: data.avatar.name,
|
|
163
|
+
originalName: 'file.jpg',
|
|
164
|
+
size: 4000000,
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
test('with path', async ({ assert }) => {
|
|
168
|
+
const path = app.makePath('../fixtures/images/img.jpg');
|
|
169
|
+
const avatar = await attachmentManager.createFromPath(path, 'file.jpg');
|
|
170
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
171
|
+
const data = await user.serialize();
|
|
172
|
+
assert.deepEqual(data.avatar, {
|
|
173
|
+
extname: 'jpg',
|
|
174
|
+
meta: {
|
|
175
|
+
dimension: {
|
|
176
|
+
height: 1313,
|
|
177
|
+
width: 1920,
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
mimeType: 'image/jpeg',
|
|
181
|
+
name: data.avatar.name,
|
|
182
|
+
originalName: 'file.jpg',
|
|
183
|
+
size: 83,
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
test('with url', async ({ assert }) => {
|
|
187
|
+
const url = new URL('https://raw.githubusercontent.com/batosai/adonis-attachment/refs/heads/develop/tests/fixtures/images/img.jpg');
|
|
188
|
+
const avatar = await attachmentManager.createFromUrl(url, 'file.jpg');
|
|
189
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
190
|
+
const data = await user.serialize();
|
|
191
|
+
assert.deepEqual(data.avatar, {
|
|
192
|
+
extname: 'jpg',
|
|
193
|
+
meta: {
|
|
194
|
+
dimension: {
|
|
195
|
+
height: 1313,
|
|
196
|
+
width: 1920,
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
mimeType: 'image/jpeg',
|
|
200
|
+
name: data.avatar.name,
|
|
201
|
+
originalName: 'file.jpg',
|
|
202
|
+
size: 31,
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
test('with stream', async ({ assert }) => {
|
|
206
|
+
async function downloadImageStream(input) {
|
|
207
|
+
return await new Promise((resolve) => {
|
|
208
|
+
https.get(input, (response) => {
|
|
209
|
+
if (response.statusCode === 200) {
|
|
210
|
+
resolve(response);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
const url = new URL('https://raw.githubusercontent.com/batosai/adonis-attachment/refs/heads/develop/tests/fixtures/images/img.jpg');
|
|
216
|
+
const stream = await downloadImageStream(url);
|
|
217
|
+
const avatar = await attachmentManager.createFromStream(stream, 'file.jpg');
|
|
218
|
+
const user = await UserFactory.merge({ avatar }).create();
|
|
219
|
+
const data = await user.serialize();
|
|
220
|
+
assert.deepEqual(data.avatar, {
|
|
221
|
+
extname: 'jpg',
|
|
222
|
+
meta: {
|
|
223
|
+
dimension: {
|
|
224
|
+
height: 1313,
|
|
225
|
+
width: 1920,
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
mimeType: 'image/jpeg',
|
|
229
|
+
name: data.avatar.name,
|
|
230
|
+
originalName: 'file.jpg',
|
|
231
|
+
size: 31,
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { test } from '@japa/runner';
|
|
8
|
+
import { UserFactory } from './fixtures/factories/user.js';
|
|
9
|
+
test.group('attachment', () => {
|
|
10
|
+
test('delete', async ({ assert }) => {
|
|
11
|
+
const user = await UserFactory.create();
|
|
12
|
+
user.avatar = null;
|
|
13
|
+
await user.save();
|
|
14
|
+
assert.isNull(user.avatar);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { test } from '@japa/runner';
|
|
8
|
+
import Configure from '@adonisjs/core/commands/configure';
|
|
9
|
+
import { IgnitorFactory } from '@adonisjs/core/factories';
|
|
10
|
+
import MakeConverter from '../commands/make/converter.js';
|
|
11
|
+
import { BASE_URL } from './helpers/index.js';
|
|
12
|
+
async function setupFakeAdonisProject(fs) {
|
|
13
|
+
await Promise.all([
|
|
14
|
+
fs.create('.env', ''),
|
|
15
|
+
fs.createJson('tsconfig.json', {}),
|
|
16
|
+
fs.create('adonisrc.ts', `export default defineConfig({})`),
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
async function setupApp() {
|
|
20
|
+
const ignitor = new IgnitorFactory()
|
|
21
|
+
.withCoreProviders()
|
|
22
|
+
.withCoreConfig()
|
|
23
|
+
.create(BASE_URL, {
|
|
24
|
+
importer: (filePath) => {
|
|
25
|
+
if (filePath.startsWith('./') || filePath.startsWith('../')) {
|
|
26
|
+
return import(new URL(filePath, BASE_URL).href);
|
|
27
|
+
}
|
|
28
|
+
return import(filePath);
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
const app = ignitor.createApp('web');
|
|
32
|
+
await app.init();
|
|
33
|
+
await app.boot();
|
|
34
|
+
const ace = await app.container.make('ace');
|
|
35
|
+
ace.ui.switchMode('raw');
|
|
36
|
+
return { ace, app };
|
|
37
|
+
}
|
|
38
|
+
test.group('configure', (group) => {
|
|
39
|
+
group.tap((t) => t.timeout(20_000));
|
|
40
|
+
group.each.setup(async ({ context }) => setupFakeAdonisProject(context.fs));
|
|
41
|
+
test('add provider, config file, and command', async ({ assert }) => {
|
|
42
|
+
const { ace } = await setupApp();
|
|
43
|
+
const command = await ace.create(Configure, ['../../configure.js']);
|
|
44
|
+
await command.exec();
|
|
45
|
+
command.assertSucceeded();
|
|
46
|
+
await assert.fileExists('config/attachment.ts');
|
|
47
|
+
await assert.fileExists('adonisrc.ts');
|
|
48
|
+
await assert.fileContains('adonisrc.ts', '@jrmc/adonis-attachment/attachment_provider');
|
|
49
|
+
await assert.fileContains('adonisrc.ts', '@jrmc/adonis-attachment/commands');
|
|
50
|
+
});
|
|
51
|
+
test('create converter', async ({ assert }) => {
|
|
52
|
+
const { ace } = await setupApp();
|
|
53
|
+
const command = await ace.create(MakeConverter, ['thumb']);
|
|
54
|
+
await command.exec();
|
|
55
|
+
command.assertSucceeded();
|
|
56
|
+
await assert.fileExists('app/converters/thumb_converter.ts');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import type { ConverterAttributes } from '../../../src/types/converter.js';
|
|
8
|
+
import type { Input } from '../../../src/types/input.js';
|
|
9
|
+
import Converter from '../../../src/converters/converter.js';
|
|
10
|
+
export default class ImageConverter extends Converter {
|
|
11
|
+
handle({ input }: ConverterAttributes): Promise<Input>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import Converter from '../../../src/converters/converter.js';
|
|
8
|
+
export default class ImageConverter extends Converter {
|
|
9
|
+
async handle({ input }) {
|
|
10
|
+
return input;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import User from '../models/user.js';
|
|
8
|
+
export declare const UserFactory: import("@adonisjs/lucid/types/factory").FactoryBuilderQueryContract<typeof User, import("@adonisjs/lucid/types/factory").FactoryModelContract<typeof User>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import User from '../models/user.js';
|
|
9
|
+
import Factory from '@adonisjs/lucid/factories';
|
|
10
|
+
import app from '@adonisjs/core/services/app';
|
|
11
|
+
export const UserFactory = Factory.define(User, async ({ faker }) => {
|
|
12
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
13
|
+
const buffer = await readFile(app.makePath('../fixtures/images/img.jpg'));
|
|
14
|
+
const avatar = await attachmentManager.createFromBuffer(buffer, 'avatar.jpg');
|
|
15
|
+
return {
|
|
16
|
+
name: faker.person.lastName(),
|
|
17
|
+
avatar,
|
|
18
|
+
};
|
|
19
|
+
}).build();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import User from '../models/user_with_variants.js';
|
|
8
|
+
export declare const UserFactory: import("@adonisjs/lucid/types/factory").FactoryBuilderQueryContract<typeof User, import("@adonisjs/lucid/types/factory").FactoryModelContract<typeof User>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from 'node:fs/promises';
|
|
8
|
+
import User from '../models/user_with_variants.js';
|
|
9
|
+
import Factory from '@adonisjs/lucid/factories';
|
|
10
|
+
import app from '@adonisjs/core/services/app';
|
|
11
|
+
export const UserFactory = Factory.define(User, async ({ faker }) => {
|
|
12
|
+
const attachmentManager = await app.container.make('jrmc.attachment');
|
|
13
|
+
const buffer = await readFile(app.makePath('../fixtures/images/img.jpg'));
|
|
14
|
+
const avatar = await attachmentManager.createFromBuffer(buffer, 'avatar.jpg');
|
|
15
|
+
return {
|
|
16
|
+
name: faker.person.lastName(),
|
|
17
|
+
avatar,
|
|
18
|
+
};
|
|
19
|
+
}).build();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { BaseSchema } from '@adonisjs/lucid/schema';
|
|
8
|
+
export default class extends BaseSchema {
|
|
9
|
+
protected tableName: string;
|
|
10
|
+
up(): Promise<void>;
|
|
11
|
+
down(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { BaseSchema } from '@adonisjs/lucid/schema';
|
|
8
|
+
export default class extends BaseSchema {
|
|
9
|
+
tableName = 'users';
|
|
10
|
+
async up() {
|
|
11
|
+
this.schema.createTable(this.tableName, (table) => {
|
|
12
|
+
table.increments('id');
|
|
13
|
+
table.string('name');
|
|
14
|
+
table.json('avatar');
|
|
15
|
+
table.json('avatar_2');
|
|
16
|
+
table.timestamp('created_at');
|
|
17
|
+
table.timestamp('updated_at');
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async down() {
|
|
21
|
+
this.schema.dropTable(this.tableName);
|
|
22
|
+
}
|
|
23
|
+
}
|