@shaivpidadi/trends-js 0.0.0-beta.8 → 1.0.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.
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
- 🚧 WIP: Temporary workaround for [#175](https://github.com/pat310/google-trends-api/issues/175)
1
+ A TypeScript library for interacting with the Google Trends API. This package provides a simple and type-safe way to access Google Trends data programmatically.
2
2
 
3
- # @shaivpidadi/trends-js
3
+ ## Showcase
4
+
5
+ ### EliteTimesNews.com — Built with `@shaivpidadi/trends-js`
6
+ **URL:** https://elitetimesnews.com
7
+ **What it uses:** `dailyTrends()` (US, en) to power the home page “Daily Trending” rail, refreshed on a schedule.
4
8
 
5
- A TypeScript library for interacting with the Google Trends API. This package provides a simple and type-safe way to access Google Trends data programmatically.
6
9
 
7
10
  ## Installation
8
11
 
@@ -1,3 +1,3 @@
1
- import { GoogleTrendsEndpoints } from './types/enums';
2
- import { GoogleTrendsMapper } from './types';
1
+ import { GoogleTrendsEndpoints } from './types/enums.js';
2
+ import { GoogleTrendsMapper } from './types/index.js';
3
3
  export declare const GOOGLE_TRENDS_MAPPER: Record<GoogleTrendsEndpoints, GoogleTrendsMapper>;
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GOOGLE_TRENDS_MAPPER = void 0;
4
- const enums_1 = require("./types/enums");
4
+ const enums_js_1 = require("./types/enums.js");
5
5
  const GOOGLE_TRENDS_BASE_URL = 'trends.google.com';
6
6
  exports.GOOGLE_TRENDS_MAPPER = {
7
- [enums_1.GoogleTrendsEndpoints.dailyTrends]: {
7
+ [enums_js_1.GoogleTrendsEndpoints.dailyTrends]: {
8
8
  path: '/_/TrendsUi/data/batchexecute',
9
9
  method: 'POST',
10
10
  host: GOOGLE_TRENDS_BASE_URL,
@@ -13,7 +13,7 @@ exports.GOOGLE_TRENDS_MAPPER = {
13
13
  'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
14
14
  },
15
15
  },
16
- [enums_1.GoogleTrendsEndpoints.autocomplete]: {
16
+ [enums_js_1.GoogleTrendsEndpoints.autocomplete]: {
17
17
  path: '/trends/api/autocomplete',
18
18
  method: 'GET',
19
19
  host: GOOGLE_TRENDS_BASE_URL,
@@ -22,28 +22,28 @@ exports.GOOGLE_TRENDS_MAPPER = {
22
22
  accept: 'application/json, text/plain, */*',
23
23
  },
24
24
  },
25
- [enums_1.GoogleTrendsEndpoints.explore]: {
25
+ [enums_js_1.GoogleTrendsEndpoints.explore]: {
26
26
  path: '/trends/api/explore',
27
27
  method: 'POST',
28
28
  host: GOOGLE_TRENDS_BASE_URL,
29
29
  url: `https://${GOOGLE_TRENDS_BASE_URL}/trends/api/explore`,
30
30
  headers: {},
31
31
  },
32
- [enums_1.GoogleTrendsEndpoints.interestByRegion]: {
32
+ [enums_js_1.GoogleTrendsEndpoints.interestByRegion]: {
33
33
  path: '/trends/api/widgetdata/comparedgeo',
34
34
  method: 'GET',
35
35
  host: GOOGLE_TRENDS_BASE_URL,
36
36
  url: `https://${GOOGLE_TRENDS_BASE_URL}/trends/api/widgetdata/comparedgeo`,
37
37
  headers: {},
38
38
  },
39
- [enums_1.GoogleTrendsEndpoints.relatedTopics]: {
39
+ [enums_js_1.GoogleTrendsEndpoints.relatedTopics]: {
40
40
  path: '/trends/api/widgetdata/relatedtopics',
41
41
  method: 'GET',
42
42
  host: GOOGLE_TRENDS_BASE_URL,
43
43
  url: `https://${GOOGLE_TRENDS_BASE_URL}/trends/api/widgetdata/relatedtopics`,
44
44
  headers: {},
45
45
  },
46
- [enums_1.GoogleTrendsEndpoints.relatedQueries]: {
46
+ [enums_js_1.GoogleTrendsEndpoints.relatedQueries]: {
47
47
  path: '/trends/api/widgetdata/relatedqueries',
48
48
  method: 'GET',
49
49
  host: GOOGLE_TRENDS_BASE_URL,
@@ -1,4 +1,4 @@
1
- import { GoogleTrendsError } from '../types';
1
+ import { GoogleTrendsError } from '../types/index.js';
2
2
  export declare class RateLimitError extends Error implements GoogleTrendsError {
3
3
  code: string;
4
4
  statusCode: number;
@@ -1,2 +1,2 @@
1
- import { DailyTrendingTopics } from '../types';
1
+ import { DailyTrendingTopics } from '../types/index.js';
2
2
  export declare const extractJsonFromResponse: (text: string) => DailyTrendingTopics | null;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.extractJsonFromResponse = void 0;
4
- const GoogleTrendsError_1 = require("../errors/GoogleTrendsError");
4
+ const GoogleTrendsError_js_1 = require("../errors/GoogleTrendsError.js");
5
5
  // For future refrence and update: from google trends page rpc call response,
6
6
  // 0 "twitter down" The main trending search term.
7
7
  // 1 null Unused (reserved for future Google Trends data).
@@ -21,29 +21,29 @@ const extractJsonFromResponse = (text) => {
21
21
  try {
22
22
  const parsedResponse = JSON.parse(cleanedText);
23
23
  if (!Array.isArray(parsedResponse) || parsedResponse.length === 0) {
24
- throw new GoogleTrendsError_1.ParseError('Invalid response format: empty array');
24
+ throw new GoogleTrendsError_js_1.ParseError('Invalid response format: empty array');
25
25
  }
26
26
  const nestedJsonString = parsedResponse[0][2];
27
27
  if (!nestedJsonString) {
28
- throw new GoogleTrendsError_1.ParseError('Invalid response format: missing nested JSON');
28
+ throw new GoogleTrendsError_js_1.ParseError('Invalid response format: missing nested JSON');
29
29
  }
30
30
  const data = JSON.parse(nestedJsonString);
31
31
  if (!data || !Array.isArray(data) || data.length < 2) {
32
- throw new GoogleTrendsError_1.ParseError('Invalid response format: missing data array');
32
+ throw new GoogleTrendsError_js_1.ParseError('Invalid response format: missing data array');
33
33
  }
34
34
  return updateResponseObject(data[1]);
35
35
  }
36
36
  catch (e) {
37
- if (e instanceof GoogleTrendsError_1.ParseError) {
37
+ if (e instanceof GoogleTrendsError_js_1.ParseError) {
38
38
  throw e;
39
39
  }
40
- throw new GoogleTrendsError_1.ParseError('Failed to parse response');
40
+ throw new GoogleTrendsError_js_1.ParseError('Failed to parse response');
41
41
  }
42
42
  };
43
43
  exports.extractJsonFromResponse = extractJsonFromResponse;
44
44
  const updateResponseObject = (data) => {
45
45
  if (!Array.isArray(data)) {
46
- throw new GoogleTrendsError_1.ParseError('Invalid data format: expected array');
46
+ throw new GoogleTrendsError_js_1.ParseError('Invalid data format: expected array');
47
47
  }
48
48
  const allTrendingStories = [];
49
49
  const summary = [];
@@ -1,4 +1,4 @@
1
- import { DailyTrendingTopics, DailyTrendingTopicsOptions, RealTimeTrendsOptions, ExploreOptions, ExploreResponse, InterestByRegionOptions, InterestByRegionResponse, GoogleTrendsResponse, RelatedTopicsResponse, RelatedQueriesResponse, RelatedData } from '../types/index';
1
+ import { DailyTrendingTopics, DailyTrendingTopicsOptions, RealTimeTrendsOptions, ExploreOptions, ExploreResponse, InterestByRegionOptions, InterestByRegionResponse, GoogleTrendsResponse, GoogleTrendsError, RelatedTopicsResponse, RelatedQueriesResponse, RelatedData } from '../types/index.js';
2
2
  export declare class GoogleTrendsApi {
3
3
  /**
4
4
  * Get autocomplete suggestions for a keyword
@@ -19,8 +19,12 @@ export declare class GoogleTrendsApi {
19
19
  * @returns Promise with trending topics data
20
20
  */
21
21
  realTimeTrends({ geo, trendingHours }: RealTimeTrendsOptions): Promise<GoogleTrendsResponse<DailyTrendingTopics>>;
22
- explore({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<ExploreResponse>;
23
- interestByRegion({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: InterestByRegionOptions): Promise<InterestByRegionResponse>;
22
+ explore({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<ExploreResponse | {
23
+ error: GoogleTrendsError;
24
+ }>;
25
+ interestByRegion({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: InterestByRegionOptions): Promise<InterestByRegionResponse | {
26
+ error: GoogleTrendsError;
27
+ }>;
24
28
  relatedTopics({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedTopicsResponse>>;
25
29
  relatedQueries({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedQueriesResponse>>;
26
30
  relatedData({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedData>>;
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GoogleTrendsApi = void 0;
4
- const enums_1 = require("../types/enums");
5
- const request_1 = require("./request");
6
- const format_1 = require("./format");
7
- const constants_1 = require("../constants");
8
- const GoogleTrendsError_1 = require("../errors/GoogleTrendsError");
4
+ const enums_js_1 = require("../types/enums.js");
5
+ const request_js_1 = require("./request.js");
6
+ const format_js_1 = require("./format.js");
7
+ const constants_js_1 = require("../constants.js");
8
+ const GoogleTrendsError_js_1 = require("../errors/GoogleTrendsError.js");
9
9
  class GoogleTrendsApi {
10
10
  /**
11
11
  * Get autocomplete suggestions for a keyword
@@ -18,14 +18,14 @@ class GoogleTrendsApi {
18
18
  return { data: [] };
19
19
  }
20
20
  const options = {
21
- ...constants_1.GOOGLE_TRENDS_MAPPER[enums_1.GoogleTrendsEndpoints.autocomplete],
21
+ ...constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.autocomplete],
22
22
  qs: {
23
23
  hl,
24
24
  tz: '240',
25
25
  },
26
26
  };
27
27
  try {
28
- const response = await (0, request_1.request)(`${options.url}/${encodeURIComponent(keyword)}`, options);
28
+ const response = await (0, request_js_1.request)(`${options.url}/${encodeURIComponent(keyword)}`, options);
29
29
  const text = await response.text();
30
30
  // Remove the first 5 characters (JSONP wrapper) and parse
31
31
  const data = JSON.parse(text.slice(5));
@@ -33,9 +33,9 @@ class GoogleTrendsApi {
33
33
  }
34
34
  catch (error) {
35
35
  if (error instanceof Error) {
36
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
36
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
37
37
  }
38
- return { error: new GoogleTrendsError_1.UnknownError() };
38
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
39
39
  }
40
40
  }
41
41
  /**
@@ -44,7 +44,7 @@ class GoogleTrendsApi {
44
44
  * @returns Promise with trending topics data
45
45
  */
46
46
  async dailyTrends({ geo = 'US', lang = 'en' }) {
47
- const defaultOptions = constants_1.GOOGLE_TRENDS_MAPPER[enums_1.GoogleTrendsEndpoints.dailyTrends];
47
+ const defaultOptions = constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.dailyTrends];
48
48
  const options = {
49
49
  ...defaultOptions,
50
50
  body: new URLSearchParams({
@@ -53,19 +53,19 @@ class GoogleTrendsApi {
53
53
  contentType: 'form'
54
54
  };
55
55
  try {
56
- const response = await (0, request_1.request)(options.url, options);
56
+ const response = await (0, request_js_1.request)(options.url, options);
57
57
  const text = await response.text();
58
- const trendingTopics = (0, format_1.extractJsonFromResponse)(text);
58
+ const trendingTopics = (0, format_js_1.extractJsonFromResponse)(text);
59
59
  if (!trendingTopics) {
60
- return { error: new GoogleTrendsError_1.ParseError() };
60
+ return { error: new GoogleTrendsError_js_1.ParseError() };
61
61
  }
62
62
  return { data: trendingTopics };
63
63
  }
64
64
  catch (error) {
65
65
  if (error instanceof Error) {
66
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
66
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
67
67
  }
68
- return { error: new GoogleTrendsError_1.UnknownError() };
68
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
69
69
  }
70
70
  }
71
71
  /**
@@ -74,7 +74,7 @@ class GoogleTrendsApi {
74
74
  * @returns Promise with trending topics data
75
75
  */
76
76
  async realTimeTrends({ geo = 'US', trendingHours = 4 }) {
77
- const defaultOptions = constants_1.GOOGLE_TRENDS_MAPPER[enums_1.GoogleTrendsEndpoints.dailyTrends];
77
+ const defaultOptions = constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.dailyTrends];
78
78
  const options = {
79
79
  ...defaultOptions,
80
80
  body: new URLSearchParams({
@@ -83,24 +83,24 @@ class GoogleTrendsApi {
83
83
  contentType: 'form'
84
84
  };
85
85
  try {
86
- const response = await (0, request_1.request)(options.url, options);
86
+ const response = await (0, request_js_1.request)(options.url, options);
87
87
  const text = await response.text();
88
- const trendingTopics = (0, format_1.extractJsonFromResponse)(text);
88
+ const trendingTopics = (0, format_js_1.extractJsonFromResponse)(text);
89
89
  if (!trendingTopics) {
90
- return { error: new GoogleTrendsError_1.ParseError() };
90
+ return { error: new GoogleTrendsError_js_1.ParseError() };
91
91
  }
92
92
  return { data: trendingTopics };
93
93
  }
94
94
  catch (error) {
95
95
  if (error instanceof Error) {
96
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
96
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
97
97
  }
98
- return { error: new GoogleTrendsError_1.UnknownError() };
98
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
99
99
  }
100
100
  }
101
101
  async explore({ keyword, geo = 'US', time = 'now 1-d', category = 0, property = '', hl = 'en-US', }) {
102
102
  const options = {
103
- ...constants_1.GOOGLE_TRENDS_MAPPER[enums_1.GoogleTrendsEndpoints.explore],
103
+ ...constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.explore],
104
104
  qs: {
105
105
  hl,
106
106
  tz: '240',
@@ -119,28 +119,35 @@ class GoogleTrendsApi {
119
119
  contentType: 'form'
120
120
  };
121
121
  try {
122
- const response = await (0, request_1.request)(options.url, options);
122
+ const response = await (0, request_js_1.request)(options.url, options);
123
123
  const text = await response.text();
124
124
  // Check if response is HTML (error page)
125
125
  if (text.includes('<html') || text.includes('<!DOCTYPE')) {
126
- console.error('Explore request returned HTML instead of JSON');
127
- return { widgets: [] };
126
+ return { error: new GoogleTrendsError_js_1.ParseError('Explore request returned HTML instead of JSON') };
128
127
  }
129
128
  // Try to parse as JSON
130
129
  try {
131
130
  // Remove the first 5 characters (JSONP wrapper) and parse
132
131
  const data = JSON.parse(text.slice(5));
133
- return data;
132
+ // Extract widgets from the response
133
+ if (data && Array.isArray(data) && data.length > 0) {
134
+ const widgets = data[0] || [];
135
+ return { widgets };
136
+ }
137
+ return { widgets: [] };
134
138
  }
135
139
  catch (parseError) {
136
- console.error('Failed to parse explore response as JSON:', parseError instanceof Error ? parseError.message : 'Unknown parse error');
137
- console.error('Response preview:', text.substring(0, 200));
138
- return { widgets: [] };
140
+ if (parseError instanceof Error) {
141
+ return { error: new GoogleTrendsError_js_1.ParseError(`Failed to parse explore response as JSON: ${parseError.message}`) };
142
+ }
143
+ return { error: new GoogleTrendsError_js_1.ParseError('Failed to parse explore response as JSON') };
139
144
  }
140
145
  }
141
146
  catch (error) {
142
- console.error('Explore request failed:', error);
143
- return { widgets: [] };
147
+ if (error instanceof Error) {
148
+ return { error: new GoogleTrendsError_js_1.NetworkError(`Explore request failed: ${error.message}`) };
149
+ }
150
+ return { error: new GoogleTrendsError_js_1.UnknownError('Explore request failed') };
144
151
  }
145
152
  }
146
153
  //
@@ -172,12 +179,15 @@ class GoogleTrendsApi {
172
179
  category,
173
180
  hl
174
181
  });
182
+ if ('error' in exploreResponse) {
183
+ return { error: exploreResponse.error };
184
+ }
175
185
  const widget = exploreResponse.widgets.find(w => w.id === 'GEO_MAP');
176
186
  if (!widget) {
177
- return { default: { geoMapData: [] } };
187
+ return { error: new GoogleTrendsError_js_1.ParseError('No GEO_MAP widget found in explore response') };
178
188
  }
179
189
  const options = {
180
- ...constants_1.GOOGLE_TRENDS_MAPPER[enums_1.GoogleTrendsEndpoints.interestByRegion],
190
+ ...constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.interestByRegion],
181
191
  qs: {
182
192
  hl,
183
193
  tz: timezone.toString(),
@@ -209,59 +219,116 @@ class GoogleTrendsApi {
209
219
  }
210
220
  };
211
221
  try {
212
- const response = await (0, request_1.request)(options.url, options);
222
+ const response = await (0, request_js_1.request)(options.url, options);
213
223
  const text = await response.text();
214
224
  // Remove the first 5 characters (JSONP wrapper) and parse
215
225
  const data = JSON.parse(text.slice(5));
216
226
  return data;
217
227
  }
218
228
  catch (error) {
219
- return { default: { geoMapData: [] } };
229
+ if (error instanceof Error) {
230
+ return { error: new GoogleTrendsError_js_1.ParseError(`Failed to parse interest by region response: ${error.message}`) };
231
+ }
232
+ return { error: new GoogleTrendsError_js_1.ParseError('Failed to parse interest by region response') };
220
233
  }
221
234
  }
222
235
  async relatedTopics({ keyword, geo = 'US', time = 'now 1-d', category = 0, property = '', hl = 'en-US', }) {
223
236
  try {
224
237
  // Validate keyword
225
238
  if (!keyword || keyword.trim() === '') {
226
- return { error: new GoogleTrendsError_1.ParseError() };
239
+ return { error: new GoogleTrendsError_js_1.InvalidRequestError('Keyword is required') };
227
240
  }
228
- const autocompleteResult = await this.autocomplete(keyword, hl);
229
- if (autocompleteResult.error) {
230
- return { error: autocompleteResult.error };
241
+ // Step 1: Call explore to get widget data and token
242
+ const exploreResponse = await this.explore({
243
+ keyword,
244
+ geo,
245
+ time,
246
+ category,
247
+ property,
248
+ hl
249
+ });
250
+ if ('error' in exploreResponse) {
251
+ return { error: exploreResponse.error };
231
252
  }
232
- const relatedTopics = autocompleteResult.data?.slice(0, 10).map((suggestion, index) => ({
233
- topic: {
234
- mid: `/m/${index}`,
235
- title: suggestion,
236
- type: 'Topic'
237
- },
238
- value: 100 - index * 10,
239
- formattedValue: (100 - index * 10).toString(),
240
- hasData: true,
241
- link: `/trends/explore?q=${encodeURIComponent(suggestion)}&date=${time}&geo=${geo}`
242
- })) || [];
243
- return {
244
- data: {
245
- default: {
246
- rankedList: [{
247
- rankedKeyword: relatedTopics
248
- }]
249
- }
253
+ if (!exploreResponse.widgets || exploreResponse.widgets.length === 0) {
254
+ return { error: new GoogleTrendsError_js_1.ParseError('No widgets found in explore response. This might be due to Google blocking the request, invalid parameters, or network issues.') };
255
+ }
256
+ // Step 2: Find the related topics widget or use any available widget
257
+ const relatedTopicsWidget = exploreResponse.widgets.find(widget => widget.id === 'RELATED_TOPICS' ||
258
+ widget.request?.restriction?.complexKeywordsRestriction?.keyword?.[0]?.value === keyword) || exploreResponse.widgets[0]; // Fallback to first widget if no specific one found
259
+ if (!relatedTopicsWidget) {
260
+ return { error: new GoogleTrendsError_js_1.ParseError('No related topics widget found in explore response') };
261
+ }
262
+ // Step 3: Call the related topics API with or without token
263
+ const options = {
264
+ ...constants_js_1.GOOGLE_TRENDS_MAPPER[enums_js_1.GoogleTrendsEndpoints.relatedTopics],
265
+ qs: {
266
+ hl,
267
+ tz: '240',
268
+ req: JSON.stringify({
269
+ restriction: {
270
+ geo: { country: geo },
271
+ time: time,
272
+ originalTimeRangeForExploreUrl: time,
273
+ complexKeywordsRestriction: {
274
+ keyword: [{
275
+ type: 'BROAD',
276
+ value: keyword
277
+ }]
278
+ }
279
+ },
280
+ keywordType: 'ENTITY',
281
+ metric: ['TOP', 'RISING'],
282
+ trendinessSettings: {
283
+ compareTime: time
284
+ },
285
+ requestOptions: {
286
+ property: property,
287
+ backend: 'CM',
288
+ category: category
289
+ },
290
+ language: hl.split('-')[0],
291
+ userCountryCode: geo,
292
+ userConfig: {
293
+ userType: 'USER_TYPE_LEGIT_USER'
294
+ }
295
+ }),
296
+ ...(relatedTopicsWidget.token && { token: relatedTopicsWidget.token })
250
297
  }
251
298
  };
299
+ const response = await (0, request_js_1.request)(options.url, options);
300
+ const text = await response.text();
301
+ // Parse the response
302
+ try {
303
+ const data = JSON.parse(text.slice(5));
304
+ // Return the data in the expected format
305
+ return {
306
+ data: {
307
+ default: {
308
+ rankedList: data.default?.rankedList || []
309
+ }
310
+ }
311
+ };
312
+ }
313
+ catch (parseError) {
314
+ if (parseError instanceof Error) {
315
+ return { error: new GoogleTrendsError_js_1.ParseError(`Failed to parse related topics response: ${parseError.message}`) };
316
+ }
317
+ return { error: new GoogleTrendsError_js_1.ParseError('Failed to parse related topics response') };
318
+ }
252
319
  }
253
320
  catch (error) {
254
321
  if (error instanceof Error) {
255
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
322
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
256
323
  }
257
- return { error: new GoogleTrendsError_1.UnknownError() };
324
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
258
325
  }
259
326
  }
260
327
  async relatedQueries({ keyword, geo = 'US', time = 'now 1-d', category = 0, property = '', hl = 'en-US', }) {
261
328
  try {
262
329
  // Validate keyword
263
330
  if (!keyword || keyword.trim() === '') {
264
- return { error: new GoogleTrendsError_1.ParseError() };
331
+ return { error: new GoogleTrendsError_js_1.ParseError() };
265
332
  }
266
333
  const autocompleteResult = await this.autocomplete(keyword, hl);
267
334
  if (autocompleteResult.error) {
@@ -286,16 +353,16 @@ class GoogleTrendsApi {
286
353
  }
287
354
  catch (error) {
288
355
  if (error instanceof Error) {
289
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
356
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
290
357
  }
291
- return { error: new GoogleTrendsError_1.UnknownError() };
358
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
292
359
  }
293
360
  }
294
361
  async relatedData({ keyword, geo = 'US', time = 'now 1-d', category = 0, property = '', hl = 'en-US', }) {
295
362
  try {
296
363
  // Validate keyword
297
364
  if (!keyword || keyword.trim() === '') {
298
- return { error: new GoogleTrendsError_1.ParseError() };
365
+ return { error: new GoogleTrendsError_js_1.ParseError() };
299
366
  }
300
367
  const autocompleteResult = await this.autocomplete(keyword, hl);
301
368
  if (autocompleteResult.error) {
@@ -329,9 +396,9 @@ class GoogleTrendsApi {
329
396
  }
330
397
  catch (error) {
331
398
  if (error instanceof Error) {
332
- return { error: new GoogleTrendsError_1.NetworkError(error.message) };
399
+ return { error: new GoogleTrendsError_js_1.NetworkError(error.message) };
333
400
  }
334
- return { error: new GoogleTrendsError_1.UnknownError() };
401
+ return { error: new GoogleTrendsError_js_1.UnknownError() };
335
402
  }
336
403
  }
337
404
  }
@@ -1,19 +1,29 @@
1
- export declare const dailyTrends: ({ geo, lang }: import("./types").DailyTrendingTopicsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
2
- export declare const realTimeTrends: ({ geo, trendingHours }: import("./types").RealTimeTrendsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
3
- export declare const autocomplete: (keyword: string, hl?: string) => Promise<import("./types").GoogleTrendsResponse<string[]>>;
4
- export declare const explore: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").ExploreResponse>;
5
- export declare const interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types").InterestByRegionOptions) => Promise<import("./types").InterestByRegionResponse>;
6
- export declare const relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedTopicsResponse>>;
7
- export declare const relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedQueriesResponse>>;
8
- export declare const relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedData>>;
1
+ import { GoogleTrendsApi } from './helpers/googleTrendsAPI.js';
2
+ export declare const dailyTrends: ({ geo, lang }: import("./types/index.js").DailyTrendingTopicsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
3
+ export declare const realTimeTrends: ({ geo, trendingHours }: import("./types/index.js").RealTimeTrendsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
4
+ export declare const autocomplete: (keyword: string, hl?: string) => Promise<import("./types/index.js").GoogleTrendsResponse<string[]>>;
5
+ export declare const explore: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").ExploreResponse | {
6
+ error: import("./types/index.js").GoogleTrendsError;
7
+ }>;
8
+ export declare const interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types/index.js").InterestByRegionOptions) => Promise<import("./types/index.js").InterestByRegionResponse | {
9
+ error: import("./types/index.js").GoogleTrendsError;
10
+ }>;
11
+ export declare const relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedTopicsResponse>>;
12
+ export declare const relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedQueriesResponse>>;
13
+ export declare const relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedData>>;
14
+ export { GoogleTrendsApi };
9
15
  declare const _default: {
10
- dailyTrends: ({ geo, lang }: import("./types").DailyTrendingTopicsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
11
- realTimeTrends: ({ geo, trendingHours }: import("./types").RealTimeTrendsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
12
- autocomplete: (keyword: string, hl?: string) => Promise<import("./types").GoogleTrendsResponse<string[]>>;
13
- explore: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").ExploreResponse>;
14
- interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types").InterestByRegionOptions) => Promise<import("./types").InterestByRegionResponse>;
15
- relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedTopicsResponse>>;
16
- relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedQueriesResponse>>;
17
- relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedData>>;
16
+ dailyTrends: ({ geo, lang }: import("./types/index.js").DailyTrendingTopicsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
17
+ realTimeTrends: ({ geo, trendingHours }: import("./types/index.js").RealTimeTrendsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
18
+ autocomplete: (keyword: string, hl?: string) => Promise<import("./types/index.js").GoogleTrendsResponse<string[]>>;
19
+ explore: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").ExploreResponse | {
20
+ error: import("./types/index.js").GoogleTrendsError;
21
+ }>;
22
+ interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types/index.js").InterestByRegionOptions) => Promise<import("./types/index.js").InterestByRegionResponse | {
23
+ error: import("./types/index.js").GoogleTrendsError;
24
+ }>;
25
+ relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedTopicsResponse>>;
26
+ relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedQueriesResponse>>;
27
+ relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedData>>;
18
28
  };
19
29
  export default _default;
package/dist/cjs/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.relatedData = exports.relatedQueries = exports.relatedTopics = exports.interestByRegion = exports.explore = exports.autocomplete = exports.realTimeTrends = exports.dailyTrends = void 0;
4
- const googleTrendsAPI_1 = require("./helpers/googleTrendsAPI");
5
- const api = new googleTrendsAPI_1.GoogleTrendsApi();
3
+ exports.GoogleTrendsApi = exports.relatedData = exports.relatedQueries = exports.relatedTopics = exports.interestByRegion = exports.explore = exports.autocomplete = exports.realTimeTrends = exports.dailyTrends = void 0;
4
+ const googleTrendsAPI_js_1 = require("./helpers/googleTrendsAPI.js");
5
+ Object.defineProperty(exports, "GoogleTrendsApi", { enumerable: true, get: function () { return googleTrendsAPI_js_1.GoogleTrendsApi; } });
6
+ const api = new googleTrendsAPI_js_1.GoogleTrendsApi();
6
7
  exports.dailyTrends = api.dailyTrends.bind(api);
7
8
  exports.realTimeTrends = api.realTimeTrends.bind(api);
8
9
  exports.autocomplete = api.autocomplete.bind(api);
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -1,3 +1,3 @@
1
- import { GoogleTrendsEndpoints } from './types/enums';
2
- import { GoogleTrendsMapper } from './types';
1
+ import { GoogleTrendsEndpoints } from './types/enums.js';
2
+ import { GoogleTrendsMapper } from './types/index.js';
3
3
  export declare const GOOGLE_TRENDS_MAPPER: Record<GoogleTrendsEndpoints, GoogleTrendsMapper>;
@@ -1,4 +1,4 @@
1
- import { GoogleTrendsEndpoints } from './types/enums';
1
+ import { GoogleTrendsEndpoints } from './types/enums.js';
2
2
  const GOOGLE_TRENDS_BASE_URL = 'trends.google.com';
3
3
  export const GOOGLE_TRENDS_MAPPER = {
4
4
  [GoogleTrendsEndpoints.dailyTrends]: {
@@ -1,4 +1,4 @@
1
- import { GoogleTrendsError } from '../types';
1
+ import { GoogleTrendsError } from '../types/index.js';
2
2
  export declare class RateLimitError extends Error implements GoogleTrendsError {
3
3
  code: string;
4
4
  statusCode: number;
@@ -1,2 +1,2 @@
1
- import { DailyTrendingTopics } from '../types';
1
+ import { DailyTrendingTopics } from '../types/index.js';
2
2
  export declare const extractJsonFromResponse: (text: string) => DailyTrendingTopics | null;
@@ -1,4 +1,4 @@
1
- import { ParseError } from '../errors/GoogleTrendsError';
1
+ import { ParseError } from '../errors/GoogleTrendsError.js';
2
2
  // For future refrence and update: from google trends page rpc call response,
3
3
  // 0 "twitter down" The main trending search term.
4
4
  // 1 null Unused (reserved for future Google Trends data).
@@ -1,4 +1,4 @@
1
- import { DailyTrendingTopics, DailyTrendingTopicsOptions, RealTimeTrendsOptions, ExploreOptions, ExploreResponse, InterestByRegionOptions, InterestByRegionResponse, GoogleTrendsResponse, RelatedTopicsResponse, RelatedQueriesResponse, RelatedData } from '../types/index';
1
+ import { DailyTrendingTopics, DailyTrendingTopicsOptions, RealTimeTrendsOptions, ExploreOptions, ExploreResponse, InterestByRegionOptions, InterestByRegionResponse, GoogleTrendsResponse, GoogleTrendsError, RelatedTopicsResponse, RelatedQueriesResponse, RelatedData } from '../types/index.js';
2
2
  export declare class GoogleTrendsApi {
3
3
  /**
4
4
  * Get autocomplete suggestions for a keyword
@@ -19,8 +19,12 @@ export declare class GoogleTrendsApi {
19
19
  * @returns Promise with trending topics data
20
20
  */
21
21
  realTimeTrends({ geo, trendingHours }: RealTimeTrendsOptions): Promise<GoogleTrendsResponse<DailyTrendingTopics>>;
22
- explore({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<ExploreResponse>;
23
- interestByRegion({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: InterestByRegionOptions): Promise<InterestByRegionResponse>;
22
+ explore({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<ExploreResponse | {
23
+ error: GoogleTrendsError;
24
+ }>;
25
+ interestByRegion({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: InterestByRegionOptions): Promise<InterestByRegionResponse | {
26
+ error: GoogleTrendsError;
27
+ }>;
24
28
  relatedTopics({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedTopicsResponse>>;
25
29
  relatedQueries({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedQueriesResponse>>;
26
30
  relatedData({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedData>>;
@@ -1,8 +1,8 @@
1
- import { GoogleTrendsEndpoints } from '../types/enums';
2
- import { request } from './request';
3
- import { extractJsonFromResponse } from './format';
4
- import { GOOGLE_TRENDS_MAPPER } from '../constants';
5
- import { NetworkError, ParseError, UnknownError, } from '../errors/GoogleTrendsError';
1
+ import { GoogleTrendsEndpoints } from '../types/enums.js';
2
+ import { request } from './request.js';
3
+ import { extractJsonFromResponse } from './format.js';
4
+ import { GOOGLE_TRENDS_MAPPER } from '../constants.js';
5
+ import { InvalidRequestError, NetworkError, ParseError, UnknownError, } from '../errors/GoogleTrendsError.js';
6
6
  export class GoogleTrendsApi {
7
7
  /**
8
8
  * Get autocomplete suggestions for a keyword
@@ -120,24 +120,31 @@ export class GoogleTrendsApi {
120
120
  const text = await response.text();
121
121
  // Check if response is HTML (error page)
122
122
  if (text.includes('<html') || text.includes('<!DOCTYPE')) {
123
- console.error('Explore request returned HTML instead of JSON');
124
- return { widgets: [] };
123
+ return { error: new ParseError('Explore request returned HTML instead of JSON') };
125
124
  }
126
125
  // Try to parse as JSON
127
126
  try {
128
127
  // Remove the first 5 characters (JSONP wrapper) and parse
129
128
  const data = JSON.parse(text.slice(5));
130
- return data;
129
+ // Extract widgets from the response
130
+ if (data && Array.isArray(data) && data.length > 0) {
131
+ const widgets = data[0] || [];
132
+ return { widgets };
133
+ }
134
+ return { widgets: [] };
131
135
  }
132
136
  catch (parseError) {
133
- console.error('Failed to parse explore response as JSON:', parseError instanceof Error ? parseError.message : 'Unknown parse error');
134
- console.error('Response preview:', text.substring(0, 200));
135
- return { widgets: [] };
137
+ if (parseError instanceof Error) {
138
+ return { error: new ParseError(`Failed to parse explore response as JSON: ${parseError.message}`) };
139
+ }
140
+ return { error: new ParseError('Failed to parse explore response as JSON') };
136
141
  }
137
142
  }
138
143
  catch (error) {
139
- console.error('Explore request failed:', error);
140
- return { widgets: [] };
144
+ if (error instanceof Error) {
145
+ return { error: new NetworkError(`Explore request failed: ${error.message}`) };
146
+ }
147
+ return { error: new UnknownError('Explore request failed') };
141
148
  }
142
149
  }
143
150
  //
@@ -169,9 +176,12 @@ export class GoogleTrendsApi {
169
176
  category,
170
177
  hl
171
178
  });
179
+ if ('error' in exploreResponse) {
180
+ return { error: exploreResponse.error };
181
+ }
172
182
  const widget = exploreResponse.widgets.find(w => w.id === 'GEO_MAP');
173
183
  if (!widget) {
174
- return { default: { geoMapData: [] } };
184
+ return { error: new ParseError('No GEO_MAP widget found in explore response') };
175
185
  }
176
186
  const options = {
177
187
  ...GOOGLE_TRENDS_MAPPER[GoogleTrendsEndpoints.interestByRegion],
@@ -213,39 +223,96 @@ export class GoogleTrendsApi {
213
223
  return data;
214
224
  }
215
225
  catch (error) {
216
- return { default: { geoMapData: [] } };
226
+ if (error instanceof Error) {
227
+ return { error: new ParseError(`Failed to parse interest by region response: ${error.message}`) };
228
+ }
229
+ return { error: new ParseError('Failed to parse interest by region response') };
217
230
  }
218
231
  }
219
232
  async relatedTopics({ keyword, geo = 'US', time = 'now 1-d', category = 0, property = '', hl = 'en-US', }) {
220
233
  try {
221
234
  // Validate keyword
222
235
  if (!keyword || keyword.trim() === '') {
223
- return { error: new ParseError() };
236
+ return { error: new InvalidRequestError('Keyword is required') };
224
237
  }
225
- const autocompleteResult = await this.autocomplete(keyword, hl);
226
- if (autocompleteResult.error) {
227
- return { error: autocompleteResult.error };
238
+ // Step 1: Call explore to get widget data and token
239
+ const exploreResponse = await this.explore({
240
+ keyword,
241
+ geo,
242
+ time,
243
+ category,
244
+ property,
245
+ hl
246
+ });
247
+ if ('error' in exploreResponse) {
248
+ return { error: exploreResponse.error };
228
249
  }
229
- const relatedTopics = autocompleteResult.data?.slice(0, 10).map((suggestion, index) => ({
230
- topic: {
231
- mid: `/m/${index}`,
232
- title: suggestion,
233
- type: 'Topic'
234
- },
235
- value: 100 - index * 10,
236
- formattedValue: (100 - index * 10).toString(),
237
- hasData: true,
238
- link: `/trends/explore?q=${encodeURIComponent(suggestion)}&date=${time}&geo=${geo}`
239
- })) || [];
240
- return {
241
- data: {
242
- default: {
243
- rankedList: [{
244
- rankedKeyword: relatedTopics
245
- }]
246
- }
250
+ if (!exploreResponse.widgets || exploreResponse.widgets.length === 0) {
251
+ return { error: new ParseError('No widgets found in explore response. This might be due to Google blocking the request, invalid parameters, or network issues.') };
252
+ }
253
+ // Step 2: Find the related topics widget or use any available widget
254
+ const relatedTopicsWidget = exploreResponse.widgets.find(widget => widget.id === 'RELATED_TOPICS' ||
255
+ widget.request?.restriction?.complexKeywordsRestriction?.keyword?.[0]?.value === keyword) || exploreResponse.widgets[0]; // Fallback to first widget if no specific one found
256
+ if (!relatedTopicsWidget) {
257
+ return { error: new ParseError('No related topics widget found in explore response') };
258
+ }
259
+ // Step 3: Call the related topics API with or without token
260
+ const options = {
261
+ ...GOOGLE_TRENDS_MAPPER[GoogleTrendsEndpoints.relatedTopics],
262
+ qs: {
263
+ hl,
264
+ tz: '240',
265
+ req: JSON.stringify({
266
+ restriction: {
267
+ geo: { country: geo },
268
+ time: time,
269
+ originalTimeRangeForExploreUrl: time,
270
+ complexKeywordsRestriction: {
271
+ keyword: [{
272
+ type: 'BROAD',
273
+ value: keyword
274
+ }]
275
+ }
276
+ },
277
+ keywordType: 'ENTITY',
278
+ metric: ['TOP', 'RISING'],
279
+ trendinessSettings: {
280
+ compareTime: time
281
+ },
282
+ requestOptions: {
283
+ property: property,
284
+ backend: 'CM',
285
+ category: category
286
+ },
287
+ language: hl.split('-')[0],
288
+ userCountryCode: geo,
289
+ userConfig: {
290
+ userType: 'USER_TYPE_LEGIT_USER'
291
+ }
292
+ }),
293
+ ...(relatedTopicsWidget.token && { token: relatedTopicsWidget.token })
247
294
  }
248
295
  };
296
+ const response = await request(options.url, options);
297
+ const text = await response.text();
298
+ // Parse the response
299
+ try {
300
+ const data = JSON.parse(text.slice(5));
301
+ // Return the data in the expected format
302
+ return {
303
+ data: {
304
+ default: {
305
+ rankedList: data.default?.rankedList || []
306
+ }
307
+ }
308
+ };
309
+ }
310
+ catch (parseError) {
311
+ if (parseError instanceof Error) {
312
+ return { error: new ParseError(`Failed to parse related topics response: ${parseError.message}`) };
313
+ }
314
+ return { error: new ParseError('Failed to parse related topics response') };
315
+ }
249
316
  }
250
317
  catch (error) {
251
318
  if (error instanceof Error) {
@@ -1,19 +1,29 @@
1
- export declare const dailyTrends: ({ geo, lang }: import("./types").DailyTrendingTopicsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
2
- export declare const realTimeTrends: ({ geo, trendingHours }: import("./types").RealTimeTrendsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
3
- export declare const autocomplete: (keyword: string, hl?: string) => Promise<import("./types").GoogleTrendsResponse<string[]>>;
4
- export declare const explore: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").ExploreResponse>;
5
- export declare const interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types").InterestByRegionOptions) => Promise<import("./types").InterestByRegionResponse>;
6
- export declare const relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedTopicsResponse>>;
7
- export declare const relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedQueriesResponse>>;
8
- export declare const relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedData>>;
1
+ import { GoogleTrendsApi } from './helpers/googleTrendsAPI.js';
2
+ export declare const dailyTrends: ({ geo, lang }: import("./types/index.js").DailyTrendingTopicsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
3
+ export declare const realTimeTrends: ({ geo, trendingHours }: import("./types/index.js").RealTimeTrendsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
4
+ export declare const autocomplete: (keyword: string, hl?: string) => Promise<import("./types/index.js").GoogleTrendsResponse<string[]>>;
5
+ export declare const explore: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").ExploreResponse | {
6
+ error: import("./types/index.js").GoogleTrendsError;
7
+ }>;
8
+ export declare const interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types/index.js").InterestByRegionOptions) => Promise<import("./types/index.js").InterestByRegionResponse | {
9
+ error: import("./types/index.js").GoogleTrendsError;
10
+ }>;
11
+ export declare const relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedTopicsResponse>>;
12
+ export declare const relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedQueriesResponse>>;
13
+ export declare const relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedData>>;
14
+ export { GoogleTrendsApi };
9
15
  declare const _default: {
10
- dailyTrends: ({ geo, lang }: import("./types").DailyTrendingTopicsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
11
- realTimeTrends: ({ geo, trendingHours }: import("./types").RealTimeTrendsOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").DailyTrendingTopics>>;
12
- autocomplete: (keyword: string, hl?: string) => Promise<import("./types").GoogleTrendsResponse<string[]>>;
13
- explore: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").ExploreResponse>;
14
- interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types").InterestByRegionOptions) => Promise<import("./types").InterestByRegionResponse>;
15
- relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedTopicsResponse>>;
16
- relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedQueriesResponse>>;
17
- relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types").ExploreOptions) => Promise<import("./types").GoogleTrendsResponse<import("./types").RelatedData>>;
16
+ dailyTrends: ({ geo, lang }: import("./types/index.js").DailyTrendingTopicsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
17
+ realTimeTrends: ({ geo, trendingHours }: import("./types/index.js").RealTimeTrendsOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").DailyTrendingTopics>>;
18
+ autocomplete: (keyword: string, hl?: string) => Promise<import("./types/index.js").GoogleTrendsResponse<string[]>>;
19
+ explore: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").ExploreResponse | {
20
+ error: import("./types/index.js").GoogleTrendsError;
21
+ }>;
22
+ interestByRegion: ({ keyword, startTime, endTime, geo, resolution, hl, timezone, category }: import("./types/index.js").InterestByRegionOptions) => Promise<import("./types/index.js").InterestByRegionResponse | {
23
+ error: import("./types/index.js").GoogleTrendsError;
24
+ }>;
25
+ relatedTopics: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedTopicsResponse>>;
26
+ relatedQueries: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedQueriesResponse>>;
27
+ relatedData: ({ keyword, geo, time, category, property, hl, }: import("./types/index.js").ExploreOptions) => Promise<import("./types/index.js").GoogleTrendsResponse<import("./types/index.js").RelatedData>>;
18
28
  };
19
29
  export default _default;
package/dist/esm/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { GoogleTrendsApi } from './helpers/googleTrendsAPI';
1
+ import { GoogleTrendsApi } from './helpers/googleTrendsAPI.js';
2
2
  const api = new GoogleTrendsApi();
3
3
  export const dailyTrends = api.dailyTrends.bind(api);
4
4
  export const realTimeTrends = api.realTimeTrends.bind(api);
@@ -8,6 +8,7 @@ export const interestByRegion = api.interestByRegion.bind(api);
8
8
  export const relatedTopics = api.relatedTopics.bind(api);
9
9
  export const relatedQueries = api.relatedQueries.bind(api);
10
10
  export const relatedData = api.relatedData.bind(api);
11
+ export { GoogleTrendsApi };
11
12
  // Default export for CommonJS compatibility
12
13
  export default {
13
14
  dailyTrends,
@@ -0,0 +1 @@
1
+ {"type":"module"}
package/package.json CHANGED
@@ -1,24 +1,30 @@
1
1
  {
2
2
  "name": "@shaivpidadi/trends-js",
3
- "version": "0.0.0-beta.8",
3
+ "version": "1.0.0",
4
4
  "description": "Google Trends API for Node.js",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
7
- "types": "./dist/types/index.d.ts",
7
+ "types": "./dist/cjs/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "import": "./dist/esm/index.js",
11
- "require": "./dist/cjs/index.js",
12
- "types": "./dist/types/index.d.ts"
10
+ "import": {
11
+ "types": "./dist/esm/index.d.ts",
12
+ "default": "./dist/esm/index.js"
13
+ },
14
+ "require": {
15
+ "types": "./dist/cjs/index.d.ts",
16
+ "default": "./dist/cjs/index.js"
17
+ }
13
18
  }
14
19
  },
15
20
  "files": [
16
21
  "dist"
17
22
  ],
18
23
  "scripts": {
19
- "build": "npm run build:esm && npm run build:cjs",
24
+ "build": "npm run build:esm && npm run build:cjs && npm run build:pkg",
20
25
  "build:esm": "tsc -p tsconfig.json --outDir dist/esm",
21
- "build:cjs": "tsc -p tsconfig.json --outDir dist/cjs --module commonjs",
26
+ "build:cjs": "tsc -p tsconfig.json --outDir dist/cjs --module commonjs --moduleResolution node",
27
+ "build:pkg": "echo '{\"type\":\"module\"}' > dist/esm/package.json && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
22
28
  "test": "jest",
23
29
  "prepare": "npm run build"
24
30
  },