diff --git a/.adonisrc.json b/.adonisrc.json index e25a497..e444ba7 100644 --- a/.adonisrc.json +++ b/.adonisrc.json @@ -24,7 +24,12 @@ "Database": "database", "Contracts": "contracts" }, - "preloads": ["./routes/index", "./start/kernel", "./start/event", "./start/bouncer"], + "preloads": [ + "./routes/index", + "./start/kernel", + "./start/event", + "./start/bouncer" + ], "providers": [ "./providers/AppProvider", "@adonisjs/core", @@ -34,9 +39,12 @@ "@adonisjs/mail", "@adonisjs/view", "@adonisjs/attachment-lite", - "@adonisjs/bouncer" + "@adonisjs/bouncer", + "@adonisjs/drive-s3" + ], + "aceProviders": [ + "@adonisjs/repl" ], - "aceProviders": ["@adonisjs/repl"], "metaFiles": [ { "pattern": "resources/views/**/*.edge", diff --git a/.env.example b/.env.example index 2dbe8bf..930d2db 100644 --- a/.env.example +++ b/.env.example @@ -19,3 +19,8 @@ SMTP_PASSWORD= MAILGUN_API_KEY= MAILGUN_DOMAIN= CACHE_VIEWS=false +S3_KEY=dummyKey +S3_SECRET=dummySecret +S3_BUCKET=dummyBucket +S3_REGION=dummyRegion +S3_ENDPOINT=dummyEndpoint diff --git a/ace-manifest.json b/ace-manifest.json index 0b1c0f2..d8e5080 100644 --- a/ace-manifest.json +++ b/ace-manifest.json @@ -83,7 +83,9 @@ ] }, "make:model": { - "settings": {}, + "settings": { + "loadApp": true + }, "commandPath": "@adonisjs/lucid/build/commands/MakeModel", "commandName": "make:model", "description": "Make a new Lucid model", diff --git a/app/Controllers/Http/Api/v1/LessonsController.ts b/app/Controllers/Http/Api/v1/LessonsController.ts index 010e413..f25f214 100644 --- a/app/Controllers/Http/Api/v1/LessonsController.ts +++ b/app/Controllers/Http/Api/v1/LessonsController.ts @@ -1,7 +1,7 @@ -import Application from '@ioc:Adonis/Core/Application'; import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone'; import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import { schema } from '@ioc:Adonis/Core/Validator'; +import { extname } from 'path'; /** * Services @@ -19,6 +19,7 @@ import LessonMaterial from 'App/Models/LessonMaterial'; import CreateLessonValidator from 'App/Validators/Lesson/CreateLessonValidator'; import UpdateLessonValidator from 'App/Validators/Lesson/UpdateLessonValidator'; +import Drive from '@ioc:Adonis/Core/Drive'; import BaseController from '../../BaseController'; @inject() @@ -118,11 +119,11 @@ export default class LessonsController extends BaseController { /** * Get lesson materials by file name - * GET /lessons/materials/:file + * GET /lessons/materials/:fileName */ public async getMaterial(ctx: HttpContextContract) { - const { file } = ctx.request.params(); - const { data, message, status, success, error } = await this.lessonService.fetchMaterialFile(ctx, file); + const { fileName } = ctx.request.params(); + const { data, message, status, success, error } = await this.lessonService.fetchMaterialFile(ctx, fileName); if (!success && error) { throw new Exception(message, status, error.code); @@ -132,8 +133,21 @@ export default class LessonsController extends BaseController { * Send file to user */ if (data instanceof LessonMaterial) { - const path = Application.makePath(data.url); - return this.sendFile(ctx, path, data.clientName); + const path = `materials/${data.name}`; + + /** + * Material file not found + */ + if (!(await Drive.exists(path))) return ctx.response.notFound(); + + const { size } = await Drive.getStats(path); + + ctx.response.type(extname(data.name)); + ctx.response.header('content-length', size); + + const stream = await Drive.getStream(path); + + return this.sendStream(ctx, stream); } return this.sendResponse(ctx, data, message, status); diff --git a/app/Controllers/Http/BaseController.ts b/app/Controllers/Http/BaseController.ts index ea36c24..960eced 100644 --- a/app/Controllers/Http/BaseController.ts +++ b/app/Controllers/Http/BaseController.ts @@ -14,6 +14,10 @@ export default class BaseController { return ctx.response.status(response.status).send(response); } + public sendStream(ctx: HttpContextContract, ...args: Parameters) { + return ctx.response.stream(...args); + } + public sendFile(ctx: HttpContextContract, ...args: Parameters) { return ctx.response.attachment(...args); } diff --git a/app/Models/LessonMaterial.ts b/app/Models/LessonMaterial.ts index 4958ba5..87f37a8 100644 --- a/app/Models/LessonMaterial.ts +++ b/app/Models/LessonMaterial.ts @@ -7,9 +7,6 @@ export default class LessonMaterial extends BaseModel { @column({ isPrimary: true }) public id: number; - @column() - public url: string; - @column() public name: string; diff --git a/app/Repositories/LessonRepository.ts b/app/Repositories/LessonRepository.ts index 867d612..1f18662 100644 --- a/app/Repositories/LessonRepository.ts +++ b/app/Repositories/LessonRepository.ts @@ -1,4 +1,5 @@ import Drive from '@ioc:Adonis/Core/Drive'; +import { cuid } from '@ioc:Adonis/Core/Helpers'; /** * Models @@ -59,16 +60,27 @@ export default class LessonRepository { } /** - * Get lesson material + * Get lesson material by name * * @param fileName Name of file - * @returns Lesson material file or null + * @returns Lesson material or null */ public async getMaterialFileByName(fileName: string): Promise { const material = await this.LessonMaterial.query().where('name', fileName).first(); return material; } + /** + * Get lesson material by id + * + * @param id Material id + * @returns Lesson material or null + */ + public async getMaterialFileById(id: number): Promise { + const material = await this.LessonMaterial.query().where('id', id).first(); + return material; + } + /** * Create lesson * @@ -104,8 +116,9 @@ export default class LessonRepository { */ const files = await Promise.all( data.materials.map(async file => { - await file.moveToDisk('materials'); - return file; + const name = `${cuid()}.${file.extname}`; + await file.moveToDisk('materials', { name }); + return { file, name }; }) ); @@ -113,16 +126,14 @@ export default class LessonRepository { * Create lesson material */ const materials = await Promise.all( - files.map(async file => { + files.map(async ({ file, name }) => { if (file.state === 'moved' && file.fileName && file.extname) { - const url = await this.Drive.getUrl(`materials/${file.fileName}`); const material = new LessonMaterial(); - material.name = file.fileName; + material.name = name; material.size = file.size; material.clientName = file.clientName; material.ext = file.extname; - material.url = url; return material; } diff --git a/app/Services/LessonService.ts b/app/Services/LessonService.ts index 3eaef25..ed6992f 100644 --- a/app/Services/LessonService.ts +++ b/app/Services/LessonService.ts @@ -111,8 +111,8 @@ export default class LessonService { * @param fileName Name of file * @returns Response */ - public async fetchMaterialFile(ctx: HttpContextContract, fileName: string): Promise> { - const material = await this.lessonRepository.getMaterialFileByName(fileName); + public async fetchMaterialFile(ctx: HttpContextContract, name: string): Promise> { + const material = await this.lessonRepository.getMaterialFileByName(name); if (!material) { return { @@ -187,7 +187,7 @@ export default class LessonService { const progress = await this.lessonProgressRepository.get(user.id, lesson.id); - if (progress === null) { + if (!progress) { await this.lessonProgressRepository.create({ user_id: user.id, lesson_id: lesson.id, is_watched: true }); } diff --git a/config/drive.ts b/config/drive.ts index e957be5..74330f2 100644 --- a/config/drive.ts +++ b/config/drive.ts @@ -93,15 +93,15 @@ const driveConfig: DriveConfig = { |************************************************************************** | */ - // 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'), - // }, + s3: { + driver: 's3', + visibility: 'private', + 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'), + }, /* |-------------------------------------------------------------------------- diff --git a/contracts/drive.ts b/contracts/drive.ts index 2d64030..26f8333 100644 --- a/contracts/drive.ts +++ b/contracts/drive.ts @@ -4,10 +4,10 @@ declare module '@ioc:Adonis/Core/Drive' { config: LocalDriverConfig; implementation: LocalDriverContract; }; - // s3: { - // config: S3DriverConfig - // implementation: S3DriverContract - // } + s3: { + config: S3DriverConfig; + implementation: S3DriverContract; + }; // gcs: { // config: GcsDriverConfig // implementation: GcsDriverContract diff --git a/database/migrations/1637080400230_lesson_materials.ts b/database/migrations/1637080400230_lesson_materials.ts index a16936d..2763388 100644 --- a/database/migrations/1637080400230_lesson_materials.ts +++ b/database/migrations/1637080400230_lesson_materials.ts @@ -6,7 +6,6 @@ export default class LessonMaterials extends BaseSchema { public async up() { this.schema.createTable(this.tableName, table => { table.increments('id').primary(); - table.string('url').notNullable(); table.string('name').notNullable(); table.integer('size').notNullable(); table.string('client_name').notNullable(); diff --git a/env.ts b/env.ts index aed92d2..730aa6c 100644 --- a/env.ts +++ b/env.ts @@ -20,7 +20,7 @@ export default Env.rules({ APP_KEY: Env.schema.string(), APP_NAME: Env.schema.string(), NODE_ENV: Env.schema.enum(['development', 'production', 'testing'] as const), - DRIVE_DISK: Env.schema.enum(['local'] as const), + DRIVE_DISK: Env.schema.enum(['local', 's3'] as const), PG_HOST: Env.schema.string({ format: 'host' }), PG_PORT: Env.schema.number(), PG_USER: Env.schema.string(), @@ -36,4 +36,9 @@ export default Env.rules({ SMTP_PASSWORD: Env.schema.string(), MAILGUN_API_KEY: Env.schema.string(), MAILGUN_DOMAIN: Env.schema.string(), + S3_KEY: Env.schema.string(), + S3_SECRET: Env.schema.string(), + S3_BUCKET: Env.schema.string(), + S3_REGION: Env.schema.string(), + S3_ENDPOINT: Env.schema.string.optional(), }); diff --git a/package-lock.json b/package-lock.json index c08db4f..455091f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "server", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -508,6 +508,16 @@ } } }, + "@adonisjs/drive-s3": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@adonisjs/drive-s3/-/drive-s3-1.0.5.tgz", + "integrity": "sha512-Jny0CH0K02vt6fo4CNfInc/kh2FefZmjTSjWLWEl6Gyg/+2GIy6+/PBgRsk8hpTR+T4tGT4V5Cgs71aVZfbzeg==", + "requires": { + "@aws-sdk/client-s3": "^3.28.0", + "@aws-sdk/s3-request-presigner": "^3.28.0", + "get-stream": "^6.0.1" + } + }, "@adonisjs/encryption": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@adonisjs/encryption/-/encryption-4.0.5.tgz", @@ -1146,6 +1156,947 @@ "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz", "integrity": "sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==" }, + "@aws-crypto/crc32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-2.0.0.tgz", + "integrity": "sha512-TvE1r2CUueyXOuHdEigYjIZVesInd9KN+K/TFFNfkkxRThiNxO6i4ZqqAVMoEjAamZZ1AA8WXJkjCz7YShHPQA==", + "requires": { + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/ie11-detection": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/ie11-detection/-/ie11-detection-2.0.0.tgz", + "integrity": "sha512-pkVXf/dq6PITJ0jzYZ69VhL8VFOFoPZLZqtU/12SGnzYuJOOGNfF41q9GxdI1yqC8R13Rq3jOLKDFpUJFT5eTA==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-browser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-2.0.0.tgz", + "integrity": "sha512-rYXOQ8BFOaqMEHJrLHul/25ckWH6GTJtdLSajhlqGMx0PmSueAuvboCuZCTqEKlxR8CQOwRarxYMZZSYlhRA1A==", + "requires": { + "@aws-crypto/ie11-detection": "^2.0.0", + "@aws-crypto/sha256-js": "^2.0.0", + "@aws-crypto/supports-web-crypto": "^2.0.0", + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/sha256-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-2.0.0.tgz", + "integrity": "sha512-VZY+mCY4Nmrs5WGfitmNqXzaE873fcIZDu54cbaDaaamsaTOP1DBImV9F4pICc3EHjQXujyE8jig+PFCaew9ig==", + "requires": { + "@aws-crypto/util": "^2.0.0", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/supports-web-crypto": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-2.0.0.tgz", + "integrity": "sha512-Ge7WQ3E0OC7FHYprsZV3h0QIcpdyJLvIeg+uTuHqRYm8D6qCFJoiC+edSzSyFiHtZf+NOQDJ1q46qxjtzIY2nA==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-crypto/util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-2.0.1.tgz", + "integrity": "sha512-JJmFFwvbm08lULw4Nm5QOLg8+lAQeC8aCXK5xrtxntYzYXCGfHwUJ4Is3770Q7HmICsXthGQ+ZsDL7C2uH3yBQ==", + "requires": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@aws-sdk/abort-controller": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/abort-controller/-/abort-controller-3.40.0.tgz", + "integrity": "sha512-S7LzLvNuwuf0q7r4q7zqGzxd/W2xYsn8cpZ90MMb3ObolhbkLySrikUJujmXae8k+2/KFCOr+FVC0YLrATSUgQ==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/chunked-blob-reader": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader/-/chunked-blob-reader-3.37.0.tgz", + "integrity": "sha512-uDacnFaczeO962RnVttwAQddS4rgDfI7nfeY8NV6iZkDv5uxGzHTfH4jT7WvPDM1pSMcOMDx8RJ+Tmtsd1VTsA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/chunked-blob-reader-native": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/chunked-blob-reader-native/-/chunked-blob-reader-native-3.37.0.tgz", + "integrity": "sha512-h9OYq6EvDrpb7SKod+Kow+d3aRNFVBYR1a8G8ahEDDQe3AtmA2Smyvni4kt/ABTiKvYdof2//Pq3BL/IUV9n9Q==", + "requires": { + "@aws-sdk/util-base64-browser": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/client-s3": { + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.44.0.tgz", + "integrity": "sha512-vv3w5RhAZnT/LfiV0SICvvzv5SAeH61erbwm6FpKC9W7lGdcA6o7F2/Bls44fyMW41awYIRZKoPGZApYCrFR6A==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/client-sts": "3.43.0", + "@aws-sdk/config-resolver": "3.40.0", + "@aws-sdk/credential-provider-node": "3.41.0", + "@aws-sdk/eventstream-serde-browser": "3.40.0", + "@aws-sdk/eventstream-serde-config-resolver": "3.40.0", + "@aws-sdk/eventstream-serde-node": "3.40.0", + "@aws-sdk/fetch-http-handler": "3.40.0", + "@aws-sdk/hash-blob-browser": "3.40.0", + "@aws-sdk/hash-node": "3.40.0", + "@aws-sdk/hash-stream-node": "3.40.0", + "@aws-sdk/invalid-dependency": "3.40.0", + "@aws-sdk/md5-js": "3.40.0", + "@aws-sdk/middleware-apply-body-checksum": "3.40.0", + "@aws-sdk/middleware-bucket-endpoint": "3.41.0", + "@aws-sdk/middleware-content-length": "3.40.0", + "@aws-sdk/middleware-expect-continue": "3.40.0", + "@aws-sdk/middleware-host-header": "3.40.0", + "@aws-sdk/middleware-location-constraint": "3.40.0", + "@aws-sdk/middleware-logger": "3.40.0", + "@aws-sdk/middleware-retry": "3.40.0", + "@aws-sdk/middleware-sdk-s3": "3.41.0", + "@aws-sdk/middleware-serde": "3.40.0", + "@aws-sdk/middleware-signing": "3.40.0", + "@aws-sdk/middleware-ssec": "3.40.0", + "@aws-sdk/middleware-stack": "3.40.0", + "@aws-sdk/middleware-user-agent": "3.40.0", + "@aws-sdk/node-config-provider": "3.40.0", + "@aws-sdk/node-http-handler": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/smithy-client": "3.41.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/url-parser": "3.40.0", + "@aws-sdk/util-base64-browser": "3.37.0", + "@aws-sdk/util-base64-node": "3.37.0", + "@aws-sdk/util-body-length-browser": "3.37.0", + "@aws-sdk/util-body-length-node": "3.37.0", + "@aws-sdk/util-user-agent-browser": "3.40.0", + "@aws-sdk/util-user-agent-node": "3.40.0", + "@aws-sdk/util-utf8-browser": "3.37.0", + "@aws-sdk/util-utf8-node": "3.37.0", + "@aws-sdk/util-waiter": "3.40.0", + "@aws-sdk/xml-builder": "3.37.0", + "entities": "2.2.0", + "fast-xml-parser": "3.19.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/client-sso": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.41.0.tgz", + "integrity": "sha512-xDvcy7wv3KdHhOpl5fZN+Ydw+dHBmsCZwMFI1ZdJVCSGO+ZKgl5KVWi1LCif6vjZP1pUuGl44oDOZz1ACqOzTg==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.40.0", + "@aws-sdk/fetch-http-handler": "3.40.0", + "@aws-sdk/hash-node": "3.40.0", + "@aws-sdk/invalid-dependency": "3.40.0", + "@aws-sdk/middleware-content-length": "3.40.0", + "@aws-sdk/middleware-host-header": "3.40.0", + "@aws-sdk/middleware-logger": "3.40.0", + "@aws-sdk/middleware-retry": "3.40.0", + "@aws-sdk/middleware-serde": "3.40.0", + "@aws-sdk/middleware-stack": "3.40.0", + "@aws-sdk/middleware-user-agent": "3.40.0", + "@aws-sdk/node-config-provider": "3.40.0", + "@aws-sdk/node-http-handler": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/smithy-client": "3.41.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/url-parser": "3.40.0", + "@aws-sdk/util-base64-browser": "3.37.0", + "@aws-sdk/util-base64-node": "3.37.0", + "@aws-sdk/util-body-length-browser": "3.37.0", + "@aws-sdk/util-body-length-node": "3.37.0", + "@aws-sdk/util-user-agent-browser": "3.40.0", + "@aws-sdk/util-user-agent-node": "3.40.0", + "@aws-sdk/util-utf8-browser": "3.37.0", + "@aws-sdk/util-utf8-node": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/client-sts": { + "version": "3.43.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.43.0.tgz", + "integrity": "sha512-4CKYimjhIEixVtJH0Y8FR5FXc7zIepZtfScy8QHgH+DERXm/YL5cuUbkJiL6ZRTpek0vztVvE+mNSQU0z1eXag==", + "requires": { + "@aws-crypto/sha256-browser": "2.0.0", + "@aws-crypto/sha256-js": "2.0.0", + "@aws-sdk/config-resolver": "3.40.0", + "@aws-sdk/credential-provider-node": "3.41.0", + "@aws-sdk/fetch-http-handler": "3.40.0", + "@aws-sdk/hash-node": "3.40.0", + "@aws-sdk/invalid-dependency": "3.40.0", + "@aws-sdk/middleware-content-length": "3.40.0", + "@aws-sdk/middleware-host-header": "3.40.0", + "@aws-sdk/middleware-logger": "3.40.0", + "@aws-sdk/middleware-retry": "3.40.0", + "@aws-sdk/middleware-sdk-sts": "3.40.0", + "@aws-sdk/middleware-serde": "3.40.0", + "@aws-sdk/middleware-signing": "3.40.0", + "@aws-sdk/middleware-stack": "3.40.0", + "@aws-sdk/middleware-user-agent": "3.40.0", + "@aws-sdk/node-config-provider": "3.40.0", + "@aws-sdk/node-http-handler": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/smithy-client": "3.41.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/url-parser": "3.40.0", + "@aws-sdk/util-base64-browser": "3.37.0", + "@aws-sdk/util-base64-node": "3.37.0", + "@aws-sdk/util-body-length-browser": "3.37.0", + "@aws-sdk/util-body-length-node": "3.37.0", + "@aws-sdk/util-user-agent-browser": "3.40.0", + "@aws-sdk/util-user-agent-node": "3.40.0", + "@aws-sdk/util-utf8-browser": "3.37.0", + "@aws-sdk/util-utf8-node": "3.37.0", + "entities": "2.2.0", + "fast-xml-parser": "3.19.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/config-resolver": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/config-resolver/-/config-resolver-3.40.0.tgz", + "integrity": "sha512-QYy6J2k31QL6J74hPBfptnLW1kQYdN+xjwH4UQ1mv7EUhRoJN9ZY2soStJowFy4at6IIOOVWbyG5dyqvrbEovg==", + "requires": { + "@aws-sdk/signature-v4": "3.40.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-config-provider": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-env": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.40.0.tgz", + "integrity": "sha512-qHZdf2vxhzZkSygjw2I4SEYFL2dMZxxYvO4QlkqQouKY81OVxs/j69oiNCjPasQzGz5jaZZKI8xEAIfkSyr1lg==", + "requires": { + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-imds": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-imds/-/credential-provider-imds-3.40.0.tgz", + "integrity": "sha512-Ty/wVa+BQrCFrP06AGl5S1CeLifDt68YrlYXUnkRn603SX4DvxBgVO7XFeDH58G8ziDCiqxfmVl4yjbncPPeSw==", + "requires": { + "@aws-sdk/node-config-provider": "3.40.0", + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/url-parser": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-ini": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.41.0.tgz", + "integrity": "sha512-98CGEHg7Tb6HxK5ZIdbAcijvD3IpLe0ddse1xMe/Ilhjz770FS/L2UNprOP6PZTqrSfBffiMrvfThUSuUaTlIQ==", + "requires": { + "@aws-sdk/credential-provider-env": "3.40.0", + "@aws-sdk/credential-provider-imds": "3.40.0", + "@aws-sdk/credential-provider-sso": "3.41.0", + "@aws-sdk/credential-provider-web-identity": "3.41.0", + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-credentials": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-node": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.41.0.tgz", + "integrity": "sha512-5FW6+wNJgyDCsbAd+mLm/1DBTDkyIYOMVzcxbr6Vi3pM4UrMFdeLdAP62edYW8usg78Xg+c6vaAoEv/M3zkS0Q==", + "requires": { + "@aws-sdk/credential-provider-env": "3.40.0", + "@aws-sdk/credential-provider-imds": "3.40.0", + "@aws-sdk/credential-provider-ini": "3.41.0", + "@aws-sdk/credential-provider-process": "3.40.0", + "@aws-sdk/credential-provider-sso": "3.41.0", + "@aws-sdk/credential-provider-web-identity": "3.41.0", + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-credentials": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-process": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.40.0.tgz", + "integrity": "sha512-qsaNCDesW2GasDbzpeOA371gxugi05JWxt3EKonLbUfkGKBK7kmmL6EgLIxZuNm2/Ve4RS07PKp8yBGm4xIx9w==", + "requires": { + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-credentials": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-sso": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.41.0.tgz", + "integrity": "sha512-9s7SWu3RVIQ/MTcBCt35EMzxNQm3avivrbpSOKfJwxR5L+oNKPsV+gSqMlkNZGwOVJyUicIsZGcq/4ON6CjrOg==", + "requires": { + "@aws-sdk/client-sso": "3.41.0", + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-credentials": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/credential-provider-web-identity": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.41.0.tgz", + "integrity": "sha512-VqvVoEh9C8xTXl4stKyJC5IKQhS8g1Gi5k6B9HPHLIxFRRfKxkE73DT4pMN6npnus7o0yi0MTFGQFQGYSrFO2g==", + "requires": { + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/eventstream-marshaller": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-marshaller/-/eventstream-marshaller-3.40.0.tgz", + "integrity": "sha512-zHGchfkG3B9M8OOKRpByeS5g1/15YQ0+QQHwxQRtm/CPtKBAIAsCZRQaCNBLu9uQMtBBKj5JsDUcjirhGeSvIg==", + "requires": { + "@aws-crypto/crc32": "2.0.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-hex-encoding": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/eventstream-serde-browser": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-browser/-/eventstream-serde-browser-3.40.0.tgz", + "integrity": "sha512-V0AXAfSkhY0hgxDJ0cNA+r42kL8295U7UTCp2Q2fvCaob3wKWh+54KZ2L4IOYTlK3yNzXJ5V6PP1zUuRlsUTew==", + "requires": { + "@aws-sdk/eventstream-marshaller": "3.40.0", + "@aws-sdk/eventstream-serde-universal": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/eventstream-serde-config-resolver": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.40.0.tgz", + "integrity": "sha512-GgGiJBsQ1/SBTpRM/wCdFBCMo1Nybvy46bNVkH1ujCdp8UTLc5PozzNpH+15V2IQbc9sPDYffMab6HSFjDp5vw==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/eventstream-serde-node": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-node/-/eventstream-serde-node-3.40.0.tgz", + "integrity": "sha512-CnzX/JZGvhWlg+ooIPVZ78T+5wIm5Ld1BD7jwhlptJa8IjTMvkc8Nh4pAhc7T0ZScy4zZa/oTkqeVYCOVCyd1Q==", + "requires": { + "@aws-sdk/eventstream-marshaller": "3.40.0", + "@aws-sdk/eventstream-serde-universal": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/eventstream-serde-universal": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-serde-universal/-/eventstream-serde-universal-3.40.0.tgz", + "integrity": "sha512-rkHwVMyZJMhp9iBixkuaAGQNer/DPxZ9kxDDtE+LuAMhepTYQ8c4lUW0QQhYbNMWf48QKD1G4FV3JXIj9JfP9A==", + "requires": { + "@aws-sdk/eventstream-marshaller": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/fetch-http-handler": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/fetch-http-handler/-/fetch-http-handler-3.40.0.tgz", + "integrity": "sha512-w1HiZromoU+/bbEo89uO81l6UO/M+c2uOMnXntZqe6t3ZHUUUo3AbvhKh0QGVFqRQa+Oi0+95KqWmTHa72/9Iw==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/querystring-builder": "3.40.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-base64-browser": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/hash-blob-browser": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-blob-browser/-/hash-blob-browser-3.40.0.tgz", + "integrity": "sha512-l8xyprVVKKH+720VrQ677X6VkvHttDXB4MxkMuxhSvwYBQwsRzP2Wppo7xIAtWGoS+oqlLmD4LCbHdhFRcN5yA==", + "requires": { + "@aws-sdk/chunked-blob-reader": "3.37.0", + "@aws-sdk/chunked-blob-reader-native": "3.37.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/hash-node": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-node/-/hash-node-3.40.0.tgz", + "integrity": "sha512-yOXXK85DdGDktdnQtXgMdaVKii4wtMjEhJ1mrvx2A9nMFNaPhxvERkVVIUKSWlJRa9ZujOw5jWOx8d2R51/Kjg==", + "requires": { + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-buffer-from": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/hash-stream-node": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/hash-stream-node/-/hash-stream-node-3.40.0.tgz", + "integrity": "sha512-4yvRwODMGYtj6qrt+fyydV5MwVwPPoyoeqDoXdLo9x75vRY71DT1pMRt8PDOoY/ZwWbIdEt4+V7x0sLt2uy9WA==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/invalid-dependency": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/invalid-dependency/-/invalid-dependency-3.40.0.tgz", + "integrity": "sha512-axIWtDwCBDDqEgAJipX1FB1ZNpWYXquVwKDMo+7G+ftPBZ4FEq4M1ELhXJL3hhNJ9ZmCQzv+4F6Wnt8dwuzUaQ==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/is-array-buffer": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/is-array-buffer/-/is-array-buffer-3.37.0.tgz", + "integrity": "sha512-XLjA/a6AuGnCvcJZLsMTy2jxF2upgGhqCCkoIJgLlzzXHSihur13KcmPvW/zcaGnCRj0SvKWXiJHl4vDlW75VQ==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/md5-js": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/md5-js/-/md5-js-3.40.0.tgz", + "integrity": "sha512-P1tzEljMD/MkjSc00TkVBYvfaVv/7S+04YEwE7tpu/jtxWxMHnk3CMKqq/F2iMhY83DRoqoYy+YqnaF4Bzr1uA==", + "requires": { + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-utf8-browser": "3.37.0", + "@aws-sdk/util-utf8-node": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-apply-body-checksum": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-apply-body-checksum/-/middleware-apply-body-checksum-3.40.0.tgz", + "integrity": "sha512-gNSFlFu/O8cxAM0X64OwiLLN/NPXvK3FsAIJRsfhIW+dX0bEq4lsGPsdU8Tx+9eenaj/Z01uqgWZ6Izar8zVvQ==", + "requires": { + "@aws-sdk/is-array-buffer": "3.37.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-bucket-endpoint": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.41.0.tgz", + "integrity": "sha512-4A0kWHH2qemd4P7CZKS7XB6qtSUP2xMJ7Dn/llxYgvadR0mKEfGPeYPhAss/k7T1JGv+kSTIV30RwUXwdXgE/A==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-arn-parser": "3.37.0", + "@aws-sdk/util-config-provider": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-content-length": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-content-length/-/middleware-content-length-3.40.0.tgz", + "integrity": "sha512-sybAJb8v7I/vvL08R3+TI/XDAg9gybQTZ2treC24Ap4+jAOz4QBTHJPMKaUlEeFlMUcq4rj6/u2897ebYH6opw==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-expect-continue": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.40.0.tgz", + "integrity": "sha512-FY6vT0u1ptDZ2bBj1yG/Iyk6HZB7U9fbrpeZNPYzgq8HJxBcTgfLwtB3VLobyhThQm9X2a7R2YZrwtArW8yQfQ==", + "requires": { + "@aws-sdk/middleware-header-default": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-header-default": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-header-default/-/middleware-header-default-3.40.0.tgz", + "integrity": "sha512-eXQ13x/AivPZKoG8/akp9g5xdNHuKftl83GMuk9K6tt4+eAa22TdxiFu4R0UVlKAvo2feqxFrNs5DhhhBeAQWA==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-host-header": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.40.0.tgz", + "integrity": "sha512-/wocR7JFOLM7/+BQM1DgAd6KCFYcdxYu1P7AhI451GlVNuYa5f89zh7p0gt3SRC6monI5lXgpL7RudhDm8fTrA==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-location-constraint": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.40.0.tgz", + "integrity": "sha512-9XaVPYsDQVJbWJH96sNdv4HHY3j1raman+lYxMu4528Awp0OdWUeSsGRYRN+CnRPlkHnfNw4m6SKdWYHxdjshw==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-logger": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.40.0.tgz", + "integrity": "sha512-19kx0Xg5ymVRKoupmhdmfTBkROcv3DZj508agpyG2YAo0abOObMlIP4Jltg0VD4PhNjGzNh0jFGJnvhjdwv4/A==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-retry": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-retry/-/middleware-retry-3.40.0.tgz", + "integrity": "sha512-SMUJrukugLL7YJE5X8B2ToukxMWMPwnf7jAFr84ptycCe8bdWv8x8klQ3EtVWpyqochtNlbTi6J/tTQBniUX7A==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/service-error-classification": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0", + "uuid": "^8.3.2" + } + }, + "@aws-sdk/middleware-sdk-s3": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.41.0.tgz", + "integrity": "sha512-B7JOpmIpm1zxERQEMwZCWj3FisTvwfUgpfQglYdqrB6VpIoCM8fk2pmi5KzU/JDeNBlhTouj6mwnhJL/z5jopA==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/signature-v4": "3.40.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-arn-parser": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-sdk-sts": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sts/-/middleware-sdk-sts-3.40.0.tgz", + "integrity": "sha512-TcrbCvj1PkabFZiNczT3yePZtuEm2fAIw1OVnQyLcF2KW+p62Hv5YkK4MPOfx3LA/0lzjOUO1RNl2x7gzV443Q==", + "requires": { + "@aws-sdk/middleware-signing": "3.40.0", + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/signature-v4": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-serde": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-serde/-/middleware-serde-3.40.0.tgz", + "integrity": "sha512-uOWfZjlAoBy6xPqp0d4ka83WNNbEVCWn9WwfqBUXThyoTdTooYSpXe5y2YzN0BJa8b+tEZTyWpgamnBpFLp47g==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-signing": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-signing/-/middleware-signing-3.40.0.tgz", + "integrity": "sha512-RqK5nPbfma0qInMvjtpVkDYY/KkFS6EKlOv3DWTdxbXJ4YuOxgKiuUromhmBUoyjFag0JO7LUWod07H+/DawoA==", + "requires": { + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/signature-v4": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-ssec": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.40.0.tgz", + "integrity": "sha512-ZoRpaZeAIQa1Q+NyEh74ATwOR3nFGfcP6Nu0jFzgqoVijCReMnhtlCRx23ccBu1ZLZNUsNk6MhKjY+ZTfNsjEg==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-stack": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-stack/-/middleware-stack-3.40.0.tgz", + "integrity": "sha512-hby9HvESUYJxpdALX+6Dn2LPmS5jtMVurGB/+j3MWOvIcDYB4bcSXgVRvXzYnTKwbSupIdbX9zOE2ZAx2SJpUQ==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/middleware-user-agent": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.40.0.tgz", + "integrity": "sha512-dzC2fxWnanetFJ1oYgil8df3N36bR1yc/OCOpbdfQNiUk1FrXiCXqH5rHNO8zCvnwJAj8GHFwpFGd9a2Qube2w==", + "requires": { + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/node-config-provider": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-config-provider/-/node-config-provider-3.40.0.tgz", + "integrity": "sha512-AmokjgUDECG8osoMfdRsPNweqI+L1pn4bYGk5iTLmzbBi0o4ot0U1FdX8Rf0qJZZwS4t1TXc3s8/PDVknmPxKg==", + "requires": { + "@aws-sdk/property-provider": "3.40.0", + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/node-http-handler": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/node-http-handler/-/node-http-handler-3.40.0.tgz", + "integrity": "sha512-qjda6IbxDhbYr8NHmrMurKkbjgLUkfTMVgagDErDK24Nm3Dn5VaO6J4n6c0Q4OLHlmFaRcUfZSTrOo5DAubqCw==", + "requires": { + "@aws-sdk/abort-controller": "3.40.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/querystring-builder": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/property-provider": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/property-provider/-/property-provider-3.40.0.tgz", + "integrity": "sha512-Mx4lkShjsYRwW9ujHA1pcnuubrWQ4kF5/DXWNfUiXuSIO/0Lojp1qTLheyBm4vzkJIlx5umyP6NvRAUkEHSN4Q==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/protocol-http": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/protocol-http/-/protocol-http-3.40.0.tgz", + "integrity": "sha512-f4ea7/HZkjpvGBrnRIuzc/bhrExWrgDv7eulj4htPukZGHdTqSJD3Jk8lEXWvFuX2vUKQDGhEhCDsqup7YWJQQ==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/querystring-builder": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-builder/-/querystring-builder-3.40.0.tgz", + "integrity": "sha512-gO24oipnNaxJRBXB7lhLfa96vIMOd8gtMBqJTjelTjS2e1ZP1YY12CNKKTWwafSk8Ge021erZAG/YTOaXGpv+g==", + "requires": { + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-uri-escape": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/querystring-parser": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/querystring-parser/-/querystring-parser-3.40.0.tgz", + "integrity": "sha512-XZIyaKQIiZAM6zelCBcsLHhVDOLafi7XIOd3jy6SymGN8ajj3HqUJ/vdQ5G6ISTk18OrqgqcCOI9oNzv+nrBcA==", + "requires": { + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/s3-request-presigner": { + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/s3-request-presigner/-/s3-request-presigner-3.44.0.tgz", + "integrity": "sha512-PYAgoYu5dMaKSrr7eJlTGUROb5G98iYt0Vq8a7MMa1ZvIArsPB2b8tPS7DzvpMb4Jx8C7ni6kf+0F9YWMmOOpQ==", + "requires": { + "@aws-sdk/middleware-sdk-s3": "3.41.0", + "@aws-sdk/protocol-http": "3.40.0", + "@aws-sdk/signature-v4": "3.40.0", + "@aws-sdk/smithy-client": "3.41.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-create-request": "3.41.0", + "@aws-sdk/util-format-url": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/service-error-classification": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/service-error-classification/-/service-error-classification-3.40.0.tgz", + "integrity": "sha512-c8btKmkvjXczWudXubGdbO3JgmjySBUVC/gCrZDNfwNGsG8RYJJQYYcnmt1gWjelUZsgMDl/2PIzxTlxVF91rA==" + }, + "@aws-sdk/shared-ini-file-loader": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/shared-ini-file-loader/-/shared-ini-file-loader-3.37.0.tgz", + "integrity": "sha512-+vRBSlfa48R9KL7DpQt3dsu5/+5atjRgoCISblWo3SLpjrx41pKcjKneo7a1u0aP1Xc2oG2TfIyqTWZuOXsmEQ==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/signature-v4": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4/-/signature-v4-3.40.0.tgz", + "integrity": "sha512-Q1GNZJRCS3W2qsRtDsX/b6EOSfMXfr6TW46N3LnLTGYZ3KAN2SOSJ1DsW59AuGpEZyRmOhJ9L/Q5U403+bZMXQ==", + "requires": { + "@aws-sdk/is-array-buffer": "3.37.0", + "@aws-sdk/types": "3.40.0", + "@aws-sdk/util-hex-encoding": "3.37.0", + "@aws-sdk/util-uri-escape": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/smithy-client": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/smithy-client/-/smithy-client-3.41.0.tgz", + "integrity": "sha512-ldhS0Pf3v6yHCd//kk5DvKcdyeUkKEwxNDRanAp+ekTW68J3XcYgKaPC9sNDhVTDH1zrywTvtEz5zWHEvXjQow==", + "requires": { + "@aws-sdk/middleware-stack": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/types": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.40.0.tgz", + "integrity": "sha512-KpILcfvRaL88TLvo3SY4OuCCg90SvcNLPyjDwUuBqiOyWODjrKShHtAPJzej4CLp92lofh+ul0UnBfV9Jb/5PA==" + }, + "@aws-sdk/url-parser": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/url-parser/-/url-parser-3.40.0.tgz", + "integrity": "sha512-HwNV+HX7bHgLk5FzTOgdXANsC0SeVz5PMC4Nh+TLz2IoeQnrw4H8dsA4YNonncjern5oC5veKRjQeOoCL5SlSQ==", + "requires": { + "@aws-sdk/querystring-parser": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-arn-parser": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.37.0.tgz", + "integrity": "sha512-njIYn8gzm7Ms17A2oEu0vN/0GJpgq7cNFFtzBrM1cPtrc1jhMRJx5hzS7uX5h6ll8BM92bA3y00evRZFHxQPVQ==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-base64-browser": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-browser/-/util-base64-browser-3.37.0.tgz", + "integrity": "sha512-o4s/rHVm5k8eC/T7grJQINyYA/mKfDmEWKMA9wk5iBroXlI2rUm7x649TBk5hzoddufk/mffEeNz/1wM7yTmlg==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-base64-node": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-base64-node/-/util-base64-node-3.37.0.tgz", + "integrity": "sha512-1UPxly1GPrGZtlIWvbNCDIAund4Oyp8cFi9neA43TeNACvrmEQu/nG01pDbOoo0ENoVSVJrNAVBeqKEpqjH2GA==", + "requires": { + "@aws-sdk/util-buffer-from": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-body-length-browser": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-browser/-/util-body-length-browser-3.37.0.tgz", + "integrity": "sha512-tClmH1uYelqWT43xxmnOsVFbCQJiIwizp6y4E109G2LIof07inxrO0L8nbwBpjhugVplx6NZr9IaqTFqbdM1gA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-body-length-node": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-body-length-node/-/util-body-length-node-3.37.0.tgz", + "integrity": "sha512-aY3mXdbEajruRi9CHgq/heM89R+Gectj/Xrs1naewmamaN8NJrvjDm3s+cw//lqqSOW903LYHXDgm7wvCzUnFA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-buffer-from": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-buffer-from/-/util-buffer-from-3.37.0.tgz", + "integrity": "sha512-aa3SBwjLwImuJoE4+hxDIWQ9REz3UFb3p7KFPe9qopdXb/yB12RTcbrXVb4whUux4i4mO6KRij0ZNjFZrjrKPg==", + "requires": { + "@aws-sdk/is-array-buffer": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-config-provider": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-config-provider/-/util-config-provider-3.40.0.tgz", + "integrity": "sha512-NjZGrA4mqhpr6gkVCAUweurP0Z9d3vFyXJCtulC0BFbpKAnKCf/crSK56NwUaNhAEMCkSuBvjRFzkbfT+HO8bA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-create-request": { + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-create-request/-/util-create-request-3.41.0.tgz", + "integrity": "sha512-mKTMCDTaQ9HH+ppg1QMcBiSlbvRmw8AOllXTkYS1pdO7gi/Sl21krXfIja2MakuK6cB6D+B8MFP8rfq14Vhhlg==", + "requires": { + "@aws-sdk/middleware-stack": "3.40.0", + "@aws-sdk/smithy-client": "3.41.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-credentials": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-credentials/-/util-credentials-3.37.0.tgz", + "integrity": "sha512-zcLhSZDKgBLhUjSU5HoQpuQiP3v8oE86NmV/tiZVPEaO6YVULEAB2Cfj1hpM/b/JXWzjSHfT06KXT7QUODKS+A==", + "requires": { + "@aws-sdk/shared-ini-file-loader": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-format-url": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.40.0.tgz", + "integrity": "sha512-eOKeYwAvsCQjTSCAW1LVhnjmTyyGK6lZjGTa9wXxxjVE6Fhc66+cCykS8u/u8Vj7BCS+ixiLetXtH1/qd+Bl+g==", + "requires": { + "@aws-sdk/querystring-builder": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-hex-encoding": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-hex-encoding/-/util-hex-encoding-3.37.0.tgz", + "integrity": "sha512-tn5UpfaeM+rZWqynoNqB8lwtcAXil5YYO3HLGH9himpWAdft/2Z7LK6bsYDpctaAI1WHgMDcL0bw3Id04ZUbhA==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-locate-window": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.37.0.tgz", + "integrity": "sha512-NvDCfOhLLVHp27oGUUs8EVirhz91aX5gdxGS7J/sh5PF0cNN8rwaR1vSLR7BxPmJHMO7NH7i9EwiELfLfYcq6g==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-uri-escape": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-uri-escape/-/util-uri-escape-3.37.0.tgz", + "integrity": "sha512-8pKf4YJTELP5lm/CEgYw2atyJBB1RWWqFa0sZx6YJmTlOtLF5G6raUdAi4iDa2hldGt2B6IAdIIyuusT8zeU8Q==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-user-agent-browser": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.40.0.tgz", + "integrity": "sha512-C69sTI26bV2EprTv3DTXu9XP7kD9Wu4YVPBzqztOYArd2GDYw3w+jS8SEg3XRbjAKY/mOPZ2Thw4StjpZlWZiA==", + "requires": { + "@aws-sdk/types": "3.40.0", + "bowser": "^2.11.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-user-agent-node": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.40.0.tgz", + "integrity": "sha512-cjIzd0hRZFTTh7iLJD6Bciu++Em1iaM1clyG02xRl0JD5DEtDSR1zO02uu+AeM7GSLGOxIvwOkK2j8ySPAOmBA==", + "requires": { + "@aws-sdk/node-config-provider": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-utf8-browser": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.37.0.tgz", + "integrity": "sha512-tuiOxzfqet1kKGYzlgpMGfhr64AHJnYsFx2jZiH/O6Yq8XQg43ryjQlbJlim/K/XHGNzY0R+nabeJg34q3Ua1g==", + "requires": { + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-utf8-node": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-node/-/util-utf8-node-3.37.0.tgz", + "integrity": "sha512-fUAgd7UTCULL36j9/vnXHxVhxvswnq23mYgTCIT8NQ7wHN30q2a89ym1e9DwGeQkJEBOkOcKLn6nsMsN7YQMDQ==", + "requires": { + "@aws-sdk/util-buffer-from": "3.37.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/util-waiter": { + "version": "3.40.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-waiter/-/util-waiter-3.40.0.tgz", + "integrity": "sha512-jdxwNEZdID49ZvyAnxaeNm5w2moIfMLOwj/q6TxKlxYoXMs16FQWkhyfGue0vEASzchS49ewbyt+KBqpT31Ebg==", + "requires": { + "@aws-sdk/abort-controller": "3.40.0", + "@aws-sdk/types": "3.40.0", + "tslib": "^2.3.0" + } + }, + "@aws-sdk/xml-builder": { + "version": "3.37.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.37.0.tgz", + "integrity": "sha512-Vf0f4ZQ+IBo/l9wUaTOXLqqQO9b/Ll5yPbg+EhHx8zlHbTHIm89ettkVCGyT/taGagC1X+ZeTK9maX6ymEOBow==", + "requires": { + "tslib": "^2.3.0" + } + }, "@babel/code-frame": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", @@ -2263,6 +3214,11 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3118,6 +4074,11 @@ "ansi-colors": "^4.1.1" } }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3868,6 +4829,11 @@ "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.8.tgz", "integrity": "sha512-lXatBjf3WPjmWD6DpIZxkeSsCOwqI0maYMpgDlx8g4U2qi4lbjA9oH/HD2a87G+KfsUmo5WbJFmqBZlPxtptag==" }, + "fast-xml-parser": { + "version": "3.19.0", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz", + "integrity": "sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==" + }, "fastify-warning": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/fastify-warning/-/fastify-warning-0.2.0.tgz", @@ -7595,6 +8561,11 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, "uuid-random": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/uuid-random/-/uuid-random-1.3.2.tgz", diff --git a/package.json b/package.json index c49df8c..406c0f9 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@adonisjs/bouncer": "^2.2.5", "@adonisjs/core": "^5.4.2", "@adonisjs/drive": "^2.0.7", + "@adonisjs/drive-s3": "^1.0.5", "@adonisjs/lucid": "^16.3.2", "@adonisjs/mail": "^7.2.4", "@adonisjs/redis": "^7.0.9", diff --git a/routes/apis/v1/lessons.ts b/routes/apis/v1/lessons.ts index b56e8af..ba16db5 100644 --- a/routes/apis/v1/lessons.ts +++ b/routes/apis/v1/lessons.ts @@ -12,7 +12,7 @@ Route.group(() => { Route.get('/:id/content', 'Api/v1/LessonsController.getContent') .middleware('role:admin,teacher,student') .as('lessons.get-content'); - Route.get('/materials/:file', 'Api/v1/LessonsController.getMaterial') + Route.get('/materials/:fileName', 'Api/v1/LessonsController.getMaterial') .middleware('role:admin,teacher,student') .as('lessons.get-material'); Route.get('/:id/progress', 'Api/v1/LessonsController.getVideoProgress') diff --git a/tsconfig.json b/tsconfig.json index 185f317..007bcc2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -35,7 +35,8 @@ "@adonisjs/mail", "@adonisjs/view", "@adonisjs/attachment-lite", - "@adonisjs/bouncer" + "@adonisjs/bouncer", + "@adonisjs/drive-s3" ] } }