Skip to content

Commit

Permalink
add cli/main.ts
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Apr 6, 2024
1 parent 781ff8f commit e96c41c
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# go.fart.tools

[![GitHub Actions](https://github.com/FartLabs/rtx/actions/workflows/check.yaml/badge.svg)](https://github.com/FartLabs/rtx/actions/workflows/check.yaml)

Link shortening service with Deno.

## Contribute

### Style

Run `deno fmt` to format the code.

Run `deno lint` to lint the code.

### Test

Run `deno test` to run the tests.

Run `deno task start` to start the server.

---

Developed with ❤️ [**@FartLabs**](https://github.com/FartLabs)
97 changes: 95 additions & 2 deletions cli/main.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,95 @@
// TODO: HTTP server setting and deleting shortlink data.
// TODO: Add vscode settings file.
import { createRouter } from "@fartlabs/rt";
import { go } from "go/go.ts";

class GoService {
public constructor(
private readonly kv: Deno.Kv,
private readonly kvNamespace: Deno.KvKey = ["go"],
) {}

public async add(
alias: string,
destination: string,
force = false,
): Promise<void> {
const collectionResult = await this.kv.get<string>(this.kvNamespace);
const collection = collectionResult.value
? JSON.parse(collectionResult.value)
: {};
if (!force && collection[alias]) {
throw new Error("Shortlink already exists.");
}

collection[alias] = destination;
const result = await this.kv.atomic()
.check(collectionResult)
.set(this.kvNamespace, JSON.stringify(collection))
.commit();
if (!result.ok) {
throw new Error("Failed to add shortlink.");
}
}

public async delete(alias: string): Promise<void> {
const collectionResult = await this.kv.get<string>(this.kvNamespace);
const collection = collectionResult.value
? JSON.parse(collectionResult.value)
: {};
delete collection[alias];
const result = await this.kv.atomic()
.check(collectionResult)
.set(this.kvNamespace, JSON.stringify(collection))
.commit();
if (!result.ok) {
throw new Error("Failed to delete shortlink.");
}
}

public async collection(): Promise<Record<string, string>> {
const collectionResult = await this.kv.get<string>(this.kvNamespace);
return collectionResult.value ? JSON.parse(collectionResult.value) : {};
}
}

function isAuthorized(headers: Headers): boolean {
const auth = headers.get("Authorization");
return auth === `Token ${Deno.env.get("GO_TOKEN")}`;
}

if (import.meta.main) {
const kv = await Deno.openKv();
const goService = new GoService(kv);
const router = createRouter()
// TODO: Use rtx to define the routes. Use htx to define the HTML index page.
.post("/api", async (ctx) => {
if (!isAuthorized(ctx.request.headers)) {
return new Response("Unauthorized", { status: 401 });
}

const body = await ctx.request.json();
await goService.add(body.alias, body.destination, body.force);
return new Response("Shortlink added.", { status: 201 });
})
.delete("/api", async (ctx) => {
if (!isAuthorized(ctx.request.headers)) {
return new Response("Unauthorized", { status: 401 });
}

const body = await ctx.request.json();
await goService.delete(body.alias);
return new Response("Shortlink removed.", { status: 200 });
})
.get("/:path*", async (ctx) => {
const collection = await goService.collection();
const destination = go(ctx.url, collection);
return new Response(
`Going to ${destination.href}...`,
{
status: 302,
headers: { "Location": destination.href },
},
);
});

Deno.serve((request) => router.fetch(request));
}
5 changes: 5 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"lock": false,
"imports": {
"go/": "./",
"@fartlabs/rt": "jsr:@fartlabs/rt@^0.0.1",
"@std/assert": "jsr:@std/assert@^0.221.0"
},
"tasks": {
"start": "deno run --unstable-kv --env -A cli/main.ts"
}
}

0 comments on commit e96c41c

Please sign in to comment.