@larkiny/astro-github-loader 0.11.3 → 0.13.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.
Files changed (51) hide show
  1. package/README.md +35 -55
  2. package/dist/github.assets.d.ts +70 -0
  3. package/dist/github.assets.js +253 -0
  4. package/dist/github.auth.js +13 -9
  5. package/dist/github.cleanup.d.ts +3 -2
  6. package/dist/github.cleanup.js +30 -23
  7. package/dist/github.constants.d.ts +0 -16
  8. package/dist/github.constants.js +0 -16
  9. package/dist/github.content.d.ts +5 -131
  10. package/dist/github.content.js +152 -794
  11. package/dist/github.dryrun.d.ts +9 -5
  12. package/dist/github.dryrun.js +49 -25
  13. package/dist/github.link-transform.d.ts +2 -2
  14. package/dist/github.link-transform.js +68 -57
  15. package/dist/github.loader.js +30 -46
  16. package/dist/github.logger.d.ts +2 -2
  17. package/dist/github.logger.js +33 -24
  18. package/dist/github.paths.d.ts +76 -0
  19. package/dist/github.paths.js +190 -0
  20. package/dist/github.storage.d.ts +16 -0
  21. package/dist/github.storage.js +115 -0
  22. package/dist/github.types.d.ts +40 -4
  23. package/dist/index.d.ts +8 -6
  24. package/dist/index.js +3 -6
  25. package/dist/test-helpers.d.ts +130 -0
  26. package/dist/test-helpers.js +194 -0
  27. package/package.json +3 -1
  28. package/src/github.assets.spec.ts +717 -0
  29. package/src/github.assets.ts +365 -0
  30. package/src/github.auth.spec.ts +245 -0
  31. package/src/github.auth.ts +24 -10
  32. package/src/github.cleanup.spec.ts +380 -0
  33. package/src/github.cleanup.ts +91 -47
  34. package/src/github.constants.ts +0 -17
  35. package/src/github.content.spec.ts +305 -454
  36. package/src/github.content.ts +259 -957
  37. package/src/github.dryrun.spec.ts +598 -0
  38. package/src/github.dryrun.ts +108 -54
  39. package/src/github.link-transform.spec.ts +1345 -0
  40. package/src/github.link-transform.ts +177 -95
  41. package/src/github.loader.spec.ts +75 -50
  42. package/src/github.loader.ts +101 -76
  43. package/src/github.logger.spec.ts +795 -0
  44. package/src/github.logger.ts +77 -35
  45. package/src/github.paths.spec.ts +523 -0
  46. package/src/github.paths.ts +259 -0
  47. package/src/github.storage.spec.ts +377 -0
  48. package/src/github.storage.ts +135 -0
  49. package/src/github.types.ts +54 -9
  50. package/src/index.ts +43 -6
  51. package/src/test-helpers.ts +215 -0
@@ -2,7 +2,7 @@
2
2
  * Multi-level logging system for astro-github-loader
3
3
  */
4
4
 
5
- export type LogLevel = 'silent' | 'default' | 'verbose' | 'debug';
5
+ export type LogLevel = "silent" | "default" | "verbose" | "debug";
6
6
 
7
7
  export interface LoggerOptions {
8
8
  level: LogLevel;
@@ -19,7 +19,7 @@ export interface ImportSummary {
19
19
  assetsDownloaded?: number;
20
20
  assetsCached?: number;
21
21
  duration: number;
22
- status: 'success' | 'error' | 'cancelled';
22
+ status: "success" | "error" | "cancelled";
23
23
  error?: string;
24
24
  }
25
25
 
@@ -43,13 +43,13 @@ export class Logger {
43
43
  private level: LogLevel;
44
44
  private prefix: string;
45
45
  private spinnerInterval?: NodeJS.Timeout;
46
- private spinnerChars = ['', '', '', '', '', '', '', '', '', ''];
46
+ private spinnerChars = ["", "", "", "", "", "", "", "", "", ""];
47
47
  private spinnerIndex = 0;
48
48
  private spinnerStartTime?: number;
49
49
 
50
50
  constructor(options: LoggerOptions) {
51
51
  this.level = options.level;
52
- this.prefix = options.prefix || '';
52
+ this.prefix = options.prefix || "";
53
53
  }
54
54
 
55
55
  /**
@@ -98,7 +98,7 @@ export class Logger {
98
98
  * Default level - summary information only
99
99
  */
100
100
  info(message: string): void {
101
- if (this.shouldLog('default')) {
101
+ if (this.shouldLog("default")) {
102
102
  console.log(this.formatMessage(message));
103
103
  }
104
104
  }
@@ -107,7 +107,7 @@ export class Logger {
107
107
  * Verbose level - detailed operation information
108
108
  */
109
109
  verbose(message: string): void {
110
- if (this.shouldLog('verbose')) {
110
+ if (this.shouldLog("verbose")) {
111
111
  console.log(this.formatMessage(message));
112
112
  }
113
113
  }
@@ -116,7 +116,7 @@ export class Logger {
116
116
  * Debug level - all information including diagnostics
117
117
  */
118
118
  debug(message: string): void {
119
- if (this.shouldLog('debug')) {
119
+ if (this.shouldLog("debug")) {
120
120
  console.log(this.formatMessage(message));
121
121
  }
122
122
  }
@@ -125,7 +125,7 @@ export class Logger {
125
125
  * Error - always shown unless silent
126
126
  */
127
127
  error(message: string): void {
128
- if (this.shouldLog('default')) {
128
+ if (this.shouldLog("default")) {
129
129
  console.error(this.formatMessage(message));
130
130
  }
131
131
  }
@@ -134,7 +134,7 @@ export class Logger {
134
134
  * Warning - shown at default level and above
135
135
  */
136
136
  warn(message: string): void {
137
- if (this.shouldLog('default')) {
137
+ if (this.shouldLog("default")) {
138
138
  console.warn(this.formatMessage(message));
139
139
  }
140
140
  }
@@ -143,34 +143,50 @@ export class Logger {
143
143
  * Log structured import summary (default level)
144
144
  */
145
145
  logImportSummary(summary: ImportSummary): void {
146
- if (!this.shouldLog('default')) return;
146
+ if (!this.shouldLog("default")) return;
147
147
 
148
- const statusIcon = summary.status === 'success' ? '✅' : summary.status === 'error' ? '❌' : '🚫';
148
+ const statusIcon =
149
+ summary.status === "success"
150
+ ? "✅"
151
+ : summary.status === "error"
152
+ ? "❌"
153
+ : "🚫";
149
154
 
150
- this.info('');
155
+ this.info("");
151
156
  this.info(`📊 Import Summary: ${summary.configName}`);
152
- this.info(`├─ Repository: ${summary.repository}${summary.ref ? `@${summary.ref}` : ''}`);
153
- this.info(`├─ Files: ${summary.filesProcessed} processed, ${summary.filesUpdated} updated, ${summary.filesUnchanged} unchanged`);
154
-
155
- if (summary.assetsDownloaded !== undefined || summary.assetsCached !== undefined) {
157
+ this.info(
158
+ `├─ Repository: ${summary.repository}${summary.ref ? `@${summary.ref}` : ""}`,
159
+ );
160
+ this.info(
161
+ `├─ Files: ${summary.filesProcessed} processed, ${summary.filesUpdated} updated, ${summary.filesUnchanged} unchanged`,
162
+ );
163
+
164
+ if (
165
+ summary.assetsDownloaded !== undefined ||
166
+ summary.assetsCached !== undefined
167
+ ) {
156
168
  const downloaded = summary.assetsDownloaded || 0;
157
169
  const cached = summary.assetsCached || 0;
158
170
  this.info(`├─ Assets: ${downloaded} downloaded, ${cached} cached`);
159
171
  }
160
172
 
161
173
  this.info(`├─ Duration: ${(summary.duration / 1000).toFixed(1)}s`);
162
- this.info(`└─ Status: ${statusIcon} ${summary.status === 'success' ? 'Success' : summary.status === 'error' ? `Error: ${summary.error}` : 'Cancelled'}`);
163
- this.info('');
174
+ this.info(
175
+ `└─ Status: ${statusIcon} ${summary.status === "success" ? "Success" : summary.status === "error" ? `Error: ${summary.error}` : "Cancelled"}`,
176
+ );
177
+ this.info("");
164
178
  }
165
179
 
166
180
  /**
167
181
  * Log sync operation summary (default level)
168
182
  */
169
183
  logSyncSummary(configName: string, summary: SyncSummary): void {
170
- if (!this.shouldLog('default')) return;
184
+ if (!this.shouldLog("default")) return;
171
185
 
172
186
  if (summary.added > 0 || summary.updated > 0 || summary.deleted > 0) {
173
- this.info(`Sync completed for ${configName}: ${summary.added} added, ${summary.updated} updated, ${summary.deleted} deleted (${summary.duration}ms)`);
187
+ this.info(
188
+ `Sync completed for ${configName}: ${summary.added} added, ${summary.updated} updated, ${summary.deleted} deleted (${summary.duration}ms)`,
189
+ );
174
190
  } else {
175
191
  this.info(`No changes needed for ${configName} (${summary.duration}ms)`);
176
192
  }
@@ -180,10 +196,12 @@ export class Logger {
180
196
  * Log cleanup operation summary (default level)
181
197
  */
182
198
  logCleanupSummary(configName: string, summary: CleanupSummary): void {
183
- if (!this.shouldLog('default')) return;
199
+ if (!this.shouldLog("default")) return;
184
200
 
185
201
  if (summary.deleted > 0) {
186
- this.info(`Cleanup completed for ${configName}: ${summary.deleted} obsolete files deleted (${summary.duration}ms)`);
202
+ this.info(
203
+ `Cleanup completed for ${configName}: ${summary.deleted} obsolete files deleted (${summary.duration}ms)`,
204
+ );
187
205
  } else {
188
206
  this.debug(`No cleanup needed for ${configName} (${summary.duration}ms)`);
189
207
  }
@@ -193,15 +211,23 @@ export class Logger {
193
211
  * Log file-level processing (verbose level)
194
212
  */
195
213
  logFileProcessing(action: string, filePath: string, details?: string): void {
196
- const message = details ? `${action}: ${filePath} - ${details}` : `${action}: ${filePath}`;
214
+ const message = details
215
+ ? `${action}: ${filePath} - ${details}`
216
+ : `${action}: ${filePath}`;
197
217
  this.verbose(message);
198
218
  }
199
219
 
200
220
  /**
201
221
  * Log asset processing (verbose level)
202
222
  */
203
- logAssetProcessing(action: string, assetPath: string, details?: string): void {
204
- const message = details ? `Asset ${action}: ${assetPath} - ${details}` : `Asset ${action}: ${assetPath}`;
223
+ logAssetProcessing(
224
+ action: string,
225
+ assetPath: string,
226
+ details?: string,
227
+ ): void {
228
+ const message = details
229
+ ? `Asset ${action}: ${assetPath} - ${details}`
230
+ : `Asset ${action}: ${assetPath}`;
205
231
  this.verbose(message);
206
232
  }
207
233
 
@@ -254,8 +280,8 @@ export class Logger {
254
280
  /**
255
281
  * Start a spinner with duration timer for long-running operations
256
282
  */
257
- startSpinner(message: string = 'Processing...'): void {
258
- if (this.level === 'silent') return;
283
+ startSpinner(message: string = "Processing..."): void {
284
+ if (this.level === "silent") return;
259
285
 
260
286
  this.spinnerStartTime = Date.now();
261
287
  this.spinnerIndex = 0;
@@ -264,7 +290,9 @@ export class Logger {
264
290
  const elapsed = Math.floor((Date.now() - this.spinnerStartTime!) / 1000);
265
291
  const spinner = this.spinnerChars[this.spinnerIndex];
266
292
  const duration = this.formatDuration(elapsed);
267
- const formattedMessage = this.formatMessage(`${message} ${spinner} (${duration})`);
293
+ const formattedMessage = this.formatMessage(
294
+ `${message} ${spinner} (${duration})`,
295
+ );
268
296
  process.stdout.write(`\r${formattedMessage}`);
269
297
  this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerChars.length;
270
298
  };
@@ -288,13 +316,15 @@ export class Logger {
288
316
  if (finalMessage && this.spinnerStartTime) {
289
317
  const totalTime = Math.floor((Date.now() - this.spinnerStartTime) / 1000);
290
318
  const duration = this.formatDuration(totalTime);
291
- const formattedMessage = this.formatMessage(`${finalMessage} (${duration})`);
319
+ const formattedMessage = this.formatMessage(
320
+ `${finalMessage} (${duration})`,
321
+ );
292
322
  process.stdout.write(`\r${formattedMessage}\n`);
293
323
  } else if (finalMessage) {
294
324
  const formattedMessage = this.formatMessage(finalMessage);
295
325
  process.stdout.write(`\r${formattedMessage}\n`);
296
326
  } else {
297
- process.stdout.write('\r\x1b[K'); // Clear the line
327
+ process.stdout.write("\r\x1b[K"); // Clear the line
298
328
  }
299
329
 
300
330
  this.spinnerStartTime = undefined;
@@ -303,14 +333,23 @@ export class Logger {
303
333
  /**
304
334
  * Execute a function with spinner feedback
305
335
  */
306
- async withSpinner<T>(message: string, fn: () => Promise<T>, successMessage?: string, errorMessage?: string): Promise<T> {
336
+ async withSpinner<T>(
337
+ message: string,
338
+ fn: () => Promise<T>,
339
+ successMessage?: string,
340
+ errorMessage?: string,
341
+ ): Promise<T> {
307
342
  this.startSpinner(message);
308
343
  try {
309
344
  const result = await fn();
310
- this.stopSpinner(successMessage || `✅ ${message.replace(/^[🔄⏳]?\s*/, '')} completed`);
345
+ this.stopSpinner(
346
+ successMessage || `✅ ${message.replace(/^[🔄⏳]?\s*/, "")} completed`,
347
+ );
311
348
  return result;
312
349
  } catch (error) {
313
- this.stopSpinner(errorMessage || `❌ ${message.replace(/^[🔄⏳]?\s*/, '')} failed`);
350
+ this.stopSpinner(
351
+ errorMessage || `❌ ${message.replace(/^[🔄⏳]?\s*/, "")} failed`,
352
+ );
314
353
  throw error;
315
354
  }
316
355
  }
@@ -319,6 +358,9 @@ export class Logger {
319
358
  /**
320
359
  * Create a logger instance with the specified level
321
360
  */
322
- export function createLogger(level: LogLevel = 'default', prefix?: string): Logger {
361
+ export function createLogger(
362
+ level: LogLevel = "default",
363
+ prefix?: string,
364
+ ): Logger {
323
365
  return new Logger({ level, prefix });
324
- }
366
+ }