diff --git a/.changeset/tender-brooms-own.md b/.changeset/tender-brooms-own.md new file mode 100644 index 00000000..f73bfe33 --- /dev/null +++ b/.changeset/tender-brooms-own.md @@ -0,0 +1,5 @@ +--- +"counterfact": minor +--- + +Until now the dashboard hasn't gotten much attention. Added a logo and took some baby steps toward the planned design. https://excalidraw.com/#json=THGkyuKCGr_69fFqUrghd,ecIPAvDtoAOajwZ9G4m3sg diff --git a/.changeset/twelve-ducks-reflect.md b/.changeset/twelve-ducks-reflect.md new file mode 100644 index 00000000..88a344b5 --- /dev/null +++ b/.changeset/twelve-ducks-reflect.md @@ -0,0 +1,5 @@ +--- +"counterfact": patch +--- + +fix links to open in VSCode diff --git a/src/client/index.html.hbs b/src/client/index.html.hbs index 666bd045..80bb6f52 100644 --- a/src/client/index.html.hbs +++ b/src/client/index.html.hbs @@ -1,3 +1,9 @@ + + @@ -11,34 +17,154 @@ font-family: Helvetica, Arial, sans-serif; max-width: 800px; margin: 0 auto; + background-color: #333540; + color: #eee; + } + + a { + color: #fff; + } + + h1 { + text-align: center; + } + + table { + width: 100%; + border-collapse: collapse; + } + + th { + color: #aaa; + } + .tilt { + width: 1.5em; + position: relative; + padding-top: 75px; + } + + .tilt > * { + display: block; + position: absolute; + transform: rotate(-90deg); + transform-origin: left; + text-align: center; + bottom: 0; + left: 20px; + + } + + thead { + position: sticky; + top: 0; + background-color: #333540; + } + + th.path > * { + visibility: hidden; + } + + td.path { + font-family: monospace; + font-size: 1.4em; + } + + .path { + text-align: left; + padding-left: 20px; + } + + .method-identifier { + text-align: center; + font-size: 1.5em; + font-weight: bold; + color: #333; + padding: 0 0.5em; } + + tbody tr:hover { + background-color: #0a0a0a; + } + + .path a { + color: #eee; + text-decoration: none; + } + + + .buttons { + position: relative; + display: flex; + justify-content: center; + top: -65px; + left: 96px + + } + .buttons > a { + display: inline-block; + margin: 0 0.5em; + padding: 0.5em 1em; + background-color: #1f1f1f; + border: 1px solid #aaa; + border-radius: 5px; + color: #aaa; + text-decoration: none; + + } + + #paths-container { + margin-top: -35px; + } + -

Counterfact

+ + +

+ Counterfact +

+ + + -

- This server implements the OpenAPI spec at {{openApiPath}}. - You can try it out using your favorite REST client (curl, Postman, etc.) or browse the interactive API documentation in Swagger UI or Rapidoc. +

+ Swagger UI + OpenAPI + Usage Guide + Github +
-

-

- The TypeScript code for each path can be found under {{basePath}}. - Click on a path below to edit its corresponding TypeScript file in VSCode. - For more information, see the usage guide. -

- - +
+ + + + + + + + + + + + + {{#each routes as |route|}} + + + + + + + + + {{/each}} + +
GETPOSTPUTDELETEPATCHPath
{{#if route.methods.GET }}⚪️{{/if}}{{#if route.methods.POST }}⚪️{{/if}}{{#if route.methods.PUT }}⚪️{{/if}}{{#if route.methods.DELETE }}⚪️{{/if}}{{#if route.methods.PATCH }}⚪️{{/if}}{{route.path}}
+
-
-

👋 Thanks for trying Counterfact! Let me know how it goes at pmcelhaney@gmail.com or Github - Patrick

diff --git a/src/server/module-tree.ts b/src/server/module-tree.ts index 1ae4d1fb..5ddb24f7 100644 --- a/src/server/module-tree.ts +++ b/src/server/module-tree.ts @@ -1,5 +1,10 @@ import type { Module } from "./registry.js"; +interface Route { + methods: { [key: string]: string }; + path: string; +} + interface File { isWildcard: boolean; module: Module; @@ -206,8 +211,8 @@ export class ModuleTree { ); } - public get routes(): string[] { - const routes: string[] = []; + public get routes(): Route[] { + const routes: Route[] = []; function traverse(directory: Directory, path: string) { Object.values(directory.directories).forEach((subdirectory) => { @@ -215,7 +220,14 @@ export class ModuleTree { }); Object.values(directory.files).forEach((file) => { - routes.push(`${path}/${file.rawName}`); + const methods: [string, string][] = Object.entries(file.module).map( + ([method, implementation]) => [method, String(implementation)], + ); + + routes.push({ + methods: Object.fromEntries(methods), + path: `${path}/${file.rawName}`, + }); }); } @@ -228,7 +240,7 @@ export class ModuleTree { // eslint-disable-next-line etc/no-assign-mutated-array return routes.sort((first, second) => - stripBrackets(first).localeCompare(stripBrackets(second)), + stripBrackets(first.path).localeCompare(stripBrackets(second.path)), ); } } diff --git a/test/server/module-tree.test.ts b/test/server/module-tree.test.ts index b6cb3446..c644ffe7 100644 --- a/test/server/module-tree.test.ts +++ b/test/server/module-tree.test.ts @@ -106,6 +106,11 @@ it("has all of the routes", () => { add(moduleTree, "/a/b", "b"); add(moduleTree, "/a/{b}", "b"); add(moduleTree, "/c", "c"); - expect(moduleTree.routes).toEqual(["/a", "/a/b", "/a/{b}", "/c"]); + expect(moduleTree.routes.map((route) => route.path)).toEqual([ + "/a", + "/a/b", + "/a/{b}", + "/c", + ]); }); export default ModuleTree; diff --git a/test/server/registry.test.ts b/test/server/registry.test.ts index 7aa9c791..b385b2d0 100644 --- a/test/server/registry.test.ts +++ b/test/server/registry.test.ts @@ -143,7 +143,7 @@ describe("a registry", () => { registry.add("/c/{b}", {}); registry.add("/c/c", {}); - expect(registry.routes).toStrictEqual([ + expect(registry.routes.map((route) => route.path)).toStrictEqual([ "/a", "/a/in/order", "/b",