@shaivpidadi/trends-js 0.0.0-beta.7 → 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
 
@@ -17,6 +20,9 @@ npm install @shaivpidadi/trends-js
17
20
  - Get autocomplete suggestions
18
21
  - Explore trends data
19
22
  - Get interest by region data
23
+ - Get related topics for any keyword
24
+ - Get related queries for any keyword
25
+ - Get combined related data (topics + queries)
20
26
  - TypeScript support
21
27
  - Promise-based API
22
28
 
@@ -33,9 +39,9 @@ import GoogleTrendsApi from '@shaivpidadi/trends-js';
33
39
  Get daily trending topics for a specific region:
34
40
 
35
41
  ```typescript
36
- const result = await GoogleTrendsApi.dailyTrends({
37
- geo: 'US', // Default: 'US'
38
- lang: 'en' // Default: 'en'
42
+ const result = await GoogleTrendsApi.dailyTrends({
43
+ geo: 'US', // Default: 'US'
44
+ lang: 'en', // Default: 'en'
39
45
  });
40
46
 
41
47
  // Result structure:
@@ -50,9 +56,9 @@ const result = await GoogleTrendsApi.dailyTrends({
50
56
  Get real-time trending topics:
51
57
 
52
58
  ```typescript
53
- const result = await GoogleTrendsApi.realTimeTrends({
54
- geo: 'US', // Default: 'US'
55
- trendingHours: 4 // Default: 4
59
+ const result = await GoogleTrendsApi.realTimeTrends({
60
+ geo: 'US', // Default: 'US'
61
+ trendingHours: 4, // Default: 4
56
62
  });
57
63
 
58
64
  // Result structure:
@@ -68,8 +74,8 @@ Get search suggestions for a keyword:
68
74
 
69
75
  ```typescript
70
76
  const suggestions = await GoogleTrendsApi.autocomplete(
71
- 'bitcoin', // Keyword to get suggestions for
72
- 'en-US' // Language (default: 'en-US')
77
+ 'bitcoin', // Keyword to get suggestions for
78
+ 'en-US', // Language (default: 'en-US')
73
79
  );
74
80
 
75
81
  // Returns: string[]
@@ -80,13 +86,13 @@ const suggestions = await GoogleTrendsApi.autocomplete(
80
86
  Get widget data for a keyword:
81
87
 
82
88
  ```typescript
83
- const result = await GoogleTrendsApi.explore({
89
+ const result = await GoogleTrendsApi.explore({
84
90
  keyword: 'bitcoin',
85
- geo: 'US', // Default: 'US'
86
- time: 'today 12-m', // Default: 'today 12-m'
87
- category: 0, // Default: 0
88
- property: '', // Default: ''
89
- hl: 'en-US' // Default: 'en-US'
91
+ geo: 'US', // Default: 'US'
92
+ time: 'today 12-m', // Default: 'today 12-m'
93
+ category: 0, // Default: 0
94
+ property: '', // Default: ''
95
+ hl: 'en-US', // Default: 'en-US'
90
96
  });
91
97
 
92
98
  // Result structure:
@@ -104,15 +110,15 @@ const result = await GoogleTrendsApi.explore({
104
110
  Get interest data by region:
105
111
 
106
112
  ```typescript
107
- const result = await GoogleTrendsApi.interestByRegion({
108
- keyword: 'Stock Market', // Required - string or string[]
113
+ const result = await GoogleTrendsApi.interestByRegion({
114
+ keyword: 'Stock Market', // Required - string or string[]
109
115
  startTime: new Date('2024-01-01'), // Optional - defaults to 2004-01-01
110
- endTime: new Date(), // Optional - defaults to current date
111
- geo: 'US', // Optional - string or string[] - defaults to 'US'
112
- resolution: 'REGION', // Optional - 'COUNTRY' | 'REGION' | 'CITY' | 'DMA'
113
- hl: 'en-US', // Optional - defaults to 'en-US'
114
- timezone: -240, // Optional - defaults to local timezone
115
- category: 0 // Optional - defaults to 0
116
+ endTime: new Date(), // Optional - defaults to current date
117
+ geo: 'US', // Optional - string or string[] - defaults to 'US'
118
+ resolution: 'REGION', // Optional - 'COUNTRY' | 'REGION' | 'CITY' | 'DMA'
119
+ hl: 'en-US', // Optional - defaults to 'en-US'
120
+ timezone: -240, // Optional - defaults to local timezone
121
+ category: 0, // Optional - defaults to 0
116
122
  });
117
123
 
118
124
  // Result structure:
@@ -137,13 +143,104 @@ const result = await GoogleTrendsApi.interestByRegion({
137
143
  Example with multiple keywords and regions:
138
144
 
139
145
  ```typescript
140
- const result = await GoogleTrendsApi.interestByRegion({
146
+ const result = await GoogleTrendsApi.interestByRegion({
141
147
  keyword: ['wine', 'peanuts'],
142
148
  geo: ['US-CA', 'US-VA'],
143
149
  startTime: new Date('2024-01-01'),
144
150
  endTime: new Date(),
145
- resolution: 'CITY'
151
+ resolution: 'CITY',
152
+ });
153
+ ```
154
+
155
+ ### Related Topics
156
+
157
+ Get related topics for any keyword:
158
+
159
+ ```typescript
160
+ const result = await GoogleTrendsApi.relatedTopics({
161
+ keyword: 'artificial intelligence', // Required
162
+ geo: 'US', // Optional - defaults to 'US'
163
+ time: 'now 1-d', // Optional - defaults to 'now 1-d'
164
+ category: 0, // Optional - defaults to 0
165
+ property: '', // Optional - defaults to ''
166
+ hl: 'en-US', // Optional - defaults to 'en-US'
167
+ });
168
+
169
+ // Result structure:
170
+ // {
171
+ // data: {
172
+ // default: {
173
+ // rankedList: Array<{
174
+ // rankedKeyword: Array<{
175
+ // topic: {
176
+ // mid: string,
177
+ // title: string,
178
+ // type: string
179
+ // },
180
+ // value: number,
181
+ // formattedValue: string,
182
+ // hasData: boolean,
183
+ // link: string
184
+ // }>
185
+ // }>
186
+ // }
187
+ // }
188
+ // }
189
+ ```
190
+
191
+ ### Related Queries
192
+
193
+ Get related queries for any keyword:
194
+
195
+ ```typescript
196
+ const result = await GoogleTrendsApi.relatedQueries({
197
+ keyword: 'machine learning', // Required
198
+ geo: 'US', // Optional - defaults to 'US'
199
+ time: 'now 1-d', // Optional - defaults to 'now 1-d'
200
+ category: 0, // Optional - defaults to 0
201
+ property: '', // Optional - defaults to ''
202
+ hl: 'en-US', // Optional - defaults to 'en-US'
203
+ });
204
+
205
+ // Result structure:
206
+ // {
207
+ // data: {
208
+ // default: {
209
+ // rankedList: Array<{
210
+ // rankedKeyword: Array<{
211
+ // query: string,
212
+ // value: number,
213
+ // formattedValue: string,
214
+ // hasData: boolean,
215
+ // link: string
216
+ // }>
217
+ // }>
218
+ // }
219
+ // }
220
+ // }
221
+ ```
222
+
223
+ ### Combined Related Data
224
+
225
+ Get both related topics and queries in a single call:
226
+
227
+ ```typescript
228
+ const result = await GoogleTrendsApi.relatedData({
229
+ keyword: 'blockchain', // Required
230
+ geo: 'US', // Optional - defaults to 'US'
231
+ time: 'now 1-d', // Optional - defaults to 'now 1-d'
232
+ category: 0, // Optional - defaults to 0
233
+ property: '', // Optional - defaults to ''
234
+ hl: 'en-US', // Optional - defaults to 'en-US'
146
235
  });
236
+
237
+ // Result structure:
238
+ // {
239
+ // data: {
240
+ // topics: Array<RelatedTopic>,
241
+ // queries: Array<RelatedQuery>
242
+ // }
243
+ // }
147
244
  ```
148
245
 
149
246
  ## API Reference
@@ -152,7 +249,7 @@ const result = await GoogleTrendsApi.interestByRegion({
152
249
 
153
250
  ```typescript
154
251
  interface DailyTrendsOptions {
155
- geo?: string; // Default: 'US'
252
+ geo?: string; // Default: 'US'
156
253
  lang?: string; // Default: 'en'
157
254
  }
158
255
  ```
@@ -171,11 +268,11 @@ interface RealTimeTrendsOptions {
171
268
  ```typescript
172
269
  interface ExploreOptions {
173
270
  keyword: string;
174
- geo?: string; // Default: 'US'
175
- time?: string; // Default: 'today 12-m'
176
- category?: number; // Default: 0
177
- property?: string; // Default: ''
178
- hl?: string; // Default: 'en-US'
271
+ geo?: string; // Default: 'US'
272
+ time?: string; // Default: 'today 12-m'
273
+ category?: number; // Default: 0
274
+ property?: string; // Default: ''
275
+ hl?: string; // Default: 'en-US'
179
276
  }
180
277
  ```
181
278
 
@@ -183,14 +280,63 @@ interface ExploreOptions {
183
280
 
184
281
  ```typescript
185
282
  interface InterestByRegionOptions {
186
- keyword: string | string[]; // Required - search term(s)
187
- startTime?: Date; // Optional - start date
188
- endTime?: Date; // Optional - end date
189
- geo?: string | string[]; // Optional - geocode(s)
283
+ keyword: string | string[]; // Required - search term(s)
284
+ startTime?: Date; // Optional - start date
285
+ endTime?: Date; // Optional - end date
286
+ geo?: string | string[]; // Optional - geocode(s)
190
287
  resolution?: 'COUNTRY' | 'REGION' | 'CITY' | 'DMA'; // Optional
191
- hl?: string; // Optional - language code
192
- timezone?: number; // Optional - timezone offset
193
- category?: number; // Optional - category number
288
+ hl?: string; // Optional - language code
289
+ timezone?: number; // Optional - timezone offset
290
+ category?: number; // Optional - category number
291
+ }
292
+ ```
293
+
294
+ ### RelatedTopicsResponse
295
+
296
+ ```typescript
297
+ interface RelatedTopicsResponse {
298
+ default: {
299
+ rankedList: Array<{
300
+ rankedKeyword: Array<{
301
+ topic: {
302
+ mid: string;
303
+ title: string;
304
+ type: string;
305
+ };
306
+ value: number;
307
+ formattedValue: string;
308
+ hasData: boolean;
309
+ link: string;
310
+ }>;
311
+ }>;
312
+ };
313
+ }
314
+ ```
315
+
316
+ ### RelatedQueriesResponse
317
+
318
+ ```typescript
319
+ interface RelatedQueriesResponse {
320
+ default: {
321
+ rankedList: Array<{
322
+ rankedKeyword: Array<{
323
+ query: string;
324
+ value: number;
325
+ formattedValue: string;
326
+ hasData: boolean;
327
+ link: string;
328
+ }>;
329
+ }>;
330
+ };
331
+ }
332
+ ```
333
+
334
+ ### RelatedData
335
+
336
+ ```typescript
337
+ interface RelatedData {
338
+ topics: Array<RelatedTopic>;
339
+ queries: Array<RelatedQuery>;
194
340
  }
195
341
  ```
196
342
 
@@ -198,4 +344,6 @@ interface InterestByRegionOptions {
198
344
 
199
345
  ### Building
200
346
 
201
- ```
347
+ ```
348
+
349
+ ```
@@ -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,18 +22,32 @@ 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_js_1.GoogleTrendsEndpoints.relatedTopics]: {
40
+ path: '/trends/api/widgetdata/relatedtopics',
41
+ method: 'GET',
42
+ host: GOOGLE_TRENDS_BASE_URL,
43
+ url: `https://${GOOGLE_TRENDS_BASE_URL}/trends/api/widgetdata/relatedtopics`,
44
+ headers: {},
45
+ },
46
+ [enums_js_1.GoogleTrendsEndpoints.relatedQueries]: {
47
+ path: '/trends/api/widgetdata/relatedqueries',
48
+ method: 'GET',
49
+ host: GOOGLE_TRENDS_BASE_URL,
50
+ url: `https://${GOOGLE_TRENDS_BASE_URL}/trends/api/widgetdata/relatedqueries`,
51
+ headers: {},
52
+ },
39
53
  };
@@ -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 } 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,15 @@ 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
+ }>;
28
+ relatedTopics({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedTopicsResponse>>;
29
+ relatedQueries({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedQueriesResponse>>;
30
+ relatedData({ keyword, geo, time, category, property, hl, }: ExploreOptions): Promise<GoogleTrendsResponse<RelatedData>>;
24
31
  }
25
32
  declare const _default: GoogleTrendsApi;
26
33
  export default _default;