Skip to content

Commit

Permalink
Merge pull request #686 from pmcelhaney/robot-prompt
Browse files Browse the repository at this point in the history
add a little spice to the CLI
  • Loading branch information
pmcelhaney committed Dec 20, 2023
2 parents 2c38cc9 + 2a69409 commit a042df6
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-crabs-grab.md
@@ -0,0 +1,5 @@
---
"counterfact": minor
---

added a 🤖 to the prompt to make it look more distinguished
5 changes: 5 additions & 0 deletions .changeset/pretty-socks-attend.md
@@ -0,0 +1,5 @@
---
"counterfact": minor
---

just for fun, the tagline when the CLI starts is different every time you run it
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -31,7 +31,7 @@ Like your favorite pair of sweatpants, Counterfact is lightweight, flexible, and
- **Instant Gratification:** If you have Node installed and an OpenAPI document handy, you're [one command away](./docs/quick-start.md) from a dependency-free workflow.
- **Flexibility at Your Fingertips:** Effortlessly toggle between mock and real services, change behavior without losing state, simulate complex use cases and error conditions, etc.
- **Dev Tools on the server:** That's what it feels like. Change code in a running server and see the effect immediately. It even has a REPL, like the JS console in your browser.
- **High code, low effort:** Wouldn't you love the simplicity of a "low code" / "no code" tool without giving up the flexibility and power you get from knowing how to write TypeScript? Inconceivable, you say? [Don't knock it 'til youy try it](./docs/quick-start.md).
- **High code, low effort:** Wouldn't you love the simplicity of a "low code" / "no code" tool without giving up the flexibility and power you get from knowing how to write TypeScript? Inconceivable, you say? [Don't knock it 'til you try it](./docs/quick-start.md).
- **Plays well with others:** Counterfact works with anything that depends on a REST API, including web apps, mobile apps, desktop apps, and microservices. It requires zero changes to your front-end framework or code.

## 10 Second Quick Start
Expand Down
10 changes: 9 additions & 1 deletion bin/counterfact.js
Expand Up @@ -8,13 +8,21 @@ import open from "open";

import { migrate } from "../dist/migrations/0.27.js";
import { counterfact } from "../dist/server/app.js";
import { taglines } from "../dist/server/taglines.js";

const DEFAULT_PORT = 3100;

const debug = createDebug("counterfact:bin:counterfact");

debug("running ./bin/counterfact.js");

function padTagLine(tagLine) {
const headerLength = 51;
const padding = " ".repeat((headerLength - tagLine.length) / 2);

return `${padding}${tagLine}`;
}

// eslint-disable-next-line max-statements
async function main(source, destination) {
debug("executing the main function");
Expand Down Expand Up @@ -60,7 +68,7 @@ async function main(source, destination) {
const introduction = [
"____ ____ _ _ _ _ ___ ____ ____ ____ ____ ____ ___",
"|___ [__] |__| |\\| | |=== |--< |--- |--| |___ | ",
" High code, low effort mock REST APIs",
padTagLine(taglines[Math.floor(Math.random() * taglines.length)]),
"",
`| API Base URL ==> ${url}`,
`| Admin Console ==> ${guiUrl}`,
Expand Down
18 changes: 9 additions & 9 deletions docs/usage.md
Expand Up @@ -20,7 +20,7 @@ npm i -g ts-node
npx counterfact@latest https://petstore3.swagger.io/api/v3/openapi.json api --open
```

It will generate TypeScript code for the Swagger Pet Store, start a server, and `--open` a browser running Swagger UI. We're using the pet store example because it's well known and convenient. If you have your own OpenAPI document handy, you can point to that instead. You can also change `api` to wherever you'd like to output the code.
This will generate TypeScript code for the Swagger Pet Store, start a server, and `--open` a browser that runs Swagger UI. We're using the pet store example because it's well known and convenient. If you have your own OpenAPI document handy, you can point to that instead. You can also change `api` to wherever you'd like to output the code.

<details>

Expand Down Expand Up @@ -73,13 +73,13 @@ export const POST: HTTP_POST = ($) => {
};
```

The file's path corresponds to the endpoint's URL. Each of the exported functions implements an HTTP request method (GET, POST, PUT, etc.). Each of these functions takes one argument -- `$` -- which is used to access request information, build a response, and interact with the server's state.
The TypeScript file's path corresponds to the endpoint's URL. Each of the exported functions implements an HTTP request method (GET, POST, PUT, etc.). Each of these functions takes one argument -- `$` -- which is used to access request information, build a response, and interact with the server's state.

> If you're familiar with Express, `$` is sort of a combination of `req` and `res` with type safety and extra super powers.
### The `$.response` object

The `$.response` object is used to build a valid response for the URL and request method. It's designed to work with your IDE's autocomplete feature and help you build a valid response without consulting the docs. Try typing `$.response.` in your IDE. You should see a list of numbers corresponding to HTTP response codes (200, 404, etc). Select one and then type another `.`. At this point the IDE should present you with one or more of the following methods.
The `$.response` object is used to build a valid response for the URL and request method. This object is designed to work with your IDE's autocomplete feature and help you build a valid response without consulting the docs. Try typing `$.response.` in your IDE. You should see a list of numbers corresponding to HTTP response codes (200, 404, etc). Select one and then type another `.`. At this point the IDE should present you with one or more of the following methods.

- `.random()` returns random data, using `examples` and other metadata from the OpenAPI document.
- `.header(name, value)` adds a response header. It will only show up when a response header is expected and you haven't already provided it.
Expand Down Expand Up @@ -193,10 +193,10 @@ ____ ____ _ _ _ _ ___ ____ ____ ____ ____ ____ ___
Starting REPL, type .help for more info
>
🤖>
```

At the `> ` prompt, you can enter JavaScript code to interact with the live [context object](#context-object). For example, here's a quick way to add a pet to the store.
At the `🤖>` prompt, you can enter JavaScript code to interact with the live [context object](#context-object). For example, here's a quick way to add a pet to the store.

```js
context.addPet({ name: "Fluffy", photoUrls: [] });
Expand All @@ -214,7 +214,7 @@ Or get a list of pets whose names start with "F"
context.pets.find((pet) => pet.name.startsWith("F"));
```

Using the REPL is a lot faster (and more fun) than wrangling config files and SQL and whatever else it takes to a real back end into the states you need to test your UI flows.
Using the REPL is a lot faster (and more fun) than wrangling config files and SQL and whatever else it takes to get a real back end into the states you need to test your UI flows.

## Proxy Peek-a-boo 🫣

Expand All @@ -229,7 +229,7 @@ To proxy an individual endpoint, you can use the `$.proxy()` function.
};
```

To toggle globally between Counterfact and a proxy server, pass `--proxy-url <url>` in he CLI.
To toggle globally between Counterfact and a proxy server, pass `--proxy-url <url>` in the CLI.

Then type `.proxy on` / `.proxy off` in the REPL to turn it on and off. When the global proxy is on, all requests will be sent to the proxy URL instead of the mock implementations in Counterfact.

Expand All @@ -253,9 +253,9 @@ More features are coming soon:

- Integrate Counterfact into your workflow (Express, Koa, Webpack Dev Server, etc.)
- Use Counterfact in your automated tests
- Record API calls while testing the front end manually and reuse those calls in automated tests (ala [Playwright](https://playwright.dev/))
- Record API calls while testing the front end manually and reuse those calls in automated tests (à la [Playwright](https://playwright.dev/))
- Use [HAR](https://toolbox.googleapps.com/apps/har_analyzer/) files to recreate scenarios / bugs encountered by real users
- Migration scripts to seed the server with test data or get it into a particular state, ala [Playwright](https://playwright.dev/).
- Migration scripts to seed the server with test data or get it into a particular state, à la [Playwright](https://playwright.dev/).
- Toggle between fake and real APIs, either the whole server or individual routes, at runtime, with a GUI

Please send feedback / questions to pmcelhaney@gmail.com or [create a new issue](https://github.com/pmcelhaney/counterfact/issues/new).
Expand Down
2 changes: 1 addition & 1 deletion src/server/repl.ts
Expand Up @@ -4,7 +4,7 @@ import type { Config } from "./config.js";
import type { ContextRegistry } from "./context-registry.js";

export function startRepl(contextRegistry: ContextRegistry, config: Config) {
const replServer = repl.start("> ");
const replServer = repl.start("🤖> ");

replServer.defineCommand("counterfact", {
action() {
Expand Down
51 changes: 51 additions & 0 deletions src/server/taglines.ts
@@ -0,0 +1,51 @@
export const taglines = [
"high code, low effort mock REST APIs",
"Are you mocking me?",
"stop, mock, and roll",
"fake it till you make it",
"things are about to get real",
"when opportunity mocks",
"your time is very important to us",
"This is an HTTP joke. GET it?",
"the REPL alliance ",
"there is no spoon",
"what you say is what you get",
"pay no attention to man behind the curtain",
"at your service",
"I'm afraid I can do that, Dave",
"Hey! I'm mockin' here!",
"all mock no friction",
"a cubic zirconia in the rough",
"maybe she’s born with it…",
"made on an Apple in Carolina",
"a Three Kids in a Trench Coat production ",
"a little sleight of &&",
"there’s no place like localhost",
"ny favorite book is Charlatan’s Web",
"fact follows fiction",
"your lovely assistant",
"my other server’s a Kubernetes cluster ",
"you wrote it here first",
"here lies “waiting on back-end”; REST in peace",
"your front-end’s REST friend",
"first past the post",
"🎶 mockin' the casbah 🎶",
"you ready to mock and roll?",
"I also do weddings and bar mocks-vahs",
"I’m thinking about going into fake estate",
"I bet you’re real fun at mocktail parties",
"Eat. Sleep. Mock. Repeat.",
"hand over the cache and no one gets hurt",
"Storybook for the back-end",
"you are now free to mock about the cabin",
"close enough for government work",
"an API in hand is worth two in the cloud",
"where we're going, we don't need wifi",
"paper prototyping the back-end",
"the cloud natives are restless",
];

// rejected because they don't fit
// "🎶 mamas don’t let your babies grow up to be front end devs 🎶",
// "yesterday: mockin’, today: mockin’, impediments: none",
//

0 comments on commit a042df6

Please sign in to comment.