Skip to content

Commit

Permalink
release (main) version 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshurajora committed Dec 14, 2023
0 parents commit 2cb73a9
Show file tree
Hide file tree
Showing 11 changed files with 4,552 additions and 0 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

name: Node.js CI

on:
push:
branches: ["main"]
pull_request:
branches: ["main"]

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
- run: npm ci
- run: npm run build --if-present
- run: npm test
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
*.js
.env
dist
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
6 changes: 6 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
jest.config.js
*.test.ts
*.test.js
.huskey
.env
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v18.16.0
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Rest Yourls

A simple rest client for generating short urls from `Yourls` backend.

Example:

```typescript
const response = await getShortLink({
username: process.env["YOURLS_USERNAME"]!,
password: process.env["YOURLS_PASSWORD"]!,
serverUrl: process.env["YOURLS_SERVER_URL"]!,
// A uniquely generated url
url: `https://example-${Date.now()}.com`,
});

console.log(response); // Should be completely typed and expected output

```

Thanks for reading!

By Vedik Dev: Himanshu Jangid @himanshurajora
41 changes: 41 additions & 0 deletions index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as dotenv from "dotenv";
import { getShortLink } from "./index";

dotenv.config();

test("Should get a unique shorturl without any errors", async () => {
const response = await getShortLink({
username: process.env["YOURLS_USERNAME"]!,
password: process.env["YOURLS_PASSWORD"]!,
serverUrl: process.env["YOURLS_SERVER_URL"]!,
// A uniquely generated url
url: `https://example-${Date.now()}.com`,
});

expect(response).toBeDefined();
expect(response.root.errorCode[0]).toBeFalsy();
expect(response.root.shorturl[0]).toBeDefined();
});

test("Should try for two requests with same url and should contain error for the second while still having the shortened url in response", async () => {
const url = `https://example-${Date.now()}.com`;

const response1 = await getShortLink({
username: process.env["YOURLS_USERNAME"]!,
password: process.env["YOURLS_PASSWORD"]!,
serverUrl: process.env["YOURLS_SERVER_URL"]!,
url,
});

const response2 = await getShortLink({
username: process.env["YOURLS_USERNAME"]!,
password: process.env["YOURLS_PASSWORD"]!,
serverUrl: process.env["YOURLS_SERVER_URL"]!,
url,
});

expect(response1).toBeDefined();
expect(response2).toBeDefined();
expect(response2.root.errorCode[0]).toBeTruthy();
expect(response2.root.shorturl[0]).toBeDefined();
});
61 changes: 61 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as axios from "axios";
import { parseStringPromise } from "xml2js";

export interface ShortLinkParam {
username: string;
password: string;
serverUrl: string;
url: string;
}

export interface YourlsResponse {
root: {
status: string[];
code: string[];
message: string[];
errorCode: string[];
statusCode: string[];
url: Array<null[]>;
title: string[];
shorturl: string[];
};
}

async function parseXml(input: string) {
try {
return parseStringPromise(input);
} catch (err: any) {
console.error(input);
throw new Error(
"Error encountered while parsing the XML, Error:" + err.message
);
}
}

export async function getShortLink({
username,
password,
url,
serverUrl,
}: ShortLinkParam): Promise<YourlsResponse> {
try {
const response = await axios.default.get<string>(
`${serverUrl}?username=${username}&password=${password}&action=shorturl&url=${url}`,
{
headers: {
"Content-Type": "text/xml",
},
}
);

return parseXml(response.data);
} catch (err: any) {
if (err instanceof axios.AxiosError) {
return parseXml(err.response?.data);
}

throw Error(
"We encountered a non axios error, perhaps there is a problem with XML response."
);
}
}
Loading

0 comments on commit 2cb73a9

Please sign in to comment.