Просмотр исходного кода

Merge pull request #10646 from growilabs/imprv/176311-improve-argument-types-of-findpageandmetadatabyviewer

imprv: Argument types of findPageAndMetaDataByViewer
Yuki Takei 3 месяцев назад
Родитель
Сommit
d76cb50736

+ 2 - 8
apps/app/src/pages/[[...path]]/page-data-props.ts

@@ -159,9 +159,7 @@ export async function getPageDataForInitial(
   const pageWithMeta = await findPageAndMetaDataByViewer(
     pageService,
     pageGrantService,
-    pageId,
-    resolvedPagePath,
-    user,
+    { pageId, path: resolvedPagePath, user },
   );
 
   // Handle URL conversion
@@ -285,11 +283,7 @@ export async function getPageDataForSameRoute(
   const pageWithMetaBasicOnly = await findPageAndMetaDataByViewer(
     pageService,
     pageGrantService,
-    pageId,
-    resolvedPagePath,
-    user,
-    false, // isSharedPage
-    true, // basicOnly
+    { pageId, path: resolvedPagePath, user, basicOnly: true },
   );
 
   const currentPathname = resolveFinalizedPathname(

+ 1 - 4
apps/app/src/pages/share/[[...path]]/page-data-props.ts

@@ -60,10 +60,7 @@ export const getPageDataForInitial = async (
   const pageWithMeta = await findPageAndMetaDataByViewer(
     pageService,
     pageGrantService,
-    pageId,
-    null,
-    undefined, // no user for share link
-    true, // isSharedPage
+    { pageId, path: null, isSharedPage: true },
   );
 
   // not found

+ 7 - 14
apps/app/src/server/routes/apiv3/page/index.ts

@@ -263,14 +263,12 @@ module.exports = (crowi: Crowi) => {
             return res.apiv3Err('ShareLink is not found', 404);
           }
           return respondWithSinglePage(
-            await findPageAndMetaDataByViewer(
-              pageService,
-              pageGrantService,
-              getIdStringForRef(shareLink.relatedPage),
+            await findPageAndMetaDataByViewer(pageService, pageGrantService, {
+              pageId: getIdStringForRef(shareLink.relatedPage),
               path,
               user,
-              true,
-            ),
+              isSharedPage: true,
+            }),
           );
         }
 
@@ -293,13 +291,11 @@ module.exports = (crowi: Crowi) => {
         }
 
         return respondWithSinglePage(
-          await findPageAndMetaDataByViewer(
-            pageService,
-            pageGrantService,
+          await findPageAndMetaDataByViewer(pageService, pageGrantService, {
             pageId,
             path,
             user,
-          ),
+          }),
         );
       } catch (err) {
         logger.error('get-page-failed', err);
@@ -595,10 +591,7 @@ module.exports = (crowi: Crowi) => {
         const { meta } = await findPageAndMetaDataByViewer(
           pageService,
           pageGrantService,
-          pageId,
-          null,
-          user,
-          isSharedPage,
+          { pageId, path: null, user, isSharedPage },
         );
 
         if (isIPageNotFoundInfo(meta)) {

+ 40 - 34
apps/app/src/server/service/page/find-page-and-meta-data-by-viewer.ts

@@ -21,58 +21,64 @@ import type { IPageGrantService } from '~/server/service/page-grant';
 import Subscription from '../../models/subscription';
 import type { IPageService } from './page-service';
 
+// ============================================================
+// Type Definitions
+// ============================================================
+
+// Shorthand for page document type
+type PageDoc = HydratedDocument<PageDocument>;
+
+// Options
+type BaseOpts = {
+  pageId: string | null;
+  path: string | null;
+  user?: HydratedDocument<IUser>;
+  isSharedPage?: boolean;
+};
+type OptsBasic = BaseOpts & { basicOnly: true };
+type OptsExt = BaseOpts & { basicOnly?: false };
+type OptsImpl = BaseOpts & { basicOnly?: boolean };
+
+// Results
+type FoundResult<T extends IPageInfoBasic | IPageInfoExt> =
+  IDataWithRequiredMeta<PageDoc, T>;
+type NotFoundResult = IDataWithRequiredMeta<null, IPageNotFoundInfo>;
+
+type ResultBasic = FoundResult<IPageInfoBasic> | NotFoundResult;
+type ResultExt = FoundResult<IPageInfoExt> | NotFoundResult;
+type ResultImpl = ResultBasic | ResultExt | NotFoundResult;
+
+// ============================================================
+// Function Overloads
+// ============================================================
+
 // Overload: basicOnly = true returns basic info only
 export async function findPageAndMetaDataByViewer(
   pageService: IPageService,
   pageGrantService: IPageGrantService,
-  pageId: string | null,
-  path: string | null,
-  user: HydratedDocument<IUser> | undefined,
-  isSharedPage: boolean,
-  basicOnly: true,
-): Promise<
-  | IDataWithRequiredMeta<HydratedDocument<PageDocument>, IPageInfoBasic>
-  | IDataWithRequiredMeta<null, IPageNotFoundInfo>
->;
+  opts: OptsBasic,
+): Promise<ResultBasic>;
 
 // Overload: basicOnly = false or undefined returns extended info
 export async function findPageAndMetaDataByViewer(
   pageService: IPageService,
   pageGrantService: IPageGrantService,
-  pageId: string | null,
-  path: string | null,
-  user?: HydratedDocument<IUser>,
-  isSharedPage?: boolean,
-  basicOnly?: false,
-): Promise<
-  | IDataWithRequiredMeta<HydratedDocument<PageDocument>, IPageInfoExt>
-  | IDataWithRequiredMeta<null, IPageNotFoundInfo>
->;
+  opts: OptsExt,
+): Promise<ResultExt>;
 
 // Implementation
 export async function findPageAndMetaDataByViewer(
   pageService: IPageService,
   pageGrantService: IPageGrantService,
+  opts: OptsImpl,
+): Promise<ResultImpl> {
+  const { pageId, path, user, isSharedPage = false, basicOnly = false } = opts;
 
-  pageId: string | null, // either pageId or path must be specified
-  path: string | null, // either pageId or path must be specified
-  user?: HydratedDocument<IUser>,
-  isSharedPage = false,
-  basicOnly = false,
-): Promise<
-  | IDataWithRequiredMeta<
-      HydratedDocument<PageDocument>,
-      IPageInfoExt | IPageInfoBasic
-    >
-  | IDataWithRequiredMeta<null, IPageNotFoundInfo>
-> {
   assert(pageId != null || path != null);
 
-  const Page = mongoose.model<HydratedDocument<PageDocument>, PageModel>(
-    'Page',
-  );
+  const Page = mongoose.model<PageDoc, PageModel>('Page');
 
-  let page: HydratedDocument<PageDocument> | null;
+  let page: PageDoc | null;
   if (pageId != null) {
     // prioritized
     page = await Page.findByIdAndViewer(pageId, user, null, true);