1
1
// originally from https://github.com/gingerchew/astro-github-file-loader
2
2
import type { AstroConfig , MarkdownHeading } from "astro" ;
3
3
import type { Loader , LoaderContext } from "astro/loaders" ;
4
+ import { octokit } from "@components/octokit.js" ;
4
5
5
6
type GithubTreeLeaf = {
6
7
path : string ;
@@ -55,10 +56,15 @@ function createProcessors(processors: Processors) {
55
56
56
57
export function githubFileLoader ( { org, repo, ref, processors, path } : PolicyLoaderConfig ) : Loader {
57
58
const baseUrl = `https://raw.githubusercontent.com/${ org } /${ repo } /${ ref } ` ;
58
- const apiUrl = `https://api.github.com/repos/${ org } /${ repo } /git/trees/${ ref } ?recursive=1` ;
59
59
60
60
const get = async < T > ( filepath : string , type : "json" | "text" ) : Promise < T > => {
61
61
try {
62
+ // If this is a GitHub API request, use octokit
63
+ if ( filepath . startsWith ( 'https://api.github.com' ) ) {
64
+ const response = await octokit . request ( 'GET ' + filepath . replace ( 'https://api.github.com' , '' ) ) ;
65
+ return response . data as T ;
66
+ }
67
+ // Otherwise use fetch for raw content
62
68
const response = await fetch ( filepath ) ;
63
69
if ( ! response . ok ) throw new Error ( `HTTP ${ response . status } ` ) ;
64
70
return type === "json" ? await response . json ( ) : await response . text ( ) ;
@@ -76,9 +82,15 @@ export function githubFileLoader({ org, repo, ref, processors, path }: PolicyLoa
76
82
// Get the last tree SHA we processed
77
83
const lastTreeSha = meta . get ( 'lastTreeSha' ) ;
78
84
79
- // Fetch current tree data
80
- const treeData = await get < GithubTreeData > ( apiUrl , "json" ) ;
81
- const currentTreeSha = treeData . hash ;
85
+ // Fetch current tree data using octokit directly
86
+ const { data : treeData } = await octokit . rest . git . getTree ( {
87
+ owner : org ,
88
+ repo : repo ,
89
+ tree_sha : ref ,
90
+ recursive : '1'
91
+ } ) ;
92
+
93
+ const currentTreeSha = treeData . sha ;
82
94
83
95
// If tree hasn't changed, we can skip processing
84
96
if ( lastTreeSha && lastTreeSha === currentTreeSha ) {
@@ -93,14 +105,14 @@ export function githubFileLoader({ org, repo, ref, processors, path }: PolicyLoa
93
105
94
106
for await ( const leaf of treeData . tree ) {
95
107
// Skip directories and .github files
96
- if ( leaf . type === "tree" || leaf . path . includes ( ".github/" ) ) continue ;
108
+ if ( leaf . type === "tree" || leaf . path ? .includes ( ".github/" ) ) continue ;
97
109
98
110
const pathMatch =
99
- ( path && typeof path === "string" && leaf . path . includes ( path ) ) ||
100
- ( path && typeof path !== "string" && path . test ( leaf . path ) ) ;
111
+ ( path && typeof path === "string" && leaf . path ? .includes ( path ) ) ||
112
+ ( path && typeof path !== "string" && path . test ( leaf . path ?? "" ) ) ;
101
113
if ( ! pathMatch ) continue ;
102
114
103
- const [ id , extension ] = leaf . path . split ( "." ) ;
115
+ const [ id , extension ] = leaf . path ? .split ( "." ) ?? [ ] ;
104
116
processedIds . add ( id ) ;
105
117
106
118
// Check if we already have this file with the same SHA
@@ -117,6 +129,9 @@ export function githubFileLoader({ org, repo, ref, processors, path }: PolicyLoa
117
129
118
130
const { html, metadata } = await $ [ extension as keyof Processors ] ( body , config ) ;
119
131
132
+ // get the last commit date for the file using GitHub API
133
+ const lastCommit = await get < any > ( `https://api.github.com/repos/${ org } /${ repo } /commits?path=${ leaf . path } &sha=${ ref } ` , "json" ) ;
134
+
120
135
store . set ( {
121
136
id,
122
137
data : {
@@ -125,7 +140,8 @@ export function githubFileLoader({ org, repo, ref, processors, path }: PolicyLoa
125
140
org,
126
141
repo,
127
142
ref,
128
- sha : leaf . sha // Store SHA for future comparisons
143
+ sha : leaf . sha , // Store SHA for future comparisons
144
+ lastCommit : lastCommit [ 0 ] . commit . committer . date ,
129
145
} ,
130
146
body,
131
147
rendered : { html, metadata } ,
0 commit comments