♻️ OOConnector: refactor a bit of string manipulation
This commit is contained in:
committed by
ericlinagora
parent
6534f23cc2
commit
ca267df7ac
@@ -7,6 +7,7 @@ import { DriveFileType } from '@/interfaces/drive.interface';
|
||||
import fileService from '@/services/file.service';
|
||||
import { OfficeToken } from '@/interfaces/routes.interface';
|
||||
import loggerService from '@/services/logger.service';
|
||||
import * as Utils from '@/utils';
|
||||
|
||||
interface RequestQuery {
|
||||
mode: string;
|
||||
@@ -89,10 +90,13 @@ class IndexController {
|
||||
);
|
||||
|
||||
res.redirect(
|
||||
`${SERVER_ORIGIN ?? ''}/${SERVER_PREFIX.replace(
|
||||
/(\/+$|^\/+)/gm,
|
||||
'',
|
||||
)}/editor?office_token=${officeToken}&token=${token}&file_id=${file_id}&company_id=${company_id}&preview=${preview}`,
|
||||
Utils.joinURL([SERVER_ORIGIN ?? '', SERVER_PREFIX, 'editor'], {
|
||||
token,
|
||||
file_id,
|
||||
company_id,
|
||||
preview,
|
||||
office_token: officeToken,
|
||||
})
|
||||
);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -126,7 +130,7 @@ class IndexController {
|
||||
|
||||
res.render('index', {
|
||||
...initResponse,
|
||||
server: SERVER_ORIGIN.replace(/\/+$/, '') + '/' + SERVER_PREFIX.replace(/(\/+$|^\/+)/, '') || `${req.protocol}://${req.get('host')}/`,
|
||||
server: Utils.joinURL([SERVER_ORIGIN, SERVER_PREFIX]),
|
||||
token: inPageToken,
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
import axios, { Axios, AxiosRequestConfig, AxiosResponse } from 'axios';
|
||||
import { CREDENTIALS_ENDPOINT, CREDENTIALS_ID, CREDENTIALS_SECRET, ONLY_OFFICE_SERVER } from '@config';
|
||||
import loggerService from './logger.service';
|
||||
import * as Utils from '@/utils';
|
||||
|
||||
/** Client for the Twake Drive backend API on behalf of the plugin (or provided token in parameters) */
|
||||
class ApiService implements IApiService {
|
||||
@@ -73,7 +74,7 @@ class ApiService implements IApiService {
|
||||
private refreshToken = async (): Promise<string> => {
|
||||
try {
|
||||
const response = await axios.post<IApiServiceApplicationTokenRequestParams, { data: IApiServiceApplicationTokenResponse }>(
|
||||
`${CREDENTIALS_ENDPOINT.replace(/\/$/, '')}/api/console/v1/login`,
|
||||
Utils.joinURL([CREDENTIALS_ENDPOINT, '/api/console/v1/login']),
|
||||
{
|
||||
id: CREDENTIALS_ID,
|
||||
secret: CREDENTIALS_SECRET,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { EditConfigInitResult, IEditorService, ModeParametersType } from '@/interfaces/editor.interface';
|
||||
import { UserType } from '@/interfaces/user.interface';
|
||||
import { ONLY_OFFICE_SERVER } from '@config';
|
||||
import * as Utils from '@/utils';
|
||||
|
||||
class EditorService implements IEditorService {
|
||||
public init = async (
|
||||
@@ -12,12 +13,14 @@ class EditorService implements IEditorService {
|
||||
file_id: string,
|
||||
): Promise<EditConfigInitResult> => {
|
||||
const { color, mode: fileMode } = this.getFileMode(file_name);
|
||||
let [, extension] = Utils.splitFilename(file_name);
|
||||
|
||||
extension = extension.toLocaleLowerCase();
|
||||
return {
|
||||
color,
|
||||
file_id,
|
||||
file_version_id,
|
||||
file_type: file_name.split('.').pop(),
|
||||
file_type: extension,
|
||||
filename: file_name,
|
||||
language: user.preferences.locale || 'en',
|
||||
mode: fileMode,
|
||||
@@ -32,7 +35,8 @@ class EditorService implements IEditorService {
|
||||
};
|
||||
|
||||
private getFileMode = (filename: string): ModeParametersType => {
|
||||
const extension = filename.split('.').pop();
|
||||
let [, extension] = Utils.splitFilename(filename);
|
||||
extension = extension.toLocaleLowerCase();
|
||||
|
||||
if (
|
||||
[
|
||||
|
||||
@@ -3,8 +3,10 @@ import apiService from './api.service';
|
||||
import loggerService from './logger.service';
|
||||
import { Stream } from 'stream';
|
||||
import FormData from 'form-data';
|
||||
import * as Utils from '@/utils';
|
||||
|
||||
class FileService implements IFileService {
|
||||
|
||||
public get = async (params: FileRequestParams): Promise<FileType> => {
|
||||
try {
|
||||
const { company_id, file_id } = params;
|
||||
@@ -55,7 +57,7 @@ class FileService implements IFileService {
|
||||
|
||||
const form = new FormData();
|
||||
|
||||
const nameSplit = (originalFile.metadata.name || '').split('.');
|
||||
const nameSplit = Utils.splitFilename(originalFile.metadata.name || '');
|
||||
const filename =
|
||||
nameSplit[0].replace(/-[0-9]{8}-[0-9]{4}$/, '') +
|
||||
(!create_new ? '.' : `-${new Date().toISOString().split('.')[0].split(':').slice(0, 2).join('').replace(/-/gm, '').split('T').join('-')}.`) +
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/** Return the key in `obj` of which the value matches the `value` parameter, or `undefined` */
|
||||
export function getKeyForValue<T>(value: T, obj: any): string | undefined {
|
||||
return (Object.entries(obj as { [key: string]: T }).filter(([_key, entryValue]) => value === entryValue)[0] ?? [])[0];
|
||||
}
|
||||
|
||||
/** Same as `getKeyForValue` but returns a default string for values not found */
|
||||
export function getKeyForValueSafe<T>(value: T, obj: any, valueKind: string): string {
|
||||
const result = getKeyForValue(value, obj);
|
||||
return result ?? `(Unknown ${valueKind}: ${JSON.stringify(value)})`;
|
||||
}
|
||||
|
||||
/** Suitable type for query arguments */
|
||||
export type QueryParams = { [key: string]: string | number };
|
||||
|
||||
/** Compose a URL removing and adding slashes and query parameters as warranted */
|
||||
export function joinURL(path: string[], params?: QueryParams) {
|
||||
let joinedPath = path.map(x => x.replace(/(?:^\/+)+|(?:\/+$)/g, "")).join("/");
|
||||
if (path[path.length - 1].endsWith("/"))
|
||||
joinedPath += "/";
|
||||
const paramEntries = Object.entries(params || {});
|
||||
if (paramEntries.length === 0)
|
||||
return joinedPath;
|
||||
const query = paramEntries.map((p) => p.map(encodeURIComponent).join("=")).join("&");
|
||||
return joinedPath + (joinedPath.indexOf("?") > -1 ? "&" : "?") + query;
|
||||
}
|
||||
|
||||
/** Split a filename into an array `[name, extension]`. Either and both can be
|
||||
* the empty string. When the extension is the whole name, it is assumed to be
|
||||
* the name and not the extension.
|
||||
* @example
|
||||
* ```js
|
||||
* splitFilename("") // [ "", "" ]
|
||||
* splitFilename(".") // [ ".", "" ]
|
||||
* splitFilename("..") // [ ".", "" ]
|
||||
* splitFilename("filename") // [ "filename", "" ]
|
||||
* splitFilename(".dotfile") // [ ".dotfile", "" ]
|
||||
* splitFilename("a.dotfile") // [ "a", "dotfile" ]
|
||||
* splitFilename(".a.dotfile") // [ ".a", "dotfile" ]
|
||||
* splitFilename("a.b.dotfile") // [ "a.b", "dotfile" ]
|
||||
* splitFilename(".a.b.dotfile") // [ ".a.b", "dotfile" ]
|
||||
* ```
|
||||
*/
|
||||
export function splitFilename(filename: string): [string, string] {
|
||||
const parts = filename.split('.');
|
||||
if (parts.length < 2 || (parts.length == 2 && parts[0] === ""))
|
||||
return [filename, ""];
|
||||
const extension = parts.pop();
|
||||
return [parts.join("."), extension];
|
||||
}
|
||||
Reference in New Issue
Block a user