From 3324de111b2beec5d6c4ed45719041f126af378a Mon Sep 17 00:00:00 2001 From: degel01459 <15-11661@usb.ve> Date: Sun, 13 Oct 2024 22:32:15 -0400 Subject: [PATCH 1/6] add "tsconfig.json", "src/groups/cover.ts" Convirtiendo "src/groups/cover.js" "cover.js" de JS a TS --- src/groups/cover.ts | 104 ++++++++++++++++++++++++++++++++++++++++++++ tsconfig.json | 14 ++++++ 2 files changed, 118 insertions(+) create mode 100644 src/groups/cover.ts create mode 100644 tsconfig.json diff --git a/src/groups/cover.ts b/src/groups/cover.ts new file mode 100644 index 0000000000..eadefcfba5 --- /dev/null +++ b/src/groups/cover.ts @@ -0,0 +1,104 @@ +'use strict'; + +import path from 'path'; +import nconf from 'nconf'; +import db from '../database'; +import image from '../image'; +import file from '../file'; + +// Inicializa nconf +nconf.argv().env().file({ file: path.join(__dirname, '../../node_modules/nconf/lib/config.json') }); + +// Tipos de datos necesarios +interface CoverData { + file?: { + path: string; + type: string; + }; + imageData?: string; + position?: string; + groupName: string; + } + + interface UploadData { + url: string; + } + +// Función principal +export default function (Groups: any) { + const allowedTypes = ['image/png', 'image/jpeg', 'image/bmp']; + + // Función para actualizar la posición de la imagen de portada + Groups.updateCoverPosition = async function (groupName: string, position: string): Promise { + if (!groupName) { + throw new Error('[[error:invalid-data]]'); + } + await Groups.setGroupField(groupName, 'cover:position', position); + }; + + // Función para actualizar la imagen de portada + Groups.updateCover = async function (uid: number, data: CoverData): Promise<{ url: string }> { + let tempPath = data.file ? data.file.path : ''; + try { + if (!data.imageData && !data.file && data.position) { + return await Groups.updateCoverPosition(data.groupName, data.position); + } + + const type = data.file ? data.file.type : image.mimeFromBase64(data.imageData || ''); + if (!type || !allowedTypes.includes(type)) { + throw new Error('[[error:invalid-image]]'); + } + + if (!tempPath) { + tempPath = await image.writeImageDataToTempFile(data.imageData as string); + } + + const filename = `groupCover-${data.groupName}${path.extname(tempPath)}`; + const uploadData: UploadData = await image.uploadImage(filename, 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + const { url } = uploadData; + await Groups.setGroupField(data.groupName, 'cover:url', url); + + await image.resizeImage({ + path: tempPath, + width: 358, + }); + + const thumbUploadData: UploadData = await image.uploadImage(`groupCoverThumb-${data.groupName}${path.extname(tempPath)}`, 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + await Groups.setGroupField(data.groupName, 'cover:thumb:url', thumbUploadData.url); + + if (data.position) { + await Groups.updateCoverPosition(data.groupName, data.position); + } + + return { url: url }; + } finally { + file.delete(tempPath); + } + }; + + // Función para eliminar la imagen de portada + Groups.removeCover = async function (data: { groupName: string }): Promise { + const fields = ['cover:url', 'cover:thumb:url']; + const values = await Groups.getGroupFields(data.groupName, fields); + + await Promise.all(fields.map((field) => { + if (!values[field] || !values[field].startsWith(`${nconf.get('relative_path')}/assets/uploads/files/`)) { + return; + } + + const filename = values[field].split('/').pop(); + const filePath = path.join(nconf.get('upload_path'), 'files', filename); + return file.delete(filePath); + })); + + await db.deleteObjectFields(`group:${data.groupName}`, ['cover:url', 'cover:thumb:url', 'cover:position']); + }; + } \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000..190408ca51 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "noImplicitAny": false, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} \ No newline at end of file From c114e7a20fe15d9f58042dd9ef9b12dcd84e258d Mon Sep 17 00:00:00 2001 From: degel01459 <57402392+degel01459@users.noreply.github.com> Date: Sun, 13 Oct 2024 22:45:34 -0400 Subject: [PATCH 2/6] Create 1511661.yml --- Workflow/1511661.yml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 Workflow/1511661.yml diff --git a/Workflow/1511661.yml b/Workflow/1511661.yml new file mode 100644 index 0000000000..ddeb9491c4 --- /dev/null +++ b/Workflow/1511661.yml @@ -0,0 +1,32 @@ +name: 1511661 + +on: + push: + branches: + - f24 + - 'feature/*' + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: '20' + + - name: Install dependencies + run: npm install + + - name: Compile TypeScript + run: npx tsc + + - name: Run tests (opcional) + run: npm test From baef7d1031cf9588f9a504e9accea15226b7f7b1 Mon Sep 17 00:00:00 2001 From: degel01459 <15-11661@usb.ve> Date: Sun, 13 Oct 2024 22:54:17 -0400 Subject: [PATCH 3/6] Cambio de ruta de prueba --- {Workflow => .github/workflows}/1511661.yml | 0 .husky/commit-msg | 0 .husky/pre-commit | 0 install/docker/entrypoint.sh | 0 nodebb | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename {Workflow => .github/workflows}/1511661.yml (100%) mode change 100755 => 100644 .husky/commit-msg mode change 100755 => 100644 .husky/pre-commit mode change 100755 => 100644 install/docker/entrypoint.sh mode change 100755 => 100644 nodebb diff --git a/Workflow/1511661.yml b/.github/workflows/1511661.yml similarity index 100% rename from Workflow/1511661.yml rename to .github/workflows/1511661.yml diff --git a/.husky/commit-msg b/.husky/commit-msg old mode 100755 new mode 100644 diff --git a/.husky/pre-commit b/.husky/pre-commit old mode 100755 new mode 100644 diff --git a/install/docker/entrypoint.sh b/install/docker/entrypoint.sh old mode 100755 new mode 100644 diff --git a/nodebb b/nodebb old mode 100755 new mode 100644 From cf92a3cf267c1cb6ef1775306865e18aea938e80 Mon Sep 17 00:00:00 2001 From: degel01459 <15-11661@usb.ve> Date: Sun, 13 Oct 2024 23:31:07 -0400 Subject: [PATCH 4/6] Rev tsconfig.json --- tsconfig.json | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 190408ca51..4105a343e1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,16 @@ { "compilerOptions": { + "allowJs": false, "target": "es6", "module": "commonjs", - "outDir": "./dist", - "rootDir": "./src", - "strict": true, + "moduleResolution": "node", "noImplicitAny": false, "esModuleInterop": true, - "skipLibCheck": true }, - "include": ["src/**/*"], + "include": [ + "public/src/**/*", + "src/**/*", + "test/**/*" + ], "exclude": ["node_modules"] } \ No newline at end of file From f822dbe15eaa5c5af4edf3c7a76b4e492eddd4d7 Mon Sep 17 00:00:00 2001 From: degel01459 <57402392+degel01459@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:50:28 -0400 Subject: [PATCH 5/6] Update cover.ts eslint-disable-next-line --- src/groups/cover.ts | 199 ++++++++++++++++++++++++-------------------- 1 file changed, 108 insertions(+), 91 deletions(-) diff --git a/src/groups/cover.ts b/src/groups/cover.ts index eadefcfba5..254af7a59c 100644 --- a/src/groups/cover.ts +++ b/src/groups/cover.ts @@ -2,103 +2,120 @@ import path from 'path'; import nconf from 'nconf'; -import db from '../database'; -import image from '../image'; -import file from '../file'; +import db from '../database'; // Módulo JS posiblemente sin migrar a TS +import image from '../image'; // Módulo JS posiblemente sin migrar a TS +import file from '../file'; // Módulo JS posiblemente sin migrar a TS // Inicializa nconf nconf.argv().env().file({ file: path.join(__dirname, '../../node_modules/nconf/lib/config.json') }); // Tipos de datos necesarios interface CoverData { - file?: { - path: string; - type: string; - }; - imageData?: string; - position?: string; - groupName: string; - } - - interface UploadData { - url: string; - } + file?: { + path: string; + type: string; + }; + imageData?: string; + position?: string; + groupName: string; +} + +interface UploadData { + url: string; +} // Función principal export default function (Groups: any) { - const allowedTypes = ['image/png', 'image/jpeg', 'image/bmp']; - - // Función para actualizar la posición de la imagen de portada - Groups.updateCoverPosition = async function (groupName: string, position: string): Promise { - if (!groupName) { - throw new Error('[[error:invalid-data]]'); - } - await Groups.setGroupField(groupName, 'cover:position', position); - }; - - // Función para actualizar la imagen de portada - Groups.updateCover = async function (uid: number, data: CoverData): Promise<{ url: string }> { - let tempPath = data.file ? data.file.path : ''; - try { - if (!data.imageData && !data.file && data.position) { - return await Groups.updateCoverPosition(data.groupName, data.position); - } - - const type = data.file ? data.file.type : image.mimeFromBase64(data.imageData || ''); - if (!type || !allowedTypes.includes(type)) { - throw new Error('[[error:invalid-image]]'); - } - - if (!tempPath) { - tempPath = await image.writeImageDataToTempFile(data.imageData as string); - } - - const filename = `groupCover-${data.groupName}${path.extname(tempPath)}`; - const uploadData: UploadData = await image.uploadImage(filename, 'files', { - path: tempPath, - uid: uid, - name: 'groupCover', - }); - const { url } = uploadData; - await Groups.setGroupField(data.groupName, 'cover:url', url); - - await image.resizeImage({ - path: tempPath, - width: 358, - }); - - const thumbUploadData: UploadData = await image.uploadImage(`groupCoverThumb-${data.groupName}${path.extname(tempPath)}`, 'files', { - path: tempPath, - uid: uid, - name: 'groupCover', - }); - await Groups.setGroupField(data.groupName, 'cover:thumb:url', thumbUploadData.url); - - if (data.position) { - await Groups.updateCoverPosition(data.groupName, data.position); - } - - return { url: url }; - } finally { - file.delete(tempPath); - } - }; - - // Función para eliminar la imagen de portada - Groups.removeCover = async function (data: { groupName: string }): Promise { - const fields = ['cover:url', 'cover:thumb:url']; - const values = await Groups.getGroupFields(data.groupName, fields); - - await Promise.all(fields.map((field) => { - if (!values[field] || !values[field].startsWith(`${nconf.get('relative_path')}/assets/uploads/files/`)) { - return; - } - - const filename = values[field].split('/').pop(); - const filePath = path.join(nconf.get('upload_path'), 'files', filename); - return file.delete(filePath); - })); - - await db.deleteObjectFields(`group:${data.groupName}`, ['cover:url', 'cover:thumb:url', 'cover:position']); - }; - } \ No newline at end of file + const allowedTypes = ['image/png', 'image/jpeg', 'image/bmp']; + + // Función para actualizar la posición de la imagen de portada + Groups.updateCoverPosition = async function (groupName: string, position: string): Promise { + if (!groupName) { + throw new Error('[[error:invalid-data]]'); + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + await Groups.setGroupField(groupName, 'cover:position', position); + }; + + // Función para actualizar la imagen de portada + Groups.updateCover = async function (uid: number, data: CoverData): Promise<{ url: string }> { + let tempPath = data.file ? data.file.path : ''; + try { + if (!data.imageData && !data.file && data.position) { + return await Groups.updateCoverPosition(data.groupName, data.position); + } + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access + const type = data.file ? data.file.type : image.mimeFromBase64(data.imageData || ''); + if (!type || !allowedTypes.includes(type)) { + throw new Error('[[error:invalid-image]]'); + } + + if (!tempPath) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + tempPath = await image.writeImageDataToTempFile(data.imageData as string); + } + + const filename = `groupCover-${data.groupName}${path.extname(tempPath)}`; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const uploadData: UploadData = await image.uploadImage(filename, 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + + const { url } = uploadData; + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + await Groups.setGroupField(data.groupName, 'cover:url', url); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + await image.resizeImage({ + path: tempPath, + width: 358, + }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const thumbUploadData: UploadData = await image.uploadImage(`groupCoverThumb-${data.groupName}${path.extname(tempPath)}`, 'files', { + path: tempPath, + uid: uid, + name: 'groupCover', + }); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + await Groups.setGroupField(data.groupName, 'cover:thumb:url', thumbUploadData.url); + + if (data.position) { + await Groups.updateCoverPosition(data.groupName, data.position); + } + + return { url: url }; + } finally { + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + file.delete(tempPath); + } + }; + + // Función para eliminar la imagen de portada + Groups.removeCover = async function (data: { groupName: string }): Promise { + const fields = ['cover:url', 'cover:thumb:url']; + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + const values = await Groups.getGroupFields(data.groupName, fields); + + await Promise.all(fields.map((field) => { + if (!values[field] || !values[field].startsWith(`${nconf.get('relative_path')}/assets/uploads/files/`)) { + return; + } + + const filename = values[field].split('/').pop(); + const filePath = path.join(nconf.get('upload_path'), 'files', filename); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + return file.delete(filePath); + })); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-call + await db.deleteObjectFields(`group:${data.groupName}`, ['cover:url', 'cover:thumb:url', 'cover:position']); + }; +} From 1836329da61e4bfa4b0ca1916b99e778d8cf55c0 Mon Sep 17 00:00:00 2001 From: degel01459 <57402392+degel01459@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:00:21 -0400 Subject: [PATCH 6/6] Update tsconfig.json MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ruta de creación de la traducción. --- tsconfig.json | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index da8cc3dcec..0e63d152ea 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,17 +1,18 @@ { - - "compilerOptions": { - "allowJs": false, - "target": "es6", - "module": "commonjs", - "moduleResolution": "node", - "noImplicitAny": false, - "esModuleInterop": true, - }, - "include": [ - "public/src/**/*", - "src/**/*", - "test/**/*" - ], - "exclude": ["node_modules"] -} \ No newline at end of file + "compilerOptions": { + "allowJs": true, + "target": "es6", + "module": "commonjs", + "moduleResolution": "node", + "outDir": "./dist", + "rootDir": "./src", + "noImplicitAny": false, + "esModuleInterop": true + }, + "include": [ + "public/src/**/*", + "src/**/*", + "test/**/*" + ], + "exclude": ["node_modules"] +}