Use the flatRels object on all templates

99f6343ce4b99c2c0a16a48e1836a823ee7036ed

Tucker McKnight <tmcknight@instructure.com> | Sun Apr 19 2026

Use the flatRels object on all templates

Fixes bugs with pages not getting generated for tags. Tag pages,
and having links properly point to them, seems to be working
in all places now.
js_templates/branches.ts:8
Before
7
8
9






10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
⁣
⁣
⁣
⁣
⁣
⁣
  const nav = NavHelper(reposConfig, slugify, data.flatRel.repoName, data.flatRel.relName)

  const branchesWithWorkInProgress = data.flatRels.filter(rel => rel.type === "branch" && rel.ahead > 0)
  const branchesFullyMerged = data.flatRels.filter(rel => rel.type === "branch" && rel.ahead === 0)

  const branchCards = (branches) => {
    return m('ul', branches.map((branch) => {
      return branch.repoName === data.flatRel.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(branch.repoName)}/branch/${slugify(branch.relName)}/branches`
          }, branch.relName),
          branch.relName === data.flatRel.relName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          branch.relName === data.reposConfig.repos[branch.repoName].defaultBranch
            ? m('div', {class: "badge rounded-pill bg-info text-dark mx-1"}, 'default') : null,
          m('ul', [
            m('li', [
After
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
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: data.flatRef.repoName,
    currentRefName: data.flatRef.refName,
    currentRefType: data.flatRef.type,
  })

  const branchesWithWorkInProgress = data.flatRefs.filter(ref => ref.type === "branch" && ref.ahead > 0)
  const branchesFullyMerged = data.flatRefs.filter(ref => ref.type === "branch" && ref.ahead === 0)

  const branchCards = (branches) => {
    return m('ul', branches.map((branch) => {
      return branch.repoName === data.flatRef.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(branch.repoName)}/branch/${slugify(branch.refName)}/branches`
          }, branch.refName),
          branch.refName === data.flatRef.refName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          branch.refName === data.reposConfig.repos[branch.repoName].defaultBranch
            ? m('div', {class: "badge rounded-pill bg-info text-dark mx-1"}, 'default') : null,
          m('ul', [
            m('li', [
js_templates/commits.ts:7
Before
6
7
8
9
10
11
12






13
14
15
  eleventyConfig: any,
  data: any,
) => {
  const pagesJustForRel = eleventyConfig.getFilter("pagesJustForRel")
  const slugify = eleventyConfig.getFilter("slugify")
  const date = eleventyConfig.getFilter("date")

⁣
⁣
⁣
⁣
⁣
⁣
  const nav = NavHelper(reposConfig, slugify, data.patchPage.repoName, data.patchPage.relName)

  const pageContent = [
    m('div', {class: "row mt-3 mb-1"},
After
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  eleventyConfig: any,
  data: any,
) => {
  const pagesJustForRef = eleventyConfig.getFilter("pagesJustForRef")
  const slugify = eleventyConfig.getFilter("slugify")
  const date = eleventyConfig.getFilter("date")

  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: data.patchPage.repoName,
    currentRefName: data.patchPage.refName,
    currentRefType: data.patchPage.type,
  })

  const pageContent = [
    m('div', {class: "row mt-3 mb-1"},
js_templates/commits.ts:21
Before
20
21
22
23
24
25
          m('span', {class: "font-monospace me-2"}, data.patchPage.relName),
          m('a', {
            class: "btn btn-outline-primary badge shadow-none",
            href: nav.repoCurrentBranchRssFeed()
          }, [
            m('img', {
              src: `${nav.rootPath()}frontend/img/rss-icon.svg`,
After
20
21
22
23
24
25
          m('span', {class: "font-monospace me-2"}, data.patchPage.relName),
          m('a', {
            class: "btn btn-outline-primary badge shadow-none",
            href: nav.rssFeed()
          }, [
            m('img', {
              src: `${nav.rootPath()}frontend/img/rss-icon.svg`,
js_templates/commits.ts:34
Before
33
34
35
36
37
38
    ),
    m('nav', 
      m('ul', {class: "pagination"},
        pagesJustForRel(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
After
33
34
35
36
37
38
    ),
    m('nav', 
      m('ul', {class: "pagination"},
        pagesJustForRef(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
js_templates/commits.ts:68
Before
67
68
69
70
71
72
    })),
    m('nav',
      m('ul', {class: "pagination"},
        pagesJustForRel(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
After
67
68
69
70
71
72
    })),
    m('nav',
      m('ul', {class: "pagination"},
        pagesJustForRef(
          data.paginatedPatches,
          data.patchPage.repoName,
          data.patchPage.relName,
js_templates/common/htmlPage.ts:11
Before
10
11
12
13
14
15






16
17
18
19
20
21
22
23
24
25
26
27
28
29
  }

  const repo: Repository = data.currentRepo
  const rel: Repository['branches'][0] = data.currentRel

  const slugify = eleventyConfig.getFilter("slugify")
⁣
⁣
⁣
⁣
⁣
⁣
  const nav = NavHelper(reposConfig, slugify, repo.name, rel.name)

  const branchesWithHrefs = repo.branches.map((branch) => {
    return {
      name: branch.name,
      href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
      date: repo.commits.get(branch.sha).date.toISOString(),
    }
  }).concat(repo.tags.map((tag) => {
    return {
      name: tag.name,
      href: nav.repoTagHome(tag.name) + '/' + data.nav.path,
      date: repo.commits.get(tag.sha).date.toISOString(),
    }
  }))
After
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
  }

  const repo: Repository = data.currentRepo
  const ref: Repository['branches'][0] = data.currentRef

  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: repo.name,
    currentRefName: ref.name,
    currentRefType: data.currentRefType,
  })

  const branchesWithHrefs = repo.branches.map((branch) => {
    return {
      name: branch.name,
      href: nav.refHome({refName: branch.name, refType: 'branch'}) + '/' + data.nav.path,
      date: repo.commits.get(branch.sha).date.toISOString(),
    }
  }).concat(repo.tags.map((tag) => {
    return {
      name: tag.name,
      href: nav.refHome({refName: tag.name, refType: 'tag'}) + '/' + data.nav.path,
      date: repo.commits.get(tag.sha).date.toISOString(),
    }
  }))
js_templates/common/htmlPage.ts:37
Before
36
37
38
39
40
41
      m('script', m.trust(`
        window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
        window.defaultBranch = "${repo.defaultBranch}";
        window.currentBranch = "${rel.name}";
        window.cloneUrl = "${repo.cloneUrl}";
      `)),
      m('link', {
After
36
37
38
39
40
41
      m('script', m.trust(`
        window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
        window.defaultBranch = "${repo.defaultBranch}";
        window.currentBranch = "${ref.name}";
        window.cloneUrl = "${repo.cloneUrl}";
      `)),
      m('link', {
js_templates/common/htmlPage.ts:58
Before
57
58
59
60
61
62
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.repoCurrentBranchHome()
          }, repo.name)
        ),
        m('li', {class: "nav-item"}, [
After
57
58
59
60
61
62
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.refHome()
          }, repo.name)
        ),
        m('li', {class: "nav-item"}, [
js_templates/common/htmlPage.ts:69
Before
68
69
70
71
72
73
              'data-bs-toggle': "dropdown",
              'data-bs-auto-close': "outside",
              'aria-expanded': "false"
            }, rel.name),
            m('div', {class: "dropdown-menu"}, [
              m('form', {class: "mx-3 my-1"}, [
                m('input', {type: "text", class: "form-control", id: "dropdownBranchSearch", placeholder: "Search branches..."}),
After
68
69
70
71
72
73
              'data-bs-toggle': "dropdown",
              'data-bs-auto-close': "outside",
              'aria-expanded': "false"
            }, ref.name),
            m('div', {class: "dropdown-menu"}, [
              m('form', {class: "mx-3 my-1"}, [
                m('input', {type: "text", class: "form-control", id: "dropdownBranchSearch", placeholder: "Search branches..."}),
js_templates/common/htmlPage.ts:93
Before
92
93
94
95
96
97
              ]),
              m('div', {class: "dropdown-divider"}),
              m('div', {id: "dropdown-branches-results", class: "dropdown-branches"},
                branchesListItems(branchesWithHrefs, repo.defaultBranch, rel.name, 'date')
              )
            ])
          ])
After
92
93
94
95
96
97
              ]),
              m('div', {class: "dropdown-divider"}),
              m('div', {id: "dropdown-branches-results", class: "dropdown-branches"},
                branchesListItems(branchesWithHrefs, repo.defaultBranch, ref.name, 'date')
              )
            ])
          ])
js_templates/common/htmlPage.ts:106
Before
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
          m('nav', {class: "navbar navbar-expand"},
            m('ul', {class: "main-nav navbar-nav flex-wrap"}, [
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'home' ? 'active' : ''}`, 'aria-current': "page", href: nav.repoCurrentBranchHome()}, 'Home')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'files' ? 'active' : ''}`, href: nav.repoCurrentBranchFiles()}, 'Files')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'commits' ? 'active' : ''}`, href: nav.repoCurrentBranchCommits()}, 'Commits')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'tags' ? 'active' : ''}`, href: nav.repoCurrentBranchTags()}, 'Tags')
              )
            ])
          )
After
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
          m('nav', {class: "navbar navbar-expand"},
            m('ul', {class: "main-nav navbar-nav flex-wrap"}, [
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'home' ? 'active' : ''}`, 'aria-current': "page", href: nav.refHome()}, 'Home')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'files' ? 'active' : ''}`, href: nav.files()}, 'Files')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'commits' ? 'active' : ''}`, href: nav.commits()}, 'Commits')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.branches()}, 'Branches')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'tags' ? 'active' : ''}`, href: nav.tags()}, 'Tags')
              )
            ])
          )
js_templates/common/htmlPage.ts.orig: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
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
import m from 'mithril'
import { type ReposConfiguration } from '../../src/configTypes.ts'
import { type Repository } from '../../src/dataTypes.ts'
import { NavHelper } from '../helpers/nav.ts'
import branchesListItems from './branchesListItems.ts'

export default async (reposConfig: ReposConfiguration, eleventyConfig: any, data: any, pageContent: any) => {
  // this still necessary?
  if (data.currentRepo === '') {
    return
  }

  const repo: Repository = data.currentRepo
  const branch: Repository['branches'][0] = data.currentBranch

  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

  const branchesWithHrefs = repo.branches.map((branch) => {
    return {
      name: branch.name,
      href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
      date: repo.commits.get(branch.head).date.toISOString(),
    }
  })

<<<<<<< HEAD
    const repo: Repository = data.currentRepo
    const branch: Repository['branches'][0] = data.currentBranch

    const slugify = eleventyConfig.getFilter("slugify")
    const nav = NavHelper(reposConfig, slugify, repo.name, branch.name)

    const branchesWithHrefs = repo.branches.map((branch) => {
      return {
        name: branch.name,
        href: nav.repoBranchHome(branch.name) + '/' + data.nav.path,
        date: repo.commits.get(branch.head).date.toISOString(),
      }
    }).concat(repo.tags.map((tag) => {
      return {
        name: tag.name,
        href: "tbd",
        date: repo.commits.get(tag.sha).date.toISOString(),
      }
    }))

    console.log(branchesWithHrefs)

    return `
      <!doctype html>
      <html lang="en">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1">
          <title>${repo.name}</title>
          <link rel="stylesheet" href="/css/design-board.css">
          <script>
            window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
            window.defaultBranch = "${repo.defaultBranch}";
            window.currentBranch = "${branch.name}";
            window.cloneUrl = "${repo.cloneUrl}";
          </script>
          <script src="${nav.rootPath()}frontend/top.js"></script>
          <link rel="stylesheet" id="prism-theme" type="text/css" href="${data.reposPath}/vendor/prism.css" />
        </head>
        <body>
          <div class="container">
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.rootPath()}">&larr; All repositories</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link" href="${nav.repoCurrentBranchHome()}">${repo.name}</a>
                    </li>
                    <li class="nav-item">
                      <span class="nav-link d-inline-block">Branch:</span>
                      <div class="branch-selector dropdown-center d-inline-block">
                        <button class="branches nav-link d-inline-block btn btn-bg dropdown-toggle" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
                          ${branch.name}
                        </button>
                        <div class="dropdown-menu">
                          <form class="mx-3 my-1">
                            <input type="text" class="form-control" id="dropdownBranchSearch" placeholder="Search branches...">
                            <div>
                              <div class="row mt-3">
                                <div class="col">
                                  <label class="form-label">Sort by:</label>
                                </div>
                              </div>
                              <div class="sortRadioButtons">
                                <div class="sortRadioButton pe-1">
                                  <input class="form-check-input sort-filter" type="radio" name="branchSort" value='date' id="branchSortByDate" checked>
                                  <label class="form-check-label" for="branchSortByDate">
                                    Last commit
                                  </label>
                                </div>
                                <div class="sortRadioButton ps-1">
                                  <input class="form-check-input sort-filter" type="radio" name="branchSort" value='name' id="branchSortByName">
                                  <label class="form-check-label" for="branchSortByName">
                                    Name
                                  </label>
                                </div>
                              </div>
                            </div>
                          </form>
                          <div class="dropdown-divider"></div>
                          <div id="dropdown-branches-results" class="dropdown-branches">
                            ${branchesListItems(branchesWithHrefs, repo.defaultBranch, branch.name, 'date')}
                          </div>
                        </div>
                      </div>
                    </li>
                  </ul>
                </nav>
              </div>
              <div class="col-auto pt-2">
                <div class="dropdown">
                  <button class="dropdown-toggle btn btn-bg" id="dark-mode-switch" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                    <span>&#xFE0F;</span>
                  </button>
                  <ul class="dropdown-menu">
                    <li><button class="btn shadow-none" data-theme-pref="light" onclick="toggleDarkMode(this)"><span class="me-1">&#x1F31E;</span>Light</button></li>
                    <li><button class="btn shadow-none" data-theme-pref="dark" onclick="toggleDarkMode(this)"><span class="me-1">&#x1F319;</span>Dark</button></li>
                    <li><button class="btn shadow-none" data-theme-pref="auto" onclick="toggleDarkMode(this)"><span class="me-1">&#x1F5A5;&#xFE0F;</span>Match OS</button></li>
                  </ul>
                </div>
              </div>
            </div>
            <div class="row">
              <div class="col">
                <nav class="navbar navbar-expand">
                  <ul class="main-nav navbar-nav flex-wrap">
                    <li class="nav-item">
                      <a class="nav-link ${data.navTab === 'home' ? 'active' : ''}" aria-current="page" href="${nav.repoCurrentBranchHome()}">Home</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link ${data.navTab === 'files' ? 'active' : ''}" href="${nav.repoCurrentBranchFiles()}">Files</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link ${data.navTab === 'commits' ? 'active' : ''}" href="${nav.repoCurrentBranchCommits()}">Commits</a>
                    </li>
                    <li class="nav-item">
                      <a class="nav-link ${data.navTab === 'branches' ? 'active' : ''}" href="${nav.repoCurrentBranchBranches()}">Branches</a>
                    </li>
                  </ul>
                </nav>
              </div>
            </div>

            <div class="row">
              <div class="col-12">
                ${await pageContent(eleventyConfig, data, nav)}
              </div>
            </div>

          </div>
          <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>
          <script src="${nav.rootPath()}frontend/main-frontend.bundle.js"></script>
        </body>
      </html>
      `
=======
  return {
    rootPath: nav.rootPath(),
    pageTitle: repo.name,
    additionalHeadContent: [
      m('script', m.trust(`
        window.branchesWithHrefs = ${JSON.stringify(branchesWithHrefs)};
        window.defaultBranch = "${repo.defaultBranch}";
        window.currentBranch = "${branch.name}";
        window.cloneUrl = "${repo.cloneUrl}";
      `)),
      m('link', {
        rel: "stylesheet",
        id: "prism-theme",
        type: "text/css",
        href: `${data.reposPath}/vendor/prism.css`
      }),
    ],
    navbarContent: m('nav', {class: "navbar navbar-expand"}, [
      m('ul', {class: "navbar-nav flex-wrap"}, [
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.rootPath()
          }, m.trust('&#10094; Repos'))
        ),
        m('li', {class: "nav-item"},
          m('a', {
            class: "nav-link",
            href: nav.repoCurrentBranchHome()
          }, repo.name)
        ),
        m('li', {class: "nav-item"}, [
          m('span', {class: "nav-link d-inline-block"}, 'Branch:'),
          m('div', {class: "branch-selector dropdown-center d-inline-block"}, [
            m('button', {
              class: "branches nav-link d-inline-block btn btn-bg dropdown-toggle",
              'data-bs-toggle': "dropdown",
              'data-bs-auto-close': "outside",
              'aria-expanded': "false"
            }, branch.name),
            m('div', {class: "dropdown-menu"}, [
              m('form', {class: "mx-3 my-1"}, [
                m('input', {type: "text", class: "form-control", id: "dropdownBranchSearch", placeholder: "Search branches..."}),
                m('div', [
                  m('div', {class: "row mt-3"},
                    m('div', {class: "col"},
                      m('label', {class: "form-label"}, 'Sort by:')
                    )
                  ),
                  m('div', {class: "sortRadioButtons"}, [
                    m('div', {class: "sortRadioButton pe-1"}, [
                      m('input', {class: "form-check-input sort-filter", type: "radio", name: "branchSort", value: 'date', id: "branchSortByDate", checked: true}),
                      m('label', {class: "form-check-label", for: "branchSortByDate"}, 'Last commit')
                    ]),
                    m('div', {class: "sortRadioButton ps-1"}, [
                      m('input', {class: "form-check-input sort-filter", type: "radio", name: "branchSort", value: 'name', id: "branchSortByName"}),
                      m('label', {class: "form-check-label", for: "branchSortByName"}, 'Name')
                    ])
                  ])
                ])
              ]),
              m('div', {class: "dropdown-divider"}),
              m('div', {id: "dropdown-branches-results", class: "dropdown-branches"},
                branchesListItems(branchesWithHrefs, repo.defaultBranch, branch.name, 'date')
              )
            ])
          ])
        ])
      ])
    ]),
    pageContent: [
      m('div', {class: "row"},
        m('div', {class: "col"},
          m('nav', {class: "navbar navbar-expand"},
            m('ul', {class: "main-nav navbar-nav flex-wrap"}, [
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'home' ? 'active' : ''}`, 'aria-current': "page", href: nav.repoCurrentBranchHome()}, 'Home')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'files' ? 'active' : ''}`, href: nav.repoCurrentBranchFiles()}, 'Files')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'commits' ? 'active' : ''}`, href: nav.repoCurrentBranchCommits()}, 'Commits')
              ),
              m('li', {class: "nav-item"},
                m('a', {class: `nav-link ${data.navTab === 'branches' ? 'active' : ''}`, href: nav.repoCurrentBranchBranches()}, 'Branches')
              )
            ])
          )
        )
      ),
      m('div', {class: "row"},
        m('div', {class: "col-12"},
          await pageContent
        )
      ),
    ]
>>>>>>> main
  }
}
After







































































































































































































































































⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
js_templates/feed.ts:1
Before
0
1
2
3
4
5
import m from 'mithril'
import render from 'mithril-node-render'
import { type Repository } from '../src/dataTypes.ts'
import getFlatRels from '../src/flatRels.ts'
import { dateToRfc3339 } from '@11ty/eleventy-plugin-rss'
import flatPatches from '../src/flatPatches.ts'
After
0
1
2
3
4
5
import m from 'mithril'
import render from 'mithril-node-render'
import { type Repository } from '../src/dataTypes.ts'
import getFlatRefs from '../src/flatRefs.ts'
import { dateToRfc3339 } from '@11ty/eleventy-plugin-rss'
import flatPatches from '../src/flatPatches.ts'
js_templates/feed.ts:9
Before
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
  eleventyConfig: any,
) => {
  return (data) => {
    const flatRel: ReturnType<typeof getFlatRels>[0] = data.flatRel
    const currentRepo: Repository = data.currentRepo
    const currentRel: Repository['branches'][0] = data.currentRel
    const currentRelCommits: Awaited<ReturnType<typeof flatPatches>> = data.currentRelCommits

    const slugify = eleventyConfig.getFilter("slugify")

    return render([
      m.trust('<?xml version="1.0" encoding="utf-8"?>'),
      m('feed', {xmlns: "http://www.w3.org/2005/Atom"}, [
        m('title', `Latest patches in ${flatRel.relName}`),
        m.trust(`<link href="${ data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName) + '/commits.xml'}" rel="self" />`),
        m.trust(`<link href="${data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName)}" />`),
        m('updated', dateToRfc3339(currentRepo.commits.get(currentRel.sha).date)),
        m('id', data.reposConfig.baseUrl),
        m('author',
          m('name', `${currentRepo.name} contributors`)
        ),
        currentRelCommits.map((commit) => {
          const commitUrl = data.reposConfig.baseUrl + '/repos/' + slugify(flatRel.repoName) + `/${flatRel.type}/` + slugify(flatRel.relName) + '/commits/' + commit.commit.hash
          return m('entry', [
            m('title', commit.commit.message.split('\n')[0]),
            m('author', m('name', commit.commit.author)),
After
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
  eleventyConfig: any,
) => {
  return (data) => {
    const flatRef: ReturnType<typeof getFlatRefs>[0] = data.flatRef
    const currentRepo: Repository = data.currentRepo
    const currentRef: Repository['branches'][0] = data.currentRef
    const currentRefCommits: Awaited<ReturnType<typeof flatPatches>> = data.currentRefCommits

    const slugify = eleventyConfig.getFilter("slugify")

    return render([
      m.trust('<?xml version="1.0" encoding="utf-8"?>'),
      m('feed', {xmlns: "http://www.w3.org/2005/Atom"}, [
        m('title', `Latest patches in ${flatRef.refName}`),
        m.trust(`<link href="${ data.reposConfig.baseUrl + '/repos/' + slugify(flatRef.repoName) + `/${flatRef.type}/` + slugify(flatRef.refName) + '/commits.xml'}" rel="self" />`),
        m.trust(`<link href="${data.reposConfig.baseUrl + '/repos/' + slugify(flatRef.repoName) + `/${flatRef.type}/` + slugify(flatRef.refName)}" />`),
        m('updated', dateToRfc3339(currentRepo.commits.get(currentRef.sha).date)),
        m('id', data.reposConfig.baseUrl),
        m('author',
          m('name', `${currentRepo.name} contributors`)
        ),
        currentRefCommits.map((commit) => {
          const commitUrl = data.reposConfig.baseUrl + '/repos/' + slugify(flatRef.repoName) + `/${flatRef.type}/` + slugify(flatRef.refName) + '/commits/' + commit.commit.hash
          return m('entry', [
            m('title', commit.commit.message.split('\n')[0]),
            m('author', m('name', commit.commit.author)),
js_templates/file.ts:15
Before
14
15
16
17
18
19
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")

  const currentRel: Branch = data.currentRel
  const fileInfo: FlatFileEntry = data.fileInfo

  const pageContent = [  
After
14
15
16
17
18
19
  const languageExtension = eleventyConfig.getFilter("languageExtension")
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")

  const currentRef: Branch = data.currentRef
  const fileInfo: FlatFileEntry = data.fileInfo

  const pageContent = [  
js_templates/file.ts:96
Before
95
96
97
98
99
100
            m('div', {class: "row rendered-content"},
              m('div', {class: "col"},
                m.trust(await renderContentIfAvailable(
                  currentRel.fileList.get(fileInfo.file).fileInfo.contents
                ))
              )
            )
After
95
96
97
98
99
100
            m('div', {class: "row rendered-content"},
              m('div', {class: "col"},
                m.trust(await renderContentIfAvailable(
                  currentRef.fileList.get(fileInfo.file).fileInfo.contents
                ))
              )
            )
js_templates/file.ts:116
Before
115
116
117
118
119
120
              m('div', {class: "col-auto p-0"},
                m('code', {style: "white-space: pre;"},
                  m('pre', {class: "language-text"},
                    lineNumbers(currentRel.fileList.get(fileInfo.file).fileInfo.contents).map((lineNumber) => {
                      return lineNumber
                    }).join('\n')
                  )
After
115
116
117
118
119
120
              m('div', {class: "col-auto p-0"},
                m('code', {style: "white-space: pre;"},
                  m('pre', {class: "language-text"},
                    lineNumbers(currentRef.fileList.get(fileInfo.file).fileInfo.contents).map((lineNumber) => {
                      return lineNumber
                    }).join('\n')
                  )
js_templates/file.ts:125
Before
124
125
126
127
128
129
130
131
132
133
134
135
136
              m('div', {id: "annotations", class: "col-auto d-none p-0"},
                m('code', {style: "white-space: pre;"}, [
                  m('pre', {class: "language-text"}, m.trust(
                    currentRel.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
                      return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branch/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
                    }).join('\n')))
                ])
              ),
              m('div', {class: "col overflow-scroll p-0"},
                m('code', m.trust(highlightCode(
                  currentRel.fileList.get(fileInfo.file).fileInfo.contents,
                  languageExtension(
                    fileInfo.file,
                    fileInfo.repoName
After
124
125
126
127
128
129
130
131
132
133
134
135
136
              m('div', {id: "annotations", class: "col-auto d-none p-0"},
                m('code', {style: "white-space: pre;"}, [
                  m('pre', {class: "language-text"}, m.trust(
                    currentRef.fileList.get(fileInfo.file).fileInfo.blameLines.map((annotation) => {
                      return `<a href="${data.reposPath}/${slugify(fileInfo.repoName)}/branch/${slugify(fileInfo.branchName)}/commits/${annotation.sha}">${annotation.sha.substr(0, 6)}</a> ${annotation.author}`
                    }).join('\n')))
                ])
              ),
              m('div', {class: "col overflow-scroll p-0"},
                m('code', m.trust(highlightCode(
                  currentRef.fileList.get(fileInfo.file).fileInfo.contents,
                  languageExtension(
                    fileInfo.file,
                    fileInfo.repoName
js_templates/files.ts:3
Before
2
3
4
5
6
7
import htmlPage from './common/htmlPage.ts'

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const branch: Repository['branches'][0] = data.currentRel
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const slugify = eleventyConfig.getFilter("slugify")
After
2
3
4
5
6
7
import htmlPage from './common/htmlPage.ts'

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const branch: Repository['branches'][0] = data.currentRef
  const topLevelFilesOnly = eleventyConfig.getFilter("topLevelFilesOnly")
  const slugify = eleventyConfig.getFilter("slugify")
js_templates/files.ts:14
Before
13
14
15
16
17
18
      m('div', {class: "col"},
        m('p', [
          'Files snapshot from ',
          m('span', {class: "font-monospace"}, data.flatRel.relName)
        ])
      )
    ]),
After
13
14
15
16
17
18
      m('div', {class: "col"},
        m('p', [
          'Files snapshot from ',
          m('span', {class: "font-monospace"}, data.flatRef.relName)
        ])
      )
    ]),
js_templates/files.ts:27
Before
26
27
28
29
30
31
      return m('li', {class: 'list-group-item'}, [
        file.isDirectory ? m.trust('<span>&#x1F4C1;&nbsp;</span>') : null,
        m('a', {
          href: `${data.reposPath}/${slugify(data.flatRel.repoName)}/branch/${slugify(data.flatRel.relName)}/files/${
            file.fullPath.split('/')
            .map((pathPart) => {
              return pathPart.split('.').map((subPart) => {
After
26
27
28
29
30
31
      return m('li', {class: 'list-group-item'}, [
        file.isDirectory ? m.trust('<span>&#x1F4C1;&nbsp;</span>') : null,
        m('a', {
          href: `${data.reposPath}/${slugify(data.flatRef.repoName)}/branch/${slugify(data.flatRef.relName)}/files/${
            file.fullPath.split('/')
            .map((pathPart) => {
              return pathPart.split('.').map((subPart) => {
js_templates/helpers/nav.ts:1
Before
0
1















2
3
4
5
6
7
8

9
10
11
12




13
14
15
import { type ReposConfiguration } from "../../src/configTypes.ts"

⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
export const NavHelper = (reposConfig: ReposConfiguration, slugify: Function, repoName: string, branchName: string) => {
  const reposPath = reposConfig.path || ""

  // These two aren't actually used by any pages, but they're in almost
  // every page URL. E.g. all of them start with 'repos/my-repo-name'
  // or 'repos/my-repo-name/branches.'
  const repoBasePath = `${reposPath}/${slugify(repoName)}`
⁣
  const rootBasePathBranches = `${repoBasePath}/branch`
  const rootBasePathTags = `${repoBasePath}/tag`

  const currentBranchPath = `${rootBasePathBranches}/${slugify(branchName)}`
⁣
⁣
⁣
⁣
  const repoBranchCommitsBase = `${currentBranchPath}/commits/`

  return {
    rootPath: () => {
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
import { type ReposConfiguration } from "../../src/configTypes.ts"

/**
 * Returns links to various pages used by the default template. Will return a link
 * that assumes you want to stay on the current ref, unless you give a new ref in
 * the function argument. E.g if you are currently at /tags/v-1-0/, and you call
 * the commits() function, it'll give you /tag/v-1-0/commits, unless you pass in
 * an argument like commits({refName: 'main', refType: 'branch'}), in which case
 * it'll give you /branch/main/commits.
 */
type CurrentRefArgs = {
  reposConfig: ReposConfiguration,
  slugify: Function,
  currentRepoName: string,
  currentRefName: string,
  currentRefType: 'branch' | 'tag'
}
export const NavHelper = (args: CurrentRefArgs) => {
  const reposPath = args.reposConfig.path || ""

  // These two aren't actually used by any pages, but they're in almost
  // every page URL. E.g. all of them start with 'repos/my-repo-name'
  // or 'repos/my-repo-name/branches.'
  const repoBasePath = `${reposPath}/${args.slugify(args.currentRepoName)}`

⁣
⁣
⁣
  const refPath = (refName, refType) => `${repoBasePath}/${refType}/${args.slugify(refName)}`

  type RefArgument = {
    refName: string,
    refType: 'branch' | 'tag'
  }

  return {
    rootPath: () => {
js_templates/helpers/nav.ts:23
Before
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
      }
    },
    repoHomePath: () => {
      return `${rootBasePathBranches}/${slugify(reposConfig.repos[repoName].defaultBranch)}`
    },
    repoCurrentBranchHome: () => {
⁣
⁣
⁣
      return currentBranchPath
⁣
⁣
    },
    repoBranchHome: (branchName: string) => {
⁣
⁣
⁣
      return `${rootBasePathBranches}/${slugify(branchName)}`
    },
    repoTagHome: (tagName: string) => {
⁣
⁣
⁣
      return `${rootBasePathTags}/${slugify(tagName)}`
    },
    repoCurrentBranchFiles: () => {
⁣
⁣
⁣
      return `${currentBranchPath}/files`
    },
    repoBranchCommitsBase: () => repoBranchCommitsBase,
⁣
⁣
⁣
⁣
    repoCurrentBranchCommits: () => `${repoBranchCommitsBase}page1`,
    repoCurrentBranchBranches: () => `${currentBranchPath}/branches`,
    // TODO: change these "currentBranch"es to "currentRel"s
⁣
⁣
⁣
    repoCurrentBranchTags: () => `${currentBranchPath}/tags`,
⁣
⁣
⁣
⁣
⁣
    repoCurrentBranchRssFeed: () => `${currentBranchPath}/commits.xml`,
    homepageButtons: reposConfig.repos[repoName].defaultTemplateConfiguration?.homepageButtons || []
  }
}
After
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
      }
    },
    repoHomePath: () => {
      return repoBasePath
    },
    refHome: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return (refType === 'branch' && refName === args.reposConfig.repos[args.currentRepoName].defaultBranch)
               ? repoBasePath
               : refPath(refName, refType)
    },
    files: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/files`
    },
    commit: (hash: string, newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/commits/${hash}`
    },
    commits: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/commits/page1`
    },
    branches: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/branches`
    },
    tags: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/tags`
    },
    rssFeed: (newRef: RefArgument = null) => {
      const refName = newRef?.refName || args.currentRefName
      const refType = newRef?.refType || args.currentRefType

      return `${refPath(refName, refType)}/commits.xml`
    },
    homepageButtons: args.reposConfig.repos[args.currentRepoName].defaultTemplateConfiguration?.homepageButtons || []
  }
}
js_templates/raw.ts:3
Before
2
3
4
5
6
7

export default async (eleventyConfig: any) => {
  return async (data) => {
    const branch: Branch = data.currentRel

    return branch.fileList.get(data.fileInfo.file).fileInfo.contents
  }
After
2
3
4
5
6
7

export default async (eleventyConfig: any) => {
  return async (data) => {
    const branch: Branch = data.currentRef

    return branch.fileList.get(data.fileInfo.file).fileInfo.contents
  }
js_templates/repo.ts:5
Before
4
5
6
7
8
9
10
11
12
13
14
15






16
17
18
19
20

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const rel: Repository['branches'][0] | Repository['tags'][0] = data.currentRel
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const slugify = eleventyConfig.getFilter("slugify")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  const latestCommit = repo.commits.get(rel.sha)
  const latestCommitMessage = latestCommit.message.length > 72
    ? latestCommit.message.split('\n')[0].substr(0, 72) + '...'
    : latestCommit.message

⁣
⁣
⁣
⁣
⁣
⁣
  const nav = NavHelper(reposConfig, slugify, repo.name, rel.name)

  const languageCounts = Array.from(rel.fileList.keys()).reduce((counts, currentFile) => {
    const fileParts = currentFile.split(".")
    const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
After
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

export default async (reposConfig: any, eleventyConfig: any, data: any) => {
  const repo: Repository = data.currentRepo
  const ref: Repository['branches'][0] | Repository['tags'][0] = data.currentRef
  const renderContentIfAvailable = eleventyConfig.getFilter("renderContentIfAvailable")
  const slugify = eleventyConfig.getFilter("slugify")
  const getReadMe = eleventyConfig.getFilter("getReadMe")
  const latestCommit = repo.commits.get(ref.sha)
  const latestCommitMessage = latestCommit.message.length > 72
    ? latestCommit.message.split('\n')[0].substr(0, 72) + '...'
    : latestCommit.message

  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: repo.name,
    currentRefName: data.flatRef.name,
    currentRefType: data.flatRef.type,
  })

  const languageCounts = Array.from(ref.fileList.keys()).reduce((counts, currentFile) => {
    const fileParts = currentFile.split(".")
    const fileExtension = fileParts[fileParts.length - 1]
// todo: add more ignoreable extensions or specific files
js_templates/repo.ts:31
Before
30
31
32
33
34
35

  // todo: this is probably broken for repos that use fewer than 6 languages
  let languagePercentages: Array<[string, number]> = []
  const total = Array.from(rel.fileList.keys()).length

  for (const entry of languageCounts) {
    languagePercentages.push([entry[0], entry[1] / total])
After
30
31
32
33
34
35

  // todo: this is probably broken for repos that use fewer than 6 languages
  let languagePercentages: Array<[string, number]> = []
  const total = Array.from(ref.fileList.keys()).length

  for (const entry of languageCounts) {
    languagePercentages.push([entry[0], entry[1] / total])
js_templates/repo.ts:46
Before
45
46
47
48
49
50

  const largestPercent = Math.max(...topLanguagePercentages.map(tuple => tuple[1]), otherLanguagePercent)

  const readmeContent = await renderContentIfAvailable(await getReadMe(repo.name, rel.name), rel.name)

  const pageContent = [
    m('div', {class: "row"}, [
After
45
46
47
48
49
50

  const largestPercent = Math.max(...topLanguagePercentages.map(tuple => tuple[1]), otherLanguagePercent)

  const readmeContent = await renderContentIfAvailable(await getReadMe(repo.name, ref.name), ref.name)

  const pageContent = [
    m('div', {class: "row"}, [
js_templates/repo.ts:103
Before
102
103
104
105
106
107
108
109
110
111
112
          m('div', {class: "row mt-2"}, [
            m('div', {class: "col"}, [
              m('p', {class: "font-monospace text-white mb-2 d-inline-block"}, [
                m('a', {class: "btn btn-outline-info badge shadow-none me-2", href: nav.repoCurrentBranchRssFeed()}, [
                  m('img', {src: `${nav.rootPath()}frontend/img/rss-icon.svg`, style: "width: 11px; margin-right: 5px;"}),
                  'RSS'
                ]),
                `Latest commit: ${latestCommit.date.toDateString()} `,
                m('a', {class: "fw-bold link-info", href: `${nav.repoBranchCommitsBase()}${latestCommit.hash}`}, latestCommit.hash.substr(0, 6)),
                ' ',
                latestCommitMessage,
              ])
After
102
103
104
105
106
107
108
109
110
111
112
          m('div', {class: "row mt-2"}, [
            m('div', {class: "col"}, [
              m('p', {class: "font-monospace text-white mb-2 d-inline-block"}, [
                m('a', {class: "btn btn-outline-info badge shadow-none me-2", href: nav.rssFeed()}, [
                  m('img', {src: `${nav.rootPath()}frontend/img/rss-icon.svg`, style: "width: 11px; margin-right: 5px;"}),
                  'RSS'
                ]),
                `Latest commit: ${latestCommit.date.toDateString()} `,
                m('a', {class: "fw-bold link-info", href: `${nav.commit(latestCommit.hash)}`}, latestCommit.hash.substr(0, 6)),
                ' ',
                latestCommitMessage,
              ])
js_templates/tags.ts:8
Before
7
8
9






10
11
12
13
14
15
16
17
18
19
20
21
22
23
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
⁣
⁣
⁣
⁣
⁣
⁣
  const nav = NavHelper(reposConfig, slugify, data.flatRel.repoName, data.flatRel.relName)

  const tags = data.flatRels.filter(rel => rel.type === "tag")

  const branchCards = (tags) => {
    return m('ul', tags.map((tag) => {
      return tag.repoName === data.flatRel.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(tag.repoName)}/tag/${slugify(tag.relName)}/tags`
          }, tag.relName),
          tag.relName === data.flatRel.relName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          m('ul', [
            tag.description ? m('li', tag.description) : null
After
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
  data: any,
) => {
  const slugify = eleventyConfig.getFilter("slugify")
  const nav = NavHelper({
    reposConfig,
    slugify,
    currentRepoName: data.flatRef.repoName,
    currentRefName: data.flatRef.refName,
    currentRefType: data.flatRef.refType,
  })

  const tags = data.flatRefs.filter(ref => ref.type === "tag")

  const branchCards = (tags) => {
    return m('ul', tags.map((tag) => {
      return tag.repoName === data.flatRef.repoName ?
        m('li', [
          m('a', {
            href: `${data.reposPath}/${slugify(tag.repoName)}/tag/${slugify(tag.refName)}/tags`
          }, tag.refName),
          tag.refName === data.flatRef.refName
            ? m('div', {class: "badge rounded-pill bg-secondary mx-1"}, 'current') : null,
          m('ul', [
            tag.description ? m('li', tag.description) : null
main.ts:2
Before
1
2
3
4
5
6
import util from 'util'
import childProcess from 'child_process'
import {repos, getBranchesAndTags} from './src/repos.ts'
import getFlatRels from './src/flatRels.ts'
import flatFiles from './src/flatFiles.ts'
import flatPatches from './src/flatPatches.ts'
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
After
1
2
3
4
5
6
import util from 'util'
import childProcess from 'child_process'
import {repos, getBranchesAndTags} from './src/repos.ts'
import getFlatRefs from './src/flatRefs.ts'
import flatFiles from './src/flatFiles.ts'
import flatPatches from './src/flatPatches.ts'
import paginatedPatches, {type PatchPage} from './src/paginatedPatches.ts'
main.ts:89
Before
88
89
90
91
92
93
94
  eleventyConfig.addGlobalData("reposConfig", reposConfiguration)
  eleventyConfig.addGlobalData("reposPath", reposPath)

  const flatRels = getFlatRels(reposData)
  eleventyConfig.addGlobalData("flatRels", flatRels)

  eleventyConfig.addFilter("getFileName", (filePath: string) => {
    const pathParts = filePath.split("/")
After
88
89
90
91
92
93
94
  eleventyConfig.addGlobalData("reposConfig", reposConfiguration)
  eleventyConfig.addGlobalData("reposPath", reposPath)

  const flatRefs = getFlatRefs(reposData)
  eleventyConfig.addGlobalData("flatRefs", flatRefs)

  eleventyConfig.addFilter("getFileName", (filePath: string) => {
    const pathParts = filePath.split("/")
main.ts:254
Before
253
254
255
256
257
258
259
    return isDirectory
  })

  eleventyConfig.addFilter("pagesJustForRel", (pages: Array<PatchPage>, repoName: string, relName: string, relType: "branch" | "tag") => {
    return pages.filter(page => page.repoName === repoName && page.relName === relName && page.type === relType)
  })

  eleventyConfig.addFilter("date", (dateString: string) => {
After
253
254
255
256
257
258
259
    return isDirectory
  })

  eleventyConfig.addFilter("pagesJustForRef", (pages: Array<PatchPage>, repoName: string, refName: string, refType: "branch" | "tag") => {
    return pages.filter(page => page.repoName === repoName && page.refName === refName && page.type === refType)
  })

  eleventyConfig.addFilter("date", (dateString: string) => {
main.ts:296
Before
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
    commonPage(branchesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/branches/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: "branches"
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          const currentRepo = reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })
          return currentRepo[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
⁣
      },
      navTab: "branches",
    }
After
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    commonPage(branchesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRefs",
        size: 1,
        alias: "flatRef",
      },
      permalink: (data) => {
        const repoName = data.flatRef.repoName
        const refName = data.flatRef.refName
        const refType = data.flatRef.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/branches/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRef.repoName,
          refName: (data) => data.flatRef.refName,
          path: "branches"
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRef.repoName
        }),
        currentRef: (data) => {
          const refType = data.flatRef.type === "branch" ? "branches" : "tags"
          const currentRepo = reposData.find(repo => {
            return repo.name === data.flatRef.repoName
          })
          return currentRepo[refType].find(ref => {
            return ref.name === data.flatRef.refName
          })
        },
        currentRefType: (data) => data.flatRef.type,
      },
      navTab: "branches",
    }
main.ts:335
Before
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
    commonPage(tagsJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/tags/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: "tags"
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          const currentRepo = reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })
          return currentRepo[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
⁣
      },
      navTab: "tags",
    }
After
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    commonPage(tagsJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRefs",
        size: 1,
        alias: "flatRef",
      },
      permalink: (data) => {
        const repoName = data.flatRef.repoName
        const refName = data.flatRef.refName
        const refType = data.flatRef.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/tags/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRef.repoName,
          refName: (data) => data.flatRef.refName,
          path: "tags"
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRef.repoName
        }),
        currentRef: (data) => {
          const refType = data.flatRef.type === "branch" ? "branches" : "tags"
          const currentRepo = reposData.find(repo => {
            return repo.name === data.flatRef.repoName
          })
          return currentRepo[refType].find(ref => {
            return ref.name === data.flatRef.refName
          })
        },
        currentRefType: (data) => data.flatRef.type,
      },
      navTab: "tags",
    }
main.ts:383
Before
382
383
384
385
386
387
388
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const relType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(branchName)}/files/${data.fileInfo.file.split('/').map((filePart) => filePart.split('.').map((subPart) => eleventyConfig.getFilter("slugify")(subPart)).join('.')).join('/')}.html`
      },
      eleventyComputed: {
        nav: {
After
382
383
384
385
386
387
388
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const refType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(branchName)}/files/${data.fileInfo.file.split('/').map((filePart) => filePart.split('.').map((subPart) => eleventyConfig.getFilter("slugify")(subPart)).join('.')).join('/')}.html`
      },
      eleventyComputed: {
        nav: {
main.ts:395
Before
394
395
396
397
398
399
400
401

402
403
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }),
        currentRel: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
        }),
⁣
      },
      navTab: "files",
    }
After
394
395
396
397
398
399
400
401
402
403
404
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }),
        currentRef: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
        }),
        currentRefType: (data) => data.fileInfo.refType,
      },
      navTab: "files",
    }
main.ts:420
Before
419
420
421
422
423
424
425
426
427
428
429
430

431
432
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const relType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => eleventyConfig.getFilter("slugify")(filePart)).join('.')}`
      },
      eleventyComputed: {
        currentRel: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
        }),
⁣
      }
    }
  )
After
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
      permalink: (data) => {
        const repoName = data.fileInfo.repoName
        const branchName = data.fileInfo.branchName
        const refType = data.fileInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(branchName)}/raw/${data.fileInfo.file.split('.').map(filePart => eleventyConfig.getFilter("slugify")(filePart)).join('.')}`
      },
      eleventyComputed: {
        currentRef: (data) => reposData.find(repo => {
          return repo.name === data.fileInfo.repoName
        }).branches.find(branch => {
          return branch.name === data.fileInfo.branchName
        }),
        currentRefType: (data) => data.fileInfo.refType,
      }
    }
  )
main.ts:439
Before
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467

468
469
    commonPage(filesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/files/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: "files",
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
⁣
      },
      navTab: "files",
    }
After
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
    commonPage(filesJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRefs",
        size: 1,
        alias: "flatRef",
      },
      permalink: (data) => {
        const repoName = data.flatRef.repoName
        const refName = data.flatRef.refName
        const refType = data.flatRef.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/files/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRef.repoName,
          refName: (data) => data.flatRef.refName,
          path: "files",
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRef.repoName
        }),
        currentRef: (data) => {
          const refType = data.flatRef.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRef.repoName
          })[refType].find(ref => {
            return ref.name === data.flatRef.refName
          })
        },
        currentRefType: (data) => data.flatRef.type,
      },
      navTab: "files",
    }
main.ts:477
Before
476
477
478
479
480
481
482
483
484
485
486




487

488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

506
507
    commonPage(repoJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
⁣
⁣
⁣
⁣
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/`
⁣
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRel.repoName,
          relName: (data) => data.flatRel.relName,
          path: (data) => '', // TODO: ask about why empty string here shows up as a function
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        }
⁣
      },
      navTab: "home"
    }
After
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
    commonPage(repoJsTemplate, reposConfiguration, eleventyConfig),
    {
      pagination: {
        data: "flatRefs",
        size: 1,
        alias: "flatRef",
      },
      permalink: (data) => {
        const repoName = data.flatRef.repoName
        const refName = data.flatRef.refName
        const refType = data.flatRef.type
        if (refType === "branch" && refName === reposConfiguration.repos[repoName].defaultBranch) {
          return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/`
        }
        else {
          return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/`
        }
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.flatRef.repoName,
          refName: (data) => data.flatRef.refName,
          path: (data) => '', // TODO: ask about why empty string here shows up as a function
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRef.repoName
        }),
        currentRef: (data) => {
          const refType = data.flatRef.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRef.repoName
          })[refType].find(ref => {
            return ref.name === data.flatRef.refName
          })
        },
        currentRefType: (data) => data.flatRef.type
      },
      navTab: "home"
    }
main.ts:523
Before
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545

546
547
      paginatedPatches: paginatedPatchesData,
      permalink: (data) => {
        const repoName = data.patchPage.repoName
        const relName = data.patchPage.relName
        const relType = data.patchPage.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits/page${data.patchPage.pageNumber}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchPage.repoName,
          relName: (data) => data.patchPage.relName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchPage.repoName
        }),
        currentRel: (data) => {
          const relType = data.patchPage.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchPage.repoName
          })[relType].find(rel => {
            return rel.name === data.patchPage.relName
          })
        }
⁣
      },
      navTab: "commits",
    }
After
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
      paginatedPatches: paginatedPatchesData,
      permalink: (data) => {
        const repoName = data.patchPage.repoName
        const refName = data.patchPage.refName
        const refType = data.patchPage.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/commits/page${data.patchPage.pageNumber}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchPage.repoName,
          refName: (data) => data.patchPage.refName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchPage.repoName
        }),
        currentRef: (data) => {
          const refType = data.patchPage.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchPage.repoName
          })[refType].find(ref => {
            return ref.name === data.patchPage.refName
          })
        },
        currentRefType: (data) => data.patchPage.type,
      },
      navTab: "commits",
    }
main.ts:563
Before
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
      flatPatches: flatPatchesData,
      permalink: (data) => {
        const repoName = data.patchInfo.repoName
        const relName = data.patchInfo.relName
        const relType = data.patchInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits/${data.patchInfo.commit.hash}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchInfo.repoName,
          relName: (data) => data.patchInfo.relName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchInfo.repoName
        }),
        currentRel: (data) => {
          const relType = data.patchInfo.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchInfo.repoName
          })[relType].find(rel => {
            return rel.name === data.patchInfo.relName
          })
        },
⁣
      },
      navTab: "commits",
    }
After
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
      flatPatches: flatPatchesData,
      permalink: (data) => {
        const repoName = data.patchInfo.repoName
        const refName = data.patchInfo.refName
        const refType = data.patchInfo.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/commits/${data.patchInfo.commit.hash}/`
      },
      eleventyComputed: {
        nav: {
          repoName: (data) => data.patchInfo.repoName,
          refName: (data) => data.patchInfo.refName,
          path: 'commits/page1',
        },
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.patchInfo.repoName
        }),
        currentRef: (data) => {
          const refType = data.patchInfo.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.patchInfo.repoName
          })[refType].find(ref => {
            return ref.name === data.patchInfo.refName
          })
        },
        currentRefType: (data) => data.patchInfo.type
      },
      navTab: "commits",
    }
main.ts:595
Before
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618

619
620
621
622
623
    feedJsTemplate(eleventyConfig),
    {
      pagination: {
        data: "flatRels",
        size: 1,
        alias: "flatRel",
      },
      permalink: (data) => {
        const repoName = data.flatRel.repoName
        const relName = data.flatRel.relName
        const relType = data.flatRel.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${relType}/${eleventyConfig.getFilter("slugify")(relName)}/commits.xml`
      },
      eleventyComputed: {
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRel.repoName
        }),
        currentRel: (data) => {
          const relType = data.flatRel.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRel.repoName
          })[relType].find(rel => {
            return rel.name === data.flatRel.relName
          })
        },
⁣
        currentRelCommits: (data) => {
          return flatPatchesData.filter((patch) => {
            return patch.relName === data.flatRel.relName
          })
        }
      },
After
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
    feedJsTemplate(eleventyConfig),
    {
      pagination: {
        data: "flatRefs",
        size: 1,
        alias: "flatRef",
      },
      permalink: (data) => {
        const repoName = data.flatRef.repoName
        const refName = data.flatRef.refName
        const refType = data.flatRef.type
        return `${reposPath}/${eleventyConfig.getFilter("slugify")(repoName)}/${refType}/${eleventyConfig.getFilter("slugify")(refName)}/commits.xml`
      },
      eleventyComputed: {
        currentRepo: (data) => reposData.find(repo => {
          return repo.name === data.flatRef.repoName
        }),
        currentRef: (data) => {
          const refType = data.flatRef.type === "branch" ? "branches" : "tags"
          return reposData.find(repo => {
            return repo.name === data.flatRef.repoName
          })[refType].find(ref => {
            return ref.name === data.flatRef.refName
          })
        },
        currentRefType: (data) => data.flatRef.type,
        currentRefCommits: (data) => {
          return flatPatchesData.filter((patch) => {
            return patch.refName === data.flatRef.refName
          })
        }
      },
src/__tests__/fixtures/patches.js:0
Before









































⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
After
-1
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
const singleCommit = `
commit 0d861762014e3ae60bca789653df9e3698d3eff3
Author: Tucker McKnight <tmcknight@instructure.com>
Date:   Sat Mar 14 13:24:39 2026 -0600

    third commit

diff --git a/README.md b/README.md
index deef711..fb2b345 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,3 @@
-initial commit text
+initial commit inline change text
+third commit
 second commit
`

const largerCommit = `
commit b517d8290796b45d05de989e438508efe03be324
Author: Tucker McKnight <tmcknight@instructure.com>
Date:   Sat Mar 7 19:57:20 2026 -0700

    add colors to language bar chart

diff --git a/new-commits-page.html b/new-commits-page.html
index 03aff8f..5e85d9b 100644
--- a/new-commits-page.html
+++ b/new-commits-page.html
@@ -10,6 +10,8 @@
     <div class="container commits-page">
       <div class="row m-2">
         <div class="col">
+
+          <!-- A COMMIT -->
           <div class="row commit">
             <div class="col">
               <div class="row">
`

export {
  singleCommit,
  largerCommit,
}
src/__tests__/helpers.test.js:0
Before






⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
After
-1
0
1
2
3
4
5
6
import { expect, test } from 'vitest'
import { getGitDiffsFromPatchText } from '../../dist/src/helpers.js'
import { singleCommit, largerCommit } from './fixtures/patches.js'

test("asdf", () => {
  const result = getGitDiffsFromPatchText(largerCommit)
  console.log(result[0])
  expect(true).toBe(true)
})
src/dataTypes.ts.orig: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
export type Repository = {
  name: string,
  description?: string,
  cloneUrl: string,
  defaultBranch: string,
  branches: Array<{
    name: string,
    head: string,
    fileList: Array<string>,
  }>,
  tags?: Array<{
    name: string,
    sha: string,
    fileList: Array<string>,
  }>,
<<<<<<< HEAD
  commits: Map<string, {
    hash: string,
=======
  commits?: Map<string, {
>>>>>>> 359136b (allow commit references to be null, e.g. for the first commit which has no parent)
    message: string,
    author: string,
    date: Date,
    parent: string | null,
    diffs: Array<{
      fileName: string,
      lineNumber: number,
      beforeText: string,
      afterText: string,
    }>
  }>,
}
After






























⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
⁣
src/flatPatches.ts:3
Before
2
3
4
5
6
7
type FlatPatchRecord = {
  commit: ReturnType<Repository['commits']['get']>,
  repoName: string,
  relName: string,
  type: "branch" | "tag",
}
After
2
3
4
5
6
7
type FlatPatchRecord = {
  commit: ReturnType<Repository['commits']['get']>,
  repoName: string,
  refName: string,
  type: "branch" | "tag",
}
src/flatPatches.ts:23
Before
22
23
24
25
26
27
          type: "branch",
          commit: currentCommit,
          repoName: repo.name,
          relName: branch.name
        })

        currentCommit = repo.commits.get(currentCommit.parent)
After
22
23
24
25
26
27
          type: "branch",
          commit: currentCommit,
          repoName: repo.name,
          refName: branch.name
        })

        currentCommit = repo.commits.get(currentCommit.parent)
src/flatPatches.ts:40
Before
39
40
41
42
43
44
          type: "tag",
          commit: currentCommit,
          repoName: repo.name,
          relName: tag.name,
        })

        currentCommit = repo.commits.get(currentCommit.parent)
After
39
40
41
42
43
44
          type: "tag",
          commit: currentCommit,
          repoName: repo.name,
          refName: tag.name,
        })

        currentCommit = repo.commits.get(currentCommit.parent)
src/flatRels.ts:1
Before
0
1
2
3
4
5
import { type Repository } from "./dataTypes.ts"

type BranchEntry = {
  relName: string,
  type: "branch",
  repoName: string,
  compareTo: string,
After
0
1
2
3
4
5
import { type Repository } from "./dataTypes.ts"

type BranchEntry = {
  refName: string,
  type: "branch",
  repoName: string,
  compareTo: string,
src/flatRels.ts:10
Before
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
}

type TagEntry = {
  relName: string,
  type: "tag",
  repoName: string,
}

let cachedRels: Array<BranchEntry | TagEntry> | null = null

export default (repos: Array<Repository>) => {
  if (cachedRels !== null) { return cachedRels }

  cachedRels = repos.flatMap((repo) => {
    const branches: Array<BranchEntry> = repo.branches.map((branch) => {
      const result: BranchEntry = {
        relName: branch.name,
        type: "branch",
        repoName: repo.name,
        compareTo: branch.compareTo,
After
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
}

type TagEntry = {
  refName: string,
  type: "tag",
  repoName: string,
}

let cachedRefs: Array<BranchEntry | TagEntry> | null = null

export default (repos: Array<Repository>) => {
  if (cachedRefs !== null) { return cachedRefs }

  cachedRefs = repos.flatMap((repo) => {
    const branches: Array<BranchEntry> = repo.branches.map((branch) => {
      const result: BranchEntry = {
        refName: branch.name,
        type: "branch",
        repoName: repo.name,
        compareTo: branch.compareTo,
src/flatRels.ts:35
Before
34
35
36
37
38
39
    })
    const tags: Array<TagEntry> = repo.tags.map((tag) => {
      return {
        relName: tag.name,
        type: "tag",
        repoName: repo.name,
      }
After
34
35
36
37
38
39
    })
    const tags: Array<TagEntry> = repo.tags.map((tag) => {
      return {
        refName: tag.name,
        type: "tag",
        repoName: repo.name,
      }
src/flatRels.ts:44
Before
43
44
45
46
    return [...branches, ...tags]
  })

  return cachedRels
}
After
43
44
45
46
    return [...branches, ...tags]
  })

  return cachedRefs
}
src/paginatedPatches.ts:3
Before
2
3
4
5
6
7

export type PatchPage = {
  repoName: string,
  relName: string,
  type: "branch" | "tag",
  commits: Array<ReturnType<Repository['commits']['get']>>,
  pageNumber: number,
After
2
3
4
5
6
7

export type PatchPage = {
  repoName: string,
  refName: string,
  type: "branch" | "tag",
  commits: Array<ReturnType<Repository['commits']['get']>>,
  pageNumber: number,
src/paginatedPatches.ts:22
Before
21
22
23
24
25
26
    const index = paginatedPatches.findIndex((page) => {
      return (
        page.repoName === patch.repoName
        && page.relName == patch.relName
        && page.type == patch.type
        && page.commits.length <= patchesPerPage
      )
After
21
22
23
24
25
26
    const index = paginatedPatches.findIndex((page) => {
      return (
        page.repoName === patch.repoName
        && page.refName == patch.refName
        && page.type == patch.type
        && page.commits.length <= patchesPerPage
      )
src/paginatedPatches.ts:31
Before
30
31
32
33
34
35
36
37
38
39
40
    if (index === -1) {
      const pageNumber = paginatedPatches.filter(page => (
        page.repoName === patch.repoName
        && page.relName === patch.relName
        && page.type === patch.type
      )).length + 1
      paginatedPatches.push({
        repoName: patch.repoName,
        relName: patch.relName,
        commits: [patch.commit],
        type: patch.type,
        // current page number is one more than "how many items in paginatedPatches already
After
30
31
32
33
34
35
36
37
38
39
40
    if (index === -1) {
      const pageNumber = paginatedPatches.filter(page => (
        page.repoName === patch.repoName
        && page.refName === patch.refName
        && page.type === patch.type
      )).length + 1
      paginatedPatches.push({
        repoName: patch.repoName,
        refName: patch.refName,
        commits: [patch.commit],
        type: patch.type,
        // current page number is one more than "how many items in paginatedPatches already
src/repos.ts:27
Before
26
27
28
29
30
31
  const cachedBranchNames = branchesForReposMap.get(repoName)
  const cachedTagNames = tagsForReposMap.get(repoName)
  if (cachedBranchNames !== undefined) {
    console.log({branches: cachedBranchNames, tags: cachedTagNames})
    return {branches: cachedBranchNames, tags: cachedTagNames}
  }
After
26
27
28

29
30
  const cachedBranchNames = branchesForReposMap.get(repoName)
  const cachedTagNames = tagsForReposMap.get(repoName)
  if (cachedBranchNames !== undefined) {
⁣
    return {branches: cachedBranchNames, tags: cachedTagNames}
  }
src/repos.ts:128
Before
127
128
129
130
131
132
133
    }).flat()
  }).flat()

  console.log(tags)

  if (branchesForReposMap.get(repoName) === undefined) {
    branchesForReposMap.set(repoName, branches)
  }
After
127
128
129


130
131
    }).flat()
  }).flat()

⁣
⁣
  if (branchesForReposMap.get(repoName) === undefined) {
    branchesForReposMap.set(repoName, branches)
  }