Yuki Takei 3 лет назад
Родитель
Сommit
be99d06cfc

+ 3 - 4
packages/app/next.config.js

@@ -1,9 +1,8 @@
-import { listScopedPackages } from './src/utils/next.config.utils';
-
-import { I18NextHMRPlugin } from "i18next-hmr/plugin";
+import { I18NextHMRPlugin } from 'i18next-hmr/plugin';
 import { WebpackManifestPlugin } from 'webpack-manifest-plugin';
 
 import { i18n, localePath } from './src/next-i18next.config';
+import { listScopedPackages } from './src/utils/next.config.utils';
 
 // define transpiled packages for '@growi/*'
 const scopedPackages = listScopedPackages(['@growi']);
@@ -54,7 +53,7 @@ const nextConfig = {
 
     // setup i18next-hmr
     if (!options.isServer && options.dev) {
-      config.plugins.push(new I18NextHMRPlugin({ localesDir: localePath }))
+      config.plugins.push(new I18NextHMRPlugin({ localesDir: localePath }));
     }
 
     return config;

+ 1 - 1
packages/app/src/client/models/BootstrapGrid.js

@@ -7,7 +7,7 @@ export default class BootstrapGrid {
 
   static ResponsiveSize = {
     XS_SIZE: 'xs', SM_SIZE: 'sm', MD_SIZE: 'md',
-  }
+  };
 
   static validateColsRatios(colsRatios) {
 

+ 2 - 2
packages/app/src/client/models/Linker.js

@@ -26,14 +26,14 @@ export default class Linker {
     markdownLink: 'mdLink',
     growiLink: 'growiLink',
     pukiwikiLink: 'pukiwikiLink',
-  }
+  };
 
   static patterns = {
     pukiwikiLinkWithLabel: /^\[\[(?<label>.+)>(?<link>.+)\]\]$/, // https://regex101.com/r/2fNmUN/2
     pukiwikiLinkWithoutLabel: /^\[\[(?<label>.+)\]\]$/, // https://regex101.com/r/S7w5Xu/1
     growiLink: /^\[(?<label>\/.+)\]$/, // https://regex101.com/r/DJfkYf/3
     markdownLink: /^\[(?<label>.*)\]\((?<link>.*)\)$/, // https://regex101.com/r/DZCKP3/2
-  }
+  };
 
   initWhenMarkdownLink() {
     // fill label with link if empty

+ 3 - 3
packages/app/src/components/PageEditor/CommentMentionHelper.ts

@@ -46,7 +46,7 @@ export default class CommentMentionHelper {
         }
       },
     });
-  }
+  };
 
   getUsersList = async(q: string) => {
     const limit = 20;
@@ -55,8 +55,8 @@ export default class CommentMentionHelper {
       text: `@${username} `,
       displayText: username,
     }));
-  }
+  };
 
-showUsernameHint= debounce(800, () => this.getUsernamHint());
+  showUsernameHint = debounce(800, () => this.getUsernamHint());
 
 }

+ 62 - 62
packages/app/src/components/PageEditor/EmojiPickerHelper.ts

@@ -7,83 +7,83 @@ const EMOJI_PATTERN = new RegExp(/\B:[^:\s]+/);
 
 export default class EmojiPickerHelper {
 
-editor;
+  editor;
 
-pattern: RegExp;
+  pattern: RegExp;
 
-constructor(editor) {
-  this.editor = editor;
-  this.pattern = EMOJI_PATTERN;
-}
+  constructor(editor) {
+    this.editor = editor;
+    this.pattern = EMOJI_PATTERN;
+  }
 
-setStyle = ():CSSProperties => {
-  const offset = 20;
-  const emojiPickerHeight = 420;
-  const cursorPos = this.editor.cursorCoords(true);
-  const editorPos = this.editor.getWrapperElement().getBoundingClientRect();
-  // Emoji Picker bottom position exceed editor's bottom position
-  if (cursorPos.bottom + emojiPickerHeight > editorPos.bottom) {
+  setStyle = ():CSSProperties => {
+    const offset = 20;
+    const emojiPickerHeight = 420;
+    const cursorPos = this.editor.cursorCoords(true);
+    const editorPos = this.editor.getWrapperElement().getBoundingClientRect();
+    // Emoji Picker bottom position exceed editor's bottom position
+    if (cursorPos.bottom + emojiPickerHeight > editorPos.bottom) {
+      return {
+        top: editorPos.bottom - emojiPickerHeight,
+        left: cursorPos.left + offset,
+        position: 'fixed',
+      };
+    }
     return {
-      top: editorPos.bottom - emojiPickerHeight,
+      top: cursorPos.top + offset,
       left: cursorPos.left + offset,
       position: 'fixed',
     };
-  }
-  return {
-    top: cursorPos.top + offset,
-    left: cursorPos.left + offset,
-    position: 'fixed',
   };
-}
 
-getSearchCursor =() => {
-  const currentPos = this.editor.getCursor();
-  const sc = this.editor.getSearchCursor(this.pattern, currentPos, { multiline: false });
-  return sc;
-}
-
-// Add emoji when triggered by search
-addEmojiOnSearch = (emoji) => {
-  const currentPos = this.editor.getCursor();
-  const sc = this.getSearchCursor();
-  if (sc.findPrevious()) {
-    sc.replace(`${emoji.colons} `, this.editor.getTokenAt(currentPos).string);
-    this.editor.focus();
-    this.editor.refresh();
-  }
-}
+  getSearchCursor = () => {
+    const currentPos = this.editor.getCursor();
+    const sc = this.editor.getSearchCursor(this.pattern, currentPos, { multiline: false });
+    return sc;
+  };
 
+  // Add emoji when triggered by search
+  addEmojiOnSearch = (emoji) => {
+    const currentPos = this.editor.getCursor();
+    const sc = this.getSearchCursor();
+    if (sc.findPrevious()) {
+      sc.replace(`${emoji.colons} `, this.editor.getTokenAt(currentPos).string);
+      this.editor.focus();
+      this.editor.refresh();
+    }
+  };
 
-// Add emoji when triggered by click emoji icon on top of editor
-addEmoji = (emoji) => {
-  const currentPos = this.editor.getCursor();
-  const doc = this.editor.getDoc();
-  doc.replaceRange(`${emoji.colons} `, currentPos);
-  this.editor.focus();
-  this.editor.refresh();
-}
 
-getEmoji = () => {
-  const sc = this.getSearchCursor();
-  const currentPos = this.editor.getCursor();
+  // Add emoji when triggered by click emoji icon on top of editor
+  addEmoji = (emoji) => {
+    const currentPos = this.editor.getCursor();
+    const doc = this.editor.getDoc();
+    doc.replaceRange(`${emoji.colons} `, currentPos);
+    this.editor.focus();
+    this.editor.refresh();
+  };
 
-  if (sc.findPrevious()) {
-    const isInputtingEmoji = (currentPos.line === sc.to().line && currentPos.ch === sc.to().ch);
-    // current search cursor position
-    if (!isInputtingEmoji) {
-      return;
+  getEmoji = () => {
+    const sc = this.getSearchCursor();
+    const currentPos = this.editor.getCursor();
+
+    if (sc.findPrevious()) {
+      const isInputtingEmoji = (currentPos.line === sc.to().line && currentPos.ch === sc.to().ch);
+      // current search cursor position
+      if (!isInputtingEmoji) {
+        return;
+      }
+      const pos = {
+        line: sc.to().line,
+        ch: sc.to().ch,
+      };
+      const currentSearchText = sc.matches(true, pos).match[0];
+      const searchWord = currentSearchText.replace(':', '');
+      return searchWord;
     }
-    const pos = {
-      line: sc.to().line,
-      ch: sc.to().ch,
-    };
-    const currentSearchText = sc.matches(true, pos).match[0];
-    const searchWord = currentSearchText.replace(':', '');
-    return searchWord;
-  }
 
-  return;
-}
+    return;
+  };
 
 }
 

+ 1 - 1
packages/app/src/next-i18next.config.ts

@@ -22,6 +22,6 @@ export const backend = {
     // options for i18next-localstorage-backend
     { expirationTime: isDev ? 0 : 24 * 60 * 60 * 1000 }, // 1 day in production
     // options for i18next-http-backend
-    { loadPath: '/static/locales/{{lng}}/{{ns}}.json', },
+    { loadPath: '/static/locales/{{lng}}/{{ns}}.json' },
   ],
 };

+ 1 - 1
packages/app/src/pages/[[...path]].page.tsx

@@ -235,7 +235,7 @@ async function injectPageInformation(context: GetServerSidePropsContext, props:
   const page = result.data;
 
   if (page == null) {
-    const count = pageId != null ?  await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname }) ;
+    const count = pageId != null ? await Page.count({ _id: pageId }) : await Page.count({ path: currentPathname });
     // check the page is forbidden or just does not exist.
     props.isForbidden = count > 0;
     props.isNotFound = true;

+ 1 - 1
packages/app/src/pages/_app.page.tsx

@@ -3,7 +3,7 @@ import React from 'react';
 import { AppProps } from 'next/app';
 import { appWithTranslation } from 'next-i18next';
 
-import * as nextI18nConfig from '../next-i18next.config'
+import * as nextI18nConfig from '../next-i18next.config';
 
 // import { appWithTranslation } from '~/i18n';
 

+ 4 - 4
packages/app/src/pages/api/hello.ts

@@ -1,13 +1,13 @@
 // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
-import type { NextApiRequest, NextApiResponse } from 'next'
+import type { NextApiRequest, NextApiResponse } from 'next';
 
 type Data = {
   name: string
 }
 
 export default function handler(
-  req: NextApiRequest,
-  res: NextApiResponse<Data>
+    req: NextApiRequest,
+    res: NextApiResponse<Data>,
 ) {
-  res.status(200).json({ name: 'John Doe' })
+  res.status(200).json({ name: 'John Doe' });
 }

+ 2 - 2
packages/app/src/server/models/vo/search-error.ts

@@ -4,9 +4,9 @@ import { AllTermsKey } from '~/server/interfaces/search';
 
 export class SearchError extends ExtensibleCustomError {
 
-  readonly id = 'SearchError'
+  readonly id = 'SearchError';
 
-  unavailableTermsKeys!: AllTermsKey[]
+  unavailableTermsKeys!: AllTermsKey[];
 
   constructor(message = '', unavailableTermsKeys: AllTermsKey[]) {
     super(message);

+ 2 - 2
packages/app/src/server/models/vo/v5-conversion-error.ts

@@ -4,9 +4,9 @@ import { V5ConversionErrCode } from '~/interfaces/errors/v5-conversion-error';
 
 export class V5ConversionError extends ExtensibleCustomError {
 
-  readonly id = 'V5ConversionError'
+  readonly id = 'V5ConversionError';
 
-  code!: V5ConversionErrCode
+  code!: V5ConversionErrCode;
 
   constructor(message: string, code: V5ConversionErrCode) {
     super(message);

+ 1 - 1
packages/app/src/server/service/comment.ts

@@ -129,7 +129,7 @@ class CommentService {
     return mentionedUserIDs?.map((user) => {
       return user._id;
     });
-  }
+  };
 
 }
 

+ 5 - 5
packages/app/src/server/service/in-app-notification.ts

@@ -50,7 +50,7 @@ export default class InAppNotificationService {
           .emit('notificationUpdated');
       });
     }
-  }
+  };
 
   upsertByActivity = async function(
       users: Types.ObjectId[], activity: ActivityDocument, snapshot: string, createdAt?: Date | null,
@@ -86,7 +86,7 @@ export default class InAppNotificationService {
     await InAppNotification.bulkWrite(operations);
     logger.info('InAppNotification bulkWrite has run');
     return;
-  }
+  };
 
   getLatestNotificationsByUser = async(
       userId: Types.ObjectId,
@@ -121,7 +121,7 @@ export default class InAppNotificationService {
       logger.error('Error', err);
       throw new Error(err);
     }
-  }
+  };
 
   read = async function(user: Types.ObjectId): Promise<void> {
     const query = { user, status: STATUS_UNREAD };
@@ -138,7 +138,7 @@ export default class InAppNotificationService {
 
     await InAppNotification.findOneAndUpdate(query, parameters, options);
     return;
-  }
+  };
 
   updateAllNotificationsAsOpened = async function(user: IUser & HasObjectId): Promise<void> {
     const filter = { user: user._id, status: STATUS_UNOPENED };
@@ -146,7 +146,7 @@ export default class InAppNotificationService {
 
     await InAppNotification.updateMany(filter, options);
     return;
-  }
+  };
 
   getUnreadCountByUser = async function(user: Types.ObjectId): Promise<number| undefined> {
     const query = { user, status: STATUS_UNREAD };

+ 5 - 5
packages/app/src/server/service/search-delegator/elasticsearch-client.ts

@@ -20,7 +20,7 @@ type ApiResponse<T = any, C = any> = ES6ApiResponse<T, C> | ES7ApiResponse<T, C>
 
 export default class ElasticsearchClient {
 
-  client: ES6Client | ES7Client
+  client: ES6Client | ES7Client;
 
   constructor(client: ES6Client | ES7Client) {
     this.client = client;
@@ -36,12 +36,12 @@ export default class ElasticsearchClient {
       this.client instanceof ES6Client ? this.client.cat.aliases(params) : this.client.cat.aliases(params),
     indices: (params: ES6RequestParams.CatIndices & ES7RequestParams.CatIndices): Promise<ApiResponse<CatIndicesResponse>> =>
       this.client instanceof ES6Client ? this.client.cat.indices(params) : this.client.cat.indices(params),
-  }
+  };
 
   cluster = {
     health: (params: ES6RequestParams.ClusterHealth & ES7RequestParams.ClusterHealth): Promise<ApiResponse<ClusterHealthResponse>> =>
       this.client instanceof ES6Client ? this.client.cluster.health(params) : this.client.cluster.health(params),
-  }
+  };
 
   indices = {
     create: (params: ES6RequestParams.IndicesCreate & ES7RequestParams.IndicesCreate) =>
@@ -62,11 +62,11 @@ export default class ElasticsearchClient {
       this.client instanceof ES6Client ? this.client.indices.validateQuery(params) : this.client.indices.validateQuery(params),
     stats: (params: ES6RequestParams.IndicesStats & ES7RequestParams.IndicesStats): Promise<ApiResponse<IndicesStatsResponse>> =>
       this.client instanceof ES6Client ? this.client.indices.stats(params) : this.client.indices.stats(params),
-  }
+  };
 
   nodes = {
     info: (): Promise<ApiResponse<NodesInfoResponse>> => (this.client instanceof ES6Client ? this.client.nodes.info() : this.client.nodes.info()),
-  }
+  };
 
   ping() {
     return this.client instanceof ES6Client ? this.client.ping() : this.client.ping();

+ 10 - 10
packages/app/src/server/service/search-delegator/elasticsearch.ts

@@ -47,25 +47,25 @@ type Data = any;
 
 class ElasticsearchDelegator implements SearchDelegator<Data, ESTermsKey, ESQueryTerms> {
 
-  name!: SearchDelegatorName.DEFAULT
+  name!: SearchDelegatorName.DEFAULT;
 
-  configManager!: any
+  configManager!: any;
 
-  socketIoService!: any
+  socketIoService!: any;
 
-  isElasticsearchV6: boolean
+  isElasticsearchV6: boolean;
 
-  isElasticsearchReindexOnBoot: boolean
+  isElasticsearchReindexOnBoot: boolean;
 
-  elasticsearch: any
+  elasticsearch: any;
 
-  client: any
+  client: any;
 
-  queries: any
+  queries: any;
 
-  indexName: string
+  indexName: string;
 
-  esUri: string
+  esUri: string;
 
   constructor(configManager, socketIoService) {
     this.name = SearchDelegatorName.DEFAULT;

+ 1 - 1
packages/app/src/server/service/search-delegator/private-legacy-pages.ts

@@ -14,7 +14,7 @@ const AVAILABLE_KEYS = ['match', 'not_match', 'prefix', 'not_prefix'];
 
 class PrivateLegacyPagesDelegator implements SearchDelegator<IPage, MongoTermsKey, MongoQueryTerms> {
 
-  name!: SearchDelegatorName.PRIVATE_LEGACY_PAGES
+  name!: SearchDelegatorName.PRIVATE_LEGACY_PAGES;
 
   constructor() {
     this.name = SearchDelegatorName.PRIVATE_LEGACY_PAGES;

+ 6 - 6
packages/app/src/server/service/search.ts

@@ -71,17 +71,17 @@ const findPageListByIds = async(pageIds: ObjectIdLike[], crowi: any) => {
 
 class SearchService implements SearchQueryParser, SearchResolver {
 
-  crowi!: any
+  crowi!: any;
 
-  configManager!: any
+  configManager!: any;
 
-  isErrorOccuredOnHealthcheck: boolean | null
+  isErrorOccuredOnHealthcheck: boolean | null;
 
-  isErrorOccuredOnSearching: boolean | null
+  isErrorOccuredOnSearching: boolean | null;
 
-  fullTextSearchDelegator: any & ElasticsearchDelegator
+  fullTextSearchDelegator: any & ElasticsearchDelegator;
 
-  nqDelegators: {[key in SearchDelegatorName]: SearchDelegator}
+  nqDelegators: {[key in SearchDelegatorName]: SearchDelegator};
 
   constructor(crowi) {
     this.crowi = crowi;

+ 16 - 13
packages/app/src/services/i18next-hmr.ts

@@ -1,24 +1,27 @@
-import { useEffect } from "react"
-import { useTranslation } from "next-i18next"
+import { useEffect } from 'react';
+
+import { useTranslation } from 'next-i18next';
 
 const isServer = typeof window === 'undefined';
 
-export const useI18nextHMR = (isDev: boolean) => {
-  const { i18n } = useTranslation()
+export const useI18nextHMR = (isDev: boolean): void => {
+  const { i18n } = useTranslation();
+
+  useEffect(() => {
+    if (isDev) {
+      import('i18next-hmr/client').then(({ applyClientHMR }) => {
+        applyClientHMR(i18n);
+      });
+    }
+  }, [i18n, isDev]);
 
   if (!isDev) {
     return;
   }
 
   if (isServer) {
-    import("i18next-hmr/server").then(({ applyServerHMR }) => {
-      applyServerHMR(i18n)
+    import('i18next-hmr/server').then(({ applyServerHMR }) => {
+      applyServerHMR(i18n);
     });
   }
-
-  useEffect(() => {
-    import("i18next-hmr/client").then(({ applyClientHMR }) => {
-      applyClientHMR(i18n)
-    })
-  }, [i18n]);
-}
+};