-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: #544-Add short.io as a shortening link #564
base: main
Are you sure you want to change the base?
Conversation
@ak7550 is attempting to deploy a commit to the Listinai Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe pull request introduces a new Changes
Possibly related issues
Poem
Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🧹 Nitpick comments (1)
libraries/nestjs-libraries/src/short-linking/short.link.service.ts (1)
12-15
: Consider provider precedence ingetProvider
functionThe current logic checks for
DUB_TOKEN
beforeSHORT_IO_SECRET_KEY
. If both environment variables are set, theDub
provider will be selected overShortIo
. IfShortIo
should take precedence, adjust the order of the checks.Apply this diff to prioritize
ShortIo
:const getProvider = (): ShortLinking => { + if (process.env.SHORT_IO_SECRET_KEY) { + return new ShortIo(); + } if (process.env.DUB_TOKEN) { return new Dub(); } - if (process.env.SHORT_IO_SECRET_KEY) { - return new ShortIo(); - } return new Empty(); };Alternatively, clearly document the intended order of provider selection if the current configuration is deliberate.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
libraries/nestjs-libraries/src/short-linking/providers/short.io.ts
(1 hunks)libraries/nestjs-libraries/src/short-linking/short.link.service.ts
(1 hunks)
🔇 Additional comments (1)
libraries/nestjs-libraries/src/short-linking/short.link.service.ts (1)
5-5
: Verify the import path forShortIo
providerEnsure that the import path
'./providers/short.io'
correctly references theShortIo
provider file. Incorrect import paths can lead to module resolution errors.If the
short.io.ts
file is not located directly under theproviders
directory or if there's a casing mismatch, update the import accordingly.
}; | ||
|
||
export class ShortIo implements ShortLinking { | ||
shortLinkDomain = 'aniket.short.gy'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Make shortLinkDomain
configurable
The shortLinkDomain
is hardcoded as 'aniket.short.gy'
. To enhance flexibility and reusability, consider making it configurable via an environment variable or a constructor parameter. Hardcoding the domain limits the usability of this provider in different environments.
Apply this diff to use an environment variable:
export class ShortIo implements ShortLinking {
- shortLinkDomain = 'aniket.short.gy';
+ shortLinkDomain = process.env.SHORT_IO_DOMAIN || 'your-default-domain.com';
Ensure that SHORT_IO_DOMAIN
is defined in your environment configuration.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
shortLinkDomain = 'aniket.short.gy'; | |
shortLinkDomain = process.env.SHORT_IO_DOMAIN || 'your-default-domain.com'; |
Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, | ||
'Content-Type': 'application/json', | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle missing SHORT_IO_SECRET_KEY
environment variable gracefully
If process.env.SHORT_IO_SECRET_KEY
is undefined, the Authorization
header will be 'Bearer undefined'
, which may cause authentication failures or security issues when making API calls. It's important to check if the environment variable is set and handle the absence appropriately.
Apply this diff to ensure the secret key is present and throw an error if it's missing:
const options = {
headers: {
- Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`,
+ Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY || ''}`,
'Content-Type': 'application/json',
},
};
+if (!process.env.SHORT_IO_SECRET_KEY) {
+ throw new Error('SHORT_IO_SECRET_KEY environment variable is not set.');
+}
Alternatively, consider initializing the options within the class constructor after verifying the presence of the secret key.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, | |
'Content-Type': 'application/json', | |
}, | |
}; | |
const options = { | |
headers: { | |
Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY || ''}`, | |
'Content-Type': 'application/json', | |
}, | |
}; | |
if (!process.env.SHORT_IO_SECRET_KEY) { | |
throw new Error('SHORT_IO_SECRET_KEY environment variable is not set.'); | |
} |
`https://api.dub.co/links/info?domain=${shortLink}`, | ||
options | ||
) | ||
).json() | ||
).url; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect API endpoint in convertShortLinkToLink
method
Similarly, the convertShortLinkToLink
method is using https://api.dub.co/links/info
, which should be a Short.io API endpoint. This inconsistency may cause the method to fail or return incorrect data.
Update the endpoint and parameters to align with Short.io's API:
await fetch(
- `https://api.dub.co/links/info?domain=${shortLink}`,
+ `https://api.short.io/links/expand?shortURL=${encodeURIComponent(shortLink)}`,
options
)
Adjust the response handling accordingly to extract the original URL:
).json()
- ).url;
+ ).originalURL;
Ensure that you handle errors and check the API documentation for correct usage.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
`https://api.dub.co/links/info?domain=${shortLink}`, | |
options | |
) | |
).json() | |
).url; | |
`https://api.short.io/links/expand?shortURL=${encodeURIComponent(shortLink)}`, | |
options | |
) | |
).json() | |
).originalURL; |
...options, | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
url: link, | ||
tenantId: id, | ||
domain: this.shortLinkDomain, | ||
}), | ||
}) | ||
).json() | ||
).shortLink; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect API endpoint in convertLinkToShortLink
method
The method is using the https://api.dub.co/links
endpoint, which does not align with the short.io
service. Since this is a ShortIo
provider, the API calls should be directed to short.io
endpoints.
Update the API endpoint and adjust the request parameters according to the Short.io API documentation:
await fetch(`https://api.dub.co/links`, {
+ await fetch(`https://api.short.io/links`, {
...options,
method: 'POST',
body: JSON.stringify({
- url: link,
- tenantId: id,
- domain: this.shortLinkDomain,
+ originalURL: link,
+ domain: this.shortLinkDomain,
+ campaignSource: id,
}),
})
Ensure that the request body matches the expected format of the Short.io API for creating short links.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
...options, | |
method: 'POST', | |
body: JSON.stringify({ | |
url: link, | |
tenantId: id, | |
domain: this.shortLinkDomain, | |
}), | |
}) | |
).json() | |
).shortLink; | |
} | |
...options, | |
method: 'POST', | |
body: JSON.stringify({ | |
originalURL: link, | |
domain: this.shortLinkDomain, | |
campaignSource: id, | |
}), | |
}) | |
).json() | |
).shortLink; | |
} |
const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`; | ||
const response = await ( fetch( url, options ) | ||
.then( res => res.json() ) ); | ||
|
||
const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; | ||
|
||
const statResponse = await ( fetch( linkStatisticsUrl, options ).then( ( res ) => res.json() ) ); | ||
|
||
return { | ||
short: response.shortURL, | ||
original: response.originalURL, | ||
clicks: statResponse.totalClicks, | ||
}; | ||
}) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for API requests in linksStatistics
method
The linksStatistics
method lacks error handling for network failures or unexpected responses, which can lead to unhandled exceptions. It's important to catch errors from fetch
and handle HTTP response statuses appropriately.
Apply this diff to include error handling:
links.map(async (link) => {
const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`;
- const response = await ( fetch( url, options )
- .then( res => res.json() ) );
+ let response;
+ try {
+ const res = await fetch(url, options);
+ if (!res.ok) {
+ throw new Error(`Failed to expand link: ${res.status} ${res.statusText}`);
+ }
+ response = await res.json();
+ } catch (error) {
+ console.error('Error fetching link expansion:', error);
+ throw error;
+ }
const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`;
- const statResponse = await ( fetch( linkStatisticsUrl, options ).then( ( res ) => res.json() ) );
+ let statResponse;
+ try {
+ const res = await fetch(linkStatisticsUrl, options);
+ if (!res.ok) {
+ throw new Error(`Failed to get link statistics: ${res.status} ${res.statusText}`);
+ }
+ statResponse = await res.json();
+ } catch (error) {
+ console.error('Error fetching link statistics:', error);
+ throw error;
+ }
return {
short: response.shortURL,
original: response.originalURL,
clicks: statResponse.totalClicks,
};
})
This ensures that any errors during the fetch operations are caught and can be handled appropriately by the calling code.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`; | |
const response = await ( fetch( url, options ) | |
.then( res => res.json() ) ); | |
const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; | |
const statResponse = await ( fetch( linkStatisticsUrl, options ).then( ( res ) => res.json() ) ); | |
return { | |
short: response.shortURL, | |
original: response.originalURL, | |
clicks: statResponse.totalClicks, | |
}; | |
}) | |
); | |
} | |
const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`; | |
let response; | |
try { | |
const res = await fetch(url, options); | |
if (!res.ok) { | |
throw new Error(`Failed to expand link: ${res.status} ${res.statusText}`); | |
} | |
response = await res.json(); | |
} catch (error) { | |
console.error('Error fetching link expansion:', error); | |
throw error; | |
} | |
const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; | |
let statResponse; | |
try { | |
const res = await fetch(linkStatisticsUrl, options); | |
if (!res.ok) { | |
throw new Error(`Failed to get link statistics: ${res.status} ${res.statusText}`); | |
} | |
statResponse = await res.json(); | |
} catch (error) { | |
console.error('Error fetching link statistics:', error); | |
throw error; | |
} | |
return { | |
short: response.shortURL, | |
original: response.originalURL, | |
clicks: statResponse.totalClicks, | |
}; | |
}) | |
); | |
} |
const response = await ( | ||
await fetch( | ||
`https://api.dub.co/links?tenantId=${id}&page=${page}&pageSize=100`, | ||
options | ||
) | ||
).json(); | ||
|
||
const mapLinks = response.links.map((link: any) => ({ | ||
short: link, | ||
original: response.url, | ||
clicks: response.clicks, | ||
})); | ||
|
||
if (mapLinks.length < 100) { | ||
return mapLinks; | ||
} | ||
|
||
return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))]; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect response mapping and endpoint in getAllLinksStatistics
method
- The method is using
https://api.dub.co/links
, which should behttps://api.short.io/links
. - The mapping of the response may not align with the actual data returned by the Short.io API.
- The termination condition for recursion might not be accurate.
Apply this diff to correct the method:
await fetch(
- `https://api.dub.co/links?tenantId=${id}&page=${page}&pageSize=100`,
+ `https://api.short.io/links?domain_id=${this.shortLinkDomain}&limit=100&offset=${(page - 1) * 100}`,
options
)
).json();
- const mapLinks = response.links.map((link: any) => ({
- short: link,
- original: response.url,
- clicks: response.clicks,
+ const mapLinks = response.data.map((link: any) => ({
+ short: link.shortURL,
+ original: link.originalURL,
+ clicks: link.clicks,
}));
- if (mapLinks.length < 100) {
+ if (response.data.length < 100) {
return mapLinks;
}
return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))];
Ensure that the response fields data
, shortURL
, originalURL
, and clicks
match the actual response from the Short.io API. Adjust the termination condition based on the returned data.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const response = await ( | |
await fetch( | |
`https://api.dub.co/links?tenantId=${id}&page=${page}&pageSize=100`, | |
options | |
) | |
).json(); | |
const mapLinks = response.links.map((link: any) => ({ | |
short: link, | |
original: response.url, | |
clicks: response.clicks, | |
})); | |
if (mapLinks.length < 100) { | |
return mapLinks; | |
} | |
return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))]; | |
} | |
} | |
const response = await ( | |
await fetch( | |
`https://api.short.io/links?domain_id=${this.shortLinkDomain}&limit=100&offset=${(page - 1) * 100}`, | |
options | |
) | |
).json(); | |
const mapLinks = response.data.map((link: any) => ({ | |
short: link.shortURL, | |
original: link.originalURL, | |
clicks: link.clicks, | |
})); | |
if (response.data.length < 100) { | |
return mapLinks; | |
} | |
return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))]; | |
} | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (4)
libraries/nestjs-libraries/src/short-linking/providers/short.io.ts (4)
4-9
:⚠️ Potential issueMove options object inside the class and handle API key securely
The options object should be initialized within the class to ensure proper encapsulation and secure handling of the API key.
Apply this diff:
-const options = { - headers: { - Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, - 'Content-Type': 'application/json', - }, -}; export class ShortIo implements ShortLinking { + private readonly options: RequestInit; + + constructor() { + if (!process.env.SHORT_IO_SECRET_KEY) { + throw new Error('SHORT_IO_SECRET_KEY environment variable is not set'); + } + this.options = { + headers: { + Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, + 'Content-Type': 'application/json', + }, + }; + }
12-12
: 🛠️ Refactor suggestionMake shortLinkDomain configurable via constructor
The domain should be configurable to support different environments and use cases.
Apply this diff:
- shortLinkDomain = 'short.io'; + private readonly shortLinkDomain: string; + + constructor(domain?: string) { + if (!process.env.SHORT_IO_SECRET_KEY) { + throw new Error('SHORT_IO_SECRET_KEY environment variable is not set'); + } + this.shortLinkDomain = domain || process.env.SHORT_IO_DOMAIN || 'short.io'; + this.options = { + headers: { + Authorization: `Bearer ${process.env.SHORT_IO_SECRET_KEY}`, + 'Content-Type': 'application/json', + }, + }; + }
14-32
:⚠️ Potential issueAdd error handling and input validation to linksStatistics method
The method needs proper error handling and input validation.
Apply this diff:
- async linksStatistics(links: string[]) { + async linksStatistics(links: string[]): Promise<Array<{ short: string; original: string; clicks: number }>> { + if (!Array.isArray(links) || links.length === 0) { + throw new Error('Links must be a non-empty array'); + } + return Promise.all( links.map(async (link) => { const url = `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${link.split('/').pop()}`; - const response = await (fetch(url, options) - .then(res => res.json())); + let response; + try { + const res = await fetch(url, this.options); + if (!res.ok) { + throw new Error(`Failed to expand link: ${res.status} ${res.statusText}`); + } + response = await res.json(); + } catch (error) { + console.error(`Error processing link ${link}:`, error); + throw error; + } const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; - const statResponse = await (fetch(linkStatisticsUrl, options).then((res) => res.json())); + let statResponse; + try { + const res = await fetch(linkStatisticsUrl, this.options); + if (!res.ok) { + throw new Error(`Failed to get statistics: ${res.status} ${res.statusText}`); + } + statResponse = await res.json(); + } catch (error) { + console.error(`Error fetching statistics for ${link}:`, error); + throw error; + } return { short: response.shortURL, original: response.originalURL, clicks: statResponse.totalClicks, }; }) ); }
61-90
:⚠️ Potential issueFix pagination, response mapping, and add error handling in getAllLinksStatistics
The method has several critical issues including incorrect pagination and response mapping.
Apply this diff:
async getAllLinksStatistics( id: string, page = 1 ): Promise<{ short: string; original: string; clicks: string }[]> { + if (!id) { + throw new Error('Domain ID is required'); + } + + const limit = 100; + try { const response = await ( await fetch( - `https://api.short.io/api/links?domain_id=${id}&limit=150`, + `https://api.short.io/api/links?domain_id=${id}&limit=${limit}&offset=${(page - 1) * limit}`, options ) ).json(); - const mapLinks = response.links.map(async (link: any) => { + if (!response.data || !Array.isArray(response.data)) { + throw new Error('Invalid response format from API'); + } + + const mapLinks = await Promise.all(response.data.map(async (link: any) => { const linkStatisticsUrl = `https://statistics.short.io/statistics/link/${response.id}?period=last30&tz=UTC`; - const statResponse = await(fetch(linkStatisticsUrl, options).then((res) => res.json())); + try { + const statResponse = await fetch(linkStatisticsUrl, this.options); + if (!statResponse.ok) { + throw new Error(`Failed to get statistics: ${statResponse.status}`); + } + const stats = await statResponse.json(); + + return { - short: link, - original: response.url, - clicks: statResponse.totalClicks, + short: link.shortURL, + original: link.originalURL, + clicks: stats.totalClicks, }; - }); + } catch (error) { + console.error(`Error fetching statistics for link ${link.id}:`, error); + throw error; + } + })); - if (mapLinks.length < 100) { + if (response.data.length < limit) { return mapLinks; } return [...mapLinks, ...(await this.getAllLinksStatistics(id, page + 1))]; + } catch (error) { + console.error('Error fetching links:', error); + throw error; + } }
🧹 Nitpick comments (1)
libraries/nestjs-libraries/src/short-linking/providers/short.io.ts (1)
11-91
: Consider implementing rate limitingThe Short.io API likely has rate limits. Consider implementing a rate limiter to prevent hitting API limits, especially in the recursive
getAllLinksStatistics
method and when processing multiple links inlinksStatistics
.Consider using a rate limiting library like
bottleneck
:import Bottleneck from 'bottleneck'; private readonly limiter = new Bottleneck({ minTime: 100, // Minimum time between requests maxConcurrent: 5 // Maximum concurrent requests }); // Then wrap API calls: const response = await this.limiter.schedule(() => fetch(url, this.options));
async convertShortLinkToLink(shortLink: string) { | ||
return await( | ||
await( | ||
await fetch( | ||
`https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${shortLink.split('/').pop()}`, | ||
options | ||
) | ||
).json() | ||
).originalURL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify promise handling and add error handling in convertShortLinkToLink
The method has unnecessary nested awaits and lacks error handling.
Apply this diff:
- async convertShortLinkToLink(shortLink: string) {
- return await(
- await(
- await fetch(
- `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${shortLink.split('/').pop()}`,
- options
- )
- ).json()
- ).originalURL;
+ async convertShortLinkToLink(shortLink: string): Promise<string> {
+ if (!shortLink) {
+ throw new Error('Short link is required');
+ }
+
+ try {
+ const path = shortLink.split('/').pop();
+ if (!path) {
+ throw new Error('Invalid short link format');
+ }
+
+ const response = await fetch(
+ `https://api.short.io/links/expand?domain=${this.shortLinkDomain}&path=${path}`,
+ this.options
+ );
+
+ if (!response.ok) {
+ throw new Error(`Failed to expand short link: ${response.status} ${response.statusText}`);
+ }
+
+ const data = await response.json();
+ return data.originalURL;
+ } catch (error) {
+ console.error('Error expanding short link:', error);
+ throw error;
+ }
}
Committable suggestion skipped: line range outside the PR's diff.
async convertLinkToShortLink ( id: string, link: string ) { | ||
const response = await fetch( `https://api.short.io/links`, { | ||
...options, | ||
method: 'POST', | ||
body: JSON.stringify( { | ||
url: link, | ||
tenantId: id, | ||
domain: this.shortLinkDomain, | ||
originalURL: link | ||
|
||
} ), | ||
} ).then( ( res ) => res.json() ); | ||
|
||
return response.shortURL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix API parameters and add error handling in convertLinkToShortLink
The method has duplicate parameters and lacks error handling.
Apply this diff:
- async convertLinkToShortLink(id: string, link: string) {
+ async convertLinkToShortLink(id: string, link: string): Promise<string> {
+ if (!link) {
+ throw new Error('Link is required');
+ }
+
+ try {
const response = await fetch(`https://api.short.io/links`, {
...options,
method: 'POST',
body: JSON.stringify({
- url: link,
- tenantId: id,
+ originalURL: link,
+ domain_id: id,
domain: this.shortLinkDomain,
- originalURL: link
-
}),
- }).then((res) => res.json());
+ });
+
+ if (!response.ok) {
+ throw new Error(`Failed to create short link: ${response.status} ${response.statusText}`);
+ }
+
+ const data = await response.json();
+ return data.shortURL;
+ } catch (error) {
+ console.error('Error creating short link:', error);
+ throw error;
+ }
- return response.shortURL;
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
async convertLinkToShortLink ( id: string, link: string ) { | |
const response = await fetch( `https://api.short.io/links`, { | |
...options, | |
method: 'POST', | |
body: JSON.stringify( { | |
url: link, | |
tenantId: id, | |
domain: this.shortLinkDomain, | |
originalURL: link | |
} ), | |
} ).then( ( res ) => res.json() ); | |
return response.shortURL; | |
} | |
async convertLinkToShortLink(id: string, link: string): Promise<string> { | |
if (!link) { | |
throw new Error('Link is required'); | |
} | |
try { | |
const response = await fetch(`https://api.short.io/links`, { | |
...options, | |
method: 'POST', | |
body: JSON.stringify({ | |
originalURL: link, | |
domain_id: id, | |
domain: this.shortLinkDomain, | |
}), | |
}); | |
if (!response.ok) { | |
throw new Error(`Failed to create short link: ${response.status} ${response.statusText}`); | |
} | |
const data = await response.json(); | |
return data.shortURL; | |
} catch (error) { | |
console.error('Error creating short link:', error); | |
throw error; | |
} | |
} |
What kind of change does this PR introduce?
#544
Feature that integrates short.io as a shortening link.
Why was this change needed?
#544
Please link to related issues when possible, and explain WHY you changed things, not WHAT you changed.
Other information:
eg: Did you discuss this change with anybody before working on it (not required, but can be a good idea for bigger changes). Any plans for the future, etc?
Checklist:
Put a "X" in the boxes below to indicate you have followed the checklist;
Summary by CodeRabbit
New Features
Improvements