mirror of
https://github.com/sergeyyarkov/educt-server.git
synced 2026-10-11 18:29:15 +03:00
feat: added drive & upd deps
This commit is contained in:
parent
697c0bdb9b
commit
bd27dfb1dc
@ -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;
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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
148
config/drive.ts
Normal 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
23
contracts/drive.ts
Normal 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
1
env.ts
@ -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(),
|
||||||
|
|||||||
10047
package-lock.json
generated
10047
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
28
package.json
28
package.json
@ -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",
|
||||||
|
|||||||
@ -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/*"],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user