2016-08-10 10:40:17 +09:00
import Telescope from 'meteor/nova:lib' ;
2016-06-23 15:00:58 +09:00
import Users from 'meteor/nova:users' ;
2016-11-14 17:17:44 +09:00
import marked from 'marked' ;
2016-11-22 18:14:51 -05:00
import mutations from './mutations.js' ;
2016-11-25 11:46:31 +09:00
import Posts from './collection.js' ;
2016-06-23 15:00:58 +09:00
/ * *
* @ summary Posts config namespace
* @ type { Object }
* /
2016-11-22 18:14:51 -05:00
const formGroups = {
2016-07-13 11:46:45 +09:00
admin : {
name : "admin" ,
order : 2
}
} ;
2016-06-23 15:00:58 +09:00
2016-07-21 09:40:05 +09:00
// check if user can create a new post
const canInsert = user => Users . canDo ( user , "posts.new" ) ;
// check if user can edit a post
2016-11-22 18:14:51 -05:00
const canEdit = mutations . edit . check ;
2016-07-21 09:40:05 +09:00
// check if user can edit *all* posts
2016-11-22 18:14:51 -05:00
const canEditAll = user => Users . canDo ( user , "posts.edit.all" ) ; // we don't use the mutations.edit check here, to be changed later with ability to give options to mutations.edit.check?
2016-07-21 09:40:05 +09:00
2016-10-29 14:17:57 +09:00
const alwaysPublic = user => true ;
2016-06-23 15:00:58 +09:00
/ * *
* @ summary Posts schema
2016-11-22 18:14:51 -05:00
* @ type { Object }
2016-06-23 15:00:58 +09:00
* /
2016-11-22 18:14:51 -05:00
const schema = {
2016-06-23 15:00:58 +09:00
/ * *
ID
* /
_id : {
type : String ,
optional : true ,
2016-11-08 15:16:58 +09:00
publish : true ,
viewableIf : alwaysPublic ,
2016-06-23 15:00:58 +09:00
} ,
/ * *
Timetstamp of post creation
* /
createdAt : {
type : Date ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : canEditAll ,
2016-11-14 17:17:44 +09:00
publish : true , // publish so that admins can sort pending posts by createdAt
autoValue : ( documentOrModifier ) => {
if ( documentOrModifier && ! documentOrModifier . $set ) return new Date ( ) // if this is an insert, set createdAt to current timestamp
}
2016-06-23 15:00:58 +09:00
} ,
/ * *
Timestamp of post first appearing on the site ( i . e . being approved )
* /
postedAt : {
type : Date ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canEditAll ,
editableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
publish : true ,
control : "datetime" ,
2016-11-22 18:14:51 -05:00
group : formGroups . admin
2016-06-23 15:00:58 +09:00
} ,
/ * *
URL
* /
url : {
type : String ,
optional : true ,
max : 500 ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canInsert ,
editableIf : canEdit ,
2016-06-23 15:00:58 +09:00
control : "text" ,
publish : true ,
order : 10
} ,
/ * *
Title
* /
title : {
type : String ,
optional : false ,
max : 500 ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canInsert ,
editableIf : canEdit ,
2016-06-23 15:00:58 +09:00
control : "text" ,
publish : true ,
order : 20
} ,
/ * *
Slug
* /
slug : {
type : String ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-06-23 15:00:58 +09:00
publish : true ,
2016-11-14 17:17:44 +09:00
autoValue : ( documentOrModifier ) => {
// if title is changing, return new slug
const newTitle = documentOrModifier . title || documentOrModifier . $set && documentOrModifier . $set . title
if ( newTitle ) {
return Telescope . utils . slugify ( newTitle )
}
}
2016-06-23 15:00:58 +09:00
} ,
/ * *
Post body ( markdown )
* /
body : {
type : String ,
optional : true ,
max : 3000 ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canInsert ,
editableIf : canEdit ,
2016-06-23 15:00:58 +09:00
control : "textarea" ,
publish : true ,
order : 30
} ,
/ * *
HTML version of the post body
* /
htmlBody : {
type : String ,
optional : true ,
publish : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-11-14 17:17:44 +09:00
autoValue ( documentOrModifier ) {
const body = documentOrModifier . body || documentOrModifier . $set && documentOrModifier . $set . body ;
if ( body ) {
return Telescope . utils . sanitize ( marked ( body ) )
} else if ( documentOrModifier . $unset && documentOrModifier . $unset . body ) {
return ''
}
}
2016-06-23 15:00:58 +09:00
} ,
/ * *
Post Excerpt
* /
excerpt : {
type : String ,
optional : true ,
max : 255 , //should not be changed the 255 is max we should load for each post/item
publish : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-11-14 17:17:44 +09:00
autoValue ( documentOrModifier ) {
const body = documentOrModifier . body || documentOrModifier . $set && documentOrModifier . $set . body ;
if ( body ) {
return Telescope . utils . trimHTML ( Telescope . utils . sanitize ( marked ( body ) ) , 30 ) ;
} else if ( documentOrModifier . $unset && documentOrModifier . $unset . body ) {
return ''
}
}
2016-06-23 15:00:58 +09:00
} ,
/ * *
Count of how many times the post ' s page was viewed
* /
viewCount : {
type : Number ,
optional : true ,
publish : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-06-23 15:00:58 +09:00
defaultValue : 0
} ,
/ * *
Timestamp of the last comment
* /
lastCommentedAt : {
type : Date ,
optional : true ,
publish : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-06-23 15:00:58 +09:00
} ,
/ * *
Count of how many times the post ' s link was clicked
* /
clickCount : {
type : Number ,
optional : true ,
publish : true ,
2016-10-29 14:17:57 +09:00
viewableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
defaultValue : 0
} ,
/ * *
The post ' s status . One of pending ( ` 1 ` ) , approved ( ` 2 ` ) , or deleted ( ` 3 ` )
* /
status : {
type : Number ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canEditAll ,
editableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
control : "select" ,
publish : true ,
2016-11-14 17:17:44 +09:00
autoValue ( documentOrModifier ) {
// provide a default value if this is an insert operation and status field is not set in the document
if ( documentOrModifier && ! documentOrModifier . $set && documentOrModifier . userId ) {
const user = Users . findOne ( documentOrModifier . userId ) ;
2016-06-23 15:00:58 +09:00
return Posts . getDefaultStatus ( user ) ;
2016-11-14 17:17:44 +09:00
}
2016-06-23 15:00:58 +09:00
} ,
2016-10-05 08:43:13 +02:00
form : {
2016-06-23 15:00:58 +09:00
noselect : true ,
2016-08-10 10:40:17 +09:00
options : Telescope . statuses ,
2016-06-23 15:00:58 +09:00
group : 'admin'
} ,
2016-11-22 18:14:51 -05:00
group : formGroups . admin
2016-06-23 15:00:58 +09:00
} ,
2016-07-14 15:54:59 +09:00
/ * *
Whether a post is scheduled in the future or not
* /
isFuture : {
type : Boolean ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-14 15:54:59 +09:00
publish : true
} ,
2016-06-23 15:00:58 +09:00
/ * *
Whether the post is sticky ( pinned to the top of posts lists )
* /
sticky : {
type : Boolean ,
optional : true ,
defaultValue : false ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-07-21 09:40:05 +09:00
insertableIf : canEditAll ,
editableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
control : "checkbox" ,
publish : true ,
2016-11-22 18:14:51 -05:00
group : formGroups . admin
2016-06-23 15:00:58 +09:00
} ,
/ * *
Whether the post is inactive . Inactive posts see their score recalculated less often
* /
inactive : {
type : Boolean ,
optional : true ,
publish : false ,
defaultValue : false
} ,
/ * *
Save info for later spam checking on a post . We will use this for the akismet package
* /
userIP : {
type : String ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
publish : false
} ,
userAgent : {
type : String ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
publish : false
} ,
referrer : {
type : String ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : canEditAll ,
2016-06-23 15:00:58 +09:00
publish : false
} ,
/ * *
The post author ' s name
* /
author : {
type : String ,
optional : true ,
2016-10-29 14:17:57 +09:00
viewableIf : alwaysPublic ,
2016-06-23 15:00:58 +09:00
publish : true ,
2016-11-14 17:17:44 +09:00
autoValue : ( documentOrModifier ) => {
// if userId is changing, change the author name too
const userId = documentOrModifier . userId || documentOrModifier . $set && documentOrModifier . $set . userId
if ( userId ) return Users . getDisplayNameById ( userId )
}
2016-06-23 15:00:58 +09:00
} ,
/ * *
The post author ' s ` _id ` .
* /
userId : {
type : String ,
optional : true ,
2016-11-18 09:28:32 +01:00
control : "select" ,
viewableIf : alwaysPublic ,
insertableIf : canInsert ,
2016-11-18 10:03:01 +01:00
hidden : true ,
2016-11-18 09:28:32 +01:00
resolveAs : 'user: User' ,
// publish: true,
2016-06-23 15:00:58 +09:00
// regEx: SimpleSchema.RegEx.Id,
2016-07-21 09:40:05 +09:00
// insertableIf: canEditAll,
// editableIf: canEditAll,
2016-11-08 14:56:39 +09:00
// form: {
// group: 'admin',
// options: function () {
// return Users.find().map(function (user) {
// return {
// value: user._id,
// label: Users.getDisplayName(user)
// };
// });
// }
// },
// join: {
// joinAs: "user",
// collection: () => Users
// }
2016-06-23 15:00:58 +09:00
}
} ;
2016-11-22 18:14:51 -05:00
export default schema ;
2016-11-08 14:56:39 +09:00
2016-11-22 18:14:51 -05:00
// TODO: to be moved elsewhere / change api
2016-11-08 14:56:39 +09:00
const termsSchema = `
input Terms {
view : String
userId : String
cat : String
date : String
after : String
before : String
enableCache : Boolean
listId : String
query : String # search query
2016-11-23 11:07:48 +09:00
postId : String
2016-11-08 14:56:39 +09:00
}
` ;
Telescope . graphQL . addSchema ( termsSchema ) ;