scolladon/sfdx-git-delta

View on GitHub
src/metadata/MetadataRepositoryImpl.ts

Summary

Maintainability
A
0 mins
Test Coverage
'use strict'

import { parse } from 'path'

import { DOT, PATH_SEP } from '../constant/fsConstants'
import {
  CUSTOM_APPLICATION_SUFFIX,
  CUSTOM_METADATA_SUFFIX,
  EMAIL_SERVICES_FUNCTION_SUFFIX,
  METAFILE_SUFFIX,
  OBJECT_TRANSLATION_TYPE,
  OBJECT_TYPE,
  SHARING_RULE_TYPE,
  SUB_OBJECT_TYPES,
  TERRITORY_MODEL_TYPE,
  WORKFLOW_TYPE,
} from '../constant/metadataConstants'
import type { Metadata } from '../types/metadata'

import { MetadataRepository } from './MetadataRepository'

export class MetadataRepositoryImpl implements MetadataRepository {
  protected readonly metadataPerExt: Map<string, Metadata>
  protected readonly metadataPerDir: Map<string, Metadata>
  constructor(
    // eslint-disable-next-line no-unused-vars
    protected readonly metadatas: Metadata[]
  ) {
    this.metadataPerExt = new Map<string, Metadata>()
    this.metadataPerDir = new Map<string, Metadata>()

    this.metadatas.forEach(metadata => {
      this.addSuffix(metadata)
      this.addFolder(metadata)
    })
  }

  protected addSuffix(metadata: Metadata) {
    if (metadata.suffix) {
      if (this.metadataPerExt.has(metadata.suffix)) {
        MetadataRepositoryImpl.UNSAFE_EXTENSION.add(metadata.suffix)
      } else {
        this.metadataPerExt.set(metadata.suffix, metadata)
      }
    }
    this.addSharedFolderSuffix(metadata)
  }

  protected addSharedFolderSuffix(metadata: Metadata) {
    if (metadata.content) {
      const metadataWithoutContent = {
        ...metadata,
        content: undefined,
      }
      for (const sharedFolderMetadataDef of metadata.content) {
        this.addSuffix({
          ...metadataWithoutContent,
          suffix: sharedFolderMetadataDef.suffix,
        } as unknown as Metadata)
      }
    }
  }

  protected addFolder(metadata: Metadata) {
    if (metadata.directoryName) {
      this.metadataPerDir.set(metadata.directoryName, metadata)
    }
  }

  public has(path: string): boolean {
    return !!this.get(path)
  }

  public get(path: string): Metadata | undefined {
    const parts = path.split(PATH_SEP)
    const metadata = this.searchByExtension(parts)
    return metadata ?? this.searchByDirectory(parts)
  }

  protected searchByExtension(parts: string[]): Metadata | undefined {
    const extension = parse(
      parts[parts.length - 1].replace(METAFILE_SUFFIX, '')
    ).ext.replace(DOT, '')

    if (MetadataRepositoryImpl.UNSAFE_EXTENSION.has(extension)) {
      return
    }
    return this.metadataPerExt.get(extension)
  }

  protected searchByDirectory(parts: string[]): Metadata | undefined {
    let metadata: Metadata | undefined
    for (const part of parts) {
      metadata = this.metadataPerDir.get(part) ?? metadata
      if (
        metadata &&
        !MetadataRepositoryImpl.TYPES_WITH_SUB_TYPES.has(metadata.xmlName!)
      ) {
        break
      }
    }
    return metadata
  }

  public getFullyQualifiedName(path: string): string {
    let fullyQualifiedName = parse(path).base
    const type = this.get(path)
    if (type && MetadataRepositoryImpl.COMPOSED_TYPES.has(type.xmlName!)) {
      const parentType = path
        .split(PATH_SEP)
        .find(part => this.metadataPerDir.has(part))!
      fullyQualifiedName = path
        .slice(path.indexOf(parentType))
        .replace(new RegExp(PATH_SEP, 'g'), '')
    }
    return fullyQualifiedName
  }

  public values(): Metadata[] {
    return this.metadatas
  }

  private static TYPES_WITH_SUB_TYPES = new Set([
    OBJECT_TYPE,
    TERRITORY_MODEL_TYPE,
    WORKFLOW_TYPE,
    SHARING_RULE_TYPE,
    '',
  ])

  private static UNSAFE_EXTENSION = new Set([
    CUSTOM_APPLICATION_SUFFIX,
    EMAIL_SERVICES_FUNCTION_SUFFIX,
    CUSTOM_METADATA_SUFFIX,
  ])

  private static COMPOSED_TYPES = new Set([
    OBJECT_TYPE,
    OBJECT_TRANSLATION_TYPE,
    WORKFLOW_TYPE,
    SHARING_RULE_TYPE,
    ...SUB_OBJECT_TYPES,
  ])
}