@larkiny/astro-github-loader 0.9.0 → 0.10.1

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.
@@ -3,7 +3,6 @@ import { fileURLToPath, pathToFileURL } from "node:url";
3
3
  import path, { join, dirname, basename, extname } from "node:path";
4
4
  import picomatch from "picomatch";
5
5
  import { globalLinkTransform, generateAutoLinkMappings } from "./github.link-transform.js";
6
- import { getLatestCommitInfo, loadImportState, createConfigId } from "./github.dryrun.js";
7
6
  import { INVALID_SERVICE_RESPONSE, INVALID_STRING_ERROR, INVALID_URL_ERROR, } from "./github.constants.js";
8
7
  /**
9
8
  * Generates a unique identifier from a file path by removing the extension
@@ -556,42 +555,6 @@ export async function toCollectionEntry({ context, octokit, options, signal, for
556
555
  throw new TypeError(INVALID_STRING_ERROR);
557
556
  // Get logger from context - it should be our Logger instance (initialize early)
558
557
  const logger = context.logger;
559
- // Repository-level caching - simple all-or-nothing approach
560
- const configName = options.name || `${owner}/${repo}`;
561
- const configId = createConfigId(options);
562
- if (!force) {
563
- try {
564
- const state = await loadImportState(process.cwd());
565
- const currentState = state.imports[configId];
566
- if (currentState && currentState.lastCommitSha) {
567
- logger.debug(`🔍 Checking repository changes for ${configName}...`);
568
- const latestCommit = await getLatestCommitInfo(octokit, options, signal);
569
- if (latestCommit && currentState.lastCommitSha === latestCommit.sha) {
570
- logger.info(`✅ Repository ${configName} unchanged (${latestCommit.sha.slice(0, 7)}) - skipping import`);
571
- return {
572
- processed: 0,
573
- updated: 0,
574
- unchanged: 0,
575
- assetsDownloaded: 0,
576
- assetsCached: 0,
577
- };
578
- }
579
- else if (latestCommit) {
580
- logger.info(`🔄 Repository ${configName} changed (${currentState.lastCommitSha?.slice(0, 7) || 'unknown'} -> ${latestCommit.sha.slice(0, 7)}) - proceeding with import`);
581
- }
582
- }
583
- else {
584
- logger.debug(`📥 First time importing ${configName} - no previous state found`);
585
- }
586
- }
587
- catch (error) {
588
- logger.warn(`Failed to check repository state for ${configName}: ${error instanceof Error ? error.message : String(error)}`);
589
- // Continue with import if state check fails
590
- }
591
- }
592
- else {
593
- logger.info(`🔄 Force mode enabled for ${configName} - proceeding with full import`);
594
- }
595
558
  // Get all unique directory prefixes from include patterns to limit scanning
596
559
  const directoriesToScan = new Set();
597
560
  if (options.includes && options.includes.length > 0) {
@@ -1,6 +1,6 @@
1
1
  import { toCollectionEntry } from "./github.content.js";
2
2
  import { performSelectiveCleanup } from "./github.cleanup.js";
3
- import { performDryRun, displayDryRunResults, updateImportState } from "./github.dryrun.js";
3
+ import { performDryRun, displayDryRunResults, updateImportState, loadImportState, createConfigId, getLatestCommitInfo } from "./github.dryrun.js";
4
4
  import { createLogger } from "./github.logger.js";
5
5
  /**
6
6
  * Performs selective cleanup for configurations with basePath
@@ -95,6 +95,42 @@ export function githubLoader({ octokit, configs, fetchOptions = {}, clear = fals
95
95
  };
96
96
  const startTime = Date.now();
97
97
  try {
98
+ // Repository-level caching check before spinner
99
+ const configId = createConfigId(config);
100
+ if (!force) {
101
+ try {
102
+ const state = await loadImportState(process.cwd());
103
+ const currentState = state.imports[configId];
104
+ if (currentState && currentState.lastCommitSha) {
105
+ configLogger.debug(`🔍 Checking repository changes for ${configName}...`);
106
+ const latestCommit = await getLatestCommitInfo(octokit, config);
107
+ if (latestCommit && currentState.lastCommitSha === latestCommit.sha) {
108
+ configLogger.info(`✅ Repository ${configName} unchanged (${latestCommit.sha.slice(0, 7)}) - skipping import`);
109
+ // Update summary for unchanged repository
110
+ summary.duration = Date.now() - startTime;
111
+ summary.filesProcessed = 0;
112
+ summary.filesUpdated = 0;
113
+ summary.filesUnchanged = 0;
114
+ summary.status = 'success';
115
+ configLogger.logImportSummary(summary);
116
+ continue; // Skip to next config
117
+ }
118
+ else if (latestCommit) {
119
+ configLogger.info(`🔄 Repository ${configName} changed (${currentState.lastCommitSha?.slice(0, 7) || 'unknown'} -> ${latestCommit.sha.slice(0, 7)}) - proceeding with import`);
120
+ }
121
+ }
122
+ else {
123
+ configLogger.debug(`📥 First time importing ${configName} - no previous state found`);
124
+ }
125
+ }
126
+ catch (error) {
127
+ configLogger.warn(`Failed to check repository state for ${configName}: ${error instanceof Error ? error.message : String(error)}`);
128
+ // Continue with import if state check fails
129
+ }
130
+ }
131
+ else {
132
+ configLogger.info(`🔄 Force mode enabled for ${configName} - proceeding with full import`);
133
+ }
98
134
  // Perform the import with spinner
99
135
  const stats = await globalLogger.withSpinner(`🔄 Importing ${configName}...`, () => toCollectionEntry({
100
136
  context: { ...context, logger: configLogger },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@larkiny/astro-github-loader",
3
3
  "type": "module",
4
- "version": "0.9.0",
4
+ "version": "0.10.1",
5
5
  "description": "Load content from GitHub repositories into Astro content collections with asset management and content transformations",
6
6
  "keywords": [
7
7
  "astro",
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "github-slugger": "^2.0.0",
46
- "octokit": "^4.1.2",
46
+ "octokit": "^5.0.4",
47
47
  "picomatch": "^4.0.2"
48
48
  },
49
49
  "peerDependencies": {
@@ -4,7 +4,6 @@ import path, { join, dirname, basename, extname } from "node:path";
4
4
  import picomatch from "picomatch";
5
5
  import { globalLinkTransform, generateAutoLinkMappings, type ImportedFile } from "./github.link-transform.js";
6
6
  import type { Logger } from "./github.logger.js";
7
- import { getLatestCommitInfo, loadImportState, createConfigId } from "./github.dryrun.js";
8
7
 
9
8
  import {
10
9
  INVALID_SERVICE_RESPONSE,
@@ -663,41 +662,6 @@ export async function toCollectionEntry({
663
662
  // Get logger from context - it should be our Logger instance (initialize early)
664
663
  const logger = context.logger as unknown as Logger;
665
664
 
666
- // Repository-level caching - simple all-or-nothing approach
667
- const configName = options.name || `${owner}/${repo}`;
668
- const configId = createConfigId(options);
669
-
670
- if (!force) {
671
- try {
672
- const state = await loadImportState(process.cwd());
673
- const currentState = state.imports[configId];
674
-
675
- if (currentState && currentState.lastCommitSha) {
676
- logger.debug(`🔍 Checking repository changes for ${configName}...`);
677
- const latestCommit = await getLatestCommitInfo(octokit, options, signal);
678
-
679
- if (latestCommit && currentState.lastCommitSha === latestCommit.sha) {
680
- logger.info(`✅ Repository ${configName} unchanged (${latestCommit.sha.slice(0, 7)}) - skipping import`);
681
- return {
682
- processed: 0,
683
- updated: 0,
684
- unchanged: 0,
685
- assetsDownloaded: 0,
686
- assetsCached: 0,
687
- };
688
- } else if (latestCommit) {
689
- logger.info(`🔄 Repository ${configName} changed (${currentState.lastCommitSha?.slice(0, 7) || 'unknown'} -> ${latestCommit.sha.slice(0, 7)}) - proceeding with import`);
690
- }
691
- } else {
692
- logger.debug(`📥 First time importing ${configName} - no previous state found`);
693
- }
694
- } catch (error) {
695
- logger.warn(`Failed to check repository state for ${configName}: ${error instanceof Error ? error.message : String(error)}`);
696
- // Continue with import if state check fails
697
- }
698
- } else {
699
- logger.info(`🔄 Force mode enabled for ${configName} - proceeding with full import`);
700
- }
701
665
 
702
666
  // Get all unique directory prefixes from include patterns to limit scanning
703
667
  const directoriesToScan = new Set<string>();
@@ -1,6 +1,6 @@
1
1
  import { toCollectionEntry } from "./github.content.js";
2
2
  import { performSelectiveCleanup } from "./github.cleanup.js";
3
- import { performDryRun, displayDryRunResults, updateImportState } from "./github.dryrun.js";
3
+ import { performDryRun, displayDryRunResults, updateImportState, loadImportState, createConfigId, getLatestCommitInfo } from "./github.dryrun.js";
4
4
  import { createLogger, type Logger, type ImportSummary } from "./github.logger.js";
5
5
 
6
6
  import type {
@@ -133,6 +133,44 @@ export function githubLoader({
133
133
  const startTime = Date.now();
134
134
 
135
135
  try {
136
+ // Repository-level caching check before spinner
137
+ const configId = createConfigId(config);
138
+
139
+ if (!force) {
140
+ try {
141
+ const state = await loadImportState(process.cwd());
142
+ const currentState = state.imports[configId];
143
+
144
+ if (currentState && currentState.lastCommitSha) {
145
+ configLogger.debug(`🔍 Checking repository changes for ${configName}...`);
146
+ const latestCommit = await getLatestCommitInfo(octokit, config);
147
+
148
+ if (latestCommit && currentState.lastCommitSha === latestCommit.sha) {
149
+ configLogger.info(`✅ Repository ${configName} unchanged (${latestCommit.sha.slice(0, 7)}) - skipping import`);
150
+
151
+ // Update summary for unchanged repository
152
+ summary.duration = Date.now() - startTime;
153
+ summary.filesProcessed = 0;
154
+ summary.filesUpdated = 0;
155
+ summary.filesUnchanged = 0;
156
+ summary.status = 'success';
157
+
158
+ configLogger.logImportSummary(summary);
159
+ continue; // Skip to next config
160
+ } else if (latestCommit) {
161
+ configLogger.info(`🔄 Repository ${configName} changed (${currentState.lastCommitSha?.slice(0, 7) || 'unknown'} -> ${latestCommit.sha.slice(0, 7)}) - proceeding with import`);
162
+ }
163
+ } else {
164
+ configLogger.debug(`📥 First time importing ${configName} - no previous state found`);
165
+ }
166
+ } catch (error) {
167
+ configLogger.warn(`Failed to check repository state for ${configName}: ${error instanceof Error ? error.message : String(error)}`);
168
+ // Continue with import if state check fails
169
+ }
170
+ } else {
171
+ configLogger.info(`🔄 Force mode enabled for ${configName} - proceeding with full import`);
172
+ }
173
+
136
174
  // Perform the import with spinner
137
175
  const stats = await globalLogger.withSpinner(
138
176
  `🔄 Importing ${configName}...`,