mirror of
https://github.com/vale981/Vulcan
synced 2025-03-07 02:21:43 -05:00
278 lines
5.3 KiB
JavaScript
278 lines
5.3 KiB
JavaScript
import Users from 'meteor/vulcan:users';
|
|
import Posts from './collection.js';
|
|
import { Utils } from 'meteor/vulcan:core';
|
|
|
|
/**
|
|
* @summary Posts config namespace
|
|
* @type {Object}
|
|
*/
|
|
const formGroups = {
|
|
admin: {
|
|
name: "admin",
|
|
order: 2
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @summary Posts schema
|
|
* @type {Object}
|
|
*/
|
|
const schema = {
|
|
/**
|
|
ID
|
|
*/
|
|
_id: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
},
|
|
/**
|
|
Timetstamp of post creation
|
|
*/
|
|
createdAt: {
|
|
type: Date,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
onInsert: (document, currentUser) => {
|
|
return new Date();
|
|
}
|
|
},
|
|
/**
|
|
Timestamp of post first appearing on the site (i.e. being approved)
|
|
*/
|
|
postedAt: {
|
|
type: Date,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['admins'],
|
|
editableBy: ['admins'],
|
|
control: "datetime",
|
|
group: formGroups.admin
|
|
},
|
|
/**
|
|
URL
|
|
*/
|
|
url: {
|
|
type: String,
|
|
optional: true,
|
|
max: 500,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['members'],
|
|
editableBy: ['members'],
|
|
control: "url",
|
|
order: 10,
|
|
searchable: true
|
|
},
|
|
/**
|
|
Title
|
|
*/
|
|
title: {
|
|
type: String,
|
|
optional: false,
|
|
max: 500,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['members'],
|
|
editableBy: ['members'],
|
|
control: "text",
|
|
order: 20,
|
|
searchable: true
|
|
},
|
|
/**
|
|
Slug
|
|
*/
|
|
slug: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
},
|
|
/**
|
|
Post body (markdown)
|
|
*/
|
|
body: {
|
|
type: String,
|
|
optional: true,
|
|
max: 3000,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['members'],
|
|
editableBy: ['members'],
|
|
control: "textarea",
|
|
order: 30
|
|
},
|
|
/**
|
|
HTML version of the post body
|
|
*/
|
|
htmlBody: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
},
|
|
/**
|
|
Post Excerpt
|
|
*/
|
|
excerpt: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
searchable: true
|
|
},
|
|
/**
|
|
Count of how many times the post's page was viewed
|
|
*/
|
|
viewCount: {
|
|
type: Number,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
defaultValue: 0
|
|
},
|
|
/**
|
|
Timestamp of the last comment
|
|
*/
|
|
lastCommentedAt: {
|
|
type: Date,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
},
|
|
/**
|
|
Count of how many times the post's link was clicked
|
|
*/
|
|
clickCount: {
|
|
type: Number,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
defaultValue: 0
|
|
},
|
|
/**
|
|
The post's status. One of pending (`1`), approved (`2`), or deleted (`3`)
|
|
*/
|
|
status: {
|
|
type: Number,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['admins'],
|
|
editableBy: ['admins'],
|
|
control: "select",
|
|
onInsert: document => {
|
|
if (document.userId && !document.status) {
|
|
const user = Users.findOne(document.userId);
|
|
return Posts.getDefaultStatus(user);
|
|
}
|
|
},
|
|
form: {
|
|
noselect: true,
|
|
options: () => Posts.statuses,
|
|
group: 'admin'
|
|
},
|
|
group: formGroups.admin
|
|
},
|
|
/**
|
|
Whether a post is scheduled in the future or not
|
|
*/
|
|
isFuture: {
|
|
type: Boolean,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
},
|
|
/**
|
|
Whether the post is sticky (pinned to the top of posts lists)
|
|
*/
|
|
sticky: {
|
|
type: Boolean,
|
|
optional: true,
|
|
defaultValue: false,
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['admins'],
|
|
editableBy: ['admins'],
|
|
control: "checkbox",
|
|
group: formGroups.admin
|
|
},
|
|
/**
|
|
Whether the post is inactive. Inactive posts see their score recalculated less often
|
|
*/
|
|
inactive: {
|
|
type: Boolean,
|
|
optional: true,
|
|
defaultValue: false
|
|
},
|
|
/**
|
|
Save info for later spam checking on a post. We will use this for the akismet package
|
|
*/
|
|
userIP: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
},
|
|
userAgent: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
},
|
|
referrer: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['admins'],
|
|
},
|
|
/**
|
|
The post author's name
|
|
*/
|
|
author: {
|
|
type: String,
|
|
optional: true,
|
|
viewableBy: ['guests'],
|
|
onEdit: (modifier, document, currentUser) => {
|
|
// if userId is changing, change the author name too
|
|
if (modifier.$set && modifier.$set.userId) {
|
|
return Users.getDisplayNameById(modifier.$set.userId)
|
|
}
|
|
}
|
|
},
|
|
/**
|
|
The post author's `_id`.
|
|
*/
|
|
userId: {
|
|
type: String,
|
|
optional: true,
|
|
control: "select",
|
|
viewableBy: ['guests'],
|
|
insertableBy: ['members'],
|
|
hidden: true,
|
|
resolveAs: {
|
|
fieldName: 'user',
|
|
type: 'User',
|
|
resolver: async (post, args, context) => {
|
|
if (!post.userId) return null;
|
|
const user = await context.Users.loader.load(post.userId);
|
|
return context.Users.restrictViewableFields(context.currentUser, context.Users, user);
|
|
},
|
|
addOriginalField: true
|
|
},
|
|
},
|
|
|
|
// GraphQL-only fields
|
|
|
|
pageUrl: {
|
|
type: String,
|
|
optional: true,
|
|
resolveAs: {
|
|
fieldName: 'pageUrl',
|
|
type: 'String',
|
|
resolver: (post, args, context) => {
|
|
return Posts.getPageUrl(post, true);
|
|
},
|
|
}
|
|
},
|
|
|
|
linkUrl: {
|
|
type: String,
|
|
optional: true,
|
|
resolveAs: {
|
|
fieldName: 'linkUrl',
|
|
type: 'String',
|
|
resolver: (post, args, context) => {
|
|
return post.url ? Utils.getOutgoingUrl(post.url) : Posts.getPageUrl(post, true);
|
|
},
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
export default schema;
|