@larkiny/astro-github-loader 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,339 @@
1
+ import type {
2
+ Loader as AstroLoader,
3
+ LoaderContext as AstroLoaderContext,
4
+ } from "astro/loaders";
5
+ import type { ContentEntryType } from "astro";
6
+ import type {MarkdownHeading} from "@astrojs/markdown-remark";
7
+ import {Octokit} from "octokit";
8
+
9
+ // Import link transformation types from the dedicated module
10
+ import type { LinkHandler } from "./github.link-transform.js";
11
+ import type { LogLevel } from "./github.logger.js";
12
+
13
+ /**
14
+ * Context information for link transformations
15
+ */
16
+ export interface LinkTransformContext {
17
+ /** Original source path in the repository */
18
+ sourcePath: string;
19
+ /** Target path where the file will be written */
20
+ targetPath: string;
21
+ /** Base path for this include pattern */
22
+ basePath: string;
23
+ /** Path mappings used for this file */
24
+ pathMappings?: Record<string, PathMappingValue>;
25
+ /** The include pattern that matched this file */
26
+ matchedPattern?: MatchedPattern;
27
+ }
28
+
29
+ /**
30
+ * Link mapping for transforming URLs in markdown links
31
+ */
32
+ export interface LinkMapping {
33
+ /** Pattern to match (string or regex) */
34
+ pattern: string | RegExp;
35
+ /** Replacement string or function */
36
+ replacement: string | ((match: string, anchor: string, context: any) => string);
37
+ /** Apply to all links, not just unresolved internal links (default: false) */
38
+ global?: boolean;
39
+ /** Function to determine if this mapping should apply to the current file context */
40
+ contextFilter?: (context: LinkTransformContext) => boolean;
41
+ /** Automatically handle relative links by prefixing with target base path (default: false) */
42
+ relativeLinks?: boolean;
43
+ }
44
+
45
+ /**
46
+ * Configuration for import link transformation
47
+ */
48
+ export interface ImportLinkTransformOptions {
49
+ /** Base paths to strip from final URLs (e.g., ["src/content/docs"]) */
50
+ stripPrefixes: string[];
51
+ /** Custom handlers for special link types */
52
+ customHandlers?: LinkHandler[];
53
+ /** Link mappings to transform URLs in markdown links */
54
+ linkMappings?: LinkMapping[];
55
+ }
56
+
57
+ /**
58
+ * Information about which include pattern matched a file
59
+ */
60
+ export interface MatchedPattern {
61
+ /** The glob pattern that matched */
62
+ pattern: string;
63
+ /** The base path for this pattern */
64
+ basePath: string;
65
+ /** Index of the pattern in the includes array */
66
+ index: number;
67
+ }
68
+
69
+ /**
70
+ * Context object passed to transform functions
71
+ */
72
+ export interface TransformContext {
73
+ /** Generated ID for the content */
74
+ id: string;
75
+ /** File path within the repository */
76
+ path: string;
77
+ /** Full configuration options */
78
+ options: ImportOptions;
79
+ /** Information about which include pattern matched (if any) */
80
+ matchedPattern?: MatchedPattern;
81
+ }
82
+
83
+ /**
84
+ * Function type for content transformations
85
+ * @param content - The markdown content to transform
86
+ * @param context - Context information about the file being processed
87
+ * @returns The transformed content
88
+ */
89
+ export type TransformFunction = (content: string, context: TransformContext) => string;
90
+
91
+ /**
92
+ * Enhanced path mapping configuration that supports cross-section linking
93
+ */
94
+ export interface EnhancedPathMapping {
95
+ /** Target path where the file should be imported */
96
+ target: string;
97
+ /**
98
+ * Cross-section path for generating links to this content from other sections.
99
+ * If not specified, will be inferred from the basePath.
100
+ * Example: '/reference/algokit-utils-ts/api'
101
+ */
102
+ crossSectionPath?: string;
103
+ }
104
+
105
+ /**
106
+ * Path mapping value - can be a simple string or an enhanced configuration object
107
+ */
108
+ export type PathMappingValue = string | EnhancedPathMapping;
109
+
110
+ /**
111
+ * Configuration for a single include pattern
112
+ */
113
+ export interface IncludePattern {
114
+ /** Glob pattern to match files (relative to repository root) */
115
+ pattern: string;
116
+ /** Local base path where matching files should be imported */
117
+ basePath: string;
118
+ /** Transforms to apply only to files matching this pattern */
119
+ transforms?: TransformFunction[];
120
+ /**
121
+ * Map of source paths to target paths for controlling where files are imported.
122
+ *
123
+ * Supports multiple mapping formats:
124
+ *
125
+ * **Simple string format:**
126
+ * - **File mapping**: `'docs/README.md': 'docs/overview.md'` - moves a specific file to a new path
127
+ * - **Folder mapping**: `'docs/capabilities/': 'docs/'` - moves all files from source folder to target folder
128
+ *
129
+ * **Enhanced object format with cross-section linking:**
130
+ * - `'docs/api/': { target: 'api/', crossSectionPath: '/reference/api' }`
131
+ *
132
+ * **Important**: Folder mappings require trailing slashes to distinguish from file mappings.
133
+ * - ✅ `'docs/capabilities/': 'docs/'` (folder mapping - moves all files)
134
+ * - ❌ `'docs/capabilities': 'docs/'` (treated as exact file match)
135
+ *
136
+ * When using enhanced format, link mappings will be automatically generated for cross-section references.
137
+ * If `crossSectionPath` is not specified, it will be inferred from the basePath.
138
+ */
139
+ pathMappings?: Record<string, PathMappingValue>;
140
+ }
141
+
142
+
143
+ export type GithubLoaderOptions = {
144
+ octokit: Octokit;
145
+ configs: Array<ImportOptions>;
146
+ clear?: boolean;
147
+ gitIgnore?: string;
148
+ basePath?: string;
149
+ fetchOptions?: FetchOptions;
150
+ /**
151
+ * When true, only checks for repository changes without importing.
152
+ * Returns a report of which repositories have new commits.
153
+ * @default false
154
+ */
155
+ dryRun?: boolean;
156
+ /**
157
+ * Global logging level for all import operations
158
+ * Overrides individual ImportOptions logLevel settings
159
+ * @default 'default'
160
+ */
161
+ logLevel?: LogLevel;
162
+ /**
163
+ * When true, forces a full import even if no repository changes are detected.
164
+ * When false (default), skips processing if repository hasn't changed.
165
+ * @default false
166
+ */
167
+ force?: boolean;
168
+ };
169
+
170
+ /**
171
+ * Represents the configuration options for a collection entry operation.
172
+ * @internal
173
+ */
174
+ export type CollectionEntryOptions = {
175
+ /**
176
+ * Represents the context object for a loader, providing metadata
177
+ * and utilities for the current loading process.
178
+ *
179
+ * The LoaderContext may contain properties and methods that offer
180
+ * control or inspection over the loading behavior.
181
+ */
182
+ context: LoaderContext;
183
+ /**
184
+ * An instance of the Octokit library, which provides a way to interact
185
+ * with GitHub's REST API. This variable allows you to access and perform
186
+ * operations such as creating repositories, managing issues, handling
187
+ * pull requests, fetching user data, and more.
188
+ *
189
+ * The Octokit instance must be configured*/
190
+ octokit: Octokit;
191
+ /**
192
+ * Represents the configuration options for initializing or customizing the root application behavior.
193
+ * The option object may include various properties that control specific features or behavior of the application.
194
+ */
195
+ options: ImportOptions;
196
+ /**
197
+ * An optional AbortSignal instance that enables observing and controlling the
198
+ * abort state of an operation. It can be used to signal cancellation requests
199
+ * to an ongoing task, such as a fetch request or custom asynchronous operations.
200
+ *
201
+ * If provided, the corresponding task can listen to the `abort` event of the signal
202
+ * to handle early termination or cleanup logic appropriately.
203
+ *
204
+ * If the signal is already aborted at the time it is assigned or checked, the task
205
+ * may respond to the abort condition immediately.
206
+ */
207
+ signal?: AbortSignal;
208
+ /**
209
+ * Represents the optional configuration settings for a fetch operation.
210
+ * This variable allows customization of the behavior of the fetch process.
211
+ */
212
+ fetchOptions?: FetchOptions;
213
+ /**
214
+ * When true, forces a full import even if no repository changes are detected.
215
+ * When false (default), skips processing if repository hasn't changed.
216
+ * @default false
217
+ */
218
+ force?: boolean;
219
+ };
220
+
221
+ /**
222
+ * Interface representing rendered content, including HTML and associated metadata.
223
+ * @internal
224
+ */
225
+ export interface RenderedContent {
226
+ /** Rendered HTML string. If present then `render(entry)` will return a component that renders this HTML. */
227
+ html: string;
228
+ metadata?: {
229
+ /** Any images that are present in this entry. Relative to the {@link DataEntry} filePath. */
230
+ imagePaths?: Array<string>;
231
+ /** Any headings that are present in this file. */
232
+ headings?: MarkdownHeading[];
233
+ /** Raw frontmatter, parsed parsed from the file. This may include data from remark plugins. */
234
+ frontmatter?: Record<string, any>;
235
+ /** Any other metadata that is present in this file. */
236
+ [key: string]: unknown;
237
+ };
238
+ }
239
+
240
+ /**
241
+ * Represents configuration options for importing content from GitHub repositories.
242
+ */
243
+ export type ImportOptions = {
244
+ /**
245
+ * Display name for this configuration (used in logging)
246
+ */
247
+ name?: string;
248
+ /**
249
+ * Repository owner
250
+ */
251
+ owner: string;
252
+ /**
253
+ * Repository Name
254
+ */
255
+ repo: string;
256
+ /**
257
+ * A specific reference in Github
258
+ */
259
+ ref?: string;
260
+ /**
261
+ * Local directory path where downloaded assets should be stored
262
+ */
263
+ assetsPath?: string;
264
+ /**
265
+ * Base URL prefix for asset references in transformed markdown content
266
+ */
267
+ assetsBaseUrl?: string;
268
+ /**
269
+ * Array of file extensions to treat as assets (e.g., ['.png', '.jpg', '.svg'])
270
+ * Defaults to common image formats if not specified
271
+ */
272
+ assetPatterns?: string[];
273
+ /**
274
+ * Whether this configuration is enabled for processing
275
+ */
276
+ enabled?: boolean;
277
+ /**
278
+ * Whether to clear target directories before importing content
279
+ */
280
+ clear?: boolean;
281
+ /**
282
+ * Array of transform functions to apply to all imported content
283
+ */
284
+ transforms?: TransformFunction[];
285
+ /**
286
+ * Array of include patterns defining which files to import and where to put them
287
+ * If not specified, all files will be imported (backward compatibility mode)
288
+ */
289
+ includes?: IncludePattern[];
290
+ /**
291
+ * Link transformation options
292
+ * Applied after all content transforms and across all include patterns
293
+ */
294
+ linkTransform?: ImportLinkTransformOptions;
295
+ /**
296
+ * Logging level for this import configuration
297
+ * Can be overridden by global logLevel in GithubLoaderOptions
298
+ * @default 'default'
299
+ */
300
+ logLevel?: LogLevel;
301
+ };
302
+
303
+ export type FetchOptions = RequestInit & {
304
+ signal?: AbortSignal;
305
+ concurrency?: number;
306
+ };
307
+
308
+ /**
309
+ * @internal
310
+ */
311
+ export interface LoaderContext extends AstroLoaderContext {
312
+ /** @internal */
313
+ entryTypes?: Map<string, ContentEntryType>;
314
+ }
315
+
316
+ /**
317
+ * @internal
318
+ */
319
+ export interface Loader extends AstroLoader {
320
+ /** Do the actual loading of the data */
321
+ load: (context: LoaderContext) => Promise<void>;
322
+ }
323
+
324
+
325
+ /**
326
+ * Statistics for a sync operation
327
+ */
328
+ export interface SyncStats {
329
+ /** Number of files added */
330
+ added: number;
331
+ /** Number of files updated */
332
+ updated: number;
333
+ /** Number of files deleted */
334
+ deleted: number;
335
+ /** Number of files unchanged */
336
+ unchanged: number;
337
+ /** Total processing time in ms */
338
+ duration: number;
339
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './github.constants.js'
2
+ export * from './github.content.js'
3
+ export * from './github.loader.js'
4
+ export * from './github.types.js'
5
+ export * from './github.link-transform.js'