gscdump 0.35.12 → 0.36.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.
@@ -1956,13 +1956,14 @@ function assertValidSiteUrl(siteUrl) {
1956
1956
  }
1957
1957
  function createAuth(options) {
1958
1958
  let credentials = { refresh_token: options.refreshToken };
1959
+ let refreshPromise = null;
1959
1960
  return {
1960
1961
  get credentials() {
1961
1962
  return credentials;
1962
1963
  },
1963
1964
  async getAccessToken() {
1964
1965
  if (credentials?.access_token && credentials.expiry_date && credentials.expiry_date > Date.now()) return { token: credentials.access_token };
1965
- const response = await ofetch("https://oauth2.googleapis.com/token", {
1966
+ refreshPromise ??= ofetch("https://oauth2.googleapis.com/token", {
1966
1967
  method: "POST",
1967
1968
  body: new URLSearchParams({
1968
1969
  client_id: options.clientId,
@@ -1970,13 +1971,17 @@ function createAuth(options) {
1970
1971
  refresh_token: options.refreshToken,
1971
1972
  grant_type: "refresh_token"
1972
1973
  })
1974
+ }).then((response) => {
1975
+ credentials = {
1976
+ ...credentials,
1977
+ access_token: response.access_token,
1978
+ expiry_date: Date.now() + response.expires_in * 1e3
1979
+ };
1980
+ return response.access_token;
1981
+ }).finally(() => {
1982
+ refreshPromise = null;
1973
1983
  });
1974
- credentials = {
1975
- ...credentials,
1976
- access_token: response.access_token,
1977
- expiry_date: Date.now() + response.expires_in * 1e3
1978
- };
1979
- return { token: response.access_token };
1984
+ return { token: await refreshPromise };
1980
1985
  }
1981
1986
  };
1982
1987
  }
package/dist/index.mjs CHANGED
@@ -644,13 +644,9 @@ function getDateRange(startDate, endDate) {
644
644
  }
645
645
  const DAYS_PER_RANGE = 30;
646
646
  function generateGscDateRange(startDate, endDate) {
647
- const dates = [];
648
- let current = startDate;
649
- while (current <= endDate && isValidGscDate(current)) {
650
- dates.push(current);
651
- current = getNextDate(current);
652
- }
653
- return dates;
647
+ const start = startDate < getOldestGscDate() ? getOldestGscDate() : startDate;
648
+ const end = endDate > getFreshestGscDate() ? getFreshestGscDate() : endDate;
649
+ return start <= end ? getDateRange(start, end) : [];
654
650
  }
655
651
  function groupIntoRanges(dates, daysPerRange = 30) {
656
652
  if (dates.length === 0) return [];
@@ -700,9 +696,8 @@ function isValidGscDate(dateStr) {
700
696
  function getBackfillProgress(oldestDateSynced, newestDateSynced) {
701
697
  if (!oldestDateSynced || !newestDateSynced) return null;
702
698
  const oldestGsc = getOldestGscDate();
703
- const newestGsc = getLatestGscDate();
704
- const totalDays = Math.ceil((new Date(newestGsc).getTime() - new Date(oldestGsc).getTime()) / MS_PER_DAY);
705
- const syncedDays = Math.ceil((new Date(newestDateSynced).getTime() - new Date(oldestDateSynced).getTime()) / MS_PER_DAY);
699
+ const totalDays = countDays(oldestGsc, getLatestGscDate());
700
+ const syncedDays = countDays(oldestDateSynced, newestDateSynced);
706
701
  return {
707
702
  progress: Math.round(Math.min(1, syncedDays / totalDays) * 100) / 100,
708
703
  daysAvailable: totalDays,
@@ -2651,13 +2646,14 @@ function assertValidSiteUrl(siteUrl) {
2651
2646
  }
2652
2647
  function createAuth(options) {
2653
2648
  let credentials = { refresh_token: options.refreshToken };
2649
+ let refreshPromise = null;
2654
2650
  return {
2655
2651
  get credentials() {
2656
2652
  return credentials;
2657
2653
  },
2658
2654
  async getAccessToken() {
2659
2655
  if (credentials?.access_token && credentials.expiry_date && credentials.expiry_date > Date.now()) return { token: credentials.access_token };
2660
- const response = await ofetch("https://oauth2.googleapis.com/token", {
2656
+ refreshPromise ??= ofetch("https://oauth2.googleapis.com/token", {
2661
2657
  method: "POST",
2662
2658
  body: new URLSearchParams({
2663
2659
  client_id: options.clientId,
@@ -2665,13 +2661,17 @@ function createAuth(options) {
2665
2661
  refresh_token: options.refreshToken,
2666
2662
  grant_type: "refresh_token"
2667
2663
  })
2664
+ }).then((response) => {
2665
+ credentials = {
2666
+ ...credentials,
2667
+ access_token: response.access_token,
2668
+ expiry_date: Date.now() + response.expires_in * 1e3
2669
+ };
2670
+ return response.access_token;
2671
+ }).finally(() => {
2672
+ refreshPromise = null;
2668
2673
  });
2669
- credentials = {
2670
- ...credentials,
2671
- access_token: response.access_token,
2672
- expiry_date: Date.now() + response.expires_in * 1e3
2673
- };
2674
- return { token: response.access_token };
2674
+ return { token: await refreshPromise };
2675
2675
  }
2676
2676
  };
2677
2677
  }
@@ -1885,8 +1885,7 @@ function extractSearchType(state) {
1885
1885
  if (!state) return void 0;
1886
1886
  if (state.searchType && KNOWN_SEARCH_TYPES.has(state.searchType)) return state.searchType;
1887
1887
  const filter = state.filter;
1888
- if (!filter || typeof filter !== "object") return void 0;
1889
- const raw = filter.searchType;
1888
+ const raw = extractSpecialFilters(normalizeFilter(filter)).searchType;
1890
1889
  if (typeof raw !== "string" || raw.length === 0) return void 0;
1891
1890
  return KNOWN_SEARCH_TYPES.has(raw) ? raw : void 0;
1892
1891
  }
@@ -2157,6 +2156,7 @@ function invertOperator(op) {
2157
2156
  return INVERSIONS[op];
2158
2157
  }
2159
2158
  function not(filter) {
2159
+ if ((filter._nestedGroups?.length ?? 0) > 0 || filter._filters.length !== 1) throw new Error("not() can only invert a single leaf filter. GSC filter groups do not support compound negation.");
2160
2160
  const inverted = [];
2161
2161
  for (const f of filter._filters) {
2162
2162
  if (DATE_OPERATORS.includes(f.operator)) throw new Error(`not() cannot invert date operator "${f.operator}": GSC has no negated date filter.`);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gscdump",
3
3
  "type": "module",
4
- "version": "0.35.12",
4
+ "version": "0.36.1",
5
5
  "description": "Google Search Console API wrapper with typed query builder, streaming pagination, and SEO analysis functions",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -98,7 +98,7 @@
98
98
  "defu": "^6.1.7",
99
99
  "ofetch": "^1.5.1",
100
100
  "ufo": "^1.6.4",
101
- "@gscdump/contracts": "0.35.12"
101
+ "@gscdump/contracts": "0.36.1"
102
102
  },
103
103
  "devDependencies": {
104
104
  "@googleapis/indexing": "^6.0.1",