feat: added drive & upd deps

This commit is contained in:
Sergey Yarkov 2021-09-04 22:58:39 +03:00
parent 697c0bdb9b
commit bd27dfb1dc
9 changed files with 1226 additions and 9078 deletions

View File

@ -1,5 +1,6 @@
import { MultipartFileContract } from '@ioc:Adonis/Core/BodyParser'; import { MultipartFileContract } from '@ioc:Adonis/Core/BodyParser';
import CloudinaryService from '@ioc:Adonis/Addons/Cloudinary'; // import CloudinaryService from '@ioc:Adonis/Addons/Cloudinary';
import Drive from '@ioc:Adonis/Core/Drive';
import Image from 'App/Models/Image'; import Image from 'App/Models/Image';
export default class ImageRepository { export default class ImageRepository {
@ -19,6 +20,24 @@ export default class ImageRepository {
return images; return images;
} }
public async create(file: MultipartFileContract): Promise<Image> {
await file.moveToDisk('./images');
const image = await this.Image.create({ name: file.clientName, path: file.filePath, ext: file.extname });
return image;
}
public async delete(id: number): Promise<Image | null> {
const image = await this.Image.query().where('id', id).first();
if (image) {
await Drive.delete(image.path);
await image.delete();
return image;
}
return null;
}
/** /**
* Create image in cloudinary cloud * Create image in cloudinary cloud
* *
@ -26,11 +45,11 @@ export default class ImageRepository {
* @param publicId Image public id * @param publicId Image public id
* @returns Created image * @returns Created image
*/ */
public async createInCloudinaryCloud(file: MultipartFileContract, publicId: string | undefined): Promise<Image> { // public async createInCloudinaryCloud(file: MultipartFileContract, publicId: string | undefined): Promise<Image> {
const response = await CloudinaryService.upload(file, publicId); // const response = await CloudinaryService.upload(file, publicId);
const image = await this.Image.create({ name: publicId, path: response.secure_url, ext: response.format }); // const image = await this.Image.create({ name: publicId, path: response.secure_url, ext: response.format });
return image; // return image;
} // }
/** /**
* Delete image from cloudinary cloud * Delete image from cloudinary cloud
@ -38,15 +57,15 @@ export default class ImageRepository {
* @param id Image id * @param id Image id
* @returns Result or null * @returns Result or null
*/ */
public async deleteFormCloudinaryCloud(id: number): Promise<Image | null> { // public async deleteFormCloudinaryCloud(id: number): Promise<Image | null> {
const image = await this.Image.query().where('id', id).first(); // const image = await this.Image.query().where('id', id).first();
if (image) { // if (image) {
await CloudinaryService.destroy(image.name); // await CloudinaryService.destroy(image.name);
await image.delete(); // await image.delete();
return image; // return image;
} // }
return null; // return null;
} // }
} }

View File

@ -1,5 +1,4 @@
import { inject, Ioc } from '@adonisjs/core/build/standalone'; import { inject, Ioc } from '@adonisjs/core/build/standalone';
import { cuid } from '@ioc:Adonis/Core/Helpers';
import StatusCodeEnum from 'App/Datatypes/Enums/StatusCodeEnum'; import StatusCodeEnum from 'App/Datatypes/Enums/StatusCodeEnum';
import IResponse from 'App/Datatypes/Interfaces/IResponse'; import IResponse from 'App/Datatypes/Interfaces/IResponse';
import ImageRepository from 'App/Repositories/ImageRepository'; import ImageRepository from 'App/Repositories/ImageRepository';
@ -48,7 +47,7 @@ export default class ImageService {
} }
public async createImage(data: CreateImageValidator['schema']['props']): Promise<IResponse> { public async createImage(data: CreateImageValidator['schema']['props']): Promise<IResponse> {
const image = await this.imageRepository.createInCloudinaryCloud(data.image, cuid()); const image = await this.imageRepository.create(data.image);
return { return {
success: true, success: true,
@ -59,7 +58,7 @@ export default class ImageService {
} }
public async deleteImage(id: number): Promise<IResponse> { public async deleteImage(id: number): Promise<IResponse> {
const image = await this.imageRepository.deleteFormCloudinaryCloud(id); const image = await this.imageRepository.delete(id);
if (!image) { if (!image) {
return { return {

View File

@ -5,7 +5,7 @@ export default class ChangePasswordValidator {
constructor(protected ctx: HttpContextContract) {} constructor(protected ctx: HttpContextContract) {}
public schema = schema.create({ public schema = schema.create({
oldPassword: schema.string(), oldPassword: schema.string({}, [rules.maxLength(128)]),
newPassword: schema.string({}, [rules.minLength(6), rules.maxLength(128)]), newPassword: schema.string({}, [rules.minLength(6), rules.maxLength(128)]),
}); });

148
config/drive.ts Normal file
View File

@ -0,0 +1,148 @@
/**
* Config source: https://git.io/JBt3o
*
* Feel free to let us know via PR, if you find something broken in this config
* file.
*/
import Env from '@ioc:Adonis/Core/Env';
import { DriveConfig } from '@ioc:Adonis/Core/Drive';
import Application from '@ioc:Adonis/Core/Application';
/*
|--------------------------------------------------------------------------
| Drive Config
|--------------------------------------------------------------------------
|
| The `DriveConfig` relies on the `DisksList` interface which is
| defined inside the `contracts` directory.
|
*/
const driveConfig: DriveConfig = {
/*
|--------------------------------------------------------------------------
| Default disk
|--------------------------------------------------------------------------
|
| The default disk to use for managing file uploads. The value is driven by
| the `DRIVE_DISK` environment variable.
|
*/
disk: Env.get('DRIVE_DISK'),
disks: {
/*
|--------------------------------------------------------------------------
| Local
|--------------------------------------------------------------------------
|
| Uses the local file system to manage files. Make sure to turn off serving
| files when not using this disk.
|
*/
local: {
driver: 'local',
visibility: 'public',
/*
|--------------------------------------------------------------------------
| Storage root - Local driver only
|--------------------------------------------------------------------------
|
| Define an absolute path to the storage directory from where to read the
| files.
|
*/
root: Application.tmpPath('uploads'),
/*
|--------------------------------------------------------------------------
| Serve files - Local driver only
|--------------------------------------------------------------------------
|
| When this is set to true, AdonisJS will configure a files server to serve
| files from the disk root. This is done to mimic the behavior of cloud
| storage services that has inbuilt capabilities to serve files.
|
*/
serveFiles: true,
/*
|--------------------------------------------------------------------------
| Base path - Local driver only
|--------------------------------------------------------------------------
|
| Base path is always required when "serveFiles = true". Also make sure
| the `basePath` is unique across all the disks using "local" driver and
| you are not registering routes with this prefix.
|
*/
basePath: '/uploads',
},
/*
|--------------------------------------------------------------------------
| S3 Driver
|--------------------------------------------------------------------------
|
| Uses the S3 cloud storage to manage files. Make sure to install the s3
| drive separately when using it.
|
|**************************************************************************
| npm i @adonisjs/drive-s3
|**************************************************************************
|
*/
// s3: {
// driver: 's3',
// visibility: 'public',
// key: Env.get('S3_KEY'),
// secret: Env.get('S3_SECRET'),
// region: Env.get('S3_REGION'),
// bucket: Env.get('S3_BUCKET'),
// endpoint: Env.get('S3_ENDPOINT'),
// },
/*
|--------------------------------------------------------------------------
| GCS Driver
|--------------------------------------------------------------------------
|
| Uses the Google cloud storage to manage files. Make sure to install the GCS
| drive separately when using it.
|
|**************************************************************************
| npm i @adonisjs/drive-gcs
|**************************************************************************
|
*/
// gcs: {
// driver: 'gcs',
// visibility: 'public',
// keyFilename: Env.get('GCS_KEY_FILENAME'),
// bucket: Env.get('GCS_BUCKET'),
/*
|--------------------------------------------------------------------------
| Uniform ACL - Google cloud storage only
|--------------------------------------------------------------------------
|
| When using the Uniform ACL on the bucket, the "visibility" option is
| ignored. Since, the files ACL is managed by the google bucket policies
| directly.
|
|**************************************************************************
| Learn more: https://cloud.google.com/storage/docs/uniform-bucket-level-access
|**************************************************************************
|
| The following option just informs drive whether your bucket is using uniform
| ACL or not. The actual setting needs to be toggled within the Google cloud
| console.
|
*/
// usingUniformAcl: false
// },
},
};
export default driveConfig;

23
contracts/drive.ts Normal file
View File

@ -0,0 +1,23 @@
/**
* Contract source: https://git.io/JBt3I
*
* Feel free to let us know via PR, if you find something broken in this contract
* file.
*/
declare module '@ioc:Adonis/Core/Drive' {
interface DisksList {
local: {
config: LocalDriverConfig;
implementation: LocalDriverContract;
};
// s3: {
// config: S3DriverConfig
// implementation: S3DriverContract
// }
// gcs: {
// config: GcsDriverConfig
// implementation: GcsDriverContract
// }
}
}

1
env.ts
View File

@ -20,6 +20,7 @@ export default Env.rules({
APP_KEY: Env.schema.string(), APP_KEY: Env.schema.string(),
APP_NAME: Env.schema.string(), APP_NAME: Env.schema.string(),
NODE_ENV: Env.schema.enum(['development', 'production', 'testing'] as const), NODE_ENV: Env.schema.enum(['development', 'production', 'testing'] as const),
DRIVE_DISK: Env.schema.string(),
PG_HOST: Env.schema.string({ format: 'host' }), PG_HOST: Env.schema.string({ format: 'host' }),
PG_PORT: Env.schema.number(), PG_PORT: Env.schema.number(),
PG_USER: Env.schema.string(), PG_USER: Env.schema.string(),

9973
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,32 +15,32 @@
"db:seed:force": "node ace seed --force" "db:seed:force": "node ace seed --force"
}, },
"devDependencies": { "devDependencies": {
"@adonisjs/assembler": "^5.3.2", "@adonisjs/assembler": "^5.3.7",
"@typescript-eslint/eslint-plugin": "^4.28.2", "@typescript-eslint/eslint-plugin": "^4.30.0",
"@typescript-eslint/parser": "^4.28.2", "@typescript-eslint/parser": "^4.30.0",
"adonis-preset-ts": "^2.1.0", "adonis-preset-ts": "^2.1.0",
"eslint": "^7.30.0", "eslint": "^7.32.0",
"eslint-config-airbnb-base": "^14.2.1", "eslint-config-airbnb-base": "^14.2.1",
"eslint-config-airbnb-typescript": "^12.3.1", "eslint-config-airbnb-typescript": "^12.3.1",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.23.4", "eslint-plugin-import": "^2.24.2",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.1",
"pino-pretty": "^5.1.1", "pino-pretty": "^5.1.3",
"prettier": "^2.3.2", "prettier": "^2.3.2",
"typescript": "^4.2.4", "typescript": "^4.4.2",
"youch": "^2.2.2", "youch": "^2.2.2",
"youch-terminal": "^1.1.1" "youch-terminal": "^1.1.1"
}, },
"dependencies": { "dependencies": {
"@adonisjs/auth": "^8.0.7", "@adonisjs/auth": "^8.0.9",
"@adonisjs/core": "^5.1.9", "@adonisjs/core": "^5.3.2",
"@adonisjs/lucid": "^15.0.3", "@adonisjs/lucid": "^15.0.3",
"@adonisjs/redis": "^7.0.7", "@adonisjs/redis": "^7.0.9",
"@adonisjs/repl": "^3.1.4", "@adonisjs/repl": "^3.1.6",
"cloudinary": "^1.26.3", "cloudinary": "^1.26.3",
"luxon": "^1.28.0", "luxon": "^1.28.0",
"nanoid": "^3.1.23", "nanoid": "^3.1.25",
"pg": "^8.6.0", "pg": "^8.7.1",
"phc-bcrypt": "^1.0.7", "phc-bcrypt": "^1.0.7",
"proxy-addr": "^2.0.7", "proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",

View File

@ -6,6 +6,7 @@
"outDir": "build", "outDir": "build",
"rootDir": "./", "rootDir": "./",
"sourceMap": true, "sourceMap": true,
"useDefineForClassFields": true,
"paths": { "paths": {
"App/*": ["./app/*"], "App/*": ["./app/*"],
"Config/*": ["./config/*"], "Config/*": ["./config/*"],