Improve documentation and start making some config fields as optional

9ff2f245867762b5e7484b354813432a5781e547

Tucker McKnight <tucker@pangolin.lan> | Sun Jul 12 2026

Improve documentation and start making some config fields as optional
js_templates/helpers/nav.ts:109
Before
108
109
110
111
112
113

      return `${refPath(refName, refType)}/commits.xml`
    },
    homepageButtons: args.reposConfig.repos[args.currentRepoName].defaultTemplateConfiguration?.homepageButtons || []
  }
}
After
108
109
110
111
112
113

      return `${refPath(refName, refType)}/commits.xml`
    },
    homepageButtons: args.reposConfig.repos[args.currentRepoName].defaultTemplate?.homepageButtons || []
  }
}
js_templates/index.ts:7
Before
6
7
8
9
10
11
  const pageContent = m('div', {class: "container"}, [
    m('div', {class: "row my-3"},
      m('div', {class: "col"},
        m('h1', data.reposConfig.defaultTemplateConfiguration?.allRepositoriesPageTitle || "All Repositories")
      )
    ),
    m('div', {class: "row d-flex flex-wrap"},
After
6
7
8
9
10
11
  const pageContent = m('div', {class: "container"}, [
    m('div', {class: "row my-3"},
      m('div', {class: "col"},
        m('h1', data.reposConfig.defaultTemplate?.allRepositoriesPageTitle || "All Repositories")
      )
    ),
    m('div', {class: "row d-flex flex-wrap"},
js_templates/index.ts:30
Before
29
30
31
32
33
34
                  class: "mx-1 my-2 btn btn-outline-secondary shadow-none dropdown-toggle clone-popover-btn",
                  'data-copy-text': repo.cloneUrl
                }, 'Clone'),
                (data.reposConfig.repos[repo.name].defaultTemplateConfiguration?.homepageButtons || []).map((button) => {
                  return m('a', {
                    class: "mx-1 my-2 btn btn-outline-secondary shadow-none",
                    href: button.url,
After
29
30
31
32
33
34
                  class: "mx-1 my-2 btn btn-outline-secondary shadow-none dropdown-toggle clone-popover-btn",
                  'data-copy-text': repo.cloneUrl
                }, 'Clone'),
                (data.reposConfig.repos[repo.name].defaultTemplate?.homepageButtons || []).map((button) => {
                  return m('a', {
                    class: "mx-1 my-2 btn btn-outline-secondary shadow-none",
                    href: button.url,
main.ts:32
Before
31
32
33
34
35
36
  const validator = ajv.compile(ConfigSchema)
  const valid = validator(reposConfiguration)
  if (!valid) {
    throw new Error(validator.errors.map(error => `config object at ${error.instancePath.replaceAll("/", ".")}: ${error.message}`).join("\n"))
  }

  return async ({directories}) => {
After
31
32
33
34
35
36
  const validator = ajv.compile(ConfigSchema)
  const valid = validator(reposConfiguration)
  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"))
  }

  return async ({directories}) => {
schemas/ReposConfiguration.json:6
Before
5
6
7


8
9
      "additionalProperties": false,
      "properties": {
        "branches": {
⁣
⁣
          "items": {
            "anyOf": [
              {
After
5
6
7
8
9
10
11
      "additionalProperties": false,
      "properties": {
        "branches": {
          "default": "branches: ['**']",
          "description": "The list of branches to pull from the source repo, making them available in the public repo. If you have some branches in your source repo (that is, the one specified in `location`,) and you don't want those branches to have a snapshot of their current files available, then do not list those branches in this field. Glob patterns can be used here. By default, pulls all available branches from the source repo.",
          "items": {
            "anyOf": [
              {
schemas/ReposConfiguration.json:60
Before
59
60
61


62
63
64
65
66
          "type": "array"
        },
        "defaultBranch": {
⁣
⁣
          "type": "string"
        },
        "defaultTemplateConfiguration": {
          "additionalProperties": false,
          "properties": {
            "homepageButtons": {
After
59
60
61
62
63
64
65
66
67
68
          "type": "array"
        },
        "defaultBranch": {
          "default": "'main', 'master', or 'develop', determined by looking for one of those branches",
          "description": "The default branch for the repository. If this field is not set, Repo Viewer will automatically try `main`, `master`, and `develop`, in that order. Set a `defaultBranch` value if your default branch is not one of those.",
          "type": "string"
        },
        "defaultTemplate": {
          "additionalProperties": false,
          "properties": {
            "homepageButtons": {
schemas/ReposConfiguration.json:106
Before
105
106
107


108
109
          "type": "string"
        },
        "tags": {
⁣
⁣
          "items": {
            "anyOf": [
              {
After
105
106
107
108
109
110
111
          "type": "string"
        },
        "tags": {
          "default": "tags: ['**']",
          "description": "The list of tags to fetch from the source repo, making them available in the public repo. If you have some tags in your source repo (that is, the one specified in `location`,) and you don't want those tags to have a snapshot of their files available, then do not list those tags in this field. Glob patterns can be used here. By default, pulls all available tags from the source repo.\n\nYou may give either an exact name of the tag, a glob pattern (like `releases/**`), or an object. If you want to limit the number of tags that are shown (e.g. to avoid generating HTML pages for very old releases), use the object. The object contains two keys: `pattern` and `max`, where `pattern` is a glob pattern for matching a tag name, and `max` is how many tags should be fetched matching that name. Older tags beyond the max number will be ignored.",
          "items": {
            "anyOf": [
              {
schemas/ReposConfiguration.json:133
Before
132
133
134
135
136
137
138
139
140
        }
      },
      "required": [
        "location",
        "defaultBranch",
        "branches",
        "tags"
      ],
      "type": "object"
    },
After
132
133
134
135



136
137
        }
      },
      "required": [
        "location"
⁣
⁣
⁣
      ],
      "type": "object"
    },
schemas/ReposConfiguration.json:145
Before
144
145
146
147
148
149
150
151

152
153
154
155





156
157
158
159

160
161
162
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
      "properties": {
        "baseUrl": {
          "description": "The root URL where this website will be. E.g.: https://blog.example.com/repos. This URL will be used when a clone or pull command is being shown on your site.",
          "type": "string"
        },
        "defaultTemplateConfiguration": {
          "additionalProperties": false,
⁣
          "properties": {
            "allRepositoriesPageTitle": {
              "type": "string"
            }
⁣
⁣
⁣
⁣
⁣
          },
          "type": "object"
        },
        "path": {
⁣
          "description": "The path to put the generated site in. All generated files will be put in this directory, repos for cloning will be put in this directory, and it will be added to the end of all URLs used by the default virtual template.",
          "type": "string"
        },
        "repos": {
After
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
      "description": "The ReposConfiguration object contains information about your local repositories, like their name and location on your local filesystem. Add repositories to this configuration object to make a static site for them.\n\nYou will also need to set the  {@link  ReposConfiguration.baseUrl }  to the URL of your live website.",
      "properties": {
        "baseUrl": {
          "description": "The root URL where this website will be. E.g.: https://blog.example.com/repos. This URL will be used when a clone or pull command is being shown on your site. Unlike on a regular Build Awesome site, this needs to be explicitly defined, since the `git clone` URL cannot be a relative link; Repo Viewer needs to know your domain name in order to know what the `git clone` URL should be.",
          "type": "string"
        },
        "defaultTemplate": {
          "additionalProperties": false,
          "description": "Some configuration options for the default template included with this plugin.",
          "properties": {
            "allRepositoriesPageTitle": {
              "type": "string"
            },
            "enabled": {
              "default": true,
              "description": "Whether or not the default template should be used. If `true`, will generate the type of HTML pages seen at https://tuckerm.us/repos.",
              "type": "boolean"
            }
          },
          "type": "object"
        },
        "path": {
          "default": "path: \"/repos\"",
          "description": "The path to put the cloned repositories in. Repositories will be cloned from their source `location` to the `path` folder inside of your site's output folder. For example, `_site/repos/my-git-repo.git`.",
          "type": "string"
        },
        "repos": {
schemas/ReposConfiguration.json:167
Before
166
167
168
169
170
171
172
173
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definition of  {@link  GitConfig }  for more details about what goes in these configuration objects."
          },
          "type": "object"
        },
        "useDefaultTemplate": {
          "type": "boolean"
        }
      },
      "required": [
After
166
167
168
169



170
            "description": "An object containing the configuration for your repositories. Each key in this object is a repository name, and the value has several config options for that repository. The required config options describe the path to the repository and which branches should be pulled. See the specific definition of  {@link  GitConfig }  for more details about what goes in these configuration objects."
          },
          "type": "object"
        }
⁣
⁣
⁣
      },
      "required": [
src/configTypes.ts:1
Before
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
/**
 * The ReposConfiguration object contains information about your local repositories,
 * like their name and location on your local filesystem. Add repositories to this
 * configuration object to make a static site for them.
 * 
 * You will also need to set the {@link ReposConfiguration.baseUrl} to the URL of your
 * live website.
 * @example
 * const config: ReposConfiguration = {
 *   baseUrl: "https://repos.tuckerm.us",
 *   repos: {
 *     "My Git Project": {
 *       defaultBranch: 'main',
 *       branches: ['main', 'develop']
 *     },
 *   },
 * }
 */
export type ReposConfiguration = {
  repos: {
⁣
    /** An object containing the configuration for your repositories.
     * Each key in this object is a repository name, and the value has several
     * config options for that repository. The required config options describe
     * the path to the repository and which branches should be pulled. See the specific
     * definition of {@link GitConfig} for more details
     * about what goes in these configuration objects.
     */
    [repoName: string]: GitConfig
  },
  /**
   * The root URL where this website will be. E.g.: https://blog.example.com/repos.
   * This URL will be used when a clone or pull command is being shown on your site.
⁣
⁣
⁣
   * @example baseUrl: "https://repos.tuckerm.us"
   */
  baseUrl: string,
  /**
   * The path to put the generated site in. All generated files will be put in this
   * directory, repos for cloning will be put in this directory, and it will be
⁣
   * added to the end of all URLs used by the default virtual template.
   * @example path: "/repos"
   */
  path?: string,
⁣
⁣
⁣
⁣
⁣
  useDefaultTemplate?: boolean,
⁣
⁣
⁣
  defaultTemplateConfiguration?: {
    allRepositoriesPageTitle?: string,
  },
}
After
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
/**
 The ReposConfiguration object contains information about your local repositories,
 like their name and location on your local filesystem. Add repositories to this
 configuration object to make a static site for them.
 
 You will also need to set the {@link ReposConfiguration.baseUrl} to the URL of your
 live website.
 @example
 const config: ReposConfiguration = {
   baseUrl: "https://repos.tuckerm.us",
   repos: {
     "My Git Project": {
       defaultBranch: 'main',
       branches: ['main', 'develop']
     },
   },
 }
 */
export type ReposConfiguration = {
  repos: {
    /**
     *An object containing the configuration for your repositories.
     *Each key in this object is a repository name, and the value has several
     *config options for that repository. The required config options describe
     *the path to the repository and which branches should be pulled. See the specific
     *definition of {@link GitConfig} for more details
     *about what goes in these configuration objects.
     */
    [repoName: string]: GitConfig
  },
  /**
   * The root URL where this website will be. E.g.: https://blog.example.com/repos.
   * This URL will be used when a clone or pull command is being shown on your site.
   * Unlike on a regular Build Awesome site, this needs to be explicitly defined,
   * since the `git clone` URL cannot be a relative link; Repo Viewer needs to know
   * your domain name in order to know what the `git clone` URL should be.
   * @example baseUrl: "https://repos.tuckerm.us"
   */
  baseUrl: string,
  /**
   * The path to put the cloned repositories in. Repositories will be cloned from
   * their source `location` to the `path` folder inside of your site's output folder.
   * For example, `_site/repos/my-git-repo.git`.
   * @default path: "/repos"
   * @example path: "/repos"
   */
  path?: string,
  /**
   * Some configuration options for the default template included with this plugin.
   */
  defaultTemplate?: {
    /**
     Whether or not the default template should be used. If `true`, will generate
     the type of HTML pages seen at https://tuckerm.us/repos.
     @default true
    */
    enabled?: boolean,
    allRepositoriesPageTitle?: string,
  },
}
src/configTypes.ts:52
Before
51
52
53








54



















55
















56

57
58
59
   */
  location: string,
  description?: string,
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
  defaultBranch: string,
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
  branches: Array<string | {pattern: string, max?: number, compareTo?: string, description?: string}>,
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
  // todo: make tags optional (and branches, too?) and auto-populate with ** if it's not filled in.
⁣
  tags: Array<string | {pattern: string, max: number}>,
  languageExtensions?: {
    [fileExtension: string]: string
  },
After
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
   */
  location: string,
  description?: string,
  /**
   The default branch for the repository. If this field is not set,
   Repo Viewer will automatically try `main`, `master`, and `develop`, in
   that order. Set a `defaultBranch` value if your default branch is not one
   of those.
   @default 'main', 'master', or 'develop', determined by looking for one of those branches
   @example defaultBranch: 'main'
  */
  defaultBranch?: string,
  /**
   The list of branches to pull from the source repo, making them available
   in the public repo. If you have some branches in your source repo (that is,
   the one specified in `location`,) and you don't want those branches to have
   a snapshot of their current files available, then do not list those branches
   in this field. Glob patterns can be used here. By default, pulls all available
   branches from the source repo.
   @example branches: [
     'main',
     'release-candidate',
     {
       pattern: 'develop/*',
       max: 50,
       compareTo: 'release-candidate'
     },
     'features/**'
   ]
   @default branches: ['**']
  */
  branches?: Array<string | {pattern: string, max?: number, compareTo?: string, description?: string}>,
  /**
   The list of tags to fetch from the source repo, making them available
   in the public repo. If you have some tags in your source repo (that is,
   the one specified in `location`,) and you don't want those tags to have
   a snapshot of their files available, then do not list those tags
   in this field. Glob patterns can be used here. By default, pulls all available
   tags from the source repo.

   You may give either an exact name of the tag, a glob pattern (like `releases/**`),
   or an object. If you want to limit the number of tags that are shown (e.g. to
   avoid generating HTML pages for very old releases), use the object. The object
   contains two keys: `pattern` and `max`, where `pattern` is a glob pattern for
   matching a tag name, and `max` is how many tags should be fetched matching
   that name. Older tags beyond the max number will be ignored.
   @type Array<string>
   @example tags: ['v1.*', 'v2.*', {pattern: 'releases/**', max: 100}]
   @default tags: ['**']
  */
  tags?: Array<string | {pattern: string, max: number}>,
  languageExtensions?: {
    [fileExtension: string]: string
  },
src/configTypes.ts:64
Before
63
64
65
66
67
68
    copyFrom: string,
    copyTo: string,
  }[],
  defaultTemplateConfiguration?: {
    homepageButtons: Array<{
      url: string,
      text: string,
After
63
64
65
66
67
68
    copyFrom: string,
    copyTo: string,
  }[],
  defaultTemplate?: {
    homepageButtons: Array<{
      url: string,
      text: string,