get-reading-time 1.0.4 → 1.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Md Nur Ahmad
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,36 +1,29 @@
1
-
2
1
  # Text Analysis Tool
3
2
 
4
3
  A simple text analysis tool that provides insights into text such as reading time, word count, sentiment, readability score, link count, and SEO-friendly keywords.
5
4
 
6
5
  ## Features
7
6
 
8
- - **Reading Time**: Estimates how long it will take to read the given text based on a default or custom reading speed (words per minute).
9
-
10
- - **Word Count**: Counts the number of words in the text.
11
-
12
- - **Character Count**: Counts the number of characters (excluding spaces) in the text.
13
-
14
- - **Sentence Count**: Counts the number of sentences based on punctuation marks.
15
-
16
- - **Link Count**: Detects and counts the number of URLs in the text.
17
-
18
- - **Readability Score**: Calculates the Flesch Reading Ease score to evaluate the text's readability.
19
-
20
- - **Sentiment Analysis**: Analyzes the sentiment of the text (Positive, Negative, or Neutral).
21
-
22
- - **SEO-friendly Keywords**: Extracts the top 5 SEO-friendly keywords or key phrases (bi-grams and tri-grams) from the text.
23
-
7
+ - **Reading Time**: Estimates how long it will take to read the given text based on a default or custom reading speed (words per minute).
8
+ - **Word Count**: Counts the number of words in the text.
9
+ - **Character Count**: Counts the number of characters (excluding spaces) in the text.
10
+ - **Sentence Count**: Counts the number of sentences based on punctuation marks.
11
+ - **Link Count**: Detects and counts the number of URLs in the text.
12
+ - **Readability Score**: Calculates the Flesch Reading Ease score to evaluate the text's readability.
13
+ - **Sentiment Analysis**: Analyzes the sentiment of the text (Positive, Negative, or Neutral).
14
+ - **SEO-friendly Keywords**: Extracts the top 5 SEO-friendly keywords or key phrases (bi-grams and tri-grams) from the text.
15
+ - **aiTexGen**: Allows users to generate content based on a search prompt using the Cohere AI API, with a specified word count.
24
16
 
25
17
  ## Installation
26
18
 
27
19
  To install the package from npm, run:
28
- ``` bash
20
+
21
+ ```bash
29
22
  npm i get-reading-time
30
23
  ```
31
24
 
32
-
33
25
  Or using yarn:
26
+
34
27
  ```bash
35
28
  yarn add get-reading-time
36
29
  ```
@@ -38,54 +31,106 @@ yarn add get-reading-time
38
31
  ## Usage
39
32
 
40
33
  Here’s how you can use the analyzeText function to analyze a piece of text:
34
+
41
35
  ```bash
42
36
  import { analyzeText } from "get-reading-time/dist/index.js";
43
37
  ```
44
- // Example input text
38
+
39
+ ### Example Code
40
+
45
41
  ```javascript
46
- const text = "This is an example of text. It contains words, sentences, and links like https://example.com.";
42
+ const text = `This is an example of text. It contains words, sentences, and links like there are https://linkedin.com/in/06nurahmed https://github.com/nurahmed123`;
47
43
 
48
- const result = analyzeText(text);
44
+ const result = analyzeText(text);
49
45
 
50
46
  // Analyze the text
51
47
  try {
52
- const result = analyzeText(text);
48
+ const result = analyzeText(text);
53
49
 
54
- // Output the analysis results
55
- console.log("Text Analysis Result:");
56
- console.log(JSON.stringify(result, null, 2));
50
+ // Output the analysis results
51
+ console.log("Text Analysis Result:");
52
+ console.log(JSON.stringify(result, null, 2));
57
53
  } catch (error) {
58
- // Narrow the type of error to Error
59
- if (error instanceof Error) {
60
- console.error("Error analyzing text:", error.message);
61
- } else {
62
- console.error("Unknown error:", error);
63
- }
54
+ // Narrow the type of error to Error
55
+ if (error instanceof Error) {
56
+ console.error("Error analyzing text:", error.message);
57
+ } else {
58
+ console.error("Unknown error:", error);
59
+ }
64
60
  }
61
+ ```
62
+
63
+ ### Example Output
65
64
 
65
+ ```json
66
+ {
67
+ "readingTime": {
68
+ "minutes": 0.09,
69
+ "seconds": 5.1
70
+ },
71
+ "wordCount": 17,
72
+ "characterCount": 132,
73
+ "sentenceCount": 3,
74
+ "linkCount": 2,
75
+ "links": [
76
+ "https://linkedin.com/in/06nurahmed",
77
+ "https://github.com/nurahmed123"
78
+ ],
79
+ "readabilityScore": 21.93039215686275,
80
+ "sentiment": "Neutral",
81
+ "keywords": ["example", "text.", "contains", "words,", "sentences,"]
82
+ }
83
+ ```
84
+
85
+ ### aiTexGen: Generate your content
86
+ This new feature allows users to generate content using Cohere AI. You provide your Cohere API key, a search prompt, and a word count, and it will return the generated content.
87
+
88
+ ### Usage
89
+ To use the **aiTexGen** feature, follow these steps:
90
+ ```bash
91
+ import { aiTexGen } from "get-reading-time/dist/index.js";
92
+ ```
93
+
94
+ ### Example Code
95
+ - Create your [Api key](https://dashboard.cohere.com/api-keys) From here.
96
+ ```javascript
97
+ // Replace this with your Cohere API key
98
+ const apiKey = '<api-key>';
99
+ const generator = new aiTexGen(apiKey);
100
+
101
+ async function testGenerateContent() {
102
+ try {
103
+ // Define a topic and word count for testing
104
+ const topic = 'arduino';
105
+ const wordCount = 100;
106
+
107
+ // Call the generateContent method
108
+ const result = await generator.generateContent(topic, wordCount);
109
+
110
+ // Output the result in JSON format
111
+ console.log('Generated Content (JSON Format):');
112
+ console.log(JSON.stringify(result, null, 2)); // Pretty print the JSON output
113
+
114
+ } catch (error) {
115
+ console.error('Error during content generation:', error);
116
+ }
117
+ }
118
+ // Run the test
119
+ testGenerateContent();
66
120
  ```
67
121
  ### Example Output
68
122
  ```json
69
123
  {
70
- "readingTime": {
71
- "minutes": 0.05,
72
- "seconds": 5.23
73
- },
74
- "wordCount": 13,
75
- "characterCount": 68,
76
- "sentenceCount": 2,
77
- "linkCount": 1,
78
- "readabilityScore": 78.5,
79
- "sentiment": "Positive",
80
- "keywords": ["example", "text", "words", "sentences", "links"]
124
+ "topic": "arduino",
125
+ "content": "Arduino is an open-source electronics platform based on easy-to-use hardware and software. It's designed to make interactive projects accessible to everyone, from artists and designers to hobbyists and engineers. \n\nAt the heart of the Arduino platform is the Arduino board, a simple microcontroller board that can read inputs and turn them into outputs, such as turning on an LED light or activating a motor. \n\nWhat makes Arduino unique is its user-friendly approach, with a simplified programming language and easy-to-use hardware, making it a popular choice for beginners and professionals alike. With its versatility and robust community support, Arduino has become a go-to platform for creating interactive, sensor-based projects and prototypes."
81
126
  }
82
127
  ```
128
+
83
129
  ## Parameters
84
130
 
85
- - text: The text to be analyzed (required).
86
-
87
- - wordsPerMinute: The reading speed in words per minute (optional, default is 200 words per minute).
88
-
131
+ - text: The text to be analyzed (required).
132
+ - wordsPerMinute: The reading speed in words per minute (optional, default is 200 words per minute).
133
+ - **apiKey**: Your Cohere API key to use this feature (required).
89
134
 
90
135
  ## Functions
91
136
 
@@ -93,45 +138,30 @@ try {
93
138
 
94
139
  Analyzes the provided text and returns an object containing:
95
140
 
96
- - readingTime: Estimated reading time in minutes and seconds.
97
-
98
- - wordCount: Total word count.
99
-
100
- - characterCount: Total character count (excluding spaces).
101
-
102
- - sentenceCount: Total sentence count.
103
-
104
- - linkCount: Number of links (URLs) in the text.
105
-
106
- - readabilityScore: Flesch Reading Ease score (higher is easier to read).
107
-
108
- - sentiment: Sentiment of the text (Positive, Negative, or Neutral).
109
-
110
- - keywords: Top 5 SEO-friendly keywords or key phrases.
111
-
141
+ - readingTime: Estimated reading time in minutes and seconds.
142
+ - wordCount: Total word count.
143
+ - characterCount: Total character count (excluding spaces).
144
+ - sentenceCount: Total sentence count.
145
+ - linkCount: Number of links (URLs) in the text.
146
+ - readabilityScore: Flesch Reading Ease score (higher is easier to read).
147
+ - sentiment: Sentiment of the text (Positive, Negative, or Neutral).
148
+ - keywords: Top 5 SEO-friendly keywords or key phrases.
149
+ ### Generate Content(topic: string, wordCount: number)
150
+ Generates content based on the given topic and word count using the Cohere AI API and returns the generated content.
112
151
 
113
152
  ### Helper Functions
114
153
 
115
- - **cleanTextInput(text: string)**: Cleans and normalizes the input text.
116
-
117
- - **calculateWordCount(text: string)**: Counts the number of words.
118
-
119
- - **calculateCharacterCount(text: string)**: Counts the number of characters (excluding spaces).
120
-
121
- - **calculateSentenceCount(text: string)**: Counts the number of sentences based on punctuation.
122
-
123
- - **countLinks(text: string)**: Counts the number of links (URLs) in the text.
124
-
125
- - **calculateReadabilityScore(text: string)**: Calculates the Flesch Reading Ease score.
126
-
127
- - **analyzeSentiment(text: string)**: Analyzes sentiment using Sentiment.js.
128
-
129
- - **extractKeywords(text: string)**: Extracts the top 5 SEO-friendly keywords or key phrases.
130
-
131
- - **extractNGrams(words: string[])**: Extracts bi-grams and tri-grams from the list of words.
132
-
133
- - **isStopWord(word: string, stopWords: Set<string>)**: Checks if a word is a stop word to exclude from keyword extraction.
134
-
154
+ - **cleanTextInput(text: string)**: Cleans and normalizes the input text.
155
+ - **calculateWordCount(text: string)**: Counts the number of words.
156
+ - **calculateCharacterCount(text: string)**: Counts the number of characters (excluding spaces).
157
+ - **calculateSentenceCount(text: string)**: Counts the number of sentences based on punctuation.
158
+ - **countLinks(text: string)**: Counts the number of links (URLs) in the text.
159
+ - **calculateReadabilityScore(text: string)**: Calculates the Flesch Reading Ease score.
160
+ - **analyzeSentiment(text: string)**: Analyzes sentiment using Sentiment.js.
161
+ - **extractKeywords(text: string)**: Extracts the top 5 SEO-friendly keywords or key phrases.
162
+ - **extractNGrams(words: string[])**: Extracts bi-grams and tri-grams from the list of words.
163
+ - **isStopWord(word: string, stopWords: Set<string>)**: Checks if a word is a stop word to exclude from keyword extraction.
164
+ - **generateContent(words: string[])**: Genarate text based on the query and word limit.
135
165
 
136
166
  ## Contributing
137
167
 
@@ -139,8 +169,9 @@ Feel free to fork the repository, make your changes, and submit a pull request.
139
169
 
140
170
  ## License
141
171
 
142
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
172
+ This project is licensed under the MIT License - see the [LICENSE](https://github.com/nurahmed123/get-reading-time/blob/main/LICENSE) file for details.
173
+ [![npm version](https://badge.fury.io/js/get-reading-time.svg)](https://www.npmjs.com/get-reading-time)
143
174
 
144
175
  ## Contact
145
176
 
146
- For any questions or inquiries, feel free to contact [[06nurahmed@gmail.com](06nurahmed@gmail.com)].
177
+ For any questions or inquiries, feel free to contact [[06nurahmed@gmail.com](06nurahmed@gmail.com)].
package/dist/index.d.mts CHANGED
@@ -14,4 +14,31 @@ interface TextAnalysisResult {
14
14
  }
15
15
  declare function analyzeText(text: string, wordsPerMinute?: number): TextAnalysisResult;
16
16
 
17
- export { analyzeText };
17
+ /**
18
+ * Formats an article by correcting punctuation and capitalization,
19
+ * intelligently inferring sentence boundaries and adding missing punctuation.
20
+ *
21
+ * @param {string} article - The raw input string to be formatted.
22
+ * @returns {{ original: string, formatted: string }} - A JSON object with the original and formatted strings.
23
+ * @throws {TypeError} If the input is not a valid non-empty string.
24
+ */
25
+ declare const getPunch: (article: string) => {
26
+ original: string;
27
+ formatted: string;
28
+ };
29
+
30
+ declare class AiTexGen {
31
+ private cohereClient;
32
+ constructor(apiKey: string);
33
+ private validateInputs;
34
+ generateContent(topic: string, wordCount?: number): Promise<{
35
+ topic: string;
36
+ content: string;
37
+ }>;
38
+ private processContent;
39
+ private extractTextFromObject;
40
+ private createErrorResponse;
41
+ private formatErrorDetails;
42
+ }
43
+
44
+ export { AiTexGen as aiTexGen, analyzeText, getPunch };
package/dist/index.d.ts CHANGED
@@ -14,4 +14,31 @@ interface TextAnalysisResult {
14
14
  }
15
15
  declare function analyzeText(text: string, wordsPerMinute?: number): TextAnalysisResult;
16
16
 
17
- export { analyzeText };
17
+ /**
18
+ * Formats an article by correcting punctuation and capitalization,
19
+ * intelligently inferring sentence boundaries and adding missing punctuation.
20
+ *
21
+ * @param {string} article - The raw input string to be formatted.
22
+ * @returns {{ original: string, formatted: string }} - A JSON object with the original and formatted strings.
23
+ * @throws {TypeError} If the input is not a valid non-empty string.
24
+ */
25
+ declare const getPunch: (article: string) => {
26
+ original: string;
27
+ formatted: string;
28
+ };
29
+
30
+ declare class AiTexGen {
31
+ private cohereClient;
32
+ constructor(apiKey: string);
33
+ private validateInputs;
34
+ generateContent(topic: string, wordCount?: number): Promise<{
35
+ topic: string;
36
+ content: string;
37
+ }>;
38
+ private processContent;
39
+ private extractTextFromObject;
40
+ private createErrorResponse;
41
+ private formatErrorDetails;
42
+ }
43
+
44
+ export { AiTexGen as aiTexGen, analyzeText, getPunch };
package/dist/index.js CHANGED
@@ -26,13 +26,37 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __async = (__this, __arguments, generator) => {
30
+ return new Promise((resolve, reject) => {
31
+ var fulfilled = (value) => {
32
+ try {
33
+ step(generator.next(value));
34
+ } catch (e) {
35
+ reject(e);
36
+ }
37
+ };
38
+ var rejected = (value) => {
39
+ try {
40
+ step(generator.throw(value));
41
+ } catch (e) {
42
+ reject(e);
43
+ }
44
+ };
45
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
46
+ step((generator = generator.apply(__this, __arguments)).next());
47
+ });
48
+ };
29
49
 
30
50
  // src/index.ts
31
51
  var index_exports = {};
32
52
  __export(index_exports, {
33
- analyzeText: () => analyzeText
53
+ aiTexGen: () => AiTexGen,
54
+ analyzeText: () => analyzeText,
55
+ getPunch: () => getPunch
34
56
  });
35
57
  module.exports = __toCommonJS(index_exports);
58
+
59
+ // src/utils/analyzeText.ts
36
60
  var import_sentiment = __toESM(require("sentiment"));
37
61
  var DEFAULT_READING_SPEED = 200;
38
62
  function analyzeText(text, wordsPerMinute = DEFAULT_READING_SPEED) {
@@ -160,7 +184,117 @@ function extractNGrams(words) {
160
184
  function isStopWord(word, stopWords) {
161
185
  return stopWords.has(word);
162
186
  }
187
+
188
+ // src/utils/getPunch.ts
189
+ var import_compromise = __toESM(require("compromise"));
190
+ var getPunch = (article) => {
191
+ if (typeof article !== "string" || article.trim().length === 0) {
192
+ throw new TypeError("Invalid input: article must be a non-empty string.");
193
+ }
194
+ try {
195
+ const doc = (0, import_compromise.default)(article);
196
+ const formatted = doc.sentences().normalize().out("text");
197
+ return {
198
+ original: article.trim(),
199
+ formatted
200
+ };
201
+ } catch (error) {
202
+ throw new Error(`Error processing the article: ${error instanceof Error ? error.message : "Unknown error"}`);
203
+ }
204
+ };
205
+
206
+ // src/utils/aiTexGen.ts
207
+ var import_cohere_ai = require("cohere-ai");
208
+ var AiTexGen = class {
209
+ constructor(apiKey) {
210
+ if (!apiKey || typeof apiKey !== "string") {
211
+ throw this.createErrorResponse("API_KEY_MISSING", "A valid API key must be provided.", 400);
212
+ }
213
+ this.cohereClient = new import_cohere_ai.CohereClientV2({ token: apiKey });
214
+ }
215
+ // Validate user input (topic and word count)
216
+ validateInputs(topic, wordCount) {
217
+ if (typeof topic !== "string" || topic.trim().length === 0) {
218
+ throw this.createErrorResponse("INVALID_TOPIC", "Topic must be a non-empty string.", 400);
219
+ }
220
+ if (typeof wordCount !== "number" || wordCount <= 0) {
221
+ console.warn("Invalid word count provided. Defaulting to 100 words.");
222
+ wordCount = 100;
223
+ }
224
+ }
225
+ // Generate content using Cohere's API
226
+ generateContent(topic, wordCount = 100) {
227
+ return __async(this, null, function* () {
228
+ var _a;
229
+ try {
230
+ this.validateInputs(topic, wordCount);
231
+ const prompt = `Write a detailed article about ${topic}, aiming for maximum ${wordCount} words.`;
232
+ const response = yield this.cohereClient.chat({
233
+ model: "command-r-plus",
234
+ // Specify the model you want to use
235
+ messages: [
236
+ {
237
+ role: "user",
238
+ content: prompt
239
+ // Use the prompt with the topic and word count
240
+ }
241
+ ]
242
+ });
243
+ const content = this.processContent((_a = response.message) == null ? void 0 : _a.content);
244
+ return {
245
+ topic,
246
+ content
247
+ };
248
+ } catch (error) {
249
+ console.error("Error generating content from Cohere API:", error);
250
+ throw this.createErrorResponse("API_ERROR", "Failed to generate content from Cohere API.", 500, this.formatErrorDetails(error));
251
+ }
252
+ });
253
+ }
254
+ // Helper method to process the content and format it properly
255
+ processContent(content) {
256
+ if (!content || content.length === 0) {
257
+ return "No content generated or content is empty.";
258
+ }
259
+ return content.map((item) => {
260
+ if (typeof item === "string") {
261
+ return item.trim();
262
+ } else if (typeof item === "object") {
263
+ return this.extractTextFromObject(item);
264
+ }
265
+ return "";
266
+ }).join(" ").trim();
267
+ }
268
+ // Helper method to safely extract text from an object, if needed
269
+ extractTextFromObject(obj) {
270
+ if (obj && obj.text) {
271
+ return obj.text.trim();
272
+ }
273
+ return "";
274
+ }
275
+ // Helper method to create an error response with a status code
276
+ createErrorResponse(code, message, statusCode, details) {
277
+ return {
278
+ error: {
279
+ code,
280
+ message,
281
+ statusCode,
282
+ details: details || ""
283
+ }
284
+ };
285
+ }
286
+ // Helper method to format error details (narrowing down the 'unknown' type)
287
+ formatErrorDetails(error) {
288
+ if (error instanceof Error) {
289
+ return error.message;
290
+ } else {
291
+ return "An unknown error occurred.";
292
+ }
293
+ }
294
+ };
163
295
  // Annotate the CommonJS export names for ESM import in node:
164
296
  0 && (module.exports = {
165
- analyzeText
297
+ aiTexGen,
298
+ analyzeText,
299
+ getPunch
166
300
  });
package/dist/index.mjs CHANGED
@@ -1,4 +1,25 @@
1
- // src/index.ts
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+
22
+ // src/utils/analyzeText.ts
2
23
  import Sentiment from "sentiment";
3
24
  var DEFAULT_READING_SPEED = 200;
4
25
  function analyzeText(text, wordsPerMinute = DEFAULT_READING_SPEED) {
@@ -126,6 +147,116 @@ function extractNGrams(words) {
126
147
  function isStopWord(word, stopWords) {
127
148
  return stopWords.has(word);
128
149
  }
150
+
151
+ // src/utils/getPunch.ts
152
+ import nlp from "compromise";
153
+ var getPunch = (article) => {
154
+ if (typeof article !== "string" || article.trim().length === 0) {
155
+ throw new TypeError("Invalid input: article must be a non-empty string.");
156
+ }
157
+ try {
158
+ const doc = nlp(article);
159
+ const formatted = doc.sentences().normalize().out("text");
160
+ return {
161
+ original: article.trim(),
162
+ formatted
163
+ };
164
+ } catch (error) {
165
+ throw new Error(`Error processing the article: ${error instanceof Error ? error.message : "Unknown error"}`);
166
+ }
167
+ };
168
+
169
+ // src/utils/aiTexGen.ts
170
+ import { CohereClientV2 } from "cohere-ai";
171
+ var AiTexGen = class {
172
+ constructor(apiKey) {
173
+ if (!apiKey || typeof apiKey !== "string") {
174
+ throw this.createErrorResponse("API_KEY_MISSING", "A valid API key must be provided.", 400);
175
+ }
176
+ this.cohereClient = new CohereClientV2({ token: apiKey });
177
+ }
178
+ // Validate user input (topic and word count)
179
+ validateInputs(topic, wordCount) {
180
+ if (typeof topic !== "string" || topic.trim().length === 0) {
181
+ throw this.createErrorResponse("INVALID_TOPIC", "Topic must be a non-empty string.", 400);
182
+ }
183
+ if (typeof wordCount !== "number" || wordCount <= 0) {
184
+ console.warn("Invalid word count provided. Defaulting to 100 words.");
185
+ wordCount = 100;
186
+ }
187
+ }
188
+ // Generate content using Cohere's API
189
+ generateContent(topic, wordCount = 100) {
190
+ return __async(this, null, function* () {
191
+ var _a;
192
+ try {
193
+ this.validateInputs(topic, wordCount);
194
+ const prompt = `Write a detailed article about ${topic}, aiming for maximum ${wordCount} words.`;
195
+ const response = yield this.cohereClient.chat({
196
+ model: "command-r-plus",
197
+ // Specify the model you want to use
198
+ messages: [
199
+ {
200
+ role: "user",
201
+ content: prompt
202
+ // Use the prompt with the topic and word count
203
+ }
204
+ ]
205
+ });
206
+ const content = this.processContent((_a = response.message) == null ? void 0 : _a.content);
207
+ return {
208
+ topic,
209
+ content
210
+ };
211
+ } catch (error) {
212
+ console.error("Error generating content from Cohere API:", error);
213
+ throw this.createErrorResponse("API_ERROR", "Failed to generate content from Cohere API.", 500, this.formatErrorDetails(error));
214
+ }
215
+ });
216
+ }
217
+ // Helper method to process the content and format it properly
218
+ processContent(content) {
219
+ if (!content || content.length === 0) {
220
+ return "No content generated or content is empty.";
221
+ }
222
+ return content.map((item) => {
223
+ if (typeof item === "string") {
224
+ return item.trim();
225
+ } else if (typeof item === "object") {
226
+ return this.extractTextFromObject(item);
227
+ }
228
+ return "";
229
+ }).join(" ").trim();
230
+ }
231
+ // Helper method to safely extract text from an object, if needed
232
+ extractTextFromObject(obj) {
233
+ if (obj && obj.text) {
234
+ return obj.text.trim();
235
+ }
236
+ return "";
237
+ }
238
+ // Helper method to create an error response with a status code
239
+ createErrorResponse(code, message, statusCode, details) {
240
+ return {
241
+ error: {
242
+ code,
243
+ message,
244
+ statusCode,
245
+ details: details || ""
246
+ }
247
+ };
248
+ }
249
+ // Helper method to format error details (narrowing down the 'unknown' type)
250
+ formatErrorDetails(error) {
251
+ if (error instanceof Error) {
252
+ return error.message;
253
+ } else {
254
+ return "An unknown error occurred.";
255
+ }
256
+ }
257
+ };
129
258
  export {
130
- analyzeText
259
+ AiTexGen as aiTexGen,
260
+ analyzeText,
261
+ getPunch
131
262
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "get-reading-time",
3
- "version": "1.0.4",
3
+ "version": "1.2.0",
4
4
  "main": "/dist/index.js",
5
5
  "module": "/dist/index.mjs",
6
6
  "types": "/dist/index.d.ts",
@@ -12,7 +12,11 @@
12
12
  },
13
13
  "repository": {
14
14
  "type": "git",
15
- "url": "git+https://github.com/nurahmed123/get-reading-time.git"
15
+ "url": "git+https://github.com/nurahmed123/get-reading-time.git",
16
+ "license": "https://github.com/nurahmed123/get-reading-time/blob/main/LICENSE"
17
+ },
18
+ "publishConfig": {
19
+ "registry": "https://www.npmjs.com/package/get-reading-time"
16
20
  },
17
21
  "keywords": [
18
22
  "Reading",
@@ -136,11 +140,15 @@
136
140
  "homepage": "https://github.com/nurahmed123/get-reading-time#readme",
137
141
  "description": "",
138
142
  "devDependencies": {
143
+ "@types/axios": "^0.9.36",
139
144
  "@types/node": "^22.10.2",
140
145
  "@types/sentiment": "^5.0.4",
141
146
  "typescript": "^5.7.2"
142
147
  },
143
148
  "dependencies": {
149
+ "axios": "^1.7.9",
150
+ "cohere-ai": "^7.15.0",
151
+ "compromise": "^14.14.3",
144
152
  "sentiment": "^5.0.2",
145
153
  "tsup": "^8.3.5"
146
154
  }