Bladeren bron

Merge pull request #2638 from Lezek123/giza-protobuf-and-query-node

Update protobuf library and mappings for Giza
shamil-gadelshin 3 jaren geleden
bovenliggende
commit
0b5c3f74dd
91 gewijzigde bestanden met toevoegingen van 2610 en 9892 verwijderingen
  1. 0 28
      .github/workflows/content-metadata.yml
  2. 2 2
      .github/workflows/joystream-cli.yml
  3. 22 0
      .github/workflows/metadata-protobuf.yml
  4. 1 1
      .github/workflows/run-network-tests.yml
  5. 1 1
      build-npm-packages.sh
  6. 1 1
      cli/package.json
  7. 0 4
      content-metadata-protobuf/.eslintignore
  8. 0 16
      content-metadata-protobuf/.eslintrc.js
  9. 0 2
      content-metadata-protobuf/.gitignore
  10. 0 4
      content-metadata-protobuf/.prettierignore
  11. 0 53
      content-metadata-protobuf/README.md
  12. 0 15
      content-metadata-protobuf/compile.sh
  13. 0 85
      content-metadata-protobuf/compiled/proto/Channel_pb.d.ts
  14. 0 646
      content-metadata-protobuf/compiled/proto/Channel_pb.js
  15. 0 57
      content-metadata-protobuf/compiled/proto/Person_pb.d.ts
  16. 0 428
      content-metadata-protobuf/compiled/proto/Person_pb.js
  17. 0 33
      content-metadata-protobuf/compiled/proto/Playlist_pb.d.ts
  18. 0 246
      content-metadata-protobuf/compiled/proto/Playlist_pb.js
  19. 0 85
      content-metadata-protobuf/compiled/proto/Series_pb.d.ts
  20. 0 666
      content-metadata-protobuf/compiled/proto/Series_pb.js
  21. 0 235
      content-metadata-protobuf/compiled/proto/Video_pb.d.ts
  22. 0 1847
      content-metadata-protobuf/compiled/proto/Video_pb.js
  23. 0 374
      content-metadata-protobuf/doc/index.md
  24. 0 13
      content-metadata-protobuf/generate-md-doc.sh
  25. 0 47
      content-metadata-protobuf/package.json
  26. 0 10
      content-metadata-protobuf/src/index.ts
  27. 0 33
      content-metadata-protobuf/test/channel.ts
  28. 0 115
      content-metadata-protobuf/test/video.ts
  29. 0 15
      content-metadata-protobuf/tsconfig.json
  30. 1 0
      metadata-protobuf/.gitignore
  31. 5 7
      metadata-protobuf/README.md
  32. 0 16
      metadata-protobuf/compile.sh
  33. 0 505
      metadata-protobuf/compiled/index.d.ts
  34. 0 1187
      metadata-protobuf/compiled/index.js
  35. 0 0
      metadata-protobuf/doc-appendix.md
  36. 389 6
      metadata-protobuf/doc/index.md
  37. 3 0
      metadata-protobuf/generate-md-doc.sh
  38. 6 2
      metadata-protobuf/package.json
  39. 0 0
      metadata-protobuf/proto/Channel.proto
  40. 0 0
      metadata-protobuf/proto/Person.proto
  41. 0 0
      metadata-protobuf/proto/Playlist.proto
  42. 0 0
      metadata-protobuf/proto/Series.proto
  43. 19 1
      metadata-protobuf/proto/Storage.proto
  44. 0 0
      metadata-protobuf/proto/Video.proto
  45. 4 0
      metadata-protobuf/scripts/compile.ts
  46. 0 0
      metadata-protobuf/src/KnownLicenses.json
  47. 4 10
      metadata-protobuf/src/licenses.ts
  48. 13 1
      metadata-protobuf/src/utils.ts
  49. 31 0
      metadata-protobuf/test/channel.ts
  50. 14 8
      metadata-protobuf/test/license-codes.ts
  51. 87 0
      metadata-protobuf/test/video.ts
  52. 0 1
      package.json
  53. 135 202
      query-node/manifest.yml
  54. 96 98
      query-node/mappings/common.ts
  55. 221 0
      query-node/mappings/content/channel.ts
  56. 25 26
      query-node/mappings/content/curatorGroup.ts
  57. 0 0
      query-node/mappings/content/index.ts
  58. 527 0
      query-node/mappings/content/utils.ts
  59. 271 0
      query-node/mappings/content/video.ts
  60. 8 0
      query-node/mappings/genesis-data/index.ts
  61. 0 0
      query-node/mappings/genesis-data/members.json
  62. 2 1
      query-node/mappings/genesis-data/storageSystem.json
  63. 20 0
      query-node/mappings/genesis-data/types.ts
  64. 35 0
      query-node/mappings/genesis.ts
  65. 0 63
      query-node/mappings/giza/common.ts
  66. 0 3
      query-node/mappings/giza/genesis-data/index.ts
  67. 0 16
      query-node/mappings/giza/genesis.ts
  68. 0 2
      query-node/mappings/giza/index.ts
  69. 3 2
      query-node/mappings/index.ts
  70. 37 45
      query-node/mappings/membership.ts
  71. 1 1
      query-node/mappings/package.json
  72. 43 179
      query-node/mappings/storage/index.ts
  73. 65 16
      query-node/mappings/storage/metadata.ts
  74. 237 0
      query-node/mappings/storage/utils.ts
  75. 0 1
      query-node/mappings/sumer/bootstrap/data/workers.json
  76. 0 69
      query-node/mappings/sumer/bootstrap/index.ts
  77. 0 42
      query-node/mappings/sumer/bootstrap/members.ts
  78. 0 48
      query-node/mappings/sumer/bootstrap/workers.ts
  79. 0 279
      query-node/mappings/sumer/content/channel.ts
  80. 0 773
      query-node/mappings/sumer/content/utils.ts
  81. 0 498
      query-node/mappings/sumer/content/video.ts
  82. 0 6
      query-node/mappings/sumer/eventFix.ts
  83. 0 280
      query-node/mappings/sumer/storage.ts
  84. 0 237
      query-node/mappings/sumer/workingGroup.ts
  85. 1 1
      query-node/mappings/tsconfig.json
  86. 156 0
      query-node/mappings/workingGroup.ts
  87. 13 182
      query-node/schemas/content.graphql
  88. 80 4
      query-node/schemas/storage.graphql
  89. 17 0
      query-node/schemas/workingGroups.graphql
  90. 0 0
      types/augment-codec/all.ts
  91. 14 12
      yarn.lock

+ 0 - 28
.github/workflows/content-metadata.yml

@@ -1,28 +0,0 @@
-name: content-metadata
-on: [pull_request, push]
-
-jobs:
-  schemas_checks:
-    name: Checks
-    runs-on: ubuntu-latest
-    strategy:
-      matrix:
-        node-version: [14.x]
-    steps:
-    - uses: actions/checkout@v1
-    - name: Use Node.js ${{ matrix.node-version }}
-      uses: actions/setup-node@v1
-      with:
-        node-version: ${{ matrix.node-version }}
-    - name: test protobuf
-      run: |
-        # # Install protoc compiler
-        # sudo apt-get install -y protobuf-compiler
-        # protoc --version
-        # # Install documentation plugin
-        # sudo apt-get install -y golang-go
-        # go get -u github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
-        yarn install --frozen-lockfile
-        yarn workspace @joystream/content-metadata-protobuf build:ts
-        yarn workspace @joystream/content-metadata-protobuf checks --quiet
-        yarn workspace @joystream/content-metadata-protobuf test

+ 2 - 2
.github/workflows/joystream-cli.yml

@@ -18,7 +18,7 @@ jobs:
       run: |
         yarn install --frozen-lockfile
         yarn workspace @joystream/types build
-        yarn workspace @joystream/content-metadata-protobuf build:ts
+        yarn workspace @joystream/metadata-protobuf build
         yarn workspace @joystream/cli checks --quiet
     - name: yarn pack test
       run: |
@@ -42,7 +42,7 @@ jobs:
       run: |
         yarn install --frozen-lockfile --network-timeout 120000
         yarn workspace @joystream/types build
-        yarn workspace @joystream/content-metadata-protobuf build:ts
+        yarn workspace @joystream/metadata-protobuf build
         yarn workspace @joystream/cli checks --quiet
     - name: yarn pack test
       run: |

+ 22 - 0
.github/workflows/metadata-protobuf.yml

@@ -0,0 +1,22 @@
+name: metadata-protobuf
+on: [pull_request, push]
+
+jobs:
+  schemas_checks:
+    name: Checks
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        node-version: [14.x]
+    steps:
+    - uses: actions/checkout@v1
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - name: test protobuf
+      run: |
+        yarn install --frozen-lockfile
+        yarn workspace @joystream/metadata-protobuf build
+        yarn workspace @joystream/metadata-protobuf checks --quiet
+        yarn workspace @joystream/metadata-protobuf test

+ 1 - 1
.github/workflows/run-network-tests.yml

@@ -152,7 +152,7 @@ jobs:
         run: |
           yarn install --frozen-lockfile
           yarn workspace @joystream/types build
-          yarn workspace @joystream/content-metadata-protobuf build:ts
+          yarn workspace @joystream/metadata-protobuf build
       - name: Ensure query-node builds
         run: yarn workspace query-node-root build
       - name: Ensure tests are runnable

+ 1 - 1
build-npm-packages.sh

@@ -4,7 +4,7 @@ set -e
 
 yarn
 yarn workspace @joystream/types build
-yarn workspace @joystream/content-metadata-protobuf build:ts
+yarn workspace @joystream/metadata-protobuf build
 yarn workspace query-node-root build
 yarn workspace @joystream/cli build
 yarn workspace storage-node build

+ 1 - 1
cli/package.json

@@ -10,7 +10,7 @@
   "dependencies": {
     "@apidevtools/json-schema-ref-parser": "^9.0.6",
     "@ffprobe-installer/ffprobe": "^1.1.0",
-    "@joystream/content-metadata-protobuf": "^1.1.0",
+    "@joystream/metadata-protobuf": "^1.0.0",
     "@joystream/types": "^0.16.1",
     "@oclif/command": "^1.5.19",
     "@oclif/config": "^1.14.0",

+ 0 - 4
content-metadata-protobuf/.eslintignore

@@ -1,4 +0,0 @@
-lib/
-proto/
-compiled/
-.eslintrc.js

+ 0 - 16
content-metadata-protobuf/.eslintrc.js

@@ -1,16 +0,0 @@
-module.exports = {
-  env: {
-    mocha: true,
-  },
-  parserOptions: {
-    project: './tsconfig.json'
-  },
-  extends: [
-    '@joystream/eslint-config'
-  ],
-  rules: {
-    'no-unused-vars': 'off', // Required by the typescript rule below
-    '@typescript-eslint/no-unused-vars': ['error'],
-    '@typescript-eslint/no-floating-promises': 'error',
-  },
-}

+ 0 - 2
content-metadata-protobuf/.gitignore

@@ -1,2 +0,0 @@
-node_modules/
-lib/

+ 0 - 4
content-metadata-protobuf/.prettierignore

@@ -1,4 +0,0 @@
-lib/
-doc/
-proto/
-compiled/

+ 0 - 53
content-metadata-protobuf/README.md

@@ -1,53 +0,0 @@
-## Joystream Content Directory Metadata Library
-
-This package contains protobuf message definitions compiled to Javascript/Typescript used for creating and updating various metadata blobs in the joystream content directory.
-
-### Message Specs
-
-Documented in [doc](./doc) folder
-
-### Choice of protobuf protocol v2
-
-For our usecase we wish to re-use same message to create and update  subset of fields.
-For this reason we need the explicit information about wether a field has been set or not and this is only possible with proto v2.
-
-Background: required/optional feilds are deprecated in [proto v3](https://www.ben-morris.com/handling-protocol-buffers-backwards-compatibility-between-versions-2-and-3-using-c/)
-
-
-### Helper methods
-The custom Joystream types such as License have helper methods to construct pre-defined well known values.
-
-### Example code:
-
-Best place to look at are the [tests specs](./test)
-
-### Opaque types
-We use simple [ISO_639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) code representation for Language.
-useful npm package https://www.npmjs.com/package/iso-639-1
-
-### Building the package
-
-Building will compile the protofiles and build the library from source.
-
-- pre-requisists for compiling protofiles:
-    - [protoc](https://github.com/protocolbuffers/protobuf/releases)
-
-- pre-requisists for generating documentation:
-    - [golang](https://golang.org/)
-    - [protoc-gen-doc](https://github.com/pseudomuto/protoc-gen-doc) to generate docs
-
-```
-yarn && yarn build
-```
-
-### Generating docs
-
-```
-yarn generate-docs
-```
-
-### Tests
-
-```
-yarn test
-```

+ 0 - 15
content-metadata-protobuf/compile.sh

@@ -1,15 +0,0 @@
-#!/usr/bin/env bash
-
-# Path to this plugin
-PROTOC_GEN_TS_PATH="./node_modules/.bin/protoc-gen-ts"
-
-# Directory to write generated code to (.js and .d.ts files)
-OUT_DIR="./compiled"
-mkdir -p ${OUT_DIR}
-
-# Compile proto files
-protoc \
-    --plugin="protoc-gen-ts=${PROTOC_GEN_TS_PATH}" \
-    --js_out="import_style=commonjs,binary:${OUT_DIR}" \
-    --ts_out="${OUT_DIR}" \
-    proto/*.proto

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

@@ -1,85 +0,0 @@
-// package: 
-// file: proto/Channel.proto
-
-import * as jspb from "google-protobuf";
-
-export class ChannelMetadata extends jspb.Message {
-  hasTitle(): boolean;
-  clearTitle(): void;
-  getTitle(): string | undefined;
-  setTitle(value: string): void;
-
-  hasDescription(): boolean;
-  clearDescription(): void;
-  getDescription(): string | undefined;
-  setDescription(value: string): void;
-
-  hasIsPublic(): boolean;
-  clearIsPublic(): void;
-  getIsPublic(): boolean | undefined;
-  setIsPublic(value: boolean): void;
-
-  hasLanguage(): boolean;
-  clearLanguage(): void;
-  getLanguage(): string | undefined;
-  setLanguage(value: string): void;
-
-  hasCoverPhoto(): boolean;
-  clearCoverPhoto(): void;
-  getCoverPhoto(): number | undefined;
-  setCoverPhoto(value: number): void;
-
-  hasAvatarPhoto(): boolean;
-  clearAvatarPhoto(): void;
-  getAvatarPhoto(): number | undefined;
-  setAvatarPhoto(value: number): void;
-
-  hasCategory(): boolean;
-  clearCategory(): void;
-  getCategory(): number | undefined;
-  setCategory(value: number): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): ChannelMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: ChannelMetadata): ChannelMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: ChannelMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): ChannelMetadata;
-  static deserializeBinaryFromReader(message: ChannelMetadata, reader: jspb.BinaryReader): ChannelMetadata;
-}
-
-export namespace ChannelMetadata {
-  export type AsObject = {
-    title?: string,
-    description?: string,
-    isPublic?: boolean,
-    language?: string,
-    coverPhoto?: number,
-    avatarPhoto?: number,
-    category?: number,
-  }
-}
-
-export class ChannelCategoryMetadata extends jspb.Message {
-  hasName(): boolean;
-  clearName(): void;
-  getName(): string | undefined;
-  setName(value: string): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): ChannelCategoryMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: ChannelCategoryMetadata): ChannelCategoryMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: ChannelCategoryMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): ChannelCategoryMetadata;
-  static deserializeBinaryFromReader(message: ChannelCategoryMetadata, reader: jspb.BinaryReader): ChannelCategoryMetadata;
-}
-
-export namespace ChannelCategoryMetadata {
-  export type AsObject = {
-    name?: string,
-  }
-}
-

+ 0 - 646
content-metadata-protobuf/compiled/proto/Channel_pb.js

@@ -1,646 +0,0 @@
-// 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.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
- * 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.ChannelCategoryMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.ChannelCategoryMetadata, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.ChannelCategoryMetadata.displayName = 'proto.ChannelCategoryMetadata';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.ChannelMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.ChannelMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.ChannelMetadata} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.ChannelMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    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) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.ChannelMetadata}
- */
-proto.ChannelMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  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.ChannelMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.ChannelMetadata}
- */
-proto.ChannelMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTitle(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDescription(value);
-      break;
-    case 3:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIsPublic(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLanguage(value);
-      break;
-    case 5:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setCoverPhoto(value);
-      break;
-    case 6:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setAvatarPhoto(value);
-      break;
-    case 7:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.setCategory(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.ChannelMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.ChannelMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.ChannelMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.ChannelMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeBool(
-      3,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeUint32(
-      5,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeUint32(
-      6,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 7));
-  if (f != null) {
-    writer.writeUint64(
-      7,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string title = 1;
- * @return {string}
- */
-proto.ChannelMetadata.prototype.getTitle = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setTitle = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasTitle = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string description = 2;
- * @return {string}
- */
-proto.ChannelMetadata.prototype.getDescription = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setDescription = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasDescription = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional bool is_public = 3;
- * @return {boolean}
- */
-proto.ChannelMetadata.prototype.getIsPublic = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 3, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setIsPublic = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasIsPublic = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional string language = 4;
- * @return {string}
- */
-proto.ChannelMetadata.prototype.getLanguage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setLanguage = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasLanguage = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional uint32 cover_photo = 5;
- * @return {number}
- */
-proto.ChannelMetadata.prototype.getCoverPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setCoverPhoto = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasCoverPhoto = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional uint32 avatar_photo = 6;
- * @return {number}
- */
-proto.ChannelMetadata.prototype.getAvatarPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setAvatarPhoto = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasAvatarPhoto = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-/**
- * optional uint64 category = 7;
- * @return {number}
- */
-proto.ChannelMetadata.prototype.getCategory = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.ChannelMetadata} returns this
- */
-proto.ChannelMetadata.prototype.setCategory = function(value) {
-  return jspb.Message.setField(this, 7, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelMetadata.prototype.hasCategory = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.ChannelCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.ChannelCategoryMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.ChannelCategoryMetadata} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.ChannelCategoryMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.ChannelCategoryMetadata}
- */
-proto.ChannelCategoryMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  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.ChannelCategoryMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.ChannelCategoryMetadata}
- */
-proto.ChannelCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.ChannelCategoryMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.ChannelCategoryMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.ChannelCategoryMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.ChannelCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.ChannelCategoryMetadata.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.ChannelCategoryMetadata} returns this
- */
-proto.ChannelCategoryMetadata.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * 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}
- */
-proto.ChannelCategoryMetadata.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-goog.object.extend(exports, proto);

+ 0 - 57
content-metadata-protobuf/compiled/proto/Person_pb.d.ts

@@ -1,57 +0,0 @@
-// package: 
-// file: proto/Person.proto
-
-import * as jspb from "google-protobuf";
-
-export class PersonMetadata extends jspb.Message {
-  hasFirstName(): boolean;
-  clearFirstName(): void;
-  getFirstName(): string | undefined;
-  setFirstName(value: string): void;
-
-  hasMiddleName(): boolean;
-  clearMiddleName(): void;
-  getMiddleName(): string | undefined;
-  setMiddleName(value: string): void;
-
-  hasLastName(): boolean;
-  clearLastName(): void;
-  getLastName(): string | undefined;
-  setLastName(value: string): void;
-
-  hasAbout(): boolean;
-  clearAbout(): void;
-  getAbout(): string | undefined;
-  setAbout(value: string): void;
-
-  hasCoverPhoto(): boolean;
-  clearCoverPhoto(): void;
-  getCoverPhoto(): number | undefined;
-  setCoverPhoto(value: number): void;
-
-  hasAvatarPhoto(): boolean;
-  clearAvatarPhoto(): void;
-  getAvatarPhoto(): number | undefined;
-  setAvatarPhoto(value: number): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): PersonMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: PersonMetadata): PersonMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: PersonMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): PersonMetadata;
-  static deserializeBinaryFromReader(message: PersonMetadata, reader: jspb.BinaryReader): PersonMetadata;
-}
-
-export namespace PersonMetadata {
-  export type AsObject = {
-    firstName?: string,
-    middleName?: string,
-    lastName?: string,
-    about?: string,
-    coverPhoto?: number,
-    avatarPhoto?: number,
-  }
-}
-

+ 0 - 428
content-metadata-protobuf/compiled/proto/Person_pb.js

@@ -1,428 +0,0 @@
-// 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
- * 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.PersonMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-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.
- * 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:
- *     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) {
-  return proto.PersonMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @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}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PersonMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    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) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.PersonMetadata}
- */
-proto.PersonMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.PersonMetadata;
-  return proto.PersonMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.PersonMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.PersonMetadata}
- */
-proto.PersonMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setFirstName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setMiddleName(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLastName(value);
-      break;
-    case 4:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setAbout(value);
-      break;
-    case 5:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setCoverPhoto(value);
-      break;
-    case 6:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setAvatarPhoto(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.PersonMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.PersonMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.PersonMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PersonMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeString(
-      4,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeUint32(
-      5,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeUint32(
-      6,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string first_name = 1;
- * @return {string}
- */
-proto.PersonMetadata.prototype.getFirstName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setFirstName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearFirstName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasFirstName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string middle_name = 2;
- * @return {string}
- */
-proto.PersonMetadata.prototype.getMiddleName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setMiddleName = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearMiddleName = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasMiddleName = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string last_name = 3;
- * @return {string}
- */
-proto.PersonMetadata.prototype.getLastName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setLastName = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearLastName = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasLastName = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional string about = 4;
- * @return {string}
- */
-proto.PersonMetadata.prototype.getAbout = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setAbout = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearAbout = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasAbout = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional uint32 cover_photo = 5;
- * @return {number}
- */
-proto.PersonMetadata.prototype.getCoverPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setCoverPhoto = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearCoverPhoto = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasCoverPhoto = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional uint32 avatar_photo = 6;
- * @return {number}
- */
-proto.PersonMetadata.prototype.getAvatarPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.setAvatarPhoto = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PersonMetadata} returns this
- */
-proto.PersonMetadata.prototype.clearAvatarPhoto = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PersonMetadata.prototype.hasAvatarPhoto = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-goog.object.extend(exports, proto);

+ 0 - 33
content-metadata-protobuf/compiled/proto/Playlist_pb.d.ts

@@ -1,33 +0,0 @@
-// package: 
-// file: proto/Playlist.proto
-
-import * as jspb from "google-protobuf";
-
-export class PlaylistMetadata extends jspb.Message {
-  hasTitle(): boolean;
-  clearTitle(): void;
-  getTitle(): string | undefined;
-  setTitle(value: string): void;
-
-  clearVideosList(): void;
-  getVideosList(): Array<number>;
-  setVideosList(value: Array<number>): void;
-  addVideos(value: number, index?: number): number;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): PlaylistMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: PlaylistMetadata): PlaylistMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: PlaylistMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): PlaylistMetadata;
-  static deserializeBinaryFromReader(message: PlaylistMetadata, reader: jspb.BinaryReader): PlaylistMetadata;
-}
-
-export namespace PlaylistMetadata {
-  export type AsObject = {
-    title?: string,
-    videosList: Array<number>,
-  }
-}
-

+ 0 - 246
content-metadata-protobuf/compiled/proto/Playlist_pb.js

@@ -1,246 +0,0 @@
-// 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
- * 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.PlaylistMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.PlaylistMetadata.repeatedFields_, null);
-};
-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>}
- * @const
- */
-proto.PlaylistMetadata.repeatedFields_ = [2];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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) {
-  return proto.PlaylistMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @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}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PlaylistMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    videosList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.PlaylistMetadata}
- */
-proto.PlaylistMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.PlaylistMetadata;
-  return proto.PlaylistMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.PlaylistMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.PlaylistMetadata}
- */
-proto.PlaylistMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTitle(value);
-      break;
-    case 2:
-      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();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.PlaylistMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.PlaylistMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.PlaylistMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PlaylistMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = message.getVideosList();
-  if (f.length > 0) {
-    writer.writeRepeatedUint64(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string title = 1;
- * @return {string}
- */
-proto.PlaylistMetadata.prototype.getTitle = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PlaylistMetadata} returns this
- */
-proto.PlaylistMetadata.prototype.setTitle = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PlaylistMetadata} returns this
- */
-proto.PlaylistMetadata.prototype.clearTitle = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PlaylistMetadata.prototype.hasTitle = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * repeated uint64 videos = 2;
- * @return {!Array<number>}
- */
-proto.PlaylistMetadata.prototype.getVideosList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 2));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.PlaylistMetadata} returns this
- */
-proto.PlaylistMetadata.prototype.setVideosList = function(value) {
-  return jspb.Message.setField(this, 2, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.PlaylistMetadata} returns this
- */
-proto.PlaylistMetadata.prototype.addVideos = function(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() {
-  return this.setVideosList([]);
-};
-
-
-goog.object.extend(exports, proto);

+ 0 - 85
content-metadata-protobuf/compiled/proto/Series_pb.d.ts

@@ -1,85 +0,0 @@
-// package: 
-// file: proto/Series.proto
-
-import * as jspb from "google-protobuf";
-
-export class SeriesMetadata extends jspb.Message {
-  hasTitle(): boolean;
-  clearTitle(): void;
-  getTitle(): string | undefined;
-  setTitle(value: string): void;
-
-  hasDescription(): boolean;
-  clearDescription(): void;
-  getDescription(): string | undefined;
-  setDescription(value: string): void;
-
-  hasCoverPhoto(): boolean;
-  clearCoverPhoto(): void;
-  getCoverPhoto(): number | undefined;
-  setCoverPhoto(value: number): void;
-
-  clearPersonsList(): void;
-  getPersonsList(): Array<number>;
-  setPersonsList(value: Array<number>): void;
-  addPersons(value: number, index?: number): number;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): SeriesMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: SeriesMetadata): SeriesMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: SeriesMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): SeriesMetadata;
-  static deserializeBinaryFromReader(message: SeriesMetadata, reader: jspb.BinaryReader): SeriesMetadata;
-}
-
-export namespace SeriesMetadata {
-  export type AsObject = {
-    title?: string,
-    description?: string,
-    coverPhoto?: number,
-    personsList: Array<number>,
-  }
-}
-
-export class SeasonMetadata extends jspb.Message {
-  hasTitle(): boolean;
-  clearTitle(): void;
-  getTitle(): string | undefined;
-  setTitle(value: string): void;
-
-  hasDescription(): boolean;
-  clearDescription(): void;
-  getDescription(): string | undefined;
-  setDescription(value: string): void;
-
-  hasCoverPhoto(): boolean;
-  clearCoverPhoto(): void;
-  getCoverPhoto(): number | undefined;
-  setCoverPhoto(value: number): void;
-
-  clearPersonsList(): void;
-  getPersonsList(): Array<number>;
-  setPersonsList(value: Array<number>): void;
-  addPersons(value: number, index?: number): number;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): SeasonMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: SeasonMetadata): SeasonMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: SeasonMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): SeasonMetadata;
-  static deserializeBinaryFromReader(message: SeasonMetadata, reader: jspb.BinaryReader): SeasonMetadata;
-}
-
-export namespace SeasonMetadata {
-  export type AsObject = {
-    title?: string,
-    description?: string,
-    coverPhoto?: number,
-    personsList: Array<number>,
-  }
-}
-

+ 0 - 666
content-metadata-protobuf/compiled/proto/Series_pb.js

@@ -1,666 +0,0 @@
-// 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;
-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
- * 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.SeriesMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.SeriesMetadata.repeatedFields_, null);
-};
-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>}
- * @const
- */
-proto.SeriesMetadata.repeatedFields_ = [4];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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) {
-  return proto.SeriesMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @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}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.SeriesMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    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) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.SeriesMetadata}
- */
-proto.SeriesMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.SeriesMetadata;
-  return proto.SeriesMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.SeriesMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.SeriesMetadata}
- */
-proto.SeriesMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTitle(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDescription(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setCoverPhoto(value);
-      break;
-    case 4:
-      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();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.SeriesMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.SeriesMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.SeriesMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.SeriesMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeUint32(
-      3,
-      f
-    );
-  }
-  f = message.getPersonsList();
-  if (f.length > 0) {
-    writer.writePackedUint64(
-      4,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string title = 1;
- * @return {string}
- */
-proto.SeriesMetadata.prototype.getTitle = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.setTitle = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.clearTitle = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeriesMetadata.prototype.hasTitle = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string description = 2;
- * @return {string}
- */
-proto.SeriesMetadata.prototype.getDescription = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.setDescription = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.clearDescription = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeriesMetadata.prototype.hasDescription = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional uint32 cover_photo = 3;
- * @return {number}
- */
-proto.SeriesMetadata.prototype.getCoverPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.setCoverPhoto = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.clearCoverPhoto = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeriesMetadata.prototype.hasCoverPhoto = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * repeated uint64 persons = 4;
- * @return {!Array<number>}
- */
-proto.SeriesMetadata.prototype.getPersonsList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 4));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.setPersonsList = function(value) {
-  return jspb.Message.setField(this, 4, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.SeriesMetadata} returns this
- */
-proto.SeriesMetadata.prototype.addPersons = function(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() {
-  return this.setPersonsList([]);
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.SeasonMetadata.repeatedFields_ = [4];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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) {
-  return proto.SeasonMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @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}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.SeasonMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    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) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.SeasonMetadata}
- */
-proto.SeasonMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.SeasonMetadata;
-  return proto.SeasonMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.SeasonMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.SeasonMetadata}
- */
-proto.SeasonMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTitle(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDescription(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setCoverPhoto(value);
-      break;
-    case 4:
-      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();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.SeasonMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.SeasonMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.SeasonMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.SeasonMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeUint32(
-      3,
-      f
-    );
-  }
-  f = message.getPersonsList();
-  if (f.length > 0) {
-    writer.writePackedUint64(
-      4,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string title = 1;
- * @return {string}
- */
-proto.SeasonMetadata.prototype.getTitle = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.setTitle = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.clearTitle = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeasonMetadata.prototype.hasTitle = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string description = 2;
- * @return {string}
- */
-proto.SeasonMetadata.prototype.getDescription = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.setDescription = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.clearDescription = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeasonMetadata.prototype.hasDescription = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional uint32 cover_photo = 3;
- * @return {number}
- */
-proto.SeasonMetadata.prototype.getCoverPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.setCoverPhoto = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.clearCoverPhoto = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.SeasonMetadata.prototype.hasCoverPhoto = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * repeated uint64 persons = 4;
- * @return {!Array<number>}
- */
-proto.SeasonMetadata.prototype.getPersonsList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 4));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.setPersonsList = function(value) {
-  return jspb.Message.setField(this, 4, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.SeasonMetadata} returns this
- */
-proto.SeasonMetadata.prototype.addPersons = function(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() {
-  return this.setPersonsList([]);
-};
-
-
-goog.object.extend(exports, proto);

+ 0 - 235
content-metadata-protobuf/compiled/proto/Video_pb.d.ts

@@ -1,235 +0,0 @@
-// package: 
-// file: proto/Video.proto
-
-import * as jspb from "google-protobuf";
-
-export class PublishedBeforeJoystream extends jspb.Message {
-  hasIsPublished(): boolean;
-  clearIsPublished(): void;
-  getIsPublished(): boolean | undefined;
-  setIsPublished(value: boolean): void;
-
-  hasDate(): boolean;
-  clearDate(): void;
-  getDate(): string | undefined;
-  setDate(value: string): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): PublishedBeforeJoystream.AsObject;
-  static toObject(includeInstance: boolean, msg: PublishedBeforeJoystream): PublishedBeforeJoystream.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: PublishedBeforeJoystream, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): PublishedBeforeJoystream;
-  static deserializeBinaryFromReader(message: PublishedBeforeJoystream, reader: jspb.BinaryReader): PublishedBeforeJoystream;
-}
-
-export namespace PublishedBeforeJoystream {
-  export type AsObject = {
-    isPublished?: boolean,
-    date?: string,
-  }
-}
-
-export class License extends jspb.Message {
-  hasCode(): boolean;
-  clearCode(): void;
-  getCode(): number | undefined;
-  setCode(value: number): void;
-
-  hasAttribution(): boolean;
-  clearAttribution(): void;
-  getAttribution(): string | undefined;
-  setAttribution(value: string): void;
-
-  hasCustomText(): boolean;
-  clearCustomText(): void;
-  getCustomText(): string | undefined;
-  setCustomText(value: string): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): License.AsObject;
-  static toObject(includeInstance: boolean, msg: License): License.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: License, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): License;
-  static deserializeBinaryFromReader(message: License, reader: jspb.BinaryReader): License;
-}
-
-export namespace License {
-  export type AsObject = {
-    code?: number,
-    attribution?: string,
-    customText?: string,
-  }
-}
-
-export class MediaType extends jspb.Message {
-  hasCodecName(): boolean;
-  clearCodecName(): void;
-  getCodecName(): string | undefined;
-  setCodecName(value: string): void;
-
-  hasContainer(): boolean;
-  clearContainer(): void;
-  getContainer(): string | undefined;
-  setContainer(value: string): void;
-
-  hasMimeMediaType(): boolean;
-  clearMimeMediaType(): void;
-  getMimeMediaType(): string | undefined;
-  setMimeMediaType(value: string): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): MediaType.AsObject;
-  static toObject(includeInstance: boolean, msg: MediaType): MediaType.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: MediaType, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): MediaType;
-  static deserializeBinaryFromReader(message: MediaType, reader: jspb.BinaryReader): MediaType;
-}
-
-export namespace MediaType {
-  export type AsObject = {
-    codecName?: string,
-    container?: string,
-    mimeMediaType?: string,
-  }
-}
-
-export class VideoMetadata extends jspb.Message {
-  hasTitle(): boolean;
-  clearTitle(): void;
-  getTitle(): string | undefined;
-  setTitle(value: string): void;
-
-  hasDescription(): boolean;
-  clearDescription(): void;
-  getDescription(): string | undefined;
-  setDescription(value: string): void;
-
-  hasVideo(): boolean;
-  clearVideo(): void;
-  getVideo(): number | undefined;
-  setVideo(value: number): void;
-
-  hasThumbnailPhoto(): boolean;
-  clearThumbnailPhoto(): void;
-  getThumbnailPhoto(): number | undefined;
-  setThumbnailPhoto(value: number): void;
-
-  hasDuration(): boolean;
-  clearDuration(): void;
-  getDuration(): number | undefined;
-  setDuration(value: number): void;
-
-  hasMediaPixelHeight(): boolean;
-  clearMediaPixelHeight(): void;
-  getMediaPixelHeight(): number | undefined;
-  setMediaPixelHeight(value: number): void;
-
-  hasMediaPixelWidth(): boolean;
-  clearMediaPixelWidth(): void;
-  getMediaPixelWidth(): number | undefined;
-  setMediaPixelWidth(value: number): void;
-
-  hasMediaType(): boolean;
-  clearMediaType(): void;
-  getMediaType(): MediaType | undefined;
-  setMediaType(value?: MediaType): void;
-
-  hasLanguage(): boolean;
-  clearLanguage(): void;
-  getLanguage(): string | undefined;
-  setLanguage(value: string): void;
-
-  hasLicense(): boolean;
-  clearLicense(): void;
-  getLicense(): License | undefined;
-  setLicense(value?: License): void;
-
-  hasPublishedBeforeJoystream(): boolean;
-  clearPublishedBeforeJoystream(): void;
-  getPublishedBeforeJoystream(): PublishedBeforeJoystream | undefined;
-  setPublishedBeforeJoystream(value?: PublishedBeforeJoystream): void;
-
-  hasHasMarketing(): boolean;
-  clearHasMarketing(): void;
-  getHasMarketing(): boolean | undefined;
-  setHasMarketing(value: boolean): void;
-
-  hasIsPublic(): boolean;
-  clearIsPublic(): void;
-  getIsPublic(): boolean | undefined;
-  setIsPublic(value: boolean): void;
-
-  hasIsExplicit(): boolean;
-  clearIsExplicit(): void;
-  getIsExplicit(): boolean | undefined;
-  setIsExplicit(value: boolean): void;
-
-  clearPersonsList(): void;
-  getPersonsList(): Array<number>;
-  setPersonsList(value: Array<number>): void;
-  addPersons(value: number, index?: number): number;
-
-  hasCategory(): boolean;
-  clearCategory(): void;
-  getCategory(): number | undefined;
-  setCategory(value: number): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): VideoMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: VideoMetadata): VideoMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: VideoMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): VideoMetadata;
-  static deserializeBinaryFromReader(message: VideoMetadata, reader: jspb.BinaryReader): VideoMetadata;
-}
-
-export namespace VideoMetadata {
-  export type AsObject = {
-    title?: string,
-    description?: string,
-    video?: number,
-    thumbnailPhoto?: number,
-    duration?: number,
-    mediaPixelHeight?: number,
-    mediaPixelWidth?: number,
-    mediaType?: MediaType.AsObject,
-    language?: string,
-    license?: License.AsObject,
-    publishedBeforeJoystream?: PublishedBeforeJoystream.AsObject,
-    hasMarketing?: boolean,
-    isPublic?: boolean,
-    isExplicit?: boolean,
-    personsList: Array<number>,
-    category?: number,
-  }
-}
-
-export class VideoCategoryMetadata extends jspb.Message {
-  hasName(): boolean;
-  clearName(): void;
-  getName(): string | undefined;
-  setName(value: string): void;
-
-  serializeBinary(): Uint8Array;
-  toObject(includeInstance?: boolean): VideoCategoryMetadata.AsObject;
-  static toObject(includeInstance: boolean, msg: VideoCategoryMetadata): VideoCategoryMetadata.AsObject;
-  static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
-  static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
-  static serializeBinaryToWriter(message: VideoCategoryMetadata, writer: jspb.BinaryWriter): void;
-  static deserializeBinary(bytes: Uint8Array): VideoCategoryMetadata;
-  static deserializeBinaryFromReader(message: VideoCategoryMetadata, reader: jspb.BinaryReader): VideoCategoryMetadata;
-}
-
-export namespace VideoCategoryMetadata {
-  export type AsObject = {
-    name?: string,
-  }
-}
-

+ 0 - 1847
content-metadata-protobuf/compiled/proto/Video_pb.js

@@ -1,1847 +0,0 @@
-// source: proto/Video.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.License', null, global);
-goog.exportSymbol('proto.MediaType', null, global);
-goog.exportSymbol('proto.PublishedBeforeJoystream', null, global);
-goog.exportSymbol('proto.VideoCategoryMetadata', null, global);
-goog.exportSymbol('proto.VideoMetadata', 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.PublishedBeforeJoystream = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.PublishedBeforeJoystream, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.PublishedBeforeJoystream.displayName = 'proto.PublishedBeforeJoystream';
-}
-/**
- * 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.License = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.License, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.License.displayName = 'proto.License';
-}
-/**
- * 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.MediaType = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.MediaType, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.MediaType.displayName = 'proto.MediaType';
-}
-/**
- * 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.VideoMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, proto.VideoMetadata.repeatedFields_, null);
-};
-goog.inherits(proto.VideoMetadata, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.VideoMetadata.displayName = 'proto.VideoMetadata';
-}
-/**
- * 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.VideoCategoryMetadata = function(opt_data) {
-  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
-};
-goog.inherits(proto.VideoCategoryMetadata, jspb.Message);
-if (goog.DEBUG && !COMPILED) {
-  /**
-   * @public
-   * @override
-   */
-  proto.VideoCategoryMetadata.displayName = 'proto.VideoCategoryMetadata';
-}
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.PublishedBeforeJoystream.prototype.toObject = function(opt_includeInstance) {
-  return proto.PublishedBeforeJoystream.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.PublishedBeforeJoystream} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PublishedBeforeJoystream.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    isPublished: (f = jspb.Message.getBooleanField(msg, 1)) == null ? undefined : f,
-    date: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.PublishedBeforeJoystream}
- */
-proto.PublishedBeforeJoystream.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.PublishedBeforeJoystream;
-  return proto.PublishedBeforeJoystream.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.PublishedBeforeJoystream} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.PublishedBeforeJoystream}
- */
-proto.PublishedBeforeJoystream.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIsPublished(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDate(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.PublishedBeforeJoystream.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.PublishedBeforeJoystream.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.PublishedBeforeJoystream} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.PublishedBeforeJoystream.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeBool(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-};
-
-
-/**
- * optional bool is_published = 1;
- * @return {boolean}
- */
-proto.PublishedBeforeJoystream.prototype.getIsPublished = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 1, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.PublishedBeforeJoystream} returns this
- */
-proto.PublishedBeforeJoystream.prototype.setIsPublished = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PublishedBeforeJoystream} returns this
- */
-proto.PublishedBeforeJoystream.prototype.clearIsPublished = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PublishedBeforeJoystream.prototype.hasIsPublished = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string date = 2;
- * @return {string}
- */
-proto.PublishedBeforeJoystream.prototype.getDate = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.PublishedBeforeJoystream} returns this
- */
-proto.PublishedBeforeJoystream.prototype.setDate = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.PublishedBeforeJoystream} returns this
- */
-proto.PublishedBeforeJoystream.prototype.clearDate = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.PublishedBeforeJoystream.prototype.hasDate = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.License.prototype.toObject = function(opt_includeInstance) {
-  return proto.License.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.License} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.License.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    code: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    attribution: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    customText: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.License}
- */
-proto.License.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.License;
-  return proto.License.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.License} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.License}
- */
-proto.License.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setCode(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setAttribution(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setCustomText(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.License.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.License.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.License} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.License.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {number} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeUint32(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-};
-
-
-/**
- * optional uint32 code = 1;
- * @return {number}
- */
-proto.License.prototype.getCode = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.License} returns this
- */
-proto.License.prototype.setCode = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.License} returns this
- */
-proto.License.prototype.clearCode = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.License.prototype.hasCode = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string attribution = 2;
- * @return {string}
- */
-proto.License.prototype.getAttribution = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.License} returns this
- */
-proto.License.prototype.setAttribution = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.License} returns this
- */
-proto.License.prototype.clearAttribution = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.License.prototype.hasAttribution = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string custom_text = 3;
- * @return {string}
- */
-proto.License.prototype.getCustomText = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.License} returns this
- */
-proto.License.prototype.setCustomText = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.License} returns this
- */
-proto.License.prototype.clearCustomText = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.License.prototype.hasCustomText = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.MediaType.prototype.toObject = function(opt_includeInstance) {
-  return proto.MediaType.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.MediaType} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.MediaType.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    codecName: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    container: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    mimeMediaType: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.MediaType}
- */
-proto.MediaType.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.MediaType;
-  return proto.MediaType.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.MediaType} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.MediaType}
- */
-proto.MediaType.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setCodecName(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setContainer(value);
-      break;
-    case 3:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setMimeMediaType(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.MediaType.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.MediaType.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.MediaType} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.MediaType.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeString(
-      3,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string codec_name = 1;
- * @return {string}
- */
-proto.MediaType.prototype.getCodecName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.setCodecName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.clearCodecName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.MediaType.prototype.hasCodecName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string container = 2;
- * @return {string}
- */
-proto.MediaType.prototype.getContainer = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.setContainer = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.clearContainer = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.MediaType.prototype.hasContainer = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional string mime_media_type = 3;
- * @return {string}
- */
-proto.MediaType.prototype.getMimeMediaType = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.setMimeMediaType = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.MediaType} returns this
- */
-proto.MediaType.prototype.clearMimeMediaType = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.MediaType.prototype.hasMimeMediaType = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-
-/**
- * List of repeated fields within this message type.
- * @private {!Array<number>}
- * @const
- */
-proto.VideoMetadata.repeatedFields_ = [15];
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.VideoMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.VideoMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.VideoMetadata} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.VideoMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    title: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f,
-    description: (f = jspb.Message.getField(msg, 2)) == null ? undefined : f,
-    video: (f = jspb.Message.getField(msg, 3)) == null ? undefined : f,
-    thumbnailPhoto: (f = jspb.Message.getField(msg, 4)) == null ? undefined : f,
-    duration: (f = jspb.Message.getField(msg, 5)) == null ? undefined : f,
-    mediaPixelHeight: (f = jspb.Message.getField(msg, 6)) == null ? undefined : f,
-    mediaPixelWidth: (f = jspb.Message.getField(msg, 7)) == null ? undefined : f,
-    mediaType: (f = msg.getMediaType()) && proto.MediaType.toObject(includeInstance, f),
-    language: (f = jspb.Message.getField(msg, 9)) == null ? undefined : f,
-    license: (f = msg.getLicense()) && proto.License.toObject(includeInstance, f),
-    publishedBeforeJoystream: (f = msg.getPublishedBeforeJoystream()) && proto.PublishedBeforeJoystream.toObject(includeInstance, f),
-    hasMarketing: (f = jspb.Message.getBooleanField(msg, 12)) == null ? undefined : f,
-    isPublic: (f = jspb.Message.getBooleanField(msg, 13)) == null ? undefined : f,
-    isExplicit: (f = jspb.Message.getBooleanField(msg, 14)) == null ? undefined : f,
-    personsList: (f = jspb.Message.getRepeatedField(msg, 15)) == null ? undefined : f,
-    category: (f = jspb.Message.getField(msg, 16)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.VideoMetadata}
- */
-proto.VideoMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.VideoMetadata;
-  return proto.VideoMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.VideoMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.VideoMetadata}
- */
-proto.VideoMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setTitle(value);
-      break;
-    case 2:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setDescription(value);
-      break;
-    case 3:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setVideo(value);
-      break;
-    case 4:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setThumbnailPhoto(value);
-      break;
-    case 5:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setDuration(value);
-      break;
-    case 6:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setMediaPixelHeight(value);
-      break;
-    case 7:
-      var value = /** @type {number} */ (reader.readUint32());
-      msg.setMediaPixelWidth(value);
-      break;
-    case 8:
-      var value = new proto.MediaType;
-      reader.readMessage(value,proto.MediaType.deserializeBinaryFromReader);
-      msg.setMediaType(value);
-      break;
-    case 9:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setLanguage(value);
-      break;
-    case 10:
-      var value = new proto.License;
-      reader.readMessage(value,proto.License.deserializeBinaryFromReader);
-      msg.setLicense(value);
-      break;
-    case 11:
-      var value = new proto.PublishedBeforeJoystream;
-      reader.readMessage(value,proto.PublishedBeforeJoystream.deserializeBinaryFromReader);
-      msg.setPublishedBeforeJoystream(value);
-      break;
-    case 12:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setHasMarketing(value);
-      break;
-    case 13:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIsPublic(value);
-      break;
-    case 14:
-      var value = /** @type {boolean} */ (reader.readBool());
-      msg.setIsExplicit(value);
-      break;
-    case 15:
-      var values = /** @type {!Array<number>} */ (reader.isDelimited() ? reader.readPackedUint64() : [reader.readUint64()]);
-      for (var i = 0; i < values.length; i++) {
-        msg.addPersons(values[i]);
-      }
-      break;
-    case 16:
-      var value = /** @type {number} */ (reader.readUint64());
-      msg.setCategory(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.VideoMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.VideoMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.VideoMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.VideoMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 2));
-  if (f != null) {
-    writer.writeString(
-      2,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 3));
-  if (f != null) {
-    writer.writeUint32(
-      3,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 4));
-  if (f != null) {
-    writer.writeUint32(
-      4,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 5));
-  if (f != null) {
-    writer.writeUint32(
-      5,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 6));
-  if (f != null) {
-    writer.writeUint32(
-      6,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 7));
-  if (f != null) {
-    writer.writeUint32(
-      7,
-      f
-    );
-  }
-  f = message.getMediaType();
-  if (f != null) {
-    writer.writeMessage(
-      8,
-      f,
-      proto.MediaType.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {string} */ (jspb.Message.getField(message, 9));
-  if (f != null) {
-    writer.writeString(
-      9,
-      f
-    );
-  }
-  f = message.getLicense();
-  if (f != null) {
-    writer.writeMessage(
-      10,
-      f,
-      proto.License.serializeBinaryToWriter
-    );
-  }
-  f = message.getPublishedBeforeJoystream();
-  if (f != null) {
-    writer.writeMessage(
-      11,
-      f,
-      proto.PublishedBeforeJoystream.serializeBinaryToWriter
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 12));
-  if (f != null) {
-    writer.writeBool(
-      12,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 13));
-  if (f != null) {
-    writer.writeBool(
-      13,
-      f
-    );
-  }
-  f = /** @type {boolean} */ (jspb.Message.getField(message, 14));
-  if (f != null) {
-    writer.writeBool(
-      14,
-      f
-    );
-  }
-  f = message.getPersonsList();
-  if (f.length > 0) {
-    writer.writePackedUint64(
-      15,
-      f
-    );
-  }
-  f = /** @type {number} */ (jspb.Message.getField(message, 16));
-  if (f != null) {
-    writer.writeUint64(
-      16,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string title = 1;
- * @return {string}
- */
-proto.VideoMetadata.prototype.getTitle = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setTitle = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearTitle = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasTitle = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-/**
- * optional string description = 2;
- * @return {string}
- */
-proto.VideoMetadata.prototype.getDescription = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setDescription = function(value) {
-  return jspb.Message.setField(this, 2, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearDescription = function() {
-  return jspb.Message.setField(this, 2, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasDescription = function() {
-  return jspb.Message.getField(this, 2) != null;
-};
-
-
-/**
- * optional uint32 video = 3;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getVideo = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setVideo = function(value) {
-  return jspb.Message.setField(this, 3, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearVideo = function() {
-  return jspb.Message.setField(this, 3, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasVideo = function() {
-  return jspb.Message.getField(this, 3) != null;
-};
-
-
-/**
- * optional uint32 thumbnail_photo = 4;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getThumbnailPhoto = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setThumbnailPhoto = function(value) {
-  return jspb.Message.setField(this, 4, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearThumbnailPhoto = function() {
-  return jspb.Message.setField(this, 4, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasThumbnailPhoto = function() {
-  return jspb.Message.getField(this, 4) != null;
-};
-
-
-/**
- * optional uint32 duration = 5;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getDuration = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setDuration = function(value) {
-  return jspb.Message.setField(this, 5, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearDuration = function() {
-  return jspb.Message.setField(this, 5, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasDuration = function() {
-  return jspb.Message.getField(this, 5) != null;
-};
-
-
-/**
- * optional uint32 media_pixel_height = 6;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getMediaPixelHeight = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setMediaPixelHeight = function(value) {
-  return jspb.Message.setField(this, 6, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearMediaPixelHeight = function() {
-  return jspb.Message.setField(this, 6, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasMediaPixelHeight = function() {
-  return jspb.Message.getField(this, 6) != null;
-};
-
-
-/**
- * optional uint32 media_pixel_width = 7;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getMediaPixelWidth = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setMediaPixelWidth = function(value) {
-  return jspb.Message.setField(this, 7, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearMediaPixelWidth = function() {
-  return jspb.Message.setField(this, 7, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasMediaPixelWidth = function() {
-  return jspb.Message.getField(this, 7) != null;
-};
-
-
-/**
- * optional MediaType media_type = 8;
- * @return {?proto.MediaType}
- */
-proto.VideoMetadata.prototype.getMediaType = function() {
-  return /** @type{?proto.MediaType} */ (
-    jspb.Message.getWrapperField(this, proto.MediaType, 8));
-};
-
-
-/**
- * @param {?proto.MediaType|undefined} value
- * @return {!proto.VideoMetadata} returns this
-*/
-proto.VideoMetadata.prototype.setMediaType = function(value) {
-  return jspb.Message.setWrapperField(this, 8, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearMediaType = function() {
-  return this.setMediaType(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasMediaType = function() {
-  return jspb.Message.getField(this, 8) != null;
-};
-
-
-/**
- * optional string language = 9;
- * @return {string}
- */
-proto.VideoMetadata.prototype.getLanguage = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setLanguage = function(value) {
-  return jspb.Message.setField(this, 9, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearLanguage = function() {
-  return jspb.Message.setField(this, 9, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasLanguage = function() {
-  return jspb.Message.getField(this, 9) != null;
-};
-
-
-/**
- * optional License license = 10;
- * @return {?proto.License}
- */
-proto.VideoMetadata.prototype.getLicense = function() {
-  return /** @type{?proto.License} */ (
-    jspb.Message.getWrapperField(this, proto.License, 10));
-};
-
-
-/**
- * @param {?proto.License|undefined} value
- * @return {!proto.VideoMetadata} returns this
-*/
-proto.VideoMetadata.prototype.setLicense = function(value) {
-  return jspb.Message.setWrapperField(this, 10, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearLicense = function() {
-  return this.setLicense(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasLicense = function() {
-  return jspb.Message.getField(this, 10) != null;
-};
-
-
-/**
- * optional PublishedBeforeJoystream published_before_joystream = 11;
- * @return {?proto.PublishedBeforeJoystream}
- */
-proto.VideoMetadata.prototype.getPublishedBeforeJoystream = function() {
-  return /** @type{?proto.PublishedBeforeJoystream} */ (
-    jspb.Message.getWrapperField(this, proto.PublishedBeforeJoystream, 11));
-};
-
-
-/**
- * @param {?proto.PublishedBeforeJoystream|undefined} value
- * @return {!proto.VideoMetadata} returns this
-*/
-proto.VideoMetadata.prototype.setPublishedBeforeJoystream = function(value) {
-  return jspb.Message.setWrapperField(this, 11, value);
-};
-
-
-/**
- * Clears the message field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearPublishedBeforeJoystream = function() {
-  return this.setPublishedBeforeJoystream(undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasPublishedBeforeJoystream = function() {
-  return jspb.Message.getField(this, 11) != null;
-};
-
-
-/**
- * optional bool has_marketing = 12;
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.getHasMarketing = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 12, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setHasMarketing = function(value) {
-  return jspb.Message.setField(this, 12, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearHasMarketing = function() {
-  return jspb.Message.setField(this, 12, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasHasMarketing = function() {
-  return jspb.Message.getField(this, 12) != null;
-};
-
-
-/**
- * optional bool is_public = 13;
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.getIsPublic = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 13, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setIsPublic = function(value) {
-  return jspb.Message.setField(this, 13, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearIsPublic = function() {
-  return jspb.Message.setField(this, 13, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasIsPublic = function() {
-  return jspb.Message.getField(this, 13) != null;
-};
-
-
-/**
- * optional bool is_explicit = 14;
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.getIsExplicit = function() {
-  return /** @type {boolean} */ (jspb.Message.getBooleanFieldWithDefault(this, 14, false));
-};
-
-
-/**
- * @param {boolean} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setIsExplicit = function(value) {
-  return jspb.Message.setField(this, 14, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearIsExplicit = function() {
-  return jspb.Message.setField(this, 14, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasIsExplicit = function() {
-  return jspb.Message.getField(this, 14) != null;
-};
-
-
-/**
- * repeated uint64 persons = 15;
- * @return {!Array<number>}
- */
-proto.VideoMetadata.prototype.getPersonsList = function() {
-  return /** @type {!Array<number>} */ (jspb.Message.getRepeatedField(this, 15));
-};
-
-
-/**
- * @param {!Array<number>} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setPersonsList = function(value) {
-  return jspb.Message.setField(this, 15, value || []);
-};
-
-
-/**
- * @param {number} value
- * @param {number=} opt_index
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.addPersons = function(value, opt_index) {
-  return jspb.Message.addToRepeatedField(this, 15, value, opt_index);
-};
-
-
-/**
- * Clears the list making it empty but non-null.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearPersonsList = function() {
-  return this.setPersonsList([]);
-};
-
-
-/**
- * optional uint64 category = 16;
- * @return {number}
- */
-proto.VideoMetadata.prototype.getCategory = function() {
-  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 16, 0));
-};
-
-
-/**
- * @param {number} value
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.setCategory = function(value) {
-  return jspb.Message.setField(this, 16, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoMetadata} returns this
- */
-proto.VideoMetadata.prototype.clearCategory = function() {
-  return jspb.Message.setField(this, 16, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoMetadata.prototype.hasCategory = function() {
-  return jspb.Message.getField(this, 16) != null;
-};
-
-
-
-
-
-if (jspb.Message.GENERATE_TO_OBJECT) {
-/**
- * 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:
- *     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.VideoCategoryMetadata.prototype.toObject = function(opt_includeInstance) {
-  return proto.VideoCategoryMetadata.toObject(opt_includeInstance, this);
-};
-
-
-/**
- * Static version of the {@see toObject} method.
- * @param {boolean|undefined} includeInstance Deprecated. Whether to include
- *     the JSPB instance for transitional soy proto support:
- *     http://goto/soy-param-migration
- * @param {!proto.VideoCategoryMetadata} msg The msg instance to transform.
- * @return {!Object}
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.VideoCategoryMetadata.toObject = function(includeInstance, msg) {
-  var f, obj = {
-    name: (f = jspb.Message.getField(msg, 1)) == null ? undefined : f
-  };
-
-  if (includeInstance) {
-    obj.$jspbMessageInstance = msg;
-  }
-  return obj;
-};
-}
-
-
-/**
- * Deserializes binary data (in protobuf wire format).
- * @param {jspb.ByteSource} bytes The bytes to deserialize.
- * @return {!proto.VideoCategoryMetadata}
- */
-proto.VideoCategoryMetadata.deserializeBinary = function(bytes) {
-  var reader = new jspb.BinaryReader(bytes);
-  var msg = new proto.VideoCategoryMetadata;
-  return proto.VideoCategoryMetadata.deserializeBinaryFromReader(msg, reader);
-};
-
-
-/**
- * Deserializes binary data (in protobuf wire format) from the
- * given reader into the given message object.
- * @param {!proto.VideoCategoryMetadata} msg The message object to deserialize into.
- * @param {!jspb.BinaryReader} reader The BinaryReader to use.
- * @return {!proto.VideoCategoryMetadata}
- */
-proto.VideoCategoryMetadata.deserializeBinaryFromReader = function(msg, reader) {
-  while (reader.nextField()) {
-    if (reader.isEndGroup()) {
-      break;
-    }
-    var field = reader.getFieldNumber();
-    switch (field) {
-    case 1:
-      var value = /** @type {string} */ (reader.readString());
-      msg.setName(value);
-      break;
-    default:
-      reader.skipField();
-      break;
-    }
-  }
-  return msg;
-};
-
-
-/**
- * Serializes the message to binary data (in protobuf wire format).
- * @return {!Uint8Array}
- */
-proto.VideoCategoryMetadata.prototype.serializeBinary = function() {
-  var writer = new jspb.BinaryWriter();
-  proto.VideoCategoryMetadata.serializeBinaryToWriter(this, writer);
-  return writer.getResultBuffer();
-};
-
-
-/**
- * Serializes the given message to binary data (in protobuf wire
- * format), writing to the given BinaryWriter.
- * @param {!proto.VideoCategoryMetadata} message
- * @param {!jspb.BinaryWriter} writer
- * @suppress {unusedLocalVariables} f is only used for nested messages
- */
-proto.VideoCategoryMetadata.serializeBinaryToWriter = function(message, writer) {
-  var f = undefined;
-  f = /** @type {string} */ (jspb.Message.getField(message, 1));
-  if (f != null) {
-    writer.writeString(
-      1,
-      f
-    );
-  }
-};
-
-
-/**
- * optional string name = 1;
- * @return {string}
- */
-proto.VideoCategoryMetadata.prototype.getName = function() {
-  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
-};
-
-
-/**
- * @param {string} value
- * @return {!proto.VideoCategoryMetadata} returns this
- */
-proto.VideoCategoryMetadata.prototype.setName = function(value) {
-  return jspb.Message.setField(this, 1, value);
-};
-
-
-/**
- * Clears the field making it undefined.
- * @return {!proto.VideoCategoryMetadata} returns this
- */
-proto.VideoCategoryMetadata.prototype.clearName = function() {
-  return jspb.Message.setField(this, 1, undefined);
-};
-
-
-/**
- * Returns whether this field is set.
- * @return {boolean}
- */
-proto.VideoCategoryMetadata.prototype.hasName = function() {
-  return jspb.Message.getField(this, 1) != null;
-};
-
-
-goog.object.extend(exports, proto);

+ 0 - 374
content-metadata-protobuf/doc/index.md

@@ -1,374 +0,0 @@
-# Protocol Documentation
-<a name="top"></a>
-
-## Table of Contents
-
-- [proto/Channel.proto](#proto/Channel.proto)
-    - [ChannelCategoryMetadata](#.ChannelCategoryMetadata)
-    - [ChannelMetadata](#.ChannelMetadata)
-  
-- [proto/Person.proto](#proto/Person.proto)
-    - [PersonMetadata](#.PersonMetadata)
-  
-- [proto/Playlist.proto](#proto/Playlist.proto)
-    - [PlaylistMetadata](#.PlaylistMetadata)
-  
-- [proto/Series.proto](#proto/Series.proto)
-    - [SeasonMetadata](#.SeasonMetadata)
-    - [SeriesMetadata](#.SeriesMetadata)
-  
-- [proto/Video.proto](#proto/Video.proto)
-    - [License](#.License)
-    - [MediaType](#.MediaType)
-    - [PublishedBeforeJoystream](#.PublishedBeforeJoystream)
-    - [VideoCategoryMetadata](#.VideoCategoryMetadata)
-    - [VideoMetadata](#.VideoMetadata)
-  
-- [Scalar Value Types](#scalar-value-types)
-
-
-
-<a name="proto/Channel.proto"></a>
-<p align="right"><a href="#top">Top</a></p>
-
-## proto/Channel.proto
-
-
-
-<a name=".ChannelCategoryMetadata"></a>
-
-### ChannelCategoryMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| name | [string](#string) | optional | Category Name |
-
-
-
-
-
-
-<a name=".ChannelMetadata"></a>
-
-### ChannelMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| title | [string](#string) | optional | Channel Title |
-| description | [string](#string) | optional | Channel Description |
-| is_public | [bool](#bool) | optional | Wether to display channel to the public |
-| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
-| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| category | [uint64](#uint64) | optional | Channel Category Id |
-
-
-
-
-
- 
-
- 
-
- 
-
- 
-
-
-
-<a name="proto/Person.proto"></a>
-<p align="right"><a href="#top">Top</a></p>
-
-## proto/Person.proto
-
-
-
-<a name=".PersonMetadata"></a>
-
-### PersonMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| first_name | [string](#string) | optional |  |
-| middle_name | [string](#string) | optional |  |
-| last_name | [string](#string) | optional |  |
-| about | [string](#string) | optional |  |
-| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-
-
-
-
-
- 
-
- 
-
- 
-
- 
-
-
-
-<a name="proto/Playlist.proto"></a>
-<p align="right"><a href="#top">Top</a></p>
-
-## proto/Playlist.proto
-
-
-
-<a name=".PlaylistMetadata"></a>
-
-### PlaylistMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| title | [string](#string) | optional |  |
-| videos | [uint64](#uint64) | repeated | Videos in the playlist |
-
-
-
-
-
- 
-
- 
-
- 
-
- 
-
-
-
-<a name="proto/Series.proto"></a>
-<p align="right"><a href="#top">Top</a></p>
-
-## proto/Series.proto
-
-
-
-<a name=".SeasonMetadata"></a>
-
-### SeasonMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| title | [string](#string) | optional |  |
-| description | [string](#string) | optional |  |
-| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Season |
-
-
-
-
-
-
-<a name=".SeriesMetadata"></a>
-
-### SeriesMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| title | [string](#string) | optional |  |
-| description | [string](#string) | optional |  |
-| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Series |
-
-
-
-
-
- 
-
- 
-
- 
-
- 
-
-
-
-<a name="proto/Video.proto"></a>
-<p align="right"><a href="#top">Top</a></p>
-
-## proto/Video.proto
-
-
-
-<a name=".License"></a>
-
-### License
-License types defined by Joystream
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| code | [uint32](#uint32) | optional | License code defined by Joystream. [reference](../src/KnownLicenses.json) |
-| attribution | [string](#string) | optional | Text for licenses that require an attribution |
-| custom_text | [string](#string) | optional | Text for custom license type |
-
-
-
-
-
-
-<a name=".MediaType"></a>
-
-### MediaType
-Codec, Container, MIME media-type information
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| codec_name | [string](#string) | optional | Codec corresponding to `name` field from [FFmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c) |
-| container | [string](#string) | optional | Video container format, eg. &#39;MP4&#39;, &#39;WebM&#39;, &#39;Ogg&#39; [ref](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs) |
-| mime_media_type | [string](#string) | optional | MIME Media Type, eg. &#39;video/mp4&#39; [ref](https://www.iana.org/assignments/media-types/media-types.xhtml#video) |
-
-
-
-
-
-
-<a name=".PublishedBeforeJoystream"></a>
-
-### PublishedBeforeJoystream
-Publication status before joystream
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| is_published | [bool](#bool) | optional | Was video published before joystream platform |
-| date | [string](#string) | optional | Date of publication: &#39;YYYY-MM-DD&#39; [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) |
-
-
-
-
-
-
-<a name=".VideoCategoryMetadata"></a>
-
-### VideoCategoryMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| name | [string](#string) | optional | Category name |
-
-
-
-
-
-
-<a name=".VideoMetadata"></a>
-
-### VideoMetadata
-
-
-
-| Field | Type | Label | Description |
-| ----- | ---- | ----- | ----------- |
-| title | [string](#string) | optional | Video Title |
-| description | [string](#string) | optional | Video Description |
-| video | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| thumbnail_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
-| duration | [uint32](#uint32) | optional | Lengths of video in seconds |
-| media_pixel_height | [uint32](#uint32) | optional | Resolution of the video (Height) |
-| media_pixel_width | [uint32](#uint32) | optional | Resolution of the video (Width) |
-| media_type | [MediaType](#MediaType) | optional | Encoding and Container format used |
-| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
-| license | [License](#License) | optional | License type for the media |
-| published_before_joystream | [PublishedBeforeJoystream](#PublishedBeforeJoystream) | optional | Date of publication |
-| has_marketing | [bool](#bool) | optional | Does video have marketing or advertising in the stream |
-| is_public | [bool](#bool) | optional | Should video be publicy visible yet |
-| is_explicit | [bool](#bool) | optional | Does Video have explicit language or scenes |
-| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this video |
-| category | [uint64](#uint64) | optional | Video Category Id |
-
-
-
-
-
- 
-
- 
-
- 
-
- 
-
-
-
-## Scalar Value Types
-
-| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
-| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
-| <a name="double" /> double |  | double | double | float | float64 | double | float | Float |
-| <a name="float" /> float |  | float | float | float | float32 | float | float | Float |
-| <a name="int32" /> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
-| <a name="int64" /> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
-| <a name="uint32" /> uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
-| <a name="uint64" /> uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
-| <a name="sint32" /> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
-| <a name="sint64" /> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
-| <a name="fixed32" /> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
-| <a name="fixed64" /> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
-| <a name="sfixed32" /> sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
-| <a name="sfixed64" /> sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
-| <a name="bool" /> bool |  | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
-| <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
-| <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
-
-<!-- 
-    This extra documentation will be appended to the generated docs.
--->
-
-## Referencing Assets
-<a name=".Assets"></a>
-
-Applications that process messages that contain a `uint32` field that references an asset such as a cover photo or video, should interpret this value as a zero based index into an array/vector that is received external (out of band) to the protobuf message.
-
-Example in context of query-node processing the runtime event `VideoCreated`
-
-```rust
-// Runtime event associated with creating a Video
-VideoCreated(video_id: VideoId, video: Video, assets: Vec<NewAsset>, params: VideoCreationParameters)
-
-struct VideoCreationParameters {
-  in_category: VideoCategoryId,
-  // binary serialized VideoMetadata protobuf message
-  meta: Vec<u8>,
-}
-
-// suppose assets is a vector of two elements. This is the "out of band" array being referenced by the VideoMetadata message
-assets = [
-    NewAsset::Uri("https://mydomain.net/thumbnail.png"),
-    NewAsset::Upload({
-       content_id,
-       ipfs_hash,
-       size,
-       ...
-    }),
-];
-
-meta = VideoMetadata {
-    ...
-    // refers to second element: assets[1] which is being uploaded to the storage system
-    video: 1,
-    // refers to the first element assets[0] which is being referneced by a url string.
-    thumbnail_photo: 0,
-    ...
-};
-```

+ 0 - 13
content-metadata-protobuf/generate-md-doc.sh

@@ -1,13 +0,0 @@
-#!/usr/bin/env bash
-
-# Directory to write generated documentation to
-OUT_DIR_DOC="./doc"
-mkdir -p ${OUT_DIR_DOC}
-
-# Gernerate Markdown docs
-protoc \
-    --doc_out="${OUT_DIR_DOC}" --doc_opt=markdown,index.md \
-    proto/*.proto
-
-# Append some custom docs to generated protocol docs
-cat doc-appendix.md >> ${OUT_DIR_DOC}/index.md

+ 0 - 47
content-metadata-protobuf/package.json

@@ -1,47 +0,0 @@
-{
-  "name": "@joystream/content-metadata-protobuf",
-  "version": "1.1.0",
-  "description": "Joystream Content Metadata Protobuf Library ",
-  "main": "lib/index.js",
-  "types": "lib/index.d.ts",
-  "repository": "https://github.com/joystream/joystream",
-  "author": "Joystream Contributors",
-  "license": "MIT",
-  "private": false,
-  "scripts": {
-    "build": "./compile.sh && yarn build:ts",
-    "build:ts": "tsc",
-    "compile": "./compile.sh",
-    "generate-doc": "./generate-md-doc.sh",
-    "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha -r ts-node/register 'test/**/*.ts'",
-    "lint": "eslint ./src --ext .ts",
-    "checks": "tsc --noEmit --pretty && prettier ./ --check && yarn lint",
-    "format": "prettier ./ --write",
-    "prepublish": "yarn build"
-  },
-  "files": [
-    "lib/**/*",
-    "doc/**",
-    "proto/**",
-    "compiled/**/*",
-    "README.md"
-  ],
-  "dependencies": {
-    "google-protobuf": "^3.14.0"
-  },
-  "devDependencies": {
-    "@types/chai": "^4.2.11",
-    "@types/mocha": "^8.2.0",
-    "chai": "^4.2.0",
-    "eslint": "^7.6.0",
-    "mocha": "^8.2.1",
-    "prettier": "2.0.2",
-    "ts-node": "^8.8.1",
-    "ts-protoc-gen": "^0.14.0",
-    "typescript": "^4.1.3"
-  },
-  "publishConfig": {
-    "access": "public",
-    "registry": "https://registry.npmjs.org"
-  }
-}

+ 0 - 10
content-metadata-protobuf/src/index.ts

@@ -1,10 +0,0 @@
-// Some helpers for constructing known licenses
-import licenses from './licenses'
-export { licenses }
-
-// protobuf message constructors
-export * from '../compiled/proto/Video_pb'
-export * from '../compiled/proto/Channel_pb'
-export * from '../compiled/proto/Person_pb'
-export * from '../compiled/proto/Playlist_pb'
-export * from '../compiled/proto/Series_pb'

+ 0 - 33
content-metadata-protobuf/test/channel.ts

@@ -1,33 +0,0 @@
-import { ChannelMetadata } from '../src'
-import { assert } from 'chai'
-
-describe('Channel Metadata', () => {
-  it('Message', () => {
-    const channel = new ChannelMetadata()
-
-    const title = 'title'
-    const description = 'description'
-    const isPublic = false
-    const language = 'fr'
-
-    channel.setTitle(title)
-    channel.setDescription(description)
-    channel.setIsPublic(isPublic)
-    channel.setLanguage(language)
-    channel.setAvatarPhoto(0)
-    channel.setCoverPhoto(1)
-    channel.setCategory(100)
-
-    assert.deepEqual(channel.toObject(), {
-      title,
-      description,
-      isPublic,
-      language,
-      avatarPhoto: 0,
-      coverPhoto: 1,
-      category: 100,
-    })
-
-    assert.deepEqual(ChannelMetadata.deserializeBinary(channel.serializeBinary()), channel)
-  })
-})

+ 0 - 115
content-metadata-protobuf/test/video.ts

@@ -1,115 +0,0 @@
-import { VideoMetadata, PublishedBeforeJoystream, MediaType, License } from '../src'
-import { assert, expect } from 'chai'
-
-describe('Video Metadata', () => {
-  it('Message', () => {
-    const meta = new VideoMetadata()
-
-    const title = 'Video Title'
-    const description = 'Video Description'
-    const duration = 100
-
-    meta.setTitle(title)
-    meta.setDescription(description)
-    meta.setDuration(duration)
-    meta.setMediaPixelHeight(1)
-    meta.setMediaPixelWidth(2)
-    meta.setMediaType(new MediaType())
-    meta.setLanguage('en')
-    meta.setLicense(new License())
-    meta.setPublishedBeforeJoystream(new PublishedBeforeJoystream())
-    meta.setHasMarketing(true)
-    meta.setIsPublic(true)
-    meta.setIsExplicit(false)
-    meta.setVideo(0)
-    meta.setThumbnailPhoto(1)
-    meta.setCategory(101)
-
-    assert.deepEqual(meta.toObject(), {
-      title,
-      description,
-      duration,
-      mediaPixelHeight: 1,
-      mediaPixelWidth: 2,
-      mediaType: {
-        codecName: undefined,
-        container: undefined,
-        mimeMediaType: undefined,
-      },
-      language: 'en',
-      license: {
-        code: undefined,
-        attribution: undefined,
-        customText: undefined,
-      },
-      publishedBeforeJoystream: { isPublished: undefined, date: undefined },
-      hasMarketing: true,
-      isPublic: true,
-      isExplicit: false,
-      thumbnailPhoto: 1,
-      video: 0,
-      personsList: [],
-      category: 101,
-    })
-
-    // sanity check - encoding / decoding works
-    assert.deepEqual(VideoMetadata.deserializeBinary(meta.serializeBinary()), meta)
-  })
-
-  it('Message: PublishedBeforeJoystream', () => {
-    const meta = new VideoMetadata()
-
-    expect(meta.hasPublishedBeforeJoystream()).equals(false, 'PublishedBeforeJoystream field should NOT be set')
-
-    const published = new PublishedBeforeJoystream()
-    const isPublished = true
-    const date = '1950-12-24'
-    published.setIsPublished(isPublished)
-    published.setDate(date)
-
-    meta.setPublishedBeforeJoystream(published)
-
-    // Field should now be set
-    expect(meta.hasPublishedBeforeJoystream()).equals(true, 'PublishedBeforeJoystream field should be set')
-
-    assert.deepEqual(published.toObject(), {
-      isPublished,
-      date,
-    })
-  })
-
-  it('Message: License', () => {
-    const license = new License()
-
-    const code = 1000
-    const attribution = 'Attribution Text'
-    const customText = 'Custom License Details'
-    license.setCode(code)
-    license.setAttribution(attribution)
-    license.setCustomText(customText)
-
-    assert.deepEqual(license.toObject(), {
-      code,
-      attribution,
-      customText,
-    })
-  })
-
-  it('Message: MediaType', () => {
-    const mediaType = new MediaType()
-
-    const codecName = 'mpeg4'
-    const container = 'avi'
-    const mimeMediaType = 'videp/mp4'
-
-    mediaType.setCodecName(codecName)
-    mediaType.setContainer(container)
-    mediaType.setMimeMediaType(mimeMediaType)
-
-    assert.deepEqual(mediaType.toObject(), {
-      codecName,
-      container,
-      mimeMediaType,
-    })
-  })
-})

+ 0 - 15
content-metadata-protobuf/tsconfig.json

@@ -1,15 +0,0 @@
-{
-  "compilerOptions": {
-    "target": "esnext",
-    "module": "commonjs",
-    "outDir": "lib",
-    "strict": true,
-    "declaration": true,
-    "esModuleInterop": true,
-    "forceConsistentCasingInFileNames": true,
-    "skipLibCheck": true,
-    "resolveJsonModule": true,
-  },
-  "include": ["src"],
-  "exclude": ["node_modules", "test"]
-}

+ 1 - 0
metadata-protobuf/.gitignore

@@ -1,2 +1,3 @@
 node_modules/
 lib/
+compiled/

+ 5 - 7
metadata-protobuf/README.md

@@ -1,6 +1,6 @@
-## Joystream Content Directory Metadata Library
+## Joystream Metadata Library
 
-This package contains protobuf message definitions compiled to Javascript/Typescript used for creating and updating various metadata blobs in the joystream content directory.
+This package contains protobuf message definitions compiled to Javascript/Typescript used for creating and updating various metadata blobs in Joystream.
 
 ### Message Specs
 
@@ -27,12 +27,10 @@ useful npm package https://www.npmjs.com/package/iso-639-1
 
 ### Building the package
 
-Building will compile the protofiles and build the library from source.
-
-- pre-requisists for compiling protofiles:
-    - [protoc](https://github.com/protocolbuffers/protobuf/releases)
+Building will compile the protofiles using [protobufjs](https://www.npmjs.com/package/protobufjs) and build the library from source.
 
 - pre-requisists for generating documentation:
+    - [protoc](https://github.com/protocolbuffers/protobuf/releases)
     - [golang](https://golang.org/)
     - [protoc-gen-doc](https://github.com/pseudomuto/protoc-gen-doc) to generate docs
 
@@ -50,4 +48,4 @@ yarn generate-docs
 
 ```
 yarn test
-```
+```

+ 0 - 16
metadata-protobuf/compile.sh

@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-
-# Directory to write generated code to (.js and .d.ts files)
-OUT_DIR="./compiled"
-mkdir -p ${OUT_DIR}
-
-yarn pbjs \
-  -t="static-module" \
-  -w="commonjs" \
-  -o="${OUT_DIR}/index.js" \
-  --force-long \
-  proto/*.proto
-
-yarn pbts \
-  -o="${OUT_DIR}/index.d.ts" \
-  ${OUT_DIR}/*.js

+ 0 - 505
metadata-protobuf/compiled/index.d.ts

@@ -1,505 +0,0 @@
-import { Long } from 'long'
-import * as $protobuf from "protobufjs";
-/** Properties of a GeoCoordiantes. */
-export interface IGeoCoordiantes {
-
-    /** GeoCoordiantes latitude */
-    latitude?: (number|null);
-
-    /** GeoCoordiantes longitude */
-    longitude?: (number|null);
-}
-
-/** Represents a GeoCoordiantes. */
-export class GeoCoordiantes implements IGeoCoordiantes {
-
-    /**
-     * Constructs a new GeoCoordiantes.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IGeoCoordiantes);
-
-    /** GeoCoordiantes latitude. */
-    public latitude: number;
-
-    /** GeoCoordiantes longitude. */
-    public longitude: number;
-
-    /**
-     * Creates a new GeoCoordiantes instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns GeoCoordiantes instance
-     */
-    public static create(properties?: IGeoCoordiantes): GeoCoordiantes;
-
-    /**
-     * Encodes the specified GeoCoordiantes message. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @param message GeoCoordiantes message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IGeoCoordiantes, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified GeoCoordiantes message, length delimited. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @param message GeoCoordiantes message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IGeoCoordiantes, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): GeoCoordiantes;
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): GeoCoordiantes;
-
-    /**
-     * Verifies a GeoCoordiantes message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a GeoCoordiantes message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns GeoCoordiantes
-     */
-    public static fromObject(object: { [k: string]: any }): GeoCoordiantes;
-
-    /**
-     * Creates a plain object from a GeoCoordiantes message. Also converts values to other types if specified.
-     * @param message GeoCoordiantes
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: GeoCoordiantes, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this GeoCoordiantes to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a NodeLocationMetadata. */
-export interface INodeLocationMetadata {
-
-    /** NodeLocationMetadata countryCode */
-    countryCode?: (string|null);
-
-    /** NodeLocationMetadata city */
-    city?: (string|null);
-
-    /** NodeLocationMetadata coordinates */
-    coordinates?: (IGeoCoordiantes|null);
-}
-
-/** Represents a NodeLocationMetadata. */
-export class NodeLocationMetadata implements INodeLocationMetadata {
-
-    /**
-     * Constructs a new NodeLocationMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: INodeLocationMetadata);
-
-    /** NodeLocationMetadata countryCode. */
-    public countryCode: string;
-
-    /** NodeLocationMetadata city. */
-    public city: string;
-
-    /** NodeLocationMetadata coordinates. */
-    public coordinates?: (IGeoCoordiantes|null);
-
-    /**
-     * Creates a new NodeLocationMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns NodeLocationMetadata instance
-     */
-    public static create(properties?: INodeLocationMetadata): NodeLocationMetadata;
-
-    /**
-     * Encodes the specified NodeLocationMetadata message. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @param message NodeLocationMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: INodeLocationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified NodeLocationMetadata message, length delimited. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @param message NodeLocationMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: INodeLocationMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): NodeLocationMetadata;
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): NodeLocationMetadata;
-
-    /**
-     * Verifies a NodeLocationMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a NodeLocationMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns NodeLocationMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): NodeLocationMetadata;
-
-    /**
-     * Creates a plain object from a NodeLocationMetadata message. Also converts values to other types if specified.
-     * @param message NodeLocationMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: NodeLocationMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this NodeLocationMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a StorageBucketOperatorMetadata. */
-export interface IStorageBucketOperatorMetadata {
-
-    /** StorageBucketOperatorMetadata endpoint */
-    endpoint?: (string|null);
-
-    /** StorageBucketOperatorMetadata location */
-    location?: (INodeLocationMetadata|null);
-
-    /** StorageBucketOperatorMetadata extra */
-    extra?: (string|null);
-}
-
-/** Represents a StorageBucketOperatorMetadata. */
-export class StorageBucketOperatorMetadata implements IStorageBucketOperatorMetadata {
-
-    /**
-     * Constructs a new StorageBucketOperatorMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IStorageBucketOperatorMetadata);
-
-    /** StorageBucketOperatorMetadata endpoint. */
-    public endpoint: string;
-
-    /** StorageBucketOperatorMetadata location. */
-    public location?: (INodeLocationMetadata|null);
-
-    /** StorageBucketOperatorMetadata extra. */
-    public extra: string;
-
-    /**
-     * Creates a new StorageBucketOperatorMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns StorageBucketOperatorMetadata instance
-     */
-    public static create(properties?: IStorageBucketOperatorMetadata): StorageBucketOperatorMetadata;
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @param message StorageBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IStorageBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message, length delimited. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @param message StorageBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IStorageBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): StorageBucketOperatorMetadata;
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): StorageBucketOperatorMetadata;
-
-    /**
-     * Verifies a StorageBucketOperatorMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a StorageBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns StorageBucketOperatorMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): StorageBucketOperatorMetadata;
-
-    /**
-     * Creates a plain object from a StorageBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @param message StorageBucketOperatorMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: StorageBucketOperatorMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this StorageBucketOperatorMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a DistributionBucketOperatorMetadata. */
-export interface IDistributionBucketOperatorMetadata {
-
-    /** DistributionBucketOperatorMetadata endpoint */
-    endpoint?: (string|null);
-
-    /** DistributionBucketOperatorMetadata location */
-    location?: (INodeLocationMetadata|null);
-
-    /** DistributionBucketOperatorMetadata extra */
-    extra?: (string|null);
-}
-
-/** Represents a DistributionBucketOperatorMetadata. */
-export class DistributionBucketOperatorMetadata implements IDistributionBucketOperatorMetadata {
-
-    /**
-     * Constructs a new DistributionBucketOperatorMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IDistributionBucketOperatorMetadata);
-
-    /** DistributionBucketOperatorMetadata endpoint. */
-    public endpoint: string;
-
-    /** DistributionBucketOperatorMetadata location. */
-    public location?: (INodeLocationMetadata|null);
-
-    /** DistributionBucketOperatorMetadata extra. */
-    public extra: string;
-
-    /**
-     * Creates a new DistributionBucketOperatorMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns DistributionBucketOperatorMetadata instance
-     */
-    public static create(properties?: IDistributionBucketOperatorMetadata): DistributionBucketOperatorMetadata;
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @param message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IDistributionBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message, length delimited. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @param message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IDistributionBucketOperatorMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): DistributionBucketOperatorMetadata;
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): DistributionBucketOperatorMetadata;
-
-    /**
-     * Verifies a DistributionBucketOperatorMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a DistributionBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns DistributionBucketOperatorMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): DistributionBucketOperatorMetadata;
-
-    /**
-     * Creates a plain object from a DistributionBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @param message DistributionBucketOperatorMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: DistributionBucketOperatorMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this DistributionBucketOperatorMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}
-
-/** Properties of a DistributionBucketFamilyMetadata. */
-export interface IDistributionBucketFamilyMetadata {
-
-    /** DistributionBucketFamilyMetadata region */
-    region?: (string|null);
-
-    /** DistributionBucketFamilyMetadata description */
-    description?: (string|null);
-
-    /** DistributionBucketFamilyMetadata boundary */
-    boundary?: (IGeoCoordiantes[]|null);
-}
-
-/** Represents a DistributionBucketFamilyMetadata. */
-export class DistributionBucketFamilyMetadata implements IDistributionBucketFamilyMetadata {
-
-    /**
-     * Constructs a new DistributionBucketFamilyMetadata.
-     * @param [properties] Properties to set
-     */
-    constructor(properties?: IDistributionBucketFamilyMetadata);
-
-    /** DistributionBucketFamilyMetadata region. */
-    public region: string;
-
-    /** DistributionBucketFamilyMetadata description. */
-    public description: string;
-
-    /** DistributionBucketFamilyMetadata boundary. */
-    public boundary: IGeoCoordiantes[];
-
-    /**
-     * Creates a new DistributionBucketFamilyMetadata instance using the specified properties.
-     * @param [properties] Properties to set
-     * @returns DistributionBucketFamilyMetadata instance
-     */
-    public static create(properties?: IDistributionBucketFamilyMetadata): DistributionBucketFamilyMetadata;
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @param message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encode(message: IDistributionBucketFamilyMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message, length delimited. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @param message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param [writer] Writer to encode to
-     * @returns Writer
-     */
-    public static encodeDelimited(message: IDistributionBucketFamilyMetadata, writer?: $protobuf.Writer): $protobuf.Writer;
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer.
-     * @param reader Reader or buffer to decode from
-     * @param [length] Message length if known beforehand
-     * @returns DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decode(reader: ($protobuf.Reader|Uint8Array), length?: number): DistributionBucketFamilyMetadata;
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer, length delimited.
-     * @param reader Reader or buffer to decode from
-     * @returns DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    public static decodeDelimited(reader: ($protobuf.Reader|Uint8Array)): DistributionBucketFamilyMetadata;
-
-    /**
-     * Verifies a DistributionBucketFamilyMetadata message.
-     * @param message Plain object to verify
-     * @returns `null` if valid, otherwise the reason why it is not
-     */
-    public static verify(message: { [k: string]: any }): (string|null);
-
-    /**
-     * Creates a DistributionBucketFamilyMetadata message from a plain object. Also converts values to their respective internal types.
-     * @param object Plain object
-     * @returns DistributionBucketFamilyMetadata
-     */
-    public static fromObject(object: { [k: string]: any }): DistributionBucketFamilyMetadata;
-
-    /**
-     * Creates a plain object from a DistributionBucketFamilyMetadata message. Also converts values to other types if specified.
-     * @param message DistributionBucketFamilyMetadata
-     * @param [options] Conversion options
-     * @returns Plain object
-     */
-    public static toObject(message: DistributionBucketFamilyMetadata, options?: $protobuf.IConversionOptions): { [k: string]: any };
-
-    /**
-     * Converts this DistributionBucketFamilyMetadata to JSON.
-     * @returns JSON object
-     */
-    public toJSON(): { [k: string]: any };
-}

+ 0 - 1187
metadata-protobuf/compiled/index.js

@@ -1,1187 +0,0 @@
-/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/
-"use strict";
-
-var $protobuf = require("protobufjs/minimal");
-
-// Common aliases
-var $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;
-
-// Exported root namespace
-var $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {});
-
-$root.GeoCoordiantes = (function() {
-
-    /**
-     * Properties of a GeoCoordiantes.
-     * @exports IGeoCoordiantes
-     * @interface IGeoCoordiantes
-     * @property {number|null} [latitude] GeoCoordiantes latitude
-     * @property {number|null} [longitude] GeoCoordiantes longitude
-     */
-
-    /**
-     * Constructs a new GeoCoordiantes.
-     * @exports GeoCoordiantes
-     * @classdesc Represents a GeoCoordiantes.
-     * @implements IGeoCoordiantes
-     * @constructor
-     * @param {IGeoCoordiantes=} [properties] Properties to set
-     */
-    function GeoCoordiantes(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * GeoCoordiantes latitude.
-     * @member {number} latitude
-     * @memberof GeoCoordiantes
-     * @instance
-     */
-    GeoCoordiantes.prototype.latitude = 0;
-
-    /**
-     * GeoCoordiantes longitude.
-     * @member {number} longitude
-     * @memberof GeoCoordiantes
-     * @instance
-     */
-    GeoCoordiantes.prototype.longitude = 0;
-
-    /**
-     * Creates a new GeoCoordiantes instance using the specified properties.
-     * @function create
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes=} [properties] Properties to set
-     * @returns {GeoCoordiantes} GeoCoordiantes instance
-     */
-    GeoCoordiantes.create = function create(properties) {
-        return new GeoCoordiantes(properties);
-    };
-
-    /**
-     * Encodes the specified GeoCoordiantes message. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @function encode
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes} message GeoCoordiantes message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    GeoCoordiantes.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.latitude != null && Object.hasOwnProperty.call(message, "latitude"))
-            writer.uint32(/* id 3, wireType 5 =*/29).float(message.latitude);
-        if (message.longitude != null && Object.hasOwnProperty.call(message, "longitude"))
-            writer.uint32(/* id 4, wireType 5 =*/37).float(message.longitude);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified GeoCoordiantes message, length delimited. Does not implicitly {@link GeoCoordiantes.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {IGeoCoordiantes} message GeoCoordiantes message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    GeoCoordiantes.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer.
-     * @function decode
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    GeoCoordiantes.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.GeoCoordiantes();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 3:
-                message.latitude = reader.float();
-                break;
-            case 4:
-                message.longitude = reader.float();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a GeoCoordiantes message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    GeoCoordiantes.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a GeoCoordiantes message.
-     * @function verify
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    GeoCoordiantes.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.latitude != null && message.hasOwnProperty("latitude"))
-            if (typeof message.latitude !== "number")
-                return "latitude: number expected";
-        if (message.longitude != null && message.hasOwnProperty("longitude"))
-            if (typeof message.longitude !== "number")
-                return "longitude: number expected";
-        return null;
-    };
-
-    /**
-     * Creates a GeoCoordiantes message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {GeoCoordiantes} GeoCoordiantes
-     */
-    GeoCoordiantes.fromObject = function fromObject(object) {
-        if (object instanceof $root.GeoCoordiantes)
-            return object;
-        var message = new $root.GeoCoordiantes();
-        if (object.latitude != null)
-            message.latitude = Number(object.latitude);
-        if (object.longitude != null)
-            message.longitude = Number(object.longitude);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a GeoCoordiantes message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof GeoCoordiantes
-     * @static
-     * @param {GeoCoordiantes} message GeoCoordiantes
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    GeoCoordiantes.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.latitude = 0;
-            object.longitude = 0;
-        }
-        if (message.latitude != null && message.hasOwnProperty("latitude"))
-            object.latitude = options.json && !isFinite(message.latitude) ? String(message.latitude) : message.latitude;
-        if (message.longitude != null && message.hasOwnProperty("longitude"))
-            object.longitude = options.json && !isFinite(message.longitude) ? String(message.longitude) : message.longitude;
-        return object;
-    };
-
-    /**
-     * Converts this GeoCoordiantes to JSON.
-     * @function toJSON
-     * @memberof GeoCoordiantes
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    GeoCoordiantes.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return GeoCoordiantes;
-})();
-
-$root.NodeLocationMetadata = (function() {
-
-    /**
-     * Properties of a NodeLocationMetadata.
-     * @exports INodeLocationMetadata
-     * @interface INodeLocationMetadata
-     * @property {string|null} [countryCode] NodeLocationMetadata countryCode
-     * @property {string|null} [city] NodeLocationMetadata city
-     * @property {IGeoCoordiantes|null} [coordinates] NodeLocationMetadata coordinates
-     */
-
-    /**
-     * Constructs a new NodeLocationMetadata.
-     * @exports NodeLocationMetadata
-     * @classdesc Represents a NodeLocationMetadata.
-     * @implements INodeLocationMetadata
-     * @constructor
-     * @param {INodeLocationMetadata=} [properties] Properties to set
-     */
-    function NodeLocationMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * NodeLocationMetadata countryCode.
-     * @member {string} countryCode
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.countryCode = "";
-
-    /**
-     * NodeLocationMetadata city.
-     * @member {string} city
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.city = "";
-
-    /**
-     * NodeLocationMetadata coordinates.
-     * @member {IGeoCoordiantes|null|undefined} coordinates
-     * @memberof NodeLocationMetadata
-     * @instance
-     */
-    NodeLocationMetadata.prototype.coordinates = null;
-
-    /**
-     * Creates a new NodeLocationMetadata instance using the specified properties.
-     * @function create
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata=} [properties] Properties to set
-     * @returns {NodeLocationMetadata} NodeLocationMetadata instance
-     */
-    NodeLocationMetadata.create = function create(properties) {
-        return new NodeLocationMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified NodeLocationMetadata message. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata} message NodeLocationMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    NodeLocationMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.countryCode != null && Object.hasOwnProperty.call(message, "countryCode"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.countryCode);
-        if (message.city != null && Object.hasOwnProperty.call(message, "city"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.city);
-        if (message.coordinates != null && Object.hasOwnProperty.call(message, "coordinates"))
-            $root.GeoCoordiantes.encode(message.coordinates, writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
-        return writer;
-    };
-
-    /**
-     * Encodes the specified NodeLocationMetadata message, length delimited. Does not implicitly {@link NodeLocationMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {INodeLocationMetadata} message NodeLocationMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    NodeLocationMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    NodeLocationMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.NodeLocationMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.countryCode = reader.string();
-                break;
-            case 2:
-                message.city = reader.string();
-                break;
-            case 3:
-                message.coordinates = $root.GeoCoordiantes.decode(reader, reader.uint32());
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a NodeLocationMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    NodeLocationMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a NodeLocationMetadata message.
-     * @function verify
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    NodeLocationMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.countryCode != null && message.hasOwnProperty("countryCode"))
-            if (!$util.isString(message.countryCode))
-                return "countryCode: string expected";
-        if (message.city != null && message.hasOwnProperty("city"))
-            if (!$util.isString(message.city))
-                return "city: string expected";
-        if (message.coordinates != null && message.hasOwnProperty("coordinates")) {
-            var error = $root.GeoCoordiantes.verify(message.coordinates);
-            if (error)
-                return "coordinates." + error;
-        }
-        return null;
-    };
-
-    /**
-     * Creates a NodeLocationMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {NodeLocationMetadata} NodeLocationMetadata
-     */
-    NodeLocationMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.NodeLocationMetadata)
-            return object;
-        var message = new $root.NodeLocationMetadata();
-        if (object.countryCode != null)
-            message.countryCode = String(object.countryCode);
-        if (object.city != null)
-            message.city = String(object.city);
-        if (object.coordinates != null) {
-            if (typeof object.coordinates !== "object")
-                throw TypeError(".NodeLocationMetadata.coordinates: object expected");
-            message.coordinates = $root.GeoCoordiantes.fromObject(object.coordinates);
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a NodeLocationMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof NodeLocationMetadata
-     * @static
-     * @param {NodeLocationMetadata} message NodeLocationMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    NodeLocationMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.countryCode = "";
-            object.city = "";
-            object.coordinates = null;
-        }
-        if (message.countryCode != null && message.hasOwnProperty("countryCode"))
-            object.countryCode = message.countryCode;
-        if (message.city != null && message.hasOwnProperty("city"))
-            object.city = message.city;
-        if (message.coordinates != null && message.hasOwnProperty("coordinates"))
-            object.coordinates = $root.GeoCoordiantes.toObject(message.coordinates, options);
-        return object;
-    };
-
-    /**
-     * Converts this NodeLocationMetadata to JSON.
-     * @function toJSON
-     * @memberof NodeLocationMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    NodeLocationMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return NodeLocationMetadata;
-})();
-
-$root.StorageBucketOperatorMetadata = (function() {
-
-    /**
-     * Properties of a StorageBucketOperatorMetadata.
-     * @exports IStorageBucketOperatorMetadata
-     * @interface IStorageBucketOperatorMetadata
-     * @property {string|null} [endpoint] StorageBucketOperatorMetadata endpoint
-     * @property {INodeLocationMetadata|null} [location] StorageBucketOperatorMetadata location
-     * @property {string|null} [extra] StorageBucketOperatorMetadata extra
-     */
-
-    /**
-     * Constructs a new StorageBucketOperatorMetadata.
-     * @exports StorageBucketOperatorMetadata
-     * @classdesc Represents a StorageBucketOperatorMetadata.
-     * @implements IStorageBucketOperatorMetadata
-     * @constructor
-     * @param {IStorageBucketOperatorMetadata=} [properties] Properties to set
-     */
-    function StorageBucketOperatorMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * StorageBucketOperatorMetadata endpoint.
-     * @member {string} endpoint
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.endpoint = "";
-
-    /**
-     * StorageBucketOperatorMetadata location.
-     * @member {INodeLocationMetadata|null|undefined} location
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.location = null;
-
-    /**
-     * StorageBucketOperatorMetadata extra.
-     * @member {string} extra
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     */
-    StorageBucketOperatorMetadata.prototype.extra = "";
-
-    /**
-     * Creates a new StorageBucketOperatorMetadata instance using the specified properties.
-     * @function create
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata=} [properties] Properties to set
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata instance
-     */
-    StorageBucketOperatorMetadata.create = function create(properties) {
-        return new StorageBucketOperatorMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata} message StorageBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    StorageBucketOperatorMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.endpoint != null && Object.hasOwnProperty.call(message, "endpoint"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.endpoint);
-        if (message.location != null && Object.hasOwnProperty.call(message, "location"))
-            $root.NodeLocationMetadata.encode(message.location, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
-        if (message.extra != null && Object.hasOwnProperty.call(message, "extra"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.extra);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified StorageBucketOperatorMetadata message, length delimited. Does not implicitly {@link StorageBucketOperatorMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {IStorageBucketOperatorMetadata} message StorageBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    StorageBucketOperatorMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    StorageBucketOperatorMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.StorageBucketOperatorMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.endpoint = reader.string();
-                break;
-            case 2:
-                message.location = $root.NodeLocationMetadata.decode(reader, reader.uint32());
-                break;
-            case 3:
-                message.extra = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a StorageBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    StorageBucketOperatorMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a StorageBucketOperatorMetadata message.
-     * @function verify
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    StorageBucketOperatorMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            if (!$util.isString(message.endpoint))
-                return "endpoint: string expected";
-        if (message.location != null && message.hasOwnProperty("location")) {
-            var error = $root.NodeLocationMetadata.verify(message.location);
-            if (error)
-                return "location." + error;
-        }
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            if (!$util.isString(message.extra))
-                return "extra: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a StorageBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {StorageBucketOperatorMetadata} StorageBucketOperatorMetadata
-     */
-    StorageBucketOperatorMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.StorageBucketOperatorMetadata)
-            return object;
-        var message = new $root.StorageBucketOperatorMetadata();
-        if (object.endpoint != null)
-            message.endpoint = String(object.endpoint);
-        if (object.location != null) {
-            if (typeof object.location !== "object")
-                throw TypeError(".StorageBucketOperatorMetadata.location: object expected");
-            message.location = $root.NodeLocationMetadata.fromObject(object.location);
-        }
-        if (object.extra != null)
-            message.extra = String(object.extra);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a StorageBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof StorageBucketOperatorMetadata
-     * @static
-     * @param {StorageBucketOperatorMetadata} message StorageBucketOperatorMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    StorageBucketOperatorMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.endpoint = "";
-            object.location = null;
-            object.extra = "";
-        }
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            object.endpoint = message.endpoint;
-        if (message.location != null && message.hasOwnProperty("location"))
-            object.location = $root.NodeLocationMetadata.toObject(message.location, options);
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            object.extra = message.extra;
-        return object;
-    };
-
-    /**
-     * Converts this StorageBucketOperatorMetadata to JSON.
-     * @function toJSON
-     * @memberof StorageBucketOperatorMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    StorageBucketOperatorMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return StorageBucketOperatorMetadata;
-})();
-
-$root.DistributionBucketOperatorMetadata = (function() {
-
-    /**
-     * Properties of a DistributionBucketOperatorMetadata.
-     * @exports IDistributionBucketOperatorMetadata
-     * @interface IDistributionBucketOperatorMetadata
-     * @property {string|null} [endpoint] DistributionBucketOperatorMetadata endpoint
-     * @property {INodeLocationMetadata|null} [location] DistributionBucketOperatorMetadata location
-     * @property {string|null} [extra] DistributionBucketOperatorMetadata extra
-     */
-
-    /**
-     * Constructs a new DistributionBucketOperatorMetadata.
-     * @exports DistributionBucketOperatorMetadata
-     * @classdesc Represents a DistributionBucketOperatorMetadata.
-     * @implements IDistributionBucketOperatorMetadata
-     * @constructor
-     * @param {IDistributionBucketOperatorMetadata=} [properties] Properties to set
-     */
-    function DistributionBucketOperatorMetadata(properties) {
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * DistributionBucketOperatorMetadata endpoint.
-     * @member {string} endpoint
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.endpoint = "";
-
-    /**
-     * DistributionBucketOperatorMetadata location.
-     * @member {INodeLocationMetadata|null|undefined} location
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.location = null;
-
-    /**
-     * DistributionBucketOperatorMetadata extra.
-     * @member {string} extra
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     */
-    DistributionBucketOperatorMetadata.prototype.extra = "";
-
-    /**
-     * Creates a new DistributionBucketOperatorMetadata instance using the specified properties.
-     * @function create
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata=} [properties] Properties to set
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata instance
-     */
-    DistributionBucketOperatorMetadata.create = function create(properties) {
-        return new DistributionBucketOperatorMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketOperatorMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.endpoint != null && Object.hasOwnProperty.call(message, "endpoint"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.endpoint);
-        if (message.location != null && Object.hasOwnProperty.call(message, "location"))
-            $root.NodeLocationMetadata.encode(message.location, writer.uint32(/* id 2, wireType 2 =*/18).fork()).ldelim();
-        if (message.extra != null && Object.hasOwnProperty.call(message, "extra"))
-            writer.uint32(/* id 3, wireType 2 =*/26).string(message.extra);
-        return writer;
-    };
-
-    /**
-     * Encodes the specified DistributionBucketOperatorMetadata message, length delimited. Does not implicitly {@link DistributionBucketOperatorMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {IDistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketOperatorMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketOperatorMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.DistributionBucketOperatorMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.endpoint = reader.string();
-                break;
-            case 2:
-                message.location = $root.NodeLocationMetadata.decode(reader, reader.uint32());
-                break;
-            case 3:
-                message.extra = reader.string();
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a DistributionBucketOperatorMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketOperatorMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a DistributionBucketOperatorMetadata message.
-     * @function verify
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    DistributionBucketOperatorMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            if (!$util.isString(message.endpoint))
-                return "endpoint: string expected";
-        if (message.location != null && message.hasOwnProperty("location")) {
-            var error = $root.NodeLocationMetadata.verify(message.location);
-            if (error)
-                return "location." + error;
-        }
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            if (!$util.isString(message.extra))
-                return "extra: string expected";
-        return null;
-    };
-
-    /**
-     * Creates a DistributionBucketOperatorMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {DistributionBucketOperatorMetadata} DistributionBucketOperatorMetadata
-     */
-    DistributionBucketOperatorMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.DistributionBucketOperatorMetadata)
-            return object;
-        var message = new $root.DistributionBucketOperatorMetadata();
-        if (object.endpoint != null)
-            message.endpoint = String(object.endpoint);
-        if (object.location != null) {
-            if (typeof object.location !== "object")
-                throw TypeError(".DistributionBucketOperatorMetadata.location: object expected");
-            message.location = $root.NodeLocationMetadata.fromObject(object.location);
-        }
-        if (object.extra != null)
-            message.extra = String(object.extra);
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a DistributionBucketOperatorMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof DistributionBucketOperatorMetadata
-     * @static
-     * @param {DistributionBucketOperatorMetadata} message DistributionBucketOperatorMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    DistributionBucketOperatorMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.defaults) {
-            object.endpoint = "";
-            object.location = null;
-            object.extra = "";
-        }
-        if (message.endpoint != null && message.hasOwnProperty("endpoint"))
-            object.endpoint = message.endpoint;
-        if (message.location != null && message.hasOwnProperty("location"))
-            object.location = $root.NodeLocationMetadata.toObject(message.location, options);
-        if (message.extra != null && message.hasOwnProperty("extra"))
-            object.extra = message.extra;
-        return object;
-    };
-
-    /**
-     * Converts this DistributionBucketOperatorMetadata to JSON.
-     * @function toJSON
-     * @memberof DistributionBucketOperatorMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    DistributionBucketOperatorMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return DistributionBucketOperatorMetadata;
-})();
-
-$root.DistributionBucketFamilyMetadata = (function() {
-
-    /**
-     * Properties of a DistributionBucketFamilyMetadata.
-     * @exports IDistributionBucketFamilyMetadata
-     * @interface IDistributionBucketFamilyMetadata
-     * @property {string|null} [region] DistributionBucketFamilyMetadata region
-     * @property {string|null} [description] DistributionBucketFamilyMetadata description
-     * @property {Array.<IGeoCoordiantes>|null} [boundary] DistributionBucketFamilyMetadata boundary
-     */
-
-    /**
-     * Constructs a new DistributionBucketFamilyMetadata.
-     * @exports DistributionBucketFamilyMetadata
-     * @classdesc Represents a DistributionBucketFamilyMetadata.
-     * @implements IDistributionBucketFamilyMetadata
-     * @constructor
-     * @param {IDistributionBucketFamilyMetadata=} [properties] Properties to set
-     */
-    function DistributionBucketFamilyMetadata(properties) {
-        this.boundary = [];
-        if (properties)
-            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
-                if (properties[keys[i]] != null)
-                    this[keys[i]] = properties[keys[i]];
-    }
-
-    /**
-     * DistributionBucketFamilyMetadata region.
-     * @member {string} region
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.region = "";
-
-    /**
-     * DistributionBucketFamilyMetadata description.
-     * @member {string} description
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.description = "";
-
-    /**
-     * DistributionBucketFamilyMetadata boundary.
-     * @member {Array.<IGeoCoordiantes>} boundary
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     */
-    DistributionBucketFamilyMetadata.prototype.boundary = $util.emptyArray;
-
-    /**
-     * Creates a new DistributionBucketFamilyMetadata instance using the specified properties.
-     * @function create
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata=} [properties] Properties to set
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata instance
-     */
-    DistributionBucketFamilyMetadata.create = function create(properties) {
-        return new DistributionBucketFamilyMetadata(properties);
-    };
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @function encode
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketFamilyMetadata.encode = function encode(message, writer) {
-        if (!writer)
-            writer = $Writer.create();
-        if (message.region != null && Object.hasOwnProperty.call(message, "region"))
-            writer.uint32(/* id 1, wireType 2 =*/10).string(message.region);
-        if (message.description != null && Object.hasOwnProperty.call(message, "description"))
-            writer.uint32(/* id 2, wireType 2 =*/18).string(message.description);
-        if (message.boundary != null && message.boundary.length)
-            for (var i = 0; i < message.boundary.length; ++i)
-                $root.GeoCoordiantes.encode(message.boundary[i], writer.uint32(/* id 3, wireType 2 =*/26).fork()).ldelim();
-        return writer;
-    };
-
-    /**
-     * Encodes the specified DistributionBucketFamilyMetadata message, length delimited. Does not implicitly {@link DistributionBucketFamilyMetadata.verify|verify} messages.
-     * @function encodeDelimited
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {IDistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata message or plain object to encode
-     * @param {$protobuf.Writer} [writer] Writer to encode to
-     * @returns {$protobuf.Writer} Writer
-     */
-    DistributionBucketFamilyMetadata.encodeDelimited = function encodeDelimited(message, writer) {
-        return this.encode(message, writer).ldelim();
-    };
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer.
-     * @function decode
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @param {number} [length] Message length if known beforehand
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketFamilyMetadata.decode = function decode(reader, length) {
-        if (!(reader instanceof $Reader))
-            reader = $Reader.create(reader);
-        var end = length === undefined ? reader.len : reader.pos + length, message = new $root.DistributionBucketFamilyMetadata();
-        while (reader.pos < end) {
-            var tag = reader.uint32();
-            switch (tag >>> 3) {
-            case 1:
-                message.region = reader.string();
-                break;
-            case 2:
-                message.description = reader.string();
-                break;
-            case 3:
-                if (!(message.boundary && message.boundary.length))
-                    message.boundary = [];
-                message.boundary.push($root.GeoCoordiantes.decode(reader, reader.uint32()));
-                break;
-            default:
-                reader.skipType(tag & 7);
-                break;
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Decodes a DistributionBucketFamilyMetadata message from the specified reader or buffer, length delimited.
-     * @function decodeDelimited
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     * @throws {Error} If the payload is not a reader or valid buffer
-     * @throws {$protobuf.util.ProtocolError} If required fields are missing
-     */
-    DistributionBucketFamilyMetadata.decodeDelimited = function decodeDelimited(reader) {
-        if (!(reader instanceof $Reader))
-            reader = new $Reader(reader);
-        return this.decode(reader, reader.uint32());
-    };
-
-    /**
-     * Verifies a DistributionBucketFamilyMetadata message.
-     * @function verify
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {Object.<string,*>} message Plain object to verify
-     * @returns {string|null} `null` if valid, otherwise the reason why it is not
-     */
-    DistributionBucketFamilyMetadata.verify = function verify(message) {
-        if (typeof message !== "object" || message === null)
-            return "object expected";
-        if (message.region != null && message.hasOwnProperty("region"))
-            if (!$util.isString(message.region))
-                return "region: string expected";
-        if (message.description != null && message.hasOwnProperty("description"))
-            if (!$util.isString(message.description))
-                return "description: string expected";
-        if (message.boundary != null && message.hasOwnProperty("boundary")) {
-            if (!Array.isArray(message.boundary))
-                return "boundary: array expected";
-            for (var i = 0; i < message.boundary.length; ++i) {
-                var error = $root.GeoCoordiantes.verify(message.boundary[i]);
-                if (error)
-                    return "boundary." + error;
-            }
-        }
-        return null;
-    };
-
-    /**
-     * Creates a DistributionBucketFamilyMetadata message from a plain object. Also converts values to their respective internal types.
-     * @function fromObject
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {Object.<string,*>} object Plain object
-     * @returns {DistributionBucketFamilyMetadata} DistributionBucketFamilyMetadata
-     */
-    DistributionBucketFamilyMetadata.fromObject = function fromObject(object) {
-        if (object instanceof $root.DistributionBucketFamilyMetadata)
-            return object;
-        var message = new $root.DistributionBucketFamilyMetadata();
-        if (object.region != null)
-            message.region = String(object.region);
-        if (object.description != null)
-            message.description = String(object.description);
-        if (object.boundary) {
-            if (!Array.isArray(object.boundary))
-                throw TypeError(".DistributionBucketFamilyMetadata.boundary: array expected");
-            message.boundary = [];
-            for (var i = 0; i < object.boundary.length; ++i) {
-                if (typeof object.boundary[i] !== "object")
-                    throw TypeError(".DistributionBucketFamilyMetadata.boundary: object expected");
-                message.boundary[i] = $root.GeoCoordiantes.fromObject(object.boundary[i]);
-            }
-        }
-        return message;
-    };
-
-    /**
-     * Creates a plain object from a DistributionBucketFamilyMetadata message. Also converts values to other types if specified.
-     * @function toObject
-     * @memberof DistributionBucketFamilyMetadata
-     * @static
-     * @param {DistributionBucketFamilyMetadata} message DistributionBucketFamilyMetadata
-     * @param {$protobuf.IConversionOptions} [options] Conversion options
-     * @returns {Object.<string,*>} Plain object
-     */
-    DistributionBucketFamilyMetadata.toObject = function toObject(message, options) {
-        if (!options)
-            options = {};
-        var object = {};
-        if (options.arrays || options.defaults)
-            object.boundary = [];
-        if (options.defaults) {
-            object.region = "";
-            object.description = "";
-        }
-        if (message.region != null && message.hasOwnProperty("region"))
-            object.region = message.region;
-        if (message.description != null && message.hasOwnProperty("description"))
-            object.description = message.description;
-        if (message.boundary && message.boundary.length) {
-            object.boundary = [];
-            for (var j = 0; j < message.boundary.length; ++j)
-                object.boundary[j] = $root.GeoCoordiantes.toObject(message.boundary[j], options);
-        }
-        return object;
-    };
-
-    /**
-     * Converts this DistributionBucketFamilyMetadata to JSON.
-     * @function toJSON
-     * @memberof DistributionBucketFamilyMetadata
-     * @instance
-     * @returns {Object.<string,*>} JSON object
-     */
-    DistributionBucketFamilyMetadata.prototype.toJSON = function toJSON() {
-        return this.constructor.toObject(this, $protobuf.util.toJSONOptions);
-    };
-
-    return DistributionBucketFamilyMetadata;
-})();
-
-module.exports = $root;

+ 0 - 0
content-metadata-protobuf/doc-appendix.md → metadata-protobuf/doc-appendix.md


+ 389 - 6
metadata-protobuf/doc/index.md

@@ -3,17 +3,213 @@
 
 ## Table of Contents
 
+- [proto/Channel.proto](#proto/Channel.proto)
+    - [ChannelCategoryMetadata](#.ChannelCategoryMetadata)
+    - [ChannelMetadata](#.ChannelMetadata)
+  
+- [proto/Person.proto](#proto/Person.proto)
+    - [PersonMetadata](#.PersonMetadata)
+  
+- [proto/Playlist.proto](#proto/Playlist.proto)
+    - [PlaylistMetadata](#.PlaylistMetadata)
+  
+- [proto/Series.proto](#proto/Series.proto)
+    - [SeasonMetadata](#.SeasonMetadata)
+    - [SeriesMetadata](#.SeriesMetadata)
+  
 - [proto/Storage.proto](#proto/Storage.proto)
     - [DistributionBucketFamilyMetadata](#.DistributionBucketFamilyMetadata)
     - [DistributionBucketOperatorMetadata](#.DistributionBucketOperatorMetadata)
     - [GeoCoordiantes](#.GeoCoordiantes)
+    - [GeographicalArea](#.GeographicalArea)
     - [NodeLocationMetadata](#.NodeLocationMetadata)
     - [StorageBucketOperatorMetadata](#.StorageBucketOperatorMetadata)
   
+    - [GeographicalArea.Continent](#.GeographicalArea.Continent)
+  
+- [proto/Video.proto](#proto/Video.proto)
+    - [License](#.License)
+    - [MediaType](#.MediaType)
+    - [PublishedBeforeJoystream](#.PublishedBeforeJoystream)
+    - [VideoCategoryMetadata](#.VideoCategoryMetadata)
+    - [VideoMetadata](#.VideoMetadata)
+  
 - [Scalar Value Types](#scalar-value-types)
 
 
 
+<a name="proto/Channel.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Channel.proto
+
+
+
+<a name=".ChannelCategoryMetadata"></a>
+
+### ChannelCategoryMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| name | [string](#string) | optional | Category Name |
+
+
+
+
+
+
+<a name=".ChannelMetadata"></a>
+
+### ChannelMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional | Channel Title |
+| description | [string](#string) | optional | Channel Description |
+| is_public | [bool](#bool) | optional | Wether to display channel to the public |
+| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| category | [uint64](#uint64) | optional | Channel Category Id |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Person.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Person.proto
+
+
+
+<a name=".PersonMetadata"></a>
+
+### PersonMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| first_name | [string](#string) | optional |  |
+| middle_name | [string](#string) | optional |  |
+| last_name | [string](#string) | optional |  |
+| about | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| avatar_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Playlist.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Playlist.proto
+
+
+
+<a name=".PlaylistMetadata"></a>
+
+### PlaylistMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| videos | [uint64](#uint64) | repeated | Videos in the playlist |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Series.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Series.proto
+
+
+
+<a name=".SeasonMetadata"></a>
+
+### SeasonMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| description | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Season |
+
+
+
+
+
+
+<a name=".SeriesMetadata"></a>
+
+### SeriesMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional |  |
+| description | [string](#string) | optional |  |
+| cover_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this Series |
+
+
+
+
+
+ 
+
+ 
+
+ 
+
+ 
+
+
+
 <a name="proto/Storage.proto"></a>
 <p align="right"><a href="#top">Top</a></p>
 
@@ -31,7 +227,8 @@
 | ----- | ---- | ----- | ----------- |
 | region | [string](#string) | optional | ID / name of the region covered by the distribution family (ie. us-east-1). Should be unique. |
 | description | [string](#string) | optional | Additional, more specific description of the region |
-| boundary | [GeoCoordiantes](#GeoCoordiantes) | repeated | Geographical boundary of the region, defined as polygon through array of coordinates |
+| areas | [GeographicalArea](#GeographicalArea) | repeated | Standarized geographical areas covered by the family (providing [{}] will unset the current value) |
+| latency_test_targets | [string](#string) | repeated | List of targets (hosts/ips) best suited latency measurements for this family |
 
 
 
@@ -47,7 +244,7 @@
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
 | endpoint | [string](#string) | optional | Root distribution node endpoint (ie. https://example.com/distribution) |
-| location | [NodeLocationMetadata](#NodeLocationMetadata) | optional | Information about node&#39;s phisical location |
+| location | [NodeLocationMetadata](#NodeLocationMetadata) | optional | Information about node&#39;s phisical location (providing {} will unset current value) |
 | extra | [string](#string) | optional | Additional information about the node / node operator |
 
 
@@ -63,8 +260,25 @@
 
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
-| latitude | [float](#float) | required |  |
-| longitude | [float](#float) | required |  |
+| latitude | [float](#float) | optional |  |
+| longitude | [float](#float) | optional |  |
+
+
+
+
+
+
+<a name=".GeographicalArea"></a>
+
+### GeographicalArea
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| continent | [GeographicalArea.Continent](#GeographicalArea.Continent) | optional |  |
+| country_code | [string](#string) | optional | ISO 3166-1 alpha-2 country code |
+| subdivision_code | [string](#string) | optional | ISO 3166-2 subdivision code |
 
 
 
@@ -81,7 +295,7 @@
 | ----- | ---- | ----- | ----------- |
 | country_code | [string](#string) | optional | ISO 3166-1 alpha-2 country code (2 letters) |
 | city | [string](#string) | optional | City name |
-| coordinates | [GeoCoordiantes](#GeoCoordiantes) | optional | Geographic coordinates |
+| coordinates | [GeoCoordiantes](#GeoCoordiantes) | optional | Geographic coordinates (providing {} will unset current value) |
 
 
 
@@ -97,7 +311,7 @@
 | Field | Type | Label | Description |
 | ----- | ---- | ----- | ----------- |
 | endpoint | [string](#string) | optional | Root storage node endpoint (ie. https://example.com/storage) |
-| location | [NodeLocationMetadata](#NodeLocationMetadata) | optional | Information about node&#39;s phisical location |
+| location | [NodeLocationMetadata](#NodeLocationMetadata) | optional | Information about node&#39;s phisical location (providing {} will unset current value) |
 | extra | [string](#string) | optional | Additional information about the node / node operator |
 
 
@@ -106,6 +320,134 @@
 
  
 
+
+<a name=".GeographicalArea.Continent"></a>
+
+### GeographicalArea.Continent
+
+
+| Name | Number | Description |
+| ---- | ------ | ----------- |
+| AF | 1 |  |
+| NA | 2 |  |
+| OC | 3 |  |
+| AN | 4 |  |
+| AS | 5 |  |
+| EU | 6 |  |
+| SA | 7 |  |
+
+
+ 
+
+ 
+
+ 
+
+
+
+<a name="proto/Video.proto"></a>
+<p align="right"><a href="#top">Top</a></p>
+
+## proto/Video.proto
+
+
+
+<a name=".License"></a>
+
+### License
+License types defined by Joystream
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| code | [uint32](#uint32) | optional | License code defined by Joystream. [reference](../src/KnownLicenses.json) |
+| attribution | [string](#string) | optional | Text for licenses that require an attribution |
+| custom_text | [string](#string) | optional | Text for custom license type |
+
+
+
+
+
+
+<a name=".MediaType"></a>
+
+### MediaType
+Codec, Container, MIME media-type information
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| codec_name | [string](#string) | optional | Codec corresponding to `name` field from [FFmpeg](https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/codec_desc.c) |
+| container | [string](#string) | optional | Video container format, eg. &#39;MP4&#39;, &#39;WebM&#39;, &#39;Ogg&#39; [ref](https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_codecs) |
+| mime_media_type | [string](#string) | optional | MIME Media Type, eg. &#39;video/mp4&#39; [ref](https://www.iana.org/assignments/media-types/media-types.xhtml#video) |
+
+
+
+
+
+
+<a name=".PublishedBeforeJoystream"></a>
+
+### PublishedBeforeJoystream
+Publication status before joystream
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| is_published | [bool](#bool) | optional | Was video published before joystream platform |
+| date | [string](#string) | optional | Date of publication: &#39;YYYY-MM-DD&#39; [ISO-8601](https://www.iso.org/iso-8601-date-and-time-format.html) |
+
+
+
+
+
+
+<a name=".VideoCategoryMetadata"></a>
+
+### VideoCategoryMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| name | [string](#string) | optional | Category name |
+
+
+
+
+
+
+<a name=".VideoMetadata"></a>
+
+### VideoMetadata
+
+
+
+| Field | Type | Label | Description |
+| ----- | ---- | ----- | ----------- |
+| title | [string](#string) | optional | Video Title |
+| description | [string](#string) | optional | Video Description |
+| video | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| thumbnail_photo | [uint32](#uint32) | optional | index into external [assets array](#.Assets) |
+| duration | [uint32](#uint32) | optional | Lengths of video in seconds |
+| media_pixel_height | [uint32](#uint32) | optional | Resolution of the video (Height) |
+| media_pixel_width | [uint32](#uint32) | optional | Resolution of the video (Width) |
+| media_type | [MediaType](#MediaType) | optional | Encoding and Container format used |
+| language | [string](#string) | optional | ISO_639-1 Language [Code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) |
+| license | [License](#License) | optional | License type for the media |
+| published_before_joystream | [PublishedBeforeJoystream](#PublishedBeforeJoystream) | optional | Date of publication |
+| has_marketing | [bool](#bool) | optional | Does video have marketing or advertising in the stream |
+| is_public | [bool](#bool) | optional | Should video be publicy visible yet |
+| is_explicit | [bool](#bool) | optional | Does Video have explicit language or scenes |
+| persons | [uint64](#uint64) | repeated | Person(s) referenced by PersonId involved in this video |
+| category | [uint64](#uint64) | optional | Video Category Id |
+
+
+
+
+
+ 
+
  
 
  
@@ -134,3 +476,44 @@
 | <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
 | <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
 
+<!-- 
+    This extra documentation will be appended to the generated docs.
+-->
+
+## Referencing Assets
+<a name=".Assets"></a>
+
+Applications that process messages that contain a `uint32` field that references an asset such as a cover photo or video, should interpret this value as a zero based index into an array/vector that is received external (out of band) to the protobuf message.
+
+Example in context of query-node processing the runtime event `VideoCreated`
+
+```rust
+// Runtime event associated with creating a Video
+VideoCreated(video_id: VideoId, video: Video, assets: Vec<NewAsset>, params: VideoCreationParameters)
+
+struct VideoCreationParameters {
+  in_category: VideoCategoryId,
+  // binary serialized VideoMetadata protobuf message
+  meta: Vec<u8>,
+}
+
+// suppose assets is a vector of two elements. This is the "out of band" array being referenced by the VideoMetadata message
+assets = [
+    NewAsset::Uri("https://mydomain.net/thumbnail.png"),
+    NewAsset::Upload({
+       content_id,
+       ipfs_hash,
+       size,
+       ...
+    }),
+];
+
+meta = VideoMetadata {
+    ...
+    // refers to second element: assets[1] which is being uploaded to the storage system
+    video: 1,
+    // refers to the first element assets[0] which is being referneced by a url string.
+    thumbnail_photo: 0,
+    ...
+};
+```

+ 3 - 0
metadata-protobuf/generate-md-doc.sh

@@ -8,3 +8,6 @@ mkdir -p ${OUT_DIR_DOC}
 protoc \
     --doc_out="${OUT_DIR_DOC}" --doc_opt=markdown,index.md \
     proto/*.proto
+
+# Append some custom docs to generated protocol docs
+cat doc-appendix.md >> ${OUT_DIR_DOC}/index.md

+ 6 - 2
metadata-protobuf/package.json

@@ -26,7 +26,8 @@
     "test": "env TS_NODE_COMPILER_OPTIONS='{\"module\": \"commonjs\" }' mocha --inline-diffs -r ts-node/register 'test/**/*.ts'",
     "lint": "eslint ./src --ext .ts",
     "checks": "tsc --noEmit --pretty && prettier ./ --check && yarn lint",
-    "format": "prettier ./ --write"
+    "format": "prettier ./ --write",
+    "prepublish": "yarn build"
   },
   "files": [
     "lib/**/*",
@@ -39,7 +40,10 @@
     "google-protobuf": "^3.14.0",
     "long": "^4.0.0",
     "@types/long": "^4.0.1",
-    "i18n-iso-countries": "^6.8.0"
+    "i18n-iso-countries": "^6.8.0",
+    "iso-639-1": "^2.1.9",
+    "iso-3166-2": "^1.0.0",
+    "@types/iso-3166-2": "^1.0.0"
   },
   "devDependencies": {
     "@types/chai": "^4.2.11",

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


+ 0 - 0
content-metadata-protobuf/proto/Person.proto → metadata-protobuf/proto/Person.proto


+ 0 - 0
content-metadata-protobuf/proto/Playlist.proto → metadata-protobuf/proto/Playlist.proto


+ 0 - 0
content-metadata-protobuf/proto/Series.proto → metadata-protobuf/proto/Series.proto


+ 19 - 1
metadata-protobuf/proto/Storage.proto

@@ -23,8 +23,26 @@ message DistributionBucketOperatorMetadata {
   optional string extra = 3; // Additional information about the node / node operator
 }
 
+message GeographicalArea {
+  enum Continent {
+    AF = 1;
+    NA = 2;
+    OC = 3;
+    AN = 4;
+    AS = 5;
+    EU = 6;
+    SA = 7;
+  }
+  oneof code {
+    Continent continent = 1;
+    string country_code = 2; // ISO 3166-1 alpha-2 country code
+    string subdivision_code = 3; // ISO 3166-2 subdivision code
+  }
+}
+
 message DistributionBucketFamilyMetadata {
   optional string region = 1; // ID / name of the region covered by the distribution family (ie. us-east-1). Should be unique.
   optional string description = 2; // Additional, more specific description of the region
-  repeated GeoCoordiantes boundary = 3; // Geographical boundary of the region, defined as polygon through array of coordinates (providing [{}] will unset the current value)
+  repeated GeographicalArea areas = 3; // Standarized geographical areas covered by the family (providing [{}] will unset the current value)
+  repeated string latency_test_targets = 4; // List of targets (hosts/ips) best suited latency measurements for this family
 }

+ 0 - 0
content-metadata-protobuf/proto/Video.proto → metadata-protobuf/proto/Video.proto


+ 4 - 0
metadata-protobuf/scripts/compile.ts

@@ -5,6 +5,10 @@ import fs from 'fs'
 
 const OUT_DIR = path.resolve(__dirname, '../compiled')
 
+if (!fs.existsSync(OUT_DIR)) {
+  fs.mkdirSync(OUT_DIR)
+}
+
 pbjs(
   ['--target', 'static-module', '-w', 'commonjs', '-o', `${OUT_DIR}/index.js`, '--force-long', 'proto/*.proto'],
   function (err) {

+ 0 - 0
content-metadata-protobuf/src/KnownLicenses.json → metadata-protobuf/src/KnownLicenses.json


+ 4 - 10
content-metadata-protobuf/src/licenses.ts → metadata-protobuf/src/licenses.ts

@@ -2,7 +2,7 @@
 // This should be factored out into a separate package
 
 import LICENSES from './KnownLicenses.json'
-import { License } from '../compiled/proto/Video_pb'
+import { License } from '../compiled/index'
 
 export type LicenseCode = number
 export const CUSTOM_LICENSE_CODE: LicenseCode = 1000
@@ -39,26 +39,20 @@ export function createKnownLicenseFromCode(code: LicenseCode, attribution?: stri
     throw new Error('Unknown License Code')
   }
 
-  const license = new License()
-
-  license.setCode(code)
+  const license = new License({ code })
 
   if (knownLicense.attributionRequired) {
     if (attribution === undefined) {
       throw new Error('Attribution required for selected license')
     }
-    license.setAttribution(attribution)
+    license.attribution = attribution
   }
 
   return license
 }
 
 export function createCustomKnownLicense(customText: string): License {
-  const license = new License()
-
-  license.setCode(CUSTOM_LICENSE_CODE)
-  license.setCustomText(customText)
-  return license
+  return new License({ code: CUSTOM_LICENSE_CODE, customText })
 }
 
 export default {

+ 13 - 1
metadata-protobuf/src/utils.ts

@@ -1,5 +1,7 @@
 import { AnyMessage, AnyMetadataClass, DecodedMetadataObject } from './types'
 import countries from 'i18n-iso-countries'
+import langs from 'iso-639-1'
+import subdivisions from 'iso-3166-2'
 
 export function isSet<T>(v: T | null | undefined): v is T {
   return v !== null && v !== undefined
@@ -32,7 +34,17 @@ export function metaToObject<T>(metaClass: AnyMetadataClass<T>, value: AnyMessag
   return metaClass.toObject(value, { arrays: false, longs: String }) as DecodedMetadataObject<T>
 }
 
-// According to ISO 3166-1 alpha-2 standard
+// Checks if the provided code is valid according to ISO 3166-1 alpha-2 standard
 export function isValidCountryCode(code: string): boolean {
   return countries.getAlpha2Codes()[code] !== undefined
 }
+
+// Checks if the provided code is valid according to ISO 639-1 standard
+export function isValidLanguageCode(code: string): boolean {
+  return langs.validate(code)
+}
+
+// According to ISO 3166-2 standard
+export function isValidSubdivisionCode(code: string): boolean {
+  return !!subdivisions.subdivision(code)
+}

+ 31 - 0
metadata-protobuf/test/channel.ts

@@ -0,0 +1,31 @@
+import { ChannelMetadata } from '../src'
+import { assert } from 'chai'
+import { encodeDecode, metaToObject } from '../src/utils'
+import Long from 'long'
+
+describe('Channel Metadata', () => {
+  it('Message', () => {
+    const channel = {
+      title: 'title',
+      description: 'description',
+      isPublic: false,
+      language: 'fr',
+      avatarPhoto: 0,
+      coverPhoto: 1,
+      category: Long.fromNumber(100, true),
+    }
+    const channelMessage = new ChannelMetadata(channel)
+
+    assert.deepEqual(metaToObject(ChannelMetadata, channelMessage), { ...channel, category: '100' })
+    assert.deepEqual(encodeDecode(ChannelMetadata, channel), { ...channel, category: '100' })
+  })
+
+  it('Channel Metadata: Category as number', () => {
+    const channel = { category: 100 as any }
+    const channelMessage = new ChannelMetadata(channel)
+    ChannelMetadata.verify(channelMessage)
+
+    assert.deepEqual(metaToObject(ChannelMetadata, channelMessage), { ...channel, category: '100' })
+    assert.deepEqual(encodeDecode(ChannelMetadata, channel), { ...channel, category: '100' })
+  })
+})

+ 14 - 8
content-metadata-protobuf/test/license-codes.ts → metadata-protobuf/test/license-codes.ts

@@ -5,7 +5,7 @@ import {
   createKnownLicenseFromCode,
   createCustomKnownLicense,
 } from '../src/licenses'
-import { VideoMetadata } from '../src/index'
+import { License } from '../src/index'
 import { assert } from 'chai'
 
 describe('Known License Codes', () => {
@@ -16,7 +16,7 @@ describe('Known License Codes', () => {
   it('Pre-defined Joystream license codes', () => {
     // Make sure we have correct known custom license
     assert(KnownLicenses.has(CUSTOM_LICENSE_CODE))
-    assert.equal(KnownLicenses.get(CUSTOM_LICENSE_CODE)!.name, 'CUSTOM')
+    assert.equal(KnownLicenses.get(CUSTOM_LICENSE_CODE)?.name, 'CUSTOM')
 
     assert(KnownLicenses.has(1001))
     assert(KnownLicenses.has(1002))
@@ -29,14 +29,20 @@ describe('Known License Codes', () => {
   })
 
   it('createCustomKnownLicense(): uses correct code', () => {
-    const license = createCustomKnownLicense('custom text')
-    assert.equal(license.getCode(), CUSTOM_LICENSE_CODE)
+    const TEXT = 'custom text'
+    const license = createCustomKnownLicense(TEXT)
+    assert.equal(license.code, CUSTOM_LICENSE_CODE)
+    assert.equal(license.customText, TEXT)
+    License.verify(license)
   })
 
   it('createKnownLicenseFromCode(): License can be created by name', () => {
-    const licenseCode = getLicenseCodeByName('CC_BY') as number
-    const license = createKnownLicenseFromCode(licenseCode as number, 'Attribution: Joystream')
-    const videoMeta = new VideoMetadata()
-    videoMeta.setLicense(license)
+    const NAME = 'CC_BY'
+    const ATTRIBUTION = 'Attribution: Joystream'
+    const licenseCode = getLicenseCodeByName(NAME) as number
+    const license = createKnownLicenseFromCode(licenseCode, ATTRIBUTION)
+    assert.isDefined(license.code)
+    assert.equal(license.attribution, ATTRIBUTION)
+    License.verify(license)
   })
 })

+ 87 - 0
metadata-protobuf/test/video.ts

@@ -0,0 +1,87 @@
+import { VideoMetadata, MediaType } from '../src'
+import { assert, expect } from 'chai'
+import { isSet, encodeDecode, metaToObject } from '../src/utils'
+import Long from 'long'
+
+describe('Video Metadata', () => {
+  it('Message', () => {
+    const video = {
+      title: 'Video Title',
+      description: 'Video Description',
+      duration: 100,
+      mediaPixelHeight: 1,
+      mediaPixelWidth: 2,
+      mediaType: {},
+      language: 'en',
+      license: {},
+      publishedBeforeJoystream: {},
+      hasMarketing: true,
+      isPublic: true,
+      isExplicit: false,
+      video: 0,
+      thumbnailPhoto: 1,
+      category: Long.fromNumber(101, true),
+    }
+    const videoMessage = new VideoMetadata(video)
+
+    assert.deepEqual(metaToObject(VideoMetadata, videoMessage), { ...video, category: '101' })
+    assert.deepEqual(encodeDecode(VideoMetadata, video), { ...video, category: '101' })
+  })
+
+  it('Message: PublishedBeforeJoystream', () => {
+    const meta = new VideoMetadata()
+
+    expect(isSet(metaToObject(VideoMetadata, meta).publishedBeforeJoystream)).equals(
+      false,
+      'PublishedBeforeJoystream field should NOT be set'
+    )
+
+    const published = {
+      isPublished: true,
+      date: '1950-12-24',
+    }
+    meta.publishedBeforeJoystream = published
+
+    // Field should now be set
+    expect(isSet(metaToObject(VideoMetadata, meta).publishedBeforeJoystream)).equals(
+      true,
+      'PublishedBeforeJoystream field should be set'
+    )
+
+    assert.deepEqual(metaToObject(VideoMetadata, meta).publishedBeforeJoystream, published)
+    assert.deepEqual(encodeDecode(VideoMetadata, meta).publishedBeforeJoystream, meta.publishedBeforeJoystream)
+  })
+
+  it('Message: License', () => {
+    const license = {
+      code: 1000,
+      attribution: 'Attribution Text',
+      customText: 'Custom License Details',
+    }
+    const meta = new VideoMetadata({ license })
+    assert.deepEqual(metaToObject(VideoMetadata, meta).license, license)
+    assert.deepEqual(encodeDecode(VideoMetadata, meta).license, license)
+
+    // Empty object check
+    meta.license = {}
+    assert.deepEqual(metaToObject(VideoMetadata, meta).license, {})
+    assert.deepEqual(encodeDecode(VideoMetadata, meta).license, {})
+
+    // Unset check
+    meta.license = undefined
+    assert.deepEqual(metaToObject(VideoMetadata, meta).license, undefined)
+    assert.deepEqual(encodeDecode(VideoMetadata, meta).license, undefined)
+  })
+
+  it('Message: MediaType', () => {
+    const mediaType = {
+      codecName: 'mpeg4',
+      container: 'avi',
+      mimeMediaType: 'videp/mp4',
+    }
+    const mediaTypeMessage = new MediaType(mediaType)
+
+    assert.deepEqual(metaToObject(MediaType, mediaTypeMessage), mediaType)
+    assert.deepEqual(encodeDecode(MediaType, mediaType), mediaType)
+  })
+})

+ 0 - 1
package.json

@@ -27,7 +27,6 @@
     "query-node",
     "query-node/mappings",
     "query-node/generated/*",
-    "content-metadata-protobuf",
     "metadata-protobuf"
   ],
   "resolutions": {

+ 135 - 202
query-node/manifest.yml

@@ -11,6 +11,7 @@ typegen:
   metadata:
     source: ws://localhost:9944
   events:
+    # storage
     - storage.StorageBucketCreated
     - storage.StorageBucketInvitationAccepted
     - storage.StorageBucketsUpdatedForBag
@@ -51,226 +52,158 @@ typegen:
     # - storage.NumberOfStorageBucketsInDynamicBagCreationPolicyUpdated
     # - storage.FamiliesInDynamicBagCreationPolicyUpdated
 
-  # TODO: Sumer mappings
-  #   # membership
-  #   - members.MemberRegistered
-  #   - members.MemberUpdatedAboutText
-  #   - members.MemberUpdatedAvatar
-  #   - members.MemberUpdatedHandle
-  #   - members.MemberSetRootAccount
-  #   - members.MemberSetControllerAccount
+    # membership
+    - members.MemberRegistered
+    - members.MemberUpdatedAboutText
+    - members.MemberUpdatedAvatar
+    - members.MemberUpdatedHandle
+    - members.MemberSetRootAccount
+    - members.MemberSetControllerAccount
 
-  #   # content directory
-  #   - content.CuratorGroupCreated
-  #   - content.CuratorGroupStatusSet
-  #   - content.CuratorAdded
-  #   - content.CuratorRemoved
-  #   - content.ChannelCreated
-  #   - content.ChannelUpdated
-  #   - content.ChannelAssetsRemoved
-  #   - content.ChannelCensorshipStatusUpdated
-  #   - content.ChannelOwnershipTransferRequested
-  #   - content.ChannelOwnershipTransferRequestWithdrawn
-  #   - content.ChannelOwnershipTransferred
-  #   - content.ChannelCategoryCreated
-  #   - content.ChannelCategoryUpdated
-  #   - content.ChannelCategoryDeleted
-  #   - content.VideoCategoryCreated
-  #   - content.VideoCategoryUpdated
-  #   - content.VideoCategoryDeleted
-  #   - content.VideoCreated
-  #   - content.VideoUpdated
-  #   - content.VideoDeleted
-  #   - content.VideoCensorshipStatusUpdated
-  #   - content.FeaturedVideosSet
+    # content directory
+    - content.CuratorGroupCreated
+    - content.CuratorGroupStatusSet
+    - content.CuratorAdded
+    - content.CuratorRemoved
+    - content.ChannelCreated
+    - content.ChannelUpdated
+    - content.ChannelAssetsRemoved
+    - content.ChannelCensorshipStatusUpdated
+    - content.ChannelOwnershipTransferRequested
+    - content.ChannelOwnershipTransferRequestWithdrawn
+    - content.ChannelOwnershipTransferred
+    - content.ChannelCategoryCreated
+    - content.ChannelCategoryUpdated
+    - content.ChannelCategoryDeleted
+    - content.VideoCategoryCreated
+    - content.VideoCategoryUpdated
+    - content.VideoCategoryDeleted
+    - content.VideoCreated
+    - content.VideoUpdated
+    - content.VideoDeleted
+    - content.VideoCensorshipStatusUpdated
+    - content.FeaturedVideosSet
+    - content.ChannelDeleted
 
-  #   # storage
-  #   - data_directory.ContentAdded
-  #   - data_directory.ContentRemoved
-  #   - data_directory.ContentAccepted
-  #   - data_directory.ContentRejected
-  #   - data_directory.ContentUploadingStatusUpdated
-
-  #   # working groups
-  #   - storage_working_group.WorkerStorageUpdated
-  #   - storage_working_group.OpeningFilled
-  #   - storage_working_group.TerminatedWorker
-  #   - storage_working_group.WorkerExited
-  #   - storage_working_group.TerminatedLeader
-
-  #   - gateway_working_group.WorkerStorageUpdated
-  #   - gateway_working_group.OpeningFilled
-  #   - gateway_working_group.TerminatedWorker
-  #   - gateway_working_group.WorkerExited
-  #   - gateway_working_group.TerminatedLeader
-  # calls:
-  #   # members
-  #   - members.buyMembership
-  #   - members.addScreenedMember
-  #   - members.changeMemberAboutText
-  #   - members.changeMemberAvatar
-  #   - members.changeMemberHandle
-  #   - members.setRootAccount
-  #   - members.setControllerAccount
-  #   - members.updateMembership
-
-  #   # content directory
-  #   - content.create_curator_group
-  #   - content.set_curator_group_status
-  #   - content.add_curator_to_group
-  #   - content.remove_curator_from_group
-  #   - content.create_channel
-  #   - content.update_channel
-  #   - content.remove_channel_assets
-  #   - content.update_channel_censorship_status
-  #   - content.create_channel_category
-  #   - content.update_channel_category
-  #   - content.delete_channel_category
-  #   - content.request_channel_transfer
-  #   - content.cancel_channel_transfer_request
-  #   - content.accept_channel_transfer
-  #   - content.create_video
-  #   - content.update_video
-  #   - content.delete_video
-  #   - content.create_playlist
-  #   - content.update_playlist
-  #   - content.delete_playlist
-  #   - content.set_featured_videos
-  #   - content.create_video_category
-  #   - content.update_video_category
-  #   - content.delete_video_category
-  #   - content.remove_person_from_video
-  #   - content.update_video_censorship_status
-
-  #   # storage
-  #   - data_directory.add_content
-  #   - data_directory.remove_content
-  #   - data_directory.accept_content
-  #   - data_directory.update_content_uploading_status
-
-  #   # working groups
-  #   - storage_working_group.update_role_storage
-  #   - storage_working_group.fill_opening
-  #   - storage_working_group.leave_role
-  #   - storage_working_group.terminate_role
-
-  #   - gateway_working_group.update_role_storage
-  #   - gateway_working_group.fill_opening
-  #   - gateway_working_group.leave_role
-  #   - gateway_working_group.terminate_role
+    # working groups (we're using "storage_working_group" as a reference module)
+    - storage_working_group.WorkerStorageUpdated
+    - storage_working_group.OpeningFilled
+    - storage_working_group.TerminatedWorker
+    - storage_working_group.WorkerExited
+    - storage_working_group.TerminatedLeader
+  calls:
+    # members
+    - members.buyMembership
+    - members.addScreenedMember
+    - members.changeMemberAboutText
+    - members.changeMemberAvatar
+    - members.changeMemberHandle
+    - members.setRootAccount
+    - members.setControllerAccount
+    - members.updateMembership
   outDir: ./mappings/generated/types
   customTypes:
     lib: '@joystream/types/augment/all/types'
     typedefsLoc: '../types/augment/all/defs.json'
 mappings:
   # js module that exports the handler functions
-  mappingsModule: mappings/lib/giza
+  mappingsModule: mappings/lib
   # additinal libraries the processor loads
   # typically it is a module with event and extrinsic types generated by hydra-typegen
   imports:
     - mappings/lib/generated/types
   eventHandlers:
-    # TODO: Sumer mappings
-    # # membership
-    # - event: members.MemberRegistered
-    #   handler: members_MemberRegistered(DatabaseManager, SubstrateEvent)
-    # - event: members.MemberUpdatedAboutText
-    #   handler: members_MemberUpdatedAboutText(DatabaseManager, SubstrateEvent)
-    # - event: members.MemberUpdatedAvatar
-    #   handler: members_MemberUpdatedAvatar(DatabaseManager, SubstrateEvent)
-    # - event: members.MemberUpdatedHandle
-    #   handler: members_MemberUpdatedHandle(DatabaseManager, SubstrateEvent)
-    # - event: members.MemberSetRootAccount
-    #   handler: members_MemberSetRootAccount(DatabaseManager, SubstrateEvent)
-    # - event: members.MemberSetControllerAccount
-    #   handler: members_MemberSetControllerAccount(DatabaseManager, SubstrateEvent)
-
-    # # content directory
-    # - event: content.CuratorGroupCreated
-    #   handler: content_CuratorGroupCreated(DatabaseManager, SubstrateEvent)
-    # - event: content.CuratorGroupStatusSet
-    #   handler: content_CuratorGroupStatusSet(DatabaseManager, SubstrateEvent)
-    # - event: content.CuratorAdded
-    #   handler: content_CuratorAdded(DatabaseManager, SubstrateEvent)
-    # - event: content.CuratorRemoved
-    #   handler: content_CuratorRemoved(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelCreated
-    #   handler: content_ChannelCreated(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelUpdated
-    #   handler: content_ChannelUpdated(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelAssetsRemoved
-    #   handler: content_ChannelAssetsRemoved(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelCensorshipStatusUpdated
-    #   handler: content_ChannelCensorshipStatusUpdated(DatabaseManager, SubstrateEvent)
-    # # these events are defined in runtime but never calles (at the time of writing)
-    # #- event: content.ChannelOwnershipTransferRequested
-    # #  handler: content_ChannelOwnershipTransferRequested(DatabaseManager, SubstrateEvent)
-    # #- event: content.ChannelOwnershipTransferRequestWithdrawn
-    # #  handler: content_ChannelOwnershipTransferRequestWithdrawn(DatabaseManager, SubstrateEvent)
-    # #- event: content.ChannelOwnershipTransferred
-    # #  handler: content_ChannelOwnershipTransferred(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelCategoryCreated
-    #   handler: content_ChannelCategoryCreated(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelCategoryUpdated
-    #   handler: content_ChannelCategoryUpdated(DatabaseManager, SubstrateEvent)
-    # - event: content.ChannelCategoryDeleted
-    #   handler: content_ChannelCategoryDeleted(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoCategoryCreated
-    #   handler: content_VideoCategoryCreated(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoCategoryUpdated
-    #   handler: content_VideoCategoryUpdated(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoCategoryDeleted
-    #   handler: content_VideoCategoryDeleted(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoCreated
-    #   handler: content_VideoCreated(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoUpdated
-    #   handler: content_VideoUpdated(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoDeleted
-    #   handler: content_VideoDeleted(DatabaseManager, SubstrateEvent)
-    # - event: content.VideoCensorshipStatusUpdated
-    #   handler: content_VideoCensorshipStatusUpdated(DatabaseManager, SubstrateEvent)
-    # - event: content.FeaturedVideosSet
-    #   handler: content_FeaturedVideosSet(DatabaseManager, SubstrateEvent)
+    # membership
+    - event: members.MemberRegistered
+      handler: members_MemberRegistered
+    - event: members.MemberUpdatedAboutText
+      handler: members_MemberUpdatedAboutText
+    - event: members.MemberUpdatedAvatar
+      handler: members_MemberUpdatedAvatar
+    - event: members.MemberUpdatedHandle
+      handler: members_MemberUpdatedHandle
+    - event: members.MemberSetRootAccount
+      handler: members_MemberSetRootAccount
+    - event: members.MemberSetControllerAccount
+      handler: members_MemberSetControllerAccount
 
-    # # storage
-    # - event: dataDirectory.ContentAdded
-    #   handler: dataDirectory_ContentAdded(DatabaseManager, SubstrateEvent)
-    # - event: dataDirectory.ContentRemoved
-    #   handler: dataDirectory_ContentRemoved(DatabaseManager, SubstrateEvent)
-    # - event: dataDirectory.ContentAccepted
-    #   handler: dataDirectory_ContentAccepted(DatabaseManager, SubstrateEvent)
-    # # not handled at the moment
-    # #- event: dataDirectory.ContentUploadingStatusUpdated
-    # #  handler: data_directory_ContentUploadingStatusUpdated(DatabaseManager, SubstrateEvent)
+    # content directory
+    - event: content.CuratorGroupCreated
+      handler: content_CuratorGroupCreated
+    - event: content.CuratorGroupStatusSet
+      handler: content_CuratorGroupStatusSet
+    - event: content.CuratorAdded
+      handler: content_CuratorAdded
+    - event: content.CuratorRemoved
+      handler: content_CuratorRemoved
+    - event: content.ChannelCreated
+      handler: content_ChannelCreated
+    - event: content.ChannelUpdated
+      handler: content_ChannelUpdated
+    - event: content.ChannelAssetsRemoved
+      handler: content_ChannelAssetsRemoved
+    - event: content.ChannelCensorshipStatusUpdated
+      handler: content_ChannelCensorshipStatusUpdated
+    # these events are defined in runtime but never emitted (at the time of writing)
+    #- event: content.ChannelOwnershipTransferRequested
+    #  handler: content_ChannelOwnershipTransferRequested
+    #- event: content.ChannelOwnershipTransferRequestWithdrawn
+    #  handler: content_ChannelOwnershipTransferRequestWithdrawn
+    #- event: content.ChannelOwnershipTransferred
+    #  handler: content_ChannelOwnershipTransferred
+    - event: content.ChannelCategoryCreated
+      handler: content_ChannelCategoryCreated
+    - event: content.ChannelCategoryUpdated
+      handler: content_ChannelCategoryUpdated
+    - event: content.ChannelCategoryDeleted
+      handler: content_ChannelCategoryDeleted
+    - event: content.VideoCategoryCreated
+      handler: content_VideoCategoryCreated
+    - event: content.VideoCategoryUpdated
+      handler: content_VideoCategoryUpdated
+    - event: content.VideoCategoryDeleted
+      handler: content_VideoCategoryDeleted
+    - event: content.VideoCreated
+      handler: content_VideoCreated
+    - event: content.VideoUpdated
+      handler: content_VideoUpdated
+    - event: content.VideoDeleted
+      handler: content_VideoDeleted
+    - event: content.VideoCensorshipStatusUpdated
+      handler: content_VideoCensorshipStatusUpdated
+    - event: content.FeaturedVideosSet
+      handler: content_FeaturedVideosSet
+    - event: content.ChannelDeleted
+      handler: content_ChannelDeleted
 
-    # # working groups
-    # ## storage - workers
-    # - event: storageWorkingGroup.WorkerStorageUpdated
-    #   handler: storageWorkingGroup_WorkerStorageUpdated(DatabaseManager, SubstrateEvent)
-    # - event: storageWorkingGroup.OpeningFilled
-    #   handler: storageWorkingGroup_OpeningFilled(DatabaseManager, SubstrateEvent)
-    # - event: storageWorkingGroup.TerminatedWorker
-    #   handler: storageWorkingGroup_TerminatedWorker(DatabaseManager, SubstrateEvent)
-    # - event: storageWorkingGroup.WorkerExited
-    #   handler: storageWorkingGroup_WorkerExited(DatabaseManager, SubstrateEvent)
+    # working groups
+    ## storage - workers
+    - event: storageWorkingGroup.WorkerStorageUpdated
+      handler: workingGroup_WorkerStorageUpdated
+    - event: storageWorkingGroup.OpeningFilled
+      handler: workingGroup_OpeningFilled
+    - event: storageWorkingGroup.TerminatedWorker
+      handler: workingGroup_TerminatedWorker
+    - event: storageWorkingGroup.WorkerExited
+      handler: workingGroup_WorkerExited
 
-    # ## storage - leader
-    # - event: storageWorkingGroup.TerminatedLeader
-    #   handler: storageWorkingGroup_TerminatedLeader(DatabaseManager, SubstrateEvent)
+    ## storage - leader
+    - event: storageWorkingGroup.TerminatedLeader
+      handler: workingGroup_TerminatedLeader
 
-    # ## gateway - workers
-    # - event: gatewayWorkingGroup.WorkerStorageUpdated
-    #   handler: gatewayWorkingGroup_WorkerStorageUpdated(DatabaseManager, SubstrateEvent)
-    # - event: gatewayWorkingGroup.OpeningFilled
-    #   handler: gatewayWorkingGroup_OpeningFilled(DatabaseManager, SubstrateEvent)
-    # - event: gatewayWorkingGroup.TerminatedWorker
-    #   handler: gatewayWorkingGroup_TerminatedWorker(DatabaseManager, SubstrateEvent)
-    # - event: gatewayWorkingGroup.WorkerExited
-    #   handler: gatewayWorkingGroup_WorkerExited(DatabaseManager, SubstrateEvent)
+    ## gateway - workers
+    - event: gatewayWorkingGroup.WorkerStorageUpdated
+      handler: workingGroup_WorkerStorageUpdated
+    - event: gatewayWorkingGroup.OpeningFilled
+      handler: workingGroup_OpeningFilled
+    - event: gatewayWorkingGroup.TerminatedWorker
+      handler: workingGroup_TerminatedWorker
+    - event: gatewayWorkingGroup.WorkerExited
+      handler: workingGroup_WorkerExited
 
-    # ## gateway - leader
-    # - event: gatewayWorkingGroup.TerminatedLeader
-    #   handler: gatewayWorkingGroup_TerminatedLeader(DatabaseManager, SubstrateEvent)
+    ## gateway - leader
+    - event: gatewayWorkingGroup.TerminatedLeader
+      handler: workingGroup_TerminatedLeader
 
     # storage v2
     - event: storage.StorageBucketCreated

+ 96 - 98
query-node/mappings/sumer/common.ts → query-node/mappings/common.ts

@@ -1,16 +1,34 @@
-import { SubstrateEvent, SubstrateExtrinsic, ExtrinsicArg } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { u64, Bytes } from '@polkadot/types/primitive'
-import { fixBlockTimestamp } from './eventFix'
+import { DatabaseManager, SubstrateEvent, SubstrateExtrinsic, ExtrinsicArg } from '@joystream/hydra-common'
+import { Bytes } from '@polkadot/types'
+import { Network } from 'query-node/dist/model'
+import { BaseModel } from '@joystream/warthog'
+import { metaToObject } from '@joystream/metadata-protobuf/utils'
+import { AnyMetadataClass, DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
+
+export const CURRENT_NETWORK = Network.GIZA
+/*
+  Simple logger enabling error and informational reporting.
 
-// Asset
-import { DataObjectOwner, DataObject, LiaisonJudgement, Network, NextEntityId } from 'query-node'
-import { ContentParameters } from '@joystream/types/augment'
+  FIXME: `Logger` class will not be needed in the future when Hydra v3 will be released.
+  Hydra will provide logger instance and relevant code using `Logger` should be refactored.
+*/
+class Logger {
+  /*
+    Log significant event.
+  */
+  info(message: string, data?: unknown) {
+    console.log(message, data)
+  }
 
-import { ContentParameters as Custom_ContentParameters } from '@joystream/types/storage'
-import { registry } from '@joystream/types'
+  /*
+    Log significant error.
+  */
+  error(message: string, data?: unknown) {
+    console.error(message, data)
+  }
+}
 
-const currentNetwork = Network.BABYLON
+export const logger = new Logger()
 
 /*
   Reports that insurmountable inconsistent state has been encountered and throws an exception.
@@ -21,71 +39,32 @@ export function inconsistentState(extraInfo: string, data?: unknown): never {
   // log error
   logger.error(errorMessage, data)
 
-  throw new Error(errorMessage)
+  throw errorMessage
 }
 
 /*
-  Reports that metadata inserted by the user are not entirely valid, but the problem can be overcome.
+  Reports that insurmountable unexpected data has been encountered and throws an exception.
 */
-export function invalidMetadata(extraInfo: string, data?: unknown): void {
-  const errorMessage = 'Invalid metadata: ' + extraInfo
+export function unexpectedData(extraInfo: string, data?: unknown): never {
+  const errorMessage = 'Unexpected data: ' + extraInfo
 
   // log error
-  logger.info(errorMessage, data)
-}
-
-/*
-  Creates a predictable and unique ID for the given content.
-*/
-export async function getNextId(db: DatabaseManager): Promise<string> {
-  // load or create record
-  const existingRecord = (await db.get(NextEntityId, {})) || new NextEntityId({ id: '0', nextId: 1 })
-
-  // remember id
-  const entityId = existingRecord.nextId
-
-  // increment id
-  existingRecord.nextId = existingRecord.nextId + 1
-
-  // save record
-  await db.save<NextEntityId>(existingRecord)
+  logger.error(errorMessage, data)
 
-  return entityId.toString()
+  throw errorMessage
 }
 
 /*
-  Prepares data object from content parameters.
+  Reports that metadata inserted by the user are not entirely valid, but the problem can be overcome.
 */
-export async function prepareDataObject(
-  db: DatabaseManager,
-  contentParameters: ContentParameters,
-  event: SubstrateEvent,
-  owner: typeof DataObjectOwner
-): Promise<DataObject> {
-  // convert generic content parameters coming from processor to custom Joystream data type
-  const customContentParameters = new Custom_ContentParameters(registry, contentParameters.toJSON() as any)
-
-  const dataObject = new DataObject({
-    id: await getNextId(db),
-    owner,
-    createdInBlock: event.blockNumber,
-    typeId: contentParameters.type_id.toNumber(),
-    size: customContentParameters.size_in_bytes.toNumber(),
-    liaisonJudgement: LiaisonJudgement.PENDING, // judgement is pending at start; liaison id is set when content is accepted/rejected
-    ipfsContentId: convertBytesToString(contentParameters.ipfs_content_id),
-    joystreamContentId: customContentParameters.content_id.encode(),
-
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    createdById: '1',
-    updatedById: '1',
-  })
+export function invalidMetadata(extraInfo: string, data?: unknown): void {
+  const errorMessage = 'Invalid metadata: ' + extraInfo
 
-  return dataObject
+  // log error
+  logger.info(errorMessage, data)
 }
 
-/// ///////////////// Sudo extrinsic calls ///////////////////////////////////////
+/// //////////////// Sudo extrinsic calls ///////////////////////////////////////
 
 // soft-peg interface for typegen-generated `*Call` types
 export interface IGenericExtrinsicObject<T> {
@@ -105,12 +84,13 @@ export interface ISudoCallArgs<T> extends ExtrinsicArg {
 */
 export function extractExtrinsicArgs<DataParams, EventObject extends IGenericExtrinsicObject<DataParams>>(
   rawEvent: SubstrateEvent,
-  callFactory: new (event: SubstrateEvent) => EventObject,
+  callFactoryConstructor: new (event: SubstrateEvent) => EventObject,
 
   // in ideal world this parameter would not be needed, but there is no way to associate parameters
   // used in sudo to extrinsic parameters without it
   argsIndeces: Record<keyof DataParams, number>
 ): EventObject['args'] {
+  const CallFactory = callFactoryConstructor
   // this is equal to DataParams but only this notation works properly
   // escape when extrinsic info is not available
   if (!rawEvent.extrinsic) {
@@ -119,8 +99,7 @@ export function extractExtrinsicArgs<DataParams, EventObject extends IGenericExt
 
   // regural extrinsic call?
   if (rawEvent.extrinsic.section !== 'sudo') {
-    // eslint-disable-next-line new-cap
-    return new callFactory(rawEvent).args
+    return new CallFactory(rawEvent).args
   }
 
   // sudo extrinsic call
@@ -150,8 +129,7 @@ export function extractExtrinsicArgs<DataParams, EventObject extends IGenericExt
   } as SubstrateEvent
 
   // create event object and extract processed args
-  // eslint-disable-next-line new-cap
-  const finalArgs = new callFactory(partialEvent).args
+  const finalArgs = new CallFactory(partialEvent).args
 
   return finalArgs
 }
@@ -183,45 +161,65 @@ export function extractSudoCallParameters<DataParams>(rawEvent: SubstrateEvent):
   return callArgs
 }
 
-/// ///////////////// Logger /////////////////////////////////////////////////////
-
-/*
-  Simple logger enabling error and informational reporting.
-
-  `Logger` class will not be needed in the future when Hydra v3 will be released.
-  Hydra will provide logger instance and relevant code using `Logger` should be refactored.
-*/
-class Logger {
-  /*
-    Log significant event.
-  */
-  info(message: string, data?: unknown) {
-    console.log(message, data)
+export function deserializeMetadata<T>(
+  metadataType: AnyMetadataClass<T>,
+  metadataBytes: Bytes
+): DecodedMetadataObject<T> | null {
+  try {
+    return metaToObject(metadataType, metadataType.decode(metadataBytes.toU8a(true)))
+  } catch (e) {
+    invalidMetadata(`Cannot deserialize ${metadataType.name}! Provided bytes: (${metadataBytes.toHex()})`)
+    return null
   }
+}
 
-  /*
-    Log significant error.
-  */
-  error(message: string, data?: unknown) {
-    console.error(message, data)
-  }
+export function bytesToString(b: Bytes): string {
+  return (
+    Buffer.from(b.toU8a(true))
+      .toString()
+      // eslint-disable-next-line no-control-regex
+      .replace(/\u0000/g, '')
+  )
 }
 
-export const logger = new Logger()
+export function perpareString(s: string): string {
+  // eslint-disable-next-line no-control-regex
+  return s.replace(/\u0000/g, '')
+}
 
-/*
-  Helper for converting Bytes type to string
-*/
-export function convertBytesToString(b: Bytes | null): string {
-  if (!b) {
-    return ''
-  }
+export function hasValuesForProperties<
+  T extends Record<string, unknown>,
+  P extends keyof T & string,
+  PA extends readonly P[]
+>(obj: T, props: PA): obj is T & { [K in PA[number]]: NonNullable<K> } {
+  props.forEach((p) => {
+    if (obj[p] === null || obj[p] === undefined) {
+      return false
+    }
+  })
+  return true
+}
 
-  const text = Buffer.from(b.toU8a(true)).toString()
+type EntityClass<T extends BaseModel> = {
+  new (): T
+  name: string
+}
 
-  // prevent utf-8 null character
-  // eslint-disable-next-line no-control-regex
-  const result = text.replace(/\u0000/g, '')
+type RelationsArr<T extends BaseModel> = Exclude<
+  keyof T & string,
+  { [K in keyof T]: T[K] extends BaseModel | undefined ? '' : T[K] extends BaseModel[] | undefined ? '' : K }[keyof T]
+>[]
+
+export async function getById<T extends BaseModel>(
+  store: DatabaseManager,
+  entityClass: EntityClass<T>,
+  id: string,
+  relations?: RelationsArr<T>
+): Promise<T> {
+  const result = await store.get(entityClass, { where: { id }, relations })
+  if (!result) {
+    throw new Error(`Expected ${entityClass.name} not found by ID: ${id}`)
+  }
 
   return result
 }

+ 221 - 0
query-node/mappings/content/channel.ts

@@ -0,0 +1,221 @@
+/*
+eslint-disable @typescript-eslint/naming-convention
+*/
+import { EventContext, StoreContext } from '@joystream/hydra-common'
+import { Content } from '../generated/types'
+import { convertContentActorToChannelOwner, processChannelMetadata } from './utils'
+import { Channel, ChannelCategory, StorageDataObject } from 'query-node/dist/model'
+import { deserializeMetadata, inconsistentState, logger } from '../common'
+import { ChannelCategoryMetadata, ChannelMetadata } from '@joystream/metadata-protobuf'
+import { integrateMeta } from '@joystream/metadata-protobuf/utils'
+import { In } from 'typeorm'
+import { removeDataObject } from '../storage/utils'
+
+export async function content_ChannelCreated(ctx: EventContext & StoreContext): Promise<void> {
+  const { store, event } = ctx
+  // read event data
+  const [contentActor, channelId, runtimeChannel, channelCreationParameters] = new Content.ChannelCreatedEvent(
+    event
+  ).params
+
+  // create entity
+  const channel = new Channel({
+    // main data
+    id: channelId.toString(),
+    isCensored: false,
+    videos: [],
+    createdInBlock: event.blockNumber,
+    rewardAccount: channelCreationParameters.reward_account.unwrapOr(undefined)?.toString(),
+    deletionPrizeDestAccount: runtimeChannel.deletion_prize_source_account_id.toString(),
+    // fill in auto-generated fields
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+    // prepare channel owner (handles fields `ownerMember` and `ownerCuratorGroup`)
+    ...(await convertContentActorToChannelOwner(store, contentActor)),
+  })
+
+  // deserialize & process metadata
+  if (channelCreationParameters.meta.isSome) {
+    const metadata = deserializeMetadata(ChannelMetadata, channelCreationParameters.meta.unwrap()) || {}
+    await processChannelMetadata(ctx, channel, metadata, channelCreationParameters.assets.unwrapOr(undefined))
+  }
+
+  // save entity
+  await store.save<Channel>(channel)
+
+  // emit log event
+  logger.info('Channel has been created', { id: channel.id })
+}
+
+export async function content_ChannelUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { store, event } = ctx
+  // read event data
+  const [, channelId, , channelUpdateParameters] = new Content.ChannelUpdatedEvent(event).params
+
+  // load channel
+  const channel = await store.get(Channel, { where: { id: channelId.toString() } })
+
+  // ensure channel exists
+  if (!channel) {
+    return inconsistentState('Non-existing channel update requested', channelId)
+  }
+
+  // prepare changed metadata
+  const newMetadataBytes = channelUpdateParameters.new_meta.unwrapOr(null)
+
+  //  update metadata if it was changed
+  if (newMetadataBytes) {
+    const newMetadata = deserializeMetadata(ChannelMetadata, newMetadataBytes) || {}
+    await processChannelMetadata(
+      ctx,
+      channel,
+      newMetadata,
+      channelUpdateParameters.assets_to_upload.unwrapOr(undefined)
+    )
+  }
+
+  // prepare changed reward account
+  const newRewardAccount = channelUpdateParameters.reward_account.unwrapOr(null)
+
+  // reward account change happened?
+  if (newRewardAccount) {
+    // this will change the `channel`!
+    channel.rewardAccount = newRewardAccount.unwrapOr(undefined)?.toString()
+  }
+
+  // set last update time
+  channel.updatedAt = new Date(event.blockTimestamp)
+
+  // save channel
+  await store.save<Channel>(channel)
+
+  // emit log event
+  logger.info('Channel has been updated', { id: channel.id })
+}
+
+export async function content_ChannelAssetsRemoved({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [, , dataObjectIds] = new Content.ChannelAssetsRemovedEvent(event).params
+  const assets = await store.getMany(StorageDataObject, {
+    where: {
+      id: In(Array.from(dataObjectIds).map((item) => item.toString())),
+    },
+  })
+  await Promise.all(assets.map((a) => removeDataObject(store, a)))
+  logger.info('Channel assets have been removed', { ids: dataObjectIds.toJSON() })
+}
+
+export async function content_ChannelCensorshipStatusUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, channelId, isCensored] = new Content.ChannelCensorshipStatusUpdatedEvent(event).params
+
+  // load event
+  const channel = await store.get(Channel, { where: { id: channelId.toString() } })
+
+  // ensure channel exists
+  if (!channel) {
+    return inconsistentState('Non-existing channel censoring requested', channelId)
+  }
+
+  // update channel
+  channel.isCensored = isCensored.isTrue
+
+  // set last update time
+  channel.updatedAt = new Date(event.blockTimestamp)
+
+  // save channel
+  await store.save<Channel>(channel)
+
+  // emit log event
+  logger.info('Channel censorship status has been updated', { id: channelId, isCensored: isCensored.isTrue })
+}
+
+/// //////////////// ChannelCategory ////////////////////////////////////////////
+
+export async function content_ChannelCategoryCreated({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [channelCategoryId, , channelCategoryCreationParameters] = new Content.ChannelCategoryCreatedEvent(event).params
+
+  // read metadata
+  const metadata = deserializeMetadata(ChannelCategoryMetadata, channelCategoryCreationParameters.meta) || {}
+
+  // create new channel category
+  const channelCategory = new ChannelCategory({
+    // main data
+    id: channelCategoryId.toString(),
+    channels: [],
+    createdInBlock: event.blockNumber,
+
+    // fill in auto-generated fields
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+  })
+  integrateMeta(channelCategory, metadata, ['name'])
+
+  // save channel
+  await store.save<ChannelCategory>(channelCategory)
+
+  // emit log event
+  logger.info('Channel category has been created', { id: channelCategory.id })
+}
+
+export async function content_ChannelCategoryUpdated({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, channelCategoryId, channelCategoryUpdateParameters] = new Content.ChannelCategoryUpdatedEvent(event).params
+
+  // load channel category
+  const channelCategory = await store.get(ChannelCategory, {
+    where: {
+      id: channelCategoryId.toString(),
+    },
+  })
+
+  // ensure channel exists
+  if (!channelCategory) {
+    return inconsistentState('Non-existing channel category update requested', channelCategoryId)
+  }
+
+  // read metadata
+  const newMeta = deserializeMetadata(ChannelCategoryMetadata, channelCategoryUpdateParameters.new_meta) || {}
+  integrateMeta(channelCategory, newMeta, ['name'])
+
+  // set last update time
+  channelCategory.updatedAt = new Date(event.blockTimestamp)
+
+  // save channel category
+  await store.save<ChannelCategory>(channelCategory)
+
+  // emit log event
+  logger.info('Channel category has been updated', { id: channelCategory.id })
+}
+
+export async function content_ChannelCategoryDeleted({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, channelCategoryId] = new Content.ChannelCategoryDeletedEvent(event).params
+
+  // load channel category
+  const channelCategory = await store.get(ChannelCategory, {
+    where: {
+      id: channelCategoryId.toString(),
+    },
+  })
+
+  // ensure channel category exists
+  if (!channelCategory) {
+    return inconsistentState('Non-existing channel category deletion requested', channelCategoryId)
+  }
+
+  // delete channel category
+  await store.remove<ChannelCategory>(channelCategory)
+
+  // emit log event
+  logger.info('Channel category has been deleted', { id: channelCategory.id })
+}
+
+export async function content_ChannelDeleted({ store, event }: EventContext & StoreContext): Promise<void> {
+  const [, channelId] = new Content.ChannelDeletedEvent(event).params
+
+  await store.remove<Channel>(new Channel({ id: channelId.toString() }))
+}

+ 25 - 26
query-node/mappings/sumer/content/curatorGroup.ts → query-node/mappings/content/curatorGroup.ts

@@ -1,16 +1,15 @@
-import { fixBlockTimestamp } from '../eventFix'
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
+/*
+eslint-disable @typescript-eslint/naming-convention
+*/
+import { EventContext, StoreContext } from '@joystream/hydra-common'
 import { FindConditions } from 'typeorm'
-
-import { CuratorGroup } from 'query-node'
-import { Content } from '../../../generated/types'
-
+import { CuratorGroup } from 'query-node/dist/model'
+import { Content } from '../generated/types'
 import { inconsistentState, logger } from '../common'
 
-export async function content_CuratorGroupCreated(db: DatabaseManager, event: SubstrateEvent) {
+export async function content_CuratorGroupCreated({ store, event }: EventContext & StoreContext): Promise<void> {
   // read event data
-  const { curatorGroupId } = new Content.CuratorGroupCreatedEvent(event).data
+  const [curatorGroupId] = new Content.CuratorGroupCreatedEvent(event).params
 
   // create new curator group
   const curatorGroup = new CuratorGroup({
@@ -20,23 +19,23 @@ export async function content_CuratorGroupCreated(db: DatabaseManager, event: Su
     isActive: false, // runtime creates inactive curator groups by default
 
     // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
   })
 
   // save curator group
-  await db.save<CuratorGroup>(curatorGroup)
+  await store.save<CuratorGroup>(curatorGroup)
 
   // emit log event
   logger.info('Curator group has been created', { id: curatorGroupId })
 }
 
-export async function content_CuratorGroupStatusSet(db: DatabaseManager, event: SubstrateEvent) {
+export async function content_CuratorGroupStatusSet({ store, event }: EventContext & StoreContext): Promise<void> {
   // read event data
-  const { curatorGroupId, bool: isActive } = new Content.CuratorGroupStatusSetEvent(event).data
+  const [curatorGroupId, isActive] = new Content.CuratorGroupStatusSetEvent(event).params
 
   // load curator group
-  const curatorGroup = await db.get(CuratorGroup, {
+  const curatorGroup = await store.get(CuratorGroup, {
     where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
   })
 
@@ -49,21 +48,21 @@ export async function content_CuratorGroupStatusSet(db: DatabaseManager, event:
   curatorGroup.isActive = isActive.isTrue
 
   // set last update time
-  curatorGroup.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  curatorGroup.updatedAt = new Date(event.blockTimestamp)
 
   // save curator group
-  await db.save<CuratorGroup>(curatorGroup)
+  await store.save<CuratorGroup>(curatorGroup)
 
   // emit log event
   logger.info('Curator group status has been set', { id: curatorGroupId, isActive })
 }
 
-export async function content_CuratorAdded(db: DatabaseManager, event: SubstrateEvent) {
+export async function content_CuratorAdded({ store, event }: EventContext & StoreContext): Promise<void> {
   // read event data
-  const { curatorGroupId, curatorId } = new Content.CuratorAddedEvent(event).data
+  const [curatorGroupId, curatorId] = new Content.CuratorAddedEvent(event).params
 
   // load curator group
-  const curatorGroup = await db.get(CuratorGroup, {
+  const curatorGroup = await store.get(CuratorGroup, {
     where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
   })
 
@@ -76,21 +75,21 @@ export async function content_CuratorAdded(db: DatabaseManager, event: Substrate
   curatorGroup.curatorIds.push(curatorId.toNumber())
 
   // set last update time
-  curatorGroup.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  curatorGroup.updatedAt = new Date(event.blockTimestamp)
 
   // save curator group
-  await db.save<CuratorGroup>(curatorGroup)
+  await store.save<CuratorGroup>(curatorGroup)
 
   // emit log event
   logger.info('Curator has been added to curator group', { id: curatorGroupId, curatorId })
 }
 
-export async function content_CuratorRemoved(db: DatabaseManager, event: SubstrateEvent) {
+export async function content_CuratorRemoved({ store, event }: EventContext & StoreContext): Promise<void> {
   // read event data
-  const { curatorGroupId, curatorId } = new Content.CuratorAddedEvent(event).data
+  const [curatorGroupId, curatorId] = new Content.CuratorAddedEvent(event).params
 
   // load curator group
-  const curatorGroup = await db.get(CuratorGroup, {
+  const curatorGroup = await store.get(CuratorGroup, {
     where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
   })
 
@@ -110,7 +109,7 @@ export async function content_CuratorRemoved(db: DatabaseManager, event: Substra
   curatorGroup.curatorIds.splice(curatorIndex, 1)
 
   // save curator group
-  await db.save<CuratorGroup>(curatorGroup)
+  await store.save<CuratorGroup>(curatorGroup)
 
   // emit log event
   logger.info('Curator has been removed from curator group', { id: curatorGroupId, curatorId })

+ 0 - 0
query-node/mappings/sumer/content/index.ts → query-node/mappings/content/index.ts


+ 527 - 0
query-node/mappings/content/utils.ts

@@ -0,0 +1,527 @@
+import { DatabaseManager, EventContext, StoreContext } from '@joystream/hydra-common'
+import { FindConditions, Raw } from 'typeorm'
+import {
+  IVideoMetadata,
+  IPublishedBeforeJoystream,
+  ILicense,
+  IMediaType,
+  IChannelMetadata,
+} from '@joystream/metadata-protobuf'
+import { integrateMeta, isSet, isValidLanguageCode } from '@joystream/metadata-protobuf/utils'
+import { invalidMetadata, inconsistentState, logger } from '../common'
+import {
+  // primary entities
+  CuratorGroup,
+  Channel,
+  Video,
+  VideoCategory,
+  // secondary entities
+  Language,
+  License,
+  VideoMediaMetadata,
+  // asset
+  Membership,
+  VideoMediaEncoding,
+  ChannelCategory,
+  StorageDataObject,
+  DataObjectTypeChannelAvatar,
+  DataObjectTypeChannelCoverPhoto,
+  DataObjectTypeVideoMedia,
+  DataObjectTypeVideoThumbnail,
+} from 'query-node/dist/model'
+// Joystream types
+import { ContentActor, StorageAssets } from '@joystream/types/augment'
+import { DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
+import BN from 'bn.js'
+import { getMostRecentlyCreatedDataObjects } from '../storage/utils'
+
+const ASSET_TYPES = {
+  channel: [
+    {
+      DataObjectTypeConstructor: DataObjectTypeChannelCoverPhoto,
+      metaFieldName: 'coverPhoto',
+      schemaFieldName: 'coverPhoto',
+    },
+    {
+      DataObjectTypeConstructor: DataObjectTypeChannelAvatar,
+      metaFieldName: 'avatarPhoto',
+      schemaFieldName: 'avatarPhoto',
+    },
+  ],
+  video: [
+    {
+      DataObjectTypeConstructor: DataObjectTypeVideoMedia,
+      metaFieldName: 'video',
+      schemaFieldName: 'media',
+    },
+    {
+      DataObjectTypeConstructor: DataObjectTypeVideoThumbnail,
+      metaFieldName: 'thumbnailPhoto',
+      schemaFieldName: 'thumbnailPhoto',
+    },
+  ],
+} as const
+
+async function processChannelAssets(
+  { event, store }: EventContext & StoreContext,
+  assets: StorageDataObject[],
+  channel: Channel,
+  meta: DecodedMetadataObject<IChannelMetadata>
+) {
+  await Promise.all(
+    ASSET_TYPES.channel.map(async ({ metaFieldName, schemaFieldName, DataObjectTypeConstructor }) => {
+      const newAssetIndex = meta[metaFieldName]
+      const currentAsset = channel[schemaFieldName]
+      if (isSet(newAssetIndex)) {
+        const asset = findAssetByIndex(assets, newAssetIndex)
+        if (asset) {
+          if (currentAsset) {
+            currentAsset.unsetAt = new Date(event.blockTimestamp)
+            await store.save<StorageDataObject>(currentAsset)
+          }
+          const dataObjectType = new DataObjectTypeConstructor()
+          dataObjectType.channelId = channel.id
+          asset.type = dataObjectType
+          channel[schemaFieldName] = asset
+          await store.save<StorageDataObject>(asset)
+        }
+      }
+    })
+  )
+}
+
+async function processVideoAssets(
+  { event, store }: EventContext & StoreContext,
+  assets: StorageDataObject[],
+  video: Video,
+  meta: DecodedMetadataObject<IVideoMetadata>
+) {
+  await Promise.all(
+    ASSET_TYPES.video.map(async ({ metaFieldName, schemaFieldName, DataObjectTypeConstructor }) => {
+      const newAssetIndex = meta[metaFieldName]
+      const currentAsset = video[schemaFieldName]
+      if (isSet(newAssetIndex)) {
+        const asset = findAssetByIndex(assets, newAssetIndex)
+        if (asset) {
+          if (currentAsset) {
+            currentAsset.unsetAt = new Date(event.blockTimestamp)
+            await store.save<StorageDataObject>(currentAsset)
+          }
+          const dataObjectType = new DataObjectTypeConstructor()
+          dataObjectType.videoId = video.id
+          asset.type = dataObjectType
+          video[schemaFieldName] = asset
+          await store.save<StorageDataObject>(asset)
+        }
+      }
+    })
+  )
+}
+
+export async function processChannelMetadata(
+  ctx: EventContext & StoreContext,
+  channel: Channel,
+  meta: DecodedMetadataObject<IChannelMetadata>,
+  assetsParams?: StorageAssets
+): Promise<Channel> {
+  const assets = assetsParams ? await processNewAssets(ctx, assetsParams) : []
+
+  integrateMeta(channel, meta, ['title', 'description', 'isPublic'])
+
+  await processChannelAssets(ctx, assets, channel, meta)
+
+  // prepare channel category if needed
+  if (isSet(meta.category)) {
+    channel.category = await processChannelCategory(ctx, channel.category, parseInt(meta.category))
+  }
+
+  // prepare language if needed
+  if (isSet(meta.language)) {
+    channel.language = await processLanguage(ctx, channel.language, meta.language)
+  }
+
+  return channel
+}
+
+export async function processVideoMetadata(
+  ctx: EventContext & StoreContext,
+  video: Video,
+  meta: DecodedMetadataObject<IVideoMetadata>,
+  assetsParams?: StorageAssets
+): Promise<Video> {
+  const assets = assetsParams ? await processNewAssets(ctx, assetsParams) : []
+
+  integrateMeta(video, meta, ['title', 'description', 'duration', 'hasMarketing', 'isExplicit', 'isPublic'])
+
+  await processVideoAssets(ctx, assets, video, meta)
+
+  // prepare video category if needed
+  if (meta.category) {
+    video.category = await processVideoCategory(ctx, video.category, parseInt(meta.category))
+  }
+
+  // prepare media meta information if needed
+  if (isSet(meta.video) || isSet(meta.mediaType) || isSet(meta.mediaPixelWidth) || isSet(meta.mediaPixelHeight)) {
+    // prepare video file size if poosible
+    const videoSize = extractVideoSize(assets)
+    video.mediaMetadata = await processVideoMediaMetadata(ctx, video.mediaMetadata, meta, videoSize)
+  }
+
+  // prepare license if needed
+  if (isSet(meta.license)) {
+    await updateVideoLicense(ctx, video, meta.license)
+  }
+
+  // prepare language if needed
+  if (isSet(meta.language)) {
+    video.language = await processLanguage(ctx, video.language, meta.language)
+  }
+
+  if (isSet(meta.publishedBeforeJoystream)) {
+    video.publishedBeforeJoystream = processPublishedBeforeJoystream(
+      ctx,
+      video.publishedBeforeJoystream,
+      meta.publishedBeforeJoystream
+    )
+  }
+
+  return video
+}
+
+function findAssetByIndex(assets: StorageDataObject[], index: number, name?: string): StorageDataObject | null {
+  if (assets[index]) {
+    return assets[index]
+  }
+
+  invalidMetadata(`Invalid${name ? ' ' + name : ''} asset index`, {
+    numberOfAssets: assets.length,
+    requestedAssetIndex: index,
+  })
+
+  return null
+}
+
+async function processVideoMediaEncoding(
+  { store, event }: StoreContext & EventContext,
+  existingVideoMediaEncoding: VideoMediaEncoding | undefined,
+  metadata: DecodedMetadataObject<IMediaType>
+): Promise<VideoMediaEncoding> {
+  const encoding =
+    existingVideoMediaEncoding ||
+    new VideoMediaEncoding({
+      createdAt: new Date(event.blockTimestamp),
+      createdById: '1',
+      updatedById: '1',
+    })
+  // integrate media encoding-related data
+  integrateMeta(encoding, metadata, ['codecName', 'container', 'mimeMediaType'])
+  encoding.updatedAt = new Date(event.blockTimestamp)
+  await store.save<VideoMediaEncoding>(encoding)
+
+  return encoding
+}
+
+async function processVideoMediaMetadata(
+  ctx: StoreContext & EventContext,
+  existingVideoMedia: VideoMediaMetadata | undefined,
+  metadata: DecodedMetadataObject<IVideoMetadata>,
+  videoSize: BN | undefined
+): Promise<VideoMediaMetadata> {
+  const { store, event } = ctx
+  const videoMedia =
+    existingVideoMedia ||
+    new VideoMediaMetadata({
+      createdInBlock: event.blockNumber,
+      createdAt: new Date(event.blockTimestamp),
+      createdById: '1',
+      updatedById: '1',
+    })
+
+  // integrate media-related data
+  const mediaMetadata = {
+    size: isSet(videoSize) ? new BN(videoSize.toString()) : undefined,
+    pixelWidth: metadata.mediaPixelWidth,
+    pixelHeight: metadata.mediaPixelHeight,
+  }
+  integrateMeta(videoMedia, mediaMetadata, ['pixelWidth', 'pixelHeight', 'size'])
+  videoMedia.updatedAt = new Date(event.blockTimestamp)
+  videoMedia.encoding = await processVideoMediaEncoding(ctx, videoMedia.encoding, metadata.mediaType || {})
+  await store.save<VideoMediaMetadata>(videoMedia)
+
+  return videoMedia
+}
+
+export async function convertContentActorToChannelOwner(
+  store: DatabaseManager,
+  contentActor: ContentActor
+): Promise<{
+  ownerMember?: Membership
+  ownerCuratorGroup?: CuratorGroup
+}> {
+  if (contentActor.isMember) {
+    const memberId = contentActor.asMember.toNumber()
+    const member = await store.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+
+    // ensure member exists
+    if (!member) {
+      return inconsistentState(`Actor is non-existing member`, memberId)
+    }
+
+    return {
+      ownerMember: member,
+      ownerCuratorGroup: undefined, // this will clear the field
+    }
+  }
+
+  if (contentActor.isCurator) {
+    const curatorGroupId = contentActor.asCurator[0].toNumber()
+    const curatorGroup = await store.get(CuratorGroup, {
+      where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
+    })
+
+    // ensure curator group exists
+    if (!curatorGroup) {
+      return inconsistentState('Actor is non-existing curator group', curatorGroupId)
+    }
+
+    return {
+      ownerMember: undefined, // this will clear the field
+      ownerCuratorGroup: curatorGroup,
+    }
+  }
+
+  // TODO: contentActor.isLead
+
+  logger.error('Not implemented ContentActor type', { contentActor: contentActor.toString() })
+  throw new Error('Not-implemented ContentActor type used')
+}
+
+function processPublishedBeforeJoystream(
+  ctx: EventContext & StoreContext,
+  currentValue: Date | undefined,
+  metadata: DecodedMetadataObject<IPublishedBeforeJoystream>
+): Date | undefined {
+  if (!isSet(metadata)) {
+    return currentValue
+  }
+
+  // Property is beeing unset
+  if (!metadata.isPublished) {
+    return undefined
+  }
+
+  // try to parse timestamp from publish date
+  const timestamp = isSet(metadata.date) ? Date.parse(metadata.date) : NaN
+
+  // ensure date is valid
+  if (isNaN(timestamp)) {
+    invalidMetadata(`Invalid date used for publishedBeforeJoystream`, {
+      timestamp,
+    })
+    return currentValue
+  }
+
+  // set new date
+  return new Date(timestamp)
+}
+
+async function processNewAssets(ctx: EventContext & StoreContext, assets: StorageAssets): Promise<StorageDataObject[]> {
+  const assetsUploaded = assets.object_creation_list.length
+  // FIXME: Ideally the runtime would provide object ids in ChannelCreated/VideoCreated/ChannelUpdated(...) events
+  const objects = await getMostRecentlyCreatedDataObjects(ctx.store, assetsUploaded)
+  return objects
+}
+
+function extractVideoSize(assets: StorageDataObject[]): BN | undefined {
+  const mediaAsset = assets.find((a) => a.type?.isTypeOf === DataObjectTypeVideoMedia.name)
+  return mediaAsset ? mediaAsset.size : undefined
+}
+
+async function processLanguage(
+  ctx: EventContext & StoreContext,
+  currentLanguage: Language | undefined,
+  languageIso: string | undefined
+): Promise<Language | undefined> {
+  const { event, store } = ctx
+
+  if (!isSet(languageIso)) {
+    return currentLanguage
+  }
+
+  // ensure language string is valid
+  if (!isValidLanguageCode(languageIso)) {
+    invalidMetadata(`Invalid language ISO-639-1 provided`, languageIso)
+    return currentLanguage
+  }
+
+  // load language
+  const existingLanguage = await store.get(Language, { where: { iso: languageIso } })
+
+  // return existing language if any
+  if (existingLanguage) {
+    return existingLanguage
+  }
+
+  // create new language
+  const newLanguage = new Language({
+    iso: languageIso,
+    createdInBlock: event.blockNumber,
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+    // TODO: remove these lines after Hydra auto-fills the values when cascading save (remove them on all places)
+    createdById: '1',
+    updatedById: '1',
+  })
+
+  await store.save<Language>(newLanguage)
+
+  return newLanguage
+}
+
+async function updateVideoLicense(
+  ctx: StoreContext & EventContext,
+  video: Video,
+  licenseMetadata: ILicense | null | undefined
+): Promise<void> {
+  const { store, event } = ctx
+
+  if (!isSet(licenseMetadata)) {
+    return
+  }
+
+  const previousLicense = video.license
+  let license: License | null = null
+
+  if (!isLicenseEmpty(licenseMetadata)) {
+    // license is meant to be created/updated
+    license =
+      previousLicense ||
+      new License({
+        createdAt: new Date(event.blockTimestamp),
+        createdById: '1',
+        updatedById: '1',
+      })
+    license.updatedAt = new Date(event.blockTimestamp)
+    integrateMeta(license, licenseMetadata, ['attribution', 'code', 'customText'])
+    await store.save<License>(license)
+  }
+
+  // Update license (and potentially remove foreign key reference)
+  // FIXME: Note that we MUST to provide "null" here in order to unset a relation,
+  // See: https://github.com/Joystream/hydra/issues/435
+  video.license = license as License | undefined
+  video.updatedAt = new Date(ctx.event.blockTimestamp)
+  await store.save<Video>(video)
+
+  // Safely remove previous license if needed
+  if (previousLicense && !license) {
+    await store.remove<License>(previousLicense)
+  }
+}
+
+/*
+  Checks if protobof contains license with some fields filled or is empty object (`{}` or `{someKey: undefined, ...}`).
+  Empty object means deletion is requested.
+*/
+function isLicenseEmpty(licenseObject: ILicense): boolean {
+  const somePropertySet = Object.values(licenseObject).some((v) => isSet(v))
+
+  return !somePropertySet
+}
+
+async function processVideoCategory(
+  ctx: EventContext & StoreContext,
+  currentCategory: VideoCategory | undefined,
+  categoryId: number
+): Promise<VideoCategory | undefined> {
+  const { store } = ctx
+
+  // load video category
+  const category = await store.get(VideoCategory, {
+    where: { id: categoryId.toString() },
+  })
+
+  // ensure video category exists
+  if (!category) {
+    invalidMetadata('Non-existing video category association with video requested', categoryId)
+    return currentCategory
+  }
+
+  return category
+}
+
+async function processChannelCategory(
+  ctx: EventContext & StoreContext,
+  currentCategory: ChannelCategory | undefined,
+  categoryId: number
+): Promise<ChannelCategory | undefined> {
+  const { store } = ctx
+
+  // load video category
+  const category = await store.get(ChannelCategory, {
+    where: { id: categoryId.toString() },
+  })
+
+  // ensure video category exists
+  if (!category) {
+    invalidMetadata('Non-existing channel category association with channel requested', categoryId)
+    return currentCategory
+  }
+
+  return category
+}
+
+// Needs to be done every time before data object is removed!
+export async function unsetAssetRelations(store: DatabaseManager, dataObject: StorageDataObject): Promise<void> {
+  const channelAssets = ['avatarPhoto', 'coverPhoto'] as const
+  const videoAssets = ['thumbnailPhoto', 'media'] as const
+
+  // NOTE: we don't need to retrieve multiple channels/videos via `store.getMany()` because dataObject
+  // is allowed to be associated only with one channel/video in runtime
+  const channel = await store.get(Channel, {
+    where: channelAssets.map((assetName) => ({
+      [assetName]: {
+        id: dataObject.id,
+      },
+    })),
+    relations: [...channelAssets],
+  })
+  const video = await store.get(Video, {
+    where: videoAssets.map((assetName) => ({
+      [assetName]: {
+        id: dataObject.id,
+      },
+    })),
+    relations: [...videoAssets],
+  })
+
+  if (channel) {
+    channelAssets.forEach((assetName) => {
+      if (channel[assetName] && channel[assetName]?.id === dataObject.id) {
+        channel[assetName] = null as any
+      }
+    })
+    await store.save<Channel>(channel)
+
+    // emit log event
+    logger.info('Content has been disconnected from Channel', {
+      channelId: channel.id.toString(),
+      dataObjectId: dataObject.id,
+    })
+  }
+
+  if (video) {
+    videoAssets.forEach((assetName) => {
+      if (video[assetName] && video[assetName]?.id === dataObject.id) {
+        video[assetName] = null as any
+      }
+    })
+    await store.save<Video>(video)
+
+    // emit log event
+    logger.info('Content has been disconnected from Video', {
+      videoId: video.id.toString(),
+      dataObjectId: dataObject.id,
+    })
+  }
+}

+ 271 - 0
query-node/mappings/content/video.ts

@@ -0,0 +1,271 @@
+/*
+eslint-disable @typescript-eslint/naming-convention
+*/
+import { EventContext, StoreContext } from '@joystream/hydra-common'
+import { In } from 'typeorm'
+import { Content } from '../generated/types'
+import { deserializeMetadata, inconsistentState, logger } from '../common'
+import { processVideoMetadata } from './utils'
+import { Channel, Video, VideoCategory } from 'query-node/dist/model'
+import { VideoMetadata, VideoCategoryMetadata } from '@joystream/metadata-protobuf'
+import { integrateMeta } from '@joystream/metadata-protobuf/utils'
+import _ from 'lodash'
+
+export async function content_VideoCategoryCreated({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoCategoryId, videoCategoryCreationParameters] = new Content.VideoCategoryCreatedEvent(event).params
+
+  // read metadata
+  const metadata = (await deserializeMetadata(VideoCategoryMetadata, videoCategoryCreationParameters.meta)) || {}
+
+  // create new video category
+  const videoCategory = new VideoCategory({
+    // main data
+    id: videoCategoryId.toString(),
+    videos: [],
+    createdInBlock: event.blockNumber,
+    // fill in auto-generated fields
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+  })
+  integrateMeta(videoCategory, metadata, ['name'])
+
+  // save video category
+  await store.save<VideoCategory>(videoCategory)
+
+  // emit log event
+  logger.info('Video category has been created', { id: videoCategoryId })
+}
+
+export async function content_VideoCategoryUpdated({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoCategoryId, videoCategoryUpdateParameters] = new Content.VideoCategoryUpdatedEvent(event).params
+
+  // load video category
+  const videoCategory = await store.get(VideoCategory, {
+    where: { id: videoCategoryId.toString() },
+  })
+
+  // ensure video category exists
+  if (!videoCategory) {
+    return inconsistentState('Non-existing video category update requested', videoCategoryId)
+  }
+
+  // read metadata
+  const newMeta = deserializeMetadata(VideoCategoryMetadata, videoCategoryUpdateParameters.new_meta) || {}
+  integrateMeta(videoCategory, newMeta, ['name'])
+
+  // set last update time
+  videoCategory.updatedAt = new Date(event.blockTimestamp)
+
+  // save video category
+  await store.save<VideoCategory>(videoCategory)
+
+  // emit log event
+  logger.info('Video category has been updated', { id: videoCategoryId })
+}
+
+export async function content_VideoCategoryDeleted({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoCategoryId] = new Content.VideoCategoryDeletedEvent(event).params
+
+  // load video category
+  const videoCategory = await store.get(VideoCategory, {
+    where: { id: videoCategoryId.toString() },
+  })
+
+  // ensure video category exists
+  if (!videoCategory) {
+    return inconsistentState('Non-existing video category deletion requested', videoCategoryId)
+  }
+
+  // remove video category
+  await store.remove<VideoCategory>(videoCategory)
+
+  // emit log event
+  logger.info('Video category has been deleted', { id: videoCategoryId })
+}
+
+/// //////////////// Video //////////////////////////////////////////////////////
+
+export async function content_VideoCreated(ctx: EventContext & StoreContext): Promise<void> {
+  const { store, event } = ctx
+  // read event data
+  const [, channelId, videoId, videoCreationParameters] = new Content.VideoCreatedEvent(event).params
+
+  // load channel
+  const channel = await store.get(Channel, { where: { id: channelId.toString() } })
+
+  // ensure channel exists
+  if (!channel) {
+    return inconsistentState('Trying to add video to non-existing channel', channelId)
+  }
+
+  const video = new Video({
+    id: videoId.toString(),
+    channel,
+    isCensored: false,
+    isFeatured: false,
+    createdInBlock: event.blockNumber,
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+  })
+  // deserialize & process metadata
+  if (videoCreationParameters.meta.isSome) {
+    const metadata = deserializeMetadata(VideoMetadata, videoCreationParameters.meta.unwrap()) || {}
+    await processVideoMetadata(ctx, video, metadata, videoCreationParameters.assets.unwrapOr(undefined))
+  }
+
+  // save video
+  await store.save<Video>(video)
+
+  // emit log event
+  logger.info('Video has been created', { id: videoId })
+}
+
+export async function content_VideoUpdated(ctx: EventContext & StoreContext): Promise<void> {
+  const { event, store } = ctx
+  // read event data
+  const [, videoId, videoUpdateParameters] = new Content.VideoUpdatedEvent(event).params
+
+  // load video
+  const video = await store.get(Video, {
+    where: { id: videoId.toString() },
+    relations: ['channel', 'license'],
+  })
+
+  // ensure video exists
+  if (!video) {
+    return inconsistentState('Non-existing video update requested', videoId)
+  }
+
+  // prepare changed metadata
+  const newMetadataBytes = videoUpdateParameters.new_meta.unwrapOr(null)
+
+  // update metadata if it was changed
+  if (newMetadataBytes) {
+    const newMetadata = deserializeMetadata(VideoMetadata, newMetadataBytes) || {}
+    await processVideoMetadata(ctx, video, newMetadata, videoUpdateParameters.assets_to_upload.unwrapOr(undefined))
+  }
+
+  // set last update time
+  video.updatedAt = new Date(event.blockTimestamp)
+
+  // save video
+  await store.save<Video>(video)
+
+  // emit log event
+  logger.info('Video has been updated', { id: videoId })
+}
+
+export async function content_VideoDeleted({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoId] = new Content.VideoDeletedEvent(event).params
+
+  // load video
+  const video = await store.get(Video, { where: { id: videoId.toString() } })
+
+  // ensure video exists
+  if (!video) {
+    return inconsistentState('Non-existing video deletion requested', videoId)
+  }
+
+  // remove video
+  await store.remove<Video>(video)
+
+  // emit log event
+  logger.info('Video has been deleted', { id: videoId })
+}
+
+export async function content_VideoCensorshipStatusUpdated({
+  store,
+  event,
+}: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoId, isCensored] = new Content.VideoCensorshipStatusUpdatedEvent(event).params
+
+  // load video
+  const video = await store.get(Video, { where: { id: videoId.toString() } })
+
+  // ensure video exists
+  if (!video) {
+    return inconsistentState('Non-existing video censoring requested', videoId)
+  }
+
+  // update video
+  video.isCensored = isCensored.isTrue
+
+  // set last update time
+  video.updatedAt = new Date(event.blockTimestamp)
+
+  // save video
+  await store.save<Video>(video)
+
+  // emit log event
+  logger.info('Video censorship status has been updated', { id: videoId, isCensored: isCensored.isTrue })
+}
+
+export async function content_FeaturedVideosSet({ store, event }: EventContext & StoreContext): Promise<void> {
+  // read event data
+  const [, videoIds] = new Content.FeaturedVideosSetEvent(event).params
+
+  // load old featured videos
+  const existingFeaturedVideos = await store.getMany(Video, { where: { isFeatured: true } })
+
+  // comparsion utility
+  const isSame = (videoIdA: string) => (videoIdB: string) => videoIdA === videoIdB
+
+  // calculate diff sets
+  const videosToRemove = existingFeaturedVideos.filter(
+    (existingFV) => !videoIds.map((videoId) => videoId.toString()).some(isSame(existingFV.id))
+  )
+  const videoIdsToAdd = videoIds.filter(
+    (videoId) => !existingFeaturedVideos.map((existingFV) => existingFV.id).some(isSame(videoId.toString()))
+  )
+
+  // mark previously featured videos as not-featured
+  await Promise.all(
+    videosToRemove.map(async (video) => {
+      video.isFeatured = false
+      // set last update time
+      video.updatedAt = new Date(event.blockTimestamp)
+
+      await store.save<Video>(video)
+    })
+  )
+
+  // read previously not-featured videos that are meant to be featured
+  const videosToAdd = await store.getMany(Video, {
+    where: {
+      id: In(videoIdsToAdd.map((item) => item.toString())),
+    },
+  })
+
+  if (videosToAdd.length !== videoIdsToAdd.length) {
+    // Do not throw, as this is not validated by the runtime
+    console.warn(
+      'Non-existing video(s) in featuredVideos set:',
+      _.difference(
+        videoIdsToAdd.map((v) => v.toString()),
+        videosToAdd.map((v) => v.id)
+      )
+    )
+  }
+
+  // mark previously not-featured videos as featured
+  await Promise.all(
+    videosToAdd.map(async (video) => {
+      video.isFeatured = true
+
+      // set last update time
+      video.updatedAt = new Date(event.blockTimestamp)
+
+      await store.save<Video>(video)
+    })
+  )
+
+  // emit log event
+  const addedVideoIds = videosToAdd.map((v) => v.id)
+  const removedVideoIds = videosToRemove.map((v) => v.id)
+  logger.info('Featured videos have been updated', { addedVideoIds, removedVideoIds })
+}

+ 8 - 0
query-node/mappings/genesis-data/index.ts

@@ -0,0 +1,8 @@
+import { MemberJson, StorageSystemJson } from './types'
+import storageSystemJson from './storageSystem.json'
+import membersJson from './members.json'
+
+const storageSystem: StorageSystemJson = storageSystemJson
+const members: MemberJson[] = membersJson
+
+export { storageSystem, members }

+ 0 - 0
query-node/mappings/sumer/bootstrap/data/members.json → query-node/mappings/genesis-data/members.json


+ 2 - 1
query-node/mappings/giza/genesis-data/storageSystem.json → query-node/mappings/genesis-data/storageSystem.json

@@ -6,5 +6,6 @@
   "uploadingBlocked": false,
   "dataObjectFeePerMb": 0,
   "storageBucketMaxObjectsCountLimit": 0,
-  "storageBucketMaxObjectsSizeLimit": 0
+  "storageBucketMaxObjectsSizeLimit": 0,
+  "nextDataObjectId": 0
 }

+ 20 - 0
query-node/mappings/genesis-data/types.ts

@@ -0,0 +1,20 @@
+export type MemberJson = {
+  member_id: string
+  root_account: string
+  controller_account: string
+  handle: string
+  about?: string
+  avatar_uri?: string
+  registered_at_time: number
+}
+
+export type StorageSystemJson = {
+  id: string
+  blacklist: string[]
+  storageBucketsPerBagLimit: number
+  distributionBucketsPerBagLimit: number
+  uploadingBlocked: boolean
+  dataObjectFeePerMb: number | string
+  storageBucketMaxObjectsCountLimit: number | string
+  storageBucketMaxObjectsSizeLimit: number | string
+}

+ 35 - 0
query-node/mappings/genesis.ts

@@ -0,0 +1,35 @@
+import { StoreContext } from '@joystream/hydra-common'
+import BN from 'bn.js'
+import { Membership, MembershipEntryMethod, StorageSystemParameters } from 'query-node/dist/model'
+import { storageSystem, members } from './genesis-data'
+
+export async function loadGenesisData({ store }: StoreContext): Promise<void> {
+  // Storage system
+  await store.save<StorageSystemParameters>(
+    new StorageSystemParameters({
+      ...storageSystem,
+      storageBucketMaxObjectsCountLimit: new BN(storageSystem.storageBucketMaxObjectsCountLimit),
+      storageBucketMaxObjectsSizeLimit: new BN(storageSystem.storageBucketMaxObjectsSizeLimit),
+      dataObjectFeePerMb: new BN(storageSystem.dataObjectFeePerMb),
+    })
+  )
+  // Members
+  for (const m of members) {
+    // create new membership
+    const member = new Membership({
+      // main data
+      id: m.member_id,
+      rootAccount: m.root_account,
+      controllerAccount: m.controller_account,
+      handle: m.handle,
+      about: m.about,
+      avatarUri: m.avatar_uri,
+      createdInBlock: 0,
+      entry: MembershipEntryMethod.GENESIS,
+      // fill in auto-generated fields
+      createdAt: new Date(m.registered_at_time),
+      updatedAt: new Date(m.registered_at_time),
+    })
+    await store.save<Membership>(member)
+  }
+}

+ 0 - 63
query-node/mappings/giza/common.ts

@@ -1,63 +0,0 @@
-import { DatabaseManager } from '@joystream/hydra-common'
-import { BaseModel } from '@joystream/warthog'
-import { WorkingGroup } from '@joystream/types/augment/all'
-import { AnyMetadataClass, DecodedMetadataObject } from '@joystream/metadata-protobuf/types'
-import { metaToObject } from '@joystream/metadata-protobuf/utils'
-import { Bytes } from '@polkadot/types'
-
-type EntityClass<T extends BaseModel> = {
-  new (): T
-  name: string
-}
-
-type RelationsArr<T extends BaseModel> = Exclude<
-  keyof T & string,
-  { [K in keyof T]: T[K] extends BaseModel | undefined ? '' : T[K] extends BaseModel[] | undefined ? '' : K }[keyof T]
->[]
-
-export async function getById<T extends BaseModel>(
-  store: DatabaseManager,
-  entityClass: EntityClass<T>,
-  id: string,
-  relations?: RelationsArr<T>
-): Promise<T> {
-  const result = await store.get(entityClass, { where: { id }, relations })
-  if (!result) {
-    throw new Error(`Expected ${entityClass.name} not found by ID: ${id}`)
-  }
-
-  return result
-}
-
-export type WorkingGroupModuleName = 'storageWorkingGroup' | 'contentDirectoryWorkingGroup'
-
-export function getWorkingGroupModuleName(group: WorkingGroup): WorkingGroupModuleName {
-  if (group.isContent) {
-    return 'contentDirectoryWorkingGroup'
-  } else if (group.isStorage) {
-    return 'storageWorkingGroup'
-  }
-
-  throw new Error(`Unsupported working group encountered: ${group.type}`)
-}
-
-export function deserializeMetadata<T>(
-  metadataType: AnyMetadataClass<T>,
-  metadataBytes: Bytes
-): DecodedMetadataObject<T> | null {
-  try {
-    return metaToObject(metadataType, metadataType.decode(metadataBytes.toU8a(true)))
-  } catch (e) {
-    console.error(`Cannot deserialize ${metadataType.name}! Provided bytes: (${metadataBytes.toHex()})`)
-    return null
-  }
-}
-
-export function bytesToString(b: Bytes): string {
-  return (
-    Buffer.from(b.toU8a(true))
-      .toString()
-      // eslint-disable-next-line no-control-regex
-      .replace(/\u0000/g, '')
-  )
-}

+ 0 - 3
query-node/mappings/giza/genesis-data/index.ts

@@ -1,3 +0,0 @@
-import storageSystem from './storageSystem.json'
-
-export { storageSystem }

+ 0 - 16
query-node/mappings/giza/genesis.ts

@@ -1,16 +0,0 @@
-import { StoreContext } from '@joystream/hydra-common'
-import BN from 'bn.js'
-import { StorageSystemParameters } from 'query-node/dist/model'
-import { storageSystem } from './genesis-data'
-
-export async function loadGenesisData({ store }: StoreContext): Promise<void> {
-  // Storage system
-  await store.save<StorageSystemParameters>(
-    new StorageSystemParameters({
-      ...storageSystem,
-      storageBucketMaxObjectsCountLimit: new BN(storageSystem.storageBucketMaxObjectsCountLimit),
-      storageBucketMaxObjectsSizeLimit: new BN(storageSystem.storageBucketMaxObjectsSizeLimit),
-      dataObjectFeePerMb: new BN(storageSystem.dataObjectFeePerMb),
-    })
-  )
-}

+ 0 - 2
query-node/mappings/giza/index.ts

@@ -1,2 +0,0 @@
-export * from './genesis'
-export * from './storage'

+ 3 - 2
query-node/mappings/sumer/index.ts → query-node/mappings/index.ts

@@ -1,4 +1,5 @@
-export * from './content'
 export * from './membership'
-export * from './storage'
 export * from './workingGroup'
+export * from './content'
+export * from './storage'
+export * from './genesis'

+ 37 - 45
query-node/mappings/sumer/membership.ts → query-node/mappings/membership.ts

@@ -1,25 +1,16 @@
-import { fixBlockTimestamp } from './eventFix'
 import { Bytes } from '@polkadot/types'
 import { MemberId } from '@joystream/types/members'
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { FindConditions } from 'typeorm'
-
-import {
-  convertBytesToString,
-  inconsistentState,
-  logger,
-  extractExtrinsicArgs,
-  extractSudoCallParameters,
-} from './common'
-import { Members } from '../../generated/types'
-import { MembershipEntryMethod, Membership } from 'query-node'
+import { SubstrateEvent, EventContext, StoreContext } from '@joystream/hydra-common'
+
+import { bytesToString, inconsistentState, logger, extractExtrinsicArgs, extractSudoCallParameters } from './common'
+import { Members } from './generated/types'
+import { MembershipEntryMethod, Membership } from 'query-node/dist/model'
 import { EntryMethod } from '@joystream/types/augment'
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberRegistered(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberRegistered({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
-  const { accountId, memberId, entryMethod } = new Members.MemberRegisteredEvent(event).data
+  const [memberId, accountId, entryMethod] = new Members.MemberRegisteredEvent(event).params
   const { avatarUri, about, handle } = extractExtrinsicArgs(event, Members.BuyMembershipCall, {
     handle: 1,
     avatarUri: 2,
@@ -32,26 +23,27 @@ export async function members_MemberRegistered(db: DatabaseManager, event: Subst
     id: memberId.toString(),
     rootAccount: accountId.toString(),
     controllerAccount: accountId.toString(),
-    handle: convertBytesToString(handle.unwrapOr(null)),
-    about: convertBytesToString(about.unwrapOr(null)),
-    avatarUri: convertBytesToString(avatarUri.unwrapOr(null)),
+    // Handle is required by the runtime during registration. Lack of it will throw an error
+    handle: bytesToString(handle.unwrap()),
+    about: about.isSome ? bytesToString(about.unwrap()) : undefined,
+    avatarUri: avatarUri.isSome ? bytesToString(avatarUri.unwrap()) : undefined,
     createdInBlock: event.blockNumber,
     entry: convertEntryMethod(entryMethod),
 
     // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
   })
 
   // save membership
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info('Member has been registered', { ids: memberId })
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberUpdatedAboutText(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberUpdatedAboutText({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
   const { text, memberId } = isUpdateMembershipExtrinsic(event)
     ? unpackUpdateMembershipOptions(
@@ -60,7 +52,7 @@ export async function members_MemberUpdatedAboutText(db: DatabaseManager, event:
     : extractExtrinsicArgs(event, Members.ChangeMemberAboutTextCall, { memberId: 0, text: 1 })
 
   // load member
-  const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+  const member = await store.get(Membership, { where: { id: memberId.toString() } })
 
   // ensure member exists
   if (!member) {
@@ -68,20 +60,20 @@ export async function members_MemberUpdatedAboutText(db: DatabaseManager, event:
   }
 
   // update member
-  member.about = convertBytesToString(text)
+  member.about = bytesToString(text)
 
   // set last update time
-  member.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  member.updatedAt = new Date(event.blockTimestamp)
 
   // save member
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info("Member's about text has been updated", { ids: memberId })
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberUpdatedAvatar(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberUpdatedAvatar({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
   const { uri, memberId } = isUpdateMembershipExtrinsic(event)
     ? unpackUpdateMembershipOptions(
@@ -90,7 +82,7 @@ export async function members_MemberUpdatedAvatar(db: DatabaseManager, event: Su
     : extractExtrinsicArgs(event, Members.ChangeMemberAvatarCall, { memberId: 0, uri: 1 })
 
   // load member
-  const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+  const member = await store.get(Membership, { where: { id: memberId.toString() } })
 
   // ensure member exists
   if (!member) {
@@ -98,20 +90,20 @@ export async function members_MemberUpdatedAvatar(db: DatabaseManager, event: Su
   }
 
   // update member
-  member.avatarUri = convertBytesToString(uri)
+  member.avatarUri = bytesToString(uri)
 
   // set last update time
-  member.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  member.updatedAt = new Date(event.blockTimestamp)
 
   // save member
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info("Member's avatar has been updated", { ids: memberId })
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberUpdatedHandle(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberUpdatedHandle({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
   const { handle, memberId } = isUpdateMembershipExtrinsic(event)
     ? unpackUpdateMembershipOptions(
@@ -120,7 +112,7 @@ export async function members_MemberUpdatedHandle(db: DatabaseManager, event: Su
     : extractExtrinsicArgs(event, Members.ChangeMemberHandleCall, { memberId: 0, handle: 1 })
 
   // load member
-  const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+  const member = await store.get(Membership, { where: { id: memberId.toString() } })
 
   // ensure member exists
   if (!member) {
@@ -128,20 +120,20 @@ export async function members_MemberUpdatedHandle(db: DatabaseManager, event: Su
   }
 
   // update member
-  member.handle = convertBytesToString(handle)
+  member.handle = bytesToString(handle)
 
   // set last update time
-  member.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  member.updatedAt = new Date(event.blockTimestamp)
 
   // save member
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info("Member's avatar has been updated", { ids: memberId })
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberSetRootAccount(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberSetRootAccount({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
   const { newRootAccount, memberId } = extractExtrinsicArgs(event, Members.SetRootAccountCall, {
     memberId: 0,
@@ -149,7 +141,7 @@ export async function members_MemberSetRootAccount(db: DatabaseManager, event: S
   })
 
   // load member
-  const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+  const member = await store.get(Membership, { where: { id: memberId.toString() } })
 
   // ensure member exists
   if (!member) {
@@ -160,17 +152,17 @@ export async function members_MemberSetRootAccount(db: DatabaseManager, event: S
   member.rootAccount = newRootAccount.toString()
 
   // set last update time
-  member.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  member.updatedAt = new Date(event.blockTimestamp)
 
   // save member
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info("Member's root has been updated", { ids: memberId })
 }
 
 // eslint-disable-next-line @typescript-eslint/naming-convention
-export async function members_MemberSetControllerAccount(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
+export async function members_MemberSetControllerAccount({ event, store }: EventContext & StoreContext): Promise<void> {
   // read event data
   const { newControllerAccount, memberId } = extractExtrinsicArgs(event, Members.SetControllerAccountCall, {
     memberId: 0,
@@ -178,7 +170,7 @@ export async function members_MemberSetControllerAccount(db: DatabaseManager, ev
   })
 
   // load member
-  const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
+  const member = await store.get(Membership, { where: { id: memberId.toString() } })
 
   // ensure member exists
   if (!member) {
@@ -189,10 +181,10 @@ export async function members_MemberSetControllerAccount(db: DatabaseManager, ev
   member.controllerAccount = newControllerAccount.toString()
 
   // set last update time
-  member.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
+  member.updatedAt = new Date(event.blockTimestamp)
 
   // save member
-  await db.save<Membership>(member)
+  await store.save<Membership>(member)
 
   // emit log event
   logger.info("Member's controller has been updated", { ids: memberId })

+ 1 - 1
query-node/mappings/package.json

@@ -16,7 +16,7 @@
     "@polkadot/types": "4.2.1",
     "@joystream/hydra-common": "3.1.0-alpha.1",
     "@joystream/hydra-db-utils": "3.1.0-alpha.1",
-    "@joystream/content-metadata-protobuf": "^1.1.0",
+    "@joystream/metadata-protobuf": "^1.0.0",
     "@joystream/types": "^0.17.0",
     "@joystream/warthog": "2.35.0"
   },

+ 43 - 179
query-node/mappings/giza/storage/index.ts → query-node/mappings/storage/index.ts

@@ -1,8 +1,8 @@
 /*
 eslint-disable @typescript-eslint/naming-convention
 */
-import { DatabaseManager, EventContext, StoreContext } from '@joystream/hydra-common'
-import { Storage } from '../../generated/types/storage'
+import { EventContext, StoreContext } from '@joystream/hydra-common'
+import { Storage } from '../generated/types/storage'
 import {
   DistributionBucket,
   DistributionBucketFamily,
@@ -11,11 +11,6 @@ import {
   DistributionBucketOperatorStatus,
   NodeLocationMetadata,
   StorageBag,
-  StorageBagOwner,
-  StorageBagOwnerChannel,
-  StorageBagOwnerCouncil,
-  StorageBagOwnerMember,
-  StorageBagOwnerWorkingGroup,
   StorageBucket,
   StorageBucketOperatorStatusActive,
   StorageBucketOperatorStatusInvited,
@@ -27,167 +22,26 @@ import {
   StorageBagStorageAssignment,
 } from 'query-node/dist/model'
 import BN from 'bn.js'
-import { getById, getWorkingGroupModuleName, bytesToString } from '../common'
-import { BTreeSet } from '@polkadot/types'
-import { DataObjectCreationParameters } from '@joystream/types/storage'
-import { registry } from '@joystream/types'
+import { getById } from '../common'
 import { In } from 'typeorm'
-import _ from 'lodash'
-import { DataObjectId, BagId, DynamicBagId, StaticBagId } from '@joystream/types/augment/all'
 import {
   processDistributionBucketFamilyMetadata,
   processDistributionOperatorMetadata,
   processStorageOperatorMetadata,
 } from './metadata'
-
-async function getDataObjectsInBag(
-  store: DatabaseManager,
-  bagId: BagId,
-  dataObjectIds: BTreeSet<DataObjectId>
-): Promise<StorageDataObject[]> {
-  const dataObjects = await store.getMany(StorageDataObject, {
-    where: {
-      id: In(Array.from(dataObjectIds).map((id) => id.toString())),
-      storageBag: { id: getBagId(bagId) },
-    },
-  })
-  if (dataObjects.length !== Array.from(dataObjectIds).length) {
-    throw new Error(
-      `Missing data objects: ${_.difference(
-        Array.from(dataObjectIds).map((id) => id.toString()),
-        dataObjects.map((o) => o.id)
-      )} in bag ${getBagId(bagId)}`
-    )
-  }
-  return dataObjects
-}
-
-function getStaticBagOwner(bagId: StaticBagId): typeof StorageBagOwner {
-  if (bagId.isCouncil) {
-    return new StorageBagOwnerCouncil()
-  } else if (bagId.isWorkingGroup) {
-    const owner = new StorageBagOwnerWorkingGroup()
-    owner.workingGroupId = getWorkingGroupModuleName(bagId.asWorkingGroup)
-    return owner
-  } else {
-    throw new Error(`Unexpected static bag type: ${bagId.type}`)
-  }
-}
-
-function getDynamicBagOwner(bagId: DynamicBagId) {
-  if (bagId.isChannel) {
-    const owner = new StorageBagOwnerChannel()
-    owner.channelId = bagId.asChannel.toNumber()
-    return owner
-  } else if (bagId.isMember) {
-    const owner = new StorageBagOwnerMember()
-    owner.memberId = bagId.asMember.toNumber()
-    return owner
-  } else {
-    throw new Error(`Unexpected dynamic bag type: ${bagId.type}`)
-  }
-}
-
-function getStaticBagId(bagId: StaticBagId): string {
-  if (bagId.isCouncil) {
-    return `static:council`
-  } else if (bagId.isWorkingGroup) {
-    return `static:wg:${bagId.asWorkingGroup.type.toLowerCase()}`
-  } else {
-    throw new Error(`Unexpected static bag type: ${bagId.type}`)
-  }
-}
-
-function getDynamicBagId(bagId: DynamicBagId): string {
-  if (bagId.isChannel) {
-    return `dynamic:channel:${bagId.asChannel.toString()}`
-  } else if (bagId.isMember) {
-    return `dynamic:member:${bagId.asMember.toString()}`
-  } else {
-    throw new Error(`Unexpected dynamic bag type: ${bagId.type}`)
-  }
-}
-
-function getBagId(bagId: BagId) {
-  return bagId.isStatic ? getStaticBagId(bagId.asStatic) : getDynamicBagId(bagId.asDynamic)
-}
-
-async function getDynamicBag(
-  store: DatabaseManager,
-  bagId: DynamicBagId,
-  relations?: 'objects'[]
-): Promise<StorageBag> {
-  return getById(store, StorageBag, getDynamicBagId(bagId), relations)
-}
-
-async function getStaticBag(store: DatabaseManager, bagId: StaticBagId, relations?: 'objects'[]): Promise<StorageBag> {
-  const id = getStaticBagId(bagId)
-  const bag = await store.get(StorageBag, { where: { id }, relations })
-  if (!bag) {
-    console.log(`Creating new static bag: ${id}`)
-    const newBag = new StorageBag({
-      id,
-      owner: getStaticBagOwner(bagId),
-    })
-    await store.save<StorageBag>(newBag)
-    return newBag
-  }
-  return bag
-}
-
-async function getBag(store: DatabaseManager, bagId: BagId, relations?: 'objects'[]): Promise<StorageBag> {
-  return bagId.isStatic
-    ? getStaticBag(store, bagId.asStatic, relations)
-    : getDynamicBag(store, bagId.asDynamic, relations)
-}
-
-async function getDistributionBucketOperatorWithMetadata(
-  store: DatabaseManager,
-  id: string
-): Promise<DistributionBucketOperator> {
-  const operator = await store.get(DistributionBucketOperator, {
-    where: { id },
-    relations: ['metadata', 'metadata.nodeLocation', 'metadata.nodeLocation.coordinates'],
-  })
-  if (!operator) {
-    throw new Error(`DistributionBucketOperator not found by id: ${id}`)
-  }
-  return operator
-}
-
-async function getStorageBucketWithOperatorMetadata(store: DatabaseManager, id: string): Promise<StorageBucket> {
-  const bucket = await store.get(StorageBucket, {
-    where: { id },
-    relations: ['operatorMetadata', 'operatorMetadata.nodeLocation', 'operatorMetadata.nodeLocation.coordinates'],
-  })
-  if (!bucket) {
-    throw new Error(`StorageBucket not found by id: ${id}`)
-  }
-  return bucket
-}
-
-async function getDistributionBucketFamilyWithMetadata(
-  store: DatabaseManager,
-  id: string
-): Promise<DistributionBucketFamily> {
-  const family = await store.get(DistributionBucketFamily, {
-    where: { id },
-    relations: ['metadata', 'metadata.boundary'],
-  })
-  if (!family) {
-    throw new Error(`DistributionBucketFamily not found by id: ${id}`)
-  }
-  return family
-}
-
-async function getStorageSystem(store: DatabaseManager) {
-  const storageSystem = await store.get(StorageSystemParameters, {})
-  if (!storageSystem) {
-    throw new Error('Storage system entity is missing!')
-  }
-
-  return storageSystem
-}
+import {
+  createDataObjects,
+  getStorageSystem,
+  removeDataObject,
+  getStorageBucketWithOperatorMetadata,
+  getBag,
+  getDynamicBagId,
+  getDynamicBagOwner,
+  getDataObjectsInBag,
+  getDynamicBag,
+  getDistributionBucketFamilyWithMetadata,
+  getDistributionBucketOperatorWithMetadata,
+} from './utils'
 
 // STORAGE BUCKETS
 
@@ -344,18 +198,40 @@ export async function storage_StorageBucketDeleted({ event, store }: EventContex
 
 // DYNAMIC BAGS
 export async function storage_DynamicBagCreated({ event, store }: EventContext & StoreContext): Promise<void> {
-  const [bagId] = new Storage.DynamicBagCreatedEvent(event).params
+  const [bagId, , storageBucketIdsSet, distributionBucketIdsSet] = new Storage.DynamicBagCreatedEvent(event).params
   const storageBag = new StorageBag({
     id: getDynamicBagId(bagId),
     owner: getDynamicBagOwner(bagId),
   })
+  const storageAssignments = Array.from(storageBucketIdsSet).map(
+    (bucketId) =>
+      new StorageBagStorageAssignment({
+        id: `${storageBag.id}-${bucketId.toString()}`,
+        storageBag,
+        storageBucket: new StorageBucket({ id: bucketId.toString() }),
+      })
+  )
+  const distributionAssignments = Array.from(distributionBucketIdsSet).map(
+    (bucketId) =>
+      new StorageBagDistributionAssignment({
+        id: `${storageBag.id}-${bucketId.toString()}`,
+        storageBag,
+        distributionBucket: new DistributionBucket({ id: bucketId.toString() }),
+      })
+  )
   await store.save<StorageBag>(storageBag)
+  await Promise.all(storageAssignments.map((a) => store.save<StorageBagStorageAssignment>(a)))
+  await Promise.all(distributionAssignments.map((a) => store.save<StorageBagDistributionAssignment>(a)))
 }
 
 export async function storage_DynamicBagDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
   const [, bagId] = new Storage.DynamicBagDeletedEvent(event).params
   const storageBag = await getDynamicBag(store, bagId, ['objects'])
-  // The bag should already be empty, so no cascade-remove required
+  // TODO: Cascade remove on db level (would require changes in Hydra / comitting autogenerated files)
+  const storageAssignments = await store.getMany(StorageBagStorageAssignment, { where: { storageBag } })
+  const distributionAssignments = await store.getMany(StorageBagDistributionAssignment, { where: { storageBag } })
+  await Promise.all(storageAssignments.map((a) => store.remove<StorageBagStorageAssignment>(a)))
+  await Promise.all(distributionAssignments.map((a) => store.remove<StorageBagDistributionAssignment>(a)))
   await store.remove<StorageBag>(storageBag)
 }
 
@@ -363,20 +239,8 @@ export async function storage_DynamicBagDeleted({ event, store }: EventContext &
 
 // Note: "Uploaded" here actually means "created" (the real upload happens later)
 export async function storage_DataObjectsUploaded({ event, store }: EventContext & StoreContext): Promise<void> {
-  const [dataObjectIds, uploadParams] = new Storage.DataObjectsUploadedEvent(event).params
-  const { bagId, objectCreationList } = uploadParams
-  const storageBag = await getBag(store, bagId)
-  const dataObjects = dataObjectIds.map((objectId, i) => {
-    const objectParams = new DataObjectCreationParameters(registry, objectCreationList[i].toJSON() as any)
-    return new StorageDataObject({
-      id: objectId.toString(),
-      isAccepted: false,
-      ipfsHash: bytesToString(objectParams.ipfsContentId),
-      size: new BN(objectParams.getField('size').toString()),
-      storageBag,
-    })
-  })
-  await Promise.all(dataObjects.map((o) => store.save<StorageDataObject>(o)))
+  const [dataObjectIds, uploadParams, deletionPrize] = new Storage.DataObjectsUploadedEvent(event).params
+  await createDataObjects(store, uploadParams, deletionPrize, dataObjectIds)
 }
 
 export async function storage_PendingDataObjectsAccepted({ event, store }: EventContext & StoreContext): Promise<void> {
@@ -405,7 +269,7 @@ export async function storage_DataObjectsMoved({ event, store }: EventContext &
 export async function storage_DataObjectsDeleted({ event, store }: EventContext & StoreContext): Promise<void> {
   const [, bagId, dataObjectIds] = new Storage.DataObjectsDeletedEvent(event).params
   const dataObjects = await getDataObjectsInBag(store, bagId, dataObjectIds)
-  await Promise.all(dataObjects.map((o) => store.remove<StorageDataObject>(o)))
+  await Promise.all(dataObjects.map((o) => removeDataObject(store, o)))
 }
 
 // DISTRIBUTION FAMILY

+ 65 - 16
query-node/mappings/giza/storage/metadata.ts → query-node/mappings/storage/metadata.ts

@@ -5,16 +5,32 @@ import {
   StorageBucketOperatorMetadata,
   GeoCoordinates,
   NodeLocationMetadata,
+  Continent,
+  GeographicalAreaContinent,
+  GeographicalAreaCountry,
+  GeographicalAreaSubdivistion,
+  DistributionBucketFamilyGeographicArea,
 } from 'query-node/dist/model'
-import { deserializeMetadata } from '../common'
+import { deserializeMetadata, invalidMetadata } from '../common'
 import { Bytes } from '@polkadot/types'
 import {
   DistributionBucketOperatorMetadata as DistributionBucketOperatorMetadataProto,
   StorageBucketOperatorMetadata as StorageBucketOperatorMetadataProto,
   DistributionBucketFamilyMetadata as DistributionBucketFamilyMetadataProto,
   INodeLocationMetadata,
+  GeographicalArea as GeographicalAreaProto,
 } from '@joystream/metadata-protobuf'
-import { isSet, isEmptyObject, isValidCountryCode } from '@joystream/metadata-protobuf/utils'
+import { isSet, isEmptyObject, isValidCountryCode, isValidSubdivisionCode } from '@joystream/metadata-protobuf/utils'
+
+const protobufContinentToGraphlContinent: { [key in GeographicalAreaProto.Continent]: Continent } = {
+  [GeographicalAreaProto.Continent.AF]: Continent.AF,
+  [GeographicalAreaProto.Continent.AN]: Continent.AN,
+  [GeographicalAreaProto.Continent.AS]: Continent.AS,
+  [GeographicalAreaProto.Continent.EU]: Continent.EU,
+  [GeographicalAreaProto.Continent.NA]: Continent.NA,
+  [GeographicalAreaProto.Continent.OC]: Continent.OC,
+  [GeographicalAreaProto.Continent.SA]: Continent.SA,
+}
 
 async function processNodeLocationMetadata(
   store: DatabaseManager,
@@ -118,24 +134,57 @@ export async function processDistributionBucketFamilyMetadata(
   if (isSet(meta.description)) {
     metadataEntity.description = meta.description || (null as any)
   }
+  if (isSet(meta.latencyTestTargets)) {
+    metadataEntity.latencyTestTargets = meta.latencyTestTargets.filter((t) => t)
+  }
 
   await store.save<DistributionBucketOperatorMetadata>(metadataEntity)
 
-  // Update boundary after metadata is saved (since we need an id to reference)
-  if (isSet(meta.boundary)) {
-    await Promise.all((metadataEntity.boundary || []).map((coords) => store.remove<GeoCoordinates>(coords)))
+  // Update areas after metadata is saved (since we need an id to reference)
+  if (isSet(meta.areas)) {
+    // Drop current areas
+    await Promise.all(metadataEntity.areas?.map((a) => store.remove<DistributionBucketFamilyGeographicArea>(a)) || [])
+    // Save new areas
     await Promise.all(
-      meta.boundary
-        .filter((c) => !isEmptyObject(c))
-        .map(({ latitude, longitude }) =>
-          store.save<GeoCoordinates>(
-            new GeoCoordinates({
-              latitude: latitude || 0,
-              longitude: longitude || 0,
-              boundarySourceBucketFamilyMeta: metadataEntity,
-            })
-          )
-        )
+      meta.areas
+        .filter((a) => !isEmptyObject(a))
+        .map(async (a) => {
+          const area = new DistributionBucketFamilyGeographicArea({
+            distributionBucketFamilyMetadata: metadataEntity,
+          })
+
+          if (a.continent) {
+            const continent = new GeographicalAreaContinent()
+            continent.code = protobufContinentToGraphlContinent[a.continent]
+            if (!continent.code) {
+              return invalidMetadata(`Unrecognized continent enum variant: ${a.continent}`)
+            }
+            area.id = `${metadataEntity.id}-C-${continent.code}`
+            area.area = continent
+          }
+
+          if (a.countryCode) {
+            if (!isValidCountryCode(a.countryCode)) {
+              return invalidMetadata(`Invalid country code: ${a.countryCode}`)
+            }
+            const country = new GeographicalAreaCountry()
+            country.code = a.countryCode
+            area.id = `${metadataEntity.id}-c-${country.code}`
+            area.area = country
+          }
+
+          if (a.subdivisionCode) {
+            if (!isValidSubdivisionCode(a.subdivisionCode)) {
+              return invalidMetadata(`Invalid subdivision code: ${a.subdivisionCode}`)
+            }
+            const subdivision = new GeographicalAreaSubdivistion()
+            subdivision.code = a.subdivisionCode
+            area.id = `${metadataEntity.id}-s-${subdivision.code}`
+            area.area = subdivision
+          }
+
+          await store.save<DistributionBucketFamilyGeographicArea>(area)
+        })
     )
   }
 

+ 237 - 0
query-node/mappings/storage/utils.ts

@@ -0,0 +1,237 @@
+import { DatabaseManager } from '@joystream/hydra-common'
+import { UploadParameters } from '@joystream/types/augment'
+import { registry } from '@joystream/types'
+import { DataObjectCreationParameters as ObjectCreationParams } from '@joystream/types/storage'
+import {
+  DataObjectTypeUnknown,
+  StorageBag,
+  StorageDataObject,
+  StorageSystemParameters,
+  StorageBagOwner,
+  StorageBagOwnerChannel,
+  StorageBagOwnerCouncil,
+  StorageBagOwnerMember,
+  StorageBagOwnerWorkingGroup,
+  StorageBucket,
+  DistributionBucketOperator,
+  DistributionBucketFamily,
+} from 'query-node/dist/model'
+import BN from 'bn.js'
+import { bytesToString, inconsistentState, getById } from '../common'
+import { In } from 'typeorm'
+import { unsetAssetRelations } from '../content/utils'
+
+import { BTreeSet } from '@polkadot/types'
+import _ from 'lodash'
+import { DataObjectId, BagId, DynamicBagId, StaticBagId } from '@joystream/types/augment/all'
+import { Balance } from '@polkadot/types/interfaces'
+
+export async function getDataObjectsInBag(
+  store: DatabaseManager,
+  bagId: BagId,
+  dataObjectIds: BTreeSet<DataObjectId>
+): Promise<StorageDataObject[]> {
+  const dataObjects = await store.getMany(StorageDataObject, {
+    where: {
+      id: In(Array.from(dataObjectIds).map((id) => id.toString())),
+      storageBag: { id: getBagId(bagId) },
+    },
+  })
+  if (dataObjects.length !== Array.from(dataObjectIds).length) {
+    throw new Error(
+      `Missing data objects: ${_.difference(
+        Array.from(dataObjectIds).map((id) => id.toString()),
+        dataObjects.map((o) => o.id)
+      )} in bag ${getBagId(bagId)}`
+    )
+  }
+  return dataObjects
+}
+
+export function getStaticBagOwner(bagId: StaticBagId): typeof StorageBagOwner {
+  if (bagId.isCouncil) {
+    return new StorageBagOwnerCouncil()
+  } else if (bagId.isWorkingGroup) {
+    const owner = new StorageBagOwnerWorkingGroup()
+    owner.workingGroupId = bagId.asWorkingGroup.toString().toLowerCase()
+    return owner
+  } else {
+    throw new Error(`Unexpected static bag type: ${bagId.type}`)
+  }
+}
+
+export function getDynamicBagOwner(bagId: DynamicBagId) {
+  if (bagId.isChannel) {
+    const owner = new StorageBagOwnerChannel()
+    owner.channelId = bagId.asChannel.toNumber()
+    return owner
+  } else if (bagId.isMember) {
+    const owner = new StorageBagOwnerMember()
+    owner.memberId = bagId.asMember.toNumber()
+    return owner
+  } else {
+    throw new Error(`Unexpected dynamic bag type: ${bagId.type}`)
+  }
+}
+
+export function getStaticBagId(bagId: StaticBagId): string {
+  if (bagId.isCouncil) {
+    return `static:council`
+  } else if (bagId.isWorkingGroup) {
+    return `static:wg:${bagId.asWorkingGroup.type.toLowerCase()}`
+  } else {
+    throw new Error(`Unexpected static bag type: ${bagId.type}`)
+  }
+}
+
+export function getDynamicBagId(bagId: DynamicBagId): string {
+  if (bagId.isChannel) {
+    return `dynamic:channel:${bagId.asChannel.toString()}`
+  } else if (bagId.isMember) {
+    return `dynamic:member:${bagId.asMember.toString()}`
+  } else {
+    throw new Error(`Unexpected dynamic bag type: ${bagId.type}`)
+  }
+}
+
+export function getBagId(bagId: BagId) {
+  return bagId.isStatic ? getStaticBagId(bagId.asStatic) : getDynamicBagId(bagId.asDynamic)
+}
+
+export async function getDynamicBag(
+  store: DatabaseManager,
+  bagId: DynamicBagId,
+  relations?: 'objects'[]
+): Promise<StorageBag> {
+  return getById(store, StorageBag, getDynamicBagId(bagId), relations)
+}
+
+export async function getStaticBag(
+  store: DatabaseManager,
+  bagId: StaticBagId,
+  relations?: 'objects'[]
+): Promise<StorageBag> {
+  const id = getStaticBagId(bagId)
+  const bag = await store.get(StorageBag, { where: { id }, relations })
+  if (!bag) {
+    console.log(`Creating new static bag: ${id}`)
+    const newBag = new StorageBag({
+      id,
+      owner: getStaticBagOwner(bagId),
+    })
+    await store.save<StorageBag>(newBag)
+    return newBag
+  }
+  return bag
+}
+
+export async function getBag(store: DatabaseManager, bagId: BagId, relations?: 'objects'[]): Promise<StorageBag> {
+  return bagId.isStatic
+    ? getStaticBag(store, bagId.asStatic, relations)
+    : getDynamicBag(store, bagId.asDynamic, relations)
+}
+
+export async function getDistributionBucketOperatorWithMetadata(
+  store: DatabaseManager,
+  id: string
+): Promise<DistributionBucketOperator> {
+  const operator = await store.get(DistributionBucketOperator, {
+    where: { id },
+    relations: ['metadata', 'metadata.nodeLocation', 'metadata.nodeLocation.coordinates'],
+  })
+  if (!operator) {
+    throw new Error(`DistributionBucketOperator not found by id: ${id}`)
+  }
+  return operator
+}
+
+export async function getStorageBucketWithOperatorMetadata(store: DatabaseManager, id: string): Promise<StorageBucket> {
+  const bucket = await store.get(StorageBucket, {
+    where: { id },
+    relations: ['operatorMetadata', 'operatorMetadata.nodeLocation', 'operatorMetadata.nodeLocation.coordinates'],
+  })
+  if (!bucket) {
+    throw new Error(`StorageBucket not found by id: ${id}`)
+  }
+  return bucket
+}
+
+export async function getDistributionBucketFamilyWithMetadata(
+  store: DatabaseManager,
+  id: string
+): Promise<DistributionBucketFamily> {
+  const family = await store.get(DistributionBucketFamily, {
+    where: { id },
+    relations: ['metadata', 'metadata.areas'],
+  })
+  if (!family) {
+    throw new Error(`DistributionBucketFamily not found by id: ${id}`)
+  }
+  return family
+}
+
+export async function getStorageSystem(store: DatabaseManager): Promise<StorageSystemParameters> {
+  const storageSystem = await store.get(StorageSystemParameters, {})
+  if (!storageSystem) {
+    throw new Error('Storage system entity is missing!')
+  }
+
+  return storageSystem
+}
+
+export async function createDataObjects(
+  store: DatabaseManager,
+  uploadParams: UploadParameters,
+  deletionPrize: Balance,
+  objectIds?: BN[]
+): Promise<StorageDataObject[]> {
+  const storageSystem = await getStorageSystem(store)
+  const { objectCreationList, bagId } = uploadParams
+  const storageBag = await getBag(store, bagId)
+
+  const dataObjects = objectCreationList.map((objectParams, i) => {
+    const params = new ObjectCreationParams(registry, objectParams.toJSON() as any)
+    const objectId = objectIds ? objectIds[i] : storageSystem.nextDataObjectId
+    const object = new StorageDataObject({
+      id: objectId.toString(),
+      isAccepted: false,
+      ipfsHash: bytesToString(objectParams.ipfsContentId),
+      size: new BN(params.getField('size').toString()),
+      type: new DataObjectTypeUnknown(),
+      deletionPrize,
+      storageBag,
+    })
+    if (objectId.gte(storageSystem.nextDataObjectId)) {
+      storageSystem.nextDataObjectId = objectId.addn(1)
+    }
+    return object
+  })
+
+  await Promise.all(dataObjects.map((o) => store.save<StorageDataObject>(o)))
+  await store.save<StorageSystemParameters>(storageSystem)
+
+  return dataObjects
+}
+
+export async function getMostRecentlyCreatedDataObjects(
+  store: DatabaseManager,
+  numberOfObjects: number
+): Promise<StorageDataObject[]> {
+  const storageSystem = await getStorageSystem(store)
+  const objectIds = Array.from({ length: numberOfObjects }, (v, k) =>
+    storageSystem.nextDataObjectId.subn(k + 1).toString()
+  )
+  const objects = await store.getMany(StorageDataObject, { where: { id: In(objectIds) } })
+  if (objects.length < numberOfObjects) {
+    inconsistentState(`Could not get ${numberOfObjects} most recently created data objects`, {
+      expected: numberOfObjects,
+      got: objects.length,
+    })
+  }
+  return objects.sort((a, b) => new BN(a.id).cmp(new BN(b.id)))
+}
+
+export async function removeDataObject(store: DatabaseManager, object: StorageDataObject): Promise<void> {
+  await unsetAssetRelations(store, object)
+  await store.remove<StorageDataObject>(object)
+}

+ 0 - 1
query-node/mappings/sumer/bootstrap/data/workers.json

@@ -1 +0,0 @@
-{}

+ 0 - 69
query-node/mappings/sumer/bootstrap/index.ts

@@ -1,69 +0,0 @@
-import { createDBConnection } from '@dzlzv/hydra-processor/lib/db'
-import { DatabaseManager, makeDatabaseManager } from '@dzlzv/hydra-db-utils'
-import { Connection, getManager, FindConditions } from 'typeorm'
-
-import { bootMembers, IBootstrapMember } from './members'
-import { bootWorkers, IBootstrapWorker, IBootstrapWorkers } from './workers'
-import { Worker, WorkerType } from 'query-node'
-
-import fs from 'fs'
-import path from 'path'
-
-// run bootstrap
-init()
-
-// bootstrap flow
-async function init() {
-  // prepare database and import data
-  const [databaseManager, connection] = await createDatabaseManager()
-
-  // escape if db is already initialized
-  if (await isDbInitialized(databaseManager)) {
-    await connection.close()
-    return
-  }
-
-  // load import data
-  const data = loadData()
-
-  // bootstrap entities
-  await bootMembers(databaseManager, data.members)
-  await bootWorkers(databaseManager, data.workers)
-
-  await connection.close()
-}
-
-async function isDbInitialized(db: DatabaseManager): Promise<boolean> {
-  // simple way to check if db is bootstrapped already - check if there is at least 1 storage provider
-  const membership = await db.get(Worker, {
-    where: {
-      type: WorkerType.STORAGE,
-    } as FindConditions<Worker>,
-  })
-
-  return !!membership
-}
-
-async function createDatabaseManager(): Promise<[DatabaseManager, Connection]> {
-  // paths in `entities` should be the same as `entities` set in `manifest.yml`
-  const entities = ['generated/graphql-server/dist/**/*.model.js']
-
-  // connect to db and create manager
-  const connection = await createDBConnection(entities)
-  const entityManager = getManager(connection.name)
-  const databaseManager = makeDatabaseManager(entityManager)
-
-  return [databaseManager, connection]
-}
-
-interface IBootstrapData {
-  members: IBootstrapMember[]
-  workers: IBootstrapWorkers
-}
-
-function loadData(): IBootstrapData {
-  return {
-    members: JSON.parse(fs.readFileSync(process.env.BOOTSTRAP_DATA_FOLDER + '/members.json').toString()),
-    workers: JSON.parse(fs.readFileSync(process.env.BOOTSTRAP_DATA_FOLDER + '/workers.json').toString()),
-  }
-}

+ 0 - 42
query-node/mappings/sumer/bootstrap/members.ts

@@ -1,42 +0,0 @@
-// import { Connection } from 'typeorm'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { logger } from '../src/common'
-import { MembershipEntryMethod, Membership } from 'query-node'
-
-export interface IBootstrapMember {
-  member_id: number
-  root_account: string
-  controller_account: string
-  handle: string
-  avatar_uri: string
-  about: string
-  registered_at_time: number
-}
-
-// export async function bootMembers(members: IBootstrapMember[], db: Connection): Promise<void> {
-export async function bootMembers(db: DatabaseManager, members: IBootstrapMember[]): Promise<void> {
-  for (const rawMember of members) {
-    // create new membership
-    const member = new Membership({
-      // main data
-      id: rawMember.member_id.toString(),
-      rootAccount: rawMember.root_account,
-      controllerAccount: rawMember.controller_account,
-      handle: rawMember.handle,
-      about: rawMember.about,
-      avatarUri: rawMember.avatar_uri,
-      createdInBlock: 0,
-      entry: MembershipEntryMethod.GENESIS,
-
-      // fill in auto-generated fields
-      createdAt: new Date(rawMember.registered_at_time),
-      updatedAt: new Date(rawMember.registered_at_time),
-    })
-
-    // save membership
-    await db.save<Membership>(member)
-
-    // emit log event
-    logger.info('Member has been bootstrapped', { id: rawMember.member_id })
-  }
-}

+ 0 - 48
query-node/mappings/sumer/bootstrap/workers.ts

@@ -1,48 +0,0 @@
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { Worker, WorkerType } from 'query-node'
-import { logger, getNextId } from '../src/common'
-
-export interface IBootstrapWorkers {
-  storage: IBootstrapWorker[]
-  gateway: IBootstrapWorker[]
-}
-
-export interface IBootstrapWorker {
-  id: string
-  created_at: string
-}
-
-export async function bootWorkers(db: DatabaseManager, workers: IBootstrapWorkers): Promise<void> {
-  await bootWorkersInGroup(db, workers.storage, WorkerType.STORAGE)
-  await bootWorkersInGroup(db, workers.gateway, WorkerType.GATEWAY)
-}
-
-export async function bootWorkersInGroup(
-  db: DatabaseManager,
-  workers: IBootstrapWorker[],
-  workerType: WorkerType
-): Promise<void> {
-  if (!workers) {
-    return
-  }
-
-  for (const rawWorker of workers) {
-    // create new membership
-    const worker = new Worker({
-      // main data
-      id: await getNextId(db),
-      workerId: rawWorker.id,
-      type: workerType,
-      isActive: true,
-
-      createdAt: new Date(rawWorker.created_at),
-      updatedAt: new Date(rawWorker.created_at),
-    })
-
-    // save worker
-    await db.save<Worker>(worker)
-
-    // emit log event
-    logger.info('Worker has been bootstrapped', { id: rawWorker.id, workerType })
-  }
-}

+ 0 - 279
query-node/mappings/sumer/content/channel.ts

@@ -1,279 +0,0 @@
-import { fixBlockTimestamp } from '../eventFix'
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import ISO6391 from 'iso-639-1'
-import { FindConditions, In } from 'typeorm'
-
-import { AccountId } from '@polkadot/types/interfaces'
-import { Option } from '@polkadot/types/codec'
-import { Content } from '../../../generated/types'
-import {
-  readProtobuf,
-  readProtobufWithAssets,
-  convertContentActorToChannelOwner,
-  convertContentActorToDataObjectOwner,
-} from './utils'
-
-import { Channel, ChannelCategory, DataObject, AssetAvailability } from 'query-node'
-import { inconsistentState, logger } from '../common'
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelCreated(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { channelId, channelCreationParameters, contentActor } = new Content.ChannelCreatedEvent(event).data
-
-  // read metadata
-  const protobufContent = await readProtobufWithAssets(new Channel(), {
-    metadata: channelCreationParameters.meta,
-    db,
-    event,
-    assets: channelCreationParameters.assets,
-    contentOwner: convertContentActorToDataObjectOwner(contentActor, channelId.toNumber()),
-  })
-
-  // create entity
-  const channel = new Channel({
-    // main data
-    id: channelId.toString(),
-    isCensored: false,
-    videos: [],
-    createdInBlock: event.blockNumber,
-
-    // default values for properties that might or might not be filled by metadata
-    coverPhotoUrls: [],
-    coverPhotoAvailability: AssetAvailability.INVALID,
-    avatarPhotoUrls: [],
-    avatarPhotoAvailability: AssetAvailability.INVALID,
-
-    // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    // prepare channel owner (handles fields `ownerMember` and `ownerCuratorGroup`)
-    ...(await convertContentActorToChannelOwner(db, contentActor)),
-
-    // integrate metadata
-    ...protobufContent,
-  })
-
-  // save entity
-  await db.save<Channel>(channel)
-
-  // emit log event
-  logger.info('Channel has been created', { id: channel.id })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelId, channelUpdateParameters, contentActor } = new Content.ChannelUpdatedEvent(event).data
-
-  // load channel
-  const channel = await db.get(Channel, { where: { id: channelId.toString() } as FindConditions<Channel> })
-
-  // ensure channel exists
-  if (!channel) {
-    return inconsistentState('Non-existing channel update requested', channelId)
-  }
-
-  // prepare changed metadata
-  const newMetadata = channelUpdateParameters.new_meta.unwrapOr(null)
-
-  //  update metadata if it was changed
-  if (newMetadata) {
-    const protobufContent = await readProtobufWithAssets(new Channel(), {
-      metadata: newMetadata,
-      db,
-      event,
-      assets: channelUpdateParameters.assets.unwrapOr([]),
-      contentOwner: convertContentActorToDataObjectOwner(contentActor, channelId.toNumber()),
-    })
-
-    // update all fields read from protobuf
-    for (const [key, value] of Object.entries(protobufContent)) {
-      channel[key] = value
-    }
-  }
-
-  // prepare changed reward account
-  const newRewardAccount = channelUpdateParameters.reward_account.unwrapOr(null)
-
-  // reward account change happened?
-  if (newRewardAccount) {
-    // this will change the `channel`!
-    handleChannelRewardAccountChange(channel, newRewardAccount)
-  }
-
-  // set last update time
-  channel.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save channel
-  await db.save<Channel>(channel)
-
-  // emit log event
-  logger.info('Channel has been updated', { id: channel.id })
-}
-
-export async function content_ChannelAssetsRemoved(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { contentId: contentIds } = new Content.ChannelAssetsRemovedEvent(event).data
-
-  // load channel
-  const assets = await db.getMany(DataObject, {
-    where: {
-      id: In(contentIds.toArray().map((item) => item.toString())),
-    } as FindConditions<DataObject>,
-  })
-
-  // delete assets
-  for (const asset of assets) {
-    await db.remove<DataObject>(asset)
-  }
-
-  // emit log event
-  logger.info('Channel assets have been removed', { ids: contentIds })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelCensorshipStatusUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelId, isCensored } = new Content.ChannelCensorshipStatusUpdatedEvent(event).data
-
-  // load event
-  const channel = await db.get(Channel, { where: { id: channelId.toString() } as FindConditions<Channel> })
-
-  // ensure channel exists
-  if (!channel) {
-    return inconsistentState('Non-existing channel censoring requested', channelId)
-  }
-
-  // update channel
-  channel.isCensored = isCensored.isTrue
-
-  // set last update time
-  channel.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save channel
-  await db.save<Channel>(channel)
-
-  // emit log event
-  logger.info('Channel censorship status has been updated', { id: channelId, isCensored: isCensored.isTrue })
-}
-
-/// ///////////////// ChannelCategory ////////////////////////////////////////////
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelCategoryCreated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelCategoryCreationParameters, channelCategoryId } = new Content.ChannelCategoryCreatedEvent(event).data
-
-  // read metadata
-  const protobufContent = await readProtobuf(new ChannelCategory(), {
-    metadata: channelCategoryCreationParameters.meta,
-    db,
-    event,
-  })
-
-  // create new channel category
-  const channelCategory = new ChannelCategory({
-    // main data
-    id: channelCategoryId.toString(),
-    channels: [],
-    createdInBlock: event.blockNumber,
-
-    // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    // integrate metadata
-    ...protobufContent,
-  })
-
-  // save channel
-  await db.save<ChannelCategory>(channelCategory)
-
-  // emit log event
-  logger.info('Channel category has been created', { id: channelCategory.id })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelCategoryUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelCategoryId, channelCategoryUpdateParameters } = new Content.ChannelCategoryUpdatedEvent(event).data
-
-  // load channel category
-  const channelCategory = await db.get(ChannelCategory, {
-    where: {
-      id: channelCategoryId.toString(),
-    } as FindConditions<ChannelCategory>,
-  })
-
-  // ensure channel exists
-  if (!channelCategory) {
-    return inconsistentState('Non-existing channel category update requested', channelCategoryId)
-  }
-
-  // read metadata
-  const protobufContent = await readProtobuf(new ChannelCategory(), {
-    metadata: channelCategoryUpdateParameters.new_meta,
-    db,
-    event,
-  })
-
-  // update all fields read from protobuf
-  for (const [key, value] of Object.entries(protobufContent)) {
-    channelCategory[key] = value
-  }
-
-  // set last update time
-  channelCategory.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save channel category
-  await db.save<ChannelCategory>(channelCategory)
-
-  // emit log event
-  logger.info('Channel category has been updated', { id: channelCategory.id })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_ChannelCategoryDeleted(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelCategoryId } = new Content.ChannelCategoryDeletedEvent(event).data
-
-  // load channel category
-  const channelCategory = await db.get(ChannelCategory, {
-    where: {
-      id: channelCategoryId.toString(),
-    } as FindConditions<ChannelCategory>,
-  })
-
-  // ensure channel category exists
-  if (!channelCategory) {
-    return inconsistentState('Non-existing channel category deletion requested', channelCategoryId)
-  }
-
-  // delete channel category
-  await db.remove<ChannelCategory>(channelCategory)
-
-  // emit log event
-  logger.info('Channel category has been deleted', { id: channelCategory.id })
-}
-
-/// ///////////////// Helpers ////////////////////////////////////////////////////
-
-function handleChannelRewardAccountChange(
-  channel: Channel, // will be modified inside of the function!
-  reward_account: Option<AccountId>
-) {
-  const rewardAccount = reward_account.unwrapOr(null)
-
-  // new different reward account set?
-  if (rewardAccount) {
-    channel.rewardAccount = rewardAccount.toString()
-    return
-  }
-
-  // reward account removed
-
-  channel.rewardAccount = undefined // plan deletion (will have effect when saved to db)
-}

+ 0 - 773
query-node/mappings/sumer/content/utils.ts

@@ -1,773 +0,0 @@
-// TODO: finish db cascade on save/remove; right now there is manually added `cascade: ["insert", "update"]` directive
-//       to all relations in `query-node/generated/graphql-server/src/modules/**/*.model.ts`. That should ensure all records
-//       are saved on one `db.save(...)` call. Missing features
-//       - find a proper way to cascade on remove or implement custom removals for every entity
-//       - convert manual changes done to `*model.ts` file into some patch or bash commands that can be executed
-//         every time query node codegen is run (that will overwrite said manual changes)
-//       - verify in integration tests that the records are trully created/updated/removed as expected
-
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { Bytes } from '@polkadot/types'
-import ISO6391 from 'iso-639-1'
-import { u64 } from '@polkadot/types/primitive'
-import { FindConditions } from 'typeorm'
-import * as jspb from 'google-protobuf'
-import { fixBlockTimestamp } from '../eventFix'
-
-// protobuf definitions
-import {
-  ChannelMetadata,
-  ChannelCategoryMetadata,
-  PublishedBeforeJoystream as PublishedBeforeJoystreamMetadata,
-  License as LicenseMetadata,
-  MediaType as MediaTypeMetadata,
-  VideoMetadata,
-  VideoCategoryMetadata,
-} from '@joystream/content-metadata-protobuf'
-
-import { Content } from '../../../generated/types'
-
-import { invalidMetadata, inconsistentState, logger, prepareDataObject, getNextId } from '../common'
-
-import {
-  // primary entities
-  CuratorGroup,
-  Channel,
-  ChannelCategory,
-  Video,
-  VideoCategory,
-
-  // secondary entities
-  Language,
-  License,
-  VideoMediaEncoding,
-  VideoMediaMetadata,
-
-  // asset
-  DataObjectOwner,
-  DataObjectOwnerMember,
-  DataObjectOwnerChannel,
-  DataObject,
-  LiaisonJudgement,
-  AssetAvailability,
-  Membership,
-} from 'query-node'
-
-// Joystream types
-import { ChannelId, ContentParameters, NewAsset, ContentActor } from '@joystream/types/augment'
-
-import { ContentParameters as Custom_ContentParameters } from '@joystream/types/storage'
-import { registry } from '@joystream/types'
-
-/*
-  Asset either stored in storage or describing list of URLs.
-*/
-type AssetStorageOrUrls = DataObject | string[]
-
-/*
-  Type guard differentiating asset stored in storage from asset describing a list of URLs.
-*/
-function isAssetInStorage(dataObject: AssetStorageOrUrls): dataObject is DataObject {
-  if (Array.isArray(dataObject)) {
-    return false
-  }
-
-  return true
-}
-
-export interface IReadProtobufArguments {
-  metadata: Bytes
-  db: DatabaseManager
-  event: SubstrateEvent
-}
-
-export interface IReadProtobufArgumentsWithAssets extends IReadProtobufArguments {
-  assets: NewAsset[] // assets provided in event
-  contentOwner: typeof DataObjectOwner
-}
-
-/*
-  This class represents one of 3 possible states when changing property read from metadata.
-  NoChange - don't change anything (used when invalid metadata are encountered)
-  Unset - unset the value (used when the unset is requested in runtime)
-  Change - set the new value
-*/
-export class PropertyChange<T> {
-  static newUnset<T>(): PropertyChange<T> {
-    return new PropertyChange<T>('unset')
-  }
-
-  static newNoChange<T>(): PropertyChange<T> {
-    return new PropertyChange<T>('nochange')
-  }
-
-  static newChange<T>(value: T): PropertyChange<T> {
-    return new PropertyChange<T>('change', value)
-  }
-
-  /*
-    Determines property change from the given object property.
-  */
-  static fromObjectProperty<T, Key extends string, ChangedObject extends { [key in Key]?: T }>(
-    object: ChangedObject,
-    key: Key
-  ): PropertyChange<T> {
-    if (!(key in object)) {
-      return PropertyChange.newNoChange<T>()
-    }
-
-    if (object[key] === undefined) {
-      return PropertyChange.newUnset<T>()
-    }
-
-    return PropertyChange.newChange<T>(object[key] as T)
-  }
-
-  private type: string
-  private value?: T
-
-  private constructor(type: 'change' | 'nochange' | 'unset', value?: T) {
-    this.type = type
-    this.value = value
-  }
-
-  public isUnset(): boolean {
-    return this.type === 'unset'
-  }
-
-  public isNoChange(): boolean {
-    return this.type === 'nochange'
-  }
-
-  public isValue(): boolean {
-    return this.type === 'change'
-  }
-
-  public getValue(): T | undefined {
-    return this.type === 'change' ? this.value : undefined
-  }
-
-  /*
-    Integrates the value into the given dictionary.
-  */
-  public integrateInto(object: Object, key: string): void {
-    if (this.isNoChange()) {
-      return
-    }
-
-    if (this.isUnset()) {
-      delete object[key]
-      return
-    }
-
-    object[key] = this.value
-  }
-}
-
-export interface RawVideoMetadata {
-  encoding: {
-    codecName: PropertyChange<string>
-    container: PropertyChange<string>
-    mimeMediaType: PropertyChange<string>
-  }
-  pixelWidth: PropertyChange<number>
-  pixelHeight: PropertyChange<number>
-  size: PropertyChange<number>
-}
-
-/*
-  Reads information from the event and protobuf metadata and constructs changeset that's fit to be used when saving to db.
-*/
-export async function readProtobuf<T extends ChannelCategory | VideoCategory>(
-  type: T,
-  parameters: IReadProtobufArguments
-): Promise<Partial<T>> {
-  // true option here is crucial, it indicates that we want just the underlying bytes (by default it will also include bytes encoding the length)
-  const metaU8a = parameters.metadata.toU8a(true)
-
-  // process channel category
-  if (type instanceof ChannelCategory) {
-    const meta = ChannelCategoryMetadata.deserializeBinary(metaU8a)
-    const result = convertMetadataToObject<ChannelCategoryMetadata.AsObject>(meta) as Partial<T>
-
-    return result
-  }
-
-  // process video category
-  if (type instanceof VideoCategory) {
-    const meta = VideoCategoryMetadata.deserializeBinary(metaU8a)
-    const result = convertMetadataToObject<VideoCategoryMetadata.AsObject>(meta) as Partial<T>
-
-    return result
-  }
-
-  // this should never happen
-  logger.error('Not implemented metadata type', { type })
-  throw new Error(`Not implemented metadata type`)
-}
-
-/*
-  Reads information from the event and protobuf metadata and constructs changeset that's fit to be used when saving to db.
-  In addition it handles any assets associated with the metadata.
-*/
-
-export async function readProtobufWithAssets<T extends Channel | Video>(
-  type: T,
-  parameters: IReadProtobufArgumentsWithAssets
-): Promise<Partial<T>> {
-  // true option here is crucial, it indicates that we want just the underlying bytes (by default it will also include bytes encoding the length)
-  const metaU8a = parameters.metadata.toU8a(true)
-
-  // process channel
-  if (type instanceof Channel) {
-    const meta = ChannelMetadata.deserializeBinary(metaU8a)
-    const metaAsObject = convertMetadataToObject<ChannelMetadata.AsObject>(meta)
-    const result = (metaAsObject as any) as Partial<Channel>
-
-    // prepare cover photo asset if needed
-    if ('coverPhoto' in metaAsObject) {
-      const asset = await extractAsset({
-        assetIndex: metaAsObject.coverPhoto,
-        assets: parameters.assets,
-        db: parameters.db,
-        event: parameters.event,
-        contentOwner: parameters.contentOwner,
-      })
-      integrateAsset('coverPhoto', result, asset) // changes `result` inline!
-      delete metaAsObject.coverPhoto
-    }
-
-    // prepare avatar photo asset if needed
-    if ('avatarPhoto' in metaAsObject) {
-      const asset = await extractAsset({
-        assetIndex: metaAsObject.avatarPhoto,
-        assets: parameters.assets,
-        db: parameters.db,
-        event: parameters.event,
-        contentOwner: parameters.contentOwner,
-      })
-      integrateAsset('avatarPhoto', result, asset) // changes `result` inline!
-      delete metaAsObject.avatarPhoto
-    }
-
-    // prepare language if needed
-    if ('language' in metaAsObject) {
-      const language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.event)
-      delete metaAsObject.language // make sure temporary value will not interfere
-      language.integrateInto(result, 'language')
-    }
-
-    return result as Partial<T>
-  }
-
-  // process video
-  if (type instanceof Video) {
-    const meta = VideoMetadata.deserializeBinary(metaU8a)
-    const metaAsObject = convertMetadataToObject<VideoMetadata.AsObject>(meta)
-    const result = (metaAsObject as any) as Partial<Video>
-
-    // prepare video category if needed
-    if ('category' in metaAsObject) {
-      const category = await prepareVideoCategory(metaAsObject.category, parameters.db)
-      delete metaAsObject.category // make sure temporary value will not interfere
-      category.integrateInto(result, 'category')
-    }
-
-    // prepare media meta information if needed
-    if ('mediaType' in metaAsObject || 'mediaPixelWidth' in metaAsObject || 'mediaPixelHeight' in metaAsObject) {
-      // prepare video file size if poosible
-      const videoSize = extractVideoSize(parameters.assets, metaAsObject.video)
-
-      // NOTE: type hack - `RawVideoMetadata` is inserted instead of VideoMediaMetadata - it should be edited in `video.ts`
-      //       see `integrateVideoMetadata()` in `video.ts` for more info
-      result.mediaMetadata = (prepareVideoMetadata(
-        metaAsObject,
-        videoSize,
-        parameters.event.blockNumber
-      ) as unknown) as VideoMediaMetadata
-
-      // remove extra values
-      delete metaAsObject.mediaType
-      delete metaAsObject.mediaPixelWidth
-      delete metaAsObject.mediaPixelHeight
-    }
-
-    // prepare license if needed
-    if ('license' in metaAsObject) {
-      result.license = await prepareLicense(parameters.db, metaAsObject.license, parameters.event)
-    }
-
-    // prepare thumbnail photo asset if needed
-    if ('thumbnailPhoto' in metaAsObject) {
-      const asset = await extractAsset({
-        assetIndex: metaAsObject.thumbnailPhoto,
-        assets: parameters.assets,
-        db: parameters.db,
-        event: parameters.event,
-        contentOwner: parameters.contentOwner,
-      })
-      integrateAsset('thumbnailPhoto', result, asset) // changes `result` inline!
-      delete metaAsObject.thumbnailPhoto
-    }
-
-    // prepare video asset if needed
-    if ('video' in metaAsObject) {
-      const asset = await extractAsset({
-        assetIndex: metaAsObject.video,
-        assets: parameters.assets,
-        db: parameters.db,
-        event: parameters.event,
-        contentOwner: parameters.contentOwner,
-      })
-      integrateAsset('media', result, asset) // changes `result` inline!
-      delete metaAsObject.video
-    }
-
-    // prepare language if needed
-    if ('language' in metaAsObject) {
-      const language = await prepareLanguage(metaAsObject.language, parameters.db, parameters.event)
-      delete metaAsObject.language // make sure temporary value will not interfere
-      language.integrateInto(result, 'language')
-    }
-
-    if (metaAsObject.publishedBeforeJoystream) {
-      const publishedBeforeJoystream = handlePublishedBeforeJoystream(result, metaAsObject.publishedBeforeJoystream)
-      delete metaAsObject.publishedBeforeJoystream // make sure temporary value will not interfere
-      publishedBeforeJoystream.integrateInto(result, 'publishedBeforeJoystream')
-    }
-
-    return result as Partial<T>
-  }
-
-  // this should never happen
-  logger.error('Not implemented metadata type', { type })
-  throw new Error(`Not implemented metadata type`)
-}
-
-export async function convertContentActorToChannelOwner(
-  db: DatabaseManager,
-  contentActor: ContentActor
-): Promise<{
-  ownerMember?: Membership
-  ownerCuratorGroup?: CuratorGroup
-}> {
-  if (contentActor.isMember) {
-    const memberId = contentActor.asMember.toNumber()
-    const member = await db.get(Membership, { where: { id: memberId.toString() } as FindConditions<Membership> })
-
-    // ensure member exists
-    if (!member) {
-      return inconsistentState(`Actor is non-existing member`, memberId)
-    }
-
-    return {
-      ownerMember: member,
-      ownerCuratorGroup: undefined, // this will clear the field
-    }
-  }
-
-  if (contentActor.isCurator) {
-    const curatorGroupId = contentActor.asCurator[0].toNumber()
-    const curatorGroup = await db.get(CuratorGroup, {
-      where: { id: curatorGroupId.toString() } as FindConditions<CuratorGroup>,
-    })
-
-    // ensure curator group exists
-    if (!curatorGroup) {
-      return inconsistentState('Actor is non-existing curator group', curatorGroupId)
-    }
-
-    return {
-      ownerMember: undefined, // this will clear the field
-      ownerCuratorGroup: curatorGroup,
-    }
-  }
-
-  // TODO: contentActor.isLead
-
-  logger.error('Not implemented ContentActor type', { contentActor: contentActor.toString() })
-  throw new Error('Not-implemented ContentActor type used')
-}
-
-export function convertContentActorToDataObjectOwner(
-  contentActor: ContentActor,
-  channelId: number
-): typeof DataObjectOwner {
-  const owner = new DataObjectOwnerChannel()
-  owner.channel = channelId
-
-  return owner
-
-  /* contentActor is irrelevant now -> all video/channel content belongs to the channel
-  if (contentActor.isMember) {
-    const owner = new DataObjectOwnerMember()
-    owner.member = contentActor.asMember.toBn()
-
-    return owner
-  }
-
-  if (contentActor.isLead || contentActor.isCurator) {
-    const owner = new DataObjectOwnerChannel()
-    owner.channel = channelId
-
-    return owner
-  }
-
-  logger.error('Not implemented ContentActor type', {contentActor: contentActor.toString()})
-  throw new Error('Not-implemented ContentActor type used')
-  */
-}
-
-function handlePublishedBeforeJoystream(
-  video: Partial<Video>,
-  metadata: PublishedBeforeJoystreamMetadata.AsObject
-): PropertyChange<Date> {
-  // is publish being unset
-  if ('isPublished' in metadata && !metadata.isPublished) {
-    return PropertyChange.newUnset()
-  }
-
-  // try to parse timestamp from publish date
-  const timestamp = metadata.date ? Date.parse(metadata.date) : NaN
-
-  // ensure date is valid
-  if (isNaN(timestamp)) {
-    invalidMetadata(`Invalid date used for publishedBeforeJoystream`, {
-      timestamp,
-    })
-    return PropertyChange.newNoChange()
-  }
-
-  // set new date
-  return PropertyChange.newChange(new Date(timestamp))
-}
-
-interface IConvertAssetParameters {
-  rawAsset: NewAsset
-  db: DatabaseManager
-  event: SubstrateEvent
-  contentOwner: typeof DataObjectOwner
-}
-
-/*
-  Converts event asset into data object or list of URLs fit to be saved to db.
-*/
-async function convertAsset(parameters: IConvertAssetParameters): Promise<AssetStorageOrUrls> {
-  // is asset describing list of URLs?
-  if (parameters.rawAsset.isUrls) {
-    const urls = parameters.rawAsset.asUrls.toArray().map((item) => item.toString())
-
-    return urls
-  }
-
-  // !parameters.rawAsset.isUrls && parameters.rawAsset.isUpload // asset is in storage
-
-  // prepare data object
-  const contentParameters: ContentParameters = parameters.rawAsset.asUpload
-  const dataObject = await prepareDataObject(
-    parameters.db,
-    contentParameters,
-    parameters.event,
-    parameters.contentOwner
-  )
-
-  return dataObject
-}
-
-interface IExtractAssetParameters {
-  assetIndex: number | undefined
-  assets: NewAsset[]
-  db: DatabaseManager
-  event: SubstrateEvent
-  contentOwner: typeof DataObjectOwner
-}
-
-/*
-  Selects asset from provided set of assets and prepares asset data fit to be saved to db.
-*/
-async function extractAsset(parameters: IExtractAssetParameters): Promise<PropertyChange<AssetStorageOrUrls>> {
-  // is asset being unset?
-  if (parameters.assetIndex === undefined) {
-    return PropertyChange.newUnset()
-  }
-
-  // ensure asset index is valid
-  if (parameters.assetIndex >= parameters.assets.length) {
-    invalidMetadata(`Non-existing asset extraction requested`, {
-      assetsProvided: parameters.assets.length,
-      assetIndex: parameters.assetIndex,
-    })
-    return PropertyChange.newNoChange()
-  }
-
-  // convert asset to data object record
-  const asset = await convertAsset({
-    rawAsset: parameters.assets[parameters.assetIndex],
-    db: parameters.db,
-    event: parameters.event,
-    contentOwner: parameters.contentOwner,
-  })
-
-  return PropertyChange.newChange(asset)
-}
-
-/*
-  As a temporary messure to overcome yet-to-be-implemented features in Hydra, we are using redudant information
-  to describe asset state. This function introduces all redudant data needed to be saved to db.
-
-  Changes `result` argument!
-*/
-function integrateAsset<T>(propertyName: string, result: Object, asset: PropertyChange<AssetStorageOrUrls>): void {
-  // helpers - property names
-  const nameUrl = propertyName + 'Urls'
-  const nameDataObject = propertyName + 'DataObject'
-  const nameAvailability = propertyName + 'Availability'
-
-  if (asset.isNoChange()) {
-    return
-  }
-
-  if (asset.isUnset()) {
-    result[nameUrl] = []
-    result[nameAvailability] = AssetAvailability.INVALID
-    result[nameDataObject] = undefined // plan deletion (will have effect when saved to db)
-
-    return
-  }
-
-  const newValue = asset.getValue() as AssetStorageOrUrls
-
-  // is asset available on external URL(s)
-  if (!isAssetInStorage(newValue)) {
-    // (un)set asset's properties
-    result[nameUrl] = newValue
-    result[nameAvailability] = AssetAvailability.ACCEPTED
-    result[nameDataObject] = undefined // plan deletion (will have effect when saved to db)
-
-    return
-  }
-
-  // asset saved in storage
-
-  // prepare conversion table between liaison judgment and asset availability
-  const conversionTable = {
-    [LiaisonJudgement.ACCEPTED]: AssetAvailability.ACCEPTED,
-    [LiaisonJudgement.PENDING]: AssetAvailability.PENDING,
-  }
-
-  // (un)set asset's properties
-  result[nameUrl] = [] // plan deletion (will have effect when saved to db)
-  result[nameAvailability] = conversionTable[newValue.liaisonJudgement]
-  result[nameDataObject] = newValue
-}
-
-function extractVideoSize(assets: NewAsset[], assetIndex: number | undefined): number | undefined {
-  // escape if no asset is required
-  if (assetIndex === undefined) {
-    return undefined
-  }
-
-  // ensure asset index is valid
-  if (assetIndex > assets.length) {
-    invalidMetadata(`Non-existing asset video size extraction requested`, { assetsProvided: assets.length, assetIndex })
-    return undefined
-  }
-
-  const rawAsset = assets[assetIndex]
-
-  // escape if asset is describing URLs (can't get size)
-  if (rawAsset.isUrls) {
-    return undefined
-  }
-
-  // !rawAsset.isUrls && rawAsset.isUpload // asset is in storage
-
-  // convert generic content parameters coming from processor to custom Joystream data type
-  const customContentParameters = new Custom_ContentParameters(registry, rawAsset.asUpload.toJSON() as any)
-  // extract video size
-  const videoSize = customContentParameters.size_in_bytes.toNumber()
-
-  return videoSize
-}
-
-async function prepareLanguage(
-  languageIso: string | undefined,
-  db: DatabaseManager,
-  event: SubstrateEvent
-): Promise<PropertyChange<Language>> {
-  // is language being unset?
-  if (languageIso === undefined) {
-    return PropertyChange.newUnset()
-  }
-
-  // validate language string
-  const isValidIso = ISO6391.validate(languageIso)
-
-  // ensure language string is valid
-  if (!isValidIso) {
-    invalidMetadata(`Invalid language ISO-639-1 provided`, languageIso)
-    return PropertyChange.newNoChange()
-  }
-
-  // load language
-  const language = await db.get(Language, { where: { iso: languageIso } as FindConditions<Language> })
-
-  // return existing language if any
-  if (language) {
-    return PropertyChange.newChange(language)
-  }
-
-  // create new language
-  const newLanguage = new Language({
-    // set id as iso to overcome current graphql filtering limitations (so we can use query `videos(where: {languageId_eq: 'en'})`)
-    // id: await getNextId(db),
-    id: languageIso,
-    iso: languageIso,
-    createdInBlock: event.blockNumber,
-
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    // TODO: remove these lines after Hydra auto-fills the values when cascading save (remove them on all places)
-    createdById: '1',
-    updatedById: '1',
-  })
-
-  await db.save<Language>(newLanguage)
-
-  return PropertyChange.newChange(newLanguage)
-}
-
-async function prepareLicense(
-  db: DatabaseManager,
-  licenseProtobuf: LicenseMetadata.AsObject | undefined,
-  event: SubstrateEvent
-): Promise<License | undefined> {
-  // NOTE: Deletion of any previous license should take place in appropriate event handling function
-  //       and not here even it might appear so.
-
-  // is license being unset?
-  if (licenseProtobuf === undefined) {
-    return undefined
-  }
-
-  // license is meant to be deleted
-  if (isLicenseEmpty(licenseProtobuf)) {
-    return new License({})
-  }
-
-  // crete new license
-  const license = new License({
-    ...licenseProtobuf,
-    id: await getNextId(db),
-
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    createdById: '1',
-    updatedById: '1',
-  })
-
-  return license
-}
-
-/*
-  Checks if protobof contains license with some fields filled or is empty object (`{}` or `{someKey: undefined, ...}`).
-  Empty object means deletion is requested.
-*/
-function isLicenseEmpty(licenseObject: LicenseMetadata.AsObject): boolean {
-  const somePropertySet = Object.entries(licenseObject).reduce((acc, [key, value]) => {
-    return acc || value !== undefined
-  }, false)
-
-  return !somePropertySet
-}
-
-function prepareVideoMetadata(
-  videoProtobuf: VideoMetadata.AsObject,
-  videoSize: number | undefined,
-  blockNumber: number
-): RawVideoMetadata {
-  const rawMeta = {
-    encoding: {
-      codecName: PropertyChange.fromObjectProperty<string, 'codecName', MediaTypeMetadata.AsObject>(
-        videoProtobuf.mediaType || {},
-        'codecName'
-      ),
-      container: PropertyChange.fromObjectProperty<string, 'container', MediaTypeMetadata.AsObject>(
-        videoProtobuf.mediaType || {},
-        'container'
-      ),
-      mimeMediaType: PropertyChange.fromObjectProperty<string, 'mimeMediaType', MediaTypeMetadata.AsObject>(
-        videoProtobuf.mediaType || {},
-        'mimeMediaType'
-      ),
-    },
-    pixelWidth: PropertyChange.fromObjectProperty<number, 'mediaPixelWidth', VideoMetadata.AsObject>(
-      videoProtobuf,
-      'mediaPixelWidth'
-    ),
-    pixelHeight: PropertyChange.fromObjectProperty<number, 'mediaPixelHeight', VideoMetadata.AsObject>(
-      videoProtobuf,
-      'mediaPixelHeight'
-    ),
-    size: videoSize === undefined ? PropertyChange.newNoChange() : PropertyChange.newChange(videoSize),
-  } as RawVideoMetadata
-
-  return rawMeta
-}
-
-async function prepareVideoCategory(
-  categoryId: number | undefined,
-  db: DatabaseManager
-): Promise<PropertyChange<VideoCategory>> {
-  // is category being unset?
-  if (categoryId === undefined) {
-    return PropertyChange.newUnset()
-  }
-
-  // load video category
-  const category = await db.get(VideoCategory, {
-    where: { id: categoryId.toString() } as FindConditions<VideoCategory>,
-  })
-
-  // ensure video category exists
-  if (!category) {
-    invalidMetadata('Non-existing video category association with video requested', categoryId)
-    return PropertyChange.newNoChange()
-  }
-
-  return PropertyChange.newChange(category)
-}
-
-function convertMetadataToObject<T extends Object>(metadata: jspb.Message): T {
-  const metaAsObject = metadata.toObject()
-  const result = {} as T
-
-  for (const key in metaAsObject) {
-    const funcNameBase = key.charAt(0).toUpperCase() + key.slice(1)
-    const hasFuncName = 'has' + funcNameBase
-    const isSet =
-      funcNameBase === 'PersonsList' // there is no `VideoMetadata.hasPersonsList` method from unkown reason -> create exception
-        ? true
-        : metadata[hasFuncName]()
-
-    if (!isSet) {
-      continue
-    }
-
-    const getFuncName = 'get' + funcNameBase
-    const value = metadata[getFuncName]()
-
-    // TODO: check that recursion trully works
-    if (value instanceof jspb.Message) {
-      result[key] = convertMetadataToObject(value)
-      continue
-    }
-
-    result[key] = metaAsObject[key]
-  }
-
-  return result
-}

+ 0 - 498
query-node/mappings/sumer/content/video.ts

@@ -1,498 +0,0 @@
-import BN from 'bn.js'
-import { fixBlockTimestamp } from '../eventFix'
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { FindConditions, In } from 'typeorm'
-
-import { Content } from '../../../generated/types'
-
-import { inconsistentState, logger, getNextId } from '../common'
-
-import { convertContentActorToDataObjectOwner, readProtobuf, readProtobufWithAssets, RawVideoMetadata } from './utils'
-
-import {
-  AssetAvailability,
-  Channel,
-  License,
-  Video,
-  VideoCategory,
-  VideoMediaEncoding,
-  VideoMediaMetadata,
-} from 'query-node'
-
-// Joystream types
-import { ChannelId } from '@joystream/types/augment'
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoCategoryCreated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoCategoryId, videoCategoryCreationParameters, contentActor } = new Content.VideoCategoryCreatedEvent(
-    event
-  ).data
-
-  // read metadata
-  const protobufContent = await readProtobuf(new VideoCategory(), {
-    metadata: videoCategoryCreationParameters.meta,
-    db,
-    event,
-  })
-
-  // create new video category
-  const videoCategory = new VideoCategory({
-    // main data
-    id: videoCategoryId.toString(),
-    videos: [],
-    createdInBlock: event.blockNumber,
-
-    // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    // integrate metadata
-    ...protobufContent,
-  })
-
-  // save video category
-  await db.save<VideoCategory>(videoCategory)
-
-  // emit log event
-  logger.info('Video category has been created', { id: videoCategoryId })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoCategoryUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoCategoryId, videoCategoryUpdateParameters, contentActor } = new Content.VideoCategoryUpdatedEvent(
-    event
-  ).data
-
-  // load video category
-  const videoCategory = await db.get(VideoCategory, {
-    where: { id: videoCategoryId.toString() } as FindConditions<VideoCategory>,
-  })
-
-  // ensure video category exists
-  if (!videoCategory) {
-    return inconsistentState('Non-existing video category update requested', videoCategoryId)
-  }
-
-  // read metadata
-  const protobufContent = await readProtobuf(new VideoCategory(), {
-    metadata: videoCategoryUpdateParameters.new_meta,
-    db,
-    event,
-  })
-
-  // update all fields read from protobuf
-  for (const [key, value] of Object.entries(protobufContent)) {
-    videoCategory[key] = value
-  }
-
-  // set last update time
-  videoCategory.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save video category
-  await db.save<VideoCategory>(videoCategory)
-
-  // emit log event
-  logger.info('Video category has been updated', { id: videoCategoryId })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoCategoryDeleted(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoCategoryId } = new Content.VideoCategoryDeletedEvent(event).data
-
-  // load video category
-  const videoCategory = await db.get(VideoCategory, {
-    where: { id: videoCategoryId.toString() } as FindConditions<VideoCategory>,
-  })
-
-  // ensure video category exists
-  if (!videoCategory) {
-    return inconsistentState('Non-existing video category deletion requested', videoCategoryId)
-  }
-
-  // remove video category
-  await db.remove<VideoCategory>(videoCategory)
-
-  // emit log event
-  logger.info('Video category has been deleted', { id: videoCategoryId })
-}
-
-/// ///////////////// Video //////////////////////////////////////////////////////
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoCreated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { channelId, videoId, videoCreationParameters, contentActor } = new Content.VideoCreatedEvent(event).data
-
-  // read metadata
-  const protobufContent = await readProtobufWithAssets(new Video(), {
-    metadata: videoCreationParameters.meta,
-    db,
-    event,
-    assets: videoCreationParameters.assets,
-    contentOwner: convertContentActorToDataObjectOwner(contentActor, channelId.toNumber()),
-  })
-
-  // load channel
-  const channel = await db.get(Channel, { where: { id: channelId.toString() } as FindConditions<Channel> })
-
-  // ensure channel exists
-  if (!channel) {
-    return inconsistentState('Trying to add video to non-existing channel', channelId)
-  }
-
-  // prepare video media metadata (if any)
-  const fixedProtobuf = await integrateVideoMediaMetadata(db, null, protobufContent, event)
-
-  const licenseIsEmpty = fixedProtobuf.license && !Object.keys(fixedProtobuf.license).length
-  if (licenseIsEmpty) {
-    // license deletion was requested - ignore it and consider it empty
-    delete fixedProtobuf.license
-  }
-
-  // create new video
-  const video = new Video({
-    // main data
-    id: videoId.toString(),
-    isCensored: false,
-    channel,
-    createdInBlock: event.blockNumber,
-    isFeatured: false,
-
-    // default values for properties that might or might not be filled by metadata
-    thumbnailPhotoUrls: [],
-    thumbnailPhotoAvailability: AssetAvailability.INVALID,
-    mediaUrls: [],
-    mediaAvailability: AssetAvailability.INVALID,
-
-    // fill in auto-generated fields
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-
-    // integrate metadata
-    ...fixedProtobuf,
-  })
-
-  // save video
-  await db.save<Video>(video)
-
-  // emit log event
-  logger.info('Video has been created', { id: videoId })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoId, videoUpdateParameters, contentActor } = new Content.VideoUpdatedEvent(event).data
-
-  // load video
-  const video = await db.get(Video, {
-    where: { id: videoId.toString() } as FindConditions<Video>,
-    relations: ['channel', 'license'],
-  })
-
-  // ensure video exists
-  if (!video) {
-    return inconsistentState('Non-existing video update requested', videoId)
-  }
-
-  // prepare changed metadata
-  const newMetadata = videoUpdateParameters.new_meta.unwrapOr(null)
-
-  // license must be deleted AFTER video is saved - plan a license deletion by assigning it to this variable
-  let licenseToDelete: License | null = null
-
-  // update metadata if it was changed
-  if (newMetadata) {
-    const protobufContent = await readProtobufWithAssets(new Video(), {
-      metadata: newMetadata,
-      db,
-      event,
-      assets: videoUpdateParameters.assets.unwrapOr([]),
-      contentOwner: convertContentActorToDataObjectOwner(contentActor, new BN(video.channel.id).toNumber()),
-    })
-
-    // prepare video media metadata (if any)
-    const fixedProtobuf = await integrateVideoMediaMetadata(db, video, protobufContent, event)
-
-    // remember original license
-    const originalLicense = video.license
-
-    // update all fields read from protobuf
-    for (const [key, value] of Object.entries(fixedProtobuf)) {
-      video[key] = value
-    }
-
-    // license has changed - plan old license delete
-    if (originalLicense && video.license !== originalLicense) {
-      ;[video.license, licenseToDelete] = handleLicenseUpdate(originalLicense, video.license)
-    } else if (!Object.keys(video.license || {}).length) {
-      // license deletion was requested event no license exists?
-      delete video.license // ensure license is empty
-    }
-  }
-
-  // set last update time
-  video.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save video
-  await db.save<Video>(video)
-
-  // delete old license if it's planned
-  if (licenseToDelete) {
-    await db.remove<License>(licenseToDelete)
-  }
-
-  // emit log event
-  logger.info('Video has been updated', { id: videoId })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoDeleted(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoId } = new Content.VideoDeletedEvent(event).data
-
-  // load video
-  const video = await db.get(Video, { where: { id: videoId.toString() } as FindConditions<Video> })
-
-  // ensure video exists
-  if (!video) {
-    return inconsistentState('Non-existing video deletion requested', videoId)
-  }
-
-  // remove video
-  await db.remove<Video>(video)
-
-  // emit log event
-  logger.info('Video has been deleted', { id: videoId })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_VideoCensorshipStatusUpdated(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoId, isCensored } = new Content.VideoCensorshipStatusUpdatedEvent(event).data
-
-  // load video
-  const video = await db.get(Video, { where: { id: videoId.toString() } as FindConditions<Video> })
-
-  // ensure video exists
-  if (!video) {
-    return inconsistentState('Non-existing video censoring requested', videoId)
-  }
-
-  // update video
-  video.isCensored = isCensored.isTrue
-
-  // set last update time
-  video.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save video
-  await db.save<Video>(video)
-
-  // emit log event
-  logger.info('Video censorship status has been updated', { id: videoId, isCensored: isCensored.isTrue })
-}
-
-// eslint-disable-next-line @typescript-eslint/naming-convention
-export async function content_FeaturedVideosSet(db: DatabaseManager, event: SubstrateEvent) {
-  // read event data
-  const { videoId: videoIds } = new Content.FeaturedVideosSetEvent(event).data
-
-  // load old featured videos
-  const existingFeaturedVideos = await db.getMany(Video, { where: { isFeatured: true } as FindConditions<Video> })
-
-  // comparsion utility
-  const isSame = (videoIdA: string) => (videoIdB: string) => videoIdA === videoIdB
-
-  // calculate diff sets
-  const toRemove = existingFeaturedVideos.filter(
-    (existingFV) => !videoIds.map((item) => item.toString()).some(isSame(existingFV.id))
-  )
-  const toAdd = videoIds.filter(
-    (video) => !existingFeaturedVideos.map((item) => item.id).some(isSame(video.toString()))
-  )
-
-  // escape if no featured video needs to be added or removed
-  if (!toRemove.length && !toAdd.length) {
-    // emit log event
-    logger.info('Featured videos unchanged')
-
-    return
-  }
-
-  // mark previously featured videos as not-featured
-  await Promise.all(
-    toRemove.map(async (video) => {
-      video.isFeatured = false
-
-      // set last update time
-      video.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-      await db.save<Video>(video)
-    })
-  )
-
-  // escape if no featured video needs to be added
-  if (!toAdd.length) {
-    // emit log event
-    logger.info('Some featured videos have been unset.', { videoIds: toRemove.map((item) => item.id.toString()) })
-
-    return
-  }
-
-  // read videos previously not-featured videos that are meant to be featured
-  const videosToAdd = await db.getMany(Video, {
-    where: {
-      id: In(toAdd.map((item) => item.toString())),
-    } as FindConditions<Video>,
-  })
-
-  if (videosToAdd.length !== toAdd.length) {
-    return inconsistentState('At least one non-existing video featuring requested', toAdd)
-  }
-
-  // mark previously not-featured videos as featured
-  await Promise.all(
-    videosToAdd.map(async (video) => {
-      video.isFeatured = true
-
-      // set last update time
-      video.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-      await db.save<Video>(video)
-    })
-  )
-
-  // emit log event
-  logger.info('New featured videos have been set', { videoIds })
-}
-
-/// ///////////////// Helpers ////////////////////////////////////////////////////
-
-/*
-  Integrates video metadata-related data into existing data (if any) or creates a new record.
-
-  NOTE: type hack - `RawVideoMetadata` is accepted for `metadata` instead of `Partial<Video>`
-        see `prepareVideoMetadata()` in `utils.ts` for more info
-*/
-async function integrateVideoMediaMetadata(
-  db: DatabaseManager,
-  existingRecord: Video | null,
-  metadata: Partial<Video>,
-  event: SubstrateEvent
-): Promise<Partial<Video>> {
-  if (!metadata.mediaMetadata) {
-    return metadata
-  }
-
-  const now = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // fix TS type
-  const rawMediaMetadata = (metadata.mediaMetadata as unknown) as RawVideoMetadata
-
-  // ensure encoding object
-  const encoding =
-    (existingRecord && existingRecord.mediaMetadata && existingRecord.mediaMetadata.encoding) ||
-    new VideoMediaEncoding({
-      createdAt: now,
-      updatedAt: now,
-
-      createdById: '1',
-      updatedById: '1',
-    })
-
-  // integrate media encoding-related data
-  rawMediaMetadata.encoding.codecName.integrateInto(encoding, 'codecName')
-  rawMediaMetadata.encoding.container.integrateInto(encoding, 'container')
-  rawMediaMetadata.encoding.mimeMediaType.integrateInto(encoding, 'mimeMediaType')
-
-  // ensure media metadata object
-  const mediaMetadata =
-    (existingRecord && existingRecord.mediaMetadata) ||
-    new VideoMediaMetadata({
-      createdInBlock: event.blockNumber,
-
-      createdAt: now,
-      updatedAt: now,
-
-      createdById: '1',
-      updatedById: '1',
-    })
-
-  // integrate media-related data
-  rawMediaMetadata.pixelWidth.integrateInto(mediaMetadata, 'pixelWidth')
-  rawMediaMetadata.pixelHeight.integrateInto(mediaMetadata, 'pixelHeight')
-  rawMediaMetadata.size.integrateInto(mediaMetadata, 'size')
-
-  // connect encoding to media metadata object
-  mediaMetadata.encoding = encoding
-
-  // ensure predictable ids
-  if (!mediaMetadata.encoding.id) {
-    mediaMetadata.encoding.id = await getNextId(db)
-  }
-  if (!mediaMetadata.id) {
-    mediaMetadata.id = await getNextId(db)
-  }
-
-  /// ///////////////// update updatedAt if needed ///////////////////////////////
-
-  const encodingNoChange =
-    true &&
-    rawMediaMetadata.encoding.codecName.isNoChange() &&
-    rawMediaMetadata.encoding.container.isNoChange() &&
-    rawMediaMetadata.encoding.mimeMediaType.isNoChange()
-  const mediaMetadataNoChange =
-    encodingNoChange &&
-    rawMediaMetadata.encoding.codecName.isNoChange() &&
-    rawMediaMetadata.encoding.container.isNoChange() &&
-    rawMediaMetadata.encoding.mimeMediaType.isNoChange()
-
-  if (!encodingNoChange) {
-    // encoding changed?
-    mediaMetadata.encoding.updatedAt = now
-  }
-  if (!mediaMetadataNoChange) {
-    // metadata changed?
-    mediaMetadata.updatedAt = now
-  }
-
-  /// ////////////////////////////////////////////////////////////////////////////
-
-  return {
-    ...metadata,
-    mediaMetadata,
-  }
-}
-
-// returns tuple `[newLicenseForVideo, oldLicenseToBeDeleted]`
-function handleLicenseUpdate(originalLicense, newLicense): [License | undefined, License | null] {
-  const isNewEmpty = !Object.keys(newLicense).length
-
-  if (!originalLicense && isNewEmpty) {
-    return [undefined, null]
-  }
-
-  if (!originalLicense) {
-    // && !isNewEmpty
-    return [newLicense, null]
-  }
-
-  if (!isNewEmpty) {
-    // && originalLicense
-    return [
-      new License({
-        ...originalLicense,
-        ...newLicense,
-      }),
-      null,
-    ]
-  }
-
-  // originalLicense && isNewEmpty
-
-  return [originalLicense, null]
-}

+ 0 - 6
query-node/mappings/sumer/eventFix.ts

@@ -1,6 +0,0 @@
-import BN from 'bn.js'
-
-// Workaround for https://github.com/Joystream/hydra/issues/326 . This file can be removed after it's fixed
-export function fixBlockTimestamp(blockTimestamp: unknown): BN {
-  return new BN(blockTimestamp as string)
-}

+ 0 - 280
query-node/mappings/sumer/storage.ts

@@ -1,280 +0,0 @@
-import { fixBlockTimestamp } from './eventFix'
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { FindConditions, In } from 'typeorm'
-
-import { inconsistentState, logger, prepareDataObject } from './common'
-
-import { DataDirectory } from '../../generated/types'
-import { ContentId, ContentParameters, StorageObjectOwner } from '@joystream/types/augment'
-
-import { ContentId as Custom_ContentId, ContentParameters as Custom_ContentParameters } from '@joystream/types/storage'
-import { registry } from '@joystream/types'
-
-import {
-  Channel,
-  Video,
-  AssetAvailability,
-  DataObject,
-  DataObjectOwner,
-  DataObjectOwnerMember,
-  DataObjectOwnerChannel,
-  DataObjectOwnerDao,
-  DataObjectOwnerCouncil,
-  DataObjectOwnerWorkingGroup,
-  LiaisonJudgement,
-  Worker,
-  WorkerType,
-} from 'query-node'
-
-export async function dataDirectory_ContentAdded(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { contentParameters, storageObjectOwner } = new DataDirectory.ContentAddedEvent(event).data
-
-  // save all content objects
-  for (const parameters of contentParameters) {
-    const owner = convertStorageObjectOwner(storageObjectOwner)
-    const dataObject = await prepareDataObject(db, parameters, event, owner)
-
-    // fill in auto-generated fields
-    dataObject.createdAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-    dataObject.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-    await db.save<DataObject>(dataObject)
-  }
-
-  // emit log event
-  logger.info('Storage content has beed added', {
-    ids: contentParameters.map((item) => encodeContentId(item.content_id)),
-  })
-}
-
-export async function dataDirectory_ContentRemoved(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { contentId: contentIds } = new DataDirectory.ContentRemovedEvent(event).data
-
-  // load assets
-  const dataObjects = await db.getMany(DataObject, {
-    where: {
-      joystreamContentId: In(contentIds.map((item) => encodeContentId(item))),
-    } as FindConditions<DataObject>,
-  })
-
-  // store dataObject ids before they are deleted (for logging purposes)
-  const dataObjectIds = dataObjects.map((item) => item.id)
-
-  // remove assets from database
-  for (const item of dataObjects) {
-    // ensure dataObject is nowhere used to prevent db constraint error
-    await disconnectDataObjectRelations(db, item)
-
-    // remove data object
-    await db.remove<DataObject>(item)
-  }
-
-  // emit log event
-  logger.info('Storage content have been removed', { id: contentIds, dataObjectIds })
-}
-
-export async function dataDirectory_ContentAccepted(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { contentId, storageProviderId } = new DataDirectory.ContentAcceptedEvent(event).data
-  const encodedContentId = encodeContentId(contentId)
-
-  // load asset
-  const dataObject = await db.get(DataObject, {
-    where: { joystreamContentId: encodedContentId } as FindConditions<DataObject>,
-  })
-
-  // ensure object exists
-  if (!dataObject) {
-    return inconsistentState('Non-existing content acceptation requested', encodedContentId)
-  }
-
-  // load storage provider
-  const worker = await db.get(Worker, {
-    where: {
-      workerId: storageProviderId.toString(),
-      type: WorkerType.STORAGE,
-    } as FindConditions<Worker>,
-  })
-
-  // ensure object exists
-  if (!worker) {
-    return inconsistentState('Missing Storage Provider Id', storageProviderId)
-  }
-
-  // update object
-  dataObject.liaison = worker
-  dataObject.liaisonJudgement = LiaisonJudgement.ACCEPTED
-
-  // set last update time
-  dataObject.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save object
-  await db.save<DataObject>(dataObject)
-
-  // emit log event
-  logger.info('Storage content has been accepted', { id: encodedContentId })
-
-  // update asset availability for all connected channels and videos
-  // this will not be needed after redudant AssetAvailability will be removed (after some Hydra upgrades)
-  await updateConnectedAssets(db, dataObject)
-}
-
-/// ///////////////// Updating connected entities ////////////////////////////////
-
-async function updateConnectedAssets(db: DatabaseManager, dataObject: DataObject) {
-  await updateSingleConnectedAsset(db, new Channel(), 'avatarPhoto', dataObject)
-  await updateSingleConnectedAsset(db, new Channel(), 'coverPhoto', dataObject)
-
-  await updateSingleConnectedAsset(db, new Video(), 'thumbnailPhoto', dataObject)
-  await updateSingleConnectedAsset(db, new Video(), 'media', dataObject)
-}
-
-// async function updateSingleConnectedAsset(db: DatabaseManager, type: typeof Channel | typeof Video, propertyName: string, dataObject: DataObject) {
-async function updateSingleConnectedAsset<T extends Channel | Video>(
-  db: DatabaseManager,
-  type: T,
-  propertyName: string,
-  dataObject: DataObject
-) {
-  // prepare lookup condition
-  const condition = {
-    where: {
-      [propertyName + 'DataObject']: dataObject,
-    },
-  } // as FindConditions<T>
-
-  // NOTE: we don't need to retrieve multiple channels/videos via `db.getMany()` because dataObject
-  //       is allowed to be associated only with one channel/video in runtime
-
-  // in therory the following condition(s) can be generalized `... db.get(type, ...` but in practice it doesn't work :-\
-  const item = type instanceof Channel ? await db.get(Channel, condition) : await db.get(Video, condition)
-
-  // escape when no dataObject association found
-  if (!item) {
-    return
-  }
-
-  item[propertyName + 'Availability'] = AssetAvailability.ACCEPTED
-
-  if (type instanceof Channel) {
-    await db.save<Channel>(item)
-
-    // emit log event
-    logger.info('Channel using Content has been accepted', {
-      channelId: item.id.toString(),
-      joystreamContentId: dataObject.joystreamContentId,
-    })
-  } else {
-    await db.save<Video>(item)
-
-    // emit log event
-    logger.info('Video using Content has been accepted', {
-      videoId: item.id.toString(),
-      joystreamContentId: dataObject.joystreamContentId,
-    })
-  }
-}
-
-// removes connection between dataObject and other entities
-async function disconnectDataObjectRelations(db: DatabaseManager, dataObject: DataObject) {
-  await disconnectSingleDataObjectRelation(db, new Channel(), 'avatarPhoto', dataObject)
-  await disconnectSingleDataObjectRelation(db, new Channel(), 'coverPhoto', dataObject)
-
-  await disconnectSingleDataObjectRelation(db, new Video(), 'thumbnailPhoto', dataObject)
-  await disconnectSingleDataObjectRelation(db, new Video(), 'media', dataObject)
-}
-
-async function disconnectSingleDataObjectRelation<T extends Channel | Video>(
-  db: DatabaseManager,
-  type: T,
-  propertyName: string,
-  dataObject: DataObject
-) {
-  // prepare lookup condition
-  const condition = {
-    where: {
-      [propertyName + 'DataObject']: dataObject,
-    },
-  } // as FindConditions<T>
-
-  // NOTE: we don't need to retrieve multiple channels/videos via `db.getMany()` because dataObject
-  //       is allowed to be associated only with one channel/video in runtime
-
-  // in therory the following condition(s) can be generalized `... db.get(type, ...` but in practice it doesn't work :-\
-  const item = type instanceof Channel ? await db.get(Channel, condition) : await db.get(Video, condition)
-
-  // escape when no dataObject association found
-  if (!item) {
-    return
-  }
-
-  item[propertyName + 'Availability'] = AssetAvailability.INVALID
-  item[propertyName + 'DataObject'] = null
-
-  if (type instanceof Channel) {
-    await db.save<Channel>(item)
-
-    // emit log event
-    logger.info('Content has been disconnected from Channel', {
-      channelId: item.id.toString(),
-      joystreamContentId: dataObject.joystreamContentId,
-    })
-  } else {
-    // type instanceof Video
-    await db.save<Video>(item)
-
-    // emit log event
-    logger.info('Content has been disconnected from Video', {
-      videoId: item.id.toString(),
-      joystreamContentId: dataObject.joystreamContentId,
-    })
-  }
-}
-
-/// ///////////////// Helpers ////////////////////////////////////////////////////
-
-function convertStorageObjectOwner(objectOwner: StorageObjectOwner): typeof DataObjectOwner {
-  if (objectOwner.isMember) {
-    const owner = new DataObjectOwnerMember()
-    owner.member = objectOwner.asMember.toNumber()
-
-    return owner
-  }
-
-  if (objectOwner.isChannel) {
-    const owner = new DataObjectOwnerChannel()
-    owner.channel = objectOwner.asChannel.toNumber()
-
-    return owner
-  }
-
-  if (objectOwner.isDao) {
-    const owner = new DataObjectOwnerDao()
-    owner.dao = objectOwner.asDao.toNumber()
-
-    return owner
-  }
-
-  if (objectOwner.isCouncil) {
-    return new DataObjectOwnerCouncil()
-  }
-
-  if (objectOwner.isWorkingGroup) {
-    const owner = new DataObjectOwnerWorkingGroup()
-    owner.workingGroup = objectOwner.asWorkingGroup.toNumber()
-
-    return owner
-  }
-
-  logger.error('Not implemented StorageObjectOwner type', { objectOwner: objectOwner.toString() })
-  throw new Error('Not implemented StorageObjectOwner type')
-}
-
-function encodeContentId(contentId: ContentId) {
-  const customContentId = new Custom_ContentId(registry, contentId)
-
-  return customContentId.encode()
-}

+ 0 - 237
query-node/mappings/sumer/workingGroup.ts

@@ -1,237 +0,0 @@
-import { SubstrateEvent } from '@dzlzv/hydra-common'
-import { DatabaseManager } from '@dzlzv/hydra-db-utils'
-import { FindConditions } from 'typeorm'
-import { Bytes } from '@polkadot/types'
-import { fixBlockTimestamp } from './eventFix'
-
-import { convertBytesToString, inconsistentState, logger, getNextId } from './common'
-
-import { Channel, Worker, WorkerType } from 'query-node'
-import { GatewayWorkingGroup, StorageWorkingGroup } from '../../generated/types'
-import { ApplicationId, ApplicationIdToWorkerIdMap, WorkerId } from '@joystream/types/augment'
-
-/// ///////////////// Storage working group //////////////////////////////////////
-
-export async function storageWorkingGroup_OpeningFilled(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { applicationIdToWorkerIdMap } = new StorageWorkingGroup.OpeningFilledEvent(event).data
-
-  // call generic processing
-  await workingGroup_OpeningFilled(db, WorkerType.STORAGE, applicationIdToWorkerIdMap, event)
-}
-
-export async function storageWorkingGroup_WorkerStorageUpdated(
-  db: DatabaseManager,
-  event: SubstrateEvent
-): Promise<void> {
-  // read event data
-  const { workerId, bytes: newMetadata } = new StorageWorkingGroup.WorkerStorageUpdatedEvent(event).data
-
-  // call generic processing
-  await workingGroup_WorkerStorageUpdated(db, WorkerType.STORAGE, workerId, newMetadata)
-}
-
-export async function storageWorkingGroup_TerminatedWorker(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new StorageWorkingGroup.TerminatedWorkerEvent(event).data
-
-  // call generic processing
-  await workingGroup_TerminatedWorker(db, event, WorkerType.STORAGE, workerId)
-}
-
-export async function storageWorkingGroup_WorkerExited(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new StorageWorkingGroup.WorkerExitedEvent(event).data
-
-  // call generic processing
-  await workingGroup_WorkerExited(db, event, WorkerType.STORAGE, workerId)
-}
-
-export async function storageWorkingGroup_TerminatedLeader(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new StorageWorkingGroup.TerminatedLeaderEvent(event).data
-
-  // call generic processing
-  await workingGroup_TerminatedLeader(db, event, WorkerType.STORAGE, workerId)
-}
-
-/// ///////////////// Gateway working group //////////////////////////////////////
-
-export async function gatewayWorkingGroup_OpeningFilled(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { applicationIdToWorkerIdMap } = new GatewayWorkingGroup.OpeningFilledEvent(event).data
-
-  // call generic processing
-  await workingGroup_OpeningFilled(db, WorkerType.GATEWAY, applicationIdToWorkerIdMap, event)
-}
-
-export async function gatewayWorkingGroup_WorkerStorageUpdated(
-  db: DatabaseManager,
-  event: SubstrateEvent
-): Promise<void> {
-  // read event data
-  const { workerId, bytes: newMetadata } = new GatewayWorkingGroup.WorkerStorageUpdatedEvent(event).data
-
-  // call generic processing
-  await workingGroup_WorkerStorageUpdated(db, WorkerType.GATEWAY, workerId, newMetadata)
-}
-
-export async function gatewayWorkingGroup_TerminatedWorker(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new GatewayWorkingGroup.TerminatedWorkerEvent(event).data
-
-  // call generic processing
-  await workingGroup_TerminatedWorker(db, event, WorkerType.GATEWAY, workerId)
-}
-
-export async function gatewayWorkingGroup_WorkerExited(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new GatewayWorkingGroup.WorkerExitedEvent(event).data
-
-  // call generic processing
-  await workingGroup_WorkerExited(db, event, WorkerType.GATEWAY, workerId)
-}
-
-export async function gatewayWorkingGroup_TerminatedLeader(db: DatabaseManager, event: SubstrateEvent): Promise<void> {
-  // read event data
-  const { workerId } = new GatewayWorkingGroup.TerminatedLeaderEvent(event).data
-
-  // call generic processing
-  await workingGroup_TerminatedLeader(db, event, WorkerType.GATEWAY, workerId)
-}
-
-/// ///////////////// Generic working group processing ///////////////////////////
-
-export async function workingGroup_OpeningFilled(
-  db: DatabaseManager,
-  workerType: WorkerType,
-  applicationIdToWorkerIdMap: ApplicationIdToWorkerIdMap,
-  event: SubstrateEvent
-): Promise<void> {
-  const workerIds = [...applicationIdToWorkerIdMap.values()]
-
-  for (const workerId of workerIds) {
-    await createWorker(db, workerId, workerType, event)
-  }
-
-  // emit log event
-  logger.info('Workers have been created', { ids: workerIds.map((item) => item.toString()), workerType })
-}
-
-export async function workingGroup_WorkerStorageUpdated(
-  db: DatabaseManager,
-  workerType: WorkerType,
-  workerId: WorkerId,
-  newMetadata: Bytes
-): Promise<void> {
-  // load worker
-  const worker = await db.get(Worker, {
-    where: {
-      workerId: workerId.toString(),
-      type: workerType,
-    } as FindConditions<Worker>,
-  })
-
-  // ensure worker exists
-  if (!worker) {
-    return inconsistentState('Non-existing worker update requested', workerId)
-  }
-
-  worker.metadata = convertBytesToString(newMetadata)
-
-  await db.save<Worker>(worker)
-
-  // emit log event
-  logger.info('Worker has been updated', { workerId, workerType })
-}
-
-export async function workingGroup_TerminatedWorker(
-  db: DatabaseManager,
-  event: SubstrateEvent,
-  workerType: WorkerType,
-  workerId: WorkerId
-): Promise<void> {
-  // do removal logic
-  await deactivateWorker(db, event, workerType, workerId)
-
-  // emit log event
-  logger.info('Worker has been removed (worker terminated)', { workerId, workerType })
-}
-
-export async function workingGroup_WorkerExited(
-  db: DatabaseManager,
-  event: SubstrateEvent,
-  workerType: WorkerType,
-  workerId: WorkerId
-): Promise<void> {
-  // do removal logic
-  await deactivateWorker(db, event, workerType, workerId)
-
-  // emit log event
-  logger.info('Worker has been removed (worker exited)', { workerId, workerType })
-}
-
-export async function workingGroup_TerminatedLeader(
-  db: DatabaseManager,
-  event: SubstrateEvent,
-  workerType: WorkerType,
-  workerId: WorkerId
-): Promise<void> {
-  // do removal logic
-  await deactivateWorker(db, event, workerType, workerId)
-
-  // emit log event
-  logger.info('Working group leader has been removed (worker exited)', { workerId, workerType })
-}
-
-/// ///////////////// Helpers ////////////////////////////////////////////////////
-
-async function createWorker(
-  db: DatabaseManager,
-  workerId: WorkerId,
-  workerType: WorkerType,
-  event: SubstrateEvent
-): Promise<void> {
-  // create entity
-  const newWorker = new Worker({
-    id: await getNextId(db),
-    workerId: workerId.toString(),
-    type: workerType,
-    isActive: true,
-
-    createdAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-    updatedAt: new Date(fixBlockTimestamp(event.blockTimestamp).toNumber()),
-  })
-
-  // save worker
-  await db.save<Worker>(newWorker)
-}
-
-async function deactivateWorker(
-  db: DatabaseManager,
-  event: SubstrateEvent,
-  workerType: WorkerType,
-  workerId: WorkerId
-) {
-  // load worker
-  const worker = await db.get(Worker, {
-    where: {
-      workerId: workerId.toString(),
-      type: workerType,
-    } as FindConditions<Worker>,
-  })
-
-  // ensure worker exists
-  if (!worker) {
-    return inconsistentState('Non-existing worker deletion requested', workerId)
-  }
-
-  // update worker
-  worker.isActive = false
-
-  // set last update time
-  worker.updatedAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())
-
-  // save worker
-  await db.save<Worker>(worker)
-}

+ 1 - 1
query-node/mappings/tsconfig.json

@@ -18,5 +18,5 @@
       "@polkadot/types/augment": ["../../types/augment/augment-types.ts"]
     }
   },
-  "include": ["./giza/**/*"]
+  "include": ["./**/*"]
 }

+ 156 - 0
query-node/mappings/workingGroup.ts

@@ -0,0 +1,156 @@
+import { EventContext, StoreContext, DatabaseManager, SubstrateEvent } from '@joystream/hydra-common'
+import { bytesToString, inconsistentState, logger } from './common'
+import { Worker, WorkerType } from 'query-node/dist/model'
+import { StorageWorkingGroup } from './generated/types'
+import { WorkerId } from '@joystream/types/augment'
+
+export async function workingGroup_OpeningFilled({ event, store }: EventContext & StoreContext): Promise<void> {
+  const workerType = getWorkerType(event)
+  if (!workerType) {
+    return
+  }
+
+  const [, applicationIdToWorkerIdMap] = new StorageWorkingGroup.OpeningFilledEvent(event).params
+  const workerIds = [...applicationIdToWorkerIdMap.values()]
+
+  for (const workerId of workerIds) {
+    await createWorker(store, workerId, workerType, event)
+  }
+
+  // emit log event
+  logger.info('Workers have been created', { ids: workerIds.map((item) => item.toString()), workerType })
+}
+
+export async function workingGroup_WorkerStorageUpdated({ event, store }: EventContext & StoreContext): Promise<void> {
+  const workerType = getWorkerType(event)
+  if (!workerType) {
+    return
+  }
+  const [workerId, newMetadata] = new StorageWorkingGroup.WorkerStorageUpdatedEvent(event).params
+
+  // load worker
+  const worker = await store.get(Worker, {
+    where: {
+      workerId: workerId.toString(),
+      type: workerType,
+    },
+  })
+
+  // ensure worker exists
+  if (!worker) {
+    return inconsistentState('Non-existing worker update requested', workerId)
+  }
+
+  worker.metadata = bytesToString(newMetadata)
+
+  await store.save<Worker>(worker)
+
+  // emit log event
+  logger.info('Worker has been updated', { workerId, workerType })
+}
+
+export async function workingGroup_TerminatedWorker({ event, store }: EventContext & StoreContext): Promise<void> {
+  const workerType = getWorkerType(event)
+  if (!workerType) {
+    return
+  }
+  const [workerId] = new StorageWorkingGroup.TerminatedWorkerEvent(event).params
+
+  // do removal logic
+  await deactivateWorker(store, event, workerType, workerId)
+
+  // emit log event
+  logger.info('Worker has been removed (worker terminated)', { workerId, workerType })
+}
+
+export async function workingGroup_WorkerExited({ event, store }: EventContext & StoreContext): Promise<void> {
+  const workerType = getWorkerType(event)
+  if (!workerType) {
+    return
+  }
+  const [workerId] = new StorageWorkingGroup.WorkerExitedEvent(event).params
+
+  // do removal logic
+  await deactivateWorker(store, event, workerType, workerId)
+
+  // emit log event
+  logger.info('Worker has been removed (worker exited)', { workerId, workerType })
+}
+
+export async function workingGroup_TerminatedLeader({ event, store }: EventContext & StoreContext): Promise<void> {
+  const workerType = getWorkerType(event)
+  if (!workerType) {
+    return
+  }
+  const [workerId] = new StorageWorkingGroup.WorkerExitedEvent(event).params
+
+  // do removal logic
+  await deactivateWorker(store, event, workerType, workerId)
+
+  // emit log event
+  logger.info('Working group leader has been removed (worker exited)', { workerId, workerType })
+}
+
+/// ///////////////// Helpers ////////////////////////////////////////////////////
+
+function getWorkerType(event: SubstrateEvent): WorkerType | null {
+  if (event.section === 'storageWorkingGroup') {
+    return WorkerType.STORAGE
+  }
+
+  if (event.section === 'gatewayWorkingGroup') {
+    return WorkerType.GATEWAY
+  }
+
+  return null
+}
+
+async function createWorker(
+  db: DatabaseManager,
+  workerId: WorkerId,
+  workerType: WorkerType,
+  event: SubstrateEvent
+): Promise<void> {
+  // create entity
+  const newWorker = new Worker({
+    id: `${workerType}-${workerId.toString()}`,
+    workerId: workerId.toString(),
+    type: workerType,
+    isActive: true,
+
+    createdAt: new Date(event.blockTimestamp),
+    updatedAt: new Date(event.blockTimestamp),
+  })
+
+  // save worker
+  await db.save<Worker>(newWorker)
+}
+
+async function deactivateWorker(
+  db: DatabaseManager,
+  event: SubstrateEvent,
+  workerType: WorkerType,
+  workerId: WorkerId
+) {
+  // load worker
+  const worker = await db.get(Worker, {
+    where: {
+      workerId: workerId.toString(),
+      type: workerType,
+    },
+  })
+
+  // ensure worker exists
+  if (!worker) {
+    return inconsistentState('Non-existing worker deletion requested', workerId)
+  }
+
+  // update worker
+  worker.isActive = false
+
+  // set last update time
+  worker.updatedAt = new Date(event.blockTimestamp)
+
+  // save worker
+  await db.save<Worker>(worker)
+}

+ 13 - 182
query-node/schemas/content.graphql

@@ -10,106 +10,6 @@ type ChannelCategory @entity {
   createdInBlock: Int!
 }
 
-"Asset availability representation"
-enum AssetAvailability {
-  "Asset is available in storage"
-  ACCEPTED,
-
-  "Asset is being uploaded to storage"
-  PENDING,
-
-  "Invalid storage (meta)data used"
-  INVALID,
-}
-
-"The decision of the storage provider when it acts as liaison"
-enum LiaisonJudgement {
-  "Content awaits for a judgment"
-  PENDING,
-
-  "Content accepted"
-  ACCEPTED,
-}
-
-"Manages content ids, type and storage provider decision about it"
-type DataObject @entity {
-  "Content owner"
-  owner: DataObjectOwner!
-
-  "Content added at"
-  createdInBlock: Int!
-
-  "Content type id"
-  typeId: Int!
-
-  "Content size in bytes"
-  size: Int!
-
-  "Storage provider id of the liaison"
-  liaison: Worker # liaison is unset until storage provider accepts or rejects the content
-
-  "Storage provider as liaison judgment"
-  liaisonJudgement: LiaisonJudgement!
-
-  "IPFS content id"
-  ipfsContentId: String!
-
-  "Joystream runtime content"
-  joystreamContentId: String!
-}
-
-"Owner type for storage object"
-union DataObjectOwner = DataObjectOwnerMember
-  | DataObjectOwnerChannel
-  | DataObjectOwnerDao
-  | DataObjectOwnerCouncil
-  | DataObjectOwnerWorkingGroup
-
-"Asset owned by a member"
-type DataObjectOwnerMember @variant {
-  # use `Int` instead of `Membership` before variant relations are featured in Hydra
-  # TODO: setup proper relations
-  #"Member identifier"
-  #memberId: Membership!
-  "Member identifier"
-  member: Int!
-
-  "Variant needs to have at least one property. This value is not used."
-  dummy: Int
-}
-
-"Asset owned by a channel"
-type DataObjectOwnerChannel @variant {
-  # use `Int` instead of `Channel` before variant relations are featured in Hydra
-  #"Channel identifier"
-  #channel: Channel!
-  "Channel identifier"
-  channel: Int!
-
-  "Variant needs to have at least one property. This value is not used."
-  dummy: Int
-}
-
-"Asset owned by a DAO"
-type DataObjectOwnerDao @variant {
-  "DAO identifier"
-  dao: Int!
-}
-
-"Asset owned by the Council"
-type DataObjectOwnerCouncil @variant {
-  "Variant needs to have at least one property. This value is not used."
-  dummy: Int
-}
-
-"Asset owned by a WorkingGroup"
-type DataObjectOwnerWorkingGroup @variant {
-  "Working group identifier"
-  workingGroup: Int!
-}
-
-#### High Level Derivative Entities ####
-
 type Language @entity {
   "Runtime entity identifier (EntityId)"
   id: ID!
@@ -135,37 +35,20 @@ type Channel @entity {
   "Reward account where revenue is sent if set."
   rewardAccount: String
 
+  "Destination account for the prize associated with channel deletion"
+  deletionPrizeDestAccount: String!
+
   "The title of the Channel"
   title: String @fulltext(query: "search")
 
   "The description of a Channel"
   description: String
 
-  ### Cover photo asset ###
-
-  # Channel's cover (background) photo. Recommended ratio: 16:9.
-
-  "Asset's data object"
-  coverPhotoDataObject: DataObject
+  "Channel's cover (background) photo asset. Recommended ratio: 16:9."
+  coverPhoto: StorageDataObject
 
-  "URLs where the asset content can be accessed (if any)"
-  coverPhotoUrls: [String!]
-
-  "Availability meta information"
-  coverPhotoAvailability: AssetAvailability!
-
-  ### Avatar photo asset ###
-
-  # Channel's avatar photo.
-
-  "Asset's data object"
-  avatarPhotoDataObject: DataObject
-
-  "URLs where the asset content can be accessed (if any)"
-  avatarPhotoUrls: [String!]
-
-  "Availability meta information"
-  avatarPhotoAvailability: AssetAvailability!
+  "Channel's avatar photo asset."
+  avatarPhoto: StorageDataObject
 
   ##########################
 
@@ -213,7 +96,7 @@ type Video @entity {
   id: ID!
 
   "Reference to member's channel"
-  channel: Channel
+  channel: Channel!
 
   "Reference to a video category"
   category: VideoCategory
@@ -227,18 +110,8 @@ type Video @entity {
   "Video duration in seconds"
   duration: Int
 
-  ### Thumbnail asset ###
-
-  # Video thumbnail (recommended ratio: 16:9)
-
-  "Asset's data object"
-  thumbnailPhotoDataObject: DataObject
-
-  "URLs where the asset content can be accessed (if any)"
-  thumbnailPhotoUrls: [String!]
-
-  "Availability meta information"
-  thumbnailPhotoAvailability: AssetAvailability!
+  "Video thumbnail asset (recommended ratio: 16:9)"
+  thumbnailPhoto: StorageDataObject
 
   ##########################
 
@@ -263,18 +136,8 @@ type Video @entity {
   "License under the video is published"
   license: License
 
-  ### Media asset ###
-
-  # Reference to video asset
-
-  "Asset's data object"
-  mediaDataObject: DataObject
-
-  "URLs where the asset content can be accessed (if any)"
-  mediaUrls: [String!]
-
-  "Availability meta information"
-  mediaAvailability: AssetAvailability!
+  "Video media asset"
+  media: StorageDataObject
 
   ##########################
 
@@ -301,7 +164,7 @@ type VideoMediaMetadata @entity {
   pixelHeight: Int
 
   "Video media size in bytes"
-  size: Int
+  size: BigInt
 
   video: Video @derivedFrom(field: "mediaMetadata")
 
@@ -332,35 +195,3 @@ type License @entity {
   "Custom license content"
   custom_text: String
 }
-
-enum WorkerType {
-  GATEWAY
-  STORAGE
-}
-
-type Worker @entity {
-  "Unique identifier"
-  id: ID!
-
-  "Sign of worker still being active"
-  isActive: Boolean!
-
-  "Runtime identifier"
-  workerId: String!
-
-  "Associated working group"
-  type: WorkerType!
-
-  "Custom metadata set by provider"
-  metadata: String
-
-  dataObjects: [DataObject!]! @derivedFrom(field: "liaison")
-}
-
-type NextEntityId @entity {
-  "Unique identifier"
-  id: ID!
-
-  "Next deterministic id for entities without custom id"
-  nextId: Int!
-}

+ 80 - 4
query-node/schemas/storage.graphql

@@ -20,6 +20,9 @@ type StorageSystemParameters @entity {
 
   "Global max. size of objects a storage bucket can store (can also be further limitted the provider)"
   storageBucketMaxObjectsSizeLimit: BigInt!
+
+  "ID of the next data object when created"
+  nextDataObjectId: BigInt!
 }
 
 type StorageBucketOperatorStatusMissing @variant {
@@ -39,11 +42,34 @@ union StorageBucketOperatorStatus = StorageBucketOperatorStatusMissing | Storage
 type GeoCoordinates @entity {
   latitude: Float!
   longitude: Float!
+}
+
+enum Continent {
+  AF
+  NA
+  OC
+  AN
+  AS
+  EU
+  SA
+}
+
+type GeographicalAreaContinent @variant {
+  code: Continent
+}
+
+type GeographicalAreaCountry @variant {
+  "ISO 3166-1 alpha-2 country code"
+  code: String
+}
 
-  "Optional DistributionBucketFamilyMetadata reference in case the coordinates are part of a region boundary"
-  boundarySourceBucketFamilyMeta: DistributionBucketFamilyMetadata
+type GeographicalAreaSubdivistion @variant {
+  "ISO 3166-2 subdivision code"
+  code: String
 }
 
+union GeographicalArea = GeographicalAreaContinent | GeographicalAreaCountry | GeographicalAreaSubdivistion
+
 type NodeLocationMetadata @entity {
   "ISO 3166-1 alpha-2 country code (2 letters)"
   countryCode: String
@@ -165,6 +191,32 @@ type StorageBagDistributionAssignment @entity {
   distributionBucketId: ID
 }
 
+type DataObjectTypeChannelAvatar @variant {
+  "Related channel entity"
+  channel: Channel!
+}
+
+type DataObjectTypeChannelCoverPhoto @variant {
+  "Related channel entity"
+  channel: Channel!
+}
+
+type DataObjectTypeVideoMedia @variant {
+  "Related video entity"
+  video: Video!
+}
+
+type DataObjectTypeVideoThumbnail @variant {
+  "Related video entity"
+  video: Video!
+}
+
+type DataObjectTypeUnknown @variant {
+  _phantom: Int
+}
+
+union DataObjectType = DataObjectTypeChannelAvatar | DataObjectTypeChannelCoverPhoto | DataObjectTypeVideoMedia | DataObjectTypeVideoThumbnail | DataObjectTypeUnknown
+
 type StorageDataObject @entity {
   "Data object runtime id"
   id: ID!
@@ -180,6 +232,27 @@ type StorageDataObject @entity {
 
   "IPFS content hash"
   ipfsHash: String!
+
+  # FIXME: Cannot be optional because: https://github.com/Joystream/hydra/issues/434
+  "The type of the asset that the data object represents (if known)"
+  type: DataObjectType!
+
+  "Prize for removing the data object"
+  deletionPrize: BigInt!
+
+  "If the object is no longer used as an asset - the time at which it was unset (if known)"
+  unsetAt: DateTime
+}
+
+type DistributionBucketFamilyGeographicArea @entity {
+  "{metadataId}-{(C|c|s)}-{code}"
+  id: ID!
+
+  "Geographical area (continent / country / subdivision)"
+  area: GeographicalArea!
+
+  "Related distribution bucket family metadata"
+  distributionBucketFamilyMetadata: DistributionBucketFamilyMetadata!
 }
 
 type DistributionBucketFamilyMetadata @entity {
@@ -189,8 +262,11 @@ type DistributionBucketFamilyMetadata @entity {
   "Optional, more specific description of the region covered by the family"
   description: String
 
-  "Optional region boundary as geocoordiantes polygon"
-  boundary: [GeoCoordinates!] @derivedFrom(field: "boundarySourceBucketFamilyMeta")
+  "Geographical areas covered by the family"
+  areas: [DistributionBucketFamilyGeographicArea!] @derivedFrom(field: "distributionBucketFamilyMetadata")
+
+  "List of targets (hosts/ips) best suited latency measurements for the family"
+  latencyTestTargets: [String]
 }
 
 type DistributionBucketOperatorMetadata @entity {

+ 17 - 0
query-node/schemas/workingGroups.graphql

@@ -0,0 +1,17 @@
+enum WorkerType {
+  GATEWAY
+  STORAGE
+}
+
+type Worker @entity {
+  "Unique identifier"
+  id: ID!
+  "Sign of worker still being active"
+  isActive: Boolean!
+  "Runtime identifier"
+  workerId: String!
+  "Associated working group"
+  type: WorkerType!
+  "Custom metadata set by provider"
+  metadata: String
+}

File diff suppressed because it is too large
+ 0 - 0
types/augment-codec/all.ts


+ 14 - 12
yarn.lock

@@ -4861,6 +4861,11 @@
   resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.0.tgz#1b0b819b1636c7baf0d6785d030d12edf70c3e83"
   integrity "sha1-GwuBmxY2x7rw1nhdAw0S7fcMPoM= sha512-iTs9HReBu7evG77Q4EC8hZnqRt57irBDkK9nvmHroiOIVwYMQc4IvYvdRgwKfYepunIY7Oh/dBuuld+Gj9uo6w=="
 
+"@types/iso-3166-2@^1.0.0":
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/@types/iso-3166-2/-/iso-3166-2-1.0.0.tgz#98a7b6e505c031e83c5aac13c9c49f9d9f6ca234"
+  integrity sha512-DYDyoRyPyxBeI9bYoTXLfsOZH12m1anrWEj9LU5Sl9rgsJ4soJMYf/7byozM+64Smn6/a1i079eQLGuPykwaHQ==
+
 "@types/isomorphic-fetch@^0.0.35":
   version "0.0.35"
   resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.35.tgz#c1c0d402daac324582b6186b91f8905340ea3361"
@@ -14492,11 +14497,6 @@ google-protobuf@^3.14.0:
   resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.17.3.tgz#f87595073545a77946c8f0b67c302c5f7646d700"
   integrity sha512-OVPzcSWIAJ+d5yiHyeaLrdufQtrvaBrF4JQg+z8ynTkbO3uFcujqXszTumqg1cGsAsjkWnI+M5B1xZ19yR4Wyg==
 
-google-protobuf@^3.6.1:
-  version "3.15.8"
-  resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.15.8.tgz#5f3948905e4951c867d6bc143f385a80e2a39efe"
-  integrity sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==
-
 got@^6.3.0, got@^6.7.1:
   version "6.7.1"
   resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0"
@@ -16923,6 +16923,15 @@ isexe@^2.0.0:
   resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
   integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
 
+iso-639-1@^2.1.9:
+  version "2.1.9"
+  resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-2.1.9.tgz#e41b11d4f1808e5316d0252c3fa16eeb9b37bb58"
+  integrity sha512-owRu9up+Cpx/hwSzm83j6G8PtC7U99UCtPVItsafefNfEgMl+pi8KBwhXwJkJfp6IouyYWFxj8n24SvCWpKZEQ==
+iso-3166-2@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/iso-3166-2/-/iso-3166-2-1.0.0.tgz#20c5cda527b56bfc7409c6802d9bff0119086131"
+  integrity sha512-xLAazfKZzwlsg/Zz/GQGQk3jJez5/2ORrjD3TjSuqz/arMht/xTK49c0GOE3afO/gEd9tHtBVVlfBla01unUng==
+
 iso-constants@^0.1.2:
   version "0.1.2"
   resolved "https://registry.yarnpkg.com/iso-constants/-/iso-constants-0.1.2.tgz#3d2456ed5aeaa55d18564f285ba02a47a0d885b4"
@@ -27740,13 +27749,6 @@ ts-pnp@^1.1.2:
   resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
   integrity "sha1-pQCtCEsHmPHDBxrzkeZZEshrypI= sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw=="
 
-ts-protoc-gen@^0.14.0:
-  version "0.14.0"
-  resolved "https://registry.yarnpkg.com/ts-protoc-gen/-/ts-protoc-gen-0.14.0.tgz#a6f4c3fc37d1d449915551c18404fb7e9aa8fef6"
-  integrity sha512-2z6w2HioMCMVNcgNHBcEvudmQfzrn+3BjAlz+xgYZ9L0o8n8UG8WUiTJcbXHFiEg2SU8IltwH2pm1otLoMSKwg==
-  dependencies:
-    google-protobuf "^3.6.1"
-
 tsconfig-paths-webpack-plugin@^3.2.0:
   version "3.5.1"
   resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.1.tgz#e4dbf492a20dca9caab60086ddacb703afc2b726"

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