Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanThatOneKid committed Mar 17, 2024
0 parents commit bd59154
Show file tree
Hide file tree
Showing 21 changed files with 829 additions and 0 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/check.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { stringify } from "@std/yaml";
import { CheckoutStep, SetupDenoStep } from "./shared.tsx";

/**
* CheckWorkflow is a GitHub workflow for the jsonx project.
*/
export function CheckWorkflow() {
return {
name: "Check",
on: {
push: {
branches: ["main"],
},
pull_request: {
branches: ["main"],
},
},
jobs: {
check: {
"runs-on": "ubuntu-latest",
steps: [
<CheckoutStep />,
<SetupDenoStep />,
<DenoFormatStep />,
<DenoLintStep />,
{
name: "Test",
run: "deno task test",
},
],
},
},
};
}

/**
* DenoFormatStep is a step that formats the code.
*/
export function DenoFormatStep() {
return {
name: "Format",
run: "deno fmt && git diff-index --quiet HEAD",
};
}

/**
* DenoLintStep is a step that lints the code.
*/
export function DenoLintStep() {
return {
name: "Lint",
run: "deno lint && git diff-index --quiet HEAD",
};
}

if (import.meta.main) {
Deno.writeTextFileSync(
Deno.args[0],
stringify(<CheckWorkflow />, { lineWidth: 80 }),
);
}
20 changes: 20 additions & 0 deletions .github/workflows/check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Check
'on':
push:
branches:
- main
pull_request:
branches:
- main
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: denoland/setup-deno@v1
- name: Format
run: deno fmt && git diff-index --quiet HEAD
- name: Lint
run: deno lint && git diff-index --quiet HEAD
- name: Test
run: deno task test
17 changes: 17 additions & 0 deletions .github/workflows/shared.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* CheckoutStep is a step that checks out the repository.
*/
export function CheckoutStep() {
return {
uses: "actions/checkout@v4",
};
}

/**
* SetupDenoStep is a step that sets up the Deno runtime.
*/
export function SetupDenoStep() {
return {
uses: "denoland/setup-deno@v1",
};
}
19 changes: 19 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"deno.enable": true,
"deno.unstable": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[markdown]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"[jsonc]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"[typescriptreact]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"files.eol": "\n"
}
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004

Copyright (C) 2004 Sam Hocevar <[email protected]>

Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.

DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. You just DO WHAT THE FUCK YOU WANT TO.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# jsonx_docs

Documentation site of [FartLabs/jsonx](https://github.com/FartLabs/jsonx), a JSX
runtime for composing JSON data.

## Contribute

### Style

Run `deno fmt` to format the code.

Run `deno lint` to lint the code.

Run `deno task generate` to generate code.

Run `deno task start` to locally serve the jsonx documentation site.

### Testing

Run `deno task test` to run the unit tests.

---

Developed with ❤️ [**@FartLabs**](https://github.com/FartLabs)
18 changes: 18 additions & 0 deletions deno.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@fartlabs/jsonx"
},
"imports": {
"@fartlabs/jsonx": "jsr:@fartlabs/jsonx@^0.0.9",
"@std/cli": "jsr:@std/cli@^0.220.1",
"@std/http": "jsr:@std/http@^0.220.1",
"@std/semver": "jsr:@std/semver@^0.220.1",
"@std/yaml": "jsr:@std/yaml@^0.220.1"
},
"tasks": {
"start": "deno run -A --unstable-kv main.ts",
"generate": "deno run -Ar https://deno.land/x/generate/cli/main.ts gen.ts"
},
"exclude": ["./static"]
}
83 changes: 83 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

110 changes: 110 additions & 0 deletions docs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { compare, greaterThan, parse } from "@std/semver";
import { serveDir } from "@std/http";

/**
* Playground is a jsonx playground.
*/
export interface Playground {
id: string;
version: string;
code: string;
}

/**
* Meta is the module metadata.
*/
export interface Meta {
latest: string;
versions: string[];
}

/**
* Docs is a class for serving the documentation site including
* jsonx playgrounds.
*/
export class Docs {
public constructor(private fsRoot: string, private kv: Deno.Kv) {}

/**
* fetch handles incoming requests.
*/
public async fetch(request: Request): Promise<Response> {
const url = new URL(request.url);
if (request.method === "GET" && url.pathname === "/meta") {
return Response.json(await this.meta);
}

if (request.method === "GET" && url.pathname.startsWith("/playgrounds/")) {
const id = url.pathname.split("/")[2];
const playground = await this.getPlayground(id);
if (playground === null) {
return new Response(null, { status: 404 });
}

return Response.json(playground);
}

if (request.method === "POST" && url.pathname === "/playgrounds") {
const playground = await request.json();
await this.setPlayground(playground);
return Response.json(playground);
}

return await serveDir(request, { fsRoot: this.fsRoot });
}

/**
* getPlayground gets a playground by ID.
*/
private async getPlayground(id: string): Promise<Playground | null> {
const result = await this.kv.get<Playground>(playgroundKey(id));
return result.value;
}

/**
* setPlayground sets a playground by ID.
*/
private async setPlayground(playground: Playground): Promise<void> {
const result = await this.kv.set(playgroundKey(playground.id), playground);
if (!result) {
throw new Error("Failed to set playground!");
}
}

/**
* meta gets the latest module metadata.
*/
private get meta(): Promise<Meta> {
return fetch("https://jsr.io/@fartlabs/jsonx/meta.json")
.then((response) => response.json())
.then((meta) => playgroundMeta(meta));
}
}

/**
* createDocs creates a new Docs instance.
*/
export function createDocs({ fsRoot, kv }: {
fsRoot: string;
kv: Deno.Kv;
}): Docs {
return new Docs(fsRoot, kv);
}

function playgroundMeta({ latest, versions }: {
latest: string;
versions: Record<string, unknown>;
}): Meta {
// https://github.com/FartLabs/jsonx/issues/13
const minCompatible = parse("0.0.8");
return {
latest: latest,
versions: Object.keys(versions)
.filter((versionTag) => greaterThan(parse(versionTag), minCompatible))
.sort((a, b) => compare(parse(b), parse(a))),
};
}

function playgroundKey(id: string): Deno.KvKey {
return ["playgrounds", id];
}
1 change: 1 addition & 0 deletions gen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//deno:generate deno run --allow-write .github/workflows/check.tsx .github/workflows/check.yaml
20 changes: 20 additions & 0 deletions main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { parseArgs } from "@std/cli";
import { createDocs } from "./docs.ts";

if (import.meta.main) {
const flags = parseArgs(Deno.args, {
string: ["port", "root"],
default: {
port: "8000",
root: "static",
},
});
const docs = createDocs({
fsRoot: flags.root,
kv: await Deno.openKv(),
});
Deno.serve(
{ port: parseInt(flags.port) },
docs.fetch.bind(docs),
);
}
Loading

0 comments on commit bd59154

Please sign in to comment.