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

Implement method to get page data from pagePath array

Shun Miyazawa 1 год назад
Родитель
Сommit
74009aa2c2

+ 21 - 0
apps/app/src/server/models/page.ts

@@ -88,6 +88,9 @@ export interface PageModel extends Model<PageDocument> {
   findByIdsAndViewer(
     pageIds: ObjectIdLike[], user, userGroups?, includeEmpty?: boolean, includeAnyoneWithTheLink?: boolean,
   ): Promise<HydratedDocument<PageDocument>[]>
+  findByPathsAndViewer(
+    paths: string[], user, userGroups?: null, includeEmpty?: boolean, includeAnyoneWithTheLink?: boolean,
+  ): Promise<HydratedDocument<PageDocument>[]>
   findByPath(path: string, includeEmpty?: boolean): Promise<HydratedDocument<PageDocument> | null>
   findByPathAndViewer(path: string | null, user, userGroups?, useFindOne?: true, includeEmpty?: boolean): Promise<HydratedDocument<PageDocument> | null>
   findByPathAndViewer(path: string | null, user, userGroups?, useFindOne?: false, includeEmpty?: boolean): Promise<HydratedDocument<PageDocument>[]>
@@ -670,6 +673,24 @@ schema.statics.findByPathAndViewer = async function(
   return queryBuilder.query.exec();
 };
 
+/*
+ * Find pages by paths and viewer.
+ */
+schema.statics.findByPathsAndViewer = async function(
+    paths: string[], user, userGroups = null, includeEmpty = false, includeAnyoneWithTheLink = false,
+): Promise<PageDocument[]> {
+  if (paths == null || paths.length === 0) {
+    throw new Error('paths are required.');
+  }
+
+  const baseQuery = this.find({ path: { $in: paths } });
+  const queryBuilder = new PageQueryBuilder(baseQuery, includeEmpty);
+
+  await queryBuilder.addViewerCondition(user, userGroups, includeAnyoneWithTheLink);
+
+  return queryBuilder.query.exec();
+};
+
 schema.statics.countByPathAndViewer = async function(path: string | null, user, userGroups = null, includeEmpty = false): Promise<number> {
   if (path == null) {
     throw new Error('path is required.');

+ 54 - 0
apps/app/src/server/routes/apiv3/page/get-pages-by-page-paths.ts

@@ -0,0 +1,54 @@
+import type { IPage, IUserHasId } from '@growi/core';
+import type { Request, RequestHandler } from 'express';
+import type { ValidationChain } from 'express-validator';
+import { query } from 'express-validator';
+import mongoose from 'mongoose';
+
+import type Crowi from '~/server/crowi';
+import { accessTokenParser } from '~/server/middlewares/access-token-parser';
+import type { PageModel } from '~/server/models/page';
+import loggerFactory from '~/utils/logger';
+
+import { apiV3FormValidator } from '../../../middlewares/apiv3-form-validator';
+import type { ApiV3Response } from '../interfaces/apiv3-response';
+
+
+const logger = loggerFactory('growi:routes:apiv3:page:get-pages-by-page-paths');
+
+type GetPageByPagePaths = (crowi: Crowi) => RequestHandler[];
+
+type ReqQuery = {
+  paths: string[],
+}
+
+interface Req extends Request<undefined, ApiV3Response, undefined, ReqQuery> {
+  user: IUserHasId,
+}
+export const getPagesByPagePaths: GetPageByPagePaths = (crowi) => {
+  const Page = mongoose.model<IPage, PageModel>('Page');
+  const loginRequiredStrictly = require('../../../middlewares/login-required')(crowi);
+
+  // define validators for req.params
+  const validator: ValidationChain[] = [
+    query('paths').isArray().withMessage('paths must be an array of strings'),
+    query('paths.*') // each item of paths
+      .isString()
+      .withMessage('paths must be an array of strings'),
+  ];
+
+  return [
+    accessTokenParser, loginRequiredStrictly,
+    validator, apiV3FormValidator,
+    async(req: Req, res: ApiV3Response) => {
+      const { paths } = req.query;
+      try {
+        const pages = await Page.findByPathsAndViewer(paths, req.user, null, true);
+        return res.apiv3({ pages });
+      }
+      catch (err) {
+        logger.error(err);
+        return res.apiv3Err(err);
+      }
+    },
+  ];
+};

+ 3 - 0
apps/app/src/server/routes/apiv3/page/index.ts

@@ -35,6 +35,7 @@ import type { ApiV3Response } from '../interfaces/apiv3-response';
 
 import { checkPageExistenceHandlersFactory } from './check-page-existence';
 import { createPageHandlersFactory } from './create-page';
+import { getPagesByPagePaths } from './get-pages-by-page-paths';
 import { getYjsDataHandlerFactory } from './get-yjs-data';
 import { publishPageHandlersFactory } from './publish-page';
 import { syncLatestRevisionBodyToYjsDraftHandlerFactory } from './sync-latest-revision-body-to-yjs-draft';
@@ -266,6 +267,8 @@ module.exports = (crowi) => {
     return res.apiv3({ page, pages });
   });
 
+  router.get('/pages', getPagesByPagePaths(crowi));
+
   router.get('/exist', checkPageExistenceHandlersFactory(crowi));
 
   /**