Browse Source

Make all possible ways to initialize content dir rely on expected class order

Leszek Wiesner 4 years ago
parent
commit
8c26a3fab7

+ 14 - 31
cli/src/commands/content-directory/initialize.ts

@@ -1,45 +1,28 @@
 import ContentDirectoryCommandBase from '../../base/ContentDirectoryCommandBase'
-import { CreateClass } from 'cd-schemas/types/extrinsics/CreateClass'
-import { getInputs, InputParser, ExtrinsicsHelper } from 'cd-schemas'
-import { AddClassSchema } from 'cd-schemas/types/extrinsics/AddClassSchema'
-import { EntityBatch } from 'cd-schemas/types/EntityBatch'
-
-// Class order (needs to be inline with query node mappings)
-const EXPECTED_CLASS_ORDER = [
-  'Channel',
-  'ContentCategory',
-  'HttpMediaLocation',
-  'JoystreamMediaLocation',
-  'KnownLicense',
-  'Language',
-  'License',
-  'MediaLocation',
-  'UserDefinedLicense',
-  'Video',
-  'VideoMedia',
-  'VideoMediaEncoding',
-  'FeaturedVideo',
-]
+import { InputParser, ExtrinsicsHelper, getInitializationInputs } from 'cd-schemas'
+import { flags } from '@oclif/command'
 
 export default class InitializeCommand extends ContentDirectoryCommandBase {
   static description =
-    'Initialize content directory with input data from @joystream/content library. Requires lead access.'
+    'Initialize content directory with input data from @joystream/content library or custom, provided one. Requires lead access.'
+
+  static flags = {
+    rootInputsDir: flags.string({
+      required: false,
+      description: 'Custom inputs directory (must follow @joystream/content directory structure)',
+    }),
+  }
 
   async run() {
     const account = await this.getRequiredSelectedAccount()
     await this.requireLead()
     await this.requestAccountDecoding(account)
 
-    const classInputs = getInputs<CreateClass>('classes')
-      .map(({ data }) => data)
-      .sort((a, b) => {
-        if (EXPECTED_CLASS_ORDER.indexOf(a.name) === -1) return 1
-        if (EXPECTED_CLASS_ORDER.indexOf(b.name) === -1) return -1
-        return EXPECTED_CLASS_ORDER.indexOf(a.name) - EXPECTED_CLASS_ORDER.indexOf(b.name)
-      })
+    const {
+      flags: { rootInputsDir },
+    } = this.parse(InitializeCommand)
 
-    const schemaInputs = getInputs<AddClassSchema>('schemas').map(({ data }) => data)
-    const entityBatchInputs = getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
+    const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs(rootInputsDir)
 
     const currentClasses = await this.getApi().availableClasses()
 

+ 2 - 7
content-directory-schemas/scripts/initializeContentDir.ts

@@ -1,20 +1,15 @@
-import { CreateClass } from '../types/extrinsics/CreateClass'
-import { AddClassSchema } from '../types/extrinsics/AddClassSchema'
 import { types } from '@joystream/types'
 import { ApiPromise, WsProvider } from '@polkadot/api'
-import { getInputs } from '../src/helpers/inputs'
+import { getInitializationInputs } from '../src/helpers/inputs'
 import fs from 'fs'
 import path from 'path'
-import { EntityBatch } from '../types/EntityBatch'
 import { InputParser } from '../src/helpers/InputParser'
 import { ExtrinsicsHelper, getAlicePair } from '../src/helpers/extrinsics'
 
 // Save entity operations output here for easier debugging
 const ENTITY_OPERATIONS_OUTPUT_PATH = path.join(__dirname, '../operations.json')
 
-const classInputs = getInputs<CreateClass>('classes').map(({ data }) => data)
-const schemaInputs = getInputs<AddClassSchema>('schemas').map(({ data }) => data)
-const entityBatchInputs = getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
+const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs()
 
 async function main() {
   // Init api

+ 16 - 0
content-directory-schemas/src/consts/index.ts

@@ -0,0 +1,16 @@
+// Class order (needs to be inline with query node mappings)
+export const EXPECTED_CLASS_ORDER = [
+  'Channel',
+  'ContentCategory',
+  'HttpMediaLocation',
+  'JoystreamMediaLocation',
+  'KnownLicense',
+  'Language',
+  'License',
+  'MediaLocation',
+  'UserDefinedLicense',
+  'Video',
+  'VideoMedia',
+  'VideoMediaEncoding',
+  'FeaturedVideo',
+]

+ 3 - 7
content-directory-schemas/src/helpers/InputParser.ts

@@ -18,7 +18,7 @@ import { ApiPromise } from '@polkadot/api'
 import { JoyBTreeSet } from '@joystream/types/common'
 import { CreateClass } from '../../types/extrinsics/CreateClass'
 import { EntityBatch } from '../../types/EntityBatch'
-import { getInputs } from './inputs'
+import { getInitializationInputs, getInputs } from './inputs'
 
 type SimpleEntityValue = string | boolean | number | string[] | boolean[] | number[] | undefined | null
 // Input without "new" or "extising" keywords
@@ -38,12 +38,8 @@ export class InputParser {
   private classIdByNameMap = new Map<string, number>()
 
   static createWithInitialInputs(api: ApiPromise): InputParser {
-    return new InputParser(
-      api,
-      getInputs<CreateClass>('classes').map(({ data }) => data),
-      getInputs<AddClassSchema>('schemas').map(({ data }) => data),
-      getInputs<EntityBatch>('entityBatches').map(({ data }) => data)
-    )
+    const { classInputs, schemaInputs, entityBatchInputs } = getInitializationInputs()
+    return new InputParser(api, classInputs, schemaInputs, entityBatchInputs)
   }
 
   static createWithKnownSchemas(api: ApiPromise, entityBatches?: EntityBatch[]): InputParser {

+ 25 - 3
content-directory-schemas/src/helpers/inputs.ts

@@ -1,5 +1,8 @@
 import path from 'path'
 import fs from 'fs'
+import { CreateClass, AddClassSchema } from '../../types/extrinsics'
+import { EntityBatch } from '../../types/EntityBatch'
+import { EXPECTED_CLASS_ORDER } from '../consts'
 
 export const INPUTS_LOCATION = path.join(__dirname, '../../inputs')
 export const INPUT_TYPES = ['classes', 'schemas', 'entityBatches'] as const
@@ -9,12 +12,31 @@ export type FetchedInput<Schema = any> = { fileName: string; data: Schema }
 
 export const getInputsLocation = (inputType: InputType) => path.join(INPUTS_LOCATION, inputType)
 
-export function getInputs<Schema = any>(inputType: InputType): FetchedInput<Schema>[] {
-  return fs.readdirSync(getInputsLocation(inputType)).map((fileName) => {
-    const inputJson = fs.readFileSync(path.join(INPUTS_LOCATION, inputType, fileName)).toString()
+export function getInputs<Schema = any>(
+  inputType: InputType,
+  rootInputsLocation = INPUTS_LOCATION
+): FetchedInput<Schema>[] {
+  return fs.readdirSync(path.join(rootInputsLocation, inputType)).map((fileName) => {
+    const inputJson = fs.readFileSync(path.join(rootInputsLocation, inputType, fileName)).toString()
     return {
       fileName,
       data: JSON.parse(inputJson) as Schema,
     }
   })
 }
+
+export function getSortedClassInputs(rootInputsLocation = INPUTS_LOCATION): FetchedInput<CreateClass>[] {
+  return getInputs<CreateClass>('classes', rootInputsLocation).sort((a, b) => {
+    if (EXPECTED_CLASS_ORDER.indexOf(a.data.name) === -1) return 1
+    if (EXPECTED_CLASS_ORDER.indexOf(b.data.name) === -1) return -1
+    return EXPECTED_CLASS_ORDER.indexOf(a.data.name) - EXPECTED_CLASS_ORDER.indexOf(b.data.name)
+  })
+}
+
+export function getInitializationInputs(rootInputsLocation = INPUTS_LOCATION) {
+  return {
+    classInputs: getSortedClassInputs(rootInputsLocation).map(({ data }) => data),
+    schemaInputs: getInputs<AddClassSchema>('schemas').map(({ data }) => data),
+    entityBatchInputs: getInputs<EntityBatch>('entityBatches').map(({ data }) => data),
+  }
+}

+ 2 - 1
content-directory-schemas/src/index.ts

@@ -1,6 +1,7 @@
 export { ExtrinsicsHelper, getAlicePair } from './helpers/extrinsics'
 export { InputParser } from './helpers/InputParser'
-export { getInputs, getInputsLocation } from './helpers/inputs'
+export { getInputs, getInitializationInputs, getInputsLocation } from './helpers/inputs'
 export { isReference, isSingle } from './helpers/propertyType'
 export { getSchemasLocation } from './helpers/schemas'
 export { default as initializeContentDir } from './helpers/initialize'
+export { EXPECTED_CLASS_ORDER } from './consts'