Refactor validations

This commit is contained in:
Tom Moor
2022-07-24 13:40:04 +01:00
parent 870d9ed41e
commit ec35af4bc5
13 changed files with 47 additions and 33 deletions

View File

@@ -6,8 +6,8 @@ import { useDrag, useDrop } from "react-dnd";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import styled from "styled-components";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { sortNavigationNodes } from "@shared/utils/collections";
import { DocumentValidation } from "@shared/validations";
import Collection from "~/models/Collection";
import Document from "~/models/Document";
import Fade from "~/components/Fade";
@@ -319,7 +319,7 @@ function InnerDocumentLink(
onSubmit={handleTitleChange}
onEditing={handleTitleEditing}
canUpdate={canUpdate}
maxLength={MAX_TITLE_LENGTH}
maxLength={DocumentValidation.maxTitleLength}
/>
}
isActive={(match, location: Location<{ starred?: boolean }>) =>

View File

@@ -3,7 +3,7 @@ import { observer } from "mobx-react";
import { useState } from "react";
import * as React from "react";
import { Trans, useTranslation } from "react-i18next";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { CollectionValidation } from "@shared/validations";
import Button from "~/components/Button";
import Flex from "~/components/Flex";
import IconPicker from "~/components/IconPicker";
@@ -94,7 +94,7 @@ const CollectionEdit = ({ collectionId, onSubmit }: Props) => {
type="text"
label={t("Name")}
onChange={handleNameChange}
maxLength={MAX_TITLE_LENGTH}
maxLength={CollectionValidation.maxNameLength}
value={name}
required
autoFocus

View File

@@ -3,7 +3,7 @@ import { observable } from "mobx";
import { observer } from "mobx-react";
import * as React from "react";
import { withTranslation, Trans, WithTranslation } from "react-i18next";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { CollectionValidation } from "@shared/validations";
import RootStore from "~/stores/RootStore";
import Collection from "~/models/Collection";
import Button from "~/components/Button";
@@ -128,7 +128,7 @@ class CollectionNew extends React.Component<Props> {
type="text"
label={t("Name")}
onChange={this.handleNameChange}
maxLength={MAX_TITLE_LENGTH}
maxLength={CollectionValidation.maxNameLength}
value={this.name}
required
autoFocus

View File

@@ -2,13 +2,13 @@ import { observer } from "mobx-react";
import * as React from "react";
import styled from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { light } from "@shared/styles/theme";
import {
getCurrentDateAsString,
getCurrentDateTimeAsString,
getCurrentTimeAsString,
} from "@shared/utils/date";
import { DocumentValidation } from "@shared/validations";
import Document from "~/models/Document";
import ContentEditable, { RefHandle } from "~/components/ContentEditable";
import Star, { AnimatedStar } from "~/components/Star";
@@ -132,7 +132,7 @@ const EditableTitle = React.forwardRef(
$emojiWidth={emojiWidth}
$isStarred={document.isStarred}
autoFocus={!value}
maxLength={MAX_TITLE_LENGTH}
maxLength={DocumentValidation.maxTitleLength}
readOnly={readOnly}
dir="auto"
ref={ref}

View File

@@ -2,10 +2,10 @@ import path from "path";
import invariant from "invariant";
import { find, orderBy, filter, compact, omitBy } from "lodash";
import { observable, action, computed, runInAction } from "mobx";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { DateFilter } from "@shared/types";
import { subtractDate } from "@shared/utils/date";
import naturalSort from "@shared/utils/naturalSort";
import { DocumentValidation } from "@shared/validations";
import BaseStore from "~/stores/BaseStore";
import RootStore from "~/stores/RootStore";
import Document from "~/models/Document";
@@ -553,7 +553,7 @@ export default class DocumentsStore extends BaseStore<Document> {
template: document.template,
title: `${document.title.slice(
0,
MAX_TITLE_LENGTH - append.length
DocumentValidation.maxTitleLength - append.length
)}${append}`,
text: document.text,
});

View File

@@ -5,8 +5,8 @@ import mammoth from "mammoth";
import quotedPrintable from "quoted-printable";
import { Transaction } from "sequelize";
import utf8 from "utf8";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import parseTitle from "@shared/utils/parseTitle";
import { DocumentValidation } from "@shared/validations";
import { APM } from "@server/logging/tracing";
import { User } from "@server/models";
import dataURItoBuffer from "@server/utils/dataURItoBuffer";
@@ -221,7 +221,7 @@ async function documentImporter({
}
// It's better to truncate particularly long titles than fail the import
title = truncate(title, { length: MAX_TITLE_LENGTH });
title = truncate(title, { length: DocumentValidation.maxTitleLength });
return {
text,

View File

@@ -1,11 +1,10 @@
import fractionalIndex from "fractional-index";
import { Sequelize, Op, WhereOptions } from "sequelize";
import { PinValidation } from "@shared/validations";
import { sequelize } from "@server/database/sequelize";
import { ValidationError } from "@server/errors";
import { Pin, User, Event } from "@server/models";
const MAX_PINS = 8;
type Props = {
/** The user creating the pin */
user: User;
@@ -40,8 +39,10 @@ export default async function pinCreator({
};
const count = await Pin.count({ where });
if (count >= MAX_PINS) {
throw ValidationError(`You cannot pin more than ${MAX_PINS} documents`);
if (count >= PinValidation.max) {
throw ValidationError(
`You cannot pin more than ${PinValidation.max} documents`
);
}
if (!index) {

View File

@@ -21,7 +21,6 @@ import {
Length as SimpleLength,
} from "sequelize-typescript";
import isUUID from "validator/lib/isUUID";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { sortNavigationNodes } from "@shared/utils/collections";
import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { CollectionValidation } from "@shared/validations";
@@ -144,8 +143,8 @@ class Collection extends ParanoidModel {
@NotContainsUrl
@Length({
max: MAX_TITLE_LENGTH,
msg: `name must be ${MAX_TITLE_LENGTH} characters or less`,
max: CollectionValidation.maxNameLength,
msg: `name must be ${CollectionValidation.maxNameLength} characters or less`,
})
@Column
name: string;

View File

@@ -35,12 +35,12 @@ import {
import MarkdownSerializer from "slate-md-serializer";
import isUUID from "validator/lib/isUUID";
import * as Y from "yjs";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { DateFilter } from "@shared/types";
import getTasks from "@shared/utils/getTasks";
import parseTitle from "@shared/utils/parseTitle";
import unescape from "@shared/utils/unescape";
import { SLUG_URL_REGEX } from "@shared/utils/urlHelpers";
import { DocumentValidation } from "@shared/validations";
import { parser } from "@server/editor";
import slugify from "@server/utils/slugify";
import Backlink from "./Backlink";
@@ -196,8 +196,8 @@ class Document extends ParanoidModel {
urlId: string;
@Length({
max: MAX_TITLE_LENGTH,
msg: `Document title must be ${MAX_TITLE_LENGTH} characters or less`,
max: DocumentValidation.maxTitleLength,
msg: `Document title must be ${DocumentValidation.maxTitleLength} characters or less`,
})
@Column
title: string;

View File

@@ -10,7 +10,7 @@ import {
Length as SimpleLength,
} from "sequelize-typescript";
import MarkdownSerializer from "slate-md-serializer";
import { MAX_TITLE_LENGTH } from "@shared/constants";
import { DocumentValidation } from "@shared/validations";
import Document from "./Document";
import User from "./User";
import IdModel from "./base/IdModel";
@@ -43,8 +43,8 @@ class Revision extends IdModel {
editorVersion: string;
@Length({
max: MAX_TITLE_LENGTH,
msg: `Revision title must be ${MAX_TITLE_LENGTH} characters or less`,
max: DocumentValidation.maxTitleLength,
msg: `Revision title must be ${DocumentValidation.maxTitleLength} characters or less`,
})
@Column
title: string;

View File

@@ -9,7 +9,7 @@ import {
BeforeValidate,
BeforeCreate,
} from "sequelize-typescript";
import { MAX_TEAM_DOMAINS } from "@shared/constants";
import { TeamValidation } from "@shared/validations";
import { ValidationError } from "@server/errors";
import Team from "./Team";
import User from "./User";
@@ -59,9 +59,9 @@ class TeamDomain extends IdModel {
const count = await this.count({
where: { teamId: model.teamId },
});
if (count >= MAX_TEAM_DOMAINS) {
if (count >= TeamValidation.maxDomains) {
throw ValidationError(
`You have reached the limit of ${MAX_TEAM_DOMAINS} domains`
`You have reached the limit of ${TeamValidation.maxDomains} domains`
);
}
}

View File

@@ -1,7 +1,3 @@
export const USER_PRESENCE_INTERVAL = 5000;
export const MAX_AVATAR_DISPLAY = 6;
export const MAX_TITLE_LENGTH = 100;
export const MAX_TEAM_DOMAINS = 10;

View File

@@ -1,4 +1,22 @@
export const CollectionValidation = {
/* The maximum length of the collection description */
/** The maximum length of the collection description */
maxDescriptionLength: 1000,
/** The maximum length of the collection name */
maxNameLength: 100,
};
export const DocumentValidation = {
/** The maximum length of the document title */
maxTitleLength: 100,
};
export const PinValidation = {
/** The maximum number of pinned documents on an individual collection or home screen */
max: 8,
};
export const TeamValidation = {
/** The maximum number of domains per team */
maxDomains: 10,
};