Skip to content

Commit aa22328

Browse files
authored
feat: add example code snippet to README (#809)
* refactor: move getExampleCodeSnippet to its own file there's probably an opportunity here to consolidate stuff since we call this twice * feat: add example usage to README * test: update fixtures * fix: lint * refactor: move getExampleCodeSnippet to class function * docs: add JSDocs for CodeGenerator properties
1 parent 0dfd14c commit aa22328

File tree

9 files changed

+124
-20
lines changed

9 files changed

+124
-20
lines changed

packages/api/src/codegen/codegenerator.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,43 @@ import { findLicense } from 'license';
88
import { PACKAGE_NAME, PACKAGE_VERSION } from '../packageInfo.js';
99

1010
export default abstract class CodeGenerator {
11+
/** The associated API definition */
1112
spec: Oas;
1213

14+
/**
15+
* The path to the API definion (might be a local path, a URL, or an API registry identifier)
16+
* @example https://raw.githubusercontent.com/readmeio/oas-examples/main/3.0/json/petstore-simple.json
17+
* @example @petstore/v1.0#n6kvf10vakpemvplx
18+
* @example ./petstore.json
19+
*/
1320
specPath: string;
1421

22+
/**
23+
* The user-specified identifier for the SDK,
24+
* used as the directory name in the `.api/apis` directory
25+
* where the SDK source code is located.
26+
*/
1527
identifier: string;
1628

29+
/** The user agent which is set for all outgoing fetch requests */
1730
userAgent: string;
1831

32+
/**
33+
* The license associated with the SDK.
34+
* This is extrapolated from the API definition file.
35+
*/
1936
spdxLicense?: string;
2037

38+
/**
39+
* Contact info for the API and/or SDK author in case users need support.
40+
* This is extrapolated from the API definition file.
41+
*/
2142
apiContact: { name?: string; url?: string } = {};
2243

44+
/**
45+
* An object containing any downstream packages that are required
46+
* for building/executing the SDK.
47+
*/
2348
requiredPackages!: Record<
2449
string,
2550
{
@@ -30,6 +55,11 @@ export default abstract class CodeGenerator {
3055
}
3156
>;
3257

58+
/**
59+
* An example code snippet that a user can run to get started with the SDK.
60+
*/
61+
exampleCodeSnippet?: string | false;
62+
3363
constructor(spec: Oas, specPath: string, identifier: string) {
3464
this.spec = spec;
3565
this.specPath = specPath;
@@ -112,6 +142,8 @@ export default abstract class CodeGenerator {
112142

113143
abstract compile(storage: Storage, opts?: InstallerOptions): Promise<void>;
114144

145+
abstract getExampleCodeSnippet(): Promise<string | false>;
146+
115147
hasRequiredPackages() {
116148
return Boolean(Object.keys(this.requiredPackages));
117149
}

packages/api/src/codegen/languages/typescript/index.ts

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import setWith from 'lodash.setwith';
2626
import semver from 'semver';
2727
import { IndentationText, Project, QuoteKind, ScriptTarget, VariableDeclarationKind } from 'ts-morph';
2828

29+
import { buildCodeSnippetForOperation, getSuggestedOperation } from '../../../lib/suggestedOperations.js';
2930
import logger from '../../../logger.js';
3031
import { PACKAGE_VERSION } from '../../../packageInfo.js';
3132
import Storage from '../../../storage.js';
@@ -213,7 +214,7 @@ export default class TSGenerator extends CodeGenerator {
213214
this.createGitIgnore();
214215
this.createPackageJSON();
215216
this.createTSConfig();
216-
this.createREADME();
217+
await this.createREADME();
217218

218219
if (Object.keys(this.schemas).length) {
219220
this.createSchemasFile(srcDirectory);
@@ -260,6 +261,23 @@ export default class TSGenerator extends CodeGenerator {
260261
].reduce((prev, next) => Object.assign(prev, next));
261262
}
262263

264+
async getExampleCodeSnippet() {
265+
// if we've already built the code snippet, return it instead of re-building it!
266+
if (typeof this.exampleCodeSnippet !== 'undefined') {
267+
return this.exampleCodeSnippet;
268+
}
269+
270+
const operation = getSuggestedOperation(this.spec);
271+
if (!operation) {
272+
this.exampleCodeSnippet = false;
273+
return false;
274+
}
275+
276+
const snippet = await buildCodeSnippetForOperation(this.spec, operation, { identifier: this.identifier });
277+
this.exampleCodeSnippet = snippet;
278+
return snippet;
279+
}
280+
263281
/**
264282
* Create our main SDK source file.
265283
*
@@ -641,15 +659,28 @@ dist/
641659
* Create a placeholder `README.md` file in the repository, with information on how to use/administer the SDK.
642660
*
643661
*/
644-
createREADME() {
662+
async createREADME() {
645663
let createdAt = new Date().toISOString();
646664
const currentAPI = Storage.getLockfile().apis.find(api => api.identifier === this.identifier);
647665
if (currentAPI) createdAt = currentAPI.createdAt;
666+
667+
let exampleUsage = 'Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀';
668+
const exampleSnippet = await this.getExampleCodeSnippet();
669+
if (exampleSnippet) {
670+
exampleUsage = `
671+
## Example Usage 🚀
672+
673+
\`\`\`js
674+
${exampleSnippet}
675+
\`\`\`
676+
`.trim();
677+
}
678+
648679
const file = `# \`@api/${this.identifier}\`
649680
650681
This SDK was autogenerated by the [\`api\` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
651682
652-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
683+
${exampleUsage}
653684
654685
<!---
655686

packages/api/src/commands/install.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import uslug from 'uslug';
1111
import { SupportedLanguages, codegenFactory } from '../codegen/factory.js';
1212
import Fetcher from '../fetcher.js';
1313
import promptTerminal from '../lib/prompt.js';
14-
import { buildCodeSnippetForOperation, getSuggestedOperation } from '../lib/suggestedOperations.js';
1514
import logger, { oraOptions } from '../logger.js';
1615
import Storage from '../storage.js';
1716

@@ -71,15 +70,6 @@ async function getIdentifier(oas: Oas, uri: string, options: Options) {
7170
return identifier;
7271
}
7372

74-
async function getExampleCodeSnippet(oas: Oas, identifier: string) {
75-
const operation = getSuggestedOperation(oas);
76-
if (!operation) {
77-
return false;
78-
}
79-
80-
return buildCodeSnippetForOperation(oas, operation, { identifier });
81-
}
82-
8373
// @todo log logs to `.api/.logs` and have `.logs` ignored
8474
const cmd = new Command();
8575
cmd
@@ -213,7 +203,7 @@ cmd
213203
)} package.`,
214204
);
215205

216-
const exampleSnippet = await getExampleCodeSnippet(oas, identifier);
206+
const exampleSnippet = await generator.getExampleCodeSnippet();
217207
if (exampleSnippet) {
218208
logger('');
219209
logger(chalk.bold("👇 Here's an example code snippet you can try out 👇"));

packages/test-utils/sdks/alby/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import alby from '@api/alby';
9+
10+
alby.auth('token');
11+
alby.getMe()
12+
.then(({ data }) => console.log(data))
13+
.catch(err => console.error(err));
14+
```
615

716
<!---
817

packages/test-utils/sdks/metrotransit/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import metrotransit from '@api/metrotransit';
9+
10+
metrotransit.getNextripAgencies()
11+
.then(({ data }) => console.log(data))
12+
.catch(err => console.error(err));
13+
```
614

715
<!---
816

packages/test-utils/sdks/operationid-quirks/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import operationidQuirks from '@api/operationid-quirks';
9+
10+
operationidQuirks.quirky_OperationId_string()
11+
.then(({ data }) => console.log(data))
12+
.catch(err => console.error(err));
13+
```
614

715
<!---
816

packages/test-utils/sdks/petstore/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import petstore from '@api/petstore';
9+
10+
petstore.auth('token');
11+
petstore.getInventory()
12+
.then(({ data }) => console.log(data))
13+
.catch(err => console.error(err));
14+
```
615

716
<!---
817

packages/test-utils/sdks/readme/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import readme from '@api/readme';
9+
10+
readme.auth('username', 'password');
11+
readme.getAPISpecification()
12+
.then(({ data }) => console.log(data))
13+
.catch(err => console.error(err));
14+
```
615

716
<!---
817

packages/test-utils/sdks/star-trek/README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22

33
This SDK was autogenerated by the [`api` SDK generator](https://api.readme.dev), powered by [ReadMe](https://readme.com) 🦉
44

5-
Add SDK setup information and usage examples here so your users get started in a jiffy! 🚀
5+
## Example Usage 🚀
6+
7+
```js
8+
import starTrek from '@api/star-trek';
9+
10+
starTrek.getAnimalSearch()
11+
.then(({ data }) => console.log(data))
12+
.catch(err => console.error(err));
13+
```
614

715
<!---
816

0 commit comments

Comments
 (0)