Browse Source

Merge branch 'content_cli_reworkings' into cli_channels

iorveth 4 years ago
parent
commit
72e769f175
35 changed files with 1610 additions and 644 deletions
  1. 2 2
      Cargo.lock
  2. 8 11
      cli/src/Api.ts
  3. 3 23
      cli/src/base/ContentDirectoryCommandBase.ts
  4. 12 13
      cli/src/helpers/InputOutput.ts
  5. 1 1
      cli/src/helpers/JsonSchemaPrompt.ts
  6. 1 1
      content-metadata-protobuf/compiled/proto/Channel_pb.d.ts
  7. 211 141
      content-metadata-protobuf/compiled/proto/Channel_pb.js
  8. 89 37
      content-metadata-protobuf/compiled/proto/Person_pb.js
  9. 47 20
      content-metadata-protobuf/compiled/proto/Playlist_pb.js
  10. 154 76
      content-metadata-protobuf/compiled/proto/Series_pb.js
  11. 360 178
      content-metadata-protobuf/compiled/proto/Video_pb.js
  12. 0 2
      content-metadata-protobuf/proto/Channel.proto
  13. 1 1
      node/Cargo.toml
  14. 4 4
      pioneer/packages/joy-proposals/src/validationSchema.ts
  15. 0 3
      runtime-modules/content/src/errors.rs
  16. 10 7
      runtime-modules/content/src/lib.rs
  17. 17 17
      runtime-modules/content/src/permissions/mod.rs
  18. 224 26
      runtime-modules/content/src/tests/channels.rs
  19. 131 0
      runtime-modules/content/src/tests/curators.rs
  20. 12 3
      runtime-modules/content/src/tests/mock.rs
  21. 2 0
      runtime-modules/content/src/tests/mod.rs
  22. 247 0
      runtime-modules/content/src/tests/videos.rs
  23. 2 2
      runtime-modules/proposals/codex/src/lib.rs
  24. 1 1
      runtime-modules/proposals/codex/src/proposal_types/mod.rs
  25. 3 3
      runtime-modules/proposals/codex/src/proposal_types/parameters.rs
  26. 8 8
      runtime-modules/proposals/codex/src/tests/mod.rs
  27. 9 4
      runtime-modules/storage/src/data_directory.rs
  28. 1 1
      runtime/Cargo.toml
  29. 1 1
      runtime/src/constants.rs
  30. 2 2
      runtime/src/lib.rs
  31. 4 4
      runtime/src/tests/proposals_integration/mod.rs
  32. 4 0
      testnets/joy-testnet-4.json
  33. 16 12
      tests/network-tests/src/fixtures/proposalsModule.ts
  34. 3 4
      tests/network-tests/src/flows/proposals/validatorCountProposal.ts
  35. 20 36
      yarn.lock

+ 2 - 2
Cargo.lock

@@ -1993,7 +1993,7 @@ dependencies = [
 
 [[package]]
 name = "joystream-node"
-version = "3.7.1"
+version = "3.7.2"
 dependencies = [
  "frame-benchmarking",
  "frame-benchmarking-cli",
@@ -2053,7 +2053,7 @@ dependencies = [
 
 [[package]]
 name = "joystream-node-runtime"
-version = "7.14.0"
+version = "7.15.0"
 dependencies = [
  "frame-benchmarking",
  "frame-executive",

+ 8 - 11
cli/src/Api.ts

@@ -48,9 +48,9 @@ import { RewardRelationship, RewardRelationshipId } from '@joystream/types/recur
 import { Stake, StakeId } from '@joystream/types/stake'
 
 import { InputValidationLengthConstraint, ChannelId, Url } from '@joystream/types/common'
-import {  CuratorGroup, CuratorGroupId, Channel, Video, VideoId } from '@joystream/types/content'
-import { DataObject } from '@joystream/types/storage'
-import { ServiceProviderRecord,  } from '@joystream/types/discovery'
+import { CuratorGroup, CuratorGroupId, Channel, Video, VideoId } from '@joystream/types/content'
+import { ContentId, DataObject } from '@joystream/types/storage'
+import { ServiceProviderRecord } from '@joystream/types/discovery'
 import _ from 'lodash'
 
 export const DEFAULT_API_URI = 'ws://localhost:9944/'
@@ -67,7 +67,6 @@ export const apiModuleByGroup: { [key in WorkingGroups]: string } = {
 // Api wrapper for handling most common api calls and allowing easy API implementation switch in the future
 export default class Api {
   private _api: ApiPromise
-  private _cdClassesCache: [ChannelId, Channel][] | null = null
 
   private constructor(originalApi: ApiPromise) {
     this._api = originalApi
@@ -495,10 +494,8 @@ export default class Api {
   }
 
   // Content directory
-  async availableChannels(useCache = true): Promise<[ChannelId, Channel][]> {
-    return useCache && this._cdClassesCache
-      ? this._cdClassesCache
-      : (this._cdClassesCache = await this.entriesByIds<ChannelId, Channel>(this._api.query.content.channelById))
+  async availableChannels(): Promise<[ChannelId, Channel][]> {
+    return await this.entriesByIds<ChannelId, Channel>(this._api.query.content.channelById)
   }
 
   availableCuratorGroups(): Promise<[CuratorGroupId, CuratorGroup][]> {
@@ -529,9 +526,9 @@ export default class Api {
     return exists ? await this._api.query.content.videoById<Video>(videoId) : null
   }
 
-  async dataByContentId(contentId: number): Promise<DataObject | null> {
-    const dataObject = await this._api.query.dataDirectory.dataByContentId<Option<DataObject>>(contentId)
-    return dataObject.unwrapOr(null)
+  async dataByContentId(contentId: ContentId): Promise<DataObject | null> {
+    const dataObject = await this._api.query.dataDirectory.dataByContentId<DataObject>(contentId)
+    return dataObject.isEmpty ? null : dataObject
   }
 
   async ipnsIdentity(storageProviderId: number): Promise<string | null> {

+ 3 - 23
cli/src/base/ContentDirectoryCommandBase.ts

@@ -1,12 +1,6 @@
 import ExitCodes from '../ExitCodes'
 import { WorkingGroups } from '../Types'
-import {
-  Channel,
-  CuratorGroup,
-  CuratorGroupId,
-  ContentActor,
-} from '@joystream/types/content'
-import { ChannelId } from '@joystream/types/common'
+import { Channel, CuratorGroup, CuratorGroupId, ContentActor } from '@joystream/types/content'
 import { Worker } from '@joystream/types/working-group'
 import { CLIError } from '@oclif/errors'
 import _ from 'lodash'
@@ -50,17 +44,13 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
     const availableGroupIds = groups
       .filter(
         ([_, group]) =>
-          group.active.valueOf() &&
-          group.curators.toArray().some((curatorId) => curatorId.eq(curator.workerId))
+          group.active.valueOf() && group.curators.toArray().some((curatorId) => curatorId.eq(curator.workerId))
       )
       .map(([id]) => id)
 
     let groupId: number
     if (!availableGroupIds.length) {
-      this.error(
-        'You do not have the curator access!',
-        { exit: ExitCodes.AccessDenied }
-      )
+      this.error('You do not have the curator access!', { exit: ExitCodes.AccessDenied })
     } else if (availableGroupIds.length === 1) {
       groupId = availableGroupIds[0].toNumber()
     } else {
@@ -83,16 +73,6 @@ export default abstract class ContentDirectoryCommandBase extends RolesCommandBa
     return selectedClass
   }
 
-  async channelEntryById(channelId: string): Promise<[ChannelId, Channel]> {
-    const channels = await this.getApi().availableChannels()
-    const foundClass = channels.find(([id, c]) => id.toString() === channelId)
-    if (!foundClass) {
-      this.error(`Class id not found by class name or id: "${channelId}"!`)
-    }
-
-    return foundClass
-  }
-
   private async curatorGroupChoices(ids?: CuratorGroupId[]) {
     const groups = await this.getApi().availableCuratorGroups()
     return groups

+ 12 - 13
cli/src/helpers/InputOutput.ts

@@ -5,7 +5,6 @@ import fs from 'fs'
 import path from 'path'
 import chalk from 'chalk'
 
-
 export const IOFlags = {
   input: flags.string({
     char: 'i',
@@ -21,19 +20,19 @@ export const IOFlags = {
 }
 
 export async function getInputJson<T>(inputPath: string): Promise<T> {
-    let content, jsonObj
-    try {
-      content = fs.readFileSync(inputPath).toString()
-    } catch (e) {
-      throw new CLIError(`Cannot access the input file at: ${inputPath}`, { exit: ExitCodes.FsOperationFailed })
-    }
-    try {
-      jsonObj = JSON.parse(content)
-    } catch (e) {
-      throw new CLIError(`JSON parsing failed for file: ${inputPath}`, { exit: ExitCodes.InvalidInput })
-    }
+  let content, jsonObj
+  try {
+    content = fs.readFileSync(inputPath).toString()
+  } catch (e) {
+    throw new CLIError(`Cannot access the input file at: ${inputPath}`, { exit: ExitCodes.FsOperationFailed })
+  }
+  try {
+    jsonObj = JSON.parse(content)
+  } catch (e) {
+    throw new CLIError(`JSON parsing failed for file: ${inputPath}`, { exit: ExitCodes.InvalidInput })
+  }
 
-    return jsonObj as T
+  return jsonObj as T
 }
 
 export function saveOutputJson(outputPath: string | undefined, fileName: string, data: any): void {

+ 1 - 1
cli/src/helpers/JsonSchemaPrompt.ts

@@ -23,7 +23,7 @@ export class JsonSchemaPrompter<JsonResult> {
     schema: JSONSchema,
     defaults?: Partial<JsonResult>,
     customPrompts?: JsonSchemaCustomPrompts,
-    schemaPath: string = ""
+    schemaPath: string = ''
   ) {
     this.customPropmpts = customPrompts
     this.schema = schema

+ 1 - 1
content-metadata-protobuf/compiled/proto/Channel_pb.d.ts

@@ -1,4 +1,4 @@
-// package: muthu.other
+// package: 
 // file: proto/Channel.proto
 
 import * as jspb from "google-protobuf";

+ 211 - 141
content-metadata-protobuf/compiled/proto/Channel_pb.js

@@ -1,19 +1,43 @@
+// source: proto/Channel.proto
 /**
  * @fileoverview
  * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
  * @suppress {messageConventions} JS Compiler reports an error if a variable or
  *     field starts with 'MSG_' and isn't a translatable message.
  * @public
  */
 // GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
 
 var jspb = require('google-protobuf');
 var goog = jspb;
 var global = Function('return this')();
 
-goog.exportSymbol('proto.muthu.other.ChannelCategoryMetadata', null, global);
-goog.exportSymbol('proto.muthu.other.ChannelMetadata', null, global);
-
+goog.exportSymbol('proto.ChannelCategoryMetadata', null, global);
+goog.exportSymbol('proto.ChannelMetadata', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.ChannelMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.ChannelMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.ChannelMetadata.displayName = 'proto.ChannelMetadata';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -24,49 +48,56 @@ goog.exportSymbol('proto.muthu.other.ChannelMetadata', null, global);
  * @extends {jspb.Message}
  * @constructor
  */
-proto.muthu.other.ChannelMetadata = function(opt_data) {
+proto.ChannelCategoryMetadata = function(opt_data) {
   jspb.Message.initialize(this, opt_data, 0, -1, null, null);
 };
-goog.inherits(proto.muthu.other.ChannelMetadata, jspb.Message);
+goog.inherits(proto.ChannelCategoryMetadata, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
-  proto.muthu.other.ChannelMetadata.displayName = 'proto.muthu.other.ChannelMetadata';
+  /**
+   * @public
+   * @override
+   */
+  proto.ChannelCategoryMetadata.displayName = 'proto.ChannelCategoryMetadata';
 }
 
 
+
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.muthu.other.ChannelMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.muthu.other.ChannelMetadata.toObject(opt_includeInstance, this);
+proto.ChannelMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.ChannelMetadata.toObject(opt_includeInstance, this);
 };
 
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.muthu.other.ChannelMetadata} msg The msg instance to transform.
+ * @param {!proto.ChannelMetadata} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.muthu.other.ChannelMetadata.toObject = function(includeInstance, msg) {
+proto.ChannelMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    title: jspb.Message.getField(msg, 1),
-    description: jspb.Message.getField(msg, 2),
-    isPublic: jspb.Message.getField(msg, 3),
-    language: jspb.Message.getField(msg, 4),
-    coverPhoto: jspb.Message.getField(msg, 5),
-    avatarPhoto: jspb.Message.getField(msg, 6),
-    category: jspb.Message.getField(msg, 7)
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    isPublic: (f = jspb.Message.getBooleanField(msg, 3)) == null ? undefined : f,
+    language: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    avatarPhoto: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
+    category: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -80,23 +111,23 @@ proto.muthu.other.ChannelMetadata.toObject = function(includeInstance, msg) {
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.muthu.other.ChannelMetadata}
+ * @return {!proto.ChannelMetadata}
  */
-proto.muthu.other.ChannelMetadata.deserializeBinary = function(bytes) {
+proto.ChannelMetadata.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.muthu.other.ChannelMetadata;
-  return proto.muthu.other.ChannelMetadata.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.ChannelMetadata;
+  return proto.ChannelMetadata.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.muthu.other.ChannelMetadata} msg The message object to deserialize into.
+ * @param {!proto.ChannelMetadata} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.muthu.other.ChannelMetadata}
+ * @return {!proto.ChannelMetadata}
  */
-proto.muthu.other.ChannelMetadata.deserializeBinaryFromReader = function(msg, reader) {
+proto.ChannelMetadata.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -144,9 +175,9 @@ proto.muthu.other.ChannelMetadata.deserializeBinaryFromReader = function(msg, re
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.muthu.other.ChannelMetadata.prototype.serializeBinary = function() {
+proto.ChannelMetadata.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.muthu.other.ChannelMetadata.serializeBinaryToWriter(this, writer);
+  proto.ChannelMetadata.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -154,11 +185,11 @@ proto.muthu.other.ChannelMetadata.prototype.serializeBinary = function() {
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.muthu.other.ChannelMetadata} message
+ * @param {!proto.ChannelMetadata} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.muthu.other.ChannelMetadata.serializeBinaryToWriter = function(message, writer) {
+proto.ChannelMetadata.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = /** @type {string} */ (jspb.Message.getField(message, 1));
   if (f != null) {
@@ -216,27 +247,34 @@ proto.muthu.other.ChannelMetadata.serializeBinaryToWriter = function(message, wr
  * optional string title = 1;
  * @return {string}
  */
-proto.muthu.other.ChannelMetadata.prototype.getTitle = function() {
+proto.ChannelMetadata.prototype.getTitle = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
-/** @param {string} value */
-proto.muthu.other.ChannelMetadata.prototype.setTitle = function(value) {
-  jspb.Message.setField(this, 1, value);
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setTitle = function(value) {
+  return jspb.Message.setField(this, 1, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearTitle = function() {
-  jspb.Message.setField(this, 1, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearTitle = function() {
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasTitle = function() {
+proto.ChannelMetadata.prototype.hasTitle = function() {
   return jspb.Message.getField(this, 1) != null;
 };
 
@@ -245,58 +283,70 @@ proto.muthu.other.ChannelMetadata.prototype.hasTitle = function() {
  * optional string description = 2;
  * @return {string}
  */
-proto.muthu.other.ChannelMetadata.prototype.getDescription = function() {
+proto.ChannelMetadata.prototype.getDescription = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
 };
 
 
-/** @param {string} value */
-proto.muthu.other.ChannelMetadata.prototype.setDescription = function(value) {
-  jspb.Message.setField(this, 2, value);
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setDescription = function(value) {
+  return jspb.Message.setField(this, 2, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearDescription = function() {
-  jspb.Message.setField(this, 2, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearDescription = function() {
+  return jspb.Message.setField(this, 2, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasDescription = function() {
+proto.ChannelMetadata.prototype.hasDescription = function() {
   return jspb.Message.getField(this, 2) != null;
 };
 
 
 /**
  * optional bool is_public = 3;
- * Note that Boolean fields may be set to 0/1 when serialized from a Java server.
- * You should avoid comparisons like {@code val === true/false} in those cases.
  * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.getIsPublic = function() {
-  return /** @type {boolean} */ (jspb.Message.getFieldWithDefault(this, 3, false));
+proto.ChannelMetadata.prototype.getIsPublic = function() {
+  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
 };
 
 
-/** @param {boolean} value */
-proto.muthu.other.ChannelMetadata.prototype.setIsPublic = function(value) {
-  jspb.Message.setField(this, 3, value);
+/**
+ * @param {boolean} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setIsPublic = function(value) {
+  return jspb.Message.setField(this, 3, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearIsPublic = function() {
-  jspb.Message.setField(this, 3, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearIsPublic = function() {
+  return jspb.Message.setField(this, 3, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasIsPublic = function() {
+proto.ChannelMetadata.prototype.hasIsPublic = function() {
   return jspb.Message.getField(this, 3) != null;
 };
 
@@ -305,27 +355,34 @@ proto.muthu.other.ChannelMetadata.prototype.hasIsPublic = function() {
  * optional string language = 4;
  * @return {string}
  */
-proto.muthu.other.ChannelMetadata.prototype.getLanguage = function() {
+proto.ChannelMetadata.prototype.getLanguage = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
 };
 
 
-/** @param {string} value */
-proto.muthu.other.ChannelMetadata.prototype.setLanguage = function(value) {
-  jspb.Message.setField(this, 4, value);
+/**
+ * @param {string} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setLanguage = function(value) {
+  return jspb.Message.setField(this, 4, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearLanguage = function() {
-  jspb.Message.setField(this, 4, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearLanguage = function() {
+  return jspb.Message.setField(this, 4, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasLanguage = function() {
+proto.ChannelMetadata.prototype.hasLanguage = function() {
   return jspb.Message.getField(this, 4) != null;
 };
 
@@ -334,27 +391,34 @@ proto.muthu.other.ChannelMetadata.prototype.hasLanguage = function() {
  * optional uint32 cover_photo = 5;
  * @return {number}
  */
-proto.muthu.other.ChannelMetadata.prototype.getCoverPhoto = function() {
+proto.ChannelMetadata.prototype.getCoverPhoto = function() {
   return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
 };
 
 
-/** @param {number} value */
-proto.muthu.other.ChannelMetadata.prototype.setCoverPhoto = function(value) {
-  jspb.Message.setField(this, 5, value);
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setCoverPhoto = function(value) {
+  return jspb.Message.setField(this, 5, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearCoverPhoto = function() {
-  jspb.Message.setField(this, 5, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearCoverPhoto = function() {
+  return jspb.Message.setField(this, 5, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasCoverPhoto = function() {
+proto.ChannelMetadata.prototype.hasCoverPhoto = function() {
   return jspb.Message.getField(this, 5) != null;
 };
 
@@ -363,27 +427,34 @@ proto.muthu.other.ChannelMetadata.prototype.hasCoverPhoto = function() {
  * optional uint32 avatar_photo = 6;
  * @return {number}
  */
-proto.muthu.other.ChannelMetadata.prototype.getAvatarPhoto = function() {
+proto.ChannelMetadata.prototype.getAvatarPhoto = function() {
   return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
 };
 
 
-/** @param {number} value */
-proto.muthu.other.ChannelMetadata.prototype.setAvatarPhoto = function(value) {
-  jspb.Message.setField(this, 6, value);
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setAvatarPhoto = function(value) {
+  return jspb.Message.setField(this, 6, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearAvatarPhoto = function() {
-  jspb.Message.setField(this, 6, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearAvatarPhoto = function() {
+  return jspb.Message.setField(this, 6, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasAvatarPhoto = function() {
+proto.ChannelMetadata.prototype.hasAvatarPhoto = function() {
   return jspb.Message.getField(this, 6) != null;
 };
 
@@ -392,79 +463,71 @@ proto.muthu.other.ChannelMetadata.prototype.hasAvatarPhoto = function() {
  * optional uint64 category = 7;
  * @return {number}
  */
-proto.muthu.other.ChannelMetadata.prototype.getCategory = function() {
+proto.ChannelMetadata.prototype.getCategory = function() {
   return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
 };
 
 
-/** @param {number} value */
-proto.muthu.other.ChannelMetadata.prototype.setCategory = function(value) {
-  jspb.Message.setField(this, 7, value);
+/**
+ * @param {number} value
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.setCategory = function(value) {
+  return jspb.Message.setField(this, 7, value);
 };
 
 
-proto.muthu.other.ChannelMetadata.prototype.clearCategory = function() {
-  jspb.Message.setField(this, 7, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelMetadata} returns this
+ */
+proto.ChannelMetadata.prototype.clearCategory = function() {
+  return jspb.Message.setField(this, 7, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelMetadata.prototype.hasCategory = function() {
+proto.ChannelMetadata.prototype.hasCategory = function() {
   return jspb.Message.getField(this, 7) != null;
 };
 
 
 
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.muthu.other.ChannelCategoryMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.muthu.other.ChannelCategoryMetadata, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  proto.muthu.other.ChannelCategoryMetadata.displayName = 'proto.muthu.other.ChannelCategoryMetadata';
-}
 
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
-proto.muthu.other.ChannelCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.muthu.other.ChannelCategoryMetadata.toObject(opt_includeInstance, this);
+proto.ChannelCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
+  return proto.ChannelCategoryMetadata.toObject(opt_includeInstance, this);
 };
 
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
- * @param {!proto.muthu.other.ChannelCategoryMetadata} msg The msg instance to transform.
+ * @param {!proto.ChannelCategoryMetadata} msg The msg instance to transform.
  * @return {!Object}
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.muthu.other.ChannelCategoryMetadata.toObject = function(includeInstance, msg) {
+proto.ChannelCategoryMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    name: jspb.Message.getField(msg, 1)
+    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -478,23 +541,23 @@ proto.muthu.other.ChannelCategoryMetadata.toObject = function(includeInstance, m
 /**
  * Deserializes binary data (in protobuf wire format).
  * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.muthu.other.ChannelCategoryMetadata}
+ * @return {!proto.ChannelCategoryMetadata}
  */
-proto.muthu.other.ChannelCategoryMetadata.deserializeBinary = function(bytes) {
+proto.ChannelCategoryMetadata.deserializeBinary = function(bytes) {
   var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.muthu.other.ChannelCategoryMetadata;
-  return proto.muthu.other.ChannelCategoryMetadata.deserializeBinaryFromReader(msg, reader);
+  var msg = new proto.ChannelCategoryMetadata;
+  return proto.ChannelCategoryMetadata.deserializeBinaryFromReader(msg, reader);
 };
 
 
 /**
  * Deserializes binary data (in protobuf wire format) from the
  * given reader into the given message object.
- * @param {!proto.muthu.other.ChannelCategoryMetadata} msg The message object to deserialize into.
+ * @param {!proto.ChannelCategoryMetadata} msg The message object to deserialize into.
  * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.muthu.other.ChannelCategoryMetadata}
+ * @return {!proto.ChannelCategoryMetadata}
  */
-proto.muthu.other.ChannelCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
+proto.ChannelCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
   while (reader.nextField()) {
     if (reader.isEndGroup()) {
       break;
@@ -518,9 +581,9 @@ proto.muthu.other.ChannelCategoryMetadata.deserializeBinaryFromReader = function
  * Serializes the message to binary data (in protobuf wire format).
  * @return {!Uint8Array}
  */
-proto.muthu.other.ChannelCategoryMetadata.prototype.serializeBinary = function() {
+proto.ChannelCategoryMetadata.prototype.serializeBinary = function() {
   var writer = new jspb.BinaryWriter();
-  proto.muthu.other.ChannelCategoryMetadata.serializeBinaryToWriter(this, writer);
+  proto.ChannelCategoryMetadata.serializeBinaryToWriter(this, writer);
   return writer.getResultBuffer();
 };
 
@@ -528,11 +591,11 @@ proto.muthu.other.ChannelCategoryMetadata.prototype.serializeBinary = function()
 /**
  * Serializes the given message to binary data (in protobuf wire
  * format), writing to the given BinaryWriter.
- * @param {!proto.muthu.other.ChannelCategoryMetadata} message
+ * @param {!proto.ChannelCategoryMetadata} message
  * @param {!jspb.BinaryWriter} writer
  * @suppress {unusedLocalVariables} f is only used for nested messages
  */
-proto.muthu.other.ChannelCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
+proto.ChannelCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
   var f = undefined;
   f = /** @type {string} */ (jspb.Message.getField(message, 1));
   if (f != null) {
@@ -548,29 +611,36 @@ proto.muthu.other.ChannelCategoryMetadata.serializeBinaryToWriter = function(mes
  * optional string name = 1;
  * @return {string}
  */
-proto.muthu.other.ChannelCategoryMetadata.prototype.getName = function() {
+proto.ChannelCategoryMetadata.prototype.getName = function() {
   return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
 };
 
 
-/** @param {string} value */
-proto.muthu.other.ChannelCategoryMetadata.prototype.setName = function(value) {
-  jspb.Message.setField(this, 1, value);
+/**
+ * @param {string} value
+ * @return {!proto.ChannelCategoryMetadata} returns this
+ */
+proto.ChannelCategoryMetadata.prototype.setName = function(value) {
+  return jspb.Message.setField(this, 1, value);
 };
 
 
-proto.muthu.other.ChannelCategoryMetadata.prototype.clearName = function() {
-  jspb.Message.setField(this, 1, undefined);
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.ChannelCategoryMetadata} returns this
+ */
+proto.ChannelCategoryMetadata.prototype.clearName = function() {
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
-proto.muthu.other.ChannelCategoryMetadata.prototype.hasName = function() {
+proto.ChannelCategoryMetadata.prototype.hasName = function() {
   return jspb.Message.getField(this, 1) != null;
 };
 
 
-goog.object.extend(exports, proto.muthu.other);
+goog.object.extend(exports, proto);

+ 89 - 37
content-metadata-protobuf/compiled/proto/Person_pb.js

@@ -1,18 +1,21 @@
+// source: proto/Person.proto
 /**
  * @fileoverview
  * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
  * @suppress {messageConventions} JS Compiler reports an error if a variable or
  *     field starts with 'MSG_' and isn't a translatable message.
  * @public
  */
 // GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
 
 var jspb = require('google-protobuf');
 var goog = jspb;
 var global = Function('return this')();
 
 goog.exportSymbol('proto.PersonMetadata', null, global);
-
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -28,19 +31,26 @@ proto.PersonMetadata = function(opt_data) {
 };
 goog.inherits(proto.PersonMetadata, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
   proto.PersonMetadata.displayName = 'proto.PersonMetadata';
 }
 
 
+
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
 proto.PersonMetadata.prototype.toObject = function(opt_includeInstance) {
@@ -50,8 +60,8 @@ proto.PersonMetadata.prototype.toObject = function(opt_includeInstance) {
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
  * @param {!proto.PersonMetadata} msg The msg instance to transform.
  * @return {!Object}
@@ -59,12 +69,12 @@ proto.PersonMetadata.prototype.toObject = function(opt_includeInstance) {
  */
 proto.PersonMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    firstName: jspb.Message.getField(msg, 1),
-    middleName: jspb.Message.getField(msg, 2),
-    lastName: jspb.Message.getField(msg, 3),
-    about: jspb.Message.getField(msg, 4),
-    coverPhoto: jspb.Message.getField(msg, 5),
-    avatarPhoto: jspb.Message.getField(msg, 6)
+    firstName: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    middleName: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    lastName: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    about: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
+    avatarPhoto: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -208,20 +218,27 @@ proto.PersonMetadata.prototype.getFirstName = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setFirstName = function(value) {
-  jspb.Message.setField(this, 1, value);
+  return jspb.Message.setField(this, 1, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearFirstName = function() {
-  jspb.Message.setField(this, 1, undefined);
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasFirstName = function() {
   return jspb.Message.getField(this, 1) != null;
@@ -237,20 +254,27 @@ proto.PersonMetadata.prototype.getMiddleName = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setMiddleName = function(value) {
-  jspb.Message.setField(this, 2, value);
+  return jspb.Message.setField(this, 2, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearMiddleName = function() {
-  jspb.Message.setField(this, 2, undefined);
+  return jspb.Message.setField(this, 2, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasMiddleName = function() {
   return jspb.Message.getField(this, 2) != null;
@@ -266,20 +290,27 @@ proto.PersonMetadata.prototype.getLastName = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setLastName = function(value) {
-  jspb.Message.setField(this, 3, value);
+  return jspb.Message.setField(this, 3, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearLastName = function() {
-  jspb.Message.setField(this, 3, undefined);
+  return jspb.Message.setField(this, 3, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasLastName = function() {
   return jspb.Message.getField(this, 3) != null;
@@ -295,20 +326,27 @@ proto.PersonMetadata.prototype.getAbout = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setAbout = function(value) {
-  jspb.Message.setField(this, 4, value);
+  return jspb.Message.setField(this, 4, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearAbout = function() {
-  jspb.Message.setField(this, 4, undefined);
+  return jspb.Message.setField(this, 4, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasAbout = function() {
   return jspb.Message.getField(this, 4) != null;
@@ -324,20 +362,27 @@ proto.PersonMetadata.prototype.getCoverPhoto = function() {
 };
 
 
-/** @param {number} value */
+/**
+ * @param {number} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setCoverPhoto = function(value) {
-  jspb.Message.setField(this, 5, value);
+  return jspb.Message.setField(this, 5, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearCoverPhoto = function() {
-  jspb.Message.setField(this, 5, undefined);
+  return jspb.Message.setField(this, 5, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasCoverPhoto = function() {
   return jspb.Message.getField(this, 5) != null;
@@ -353,20 +398,27 @@ proto.PersonMetadata.prototype.getAvatarPhoto = function() {
 };
 
 
-/** @param {number} value */
+/**
+ * @param {number} value
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.setAvatarPhoto = function(value) {
-  jspb.Message.setField(this, 6, value);
+  return jspb.Message.setField(this, 6, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PersonMetadata} returns this
+ */
 proto.PersonMetadata.prototype.clearAvatarPhoto = function() {
-  jspb.Message.setField(this, 6, undefined);
+  return jspb.Message.setField(this, 6, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PersonMetadata.prototype.hasAvatarPhoto = function() {
   return jspb.Message.getField(this, 6) != null;

+ 47 - 20
content-metadata-protobuf/compiled/proto/Playlist_pb.js

@@ -1,18 +1,21 @@
+// source: proto/Playlist.proto
 /**
  * @fileoverview
  * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
  * @suppress {messageConventions} JS Compiler reports an error if a variable or
  *     field starts with 'MSG_' and isn't a translatable message.
  * @public
  */
 // GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
 
 var jspb = require('google-protobuf');
 var goog = jspb;
 var global = Function('return this')();
 
 goog.exportSymbol('proto.PlaylistMetadata', null, global);
-
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -28,8 +31,13 @@ proto.PlaylistMetadata = function(opt_data) {
 };
 goog.inherits(proto.PlaylistMetadata, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
   proto.PlaylistMetadata.displayName = 'proto.PlaylistMetadata';
 }
+
 /**
  * List of repeated fields within this message type.
  * @private {!Array<number>}
@@ -41,13 +49,15 @@ proto.PlaylistMetadata.repeatedFields_ = [2];
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
 proto.PlaylistMetadata.prototype.toObject = function(opt_includeInstance) {
@@ -57,8 +67,8 @@ proto.PlaylistMetadata.prototype.toObject = function(opt_includeInstance) {
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
  * @param {!proto.PlaylistMetadata} msg The msg instance to transform.
  * @return {!Object}
@@ -66,8 +76,8 @@ proto.PlaylistMetadata.prototype.toObject = function(opt_includeInstance) {
  */
 proto.PlaylistMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    title: jspb.Message.getField(msg, 1),
-    videosList: jspb.Message.getRepeatedField(msg, 2)
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    videosList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -109,8 +119,10 @@ proto.PlaylistMetadata.deserializeBinaryFromReader = function(msg, reader) {
       msg.setTitle(value);
       break;
     case 2:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.addVideos(value);
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addVideos(values[i]);
+      }
       break;
     default:
       reader.skipField();
@@ -167,20 +179,27 @@ proto.PlaylistMetadata.prototype.getTitle = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.PlaylistMetadata} returns this
+ */
 proto.PlaylistMetadata.prototype.setTitle = function(value) {
-  jspb.Message.setField(this, 1, value);
+  return jspb.Message.setField(this, 1, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.PlaylistMetadata} returns this
+ */
 proto.PlaylistMetadata.prototype.clearTitle = function() {
-  jspb.Message.setField(this, 1, undefined);
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.PlaylistMetadata.prototype.hasTitle = function() {
   return jspb.Message.getField(this, 1) != null;
@@ -196,23 +215,31 @@ proto.PlaylistMetadata.prototype.getVideosList = function() {
 };
 
 
-/** @param {!Array<number>} value */
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.PlaylistMetadata} returns this
+ */
 proto.PlaylistMetadata.prototype.setVideosList = function(value) {
-  jspb.Message.setField(this, 2, value || []);
+  return jspb.Message.setField(this, 2, value || []);
 };
 
 
 /**
- * @param {!number} value
+ * @param {number} value
  * @param {number=} opt_index
+ * @return {!proto.PlaylistMetadata} returns this
  */
 proto.PlaylistMetadata.prototype.addVideos = function(value, opt_index) {
-  jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
 };
 
 
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.PlaylistMetadata} returns this
+ */
 proto.PlaylistMetadata.prototype.clearVideosList = function() {
-  this.setVideosList([]);
+  return this.setVideosList([]);
 };
 
 

+ 154 - 76
content-metadata-protobuf/compiled/proto/Series_pb.js

@@ -1,11 +1,15 @@
+// source: proto/Series.proto
 /**
  * @fileoverview
  * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
  * @suppress {messageConventions} JS Compiler reports an error if a variable or
  *     field starts with 'MSG_' and isn't a translatable message.
  * @public
  */
 // GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
 
 var jspb = require('google-protobuf');
 var goog = jspb;
@@ -13,7 +17,6 @@ var global = Function('return this')();
 
 goog.exportSymbol('proto.SeasonMetadata', null, global);
 goog.exportSymbol('proto.SeriesMetadata', null, global);
-
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -29,8 +32,34 @@ proto.SeriesMetadata = function(opt_data) {
 };
 goog.inherits(proto.SeriesMetadata, jspb.Message);
 if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
   proto.SeriesMetadata.displayName = 'proto.SeriesMetadata';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.SeasonMetadata = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.SeasonMetadata.repeatedFields_, null);
+};
+goog.inherits(proto.SeasonMetadata, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.SeasonMetadata.displayName = 'proto.SeasonMetadata';
+}
+
 /**
  * List of repeated fields within this message type.
  * @private {!Array<number>}
@@ -42,13 +71,15 @@ proto.SeriesMetadata.repeatedFields_ = [4];
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
 proto.SeriesMetadata.prototype.toObject = function(opt_includeInstance) {
@@ -58,8 +89,8 @@ proto.SeriesMetadata.prototype.toObject = function(opt_includeInstance) {
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
  * @param {!proto.SeriesMetadata} msg The msg instance to transform.
  * @return {!Object}
@@ -67,10 +98,10 @@ proto.SeriesMetadata.prototype.toObject = function(opt_includeInstance) {
  */
 proto.SeriesMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    title: jspb.Message.getField(msg, 1),
-    description: jspb.Message.getField(msg, 2),
-    coverPhoto: jspb.Message.getField(msg, 3),
-    personsList: jspb.Message.getRepeatedField(msg, 4)
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    personsList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -120,8 +151,10 @@ proto.SeriesMetadata.deserializeBinaryFromReader = function(msg, reader) {
       msg.setCoverPhoto(value);
       break;
     case 4:
-      var value = /** @type {!Array<number>} */ (reader.readPackedUint64());
-      msg.setPersonsList(value);
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPersons(values[i]);
+      }
       break;
     default:
       reader.skipField();
@@ -192,20 +225,27 @@ proto.SeriesMetadata.prototype.getTitle = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.setTitle = function(value) {
-  jspb.Message.setField(this, 1, value);
+  return jspb.Message.setField(this, 1, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.clearTitle = function() {
-  jspb.Message.setField(this, 1, undefined);
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeriesMetadata.prototype.hasTitle = function() {
   return jspb.Message.getField(this, 1) != null;
@@ -221,20 +261,27 @@ proto.SeriesMetadata.prototype.getDescription = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.setDescription = function(value) {
-  jspb.Message.setField(this, 2, value);
+  return jspb.Message.setField(this, 2, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.clearDescription = function() {
-  jspb.Message.setField(this, 2, undefined);
+  return jspb.Message.setField(this, 2, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeriesMetadata.prototype.hasDescription = function() {
   return jspb.Message.getField(this, 2) != null;
@@ -250,20 +297,27 @@ proto.SeriesMetadata.prototype.getCoverPhoto = function() {
 };
 
 
-/** @param {number} value */
+/**
+ * @param {number} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.setCoverPhoto = function(value) {
-  jspb.Message.setField(this, 3, value);
+  return jspb.Message.setField(this, 3, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.clearCoverPhoto = function() {
-  jspb.Message.setField(this, 3, undefined);
+  return jspb.Message.setField(this, 3, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeriesMetadata.prototype.hasCoverPhoto = function() {
   return jspb.Message.getField(this, 3) != null;
@@ -279,44 +333,35 @@ proto.SeriesMetadata.prototype.getPersonsList = function() {
 };
 
 
-/** @param {!Array<number>} value */
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.setPersonsList = function(value) {
-  jspb.Message.setField(this, 4, value || []);
+  return jspb.Message.setField(this, 4, value || []);
 };
 
 
 /**
- * @param {!number} value
+ * @param {number} value
  * @param {number=} opt_index
+ * @return {!proto.SeriesMetadata} returns this
  */
 proto.SeriesMetadata.prototype.addPersons = function(value, opt_index) {
-  jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
 };
 
 
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SeriesMetadata} returns this
+ */
 proto.SeriesMetadata.prototype.clearPersonsList = function() {
-  this.setPersonsList([]);
+  return this.setPersonsList([]);
 };
 
 
 
-/**
- * Generated by JsPbCodeGenerator.
- * @param {Array=} opt_data Optional initial data array, typically from a
- * server response, or constructed directly in Javascript. The array is used
- * in place and becomes part of the constructed object. It is not cloned.
- * If no data is provided, the constructed object will be empty, but still
- * valid.
- * @extends {jspb.Message}
- * @constructor
- */
-proto.SeasonMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.SeasonMetadata.repeatedFields_, null);
-};
-goog.inherits(proto.SeasonMetadata, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  proto.SeasonMetadata.displayName = 'proto.SeasonMetadata';
-}
 /**
  * List of repeated fields within this message type.
  * @private {!Array<number>}
@@ -328,13 +373,15 @@ proto.SeasonMetadata.repeatedFields_ = [4];
 
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
- * Creates an object representation of this proto suitable for use in Soy templates.
+ * Creates an object representation of this proto.
  * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
  * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
  * For the list of reserved names please see:
- *     com.google.apps.jspb.JsClassTemplate.JS_RESERVED_WORDS.
- * @param {boolean=} opt_includeInstance Whether to include the JSPB instance
- *     for transitional soy proto support: http://goto/soy-param-migration
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
  * @return {!Object}
  */
 proto.SeasonMetadata.prototype.toObject = function(opt_includeInstance) {
@@ -344,8 +391,8 @@ proto.SeasonMetadata.prototype.toObject = function(opt_includeInstance) {
 
 /**
  * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Whether to include the JSPB
- *     instance for transitional soy proto support:
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
  *     http://goto/soy-param-migration
  * @param {!proto.SeasonMetadata} msg The msg instance to transform.
  * @return {!Object}
@@ -353,10 +400,10 @@ proto.SeasonMetadata.prototype.toObject = function(opt_includeInstance) {
  */
 proto.SeasonMetadata.toObject = function(includeInstance, msg) {
   var f, obj = {
-    title: jspb.Message.getField(msg, 1),
-    description: jspb.Message.getField(msg, 2),
-    coverPhoto: jspb.Message.getField(msg, 3),
-    personsList: jspb.Message.getRepeatedField(msg, 4)
+    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
+    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
+    coverPhoto: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
+    personsList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f
   };
 
   if (includeInstance) {
@@ -406,8 +453,10 @@ proto.SeasonMetadata.deserializeBinaryFromReader = function(msg, reader) {
       msg.setCoverPhoto(value);
       break;
     case 4:
-      var value = /** @type {!Array<number>} */ (reader.readPackedUint64());
-      msg.setPersonsList(value);
+      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
+      for (var i = 0; i < values.length; i++) {
+        msg.addPersons(values[i]);
+      }
       break;
     default:
       reader.skipField();
@@ -478,20 +527,27 @@ proto.SeasonMetadata.prototype.getTitle = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.setTitle = function(value) {
-  jspb.Message.setField(this, 1, value);
+  return jspb.Message.setField(this, 1, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.clearTitle = function() {
-  jspb.Message.setField(this, 1, undefined);
+  return jspb.Message.setField(this, 1, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeasonMetadata.prototype.hasTitle = function() {
   return jspb.Message.getField(this, 1) != null;
@@ -507,20 +563,27 @@ proto.SeasonMetadata.prototype.getDescription = function() {
 };
 
 
-/** @param {string} value */
+/**
+ * @param {string} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.setDescription = function(value) {
-  jspb.Message.setField(this, 2, value);
+  return jspb.Message.setField(this, 2, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.clearDescription = function() {
-  jspb.Message.setField(this, 2, undefined);
+  return jspb.Message.setField(this, 2, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeasonMetadata.prototype.hasDescription = function() {
   return jspb.Message.getField(this, 2) != null;
@@ -536,20 +599,27 @@ proto.SeasonMetadata.prototype.getCoverPhoto = function() {
 };
 
 
-/** @param {number} value */
+/**
+ * @param {number} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.setCoverPhoto = function(value) {
-  jspb.Message.setField(this, 3, value);
+  return jspb.Message.setField(this, 3, value);
 };
 
 
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.clearCoverPhoto = function() {
-  jspb.Message.setField(this, 3, undefined);
+  return jspb.Message.setField(this, 3, undefined);
 };
 
 
 /**
  * Returns whether this field is set.
- * @return {!boolean}
+ * @return {boolean}
  */
 proto.SeasonMetadata.prototype.hasCoverPhoto = function() {
   return jspb.Message.getField(this, 3) != null;
@@ -565,23 +635,31 @@ proto.SeasonMetadata.prototype.getPersonsList = function() {
 };
 
 
-/** @param {!Array<number>} value */
+/**
+ * @param {!Array<number>} value
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.setPersonsList = function(value) {
-  jspb.Message.setField(this, 4, value || []);
+  return jspb.Message.setField(this, 4, value || []);
 };
 
 
 /**
- * @param {!number} value
+ * @param {number} value
  * @param {number=} opt_index
+ * @return {!proto.SeasonMetadata} returns this
  */
 proto.SeasonMetadata.prototype.addPersons = function(value, opt_index) {
-  jspb.Message.addToRepeatedField(this, 4, value, opt_index);
+  return jspb.Message.addToRepeatedField(this, 4, value, opt_index);
 };
 
 
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.SeasonMetadata} returns this
+ */
 proto.SeasonMetadata.prototype.clearPersonsList = function() {
-  this.setPersonsList([]);
+  return this.setPersonsList([]);
 };
 
 

File diff suppressed because it is too large
+ 360 - 178
content-metadata-protobuf/compiled/proto/Video_pb.js


+ 0 - 2
content-metadata-protobuf/proto/Channel.proto

@@ -1,7 +1,5 @@
 syntax = "proto2";
 
-package muthu.other;
-
 message ChannelMetadata {
     // Channel Title
     optional string title = 1;

+ 1 - 1
node/Cargo.toml

@@ -3,7 +3,7 @@ authors = ['Joystream contributors']
 build = 'build.rs'
 edition = '2018'
 name = 'joystream-node'
-version = '3.7.1'
+version = '3.7.2'
 default-run = "joystream-node"
 
 [[bin]]

+ 4 - 4
pioneer/packages/joy-proposals/src/validationSchema.ts

@@ -32,8 +32,8 @@ const RATIONALE_MAX_LENGTH = 3000;
 const FILE_SIZE_BYTES_MIN = 1;
 
 // Set Election Parameters
-const ANNOUNCING_PERIOD_MAX = 43200;
 const ANNOUNCING_PERIOD_MIN = 14400;
+const ANNOUNCING_PERIOD_MAX = 43200;
 const VOTING_PERIOD_MIN = 14400;
 const VOTING_PERIOD_MAX = 28800;
 const REVEALING_PERIOD_MIN = 14400;
@@ -42,10 +42,10 @@ const MIN_COUNCIL_STAKE_MIN = 1;
 const MIN_COUNCIL_STAKE_MAX = 100000;
 const NEW_TERM_DURATION_MIN = 14400;
 const NEW_TERM_DURATION_MAX = 432000;
-const CANDIDACY_LIMIT_MIN = 25;
+const CANDIDACY_LIMIT_MIN = 50;
 const CANDIDACY_LIMIT_MAX = 100;
-const COUNCIL_SIZE_MAX = 20;
 const COUNCIL_SIZE_MIN = 4;
+const COUNCIL_SIZE_MAX = 20;
 const MIN_VOTING_STAKE_MIN = 1;
 const MIN_VOTING_STAKE_MAX = 100000;
 
@@ -55,7 +55,7 @@ const TOKENS_MAX = 5000000;
 
 // Set Validator Count
 const MAX_VALIDATOR_COUNT_MIN = 4;
-const MAX_VALIDATOR_COUNT_MAX = 100;
+const MAX_VALIDATOR_COUNT_MAX = 300;
 
 // Add Working Group Leader Opening Parameters
 // TODO: Discuss the actual values

+ 0 - 3
runtime-modules/content/src/errors.rs

@@ -10,9 +10,6 @@ decl_error! {
         // Curator Management Errors
         // -------------------------
 
-        /// Curator group can`t be removed
-        CuratorGroupRemovalForbidden,
-
         /// Curator under provided curator id is not a member of curaror group under given id
         CuratorIsNotAMemberOfGivenCuratorGroup,
 

+ 10 - 7
runtime-modules/content/src/lib.rs

@@ -638,7 +638,7 @@ decl_module! {
             actor: ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
             params: ChannelCreationParameters<ContentParameters<T>, T::AccountId>,
         ) {
-            ensure_actor_authorized_to_create_channels_and_videos_assets::<T>(
+            ensure_actor_authorized_to_create_channel::<T>(
                 origin,
                 &actor,
             )?;
@@ -691,7 +691,7 @@ decl_module! {
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
 
-            ensure_actor_authorized_update_channel_and_videos::<T>(
+            ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
                 &channel.owner,
@@ -752,7 +752,7 @@ decl_module! {
             // check that channel exists
             let channel = Self::ensure_channel_exists(&channel_id)?;
 
-            ensure_actor_authorized_update_channel_and_videos::<T>(
+            ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
                 &channel.owner,
@@ -926,9 +926,13 @@ decl_module! {
             channel_id: T::ChannelId,
             params: VideoCreationParameters<ContentParameters<T>>,
         ) {
-            ensure_actor_authorized_to_create_channels_and_videos_assets::<T>(
+            // check that channel exists
+            let channel = Self::ensure_channel_exists(&channel_id)?;
+
+            ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
+                &channel.owner,
             )?;
 
             // Pick out the assets to be uploaded to storage system
@@ -982,10 +986,9 @@ decl_module! {
             // check that video exists, retrieve corresponding channel id.
             let channel_id = Self::ensure_video_exists(&video_id)?.in_channel;
 
-            ensure_actor_authorized_update_channel_and_videos::<T>(
+            ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
-                // The channel owner will be..
                 &Self::channel_by_id(channel_id).owner,
             )?;
 
@@ -1035,7 +1038,7 @@ decl_module! {
 
             let channel_id = video.in_channel;
 
-            ensure_actor_authorized_update_channel_and_videos::<T>(
+            ensure_actor_authorized_to_update_channel::<T>(
                 origin,
                 &actor,
                 // The channel owner will be..

+ 17 - 17
runtime-modules/content/src/permissions/mod.rs

@@ -12,7 +12,7 @@ use frame_support::{ensure, Parameter};
 pub use serde::{Deserialize, Serialize};
 use sp_arithmetic::traits::BaseArithmetic;
 use sp_runtime::traits::{MaybeSerializeDeserialize, Member};
-use system::ensure_root;
+// use system::ensure_root;
 
 /// Model of authentication manager.
 pub trait ContentActorAuthenticator: system::Trait + MembershipTypes {
@@ -99,7 +99,7 @@ pub fn ensure_is_lead<T: Trait>(origin: T::Origin) -> DispatchResult {
     ensure_lead_auth_success::<T>(&account_id)
 }
 
-pub fn ensure_actor_authorized_to_create_channels_and_videos_assets<T: Trait>(
+pub fn ensure_actor_authorized_to_create_channel<T: Trait>(
     origin: T::Origin,
     actor: &ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
 ) -> DispatchResult {
@@ -128,8 +128,8 @@ pub fn ensure_actor_authorized_to_create_channels_and_videos_assets<T: Trait>(
     }
 }
 
-// Enure actor can update or delete channels and videos
-pub fn ensure_actor_authorized_update_channel_and_videos<T: Trait>(
+// Enure actor can update channels and videos in the channel
+pub fn ensure_actor_authorized_to_update_channel<T: Trait>(
     origin: T::Origin,
     actor: &ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
     owner: &ChannelOwner<T::MemberId, T::CuratorGroupId, T::DAOId>,
@@ -263,19 +263,19 @@ pub fn ensure_actor_authorized_to_manage_categories<T: Trait>(
     }
 }
 
-pub fn ensure_actor_authorized_to_delete_stale_assets<T: Trait>(
-    origin: T::Origin,
-    actor: &ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
-) -> DispatchResult {
-    // Only Lead and (sudo) can delete assets no longer associated with a channel or person.
-    if let ContentActor::Lead = actor {
-        let sender = ensure_signed(origin)?;
-        ensure_lead_auth_success::<T>(&sender)
-    } else {
-        ensure_root(origin)?;
-        Ok(())
-    }
-}
+// pub fn ensure_actor_authorized_to_delete_stale_assets<T: Trait>(
+//     origin: T::Origin,
+//     actor: &ContentActor<T::CuratorGroupId, T::CuratorId, T::MemberId>,
+// ) -> DispatchResult {
+//     // Only Lead and (sudo) can delete assets no longer associated with a channel or person.
+//     if let ContentActor::Lead = actor {
+//         let sender = ensure_signed(origin)?;
+//         ensure_lead_auth_success::<T>(&sender)
+//     } else {
+//         ensure_root(origin)?;
+//         Ok(())
+//     }
+// }
 
 /// Enum, representing all possible `Actor`s
 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]

+ 224 - 26
runtime-modules/content/src/tests/channels.rs

@@ -1,33 +1,16 @@
 #![cfg(test)]
 
+use super::curators;
 use super::mock::*;
 use crate::*;
 use frame_support::{assert_err, assert_ok};
 
-fn add_curator_to_new_group(curator_id: CuratorId) -> CuratorGroupId {
-    let curator_group_id = Content::next_curator_group_id();
-    // create new group and add curator id to it
-    assert_ok!(Content::create_curator_group(Origin::signed(LEAD_ORIGIN)));
-    assert_ok!(Content::add_curator_to_group(
-        Origin::signed(LEAD_ORIGIN),
-        curator_group_id,
-        curator_id
-    ));
-    // make group active
-    assert_ok!(Content::set_curator_group_status(
-        Origin::signed(LEAD_ORIGIN),
-        curator_group_id,
-        true
-    ));
-    curator_group_id
-}
-
 #[test]
 fn lead_cannot_create_channel() {
     with_default_mock_builder(|| {
         assert_err!(
             Content::create_channel(
-                Origin::signed(FIRST_MEMBER_ORIGIN),
+                Origin::signed(LEAD_ORIGIN),
                 ContentActor::Lead,
                 ChannelCreationParameters {
                     assets: vec![],
@@ -41,8 +24,11 @@ fn lead_cannot_create_channel() {
 }
 
 #[test]
-fn curators_can_create_channel() {
+fn curator_owned_channels() {
     with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+
         // Curator group doesn't exist yet
         assert_err!(
             Content::create_channel(
@@ -57,7 +43,7 @@ fn curators_can_create_channel() {
             Error::<Test>::CuratorGroupIsNotActive
         );
 
-        let group_id = add_curator_to_new_group(FIRST_CURATOR_ID);
+        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
         assert_eq!(FIRST_CURATOR_GROUP_ID, group_id);
 
         // Curator from wrong group
@@ -88,6 +74,8 @@ fn curators_can_create_channel() {
             Error::<Test>::CuratorAuthFailed
         );
 
+        let channel_id = Content::next_channel_id();
+
         // Curator in correct active group, with correct origin
         assert_ok!(Content::create_channel(
             Origin::signed(FIRST_CURATOR_ORIGIN),
@@ -98,11 +86,60 @@ fn curators_can_create_channel() {
                 reward_account: None,
             }
         ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCreated(
+                ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
+                channel_id,
+                ChannelRecord {
+                    owner: ChannelOwner::CuratorGroup(FIRST_CURATOR_GROUP_ID),
+                    videos: vec![],
+                    playlists: vec![],
+                    series: vec![],
+                    is_censored: false,
+                    reward_account: None,
+                },
+                ChannelCreationParameters {
+                    assets: vec![],
+                    meta: vec![],
+                    reward_account: None,
+                }
+            ))
+        );
+
+        // Curator can update channel
+        assert_ok!(Content::update_channel(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(FIRST_CURATOR_GROUP_ID, FIRST_CURATOR_ID),
+            channel_id,
+            ChannelUpdateParameters {
+                assets: None,
+                new_meta: None,
+                reward_account: None,
+            }
+        ));
+
+        // Lead can update curator owned channels
+        assert_ok!(Content::update_channel(
+            Origin::signed(LEAD_ORIGIN),
+            ContentActor::Lead,
+            channel_id,
+            ChannelUpdateParameters {
+                assets: None,
+                new_meta: None,
+                reward_account: None,
+            }
+        ));
     })
 }
+
 #[test]
-fn members_can_manage_channels() {
+fn member_owned_channels() {
     with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+
         // Not a member
         assert_err!(
             Content::create_channel(
@@ -130,7 +167,26 @@ fn members_can_manage_channels() {
             }
         ));
 
-        // TODO: assert emitted events...
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCreated(
+                ContentActor::Member(FIRST_MEMBER_ID),
+                channel_id_1,
+                ChannelRecord {
+                    owner: ChannelOwner::Member(FIRST_MEMBER_ID),
+                    videos: vec![],
+                    playlists: vec![],
+                    series: vec![],
+                    is_censored: false,
+                    reward_account: None,
+                },
+                ChannelCreationParameters {
+                    assets: vec![],
+                    meta: vec![],
+                    reward_account: None,
+                }
+            ))
+        );
 
         let channel_id_2 = Content::next_channel_id();
 
@@ -145,7 +201,26 @@ fn members_can_manage_channels() {
             }
         ));
 
-        // TODO: assert emitted events...
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCreated(
+                ContentActor::Member(SECOND_MEMBER_ID),
+                channel_id_2,
+                ChannelRecord {
+                    owner: ChannelOwner::Member(SECOND_MEMBER_ID),
+                    videos: vec![],
+                    playlists: vec![],
+                    series: vec![],
+                    is_censored: false,
+                    reward_account: None,
+                },
+                ChannelCreationParameters {
+                    assets: vec![],
+                    meta: vec![],
+                    reward_account: None,
+                }
+            ))
+        );
 
         // Update channel
         assert_ok!(Content::update_channel(
@@ -159,7 +234,26 @@ fn members_can_manage_channels() {
             }
         ));
 
-        // TODO: assert emitted events...
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelUpdated(
+                ContentActor::Member(FIRST_MEMBER_ID),
+                channel_id_1,
+                ChannelRecord {
+                    owner: ChannelOwner::Member(FIRST_MEMBER_ID),
+                    videos: vec![],
+                    playlists: vec![],
+                    series: vec![],
+                    is_censored: false,
+                    reward_account: None,
+                },
+                ChannelUpdateParameters {
+                    assets: None,
+                    new_meta: None,
+                    reward_account: None,
+                }
+            ))
+        );
 
         // Member cannot update a channel they do not own
         assert_err!(
@@ -175,7 +269,111 @@ fn members_can_manage_channels() {
             ),
             Error::<Test>::ActorNotAuthorized
         );
+    })
+}
+
+#[test]
+fn channel_censoring() {
+    with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+
+        let channel_id = Content::next_channel_id();
+        assert_ok!(Content::create_channel(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
+            ContentActor::Member(FIRST_MEMBER_ID),
+            ChannelCreationParameters {
+                assets: vec![],
+                meta: vec![],
+                reward_account: None,
+            }
+        ));
+
+        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
+
+        // Curator can censor channels
+        assert_ok!(Content::censor_channel(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            channel_id,
+            vec![]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelCensored(
+                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                channel_id,
+                vec![]
+            ))
+        );
+
+        let channel = Content::channel_by_id(channel_id);
+
+        assert!(channel.is_censored);
+
+        // Curator can un-censor channels
+        assert_ok!(Content::uncensor_channel(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            channel_id,
+            vec![]
+        ));
 
-        // TODO: assert emitted events...
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::ChannelUncensored(
+                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                channel_id,
+                vec![]
+            ))
+        );
+
+        let channel = Content::channel_by_id(channel_id);
+
+        assert!(!channel.is_censored);
+
+        // Member cannot censor channels
+        assert_err!(
+            Content::censor_channel(
+                Origin::signed(FIRST_MEMBER_ORIGIN),
+                ContentActor::Member(FIRST_MEMBER_ID),
+                channel_id,
+                vec![]
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+
+        let curator_channel_id = Content::next_channel_id();
+
+        // create curator channel
+        assert_ok!(Content::create_channel(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            ChannelCreationParameters {
+                assets: vec![],
+                meta: vec![],
+                reward_account: None,
+            }
+        ));
+
+        // Curator cannot censor curator group channels
+        assert_err!(
+            Content::censor_channel(
+                Origin::signed(FIRST_CURATOR_ORIGIN),
+                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                curator_channel_id,
+                vec![]
+            ),
+            Error::<Test>::CannotCensoreCuratorGroupOwnedChannels
+        );
+
+        // Lead can still censor curator group channels
+        assert_ok!(Content::censor_channel(
+            Origin::signed(LEAD_ORIGIN),
+            ContentActor::Lead,
+            curator_channel_id,
+            vec![]
+        ));
     })
 }

+ 131 - 0
runtime-modules/content/src/tests/curators.rs

@@ -0,0 +1,131 @@
+#![cfg(test)]
+
+use super::mock::*;
+use crate::*;
+use frame_support::{assert_err, assert_ok};
+
+pub fn add_curator_to_new_group(curator_id: CuratorId) -> CuratorGroupId {
+    let curator_group_id = Content::next_curator_group_id();
+    // create new group and add curator id to it
+    assert_ok!(Content::create_curator_group(Origin::signed(LEAD_ORIGIN)));
+    assert_ok!(Content::add_curator_to_group(
+        Origin::signed(LEAD_ORIGIN),
+        curator_group_id,
+        curator_id
+    ));
+    // make group active
+    assert_ok!(Content::set_curator_group_status(
+        Origin::signed(LEAD_ORIGIN),
+        curator_group_id,
+        true
+    ));
+    curator_group_id
+}
+
+#[test]
+fn curator_group_management() {
+    with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+
+        let curator_group_id = Content::next_curator_group_id();
+        assert_ok!(Content::create_curator_group(Origin::signed(LEAD_ORIGIN)));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::CuratorGroupCreated(curator_group_id))
+        );
+
+        let group = Content::curator_group_by_id(curator_group_id);
+
+        // By default group is empty and not active
+        assert_eq!(group.is_active(), false);
+        assert_eq!(group.get_curators().len(), 0);
+
+        // Activate group
+        assert_ok!(Content::set_curator_group_status(
+            Origin::signed(LEAD_ORIGIN),
+            curator_group_id,
+            true
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::CuratorGroupStatusSet(curator_group_id, true))
+        );
+
+        let group = Content::curator_group_by_id(curator_group_id);
+        assert_eq!(group.is_active(), true);
+
+        // Cannot add non curators into group
+        assert_err!(
+            Content::add_curator_to_group(
+                Origin::signed(LEAD_ORIGIN),
+                curator_group_id,
+                MEMBERS_COUNT + 1 // not a curator
+            ),
+            Error::<Test>::CuratorIdInvalid
+        );
+
+        // Add curator to group
+        assert_ok!(Content::add_curator_to_group(
+            Origin::signed(LEAD_ORIGIN),
+            curator_group_id,
+            FIRST_CURATOR_ID
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::CuratorAdded(curator_group_id, FIRST_CURATOR_ID))
+        );
+
+        // Ensure curator is in group
+        let group = Content::curator_group_by_id(curator_group_id);
+        assert!(group.has_curator(&FIRST_CURATOR_ID));
+
+        // Cannot add same curator again
+        assert_err!(
+            Content::add_curator_to_group(
+                Origin::signed(LEAD_ORIGIN),
+                curator_group_id,
+                FIRST_CURATOR_ID
+            ),
+            Error::<Test>::CuratorIsAlreadyAMemberOfGivenCuratorGroup
+        );
+
+        // Cannot remove curator if not in group
+        assert_err!(
+            Content::remove_curator_from_group(
+                Origin::signed(LEAD_ORIGIN),
+                curator_group_id,
+                MEMBERS_COUNT + 1 // not a curator
+            ),
+            Error::<Test>::CuratorIsNotAMemberOfGivenCuratorGroup
+        );
+
+        // Remove curator from group
+        assert_ok!(Content::remove_curator_from_group(
+            Origin::signed(LEAD_ORIGIN),
+            curator_group_id,
+            FIRST_CURATOR_ID
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::CuratorRemoved(curator_group_id, FIRST_CURATOR_ID))
+        );
+
+        let group = Content::curator_group_by_id(curator_group_id);
+        assert!(!group.has_curator(&FIRST_CURATOR_ID));
+
+        // Already removed cannot remove again
+        assert_err!(
+            Content::remove_curator_from_group(
+                Origin::signed(LEAD_ORIGIN),
+                curator_group_id,
+                FIRST_CURATOR_ID
+            ),
+            Error::<Test>::CuratorIsNotAMemberOfGivenCuratorGroup
+        );
+    })
+}

+ 12 - 3
runtime-modules/content/src/tests/mock.rs

@@ -2,8 +2,7 @@
 
 use crate::*;
 
-// use frame_support::storage::StorageMap;
-// use frame_support::traits::{OnFinalize, OnInitialize};
+use frame_support::traits::{OnFinalize, OnInitialize};
 use frame_support::{impl_outer_event, impl_outer_origin, parameter_types};
 use sp_core::H256;
 use sp_runtime::{
@@ -20,7 +19,7 @@ use common::storage::StorageSystem;
 pub type CuratorId = <Test as ContentActorAuthenticator>::CuratorId;
 pub type CuratorGroupId = <Test as ContentActorAuthenticator>::CuratorGroupId;
 pub type MemberId = <Test as MembershipTypes>::MemberId;
-// pub type ChannelId = <Test as StorageOwnership>::ChannelId;
+pub type ChannelId = <Test as StorageOwnership>::ChannelId;
 // pub type DAOId = <Test as StorageOwnership>::DAOId;
 
 /// Origins
@@ -294,3 +293,13 @@ impl ExtBuilder {
 pub fn with_default_mock_builder<R, F: FnOnce() -> R>(f: F) -> R {
     ExtBuilder::default().build().execute_with(|| f())
 }
+
+// Recommendation from Parity on testing on_finalize
+// https://substrate.dev/docs/en/next/development/module/tests
+pub fn run_to_block(n: u64) {
+    while System::block_number() < n {
+        <System as OnFinalize<u64>>::on_finalize(System::block_number());
+        System::set_block_number(System::block_number() + 1);
+        <System as OnInitialize<u64>>::on_initialize(System::block_number());
+    }
+}

+ 2 - 0
runtime-modules/content/src/tests/mod.rs

@@ -1,4 +1,6 @@
 #![cfg(test)]
 
 mod channels;
+mod curators;
 mod mock;
+mod videos;

+ 247 - 0
runtime-modules/content/src/tests/videos.rs

@@ -0,0 +1,247 @@
+#![cfg(test)]
+
+use super::curators;
+use super::mock::*;
+use crate::*;
+use frame_support::{assert_err, assert_ok};
+
+fn create_member_channel() -> ChannelId {
+    let channel_id = Content::next_channel_id();
+
+    // Member can create the channel
+    assert_ok!(Content::create_channel(
+        Origin::signed(FIRST_MEMBER_ORIGIN),
+        ContentActor::Member(FIRST_MEMBER_ID),
+        ChannelCreationParameters {
+            assets: vec![],
+            meta: vec![],
+            reward_account: None,
+        }
+    ));
+
+    channel_id
+}
+
+#[test]
+fn member_can_create_videos() {
+    with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+        let channel_id = create_member_channel();
+
+        let video_id = Content::next_video_id();
+        assert_ok!(Content::create_video(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
+            ContentActor::Member(FIRST_MEMBER_ID),
+            channel_id,
+            VideoCreationParameters {
+                assets: vec![NewAsset::Urls(vec![b"https://somewhere.com/".to_vec()])],
+                meta: b"metablob".to_vec(),
+            }
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::VideoCreated(
+                ContentActor::Member(FIRST_MEMBER_ID),
+                channel_id,
+                video_id,
+                VideoCreationParameters {
+                    assets: vec![NewAsset::Urls(vec![b"https://somewhere.com/".to_vec()])],
+                    meta: b"metablob".to_vec(),
+                }
+            ))
+        );
+
+        // Video is created in correct channel
+        let video = Content::video_by_id(video_id);
+        assert_eq!(channel_id, video.in_channel);
+
+        // Can update own video
+        assert_ok!(Content::update_video(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
+            ContentActor::Member(FIRST_MEMBER_ID),
+            video_id,
+            VideoUpdateParameters {
+                assets: Some(vec![NewAsset::Urls(vec![
+                    b"https://somewhere-else.com/".to_vec()
+                ])]),
+                new_meta: Some(b"newmetablob".to_vec()),
+            }
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::VideoUpdated(
+                ContentActor::Member(FIRST_MEMBER_ID),
+                video_id,
+                VideoUpdateParameters {
+                    assets: Some(vec![NewAsset::Urls(vec![
+                        b"https://somewhere-else.com/".to_vec()
+                    ])]),
+                    new_meta: Some(b"newmetablob".to_vec()),
+                }
+            ))
+        );
+
+        // Member cannot create video in a channel they do not own
+        assert_err!(
+            Content::create_video(
+                Origin::signed(SECOND_MEMBER_ORIGIN),
+                ContentActor::Member(SECOND_MEMBER_ID),
+                channel_id,
+                VideoCreationParameters {
+                    assets: vec![],
+                    meta: vec![],
+                }
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+
+        // Member cannot update video in a channel they do not own
+        assert_err!(
+            Content::update_video(
+                Origin::signed(SECOND_MEMBER_ORIGIN),
+                ContentActor::Member(SECOND_MEMBER_ID),
+                video_id,
+                VideoUpdateParameters {
+                    assets: None,
+                    new_meta: None,
+                }
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+
+        // Member cannot delete video in a channel they do not own
+        assert_err!(
+            Content::delete_video(
+                Origin::signed(SECOND_MEMBER_ORIGIN),
+                ContentActor::Member(SECOND_MEMBER_ID),
+                video_id
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+
+        // Owner can delete their video
+        assert_ok!(Content::delete_video(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
+            ContentActor::Member(FIRST_MEMBER_ID),
+            video_id
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::VideoDeleted(
+                ContentActor::Member(FIRST_MEMBER_ID),
+                video_id
+            ))
+        );
+    })
+}
+
+#[test]
+fn curators_can_censor_videos() {
+    with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+        let channel_id = create_member_channel();
+
+        let video_id = Content::next_video_id();
+        assert_ok!(Content::create_video(
+            Origin::signed(FIRST_MEMBER_ORIGIN),
+            ContentActor::Member(FIRST_MEMBER_ID),
+            channel_id,
+            VideoCreationParameters {
+                assets: vec![NewAsset::Urls(vec![b"https://somewhere.com/".to_vec()])],
+                meta: b"metablob".to_vec(),
+            }
+        ));
+
+        let group_id = curators::add_curator_to_new_group(FIRST_CURATOR_ID);
+
+        // Curator can censor videos
+        assert_ok!(Content::censor_video(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            video_id,
+            vec![]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::VideoCensored(
+                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                video_id,
+                vec![]
+            ))
+        );
+
+        let video = Content::video_by_id(video_id);
+
+        assert!(video.is_censored);
+
+        // Curator can un-censor videos
+        assert_ok!(Content::uncensor_video(
+            Origin::signed(FIRST_CURATOR_ORIGIN),
+            ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+            video_id,
+            vec![]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::VideoUncensored(
+                ContentActor::Curator(group_id, FIRST_CURATOR_ID),
+                video_id,
+                vec![]
+            ))
+        );
+
+        let video = Content::video_by_id(video_id);
+
+        assert!(!video.is_censored);
+
+        // Members cannot censor videos
+        assert_err!(
+            Content::censor_video(
+                Origin::signed(FIRST_MEMBER_ORIGIN),
+                ContentActor::Member(FIRST_MEMBER_ORIGIN),
+                channel_id,
+                vec![]
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+    })
+}
+
+#[test]
+fn featured_videos() {
+    with_default_mock_builder(|| {
+        // Run to block one to see emitted events
+        run_to_block(1);
+
+        // Lead can update curator owned channels
+        assert_ok!(Content::set_featured_videos(
+            Origin::signed(LEAD_ORIGIN),
+            ContentActor::Lead,
+            vec![1, 2, 3]
+        ));
+
+        assert_eq!(
+            System::events().last().unwrap().event,
+            MetaEvent::content(RawEvent::FeaturedVideosSet(
+                ContentActor::Lead,
+                vec![1, 2, 3]
+            ))
+        );
+
+        assert_err!(
+            Content::set_featured_videos(
+                Origin::signed(FIRST_MEMBER_ORIGIN),
+                ContentActor::Member(FIRST_MEMBER_ID),
+                vec![1, 2, 3]
+            ),
+            Error::<Test>::ActorNotAuthorized
+        );
+    })
+}

+ 2 - 2
runtime-modules/proposals/codex/src/lib.rs

@@ -85,13 +85,13 @@ const WORKING_GROUP_MINT_CAPACITY_MAX_VALUE: u32 = 5_000_000;
 // Max allowed value for 'spending' proposal
 const MAX_SPENDING_PROPOSAL_VALUE: u32 = 5_000_000_u32;
 // Max validator count for the 'set validator count' proposal
-const MAX_VALIDATOR_COUNT: u32 = 100;
+const MAX_VALIDATOR_COUNT: u32 = 300;
 // council_size min value for the 'set election parameters' proposal
 const ELECTION_PARAMETERS_COUNCIL_SIZE_MIN_VALUE: u32 = 4;
 // council_size max value for the 'set election parameters' proposal
 const ELECTION_PARAMETERS_COUNCIL_SIZE_MAX_VALUE: u32 = 20;
 // candidacy_limit min value for the 'set election parameters' proposal
-const ELECTION_PARAMETERS_CANDIDACY_LIMIT_MIN_VALUE: u32 = 25;
+const ELECTION_PARAMETERS_CANDIDACY_LIMIT_MIN_VALUE: u32 = 50;
 // candidacy_limit max value for the 'set election parameters' proposal
 const ELECTION_PARAMETERS_CANDIDACY_LIMIT_MAX_VALUE: u32 = 100;
 // min_voting_stake min value for the 'set election parameters' proposal

+ 1 - 1
runtime-modules/proposals/codex/src/proposal_types/mod.rs

@@ -317,7 +317,7 @@ impl Default for ProposalsConfigParameters {
             set_validator_count_proposal_voting_period: 43200u32,
             set_validator_count_proposal_grace_period: 0u32,
             runtime_upgrade_proposal_voting_period: 72000u32,
-            runtime_upgrade_proposal_grace_period: 72000u32,
+            runtime_upgrade_proposal_grace_period: 28800u32,
             text_proposal_voting_period: 72000u32,
             text_proposal_grace_period: 0u32,
             set_election_parameters_proposal_voting_period: 72000u32,

+ 3 - 3
runtime-modules/proposals/codex/src/proposal_types/parameters.rs

@@ -10,7 +10,7 @@ pub(crate) fn set_validator_count_proposal<T: crate::Trait>(
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
         slashing_threshold_percentage: 80,
-        required_stake: Some(<BalanceOf<T>>::from(100_000_u32)),
+        required_stake: Some(<BalanceOf<T>>::from(500_000_u32)),
     }
 }
 
@@ -24,7 +24,7 @@ pub(crate) fn runtime_upgrade_proposal<T: crate::Trait>(
         approval_threshold_percentage: 100,
         slashing_quorum_percentage: 60,
         slashing_threshold_percentage: 80,
-        required_stake: Some(<BalanceOf<T>>::from(1_000_000_u32)),
+        required_stake: Some(<BalanceOf<T>>::from(5_000_000_u32)),
     }
 }
 
@@ -51,7 +51,7 @@ pub(crate) fn set_election_parameters_proposal<T: crate::Trait>(
         approval_threshold_percentage: 80,
         slashing_quorum_percentage: 60,
         slashing_threshold_percentage: 80,
-        required_stake: Some(<BalanceOf<T>>::from(200_000_u32)),
+        required_stake: Some(<BalanceOf<T>>::from(1_000_000_u32)),
     }
 }
 

+ 8 - 8
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -187,7 +187,7 @@ fn create_text_proposal_codex_call_fails_with_incorrect_text_size() {
 #[test]
 fn create_runtime_upgrade_common_checks_succeed() {
     initial_test_ext().execute_with(|| {
-        increase_total_balance_issuance_using_account_id(1, 5000000);
+        increase_total_balance_issuance_using_account_id(1, 10000000);
 
         let proposal_fixture = ProposalTestFixture {
             insufficient_rights_call: || {
@@ -226,7 +226,7 @@ fn create_runtime_upgrade_common_checks_succeed() {
                     1,
                     b"title".to_vec(),
                     b"body".to_vec(),
-                    Some(<BalanceOf<Test>>::from(1_000_000_u32)),
+                    Some(<BalanceOf<Test>>::from(5_000_000_u32)),
                     b"wasm".to_vec(),
                 )
             },
@@ -272,7 +272,7 @@ fn create_upgrade_runtime_proposal_codex_call_fails_with_incorrect_wasm_size() {
 #[test]
 fn create_set_election_parameters_proposal_common_checks_succeed() {
     initial_test_ext().execute_with(|| {
-        increase_total_balance_issuance_using_account_id(1, 500000);
+        increase_total_balance_issuance_using_account_id(1, 2000000);
 
         let proposal_fixture = ProposalTestFixture {
             insufficient_rights_call: || {
@@ -311,7 +311,7 @@ fn create_set_election_parameters_proposal_common_checks_succeed() {
                     1,
                     b"title".to_vec(),
                     b"body".to_vec(),
-                    Some(<BalanceOf<Test>>::from(200_000_u32)),
+                    Some(<BalanceOf<Test>>::from(1_000_000_u32)),
                     get_valid_election_parameters(),
                 )
             },
@@ -348,7 +348,7 @@ fn get_valid_election_parameters() -> ElectionParameters<u64, u64> {
         voting_period: 14400,
         revealing_period: 14400,
         council_size: 4,
-        candidacy_limit: 25,
+        candidacy_limit: 50,
         new_term_duration: 14400,
         min_council_stake: 1,
         min_voting_stake: 1,
@@ -358,7 +358,7 @@ fn get_valid_election_parameters() -> ElectionParameters<u64, u64> {
 #[test]
 fn create_set_election_parameters_call_fails_with_incorrect_parameters() {
     initial_test_ext().execute_with(|| {
-        increase_total_balance_issuance_using_account_id(1, 500000);
+        increase_total_balance_issuance_using_account_id(1, 1500000);
 
         let mut election_parameters = get_valid_election_parameters();
         election_parameters.council_size = 2;
@@ -566,7 +566,7 @@ fn create_spending_proposal_call_fails_with_incorrect_balance() {
 #[test]
 fn create_set_validator_count_proposal_common_checks_succeed() {
     initial_test_ext().execute_with(|| {
-        increase_total_balance_issuance_using_account_id(1, 500000);
+        increase_total_balance_issuance_using_account_id(1, 1000000);
 
         let proposal_fixture = ProposalTestFixture {
             insufficient_rights_call: || {
@@ -605,7 +605,7 @@ fn create_set_validator_count_proposal_common_checks_succeed() {
                     1,
                     b"title".to_vec(),
                     b"body".to_vec(),
-                    Some(<BalanceOf<Test>>::from(100_000_u32)),
+                    Some(<BalanceOf<Test>>::from(500_000_u32)),
                     4,
                 )
             },

+ 9 - 4
runtime-modules/storage/src/data_directory.rs

@@ -39,10 +39,15 @@ use crate::data_object_type_registry;
 use crate::data_object_type_registry::IsActiveDataObjectType;
 use crate::*;
 
-pub const DEFAULT_VOUCHER_SIZE_LIMIT_UPPER_BOUND: u64 = 100000000;
-pub const DEFAULT_VOUCHER_OBJECTS_LIMIT_UPPER_BOUND: u64 = 200;
-pub const DEFAULT_GLOBAL_VOUCHER: Voucher = Voucher::new(200000000, 2000);
-pub const DEFAULT_VOUCHER: Voucher = Voucher::new(5000000, 100);
+/// The default maximum storage size (bytes) that lead can set on the voucher of an owner
+pub const DEFAULT_VOUCHER_SIZE_LIMIT_UPPER_BOUND: u64 = 54_000_000_000;
+/// The default maximum number of objects that lead can set on the voucher of an owner
+pub const DEFAULT_VOUCHER_OBJECTS_LIMIT_UPPER_BOUND: u64 = 10_000;
+/// The default system global storage limits
+pub const DEFAULT_GLOBAL_VOUCHER: Voucher = Voucher::new(1_100_000_000_000, 1_000_000);
+/// The default initial owner voucher
+pub const DEFAULT_VOUCHER: Voucher = Voucher::new(5_400_000_000, 1_000);
+/// The default starting upload blocked status
 pub const DEFAULT_UPLOADING_BLOCKED_STATUS: bool = false;
 
 /// The _Data directory_ main _Trait_.

+ 1 - 1
runtime/Cargo.toml

@@ -4,7 +4,7 @@ edition = '2018'
 name = 'joystream-node-runtime'
 # Follow convention: https://github.com/Joystream/substrate-runtime-joystream/issues/1
 # {Authoring}.{Spec}.{Impl} of the RuntimeVersion
-version = '7.14.0'
+version = '7.15.0'
 
 [dependencies]
 # Third-party dependencies

+ 1 - 1
runtime/src/constants.rs

@@ -18,7 +18,7 @@ pub const MILLISECS_PER_BLOCK: Moment = 6000;
 pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000;
 
 pub const SLOT_DURATION: Moment = 6000;
-pub const BONDING_DURATION: u32 = 24;
+pub const BONDING_DURATION: u32 = 24 * 7;
 
 pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
 pub const EPOCH_DURATION_IN_SLOTS: u64 = {

+ 2 - 2
runtime/src/lib.rs

@@ -71,7 +71,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
     spec_name: create_runtime_str!("joystream-node"),
     impl_name: create_runtime_str!("joystream-node"),
     authoring_version: 7,
-    spec_version: 14,
+    spec_version: 15,
     impl_version: 0,
     apis: crate::runtime_api::EXPORTED_RUNTIME_API_VERSIONS,
     transaction_version: 1,
@@ -538,7 +538,7 @@ parameter_types! {
     pub const ProposalRejectionFee: u64 = 5000;
     pub const ProposalTitleMaxLength: u32 = 40;
     pub const ProposalDescriptionMaxLength: u32 = 3000;
-    pub const ProposalMaxActiveProposalLimit: u32 = 5;
+    pub const ProposalMaxActiveProposalLimit: u32 = 20;
 }
 
 impl proposals_engine::Trait for Runtime {

+ 4 - 4
runtime/src/tests/proposals_integration/mod.rs

@@ -513,7 +513,7 @@ where
             setup_members(NUMBER_OF_MEMBERS_TO_SETUP_IN_CODEX_PROPOSAL_FIXTURE);
             setup_council();
 
-            increase_total_balance_issuance_using_account_id(account_id.clone().into(), 500000);
+            increase_total_balance_issuance_using_account_id(account_id.clone().into(), 1000000);
         }
 
         assert_eq!((self.successful_call)(), Ok(()));
@@ -620,7 +620,7 @@ fn set_election_parameters_proposal_execution_succeeds() {
             voting_period: 14400,
             revealing_period: 14400,
             council_size: 4,
-            candidacy_limit: 25,
+            candidacy_limit: 50,
             new_term_duration: 14400,
             min_council_stake: 1,
             min_voting_stake: 1,
@@ -633,7 +633,7 @@ fn set_election_parameters_proposal_execution_succeeds() {
                 member_id as u64,
                 b"title".to_vec(),
                 b"body".to_vec(),
-                Some(<BalanceOf<Runtime>>::from(200_000_u32)),
+                Some(<BalanceOf<Runtime>>::from(1_000_000_u32)),
                 election_parameters,
             )
         });
@@ -658,7 +658,7 @@ fn set_validator_count_proposal_execution_succeeds() {
                 member_id as u64,
                 b"title".to_vec(),
                 b"body".to_vec(),
-                Some(<BalanceOf<Runtime>>::from(100_000_u32)),
+                Some(<BalanceOf<Runtime>>::from(500_000_u32)),
                 new_validator_count,
             )
         });

+ 4 - 0
testnets/joy-testnet-4.json

@@ -12,6 +12,10 @@
     [
       "/dns/telemetry.polkadot.io/tcp/443/x-parity-wss/%2Fsubmit%2F",
       0
+    ],
+    [
+      "/dns/telemetry.joystream.org/tcp/443/x-parity-wss/%2Fsubmit%2F",
+      0
     ]
   ],
   "protocolId": "/joy/testnet/4",

+ 16 - 12
tests/network-tests/src/fixtures/proposalsModule.ts

@@ -415,7 +415,7 @@ export class ElectionParametersProposalFixture extends BaseFixture {
   public async execute(): Promise<void> {
     // Setup
     const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8)
-    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
+    const description: string = 'Testing Election Parameters proposal ' + uuid().substring(0, 8)
 
     const announcingPeriod: BN = new BN(28800)
     const votingPeriod: BN = new BN(14400)
@@ -428,7 +428,7 @@ export class ElectionParametersProposalFixture extends BaseFixture {
 
     // Proposal stake calculation
     // Required stake is hardcoded in runtime-module (but not available as const)
-    const proposalStake: BN = new BN(200000)
+    const proposalStake: BN = new BN(1000000)
     const proposalFee: BN = this.api.estimateProposeElectionParametersFee(
       description,
       description,
@@ -450,7 +450,9 @@ export class ElectionParametersProposalFixture extends BaseFixture {
     const proposedVotingPeriod: BN = votingPeriod.addn(1)
     const proposedRevealingPeriod: BN = revealingPeriod.addn(1)
     const proposedCouncilSize: BN = councilSize.addn(1)
-    const proposedCandidacyLimit: BN = candidacyLimit.addn(1)
+    const proposedCandidacyLimit: BN = new BN(51) // candidacyLimit.addn(1)
+    // assert they are different
+    assert(!candidacyLimit.eq(proposedCandidacyLimit))
     const proposedNewTermDuration: BN = newTermDuration.addn(1)
     const proposedMinCouncilStake: BN = minCouncilStake.addn(1)
     const proposedMinVotingStake: BN = minVotingStake.addn(1)
@@ -618,12 +620,12 @@ export class TextProposalFixture extends BaseFixture {
 
 export class ValidatorCountProposalFixture extends BaseFixture {
   private proposer: string
-  private validatorCountIncrement: BN
+  private proposedValidatorCount: BN
 
-  constructor(api: Api, proposer: string, validatorCountIncrement: BN) {
+  constructor(api: Api, proposer: string, validatorCount: BN) {
     super(api)
     this.proposer = proposer
-    this.validatorCountIncrement = validatorCountIncrement
+    this.proposedValidatorCount = validatorCount
   }
 
   public async execute(): Promise<void> {
@@ -632,19 +634,21 @@ export class ValidatorCountProposalFixture extends BaseFixture {
     const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8)
 
     // Proposal stake calculation
-    const proposalStake: BN = new BN(100000)
+    const proposalStake: BN = new BN(500000)
     const proposalFee: BN = this.api.estimateProposeValidatorCountFee(description, description, proposalStake)
     this.api.treasuryTransferBalance(this.proposer, proposalFee.add(proposalStake))
-    const validatorCount: BN = await this.api.getValidatorCount()
+    const currentValidatorCount: BN = await this.api.getValidatorCount()
 
     // Proposal creation
-    const proposedValidatorCount: BN = validatorCount.add(this.validatorCountIncrement)
+    // Make sure proposed is different than current to ensure change is applied.
+    assert(!currentValidatorCount.eq(this.proposedValidatorCount))
+
     const result = await this.api.proposeValidatorCount(
       this.proposer,
       proposalTitle,
       description,
       proposalStake,
-      proposedValidatorCount
+      this.proposedValidatorCount
     )
     const proposalNumber: ProposalId = this.api.findProposalCreatedEvent(result.events) as ProposalId
     assert.notEqual(proposalNumber, undefined)
@@ -656,8 +660,8 @@ export class ValidatorCountProposalFixture extends BaseFixture {
 
     const newValidatorCount: BN = await this.api.getValidatorCount()
     assert(
-      proposedValidatorCount.eq(newValidatorCount),
-      `Validator count has unexpeccted value ${newValidatorCount}, expected ${proposedValidatorCount}`
+      this.proposedValidatorCount.eq(newValidatorCount),
+      `Validator count has unexpeccted value ${newValidatorCount}, expected ${this.proposedValidatorCount}`
     )
   }
 }

+ 3 - 4
tests/network-tests/src/flows/proposals/validatorCountProposal.ts

@@ -6,7 +6,7 @@ import { FixtureRunner } from '../../Fixture'
 import Debugger from 'debug'
 import { Resource } from '../../Resources'
 
-export default async function validatorCount({ api, env, lock }: FlowProps): Promise<void> {
+export default async function validatorCount({ api, lock }: FlowProps): Promise<void> {
   const debug = Debugger('flow:validatorCountProposal')
   debug('Started')
   await lock(Resource.Proposals)
@@ -16,13 +16,12 @@ export default async function validatorCount({ api, env, lock }: FlowProps): Pro
   assert(council.length)
 
   const proposer = council[0].member.toString()
-
-  const validatorCountIncrement: BN = new BN(+env.VALIDATOR_COUNT_INCREMENT!)
+  const proposedValidatorCount = new BN(300)
 
   const validatorCountProposalFixture: ValidatorCountProposalFixture = new ValidatorCountProposalFixture(
     api,
     proposer,
-    validatorCountIncrement
+    proposedValidatorCount
   )
   await new FixtureRunner(validatorCountProposalFixture).run()
 

+ 20 - 36
yarn.lock

@@ -9118,19 +9118,6 @@ cli-cursor@^3.1.0:
   dependencies:
     restore-cursor "^3.1.0"
 
-<<<<<<< HEAD
-cli-highlight@^2.1.4:
-  version "2.1.4"
-  resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.4.tgz#098cb642cf17f42adc1c1145e07f960ec4d7522b"
-  integrity sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ==
-  dependencies:
-    chalk "^3.0.0"
-    highlight.js "^9.6.0"
-    mz "^2.4.0"
-    parse5 "^5.1.1"
-    parse5-htmlparser2-tree-adapter "^5.1.1"
-    yargs "^15.0.0"
-=======
 cli-highlight@^2.1.10:
   version "2.1.10"
   resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.10.tgz#26a087da9209dce4fcb8cf5427dc97cd96ac173a"
@@ -9142,7 +9129,6 @@ cli-highlight@^2.1.10:
     parse5 "^5.1.1"
     parse5-htmlparser2-tree-adapter "^6.0.0"
     yargs "^16.0.0"
->>>>>>> 61a854817e3fdf569f4e993d854a0ef2b89cad4c
 
 cli-progress@^3.4.0:
   version "3.8.2"
@@ -22247,21 +22233,12 @@ parse-url@^5.0.0:
     parse-path "^4.0.0"
     protocols "^1.4.0"
 
-<<<<<<< HEAD
-parse5-htmlparser2-tree-adapter@^5.1.1:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc"
-  integrity sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw==
-  dependencies:
-    parse5 "^5.1.1"
-=======
 parse5-htmlparser2-tree-adapter@^6.0.0:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
   integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
   dependencies:
     parse5 "^6.0.1"
->>>>>>> 61a854817e3fdf569f4e993d854a0ef2b89cad4c
 
 parse5@4.0.0:
   version "4.0.0"
@@ -22273,6 +22250,11 @@ parse5@5.1.1, parse5@^5.0.0, parse5@^5.1.1:
   resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
   integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
 
+parse5@^6.0.1:
+  version "6.0.1"
+  resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
+  integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
+
 parseurl@^1.3.2, parseurl@^1.3.3, parseurl@~1.3.2, parseurl@~1.3.3:
   version "1.3.3"
   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -28139,27 +28121,16 @@ typeorm-typedi-extensions@^0.2.3:
   resolved "https://registry.yarnpkg.com/typeorm-typedi-extensions/-/typeorm-typedi-extensions-0.2.3.tgz#94fca2656206d771bf6d2242f5aab570511188e8"
   integrity sha512-T9i1NvRZNjPn9Jb8oT772ihfn6PwdqDVpzPCtKSqjkZGOgXrCkdyD3dDrzfMaoWJ1afU58bVx2CMb95FzT42Ow==
 
-<<<<<<< HEAD
-typeorm@^0.2.25:
-  version "0.2.29"
-  resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.29.tgz#401289dc91900d72eccb26e31cdb7f0591a2272e"
-  integrity sha512-ih1vrTe3gEAGKRcWlcsTRxTL7gNjacQE498wVGuJ3ZRujtMqPZlbAWuC7xDzWCRjQnkZYNwZQeG9UgKfxSHB5g==
-=======
 typeorm@^0.2.25, typeorm@^0.2.31:
   version "0.2.31"
   resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.31.tgz#82b8a1b233224f81c738f53b0380386ccf360917"
   integrity sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==
->>>>>>> 61a854817e3fdf569f4e993d854a0ef2b89cad4c
   dependencies:
     "@sqltools/formatter" "1.2.2"
     app-root-path "^3.0.0"
     buffer "^5.5.0"
     chalk "^4.1.0"
-<<<<<<< HEAD
-    cli-highlight "^2.1.4"
-=======
     cli-highlight "^2.1.10"
->>>>>>> 61a854817e3fdf569f4e993d854a0ef2b89cad4c
     debug "^4.1.1"
     dotenv "^8.2.0"
     glob "^7.1.6"
@@ -29904,7 +29875,7 @@ y18n@^3.2.1:
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"
   integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==
 
-y18n@^5.0.2:
+y18n@^5.0.2, y18n@^5.0.5:
   version "5.0.5"
   resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
   integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
@@ -30146,6 +30117,19 @@ yargs@^15.0.1, yargs@^15.3.1, yargs@^15.4.1:
     y18n "^4.0.0"
     yargs-parser "^18.1.2"
 
+yargs@^16.0.0:
+  version "16.2.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
+  integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
+  dependencies:
+    cliui "^7.0.2"
+    escalade "^3.1.1"
+    get-caller-file "^2.0.5"
+    require-directory "^2.1.1"
+    string-width "^4.2.0"
+    y18n "^5.0.5"
+    yargs-parser "^20.2.2"
+
 yargs@^16.0.3:
   version "16.1.0"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.1.0.tgz#fc333fe4791660eace5a894b39d42f851cd48f2a"
@@ -30242,4 +30226,4 @@ zen-observable@^0.8.0, zen-observable@^0.8.14:
 zepto@^1.2.0:
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/zepto/-/zepto-1.2.0.tgz#e127bd9e66fd846be5eab48c1394882f7c0e4f98"
-  integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=
+  integrity sha1-4Se9nmb9hGvl6rSME5SIL3wOT5g=

Some files were not shown because too many files changed in this diff