Taichi Masuyama 4 лет назад
Родитель
Сommit
00ad9752a3

+ 26 - 0
packages/app/src/server/models/interfaces/page.ts

@@ -0,0 +1,26 @@
+import { Schema } from 'mongoose';
+
+export interface IPage {
+  parent: Schema.Types.ObjectId,
+  isEmpty: boolean,
+  path: string
+  revision: Schema.Types.ObjectId,
+  redirectTo: string,
+  status: string,
+  grant: number,
+  grantedUsers: Schema.Types.ObjectId[],
+  grantedGroup: Schema.Types.ObjectId,
+  creator: Schema.Types.ObjectId,
+  lastUpdateUser: Schema.Types.ObjectId,
+  liker: Schema.Types.ObjectId[],
+  seenUsers: Schema.Types.ObjectId[],
+  commentCount: number,
+  slackChannels: string,
+  pageIdOnHackmd: string,
+  revisionHackmdSynced: Schema.Types.ObjectId,
+  hasDraftOnHackmd: boolean,
+  createdAt: Date,
+  updatedAt: Date,
+  deleteUser: Schema.Types.ObjectId,
+  deletedAt: Date,
+}

+ 2 - 2
packages/app/src/server/models/obsolete-page.js

@@ -77,7 +77,7 @@ const populateDataToShowRevision = (page, userPublicFields) => {
 /* eslint-enable object-curly-newline, object-property-newline */
 /* eslint-enable object-curly-newline, object-property-newline */
 
 
 
 
-class PageQueryBuilder {
+export class PageQueryBuilder {
 
 
   constructor(query) {
   constructor(query) {
     this.query = query;
     this.query = query;
@@ -246,7 +246,7 @@ class PageQueryBuilder {
 
 
 }
 }
 
 
-module.exports = function(crowi) {
+export const getPageSchema = (crowi) => {
   let pageEvent;
   let pageEvent;
 
 
   // init event
   // init event

+ 87 - 110
packages/app/src/server/models/page.ts

@@ -10,10 +10,11 @@ import nodePath from 'path';
 import { getOrCreateModel } from '@growi/core';
 import { getOrCreateModel } from '@growi/core';
 import loggerFactory from '../../utils/logger';
 import loggerFactory from '../../utils/logger';
 import Crowi from '../crowi';
 import Crowi from '../crowi';
+import { IPage } from './interfaces/page';
+import { getPageSchema, PageQueryBuilder } from './obsolete-page';
 
 
 const logger = loggerFactory('growi:models:page');
 const logger = loggerFactory('growi:models:page');
 
 
-const getPageSchema = require('./obsolete-page');
 
 
 /*
 /*
  * define schema
  * define schema
@@ -27,31 +28,6 @@ const PAGE_GRANT_ERROR = 1;
 const STATUS_PUBLISHED = 'published';
 const STATUS_PUBLISHED = 'published';
 const STATUS_DELETED = 'deleted';
 const STATUS_DELETED = 'deleted';
 
 
-export interface IPage {
-  parent: Schema.Types.ObjectId,
-  isEmpty: boolean,
-  path: string
-  revision: Schema.Types.ObjectId,
-  redirectTo: string,
-  status: string,
-  grant: number,
-  grantedUsers: Schema.Types.ObjectId[],
-  grantedGroup: Schema.Types.ObjectId,
-  creator: Schema.Types.ObjectId,
-  lastUpdateUser: Schema.Types.ObjectId,
-  liker: Schema.Types.ObjectId[],
-  seenUsers: Schema.Types.ObjectId[],
-  commentCount: number,
-  slackChannels: string,
-  pageIdOnHackmd: string,
-  revisionHackmdSynced: Schema.Types.ObjectId,
-  hasDraftOnHackmd: boolean,
-  createdAt: Date,
-  updatedAt: Date,
-  deleteUser: Schema.Types.ObjectId,
-  deletedAt: Date,
-}
-
 export interface PageDocument extends IPage, Document {}
 export interface PageDocument extends IPage, Document {}
 
 
 export interface PageModel extends Model<PageDocument> {
 export interface PageModel extends Model<PageDocument> {
@@ -96,94 +72,95 @@ const schema = new Schema<PageDocument, PageModel>({
 schema.plugin(mongoosePaginate);
 schema.plugin(mongoosePaginate);
 schema.plugin(uniqueValidator);
 schema.plugin(uniqueValidator);
 
 
-export default (crowi: Crowi): any => {
-  // add old page schema methods
-  const pageSchema = getPageSchema(crowi);
-  schema.methods = pageSchema.methods;
-  schema.statics = pageSchema.statics;
-  const { PageQueryBuilder } = pageSchema.statics;
 
 
-  const collectAncestorPaths = (path: string, ancestorPaths: string[] = []): string[] => {
-    const parentPath = nodePath.dirname(path);
-    ancestorPaths.push(parentPath);
-
-    if (path !== '/') return collectAncestorPaths(parentPath, ancestorPaths);
-
-    return ancestorPaths;
-  };
-
-  schema.statics.createEmptyPagesByPaths = async function(paths: string[]): Promise<void> {
-    const Page = this;
-
-    // find existing parents
-    const builder = new PageQueryBuilder(Page.find({}, { _id: 0, path: 1 }));
-    const existingPages = await builder
-      .addConditionToListByPathsArray(paths)
-      .query
-      .lean()
-      .exec();
-    const existingPagePaths = existingPages.map(page => page.path);
-
-    // paths to create empty pages
-    const notExistingPagePaths = paths.filter(path => !existingPagePaths.includes(path));
-
-    // insertMany empty pages
-    try {
-      await Page.insertMany(notExistingPagePaths.map(path => ({ path, isEmpty: true })));
-    }
-    catch (err) {
-      logger.error('Failed to insert empty pages.', err);
-      throw err;
-    }
-  };
-
-  schema.statics.getParentIdAndFillAncestors = async function(path: string): Promise<string | null> {
-    const Page = this;
-    const parentPath = nodePath.dirname(path);
+/*
+ * Methods
+ */
+const collectAncestorPaths = (path: string, ancestorPaths: string[] = []): string[] => {
+  const parentPath = nodePath.dirname(path);
+  ancestorPaths.push(parentPath);
+
+  if (path !== '/') return collectAncestorPaths(parentPath, ancestorPaths);
+
+  return ancestorPaths;
+};
+
+schema.statics.createEmptyPagesByPaths = async function(paths: string[]): Promise<void> {
+  // find existing parents
+  const builder = new PageQueryBuilder(this.find({}, { _id: 0, path: 1 }));
+  const existingPages = await builder
+    .addConditionToListByPathsArray(paths)
+    .query
+    .lean()
+    .exec();
+  const existingPagePaths = existingPages.map(page => page.path);
+
+  // paths to create empty pages
+  const notExistingPagePaths = paths.filter(path => !existingPagePaths.includes(path));
+
+  // insertMany empty pages
+  try {
+    await this.insertMany(notExistingPagePaths.map(path => ({ path, isEmpty: true })));
+  }
+  catch (err) {
+    logger.error('Failed to insert empty pages.', err);
+    throw err;
+  }
+};
+
+schema.statics.getParentIdAndFillAncestors = async function(path: string): Promise<string | null> {
+  const parentPath = nodePath.dirname(path);
 
 
-    const parent = await Page.findOne({ path: parentPath }); // find the oldest parent which must always be the true parent
-    if (parent != null) { // fill parents if parent is null
-      return parent._id;
-    }
-
-    const ancestorPaths = collectAncestorPaths(path); // paths of parents need to be created
-
-    // just create ancestors with empty pages
-    await Page.createEmptyPagesByPaths(ancestorPaths);
-
-    // find ancestors
-    const builder = new PageQueryBuilder(Page.find({}, { _id: 1, path: 1 }));
-    const ancestors = await builder
-      .addConditionToListByPathsArray(ancestorPaths)
-      .query
-      .lean()
-      .exec();
-
-
-    const ancestorsMap = new Map(); // Map<path, _id>
-    ancestors.forEach(page => ancestorsMap.set(page.path, page._id));
-
-    // bulkWrite to update ancestors
-    const nonRootAncestors = ancestors.filter(page => page.path !== '/');
-    const operations = nonRootAncestors.map((page) => {
-      const { path } = page;
-      const parentPath = nodePath.dirname(path);
-      return {
-        updateOne: {
-          filter: {
-            path,
-          },
-          update: {
-            parent: ancestorsMap.get(parentPath),
-          },
+  const parent = await this.findOne({ path: parentPath }); // find the oldest parent which must always be the true parent
+  if (parent != null) { // fill parents if parent is null
+    return parent._id;
+  }
+
+  const ancestorPaths = collectAncestorPaths(path); // paths of parents need to be created
+
+  // just create ancestors with empty pages
+  await this.createEmptyPagesByPaths(ancestorPaths);
+
+  // find ancestors
+  const builder = new PageQueryBuilder(this.find({}, { _id: 1, path: 1 }));
+  const ancestors = await builder
+    .addConditionToListByPathsArray(ancestorPaths)
+    .query
+    .lean()
+    .exec();
+
+
+  const ancestorsMap = new Map(); // Map<path, _id>
+  ancestors.forEach(page => ancestorsMap.set(page.path, page._id));
+
+  // bulkWrite to update ancestors
+  const nonRootAncestors = ancestors.filter(page => page.path !== '/');
+  const operations = nonRootAncestors.map((page) => {
+    const { path } = page;
+    const parentPath = nodePath.dirname(path);
+    return {
+      updateOne: {
+        filter: {
+          path,
         },
         },
-      };
-    });
-    await Page.bulkWrite(operations);
+        update: {
+          parent: ancestorsMap.get(parentPath),
+        },
+      },
+    };
+  });
+  await this.bulkWrite(operations);
+
+  const parentId = ancestorsMap.get(parentPath);
+  return parentId;
+};
+
+export default (crowi: Crowi): any => {
+  // add old page schema methods
+  const pageSchema = getPageSchema(crowi);
+  schema.methods = { ...pageSchema.methods, ...schema.methods };
+  schema.statics = { ...pageSchema.statics, ...schema.statics };
 
 
-    const parentId = ancestorsMap.get(parentPath);
-    return parentId;
-  };
 
 
   return getOrCreateModel<PageDocument, PageModel>('Page', schema);
   return getOrCreateModel<PageDocument, PageModel>('Page', schema);
 };
 };