Compare commits

..

1 commit

Author SHA1 Message Date
e56faa2082 Update dependency ts-jest to v29.2.3
All checks were successful
Test / build (push) Successful in 7s
2024-07-21 23:03:09 +00:00
22 changed files with 696 additions and 627 deletions

1
.eslintignore Normal file
View file

@ -0,0 +1 @@
dist/

50
.eslintrc Normal file
View file

@ -0,0 +1,50 @@
{
"parserOptions": {
"ecmaVersion": 6
},
"extends": [
"eslint:recommended"
],
"rules": {
"camelcase": "error",
"brace-style": [
"error",
"1tbs"
],
"comma-dangle": [
"error",
"never"
],
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
],
"comma-style": [
"error",
"last"
],
"arrow-body-style": [
"error",
"as-needed"
],
"arrow-parens": [
"error",
"as-needed"
],
"arrow-spacing": "error",
"no-var": "error",
"prefer-template": "error",
"prefer-const": "error"
},
"globals": {
"exports": "writable",
"module": "writable",
"require": "writable",
"process": "writable",
"console": "writable",
"jest": "writable"
}
}

View file

@ -13,7 +13,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: 20.x
- run: yarn install --frozen-lockfile
@ -26,7 +26,7 @@ jobs:
runs-on: node
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- uses: actions/setup-node@v3
with:
node-version: 20.x
- run: yarn install --frozen-lockfile

View file

@ -17,7 +17,7 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version: 20.x
- run: yarn install --frozen-lockfile

View file

@ -4,7 +4,7 @@ Since Version 2.2, Random Bunny contains a command line interface (CLI).
## Downloads
The project can be downloaded as a binary for your system via the [GitHub Releases](https://github.com/Vylpes/random-bunny/releases) or [Forgejo Releases](https://git.vylpes.xyz/RabbitLabs/random-bunny/releases) page.
The project can be downloaded as a binary for your system via the [GitHub Releases](https://github.com/Vylpes/random-bunny/releases) or [Gitea Releases](https://gitea.vylpes.xyz/RabbitLabs/random-bunny/releases) page.
We currently support:
- Linux (x64)
@ -13,8 +13,6 @@ We currently support:
The git repository can also be cloned and ran via `yarn build` and `yarn start`.
You can produce the binary using the `yarn package` command. This creates the binaries in the `./bin` folder.
> **NOTE:** We are aware of a bug in the macOS Arm64 builds failing to execute. For now you're still able to use the x64 builds under Rosetta fine. This will hopefully be fixed in a future release.
## Default Output
@ -22,7 +20,7 @@ You can produce the binary using the `yarn package` command. This creates the bi
By default, the command will fetch a random image from `r/rabbits` and return it in a human-readable output.
```
$ random-bunny
$ randombunny
Archived = false
Downvotes = 0
@ -40,11 +38,11 @@ Url = https://i.redd.it/sfz0srdrimjc1.png
The command also includes a help option in case you are stuck.
```
$ random-bunny --help
$ randombunny --help
# or
$ random-bunny -h
$ randombunny -h
Usage: random-bunny [options]
@ -57,7 +55,6 @@ Options:
-q, --query-metadata Include query metadata in result
-o <file> Output to file
--sort <sort> Sort by (choices: "hot", "new", "top", default: "hot")
--limit <limit> The amount of posts to fetch from the reddit api (default: 100)
-h, --help display help for command
```
@ -66,11 +63,11 @@ Options:
You can also convert the output into JSON, if you need to input it to another program.
```bash
$ random-bunny --json
$ randombunny --json
# or
$ randon-bunny -j
$ randonbunny -j
{"Archived":false,"Downs":0,"Hidden":false,"Permalink":"/r/Rabbits/comments/1av1rg9/cute_baby_bun/","Subreddit":"Rabbits","SubredditSubscribers":486085,"Title":"Cute baby bun","Ups":210,"Url":"https://i.redd.it/sfz0srdrimjc1.png"}
```
@ -82,9 +79,9 @@ You can also choose the sorting option which reddit will use to return the avail
This defaults to "hot". The valid options are "hot", "new", and "top".
```
$ random-bunny --sort hot
$ random-bunny --sort new
$ random-bunny --sort top
$ randombunny --sort hot
$ randombunny --sort new
$ randomBunny --sort top
```
@ -95,8 +92,8 @@ You can change the subreddit which the command fetches from.
This defaults to "rabbits"
```
$ random-bunny --subreddit rabbits
$ random-bunny -s horses
$ randombunny --subreddit rabbits
$ randombunny -s horses
```
## Output to file
@ -106,17 +103,3 @@ If you'd rather send the output to a file, you can supply the `-o` flag.
```
$ randombunny -o ~/Desktop/output.txt
```
## Reddit API Return Limits
You can also limit the amount the posts the script requests from the Reddit API
using the `--limit` option.
This defaults to 100. This accepts any number between 1 and 100.
Please note limiting the calls to less than 100 will give a higher chance of
the script not finding any valid image post to return.
```
$ random-bunny --limit 50
```

View file

@ -1,54 +0,0 @@
import js from "@eslint/js";
import ts from "typescript-eslint";
export default [
{
ignores: [
"**/dist/",
"eslint.config.mjs",
"jest.config.cjs",
"jest.setup.js"
],
},
js.configs.recommended,
...ts.configs.recommended,
{
languageOptions: {
globals: {
exports: "writable",
module: "writable",
require: "writable",
process: "writable",
console: "writable",
jest: "writable",
},
ecmaVersion: 6,
sourceType: "script",
},
files: [
"./src",
"./tests"
],
rules: {
camelcase: "error",
"brace-style": ["error", "1tbs"],
"comma-dangle": ["error", "never"],
"comma-spacing": ["error", {
before: false,
after: true,
}],
"comma-style": ["error", "last"],
"arrow-body-style": ["error", "as-needed"],
"arrow-parens": ["error", "as-needed"],
"arrow-spacing": "error",
"no-var": "error",
"prefer-template": "error",
"prefer-const": "error",
},
}
];

View file

@ -39,22 +39,19 @@
"homepage": "https://gitea.vylpes.xyz/RabbitLabs/random-bunny",
"funding": "https://ko-fi.com/vylpes",
"devDependencies": {
"@eslint/eslintrc": "^3.1.0",
"@eslint/js": "^9.7.0",
"@types/eslint": "^9.6.0",
"@types/eslint": "^8.21.1",
"@types/jest": "^29.5.8",
"@types/node": "^20.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"@yao-pkg/pkg": "^5.12.0",
"eslint": "^9.7.0",
"eslint": "^8.49.0",
"jest": "^29.7.0",
"jest-mock-extended": "^3.0.3",
"np": "^10.0.0",
"pkg": "^5.8.1",
"ts-jest": "^29.1.1",
"ts-mockito": "^2.6.1",
"typescript": "^5.0.0",
"typescript-eslint": "^7.17.0"
"typescript": "^5.0.0"
},
"resolutions": {
"np/**/got": "^14.0.0",

View file

@ -33,7 +33,7 @@ console.log(result);
### `randomBunny()`
Returns a `json string` for a random post. Accepts 3 arguments: `subreddit`, `sortby` ('new', 'hot', 'top'), and `limit` (1-100, default 100)
Returns a `json string` for a random post. Accepts 2 arguments: `subreddit`, and `sortby` ('new', 'hot', 'top')
The json string which gets returned consists of:
- archived

View file

@ -1,5 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"baseBranches": ["develop"],
"labels": ["type/dependencies"]
"baseBranches": ["develop"]
}

View file

@ -14,12 +14,11 @@ program
.option('-j, --json', 'Output as JSON')
.option('-q, --query-metadata', 'Include query metadata in result')
.option('-o <file>', 'Output to file')
.addOption(new Option('--sort <sort>', 'Sort by').default('hot').choices(['hot', 'new', 'top']))
.addOption(new Option('--limit <limit>', 'The amount of posts to fetch from the reddit api').default(100));
.addOption(new Option('--sort <sort>', 'Sort by').default('hot').choices(['hot', 'new', 'top']));
program.parse();
const options: ICliOptions = program.opts();
randomBunny(options.subreddit, options.sort, options.limit)
randomBunny(options.subreddit, options.sort)
.then((response) => exit(CliHelper.Endpoint(response, options)));

View file

@ -3,5 +3,4 @@ export enum ErrorCode {
FailedToFetchReddit,
UnableToParseJSON,
NoImageResultsFound,
LimitOutOfRange,
}

View file

@ -2,5 +2,4 @@ export default class ErrorMessages {
public static readonly FailedToFetchReddit = "Failed to fetch result from Reddit";
public static readonly UnableToParseJSON = "Unable to parse the JSON result";
public static readonly NoImageResultsFound = "No image results found in response from Reddit";
public static readonly LimitOutOfRange = "Limit must be a number between 1 and 100";
}

View file

@ -3,6 +3,5 @@ export default interface ICliOptions {
json?: boolean,
sort: "new" | "hot" | "top",
o?: string,
limit: number,
queryMetadata?: boolean,
}

View file

@ -1,5 +1,4 @@
export default interface QueryResult {
subreddit: string,
sortBy: string,
limit: number,
}

View file

@ -9,7 +9,7 @@ export default class CliHelper {
const output = OutputHelper.GenerateOutput(response, options);
if (options.o) {
writeFileSync(options.o, `${output}\n`);
writeFileSync(options.o, output);
} else {
console.log(output);
}

View file

@ -24,7 +24,6 @@ export default class OutputHelper {
if (options.queryMetadata != null) {
outputLines.push(`Query.Subreddit = ${response.Query.subreddit}`);
outputLines.push(`Query.Sort By = ${response.Query.sortBy}`);
outputLines.push(`Query.Limit = ${response.Query.limit}`);
}
return outputLines.join("\n");

View file

@ -7,23 +7,8 @@ import { ErrorCode } from "./constants/ErrorCode";
import ErrorMessages from "./constants/ErrorMessages";
import ImageHelper from "./helpers/imageHelper";
export default async function randomBunny(subreddit: string, sortBy: "new" | "hot" | "top" = 'hot', limit: number = 100): Promise<IReturnResult> {
if (limit < 1 || limit > 100) {
return {
IsSuccess: false,
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Error: {
Code: ErrorCode.LimitOutOfRange,
Message: ErrorMessages.LimitOutOfRange,
}
};
}
const result = await fetch(`https://reddit.com/r/${subreddit}/${sortBy}.json?limit=${limit}`)
export default async function randomBunny(subreddit: string, sortBy: "new" | "hot" | "top" = 'hot'): Promise<IReturnResult> {
const result = await fetch(`https://reddit.com/r/${subreddit}/${sortBy}.json?limit=100`)
.then((res) => {
return res;
})
@ -37,7 +22,6 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Error: {
Code: ErrorCode.FailedToFetchReddit,
@ -54,7 +38,6 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Error: {
Code: ErrorCode.UnableToParseJSON,
@ -77,7 +60,6 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Error: {
Code: ErrorCode.NoImageResultsFound,
@ -103,7 +85,6 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Error: {
Code: ErrorCode.NoImageResultsFound,
@ -134,7 +115,6 @@ export default async function randomBunny(subreddit: string, sortBy: "new" | "ho
Query: {
subreddit: subreddit,
sortBy: sortBy,
limit: limit,
},
Result: redditResult
};

View file

@ -25,6 +25,5 @@ Title = This is my Ms Bear!
Upvotes = 17
Url = https://preview.redd.it/d5yno653zf7d1.jpg?width=640&crop=smart&auto=webp&s=5064d1caec3c12ac2855eb57ff131d0b313d5e9d
Query.Subreddit = rabbits
Query.Sort By = hot
Query.Limit = 100"
Query.Sort By = hot"
`;

View file

@ -35,7 +35,7 @@ describe("Endpoint", () => {
expect(OutputHelper.GenerateOutput).toHaveBeenCalledWith(response, options);
expect(fs.writeFileSync).toHaveBeenCalledTimes(1);
expect(fs.writeFileSync).toHaveBeenCalledWith("file.txt", "test output\n");
expect(fs.writeFileSync).toHaveBeenCalledWith("file.txt", "test output");
expect(console.log).not.toHaveBeenCalled();

View file

@ -10,7 +10,6 @@ describe("GenerateOutput", () => {
Query: {
subreddit: "rabbits",
sortBy: "hot",
limit: 100,
},
Result: {
Archived: false,
@ -41,7 +40,6 @@ describe("GenerateOutput", () => {
Query: {
subreddit: "rabbits",
sortBy: "hot",
limit: 100,
},
Result: {
Archived: false,
@ -74,7 +72,6 @@ describe("GenerateOutput", () => {
Query: {
subreddit: "rabbits",
sortBy: "hot",
limit: 100,
},
Result: {
Archived: false,

View file

@ -7,10 +7,6 @@ import fetch from "got-cjs";
jest.mock('got-cjs');
const fetchMock = jest.mocked(fetch);
beforeEach(() => {
fetchMock.mockReset();
});
describe('randomBunny', () => {
test('GIVEN subreddit AND sortBy is supplied, EXPECT successful result', async() => {
fetchMock.mockResolvedValue({
@ -126,7 +122,7 @@ describe('randomBunny', () => {
expect(result.Error!.Code).toBe(ErrorCode.NoImageResultsFound);
expect(result.Error!.Message).toBe(ErrorMessages.NoImageResultsFound);
expect(fetchMock).toHaveBeenCalledWith('https://reddit.com/r/rabbits/new.json?limit=100');
expect(fetchMock).toBeCalledWith('https://reddit.com/r/rabbits/new.json?limit=100');
});
test('GIVEN randomSelect does NOT find a valid response, EXPECT failure result', async () => {
@ -235,106 +231,4 @@ describe('randomBunny', () => {
expect(result.Error?.Code).toBe(ErrorCode.NoImageResultsFound);
expect(result.Error?.Message).toBe(ErrorMessages.NoImageResultsFound);
});
test("GIVEN limit is supplied, EXPECT limit sent to the API", async () => {
fetchMock.mockResolvedValue({
body: JSON.stringify({
data: {
children: [
{
data: {
archived: false,
downs: 0,
hidden: false,
permalink: '/r/Rabbits/comments/12pa5te/someone_told_pickles_its_monday_internal_fury/',
subreddit: 'Rabbits',
subreddit_subscribers: 298713,
title: 'Someone told pickles its Monday… *internal fury*',
ups: 1208,
url: 'https://i.redd.it/cr8xudsnkgua1.jpg',
},
},
],
}
}),
});
const result = await randomBunny('rabbits', 'new', 50);
expect(result.IsSuccess).toBeTruthy();
expect(result.Result).toBeDefined();
expect(result.Error).toBeUndefined();
expect(fetchMock).toHaveBeenCalledWith('https://reddit.com/r/rabbits/new.json?limit=50');
});
test("GIVEN limit is less than 1, EXPECT error to be returned", async () => {
fetchMock.mockResolvedValue({
body: JSON.stringify({
data: {
children: [
{
data: {
archived: false,
downs: 0,
hidden: false,
permalink: '/r/Rabbits/comments/12pa5te/someone_told_pickles_its_monday_internal_fury/',
subreddit: 'Rabbits',
subreddit_subscribers: 298713,
title: 'Someone told pickles its Monday… *internal fury*',
ups: 1208,
url: 'https://i.redd.it/cr8xudsnkgua1.jpg',
},
},
],
}
}),
});
const result = await randomBunny('rabbits', 'new', 0);
expect(result.IsSuccess).toBeFalsy();
expect(result.Result).toBeUndefined();
expect(result.Error).toBeDefined();
expect(result.Error!.Code).toBe(ErrorCode.LimitOutOfRange);
expect(result.Error!.Message).toBe(ErrorMessages.LimitOutOfRange);
expect(fetchMock).not.toHaveBeenCalled();
});
test("GIVEN limit is greater than 100, EXPECT error to be returned", async () => {
fetchMock.mockResolvedValue({
body: JSON.stringify({
data: {
children: [
{
data: {
archived: false,
downs: 0,
hidden: false,
permalink: '/r/Rabbits/comments/12pa5te/someone_told_pickles_its_monday_internal_fury/',
subreddit: 'Rabbits',
subreddit_subscribers: 298713,
title: 'Someone told pickles its Monday… *internal fury*',
ups: 1208,
url: 'https://i.redd.it/cr8xudsnkgua1.jpg',
},
},
],
}
}),
});
const result = await randomBunny('rabbits', 'new', 101);
expect(result.IsSuccess).toBeFalsy();
expect(result.Result).toBeUndefined();
expect(result.Error).toBeDefined();
expect(result.Error!.Code).toBe(ErrorCode.LimitOutOfRange);
expect(result.Error!.Message).toBe(ErrorMessages.LimitOutOfRange);
expect(fetchMock).not.toHaveBeenCalled();
});
});

1005
yarn.lock

File diff suppressed because it is too large Load diff