Преглед на файлове

Merge branch 'alex-versioned-store' into joystream-update-membership-roles

Mokhtar Naamani преди 5 години
родител
ревизия
6499114946

+ 7 - 2
.gitignore

@@ -2,7 +2,8 @@ build/
 coverage/
 node_modules/
 tmp/
-.idea
+.idea/
+.vscode/
 .DS_Store
 .env.local
 .env.development.local
@@ -14,4 +15,8 @@ package-lock.json
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
-.idea/
+
+!patches/**
+
+# Compiled Joystream types:
+packages/joy-types/lib/

+ 1 - 1
packages/joy-types/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@joystream/types",
-  "version": "0.3.1",
+  "version": "0.4.0",
   "description": "Joystream types for Substrate modules",
   "main": "lib/index.js",
   "scripts": {

+ 34 - 0
packages/joy-types/src/JoyStruct.ts

@@ -0,0 +1,34 @@
+import { Option, Struct } from '@polkadot/types/codec';
+import { Text, bool as Bool } from '@polkadot/types';
+import { Codec } from '@polkadot/types/types';
+
+export class JoyStruct<T extends {
+  [K: string]: Codec;
+}> extends Struct {
+
+  getField<C extends Codec> (name: keyof T): C {
+    return super.get(name as string) as C;
+  }
+
+  getString (name: keyof T): string {
+    return this.getField<Text>(name).toString();
+  }
+
+  getBoolean (name: keyof T): boolean {
+    return this.getField<Bool>(name).valueOf();
+  }
+
+  unwrapOrUndefined<C extends Codec> (name: keyof T): C | undefined {
+    return this.getField<Option<C>>(name).unwrapOr(undefined);
+  }
+
+  cloneValues (): T {
+    const objectClone = {} as { [K: string]: Codec };
+
+    super.forEach((v, k) => {
+      objectClone[k] = v; // shallow copy acceptable ?
+    });
+
+    return objectClone as T;
+  }
+}

+ 45 - 63
packages/joy-types/src/forum.ts

@@ -1,26 +1,8 @@
-import { getTypeRegistry, bool, u16, u32, u64, Text, Struct, Option, Vec as Vector} from '@polkadot/types';
+import { getTypeRegistry, bool, u16, u32, u64, Text, Option, Vec as Vector} from '@polkadot/types';
 import { AccountId, Moment, BlockNumber } from '@polkadot/types/interfaces';
 import { GenericAccountId } from '@polkadot/types';
 
-import { getTextPropAsString, getBoolPropAsBoolean, getOptionPropOrUndefined } from './';
-import { Codec } from '@polkadot/types/types';
-
-export class JoyStruct<T extends { [K: string]: Codec }> extends Struct {
-
-  getRequired <C extends Codec> (name: keyof T): C {
-    return super.get(name as string) as C;
-  }
-
-  cloneValues (): T {
-    const objectClone = {} as { [K: string]: Codec };
-
-    super.forEach((v, k) => {
-      objectClone[k] = v; // shallow copy acceptable ?
-    });
-
-    return objectClone as T;
-  }
-}
+import { JoyStruct } from './JoyStruct';
 
 // Based on copypasta from joy-media/BlockAndTimeType
 export type BlockchainTimestampType = {
@@ -38,11 +20,11 @@ export class BlockchainTimestamp extends JoyStruct<BlockchainTimestampType> {
   }
 
   get block (): BlockNumber {
-    return this.getRequired('block');
+    return this.getField('block');
   }
 
   get time (): Moment {
-    return this.getRequired('time');
+    return this.getField('time');
   }
 
   static newEmpty (): BlockchainTimestamp {
@@ -66,15 +48,15 @@ export class ModerationAction extends JoyStruct<ModerationActionType> {
   }
 
   get moderated_at (): BlockchainTimestamp {
-    return this.getRequired('moderated_at');
+    return this.getField('moderated_at');
   }
 
   get moderator_id (): AccountId {
-    return this.getRequired('moderator_id');
+    return this.getField('moderator_id');
   }
 
   get rationale (): string {
-    return getTextPropAsString(this, 'rationale');
+    return this.getString('rationale');
   }
 }
 
@@ -92,11 +74,11 @@ export class PostTextChange extends JoyStruct<PostTextChangeType> {
   }
 
   get expired_at (): BlockchainTimestamp {
-    return this.getRequired('expired_at');
+    return this.getField('expired_at');
   }
 
   get text (): string {
-    return getTextPropAsString(this, 'text');
+    return this.getString('text');
   }
 }
 
@@ -132,11 +114,11 @@ export class InputValidationLengthConstraint extends JoyStruct<InputValidationLe
   }
 
   get min (): u16 {
-    return this.getRequired('min');
+    return this.getField('min');
   }
 
   get max_min_diff (): u16 {
-    return this.getRequired('max_min_diff');
+    return this.getField('max_min_diff');
   }
 
   get max (): u16 {
@@ -158,11 +140,11 @@ export class ChildPositionInParentCategory extends JoyStruct<ChildPositionInPare
   }
 
   get parent_id (): CategoryId {
-    return this.getRequired('parent_id');
+    return this.getField('parent_id');
   }
 
   get child_nr_in_parent_category (): u32 {
-    return this.getRequired('child_nr_in_parent_category');
+    return this.getField('child_nr_in_parent_category');
   }
 }
 
@@ -204,39 +186,39 @@ export class Category extends JoyStruct<CategoryType> {
   }
 
   get id (): CategoryId {
-    return this.getRequired('id');
+    return this.getField('id');
   }
 
   get title (): string {
-    return getTextPropAsString(this, 'title');
+    return this.getString('title');
   }
 
   get description (): string {
-    return getTextPropAsString(this, 'description');
+    return this.getString('description');
   }
 
   get created_at (): BlockchainTimestamp {
-    return this.getRequired('created_at');
+    return this.getField('created_at');
   }
 
   get deleted (): boolean {
-    return getBoolPropAsBoolean(this, 'deleted');
+    return this.getBoolean('deleted');
   }
 
   get archived (): boolean {
-    return getBoolPropAsBoolean(this, 'archived');
+    return this.getBoolean('archived');
   }
 
   get num_direct_subcategories (): u32 {
-    return this.getRequired('num_direct_subcategories');
+    return this.getField('num_direct_subcategories');
   }
 
   get num_direct_unmoderated_threads (): u32 {
-    return this.getRequired('num_direct_unmoderated_threads');
+    return this.getField('num_direct_unmoderated_threads');
   }
 
   get num_direct_moderated_threads (): u32 {
-    return this.getRequired('num_direct_moderated_threads');
+    return this.getField('num_direct_moderated_threads');
   }
 
   get num_threads_created (): u32 {
@@ -252,7 +234,7 @@ export class Category extends JoyStruct<CategoryType> {
   }
 
   get position_in_parent_category (): Option<ChildPositionInParentCategory> {
-    return this.getRequired('position_in_parent_category');
+    return this.getField('position_in_parent_category');
   }
 
   get parent_id (): CategoryId | undefined {
@@ -270,7 +252,7 @@ export class Category extends JoyStruct<CategoryType> {
   }
 
   get moderator_id (): AccountId {
-    return this.getRequired('moderator_id');
+    return this.getField('moderator_id');
   }
 }
 
@@ -306,23 +288,23 @@ export class Thread extends JoyStruct<ThreadType> {
   }
 
   get id (): ThreadId {
-    return this.getRequired('id');
+    return this.getField('id');
   }
 
   get title (): string {
-    return getTextPropAsString(this, 'title');
+    return this.getString('title');
   }
 
   get category_id (): CategoryId {
-    return this.getRequired('category_id');
+    return this.getField('category_id');
   }
 
   get nr_in_category (): u32 {
-    return this.getRequired('nr_in_category');
+    return this.getField('nr_in_category');
   }
 
   get moderation (): ModerationAction | undefined {
-    return getOptionPropOrUndefined(this, 'moderation');
+    return this.unwrapOrUndefined('moderation');
   }
 
   get moderated (): boolean {
@@ -330,11 +312,11 @@ export class Thread extends JoyStruct<ThreadType> {
   }
 
   get num_unmoderated_posts (): u32 {
-    return this.getRequired('num_unmoderated_posts');
+    return this.getField('num_unmoderated_posts');
   }
 
   get num_moderated_posts (): u32 {
-    return this.getRequired('num_moderated_posts');
+    return this.getField('num_moderated_posts');
   }
 
   get num_posts_ever_created (): u32 {
@@ -342,11 +324,11 @@ export class Thread extends JoyStruct<ThreadType> {
   }
 
   get created_at (): BlockchainTimestamp {
-    return this.getRequired('created_at');
+    return this.getField('created_at');
   }
 
   get author_id (): AccountId {
-    return this.getRequired('author_id');
+    return this.getField('author_id');
   }
 }
 
@@ -381,23 +363,23 @@ export class Post extends JoyStruct<PostType> {
   }
 
   get id (): PostId {
-    return this.getRequired('id');
+    return this.getField('id');
   }
 
   get thread_id (): ThreadId {
-    return this.getRequired('thread_id');
+    return this.getField('thread_id');
   }
 
   get nr_in_thread (): u32 {
-    return this.getRequired('nr_in_thread');
+    return this.getField('nr_in_thread');
   }
 
   get current_text (): string {
-    return getTextPropAsString(this, 'current_text');
+    return this.getString('current_text');
   }
 
   get moderation (): ModerationAction | undefined {
-    return getOptionPropOrUndefined(this, 'moderation');
+    return this.unwrapOrUndefined('moderation');
   }
 
   get moderated (): boolean {
@@ -405,15 +387,15 @@ export class Post extends JoyStruct<PostType> {
   }
 
   get text_change_history (): VecPostTextChange {
-    return this.getRequired('text_change_history');
+    return this.getField('text_change_history');
   }
 
   get created_at (): BlockchainTimestamp {
-    return this.getRequired('created_at');
+    return this.getField('created_at');
   }
 
   get author_id (): AccountId {
-    return this.getRequired('author_id');
+    return this.getField('author_id');
   }
 }
 
@@ -436,19 +418,19 @@ export class Reply extends JoyStruct<ReplyType> {
   }
 
   get owner (): AccountId {
-    return this.getRequired('owner');
+    return this.getField('owner');
   }
 
   get thread_id (): ThreadId {
-    return this.getRequired('thread_id');
+    return this.getField('thread_id');
   }
 
   get text (): string {
-    return getTextPropAsString(this, 'text');
+    return this.getString('text');
   }
 
   get moderation (): ModerationAction | undefined {
-    return getOptionPropOrUndefined(this, 'moderation');
+    return this.unwrapOrUndefined('moderation');
   }
 
   get moderated (): boolean {

+ 5 - 1
packages/joy-types/src/index.ts

@@ -2,12 +2,14 @@ import { Enum, Option, Struct } from '@polkadot/types/codec';
 import { getTypeRegistry, Text } from '@polkadot/types';
 import { BlockNumber, AccountId, Balance, Hash } from '@polkadot/types/interfaces';
 import { u32, bool } from '@polkadot/types/primitive';
+import { Codec } from '@polkadot/types/types';
+
 import { registerForumTypes } from './forum';
 import { registerMediaTypes } from './media';
 import { registerMembershipTypes } from './members';
 import { registerRolesTypes } from './roles';
 import { registerDiscoveryTypes } from './discovery';
-import { Codec } from '@polkadot/types/types';
+
 
 export function getTextPropAsString (struct: Struct, fieldName: string): string {
   return (struct.get(fieldName) as Text).toString();
@@ -22,6 +24,7 @@ export function getOptionPropOrUndefined <T extends Codec>
 
   return (struct.get(fieldName) as Option<T>).unwrapOr(undefined);
 }
+import { registerVersionedStoreTypes } from './versioned-store';
 
 export class OptionText extends Option.with(Text) {
 
@@ -241,4 +244,5 @@ export function registerJoystreamTypes () {
   registerForumTypes();
   registerElectionAndProposalTypes();
   registerDiscoveryTypes();
+  registerVersionedStoreTypes();
 }

+ 3 - 0
packages/joy-types/src/versioned-store/ClassId.ts

@@ -0,0 +1,3 @@
+import { u64 } from '@polkadot/types';
+
+export default class ClassId extends u64 {}

+ 3 - 0
packages/joy-types/src/versioned-store/EntityId.ts

@@ -0,0 +1,3 @@
+import { u64 } from '@polkadot/types';
+
+export default class EntityId extends u64 {}

+ 101 - 0
packages/joy-types/src/versioned-store/PropertyType.ts

@@ -0,0 +1,101 @@
+import { u16, Null } from '@polkadot/types';
+import { Enum, Tuple } from '@polkadot/types/codec';
+import ClassId from './ClassId';
+
+export class None extends Null {}
+
+// Single values:
+
+export class Bool extends Null {}
+export class Uint16 extends Null {}
+export class Uint32 extends Null {}
+export class Uint64 extends Null {}
+export class Int16 extends Null {}
+export class Int32 extends Null {}
+export class Int64 extends Null {}
+export class Text extends u16 {}
+export class Internal extends ClassId {}
+
+// Vectors:
+
+export class BoolVec extends u16 {}
+export class Uint16Vec extends u16 {}
+export class Uint32Vec extends u16 {}
+export class Uint64Vec extends u16 {}
+export class Int16Vec extends u16 {}
+export class Int32Vec extends u16 {}
+export class Int64Vec extends u16 {}
+
+export class TextVec extends Tuple.with([u16, u16]) {
+  static newTypesafe (maxItems: u16 | number, maxTextLength: u16 | number) {
+    return new this([ maxItems, maxTextLength ]);
+  }
+}
+
+export class InternalVec extends Tuple.with([u16, ClassId]) {
+  static newTypesafe (maxItems: u16 | number, classId: ClassId | number) {
+    return new this([ maxItems, classId ]);
+  }
+}
+
+export type PropertyTypeEnum =
+  None |
+
+  // Single values:
+  Bool |
+  Uint16 |
+  Uint32 |
+  Uint64 |
+  Int16 |
+  Int32 |
+  Int64 |
+  Text |
+  Internal |
+
+  // Vectors:
+  BoolVec |
+  Uint16Vec |
+  Uint32Vec |
+  Uint64Vec |
+  Int16Vec |
+  Int32Vec |
+  Int64Vec |
+  TextVec |
+  InternalVec
+;
+
+type PropertyTypeEnumValue = {
+  [typeName: string]: PropertyTypeEnum;
+};
+
+export class PropertyType extends Enum {
+  constructor (value?: PropertyTypeEnumValue, index?: number) {
+    super({
+      None,
+
+      // Single values:
+      Bool,
+      Uint16,
+      Uint32,
+      Uint64,
+      Int16,
+      Int32,
+      Int64,
+      Text,
+      Internal,
+
+      // Vectors:
+      BoolVec,
+      Uint16Vec,
+      Uint32Vec,
+      Uint64Vec,
+      Int16Vec,
+      Int32Vec,
+      Int64Vec,
+      TextVec,
+      InternalVec
+    }, value, index);
+  }
+}
+
+export default PropertyType;

+ 26 - 0
packages/joy-types/src/versioned-store/PropertyTypeName.ts

@@ -0,0 +1,26 @@
+export type PropertyTypeName =
+  'None' |
+  'Bool' |
+  'Uint16' |
+  'Uint32' |
+  'Uint64' |
+  'Int16' |
+  'Int32' |
+  'Int64' |
+  'Text' |
+  'Internal' |
+
+  // Vectors:
+
+  'BoolVec' |
+  'Uint16Vec' |
+  'Uint32Vec' |
+  'Uint64Vec' |
+  'Int16Vec' |
+  'Int32Vec' |
+  'Int64Vec' |
+  'TextVec' |
+  'InternalVec'
+;
+
+export default PropertyTypeName;

+ 92 - 0
packages/joy-types/src/versioned-store/PropertyValue.ts

@@ -0,0 +1,92 @@
+import { Vec as Vector, Text as PolkaText, bool as PolkaBool, Null, u16, u32, u64, i16, i32, i64 } from '@polkadot/types';
+import { Enum } from '@polkadot/types/codec';
+import EntityId from './EntityId';
+
+export class None extends Null {}
+
+// Single values:
+
+export class Bool extends PolkaBool {}
+export class Uint16 extends u16 {}
+export class Uint32 extends u32 {}
+export class Uint64 extends u64 {}
+export class Int16 extends i16 {}
+export class Int32 extends i32 {}
+export class Int64 extends i64 {}
+export class Text extends PolkaText {}
+export class Internal extends EntityId {}
+
+// Vectors:
+
+export class BoolVec extends Vector.with(PolkaBool) {}
+export class Uint16Vec extends Vector.with(u16) {}
+export class Uint32Vec extends Vector.with(u32) {}
+export class Uint64Vec extends Vector.with(u64) {}
+export class Int16Vec extends Vector.with(i16) {}
+export class Int32Vec extends Vector.with(i32) {}
+export class Int64Vec extends Vector.with(i64) {}
+
+export class TextVec extends Vector.with(PolkaText) {}
+export class InternalVec extends Vector.with(EntityId) {}
+
+export type PropertyValueEnum =
+  None |
+
+  // Single values:
+  Bool |
+  Uint16 |
+  Uint32 |
+  Uint64 |
+  Int16 |
+  Int32 |
+  Int64 |
+  Text |
+  Internal |
+
+  // Vectors:
+  BoolVec |
+  Uint16Vec |
+  Uint32Vec |
+  Uint64Vec |
+  Int16Vec |
+  Int32Vec |
+  Int64Vec |
+  TextVec |
+  InternalVec
+;
+
+type PropertyValueEnumValue = {
+  [typeName: string]: PropertyValueEnum;
+};
+
+export class PropertyValue extends Enum {
+  constructor (value?: PropertyValueEnumValue, index?: number) {
+    super({
+      None,
+
+      // Single values:
+      Bool,
+      Uint16,
+      Uint32,
+      Uint64,
+      Int16,
+      Int32,
+      Int64,
+      Text,
+      Internal,
+
+      // Vectors:
+      BoolVec,
+      Uint16Vec,
+      Uint32Vec,
+      Uint64Vec,
+      Int16Vec,
+      Int32Vec,
+      Int64Vec,
+      TextVec,
+      InternalVec
+    }, value, index);
+  }
+}
+
+export default PropertyValue;

+ 207 - 0
packages/joy-types/src/versioned-store/index.ts

@@ -0,0 +1,207 @@
+import { getTypeRegistry, u16, Text, bool as Bool } from '@polkadot/types';
+import { Vec as Vector } from '@polkadot/types/codec';
+import { JoyStruct } from '../JoyStruct';
+import PropertyType from './PropertyType';
+import PropertyValue from './PropertyValue';
+import ClassId from './ClassId';
+import EntityId from './EntityId';
+
+export type InputValidationLengthConstraintType = {
+  min: u16,
+  max_min_diff: u16
+};
+
+export class InputValidationLengthConstraint extends JoyStruct<InputValidationLengthConstraintType> {
+  constructor (value: InputValidationLengthConstraintType) {
+    super({
+      min: u16,
+      max_min_diff: u16
+    }, value);
+  }
+
+  get min (): u16 {
+    return this.getField('min');
+  }
+
+  get max_min_diff (): u16 {
+    return this.getField('max_min_diff');
+  }
+
+  get max (): u16 {
+    return new u16(this.min.add(this.max_min_diff));
+  }
+}
+
+export type PropertyTsType = {
+  prop_type: PropertyType,
+  required: Bool,
+  name: Text,
+  description: Text
+};
+
+export class Property extends JoyStruct<PropertyTsType> {
+  constructor (value: PropertyTsType) {
+    super({
+      prop_type: PropertyType,
+      required: Bool,
+      name: Text,
+      description: Text
+    }, value);
+  }
+
+  get prop_type (): PropertyType {
+    return this.getField('prop_type');
+  }
+
+  get required (): boolean {
+    return this.getBoolean('required');
+  }
+
+  get name (): string {
+    return this.getString('name');
+  }
+
+  get description (): string {
+    return this.getString('description');
+  }
+}
+
+export class VecProperty extends Vector.with(Property) {}
+
+export class VecU16 extends Vector.with(u16) {}
+
+export type ClassSchemaType = {
+  properties: VecU16
+};
+
+export class ClassSchema extends JoyStruct<ClassSchemaType> {
+  constructor (value: ClassSchemaType) {
+    super({
+      properties: VecU16
+    }, value);
+  }
+
+  get properties (): VecU16 {
+    return this.getField('properties');
+  }
+}
+
+export class VecClassSchema extends Vector.with(ClassSchema) {}
+
+export type ClassPropertyValueType = {
+  in_class_index: u16,
+  value: PropertyValue
+};
+
+export class ClassPropertyValue extends JoyStruct<ClassPropertyValueType> {
+  constructor (value: ClassPropertyValueType) {
+    super({
+      in_class_index: u16,
+      value: PropertyValue
+    }, value);
+  }
+
+  get in_class_index (): u16 {
+    return this.getField('in_class_index');
+  }
+
+  get value (): PropertyValue {
+    return this.getField('value');
+  }
+}
+
+export class VecClassPropertyValue extends Vector.with(ClassPropertyValue) {}
+
+export type ClassType = {
+  id: ClassId,
+  properties: VecProperty,
+  schemas: VecClassSchema,
+  name: Text,
+  description: Text
+};
+
+export class Class extends JoyStruct<ClassType> {
+  constructor (value: ClassType) {
+    super({
+      id: ClassId,
+      properties: VecProperty,
+      schemas: VecClassSchema,
+      name: Text,
+      description: Text
+    }, value);
+  }
+
+  get id (): ClassId {
+    return this.getField('id');
+  }
+
+  get properties (): VecProperty {
+    return this.getField('properties');
+  }
+
+  get schemas (): VecClassSchema {
+    return this.getField('schemas');
+  }
+
+  get name (): Text {
+    return this.getField('name');
+  }
+
+  get description (): Text {
+    return this.getField('description');
+  }
+}
+
+export type EntityType = {
+  id: EntityId,
+  class_id: ClassId,
+  in_class_schema_indexes: VecU16,
+  values: VecClassPropertyValue
+};
+
+export class Entity extends JoyStruct<EntityType> {
+  constructor (value: EntityType) {
+    super({
+      id: EntityId,
+      class_id: ClassId,
+      in_class_schema_indexes: VecU16,
+      values: VecClassPropertyValue
+    }, value);
+  }
+
+  get id (): EntityId {
+    return this.getField('id');
+  }
+
+  get class_id (): ClassId {
+    return this.getField('class_id');
+  }
+
+  get in_class_schema_indexes (): VecU16 {
+    return this.getField('in_class_schema_indexes');
+  }
+
+  /** NOTE: rename to `entity_values` because `values` is already in use. */
+  get entity_values (): VecClassPropertyValue {
+    return this.getField('values');
+  }
+}
+
+export function registerVersionedStoreTypes () {
+  try {
+    getTypeRegistry().register({
+      InputValidationLengthConstraint,
+      ClassId,
+      EntityId,
+      Class,
+      Entity,
+      ClassSchema,
+      Property,
+      PropertyType,
+      PropertyValue,
+      ClassPropertyValue
+    });
+  } catch (err) {
+    console.error('Failed to register custom types of versioned store module', err);
+  }
+}

+ 1 - 1
packages/joy-types/tsconfig.json

@@ -14,6 +14,6 @@
     "outDir": "lib"
   },
   "include": [
-    "src/*.ts"
+    "src/**/*.ts"
   ]
 }