@jrmc/adonis-attachment 3.0.0 → 3.2.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/README.md +4 -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/adapters/meta.d.ts +3 -0
- package/build/src/adapters/meta.js +40 -0
- package/build/src/attachment_manager.d.ts +6 -3
- package/build/src/attachment_manager.js +46 -17
- package/build/src/attachments/attachment.js +9 -2
- package/build/src/decorators/attachment.js +25 -0
- package/build/src/errors.d.ts +4 -0
- package/build/src/errors.js +4 -0
- package/build/src/mixins/attachmentable.d.ts +55 -349
- package/build/src/mixins/attachmentable.js +12 -90
- package/build/src/types/converter.d.ts +22 -1
- package/build/src/types/input.d.ts +5 -0
- package/build/src/utils/helpers.d.ts +2 -7
- package/build/src/utils/helpers.js +37 -25
- package/build/src/utils/hooks.d.ts +11 -0
- package/build/src/utils/hooks.js +92 -0
- package/package.json +42 -15
|
@@ -10,101 +10,23 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
10
10
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
11
11
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
12
12
|
};
|
|
13
|
-
import { beforeSave,
|
|
14
|
-
import {
|
|
15
|
-
import { clone, getAttachmentAttributeNames, getDirtyAttachmentAttributeNames, } from '../utils/helpers.js';
|
|
13
|
+
import { beforeSave, beforeFind, beforeFetch, beforePaginate, beforeCreate, } from '@adonisjs/lucid/orm';
|
|
14
|
+
import { clone } from '../utils/helpers.js';
|
|
16
15
|
import { defaultStateAttributeMixin } from '../utils/default_values.js';
|
|
17
|
-
|
|
16
|
+
import logger from '@adonisjs/core/services/logger';
|
|
17
|
+
export function Attachmentable(superclass) {
|
|
18
18
|
class ModelWithAttachment extends superclass {
|
|
19
19
|
$attachments = clone(defaultStateAttributeMixin);
|
|
20
|
-
static async
|
|
21
|
-
|
|
22
|
-
await Promise.all(attachmentAttributeNames.map((attributeName) => {
|
|
23
|
-
return preComputeUrl(modelInstance, attributeName);
|
|
24
|
-
}));
|
|
25
|
-
}
|
|
26
|
-
static async afterFetchHook(modelInstances) {
|
|
27
|
-
await Promise.all(modelInstances.map((row) => this.afterFindHook(row)));
|
|
28
|
-
}
|
|
29
|
-
static async beforeSaveHook(modelInstance) {
|
|
30
|
-
const attachmentAttributeNames = getDirtyAttachmentAttributeNames(modelInstance);
|
|
31
|
-
/**
|
|
32
|
-
* Empty previous $attachments
|
|
33
|
-
*/
|
|
34
|
-
modelInstance.$attachments = clone(defaultStateAttributeMixin);
|
|
35
|
-
/**
|
|
36
|
-
* Set attributes Attachment type modified
|
|
37
|
-
*/
|
|
38
|
-
attachmentAttributeNames.forEach((attributeName) => modelInstance.$attachments.attributesModified.push(attributeName));
|
|
39
|
-
/**
|
|
40
|
-
* Persist attachments before saving the model to the database. This
|
|
41
|
-
* way if file saving fails we will not write anything to the
|
|
42
|
-
* database
|
|
43
|
-
*/
|
|
44
|
-
await Promise.all(attachmentAttributeNames.map((attributeName) => persistAttachment(modelInstance, attributeName)));
|
|
45
|
-
try {
|
|
46
|
-
if (modelInstance.$trx) {
|
|
47
|
-
modelInstance.$trx.after('commit', () => commit(modelInstance));
|
|
48
|
-
modelInstance.$trx.after('rollback', () => rollback(modelInstance));
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
await commit(modelInstance);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
await rollback(modelInstance);
|
|
56
|
-
throw error;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
static async afterSaveHook(modelInstance) {
|
|
60
|
-
const attachmentAttributeNames = getAttachmentAttributeNames(modelInstance);
|
|
61
|
-
/**
|
|
62
|
-
* For all properties Attachment
|
|
63
|
-
* Launch async generation variants
|
|
64
|
-
*/
|
|
65
|
-
await Promise.all(attachmentAttributeNames.map((attributeName) => {
|
|
66
|
-
if (modelInstance.$attachments.attributesModified.includes(attributeName)) {
|
|
67
|
-
return generateVariants(modelInstance, attributeName);
|
|
68
|
-
}
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
static async beforeDeleteHook(modelInstance) {
|
|
72
|
-
const attachmentAttributeNames = getAttachmentAttributeNames(modelInstance);
|
|
73
|
-
/**
|
|
74
|
-
* Mark all attachments for deletion
|
|
75
|
-
*/
|
|
76
|
-
attachmentAttributeNames.map((attributeName) => {
|
|
77
|
-
if (modelInstance.$attributes[attributeName]) {
|
|
78
|
-
modelInstance.$attachments.detached.push(modelInstance.$attributes[attributeName]);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
/**
|
|
82
|
-
* If model is using transaction, then wait for the transaction
|
|
83
|
-
* to settle
|
|
84
|
-
*/
|
|
85
|
-
if (modelInstance.$trx) {
|
|
86
|
-
modelInstance.$trx.after('commit', () => commit(modelInstance));
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
await commit(modelInstance);
|
|
90
|
-
}
|
|
20
|
+
static async warn() {
|
|
21
|
+
logger.warn(`The "Attachmentable" mixin is deprecated and may be removed in a future version.`);
|
|
91
22
|
}
|
|
92
23
|
}
|
|
93
24
|
__decorate([
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
afterPaginate()
|
|
99
|
-
], ModelWithAttachment, "afterFetchHook", null);
|
|
100
|
-
__decorate([
|
|
25
|
+
beforeCreate(),
|
|
26
|
+
beforeFind(),
|
|
27
|
+
beforeFetch(),
|
|
28
|
+
beforePaginate(),
|
|
101
29
|
beforeSave()
|
|
102
|
-
], ModelWithAttachment, "
|
|
103
|
-
__decorate([
|
|
104
|
-
afterSave()
|
|
105
|
-
], ModelWithAttachment, "afterSaveHook", null);
|
|
106
|
-
__decorate([
|
|
107
|
-
beforeDelete()
|
|
108
|
-
], ModelWithAttachment, "beforeDeleteHook", null);
|
|
30
|
+
], ModelWithAttachment, "warn", null);
|
|
109
31
|
return ModelWithAttachment;
|
|
110
|
-
}
|
|
32
|
+
}
|
|
@@ -86,6 +86,27 @@ type webp = {
|
|
|
86
86
|
force?: Boolean;
|
|
87
87
|
};
|
|
88
88
|
};
|
|
89
|
+
type avif = {
|
|
90
|
+
format: 'avif';
|
|
91
|
+
options: {
|
|
92
|
+
quality?: number;
|
|
93
|
+
lossless?: Boolean;
|
|
94
|
+
effort?: number;
|
|
95
|
+
chromaSubsampling?: string;
|
|
96
|
+
bitdepth?: number;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
type heif = {
|
|
100
|
+
format: 'heif';
|
|
101
|
+
options: {
|
|
102
|
+
compression?: string;
|
|
103
|
+
quality?: number;
|
|
104
|
+
lossless?: Boolean;
|
|
105
|
+
effort?: number;
|
|
106
|
+
chromaSubsampling?: string;
|
|
107
|
+
bitdepth?: number;
|
|
108
|
+
};
|
|
109
|
+
};
|
|
89
110
|
export type ConverterOptions = {
|
|
90
111
|
resize?: number | {
|
|
91
112
|
width?: number;
|
|
@@ -103,6 +124,6 @@ export type ConverterOptions = {
|
|
|
103
124
|
withoutReduction?: Boolean;
|
|
104
125
|
fastShrinkOnLoad?: Boolean;
|
|
105
126
|
};
|
|
106
|
-
format?:
|
|
127
|
+
format?: 'jpeg' | 'jpg' | 'png' | 'gif' | 'webp' | 'avif' | 'heif' | 'tiff' | 'raw' | jpeg | png | gif | webp | avif | heif;
|
|
107
128
|
};
|
|
108
129
|
export {};
|
|
@@ -5,19 +5,14 @@
|
|
|
5
5
|
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
6
|
*/
|
|
7
7
|
import type { LucidOptions } from '../types/attachment.js';
|
|
8
|
-
import type { Input } from '../types/input.js';
|
|
9
8
|
import type { ModelWithAttachment } from '../types/mixin.js';
|
|
10
9
|
export declare function getAttachmentAttributeNames(modelInstance: ModelWithAttachment): string[];
|
|
11
10
|
export declare function getDirtyAttachmentAttributeNames(modelInstance: ModelWithAttachment): string[];
|
|
12
11
|
export declare function getOptions(modelInstance: ModelWithAttachment, attributeName: string): LucidOptions;
|
|
13
|
-
export declare function createAttachmentAttributes(input: Input, name?: string): Promise<{
|
|
14
|
-
originalName: string;
|
|
15
|
-
extname: import("file-type").FileExtension;
|
|
16
|
-
mimeType: import("file-type").MimeType;
|
|
17
|
-
size: number;
|
|
18
|
-
}>;
|
|
19
12
|
export declare function cleanObject(obj: any): any;
|
|
20
13
|
export declare function clone(object: Object): any;
|
|
21
14
|
export declare function use(module: string): Promise<any>;
|
|
22
15
|
export declare function bufferToTempFile(input: Buffer): Promise<string>;
|
|
16
|
+
export declare function streamToTempFile(input: NodeJS.ReadableStream): Promise<string>;
|
|
17
|
+
export declare function downloadToTempFile(input: URL): Promise<string>;
|
|
23
18
|
export declare function isBase64(str: string): boolean;
|
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import os from 'node:os';
|
|
8
8
|
import path from 'node:path';
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
9
|
+
import https from 'node:https';
|
|
10
|
+
import fs from 'node:fs/promises';
|
|
11
|
+
import { pipeline } from 'node:stream';
|
|
12
|
+
import { promisify } from 'node:util';
|
|
13
|
+
import { createWriteStream } from 'node:fs';
|
|
13
14
|
import { Attachment } from '../attachments/attachment.js';
|
|
14
15
|
import * as errors from '../errors.js';
|
|
15
16
|
import { optionsSym } from './symbols.js';
|
|
17
|
+
const streamPipeline = promisify(pipeline);
|
|
16
18
|
export function getAttachmentAttributeNames(modelInstance) {
|
|
17
19
|
return Object.keys(modelInstance.$attributes).filter((attr) => modelInstance.$attributes[attr] instanceof Attachment);
|
|
18
20
|
}
|
|
@@ -23,27 +25,6 @@ export function getDirtyAttachmentAttributeNames(modelInstance) {
|
|
|
23
25
|
export function getOptions(modelInstance, attributeName) {
|
|
24
26
|
return modelInstance.constructor.prototype[optionsSym]?.[attributeName];
|
|
25
27
|
}
|
|
26
|
-
export async function createAttachmentAttributes(input, name) {
|
|
27
|
-
let fileType;
|
|
28
|
-
if (Buffer.isBuffer(input)) {
|
|
29
|
-
fileType = await fileTypeFromBuffer(input);
|
|
30
|
-
}
|
|
31
|
-
else {
|
|
32
|
-
fileType = await fileTypeFromFile(input);
|
|
33
|
-
}
|
|
34
|
-
if (name) {
|
|
35
|
-
name = string.slug(name);
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
name = `${cuid()}.${fileType.ext}`;
|
|
39
|
-
}
|
|
40
|
-
return {
|
|
41
|
-
originalName: name,
|
|
42
|
-
extname: fileType.ext,
|
|
43
|
-
mimeType: fileType.mime,
|
|
44
|
-
size: input.length,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
28
|
export function cleanObject(obj) {
|
|
48
29
|
if (obj === null || typeof obj !== 'object') {
|
|
49
30
|
return obj;
|
|
@@ -83,6 +64,37 @@ export async function bufferToTempFile(input) {
|
|
|
83
64
|
await fs.writeFile(tempFilePath, input);
|
|
84
65
|
return tempFilePath;
|
|
85
66
|
}
|
|
67
|
+
// TODO
|
|
68
|
+
// gestion des erreurs
|
|
69
|
+
export async function streamToTempFile(input) {
|
|
70
|
+
const folder = os.tmpdir();
|
|
71
|
+
const tempFilePath = path.join(folder, `tempfile-${Date.now()}.tmp`);
|
|
72
|
+
const writeStream = createWriteStream(tempFilePath);
|
|
73
|
+
try {
|
|
74
|
+
await streamPipeline(input, writeStream);
|
|
75
|
+
return tempFilePath;
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw new errors.E_CANNOT_GENERATE_TEMP_FILE([err.message]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export async function downloadToTempFile(input) {
|
|
82
|
+
return await new Promise((resolve) => {
|
|
83
|
+
https
|
|
84
|
+
.get(input, (response) => {
|
|
85
|
+
if (response.statusCode === 200) {
|
|
86
|
+
resolve(streamToTempFile(response));
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
// reject(`${response.statusCode}`)
|
|
90
|
+
throw new errors.E_CANNOT_GENERATE_TEMP_FILE(['']);
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
.on('error', (err) => {
|
|
94
|
+
throw new errors.E_CANNOT_GENERATE_TEMP_FILE([err.message]);
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
}
|
|
86
98
|
export function isBase64(str) {
|
|
87
99
|
const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
88
100
|
if (!base64Regex.test(str)) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
export declare const afterFindHook: (instance: unknown) => Promise<void>;
|
|
8
|
+
export declare const afterFetchHook: (instance: unknown) => Promise<void>;
|
|
9
|
+
export declare const beforeSaveHook: (instance: unknown) => Promise<void>;
|
|
10
|
+
export declare const afterSaveHook: (instance: unknown) => Promise<void>;
|
|
11
|
+
export declare const beforeDeleteHook: (instance: unknown) => Promise<void>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jrmc/adonis-attachment
|
|
3
|
+
*
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
|
|
6
|
+
*/
|
|
7
|
+
import { persistAttachment, commit, rollback, generateVariants, preComputeUrl, } from '../utils/actions.js';
|
|
8
|
+
import { clone, getAttachmentAttributeNames, getDirtyAttachmentAttributeNames, } from '../utils/helpers.js';
|
|
9
|
+
import { defaultStateAttributeMixin } from '../utils/default_values.js';
|
|
10
|
+
// @afterFind()
|
|
11
|
+
export const afterFindHook = async (instance) => {
|
|
12
|
+
const modelInstance = instance;
|
|
13
|
+
const attachmentAttributeNames = getAttachmentAttributeNames(modelInstance);
|
|
14
|
+
await Promise.all(attachmentAttributeNames.map((attributeName) => {
|
|
15
|
+
return preComputeUrl(modelInstance, attributeName);
|
|
16
|
+
}));
|
|
17
|
+
};
|
|
18
|
+
// @afterFetch()
|
|
19
|
+
// @afterPaginate()
|
|
20
|
+
export const afterFetchHook = async (instance) => {
|
|
21
|
+
const modelInstances = instance;
|
|
22
|
+
await Promise.all(modelInstances.map((row) => afterFindHook(row)));
|
|
23
|
+
};
|
|
24
|
+
// @beforeSave()
|
|
25
|
+
export const beforeSaveHook = async (instance) => {
|
|
26
|
+
const modelInstance = instance;
|
|
27
|
+
const attachmentAttributeNames = getDirtyAttachmentAttributeNames(modelInstance);
|
|
28
|
+
/**
|
|
29
|
+
* Empty previous $attachments
|
|
30
|
+
*/
|
|
31
|
+
modelInstance.$attachments = clone(defaultStateAttributeMixin);
|
|
32
|
+
/**
|
|
33
|
+
* Set attributes Attachment type modified
|
|
34
|
+
*/
|
|
35
|
+
attachmentAttributeNames.forEach((attributeName) => modelInstance.$attachments.attributesModified.push(attributeName));
|
|
36
|
+
/**
|
|
37
|
+
* Persist attachments before saving the model to the database. This
|
|
38
|
+
* way if file saving fails we will not write anything to the
|
|
39
|
+
* database
|
|
40
|
+
*/
|
|
41
|
+
await Promise.all(attachmentAttributeNames.map((attributeName) => persistAttachment(modelInstance, attributeName)));
|
|
42
|
+
try {
|
|
43
|
+
if (modelInstance.$trx) {
|
|
44
|
+
modelInstance.$trx.after('commit', () => commit(modelInstance));
|
|
45
|
+
modelInstance.$trx.after('rollback', () => rollback(modelInstance));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
await commit(modelInstance);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
await rollback(modelInstance);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
// @afterSave()
|
|
57
|
+
export const afterSaveHook = async (instance) => {
|
|
58
|
+
const modelInstance = instance;
|
|
59
|
+
const attachmentAttributeNames = getAttachmentAttributeNames(modelInstance);
|
|
60
|
+
/**
|
|
61
|
+
* For all properties Attachment
|
|
62
|
+
* Launch async generation variants
|
|
63
|
+
*/
|
|
64
|
+
await Promise.all(attachmentAttributeNames.map((attributeName) => {
|
|
65
|
+
if (modelInstance.$attachments.attributesModified.includes(attributeName)) {
|
|
66
|
+
return generateVariants(modelInstance, attributeName);
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
};
|
|
70
|
+
// @beforeDelete()
|
|
71
|
+
export const beforeDeleteHook = async (instance) => {
|
|
72
|
+
const modelInstance = instance;
|
|
73
|
+
const attachmentAttributeNames = getAttachmentAttributeNames(modelInstance);
|
|
74
|
+
/**
|
|
75
|
+
* Mark all attachments for deletion
|
|
76
|
+
*/
|
|
77
|
+
attachmentAttributeNames.map((attributeName) => {
|
|
78
|
+
if (modelInstance.$attributes[attributeName]) {
|
|
79
|
+
modelInstance.$attachments.detached.push(modelInstance.$attributes[attributeName]);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
/**
|
|
83
|
+
* If model is using transaction, then wait for the transaction
|
|
84
|
+
* to settle
|
|
85
|
+
*/
|
|
86
|
+
if (modelInstance.$trx) {
|
|
87
|
+
modelInstance.$trx.after('commit', () => commit(modelInstance));
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
await commit(modelInstance);
|
|
91
|
+
}
|
|
92
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jrmc/adonis-attachment",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Turn any field on your Lucid model to an attachment data type",
|
|
6
6
|
"engines": {
|
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
"format": "prettier --write .",
|
|
47
47
|
"docs:dev": "vitepress dev docs",
|
|
48
48
|
"docs:build": "vitepress build docs",
|
|
49
|
-
"docs:preview": "vitepress preview docs"
|
|
49
|
+
"docs:preview": "vitepress preview docs",
|
|
50
|
+
"test": "c8 npm run quick:test",
|
|
51
|
+
"quick:test": "node --import=./tsnode.esm.js --enable-source-maps bin/test.ts"
|
|
50
52
|
},
|
|
51
53
|
"exports": {
|
|
52
54
|
".": "./build/index.js",
|
|
@@ -62,23 +64,39 @@
|
|
|
62
64
|
"./attachment_provider": "./build/providers/attachment_provider.js"
|
|
63
65
|
},
|
|
64
66
|
"dependencies": {
|
|
65
|
-
"@poppinss/defer": "^1.1.
|
|
66
|
-
"exifreader": "^4.
|
|
67
|
-
"file-type": "^19.
|
|
67
|
+
"@poppinss/defer": "^1.1.1",
|
|
68
|
+
"exifreader": "^4.26.0",
|
|
69
|
+
"file-type": "^19.6.0",
|
|
70
|
+
"mime-types": "^2.1.35"
|
|
68
71
|
},
|
|
69
72
|
"devDependencies": {
|
|
70
|
-
"@adonisjs/assembler": "^7.
|
|
71
|
-
"@adonisjs/core": "^6.
|
|
73
|
+
"@adonisjs/assembler": "^7.8.2",
|
|
74
|
+
"@adonisjs/core": "^6.17.1",
|
|
72
75
|
"@adonisjs/drive": "^3.2.0",
|
|
73
|
-
"@adonisjs/lucid": "^
|
|
74
|
-
"@adonisjs/prettier-config": "^1.
|
|
75
|
-
"@adonisjs/tsconfig": "^1.
|
|
76
|
-
"@
|
|
76
|
+
"@adonisjs/lucid": "^21.6.0",
|
|
77
|
+
"@adonisjs/prettier-config": "^1.4.0",
|
|
78
|
+
"@adonisjs/tsconfig": "^1.4.0",
|
|
79
|
+
"@japa/assert": "^4.0.1",
|
|
80
|
+
"@japa/expect-type": "^2.0.3",
|
|
81
|
+
"@japa/file-system": "^2.3.2",
|
|
82
|
+
"@japa/plugin-adonisjs": "^4.0.0",
|
|
83
|
+
"@japa/runner": "^4.1.0",
|
|
84
|
+
"@poppinss/utils": "^6.9.2",
|
|
85
|
+
"@swc/core": "^1.10.7",
|
|
86
|
+
"@types/luxon": "^3.4.2",
|
|
87
|
+
"@types/mime-types": "^2.1.4",
|
|
88
|
+
"@types/node": "^22.10.7",
|
|
89
|
+
"@types/sinon": "^17.0.3",
|
|
90
|
+
"better-sqlite3": "^11.8.0",
|
|
91
|
+
"c8": "^10.1.3",
|
|
77
92
|
"copyfiles": "^2.4.1",
|
|
78
|
-
"del-cli": "^
|
|
79
|
-
"
|
|
80
|
-
"
|
|
81
|
-
"
|
|
93
|
+
"del-cli": "^6.0.0",
|
|
94
|
+
"flydrive": "^1.1.0",
|
|
95
|
+
"luxon": "^3.5.0",
|
|
96
|
+
"prettier": "^3.4.2",
|
|
97
|
+
"ts-node": "^10.9.2",
|
|
98
|
+
"typescript": "^5.7.3",
|
|
99
|
+
"vitepress": "^1.5.0"
|
|
82
100
|
},
|
|
83
101
|
"peerDependencies": {
|
|
84
102
|
"@adonisjs/core": "^6.12.1",
|
|
@@ -86,6 +104,15 @@
|
|
|
86
104
|
"@adonisjs/lucid": "^20.6.0 || ^21.0.0"
|
|
87
105
|
},
|
|
88
106
|
"prettier": "@adonisjs/prettier-config",
|
|
107
|
+
"c8": {
|
|
108
|
+
"reporter": [
|
|
109
|
+
"text",
|
|
110
|
+
"html"
|
|
111
|
+
],
|
|
112
|
+
"exclude": [
|
|
113
|
+
"tests/**"
|
|
114
|
+
]
|
|
115
|
+
},
|
|
89
116
|
"publishConfig": {
|
|
90
117
|
"access": "public",
|
|
91
118
|
"tag": "latest"
|