Files snapshot from main

./getConfig.ts

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
9add9c Tucker McKnight
9add9c Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
9e4c7e Tucker McKnight
90eb8e Tucker McKnight
90eb8e Tucker McKnight
import {Ajv} from 'ajv'
import {ReposConfiguration, ReposConfigurationWithDefaultsApplied} from './src/configTypes.ts'
import ConfigSchema from './schemas/ReposConfiguration.json' with { type: 'json' }

const ajv = new Ajv()

function isObject(item) {
  return (item && typeof item === 'object' && !Array.isArray(item));
}

function mergeDeep(target, ...sources) {
  if (!sources.length) return target;
  const source = sources.shift();

  if (isObject(target) && isObject(source)) {
    for (const key in source) {
      if (isObject(source[key])) {
        if (!target[key]) Object.assign(target, { [key]: {} });
        mergeDeep(target[key], source[key]);
      } else {
        Object.assign(target, { [key]: source[key] });
      }
    }
  }

  return mergeDeep(target, ...sources);
}

export const getConfig = (userConfiguration: ReposConfiguration)
                         : ReposConfigurationWithDefaultsApplied => {
  const validator = ajv.compile(ConfigSchema)
  const valid = validator(userConfiguration)
  if (!valid) {
    throw new Error(validator.errors.map(error => `config object at ${error.instancePath.replaceAll("/", ".")}: ${error.message}\n${Object.values(error.params).toString()}`).join("\n"))
  }

  const defaults = {
    path: '/repos',
    defaultTemplate: {
      enabled: true,
      homepageButtons: [],
      lineCountForLageCommit: 100,
      allRepositoriesPageTitle: "All Repositories",
      colors: {
        languageGraph: [
          { light: '#ff549bff' },
          { light: '#8ec323ff' },
          { light: '#f8e276ff' },
          { light: '#f49530ff' },
          { light: '#edabb8ff' },
          { light: '#e273faff' },
          { light: '#852cdfff', dark: '#B673FA' },
        ]
      }
    }
  }

  const userRepos = userConfiguration.repos

  const reposConfiguration = mergeDeep({}, defaults, userConfiguration)

  const repoDefaults = {
    defaultBranch: 'main',
    branches: ['**'],
    tags: ['**'],
    languageExtensions: {},
    defaultTemplate: {
      homepageButtons: [],
    }
  }

  const repos = {}
  for (const repoName in userRepos) {
    const res = mergeDeep({}, repoDefaults, userRepos[repoName])
    repos[repoName] = res
  }

  reposConfiguration['repos'] = repos

  // Special fixup on the path value, since we expect it
  // to always start and end with a slash (or just be a slash).
  if (!reposConfiguration.path.endsWith('/')) {
    reposConfiguration.path = reposConfiguration.path + '/'
  }
  if (!reposConfiguration.path.startsWith('/')) {
    reposConfiguration.path = '/' + reposConfiguration.path
  }
  return reposConfiguration
}