]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/activitypub/context.ts
Refactor AP context builder
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / context.ts
index 71f08da80052953c1a0b1fd74be1cd1c107c895f..3bc40e2aa2749114f9786d0b40a76948776bfd03 100644 (file)
 import { ContextType } from '@shared/models'
 
-function getContextData (type: ContextType) {
-  const context: any[] = [
-    'https://www.w3.org/ns/activitystreams',
-    'https://w3id.org/security/v1',
-    {
-      RsaSignature2017: 'https://w3id.org/security#RsaSignature2017'
+function activityPubContextify <T> (data: T, type: ContextType) {
+  return { ...getContextData(type), ...data }
+}
+
+// ---------------------------------------------------------------------------
+
+export {
+  getContextData,
+  activityPubContextify
+}
+
+// ---------------------------------------------------------------------------
+
+type ContextValue = { [ id: string ]: (string | { '@type': string, '@id': string }) }
+
+const contextStore = {
+  Video: buildContext({
+    Hashtag: 'as:Hashtag',
+    uuid: 'sc:identifier',
+    category: 'sc:category',
+    licence: 'sc:license',
+    subtitleLanguage: 'sc:subtitleLanguage',
+    sensitive: 'as:sensitive',
+    language: 'sc:inLanguage',
+
+    // TODO: remove in a few versions, introduced in 4.2
+    icons: 'as:icon',
+
+    isLiveBroadcast: 'sc:isLiveBroadcast',
+    liveSaveReplay: {
+      '@type': 'sc:Boolean',
+      '@id': 'pt:liveSaveReplay'
+    },
+    permanentLive: {
+      '@type': 'sc:Boolean',
+      '@id': 'pt:permanentLive'
+    },
+    latencyMode: {
+      '@type': 'sc:Number',
+      '@id': 'pt:latencyMode'
+    },
+
+    Infohash: 'pt:Infohash',
+
+    originallyPublishedAt: 'sc:datePublished',
+    views: {
+      '@type': 'sc:Number',
+      '@id': 'pt:views'
+    },
+    state: {
+      '@type': 'sc:Number',
+      '@id': 'pt:state'
+    },
+    size: {
+      '@type': 'sc:Number',
+      '@id': 'pt:size'
+    },
+    fps: {
+      '@type': 'sc:Number',
+      '@id': 'pt:fps'
+    },
+    commentsEnabled: {
+      '@type': 'sc:Boolean',
+      '@id': 'pt:commentsEnabled'
+    },
+    downloadEnabled: {
+      '@type': 'sc:Boolean',
+      '@id': 'pt:downloadEnabled'
+    },
+    waitTranscoding: {
+      '@type': 'sc:Boolean',
+      '@id': 'pt:waitTranscoding'
+    },
+    support: {
+      '@type': 'sc:Text',
+      '@id': 'pt:support'
+    },
+    likes: {
+      '@id': 'as:likes',
+      '@type': '@id'
+    },
+    dislikes: {
+      '@id': 'as:dislikes',
+      '@type': '@id'
+    },
+    shares: {
+      '@id': 'as:shares',
+      '@type': '@id'
+    },
+    comments: {
+      '@id': 'as:comments',
+      '@type': '@id'
     }
-  ]
+  }),
 
-  if (type !== 'View' && type !== 'Announce') {
-    const additional = {
-      pt: 'https://joinpeertube.org/ns#',
-      sc: 'http://schema.org#'
+  Playlist: buildContext({
+    Playlist: 'pt:Playlist',
+    PlaylistElement: 'pt:PlaylistElement',
+    position: {
+      '@type': 'sc:Number',
+      '@id': 'pt:position'
+    },
+    startTimestamp: {
+      '@type': 'sc:Number',
+      '@id': 'pt:startTimestamp'
+    },
+    stopTimestamp: {
+      '@type': 'sc:Number',
+      '@id': 'pt:stopTimestamp'
     }
+  }),
+
+  CacheFile: buildContext({
+    expires: 'sc:expires',
+    CacheFile: 'pt:CacheFile'
+  }),
 
-    if (type === 'CacheFile') {
-      Object.assign(additional, {
-        expires: 'sc:expires',
-        CacheFile: 'pt:CacheFile'
-      })
-    } else {
-      Object.assign(additional, {
-        Hashtag: 'as:Hashtag',
-        uuid: 'sc:identifier',
-        category: 'sc:category',
-        licence: 'sc:license',
-        subtitleLanguage: 'sc:subtitleLanguage',
-        sensitive: 'as:sensitive',
-        language: 'sc:inLanguage',
-
-        // TODO: remove in a few versions, introduced in 4.2
-        icons: 'as:icon',
-
-        isLiveBroadcast: 'sc:isLiveBroadcast',
-        liveSaveReplay: {
-          '@type': 'sc:Boolean',
-          '@id': 'pt:liveSaveReplay'
-        },
-        permanentLive: {
-          '@type': 'sc:Boolean',
-          '@id': 'pt:permanentLive'
-        },
-        latencyMode: {
-          '@type': 'sc:Number',
-          '@id': 'pt:latencyMode'
-        },
-
-        Infohash: 'pt:Infohash',
-        Playlist: 'pt:Playlist',
-        PlaylistElement: 'pt:PlaylistElement',
-
-        originallyPublishedAt: 'sc:datePublished',
-        views: {
-          '@type': 'sc:Number',
-          '@id': 'pt:views'
-        },
-        state: {
-          '@type': 'sc:Number',
-          '@id': 'pt:state'
-        },
-        size: {
-          '@type': 'sc:Number',
-          '@id': 'pt:size'
-        },
-        fps: {
-          '@type': 'sc:Number',
-          '@id': 'pt:fps'
-        },
-        startTimestamp: {
-          '@type': 'sc:Number',
-          '@id': 'pt:startTimestamp'
-        },
-        stopTimestamp: {
-          '@type': 'sc:Number',
-          '@id': 'pt:stopTimestamp'
-        },
-        position: {
-          '@type': 'sc:Number',
-          '@id': 'pt:position'
-        },
-        commentsEnabled: {
-          '@type': 'sc:Boolean',
-          '@id': 'pt:commentsEnabled'
-        },
-        downloadEnabled: {
-          '@type': 'sc:Boolean',
-          '@id': 'pt:downloadEnabled'
-        },
-        waitTranscoding: {
-          '@type': 'sc:Boolean',
-          '@id': 'pt:waitTranscoding'
-        },
-        support: {
-          '@type': 'sc:Text',
-          '@id': 'pt:support'
-        },
-        likes: {
-          '@id': 'as:likes',
-          '@type': '@id'
-        },
-        dislikes: {
-          '@id': 'as:dislikes',
-          '@type': '@id'
-        },
-        playlists: {
-          '@id': 'pt:playlists',
-          '@type': '@id'
-        },
-        shares: {
-          '@id': 'as:shares',
-          '@type': '@id'
-        },
-        comments: {
-          '@id': 'as:comments',
-          '@type': '@id'
-        }
-      })
+  Flag: buildContext({
+    Hashtag: 'as:Hashtag'
+  }),
+
+  Actor: buildContext({
+    playlists: {
+      '@id': 'pt:playlists',
+      '@type': '@id'
     }
+  }),
 
-    context.push(additional)
-  }
+  Follow: buildContext(),
+  Reject: buildContext(),
+  Accept: buildContext(),
+  View: buildContext(),
+  Announce: buildContext(),
+  Comment: buildContext(),
+  Delete: buildContext(),
+  Rate: buildContext()
+}
 
+function getContextData (type: ContextType) {
   return {
-    '@context': context
+    '@context': contextStore[type]
   }
 }
 
-function activityPubContextify <T> (data: T, type: ContextType = 'All') {
-  return Object.assign({}, data, getContextData(type))
-}
+function buildContext (contextValue?: ContextValue) {
+  const baseContext = [
+    'https://www.w3.org/ns/activitystreams',
+    'https://w3id.org/security/v1',
+    {
+      RsaSignature2017: 'https://w3id.org/security#RsaSignature2017'
+    }
+  ]
 
-export {
-  getContextData,
-  activityPubContextify
+  if (!contextValue) return baseContext
+
+  return [
+    ...baseContext,
+
+    {
+      pt: 'https://joinpeertube.org/ns#',
+      sc: 'http://schema.org#',
+
+      ...contextValue
+    }
+  ]
 }