astro-indexnow 2.3.6 → 2.3.8

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.
package/README.MD CHANGED
@@ -6,7 +6,7 @@ to **IndexNow** after each build.
6
6
  This package is designed for **modern CI/CD pipelines**, **Docker-based deployments**, and
7
7
  **large static sites**, while remaining fully deterministic and explicit.
8
8
 
9
- > **Current release:** v2.3.6
9
+ > **Current release:** v2.3.8
10
10
  > **Stateful by design. `changed` by default, `all` available. Batch-safe. CI-aware.**
11
11
 
12
12
  ---
@@ -198,10 +198,12 @@ To detect changes between builds, the integration stores a small cache file:
198
198
 
199
199
  This file:
200
200
  - Is created automatically
201
- - Contains only URL → hash mappings
201
+ - Contains a small version marker plus URL → hash mappings
202
202
  - Contains **no secrets**
203
203
  - Is safe to inspect, commit, or delete
204
204
 
205
+ Older flat cache files are still read automatically and will be upgraded on the next write.
206
+
205
207
  Deleting the file simply causes the next build to treat all pages as new.
206
208
 
207
209
  ---
@@ -312,6 +314,10 @@ The directory where the `.astro-indexnow-cache.json` file will be stored. Can be
312
314
 
313
315
  Example: `./node_modules/.astro`
314
316
 
317
+ The `site` value in Astro config may include a path prefix, such as `https://example.com/blog`. The integration preserves that base path when building submission URLs.
318
+
319
+ Submitted URLs use the canonical no-trailing-slash form for generated pages, except for the site root itself.
320
+
315
321
  ---
316
322
 
317
323
  ### `submissionMode` (optional)
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAM9C,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CAmUlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAM9C,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;IACzC,cAAc,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAOD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CA2WlB"}
package/dist/index.js CHANGED
@@ -48,7 +48,16 @@ export default function indexNow(options = {}) {
48
48
  function loadCache(logger) {
49
49
  logger.debug("loading cache file");
50
50
  try {
51
- return JSON.parse(fs.readFileSync(cachePath, "utf8"));
51
+ const parsed = JSON.parse(fs.readFileSync(cachePath, "utf8"));
52
+ if (parsed &&
53
+ typeof parsed === "object" &&
54
+ "version" in parsed &&
55
+ parsed.version === 1 &&
56
+ "entries" in parsed &&
57
+ typeof parsed.entries === "object") {
58
+ return parsed.entries;
59
+ }
60
+ return parsed;
52
61
  }
53
62
  catch {
54
63
  logger.warn("cache file unreadable, resetting");
@@ -57,7 +66,11 @@ export default function indexNow(options = {}) {
57
66
  }
58
67
  function saveCache(logger, data) {
59
68
  logger.debug("writing cache file");
60
- fs.writeFileSync(cachePath, JSON.stringify(data, null, 2), "utf8");
69
+ const cacheFile = {
70
+ version: 1,
71
+ entries: data,
72
+ };
73
+ fs.writeFileSync(cachePath, JSON.stringify(cacheFile, null, 2), "utf8");
61
74
  }
62
75
  function chunk(array, size) {
63
76
  const chunks = [];
@@ -69,6 +82,19 @@ export default function indexNow(options = {}) {
69
82
  function sleep(ms) {
70
83
  return new Promise((resolve) => setTimeout(resolve, ms));
71
84
  }
85
+ function normalizeSiteUrl(value) {
86
+ const url = new URL(value);
87
+ const normalizedPath = url.pathname.replace(/\/+$/, "").replace(/\/+/g, "/");
88
+ url.pathname = normalizedPath || "/";
89
+ return url.toString().replace(/\/$/, "");
90
+ }
91
+ function normalizeSubmittedUrl(value) {
92
+ const url = new URL(value);
93
+ if (url.pathname !== "/") {
94
+ url.pathname = url.pathname.replace(/\/+$/, "");
95
+ }
96
+ return url.toString();
97
+ }
72
98
  function isQuiet() {
73
99
  return options.logMode === "quiet";
74
100
  }
@@ -139,8 +165,11 @@ export default function indexNow(options = {}) {
139
165
  ----------------------------------------------- */
140
166
  "astro:config:setup": ({ config, logger }) => {
141
167
  site =
142
- options.siteUrl ??
143
- (config.site ? config.site.replace(/\/$/, "") : null);
168
+ options.siteUrl
169
+ ? normalizeSiteUrl(options.siteUrl)
170
+ : config.site
171
+ ? normalizeSiteUrl(config.site)
172
+ : null;
144
173
  logVerbose(logger, `project root: ${projectRoot}`);
145
174
  ensureCacheFile(logger);
146
175
  },
@@ -175,7 +204,7 @@ export default function indexNow(options = {}) {
175
204
  .relative(outDir, fullPath)
176
205
  .replace(/index\.html$/, "")
177
206
  .replace(/\\/g, "/");
178
- const url = site + "/" + relativePath.replace(/^\/+/, "");
207
+ const url = normalizeSubmittedUrl(new URL(relativePath.replace(/^\/+/, ""), `${site}/`).toString());
179
208
  const hash = hashFile(fullPath);
180
209
  // Cache by URL because IndexNow submits URLs, not filesystem paths.
181
210
  nextCache[url] = hash;
@@ -228,13 +257,13 @@ export default function indexNow(options = {}) {
228
257
  anyBatchFailed = true;
229
258
  }
230
259
  }
231
- saveCache(logger, nextCache);
232
260
  if (anyBatchFailed) {
233
261
  logWarn(logger, `IndexNow submission failed`);
262
+ logWarn(logger, "cache left unchanged because one or more submissions failed");
263
+ return;
234
264
  }
235
- else {
236
- logInfo(logger, `IndexNow submission complete`);
237
- }
265
+ saveCache(logger, nextCache);
266
+ logInfo(logger, `IndexNow submission complete`);
238
267
  },
239
268
  },
240
269
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-indexnow",
3
- "version": "2.3.6",
3
+ "version": "2.3.8",
4
4
  "description": "Astro integration to submit pages to IndexNow automatically after build",
5
5
  "type": "module",
6
6
  "exports": {