Browse Source

query node - predictable ids III

ondratra 3 years ago
parent
commit
95bbe0e958

+ 80 - 78
query-node/generated/graphql-server/generated/binding.ts

@@ -12,9 +12,6 @@ export interface Query {
     dataObjects: <T = Array<DataObject>>(args: { offset?: Int | null, limit?: Int | null, where?: DataObjectWhereInput | null, orderBy?: DataObjectOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     dataObjectByUniqueInput: <T = DataObject | null>(args: { where: DataObjectWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T | null> ,
     dataObjectsConnection: <T = DataObjectConnection>(args: { first?: Int | null, after?: String | null, last?: Int | null, before?: String | null, where?: DataObjectWhereInput | null, orderBy?: DataObjectOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
-    featuredVideos: <T = Array<FeaturedVideo>>(args: { offset?: Int | null, limit?: Int | null, where?: FeaturedVideoWhereInput | null, orderBy?: FeaturedVideoOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
-    featuredVideoByUniqueInput: <T = FeaturedVideo | null>(args: { where: FeaturedVideoWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T | null> ,
-    featuredVideosConnection: <T = FeaturedVideoConnection>(args: { first?: Int | null, after?: String | null, last?: Int | null, before?: String | null, where?: FeaturedVideoWhereInput | null, orderBy?: FeaturedVideoOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     channelCategories: <T = Array<ChannelCategory>>(args: { offset?: Int | null, limit?: Int | null, where?: ChannelCategoryWhereInput | null, orderBy?: ChannelCategoryOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     channelCategoryByUniqueInput: <T = ChannelCategory | null>(args: { where: ChannelCategoryWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T | null> ,
     channelCategoriesConnection: <T = ChannelCategoryConnection>(args: { first?: Int | null, after?: String | null, last?: Int | null, before?: String | null, where?: ChannelCategoryWhereInput | null, orderBy?: ChannelCategoryOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
@@ -30,6 +27,9 @@ export interface Query {
     memberships: <T = Array<Membership>>(args: { offset?: Int | null, limit?: Int | null, where?: MembershipWhereInput | null, orderBy?: MembershipOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     membershipByUniqueInput: <T = Membership | null>(args: { where: MembershipWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T | null> ,
     membershipsConnection: <T = MembershipConnection>(args: { first?: Int | null, after?: String | null, last?: Int | null, before?: String | null, where?: MembershipWhereInput | null, orderBy?: MembershipOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
+    nextEntityIds: <T = Array<NextEntityId>>(args: { offset?: Int | null, limit?: Int | null, where?: NextEntityIdWhereInput | null, orderBy?: NextEntityIdOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
+    nextEntityIdByUniqueInput: <T = NextEntityId | null>(args: { where: NextEntityIdWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T | null> ,
+    nextEntityIdsConnection: <T = NextEntityIdConnection>(args: { first?: Int | null, after?: String | null, last?: Int | null, before?: String | null, where?: NextEntityIdWhereInput | null, orderBy?: NextEntityIdOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     channelCategoriesByName: <T = Array<ChannelCategoriesByNameFTSOutput>>(args: { whereChannelCategory?: ChannelCategoryWhereInput | null, skip?: Int | null, limit?: Int | null, text: String }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     membersByHandle: <T = Array<MembersByHandleFTSOutput>>(args: { whereMembership?: MembershipWhereInput | null, skip?: Int | null, limit?: Int | null, text: String }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
     search: <T = Array<SearchFTSOutput>>(args: { whereVideo?: VideoWhereInput | null, whereChannel?: ChannelWhereInput | null, skip?: Int | null, limit?: Int | null, text: String }, info?: GraphQLResolveInfo | string, options?: Options) => Promise<T> ,
@@ -115,15 +115,6 @@ export type DataObjectOrderByInput =   'createdAt_ASC' |
   'joystreamContentId_ASC' |
   'joystreamContentId_DESC'
 
-export type FeaturedVideoOrderByInput =   'createdAt_ASC' |
-  'createdAt_DESC' |
-  'updatedAt_ASC' |
-  'updatedAt_DESC' |
-  'deletedAt_ASC' |
-  'deletedAt_DESC' |
-  'videoId_ASC' |
-  'videoId_DESC'
-
 export type ChannelCategoryOrderByInput =   'createdAt_ASC' |
   'createdAt_DESC' |
   'updatedAt_ASC' |
@@ -224,6 +215,15 @@ export type MembershipOrderByInput =   'createdAt_ASC' |
   'subscription_ASC' |
   'subscription_DESC'
 
+export type NextEntityIdOrderByInput =   'createdAt_ASC' |
+  'createdAt_DESC' |
+  'updatedAt_ASC' |
+  'updatedAt_DESC' |
+  'deletedAt_ASC' |
+  'deletedAt_DESC' |
+  'nextId_ASC' |
+  'nextId_DESC'
+
 export type VideoCategoryOrderByInput =   'createdAt_ASC' |
   'createdAt_DESC' |
   'updatedAt_ASC' |
@@ -722,47 +722,6 @@ export interface DataObjectWhereUniqueInput {
   id: ID_Output
 }
 
-export interface FeaturedVideoCreateInput {
-  videoId: ID_Output
-}
-
-export interface FeaturedVideoUpdateInput {
-  videoId?: ID_Input | null
-}
-
-export interface FeaturedVideoWhereInput {
-  id_eq?: ID_Input | null
-  id_in?: ID_Output[] | ID_Output | null
-  createdAt_eq?: DateTime | null
-  createdAt_lt?: DateTime | null
-  createdAt_lte?: DateTime | null
-  createdAt_gt?: DateTime | null
-  createdAt_gte?: DateTime | null
-  createdById_eq?: ID_Input | null
-  createdById_in?: ID_Output[] | ID_Output | null
-  updatedAt_eq?: DateTime | null
-  updatedAt_lt?: DateTime | null
-  updatedAt_lte?: DateTime | null
-  updatedAt_gt?: DateTime | null
-  updatedAt_gte?: DateTime | null
-  updatedById_eq?: ID_Input | null
-  updatedById_in?: ID_Output[] | ID_Output | null
-  deletedAt_all?: Boolean | null
-  deletedAt_eq?: DateTime | null
-  deletedAt_lt?: DateTime | null
-  deletedAt_lte?: DateTime | null
-  deletedAt_gt?: DateTime | null
-  deletedAt_gte?: DateTime | null
-  deletedById_eq?: ID_Input | null
-  deletedById_in?: ID_Output[] | ID_Output | null
-  videoId_eq?: ID_Input | null
-  videoId_in?: ID_Output[] | ID_Output | null
-}
-
-export interface FeaturedVideoWhereUniqueInput {
-  id: ID_Output
-}
-
 export interface ChannelCategoryCreateInput {
   name?: String | null
   createdInBlock: Float
@@ -1129,6 +1088,51 @@ export interface MembershipWhereUniqueInput {
   handle?: String | null
 }
 
+export interface NextEntityIdCreateInput {
+  nextId: Float
+}
+
+export interface NextEntityIdUpdateInput {
+  nextId?: Float | null
+}
+
+export interface NextEntityIdWhereInput {
+  id_eq?: ID_Input | null
+  id_in?: ID_Output[] | ID_Output | null
+  createdAt_eq?: DateTime | null
+  createdAt_lt?: DateTime | null
+  createdAt_lte?: DateTime | null
+  createdAt_gt?: DateTime | null
+  createdAt_gte?: DateTime | null
+  createdById_eq?: ID_Input | null
+  createdById_in?: ID_Output[] | ID_Output | null
+  updatedAt_eq?: DateTime | null
+  updatedAt_lt?: DateTime | null
+  updatedAt_lte?: DateTime | null
+  updatedAt_gt?: DateTime | null
+  updatedAt_gte?: DateTime | null
+  updatedById_eq?: ID_Input | null
+  updatedById_in?: ID_Output[] | ID_Output | null
+  deletedAt_all?: Boolean | null
+  deletedAt_eq?: DateTime | null
+  deletedAt_lt?: DateTime | null
+  deletedAt_lte?: DateTime | null
+  deletedAt_gt?: DateTime | null
+  deletedAt_gte?: DateTime | null
+  deletedById_eq?: ID_Input | null
+  deletedById_in?: ID_Output[] | ID_Output | null
+  nextId_eq?: Float | null
+  nextId_gt?: Float | null
+  nextId_gte?: Float | null
+  nextId_lt?: Float | null
+  nextId_lte?: Float | null
+  nextId_in?: Float[] | Float | null
+}
+
+export interface NextEntityIdWhereUniqueInput {
+  id: ID_Output
+}
+
 export interface VideoCategoryCreateInput {
   name?: String | null
   createdInBlock: Float
@@ -1628,30 +1632,6 @@ export interface DataObjectOwnerWorkingGroup {
   workingGroup: Int
 }
 
-export interface FeaturedVideo extends BaseGraphQLObject {
-  id: ID_Output
-  createdAt: DateTime
-  createdById: String
-  updatedAt?: DateTime | null
-  updatedById?: String | null
-  deletedAt?: DateTime | null
-  deletedById?: String | null
-  version: Int
-  video: Video
-  videoId: String
-}
-
-export interface FeaturedVideoConnection {
-  totalCount: Int
-  edges: Array<FeaturedVideoEdge>
-  pageInfo: PageInfo
-}
-
-export interface FeaturedVideoEdge {
-  node: FeaturedVideo
-  cursor: String
-}
-
 export interface Channel extends BaseGraphQLObject {
   id: ID_Output
   createdAt: DateTime
@@ -1827,6 +1807,29 @@ export interface MembershipEdge {
   cursor: String
 }
 
+export interface NextEntityId extends BaseGraphQLObject {
+  id: ID_Output
+  createdAt: DateTime
+  createdById: String
+  updatedAt?: DateTime | null
+  updatedById?: String | null
+  deletedAt?: DateTime | null
+  deletedById?: String | null
+  version: Int
+  nextId: Float
+}
+
+export interface NextEntityIdConnection {
+  totalCount: Int
+  edges: Array<NextEntityIdEdge>
+  pageInfo: PageInfo
+}
+
+export interface NextEntityIdEdge {
+  node: NextEntityId
+  cursor: String
+}
+
 export interface PageInfo {
   hasNextPage: Boolean
   hasPreviousPage: Boolean
@@ -1889,7 +1892,6 @@ export interface Video extends BaseGraphQLObject {
   mediaMetadataId?: String | null
   createdInBlock: Int
   isFeatured: Boolean
-  featured?: FeaturedVideo | null
 }
 
 export interface VideoCategoriesByNameFTSOutput {

+ 152 - 140
query-node/generated/graphql-server/generated/classes.ts

@@ -43,8 +43,6 @@ import { VideoMediaEncoding } from "../src/modules/video-media-encoding/video-me
 // @ts-ignore
 import { VideoMediaMetadata } from "../src/modules/video-media-metadata/video-media-metadata.model";
 // @ts-ignore
-import { FeaturedVideo } from "../src/modules/featured-video/featured-video.model";
-// @ts-ignore
 import { Video } from "../src/modules/video/video.model";
 // @ts-ignore
 import { Language } from "../src/modules/language/language.model";
@@ -54,6 +52,8 @@ import { Channel } from "../src/modules/channel/channel.model";
 import { DataObject } from "../src/modules/data-object/data-object.model";
 // @ts-ignore
 import { Worker } from "../src/modules/worker/worker.model";
+// @ts-ignore
+import { NextEntityId } from "../src/modules/next-entity-id/next-entity-id.model";
 
 export enum DataObjectOwnerChannelOrderByEnum {
   createdAt_ASC = "createdAt_ASC",
@@ -2309,144 +2309,6 @@ export class VideoMediaMetadataUpdateArgs {
   @TypeGraphQLField() where!: VideoMediaMetadataWhereUniqueInput;
 }
 
-export enum FeaturedVideoOrderByEnum {
-  createdAt_ASC = "createdAt_ASC",
-  createdAt_DESC = "createdAt_DESC",
-
-  updatedAt_ASC = "updatedAt_ASC",
-  updatedAt_DESC = "updatedAt_DESC",
-
-  deletedAt_ASC = "deletedAt_ASC",
-  deletedAt_DESC = "deletedAt_DESC",
-
-  videoId_ASC = "videoId_ASC",
-  videoId_DESC = "videoId_DESC"
-}
-
-registerEnumType(FeaturedVideoOrderByEnum, {
-  name: "FeaturedVideoOrderByInput"
-});
-
-@TypeGraphQLInputType()
-export class FeaturedVideoWhereInput {
-  @TypeGraphQLField(() => ID, { nullable: true })
-  id_eq?: string;
-
-  @TypeGraphQLField(() => [ID], { nullable: true })
-  id_in?: string[];
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  createdAt_eq?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  createdAt_lt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  createdAt_lte?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  createdAt_gt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  createdAt_gte?: Date;
-
-  @TypeGraphQLField(() => ID, { nullable: true })
-  createdById_eq?: string;
-
-  @TypeGraphQLField(() => [ID], { nullable: true })
-  createdById_in?: string[];
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  updatedAt_eq?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  updatedAt_lt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  updatedAt_lte?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  updatedAt_gt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  updatedAt_gte?: Date;
-
-  @TypeGraphQLField(() => ID, { nullable: true })
-  updatedById_eq?: string;
-
-  @TypeGraphQLField(() => [ID], { nullable: true })
-  updatedById_in?: string[];
-
-  @TypeGraphQLField({ nullable: true })
-  deletedAt_all?: Boolean;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  deletedAt_eq?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  deletedAt_lt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  deletedAt_lte?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  deletedAt_gt?: Date;
-
-  @TypeGraphQLField(() => DateTime, { nullable: true })
-  deletedAt_gte?: Date;
-
-  @TypeGraphQLField(() => ID, { nullable: true })
-  deletedById_eq?: string;
-
-  @TypeGraphQLField(() => [ID], { nullable: true })
-  deletedById_in?: string[];
-
-  @TypeGraphQLField(() => ID, { nullable: true })
-  videoId_eq?: string;
-
-  @TypeGraphQLField(() => [ID], { nullable: true })
-  videoId_in?: string[];
-}
-
-@TypeGraphQLInputType()
-export class FeaturedVideoWhereUniqueInput {
-  @TypeGraphQLField(() => ID)
-  id?: string;
-}
-
-@TypeGraphQLInputType()
-export class FeaturedVideoCreateInput {
-  @TypeGraphQLField(() => ID)
-  videoId!: string;
-}
-
-@TypeGraphQLInputType()
-export class FeaturedVideoUpdateInput {
-  @TypeGraphQLField(() => ID, { nullable: true })
-  videoId?: string;
-}
-
-@ArgsType()
-export class FeaturedVideoWhereArgs extends PaginationArgs {
-  @TypeGraphQLField(() => FeaturedVideoWhereInput, { nullable: true })
-  where?: FeaturedVideoWhereInput;
-
-  @TypeGraphQLField(() => FeaturedVideoOrderByEnum, { nullable: true })
-  orderBy?: FeaturedVideoOrderByEnum;
-}
-
-@ArgsType()
-export class FeaturedVideoCreateManyArgs {
-  @TypeGraphQLField(() => [FeaturedVideoCreateInput])
-  data!: FeaturedVideoCreateInput[];
-}
-
-@ArgsType()
-export class FeaturedVideoUpdateArgs {
-  @TypeGraphQLField() data!: FeaturedVideoUpdateInput;
-  @TypeGraphQLField() where!: FeaturedVideoWhereUniqueInput;
-}
-
 export enum VideoOrderByEnum {
   createdAt_ASC = "createdAt_ASC",
   createdAt_DESC = "createdAt_DESC",
@@ -3967,3 +3829,153 @@ export class WorkerUpdateArgs {
   @TypeGraphQLField() data!: WorkerUpdateInput;
   @TypeGraphQLField() where!: WorkerWhereUniqueInput;
 }
+
+export enum NextEntityIdOrderByEnum {
+  createdAt_ASC = "createdAt_ASC",
+  createdAt_DESC = "createdAt_DESC",
+
+  updatedAt_ASC = "updatedAt_ASC",
+  updatedAt_DESC = "updatedAt_DESC",
+
+  deletedAt_ASC = "deletedAt_ASC",
+  deletedAt_DESC = "deletedAt_DESC",
+
+  nextId_ASC = "nextId_ASC",
+  nextId_DESC = "nextId_DESC"
+}
+
+registerEnumType(NextEntityIdOrderByEnum, {
+  name: "NextEntityIdOrderByInput"
+});
+
+@TypeGraphQLInputType()
+export class NextEntityIdWhereInput {
+  @TypeGraphQLField(() => ID, { nullable: true })
+  id_eq?: string;
+
+  @TypeGraphQLField(() => [ID], { nullable: true })
+  id_in?: string[];
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  createdAt_eq?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  createdAt_lt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  createdAt_lte?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  createdAt_gt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  createdAt_gte?: Date;
+
+  @TypeGraphQLField(() => ID, { nullable: true })
+  createdById_eq?: string;
+
+  @TypeGraphQLField(() => [ID], { nullable: true })
+  createdById_in?: string[];
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  updatedAt_eq?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  updatedAt_lt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  updatedAt_lte?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  updatedAt_gt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  updatedAt_gte?: Date;
+
+  @TypeGraphQLField(() => ID, { nullable: true })
+  updatedById_eq?: string;
+
+  @TypeGraphQLField(() => [ID], { nullable: true })
+  updatedById_in?: string[];
+
+  @TypeGraphQLField({ nullable: true })
+  deletedAt_all?: Boolean;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  deletedAt_eq?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  deletedAt_lt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  deletedAt_lte?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  deletedAt_gt?: Date;
+
+  @TypeGraphQLField(() => DateTime, { nullable: true })
+  deletedAt_gte?: Date;
+
+  @TypeGraphQLField(() => ID, { nullable: true })
+  deletedById_eq?: string;
+
+  @TypeGraphQLField(() => [ID], { nullable: true })
+  deletedById_in?: string[];
+
+  @TypeGraphQLField(() => Float, { nullable: true })
+  nextId_eq?: number;
+
+  @TypeGraphQLField(() => Float, { nullable: true })
+  nextId_gt?: number;
+
+  @TypeGraphQLField(() => Float, { nullable: true })
+  nextId_gte?: number;
+
+  @TypeGraphQLField(() => Float, { nullable: true })
+  nextId_lt?: number;
+
+  @TypeGraphQLField(() => Float, { nullable: true })
+  nextId_lte?: number;
+
+  @TypeGraphQLField(() => [Float], { nullable: true })
+  nextId_in?: number[];
+}
+
+@TypeGraphQLInputType()
+export class NextEntityIdWhereUniqueInput {
+  @TypeGraphQLField(() => ID)
+  id?: string;
+}
+
+@TypeGraphQLInputType()
+export class NextEntityIdCreateInput {
+  @TypeGraphQLField()
+  nextId!: number;
+}
+
+@TypeGraphQLInputType()
+export class NextEntityIdUpdateInput {
+  @TypeGraphQLField({ nullable: true })
+  nextId?: number;
+}
+
+@ArgsType()
+export class NextEntityIdWhereArgs extends PaginationArgs {
+  @TypeGraphQLField(() => NextEntityIdWhereInput, { nullable: true })
+  where?: NextEntityIdWhereInput;
+
+  @TypeGraphQLField(() => NextEntityIdOrderByEnum, { nullable: true })
+  orderBy?: NextEntityIdOrderByEnum;
+}
+
+@ArgsType()
+export class NextEntityIdCreateManyArgs {
+  @TypeGraphQLField(() => [NextEntityIdCreateInput])
+  data!: NextEntityIdCreateInput[];
+}
+
+@ArgsType()
+export class NextEntityIdUpdateArgs {
+  @TypeGraphQLField() data!: NextEntityIdUpdateInput;
+  @TypeGraphQLField() where!: NextEntityIdWhereUniqueInput;
+}

+ 84 - 80
query-node/generated/graphql-server/generated/schema.graphql

@@ -586,82 +586,6 @@ interface DeleteResponse {
   id: ID!
 }
 
-type FeaturedVideo implements BaseGraphQLObject {
-  id: ID!
-  createdAt: DateTime!
-  createdById: String!
-  updatedAt: DateTime
-  updatedById: String
-  deletedAt: DateTime
-  deletedById: String
-  version: Int!
-  video: Video!
-  videoId: String!
-}
-
-type FeaturedVideoConnection {
-  totalCount: Int!
-  edges: [FeaturedVideoEdge!]!
-  pageInfo: PageInfo!
-}
-
-input FeaturedVideoCreateInput {
-  videoId: ID!
-}
-
-type FeaturedVideoEdge {
-  node: FeaturedVideo!
-  cursor: String!
-}
-
-enum FeaturedVideoOrderByInput {
-  createdAt_ASC
-  createdAt_DESC
-  updatedAt_ASC
-  updatedAt_DESC
-  deletedAt_ASC
-  deletedAt_DESC
-  videoId_ASC
-  videoId_DESC
-}
-
-input FeaturedVideoUpdateInput {
-  videoId: ID
-}
-
-input FeaturedVideoWhereInput {
-  id_eq: ID
-  id_in: [ID!]
-  createdAt_eq: DateTime
-  createdAt_lt: DateTime
-  createdAt_lte: DateTime
-  createdAt_gt: DateTime
-  createdAt_gte: DateTime
-  createdById_eq: ID
-  createdById_in: [ID!]
-  updatedAt_eq: DateTime
-  updatedAt_lt: DateTime
-  updatedAt_lte: DateTime
-  updatedAt_gt: DateTime
-  updatedAt_gte: DateTime
-  updatedById_eq: ID
-  updatedById_in: [ID!]
-  deletedAt_all: Boolean
-  deletedAt_eq: DateTime
-  deletedAt_lt: DateTime
-  deletedAt_lte: DateTime
-  deletedAt_gt: DateTime
-  deletedAt_gte: DateTime
-  deletedById_eq: ID
-  deletedById_in: [ID!]
-  videoId_eq: ID
-  videoId_in: [ID!]
-}
-
-input FeaturedVideoWhereUniqueInput {
-  id: ID!
-}
-
 type Channel implements BaseGraphQLObject {
   id: ID!
   createdAt: DateTime!
@@ -1364,6 +1288,87 @@ input MembershipWhereUniqueInput {
   handle: String
 }
 
+type NextEntityId implements BaseGraphQLObject {
+  id: ID!
+  createdAt: DateTime!
+  createdById: String!
+  updatedAt: DateTime
+  updatedById: String
+  deletedAt: DateTime
+  deletedById: String
+  version: Int!
+
+  """Next deterministic id for entities without custom id"""
+  nextId: Float!
+}
+
+type NextEntityIdConnection {
+  totalCount: Int!
+  edges: [NextEntityIdEdge!]!
+  pageInfo: PageInfo!
+}
+
+input NextEntityIdCreateInput {
+  nextId: Float!
+}
+
+type NextEntityIdEdge {
+  node: NextEntityId!
+  cursor: String!
+}
+
+enum NextEntityIdOrderByInput {
+  createdAt_ASC
+  createdAt_DESC
+  updatedAt_ASC
+  updatedAt_DESC
+  deletedAt_ASC
+  deletedAt_DESC
+  nextId_ASC
+  nextId_DESC
+}
+
+input NextEntityIdUpdateInput {
+  nextId: Float
+}
+
+input NextEntityIdWhereInput {
+  id_eq: ID
+  id_in: [ID!]
+  createdAt_eq: DateTime
+  createdAt_lt: DateTime
+  createdAt_lte: DateTime
+  createdAt_gt: DateTime
+  createdAt_gte: DateTime
+  createdById_eq: ID
+  createdById_in: [ID!]
+  updatedAt_eq: DateTime
+  updatedAt_lt: DateTime
+  updatedAt_lte: DateTime
+  updatedAt_gt: DateTime
+  updatedAt_gte: DateTime
+  updatedById_eq: ID
+  updatedById_in: [ID!]
+  deletedAt_all: Boolean
+  deletedAt_eq: DateTime
+  deletedAt_lt: DateTime
+  deletedAt_lte: DateTime
+  deletedAt_gt: DateTime
+  deletedAt_gte: DateTime
+  deletedById_eq: ID
+  deletedById_in: [ID!]
+  nextId_eq: Float
+  nextId_gt: Float
+  nextId_gte: Float
+  nextId_lt: Float
+  nextId_lte: Float
+  nextId_in: [Float!]
+}
+
+input NextEntityIdWhereUniqueInput {
+  id: ID!
+}
+
 type PageInfo {
   hasNextPage: Boolean!
   hasPreviousPage: Boolean!
@@ -1385,9 +1390,6 @@ type Query {
   dataObjects(offset: Int, limit: Int = 50, where: DataObjectWhereInput, orderBy: DataObjectOrderByInput): [DataObject!]!
   dataObjectByUniqueInput(where: DataObjectWhereUniqueInput!): DataObject
   dataObjectsConnection(first: Int, after: String, last: Int, before: String, where: DataObjectWhereInput, orderBy: DataObjectOrderByInput): DataObjectConnection!
-  featuredVideos(offset: Int, limit: Int = 50, where: FeaturedVideoWhereInput, orderBy: FeaturedVideoOrderByInput): [FeaturedVideo!]!
-  featuredVideoByUniqueInput(where: FeaturedVideoWhereUniqueInput!): FeaturedVideo
-  featuredVideosConnection(first: Int, after: String, last: Int, before: String, where: FeaturedVideoWhereInput, orderBy: FeaturedVideoOrderByInput): FeaturedVideoConnection!
   channelCategories(offset: Int, limit: Int = 50, where: ChannelCategoryWhereInput, orderBy: ChannelCategoryOrderByInput): [ChannelCategory!]!
   channelCategoryByUniqueInput(where: ChannelCategoryWhereUniqueInput!): ChannelCategory
   channelCategoriesConnection(first: Int, after: String, last: Int, before: String, where: ChannelCategoryWhereInput, orderBy: ChannelCategoryOrderByInput): ChannelCategoryConnection!
@@ -1403,6 +1405,9 @@ type Query {
   memberships(offset: Int, limit: Int = 50, where: MembershipWhereInput, orderBy: MembershipOrderByInput): [Membership!]!
   membershipByUniqueInput(where: MembershipWhereUniqueInput!): Membership
   membershipsConnection(first: Int, after: String, last: Int, before: String, where: MembershipWhereInput, orderBy: MembershipOrderByInput): MembershipConnection!
+  nextEntityIds(offset: Int, limit: Int = 50, where: NextEntityIdWhereInput, orderBy: NextEntityIdOrderByInput): [NextEntityId!]!
+  nextEntityIdByUniqueInput(where: NextEntityIdWhereUniqueInput!): NextEntityId
+  nextEntityIdsConnection(first: Int, after: String, last: Int, before: String, where: NextEntityIdWhereInput, orderBy: NextEntityIdOrderByInput): NextEntityIdConnection!
   channelCategoriesByName(whereChannelCategory: ChannelCategoryWhereInput, skip: Int = 0, limit: Int = 5, text: String!): [ChannelCategoriesByNameFTSOutput!]!
   membersByHandle(whereMembership: MembershipWhereInput, skip: Int = 0, limit: Int = 5, text: String!): [MembersByHandleFTSOutput!]!
   search(whereVideo: VideoWhereInput, whereChannel: ChannelWhereInput, skip: Int = 0, limit: Int = 5, text: String!): [SearchFTSOutput!]!
@@ -1506,7 +1511,6 @@ type Video implements BaseGraphQLObject {
 
   """Is video featured or not"""
   isFeatured: Boolean!
-  featured: FeaturedVideo
 }
 
 type VideoCategoriesByNameFTSOutput {

+ 2 - 0
query-node/generated/graphql-server/model/index.ts

@@ -12,6 +12,8 @@ import { License } from '../src/modules/license/license.model';
 export { License };
 import { Membership } from '../src/modules/membership/membership.model';
 export { Membership };
+import { NextEntityId } from '../src/modules/next-entity-id/next-entity-id.model';
+export { NextEntityId };
 import { Video } from '../src/modules/video/video.model';
 export { Video };
 import { VideoCategory } from '../src/modules/video-category/video-category.model';

+ 14 - 0
query-node/generated/graphql-server/src/modules/next-entity-id/next-entity-id.model.ts

@@ -0,0 +1,14 @@
+import { BaseModel, FloatField, Model, StringField } from 'warthog';
+
+@Model({ api: {} })
+export class NextEntityId extends BaseModel {
+  @FloatField({
+    description: `Next deterministic id for entities without custom id`,
+  })
+  nextId!: number;
+
+  constructor(init?: Partial<NextEntityId>) {
+    super();
+    Object.assign(this, init);
+  }
+}

+ 128 - 0
query-node/generated/graphql-server/src/modules/next-entity-id/next-entity-id.resolver.ts

@@ -0,0 +1,128 @@
+import {
+  Arg,
+  Args,
+  Mutation,
+  Query,
+  Root,
+  Resolver,
+  FieldResolver,
+  ObjectType,
+  Field,
+  Int,
+  ArgsType,
+  Info,
+} from 'type-graphql';
+import graphqlFields from 'graphql-fields';
+import { Inject } from 'typedi';
+import { Min } from 'class-validator';
+import { Fields, StandardDeleteResponse, UserId, PageInfo, RawFields } from 'warthog';
+
+import {
+  NextEntityIdCreateInput,
+  NextEntityIdCreateManyArgs,
+  NextEntityIdUpdateArgs,
+  NextEntityIdWhereArgs,
+  NextEntityIdWhereInput,
+  NextEntityIdWhereUniqueInput,
+  NextEntityIdOrderByEnum,
+} from '../../../generated';
+
+import { NextEntityId } from './next-entity-id.model';
+import { NextEntityIdService } from './next-entity-id.service';
+
+@ObjectType()
+export class NextEntityIdEdge {
+  @Field(() => NextEntityId, { nullable: false })
+  node!: NextEntityId;
+
+  @Field(() => String, { nullable: false })
+  cursor!: string;
+}
+
+@ObjectType()
+export class NextEntityIdConnection {
+  @Field(() => Int, { nullable: false })
+  totalCount!: number;
+
+  @Field(() => [NextEntityIdEdge], { nullable: false })
+  edges!: NextEntityIdEdge[];
+
+  @Field(() => PageInfo, { nullable: false })
+  pageInfo!: PageInfo;
+}
+
+@ArgsType()
+export class ConnectionPageInputOptions {
+  @Field(() => Int, { nullable: true })
+  @Min(0)
+  first?: number;
+
+  @Field(() => String, { nullable: true })
+  after?: string; // V3: TODO: should we make a RelayCursor scalar?
+
+  @Field(() => Int, { nullable: true })
+  @Min(0)
+  last?: number;
+
+  @Field(() => String, { nullable: true })
+  before?: string;
+}
+
+@ArgsType()
+export class NextEntityIdConnectionWhereArgs extends ConnectionPageInputOptions {
+  @Field(() => NextEntityIdWhereInput, { nullable: true })
+  where?: NextEntityIdWhereInput;
+
+  @Field(() => NextEntityIdOrderByEnum, { nullable: true })
+  orderBy?: NextEntityIdOrderByEnum;
+}
+
+@Resolver(NextEntityId)
+export class NextEntityIdResolver {
+  constructor(@Inject('NextEntityIdService') public readonly service: NextEntityIdService) {}
+
+  @Query(() => [NextEntityId])
+  async nextEntityIds(
+    @Args() { where, orderBy, limit, offset }: NextEntityIdWhereArgs,
+    @Fields() fields: string[]
+  ): Promise<NextEntityId[]> {
+    return this.service.find<NextEntityIdWhereInput>(where, orderBy, limit, offset, fields);
+  }
+
+  @Query(() => NextEntityId, { nullable: true })
+  async nextEntityIdByUniqueInput(
+    @Arg('where') where: NextEntityIdWhereUniqueInput,
+    @Fields() fields: string[]
+  ): Promise<NextEntityId | null> {
+    const result = await this.service.find(where, undefined, 1, 0, fields);
+    return result && result.length >= 1 ? result[0] : null;
+  }
+
+  @Query(() => NextEntityIdConnection)
+  async nextEntityIdsConnection(
+    @Args() { where, orderBy, ...pageOptions }: NextEntityIdConnectionWhereArgs,
+    @Info() info: any
+  ): Promise<NextEntityIdConnection> {
+    const rawFields = graphqlFields(info, {}, { excludedFields: ['__typename'] });
+
+    let result: any = {
+      totalCount: 0,
+      edges: [],
+      pageInfo: {
+        hasNextPage: false,
+        hasPreviousPage: false,
+      },
+    };
+    // If the related database table does not have any records then an error is thrown to the client
+    // by warthog
+    try {
+      result = await this.service.findConnection<NextEntityIdWhereInput>(where, orderBy, pageOptions, rawFields);
+    } catch (err) {
+      console.log(err);
+      // TODO: should continue to return this on `Error: Items is empty` or throw the error
+      if (!(err.message as string).includes('Items is empty')) throw err;
+    }
+
+    return result as Promise<NextEntityIdConnection>;
+  }
+}

+ 28 - 0
query-node/generated/graphql-server/src/modules/next-entity-id/next-entity-id.service.ts

@@ -0,0 +1,28 @@
+import { Service } from 'typedi';
+import { Repository } from 'typeorm';
+import { InjectRepository } from 'typeorm-typedi-extensions';
+import { BaseService, WhereInput } from 'warthog';
+
+import { NextEntityId } from './next-entity-id.model';
+
+@Service('NextEntityIdService')
+export class NextEntityIdService extends BaseService<NextEntityId> {
+  constructor(@InjectRepository(NextEntityId) protected readonly repository: Repository<NextEntityId>) {
+    super(NextEntityId, repository);
+  }
+
+  async find<W extends WhereInput>(
+    where?: any,
+    orderBy?: string,
+    limit?: number,
+    offset?: number,
+    fields?: string[]
+  ): Promise<NextEntityId[]> {
+    let f = fields;
+    if (f == undefined) {
+      f = [];
+    }
+
+    return super.find<W>(where, orderBy, limit, offset, f);
+  }
+}

+ 15 - 12
query-node/mappings/src/common.ts

@@ -1,7 +1,6 @@
 import { SubstrateEvent } from '@dzlzv/hydra-common'
 import { DatabaseManager } from '@dzlzv/hydra-db-utils'
 import { u64 } from '@polkadot/types/primitive';
-import * as crypto from 'crypto'
 import { SubstrateExtrinsic, ExtrinsicArg } from '@dzlzv/hydra-common'
 
 // Asset
@@ -10,6 +9,7 @@ import {
   DataObject,
   LiaisonJudgement,
   Network,
+  NextEntityId,
 } from 'query-node'
 import {
   ContentParameters,
@@ -45,23 +45,27 @@ export function invalidMetadata(extraInfo: string, data?: unknown): void {
 /*
   Creates a predictable and unique ID for the given content.
 */
-export function createPredictableId(event: SubstrateEvent, content: string | Object): string {
-  const contentType = typeof content == 'string'
-    ? content
-    : JSON.stringify(content)
+export async function createPredictableId(db: DatabaseManager): Promise<string> {
+  // load or create record
+  const existingRecord = await db.get(NextEntityId, {}) || new NextEntityId({id: '0', nextId: 0})
 
-  const id = `${event.blockNumber}_${event.index}_${contentType}`
+  // remember id
+  const entityId = existingRecord.nextId
 
-  return crypto
-    .createHash('sha256')
-    .update(id, 'utf-8')
-    .digest('base64')
+  // increment id
+  existingRecord.nextId = existingRecord.nextId + 1
+
+  // save record
+  await db.save<NextEntityId>(existingRecord)
+
+  return entityId.toString()
 }
 
 /*
   Prepares data object from content parameters.
 */
 export async function prepareDataObject(
+  db: DatabaseManager,
   contentParameters: ContentParameters,
   event: SubstrateEvent,
   owner: typeof DataObjectOwner,
@@ -70,6 +74,7 @@ export async function prepareDataObject(
   const customContentParameters = new Custom_ContentParameters(registry, contentParameters.toJSON() as any)
 
   const dataObject = new DataObject({
+    id: await createPredictableId(db),
     owner,
     createdInBlock: event.blockNumber,
     typeId: contentParameters.type_id.toNumber(),
@@ -82,8 +87,6 @@ export async function prepareDataObject(
     updatedById: '1',
   })
 
-  dataObject.id = createPredictableId(event, dataObject)
-
   return dataObject
 }
 

+ 5 - 5
query-node/mappings/src/content/utils.ts

@@ -313,7 +313,7 @@ export async function readProtobufWithAssets<T extends Channel | Video>(
 
     // prepare license if needed
     if ('license' in metaAsObject) {
-      result.license = await prepareLicense(metaAsObject.license, parameters.event)
+      result.license = await prepareLicense(parameters.db, metaAsObject.license, parameters.event)
     }
 
     // prepare thumbnail photo asset if needed
@@ -479,6 +479,7 @@ async function convertAsset(parameters: IConvertAssetParameters): Promise<AssetS
   // prepare data object
   const contentParameters: ContentParameters = parameters.rawAsset.asUpload
   const dataObject = await prepareDataObject(
+    parameters.db,
     contentParameters,
     parameters.event,
     parameters.contentOwner,
@@ -633,6 +634,7 @@ async function prepareLanguage(
 
   // create new language
   const newLanguage = new Language({
+    id: await createPredictableId(db),
     iso: languageIso,
     createdInBlock: event.blockNumber,
 
@@ -641,14 +643,13 @@ async function prepareLanguage(
     updatedById: '1',
   })
 
-  newLanguage.id = createPredictableId(event, newLanguage)
-
   await db.save<Language>(newLanguage)
 
   return PropertyChange.newChange(newLanguage)
 }
 
 async function prepareLicense(
+  db: DatabaseManager,
   licenseProtobuf: LicenseMetadata.AsObject | undefined,
   event: SubstrateEvent,
 ): Promise<License | undefined> {
@@ -668,13 +669,12 @@ async function prepareLicense(
   // crete new license
   const license = new License({
     ...licenseProtobuf,
+    id: await createPredictableId(db),
 
     createdById: '1',
     updatedById: '1',
   })
 
-  license.id = createPredictableId(event, license)
-
   return license
 }
 

+ 7 - 6
query-node/mappings/src/content/video.ts

@@ -187,7 +187,7 @@ export async function content_VideoCreated(
   }
 
   // prepare video media metadata (if any)
-  const fixedProtobuf = integrateVideoMediaMetadata(null, protobufContent, event)
+  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
@@ -265,7 +265,7 @@ export async function content_VideoUpdated(
     )
 
     // prepare video media metadata (if any)
-    const fixedProtobuf = integrateVideoMediaMetadata(video, protobufContent, event)
+    const fixedProtobuf = await integrateVideoMediaMetadata(db, video, protobufContent, event)
 
     // remember original license
     const originalLicense = video.license
@@ -426,11 +426,12 @@ export async function content_FeaturedVideosSet(
   NOTE: type hack - `RawVideoMetadata` is accepted for `metadata` instead of `Partial<Video>`
         see `prepareVideoMetadata()` in `utils.ts` for more info
 */
-function integrateVideoMediaMetadata(
+async function integrateVideoMediaMetadata(
+  db: DatabaseManager,
   existingRecord: Video | null,
   metadata: Partial<Video>,
   event: SubstrateEvent,
-): Partial<Video> {
+): Promise<Partial<Video>> {
   if (!metadata.mediaMetadata) {
     return metadata
   }
@@ -468,10 +469,10 @@ function integrateVideoMediaMetadata(
 
   // ensure predictable ids
   if (!mediaMetadata.encoding.id) {
-    mediaMetadata.encoding.id = createPredictableId(event, mediaMetadata.encoding)
+    mediaMetadata.encoding.id = await createPredictableId(db)
   }
   if (!mediaMetadata.id) {
-    mediaMetadata.id = createPredictableId(event, mediaMetadata)
+    mediaMetadata.id = await createPredictableId(db)
   }
 
   return {

+ 1 - 1
query-node/mappings/src/storage.ts

@@ -45,7 +45,7 @@ export async function dataDirectory_ContentAdded(db: DatabaseManager, event: Sub
   // save all content objects
   for (let parameters of contentParameters) {
     const owner = convertStorageObjectOwner(storageObjectOwner)
-    const dataObject = await prepareDataObject(parameters, event, owner)
+    const dataObject = await prepareDataObject(db, parameters, event, owner)
 
     // fill in auto-generated fields
     dataObject.createdAt = new Date(fixBlockTimestamp(event.blockTimestamp).toNumber())

+ 1 - 1
query-node/mappings/src/workingGroup.ts

@@ -181,7 +181,7 @@ async function createWorker(
   event: SubstrateEvent,
 ): Promise<void> {
   const newWorker = new Worker({
-    id: createPredictableId(event, workerType),
+    id: await createPredictableId(db),
     workerId: workerId.toString(),
     type: workerType,
     isActive: true,

+ 8 - 0
query-node/schema.graphql

@@ -400,3 +400,11 @@ type Worker @entity {
 
   dataObjects: [DataObject!]! @derivedFrom(field: "liaison")
 }
+
+type NextEntityId @entity {
+  "Unique identifier"
+  id: ID!
+
+  "Next deterministic id for entities without custom id"
+  nextId: Int!
+}