]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Add new name/terms/description config options
authorChocobozzz <me@florianbigard.com>
Wed, 31 Jan 2018 15:42:40 +0000 (16:42 +0100)
committerChocobozzz <me@florianbigard.com>
Wed, 31 Jan 2018 15:42:40 +0000 (16:42 +0100)
22 files changed:
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.html
client/src/app/+admin/config/edit-custom-config/edit-custom-config.component.ts
client/src/app/shared/forms/form-validators/custom-config.ts
client/src/app/shared/forms/markdown-textarea.component.html [new file with mode: 0644]
client/src/app/shared/forms/markdown-textarea.component.scss [new file with mode: 0644]
client/src/app/shared/forms/markdown-textarea.component.ts [moved from client/src/app/videos/+video-edit/shared/video-description.component.ts with 66% similarity]
client/src/app/shared/shared.module.ts
client/src/app/shared/video/video.service.ts
client/src/app/videos/+video-edit/shared/video-description.component.html [deleted file]
client/src/app/videos/+video-edit/shared/video-description.component.scss [deleted file]
client/src/app/videos/+video-edit/shared/video-edit.component.html
client/src/app/videos/+video-edit/shared/video-edit.module.ts
client/src/app/videos/shared/markdown.service.ts
config/default.yaml
config/production.yaml.example
server/controllers/api/config.ts
server/initializers/checker.ts
server/initializers/constants.ts
server/tests/api/check-params/config.ts
server/tests/api/server/config.ts
server/tests/utils/videos/videos.ts
shared/models/config/custom-config.model.ts

index c568a43b43ffe7a2e325851f6c1a0d6bc54cf6f3..0fe2aa20324ec04ec2f726ce82e8d70205083dde 100644 (file)
@@ -2,6 +2,41 @@
 
 <form role="form" (ngSubmit)="formValidated()" [formGroup]="form">
 
+  <div class="inner-form-title">Instance</div>
+
+  <div class="form-group">
+    <label for="instanceName">Name</label>
+    <input
+        type="text" id="instanceName"
+        formControlName="instanceName" [ngClass]="{ 'input-error': formErrors['instanceName'] }"
+    >
+    <div *ngIf="formErrors.instanceName" class="form-error">
+      {{ formErrors.instanceName }}
+    </div>
+  </div>
+
+  <div class="form-group">
+    <label for="instanceDescription">Description (markdown)</label>
+    <my-markdown-textarea
+        id="instanceDescription" formControlName="instanceDescription" textareaWidth="500px" [previewColumn]="true"
+        [classes]="{ 'input-error': formErrors['instanceDescription'] }"
+    ></my-markdown-textarea>
+    <div *ngIf="formErrors.instanceDescription" class="form-error">
+      {{ formErrors.instanceDescription }}
+    </div>
+  </div>
+
+  <div class="form-group">
+    <label for="instanceTerms">Terms (markdown)</label>
+    <my-markdown-textarea
+        id="instanceTerms" formControlName="instanceTerms" textareaWidth="500px" [previewColumn]="true"
+        [ngClass]="{ 'input-error': formErrors['instanceTerms'] }"
+    ></my-markdown-textarea>
+    <div *ngIf="formErrors.instanceTerms" class="form-error">
+      {{ formErrors.instanceTerms }}
+    </div>
+  </div>
+
   <div class="inner-form-title">Cache</div>
 
   <div class="form-group">
index 1b35227864c87759eed9038a51e14c8aa6c8698e..cd8c926f7b48e0885cddd813162526843abc0838 100644 (file)
@@ -4,7 +4,13 @@ import { Router } from '@angular/router'
 import { ConfigService } from '@app/+admin/config/shared/config.service'
 import { ServerService } from '@app/core/server/server.service'
 import { FormReactive, USER_VIDEO_QUOTA } from '@app/shared'
-import { ADMIN_EMAIL, CACHE_PREVIEWS_SIZE, SIGNUP_LIMIT, TRANSCODING_THREADS } from '@app/shared/forms/form-validators/custom-config'
+import {
+  ADMIN_EMAIL,
+  CACHE_PREVIEWS_SIZE,
+  INSTANCE_NAME,
+  SIGNUP_LIMIT,
+  TRANSCODING_THREADS
+} from '@app/shared/forms/form-validators/custom-config'
 import { NotificationsService } from 'angular2-notifications'
 import { CustomConfig } from '../../../../../../shared/models/config/custom-config.model'
 
@@ -36,6 +42,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
 
   form: FormGroup
   formErrors = {
+    instanceName: '',
+    instanceDescription: '',
+    instanceTerms: '',
     cachePreviewsSize: '',
     signupLimit: '',
     adminEmail: '',
@@ -43,6 +52,7 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
     transcodingThreads: ''
   }
   validationMessages = {
+    instanceName: INSTANCE_NAME.MESSAGES,
     cachePreviewsSize: CACHE_PREVIEWS_SIZE.MESSAGES,
     signupLimit: SIGNUP_LIMIT.MESSAGES,
     adminEmail: ADMIN_EMAIL.MESSAGES,
@@ -65,6 +75,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
 
   buildForm () {
     const formGroupData = {
+      instanceName: [ '', INSTANCE_NAME.VALIDATORS ],
+      instanceDescription: [ '' ],
+      instanceTerms: [ '' ],
       cachePreviewsSize: [ '', CACHE_PREVIEWS_SIZE.VALIDATORS ],
       signupEnabled: [ ],
       signupLimit: [ '', SIGNUP_LIMIT.VALIDATORS ],
@@ -109,6 +122,11 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
 
   formValidated () {
     const data = {
+      instance: {
+        name: this.form.value['instanceName'],
+        description: this.form.value['instanceDescription'],
+        terms: this.form.value['instanceTerms']
+      },
       cache: {
         previews: {
           size: this.form.value['cachePreviewsSize']
@@ -146,6 +164,8 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
           this.serverService.loadConfig()
 
           this.updateForm()
+
+          this.notificationsService.success('Success', 'Configuration updated.')
         },
 
         err => this.notificationsService.error('Error', err.message)
@@ -154,6 +174,9 @@ export class EditCustomConfigComponent extends FormReactive implements OnInit {
 
   private updateForm () {
     const data = {
+      instanceName: this.customConfig.instance.name,
+      instanceDescription: this.customConfig.instance.description,
+      instanceTerms: this.customConfig.instance.terms,
       cachePreviewsSize: this.customConfig.cache.previews.size,
       signupEnabled: this.customConfig.signup.enabled,
       signupLimit: this.customConfig.signup.limit,
index 17ae0e75c7d4d5998f5befea9f38fd16f0640bb3..9e3fa98d826f9b678ebb63f5f2350507202a5b3b 100644 (file)
@@ -1,5 +1,12 @@
 import { Validators } from '@angular/forms'
 
+export const INSTANCE_NAME = {
+  VALIDATORS: [ Validators.required ],
+  MESSAGES: {
+    'required': 'Instance name is required.',
+  }
+}
+
 export const CACHE_PREVIEWS_SIZE = {
   VALIDATORS: [ Validators.required, Validators.min(1), Validators.pattern('[0-9]+') ],
   MESSAGES: {
diff --git a/client/src/app/shared/forms/markdown-textarea.component.html b/client/src/app/shared/forms/markdown-textarea.component.html
new file mode 100644 (file)
index 0000000..d2d4cf9
--- /dev/null
@@ -0,0 +1,12 @@
+<div class="root" [ngStyle]="{ 'flex-direction': flexDirection }">
+  <textarea
+    [(ngModel)]="description" (ngModelChange)="onModelChange()"
+    [ngClass]="classes" [ngStyle]="{ width: textareaWidth, height: textareaHeight, 'margin-right': textareaMarginRight }"
+    id="description" name="description">
+  </textarea>
+
+  <tabset *ngIf="arePreviewsDisplayed()" #staticTabs class="previews">
+    <tab *ngIf="truncate !== undefined" heading="Truncated description preview" [innerHTML]="truncatedDescriptionHTML"></tab>
+    <tab heading="Complete description preview" [innerHTML]="descriptionHTML"></tab>
+  </tabset>
+</div>
diff --git a/client/src/app/shared/forms/markdown-textarea.component.scss b/client/src/app/shared/forms/markdown-textarea.component.scss
new file mode 100644 (file)
index 0000000..82aff54
--- /dev/null
@@ -0,0 +1,27 @@
+@import '_variables';
+@import '_mixins';
+
+.root {
+  display: flex;
+  
+  textarea {
+    @include peertube-textarea(100%, 150px);
+
+    margin-bottom: 15px;
+  }
+
+  /deep/ {
+    .nav-link {
+      display: flex !important;
+      align-items: center;
+      height: 30px !important;
+      padding: 0 15px !important;
+    }
+
+    .tab-content {
+      min-height: 75px;
+      padding: 15px;
+      font-size: 15px;
+    }
+  }
+}
similarity index 66%
rename from client/src/app/videos/+video-edit/shared/video-description.component.ts
rename to client/src/app/shared/forms/markdown-textarea.component.ts
index eba345412112e17711aaedb7f89664550dcb1599..20f13b28c48242e26a77d3e3914234f6814f8b79 100644 (file)
@@ -3,25 +3,33 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'
 import 'rxjs/add/operator/debounceTime'
 import 'rxjs/add/operator/distinctUntilChanged'
 import { isInMobileView } from '@app/shared/misc/utils'
+import { MarkdownService } from '@app/videos/shared'
 import { Subject } from 'rxjs/Subject'
-import { MarkdownService } from '../../shared'
 import truncate from 'lodash-es/truncate'
 
 @Component({
-  selector: 'my-video-description',
-  templateUrl: './video-description.component.html',
-  styleUrls: [ './video-description.component.scss' ],
+  selector: 'my-markdown-textarea',
+  templateUrl: './markdown-textarea.component.html',
+  styleUrls: [ './markdown-textarea.component.scss' ],
   providers: [
     {
       provide: NG_VALUE_ACCESSOR,
-      useExisting: forwardRef(() => VideoDescriptionComponent),
+      useExisting: forwardRef(() => MarkdownTextareaComponent),
       multi: true
     }
   ]
 })
 
-export class VideoDescriptionComponent implements ControlValueAccessor, OnInit {
+export class MarkdownTextareaComponent implements ControlValueAccessor, OnInit {
   @Input() description = ''
+  @Input() classes: string[] = []
+  @Input() textareaWidth = '100%'
+  @Input() textareaHeight = '150px'
+  @Input() previewColumn = false
+  @Input() truncate: number
+
+  textareaMarginRight = '0'
+  flexDirection = 'column'
   truncatedDescriptionHTML = ''
   descriptionHTML = ''
 
@@ -36,6 +44,11 @@ export class VideoDescriptionComponent implements ControlValueAccessor, OnInit {
       .subscribe(() => this.updateDescriptionPreviews())
 
     this.descriptionChanged.next(this.description)
+
+    if (this.previewColumn) {
+      this.flexDirection = 'row'
+      this.textareaMarginRight = '15px'
+    }
   }
 
   propagateChange = (_: any) => { /* empty */ }
@@ -65,9 +78,9 @@ export class VideoDescriptionComponent implements ControlValueAccessor, OnInit {
   }
 
   private updateDescriptionPreviews () {
-    if (!this.description) return
+    if (this.description === null || this.description === undefined) return
 
-    this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: 250 }))
+    this.truncatedDescriptionHTML = this.markdownService.markdownToHTML(truncate(this.description, { length: this.truncate }))
     this.descriptionHTML = this.markdownService.markdownToHTML(this.description)
   }
 }
index a5c56cb461e789b3b8aacc49a66756f91e9aa0e7..d8f98bdf6c87e30991a9a66fb0a9a84dd8535e52 100644 (file)
@@ -3,10 +3,13 @@ import { HttpClientModule } from '@angular/common/http'
 import { NgModule } from '@angular/core'
 import { FormsModule, ReactiveFormsModule } from '@angular/forms'
 import { RouterModule } from '@angular/router'
+import { MarkdownTextareaComponent } from '@app/shared/forms/markdown-textarea.component'
+import { MarkdownService } from '@app/videos/shared'
 import { LoadingBarHttpClientModule } from '@ngx-loading-bar/http-client'
 
 import { BsDropdownModule } from 'ngx-bootstrap/dropdown'
 import { ModalModule } from 'ngx-bootstrap/modal'
+import { TabsModule } from 'ngx-bootstrap/tabs'
 import { InfiniteScrollModule } from 'ngx-infinite-scroll'
 import { BytesPipe, KeysPipe, NgPipesModule } from 'ngx-pipes'
 import { SharedModule as PrimeSharedModule } from 'primeng/components/common/shared'
@@ -40,7 +43,8 @@ import { VideoService } from './video/video.service'
 
     PrimeSharedModule,
     InfiniteScrollModule,
-    NgPipesModule
+    NgPipesModule,
+    TabsModule.forRoot()
   ],
 
   declarations: [
@@ -50,7 +54,8 @@ import { VideoService } from './video/video.service'
     DeleteButtonComponent,
     EditButtonComponent,
     NumberFormatterPipe,
-    FromNowPipe
+    FromNowPipe,
+    MarkdownTextareaComponent
   ],
 
   exports: [
@@ -74,6 +79,7 @@ import { VideoService } from './video/video.service'
     VideoMiniatureComponent,
     DeleteButtonComponent,
     EditButtonComponent,
+    MarkdownTextareaComponent,
 
     NumberFormatterPipe,
     FromNowPipe
@@ -86,7 +92,8 @@ import { VideoService } from './video/video.service'
     VideoAbuseService,
     VideoBlacklistService,
     UserService,
-    VideoService
+    VideoService,
+    MarkdownService
   ]
 })
 export class SharedModule { }
index 50761ca0c106c71cb2c8f89de8adc1951f42837f..d4f5e258f155ff2ae3b697bf21d617e6e9ecbc6c 100644 (file)
@@ -42,10 +42,10 @@ export class VideoService {
   }
 
   updateVideo (video: VideoEdit) {
-    const language = video.language || undefined
-    const licence = video.licence || undefined
-    const category = video.category || undefined
-    const description = video.description || undefined
+    const language = video.language || null
+    const licence = video.licence || null
+    const category = video.category || null
+    const description = video.description || null
 
     const body: VideoUpdate = {
       name: video.name,
diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.html b/client/src/app/videos/+video-edit/shared/video-description.component.html
deleted file mode 100644 (file)
index 989292c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-<textarea
-  [(ngModel)]="description" (ngModelChange)="onModelChange()"
-  id="description" name="description">
-</textarea>
-
-<tabset *ngIf="arePreviewsDisplayed()" #staticTabs class="previews">
-  <tab heading="Truncated description preview" [innerHTML]="truncatedDescriptionHTML"></tab>
-  <tab heading="Complete description preview" [innerHTML]="descriptionHTML"></tab>
-</tabset>
diff --git a/client/src/app/videos/+video-edit/shared/video-description.component.scss b/client/src/app/videos/+video-edit/shared/video-description.component.scss
deleted file mode 100644 (file)
index 2c731be..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-@import '_variables';
-@import '_mixins';
-
-textarea {
-  @include peertube-textarea(100%, 150px);
-
-  margin-bottom: 15px;
-}
-
-/deep/ {
-  .nav-link {
-    display: flex !important;
-    align-items: center;
-    height: 30px !important;
-    padding: 0 15px !important;
-  }
-
-  .tab-content {
-    min-height: 75px;
-    padding: 15px;
-    font-size: 15px;
-  }
-}
-
index 80377933ecadc712393a5d3a8772d10a2afe9532..d031825bdb9ad391d0dfe601c3ec3b3447dc998b 100644 (file)
     <div class="form-group">
       <label class="label-tags">Tags</label> <span>(press Enter to add)</span>
       <tag-input
-          [ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
-          formControlName="tags" maxItems="5" modelAsStrings="true"
+        [ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
+        formControlName="tags" maxItems="5" modelAsStrings="true"
       ></tag-input>
     </div>
 
     <div class="form-group">
       <label for="description">Description</label>
-      <my-video-description formControlName="description"></my-video-description>
+      <my-markdown-textarea truncate="250" formControlName="description"></my-markdown-textarea>
 
       <div *ngIf="formErrors.description" class="form-error">
         {{ formErrors.description }}
index ce106d82f5bcb19e13bef04a74093753ec2bf3a4..098a71ae6d93e7180cbb58d78023a91c8dd9ba65 100644 (file)
@@ -1,23 +1,17 @@
 import { NgModule } from '@angular/core'
-
-import { TagInputModule } from 'ngx-chips'
 import { TabsModule } from 'ngx-bootstrap/tabs'
-
-import { MarkdownService } from '../../shared'
+import { TagInputModule } from 'ngx-chips'
 import { SharedModule } from '../../../shared'
-import { VideoDescriptionComponent } from './video-description.component'
 import { VideoEditComponent } from './video-edit.component'
 
 @NgModule({
   imports: [
     TagInputModule,
-    TabsModule.forRoot(),
 
     SharedModule
   ],
 
   declarations: [
-    VideoDescriptionComponent,
     VideoEditComponent
   ],
 
@@ -25,12 +19,9 @@ import { VideoEditComponent } from './video-edit.component'
     TagInputModule,
     TabsModule,
 
-    VideoDescriptionComponent,
     VideoEditComponent
   ],
 
-  providers: [
-    MarkdownService
-  ]
+  providers: []
 })
 export class VideoEditModule { }
index 82745f0c68283ab2e7f7385091b4f22e1713f3c8..fd0330f9bc8f5d0c34ba92050df1efb56e7e5973 100644 (file)
@@ -14,6 +14,17 @@ export class MarkdownService {
       .enable('link')
       .enable('newline')
 
+    this.setTargetToLinks()
+  }
+
+  markdownToHTML (markdown: string) {
+    const html = this.markdownIt.render(markdown)
+
+    // Avoid linkify truncated links
+    return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...')
+  }
+
+  private setTargetToLinks () {
     // Snippet from markdown-it documentation: https://github.com/markdown-it/markdown-it/blob/master/docs/architecture.md#renderer
     const defaultRender = this.markdownIt.renderer.rules.link_open || function (tokens, idx, options, env, self) {
       return self.renderToken(tokens, idx, options)
@@ -33,11 +44,4 @@ export class MarkdownService {
       return defaultRender(tokens, idx, options, env, self)
     }
   }
-
-  markdownToHTML (markdown: string) {
-    const html = this.markdownIt.render(markdown)
-
-    // Avoid linkify truncated links
-    return html.replace(/<a[^>]+>([^<]+)<\/a>\s*...(<\/p>)?$/mi, '$1...')
-  }
 }
index 691c9e00b3d59647d7e47b6b335e2bd1aaecfe6b..6c73c5fea15002dba86c071c70235affda836143 100644 (file)
@@ -69,3 +69,8 @@ transcoding:
     480p: true
     720p: true
     1080p: true
+
+instance:
+  name: 'PeerTube'
+  description: '' # Support markdown
+  terms: '' # Support markdown
index 04354b75d5c072d9c79f0533f18691c54ab3b499..e476bbcfa03e0da4d579415f902092a105c84bae 100644 (file)
@@ -69,3 +69,8 @@ transcoding:
     480p: true
     720p: true
     1080p: true
+
+instance:
+  name: 'PeerTube'
+  description: '' # Support markdown
+  terms: '' # Support markdown
index bc804d9ba9c2bb385bac5ece84e37def482fb506..e4cb028207733abef7e0fe09ae9bed83e5331880 100644 (file)
@@ -105,6 +105,11 @@ export {
 
 function customConfig (): CustomConfig {
   return {
+    instance: {
+      name: CONFIG.INSTANCE.NAME,
+      description: CONFIG.INSTANCE.DESCRIPTION,
+      terms: CONFIG.INSTANCE.TERMS
+    },
     cache: {
       previews: {
         size: CONFIG.CACHE.PREVIEWS.SIZE
index d550fd23f869d3bfbc7b3cfa021ea604bc5da032..e5cc1b7be202544048ab5a4222174f79583089f7 100644 (file)
@@ -23,7 +23,8 @@ function checkMissedConfig () {
     'database.hostname', 'database.port', 'database.suffix', 'database.username', 'database.password',
     'storage.videos', 'storage.logs', 'storage.thumbnails', 'storage.previews', 'storage.torrents', 'storage.cache', 'log.level',
     'cache.previews.size', 'admin.email', 'signup.enabled', 'signup.limit', 'transcoding.enabled', 'transcoding.threads',
-    'user.video_quota', 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address'
+    'user.video_quota', 'smtp.hostname', 'smtp.port', 'smtp.username', 'smtp.password', 'smtp.tls', 'smtp.from_address',
+    'instance.name', 'instance.description', 'instance.terms'
   ]
   const miss: string[] = []
 
index e7b1656e261192ca796b9967f1c7b79722f299bd..e531c4c394fd7377dcbbef9a6dde98906e72ad2f 100644 (file)
@@ -154,6 +154,11 @@ const CONFIG = {
     PREVIEWS: {
       get SIZE () { return config.get<number>('cache.previews.size') }
     }
+  },
+  INSTANCE: {
+    get NAME () { return config.get<string>('instance.name') },
+    get DESCRIPTION () { return config.get<string>('instance.description') },
+    get TERMS () { return config.get<string>('instance.terms') }
   }
 }
 
index a2a40470230238e200b0749f43537f763172b7d5..efc1e4e09bf0499f9319ba5c80a113b0562403fa 100644 (file)
@@ -14,6 +14,11 @@ describe('Test config API validators', function () {
   let server: ServerInfo
   let userAccessToken: string
   const updateParams: CustomConfig = {
+    instance: {
+      name: 'PeerTube updated',
+      description: 'my super description',
+      terms: 'my super terms'
+    },
     cache: {
       previews: {
         size: 2
index a1f8212bb07a97cd47f4342eb475c2218ca8007a..f83e21e82c234404f5928021e263aeafefba1beb 100644 (file)
@@ -49,6 +49,9 @@ describe('Test config', function () {
     const res = await getCustomConfig(server.url, server.accessToken)
     const data = res.body
 
+    expect(data.instance.name).to.equal('PeerTube')
+    expect(data.instance.description).to.be.empty
+    expect(data.instance.terms).to.be.empty
     expect(data.cache.previews.size).to.equal(1)
     expect(data.signup.enabled).to.be.true
     expect(data.signup.limit).to.equal(4)
@@ -65,6 +68,11 @@ describe('Test config', function () {
 
   it('Should update the customized configuration', async function () {
     const newCustomConfig = {
+      instance: {
+        name: 'PeerTube updated',
+        description: 'my super description',
+        terms: 'my super terms'
+      },
       cache: {
         previews: {
           size: 2
@@ -97,7 +105,9 @@ describe('Test config', function () {
     const res = await getCustomConfig(server.url, server.accessToken)
     const data = res.body
 
-    expect(data.cache.previews.size).to.equal(2)
+    expect(data.instance.name).to.equal('PeerTube updated')
+    expect(data.instance.description).to.equal('my super description')
+    expect(data.instance.terms).to.equal('my super terms')
     expect(data.signup.enabled).to.be.false
     expect(data.signup.limit).to.equal(5)
     expect(data.admin.email).to.equal('superadmin1@example.com')
index 860f04fd80e30d58e13b18a5bdc2277e63aeff8f..0b28edd48f2bf5946a83cb56ed66d8e4b6bfe2b2 100644 (file)
@@ -373,7 +373,7 @@ async function completeVideoCheck (
   expect(dateIsValid(video.createdAt)).to.be.true
   expect(dateIsValid(video.updatedAt)).to.be.true
 
-  const res = await getVideo(url, video.id)
+  const res = await getVideo(url, video.uuid)
   const videoDetails = res.body
 
   expect(videoDetails.files).to.have.lengthOf(attributes.files.length)
index 73b5b6a72469f1f550511f1a408f31f38ac14278..6ef0fc5a20795a9b0914010a7eb1713887658368 100644 (file)
@@ -1,4 +1,10 @@
 export interface CustomConfig {
+  instance: {
+    name: string
+    description: string
+    terms: string
+  }
+
   cache: {
     previews: {
       size: number