-
Notifications
You must be signed in to change notification settings - Fork 0
feat: add tryitnow for usage snippets through code samples API #20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
595e165
8136687
9f84e59
cbbce85
8a62eb9
9ddf2fb
914c786
3d068e5
811f645
67ef515
9d07a43
232a468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -26,6 +26,7 @@ const CONFIG_FILE_NAMES = [ | |||
| ]; | ||||
|
|
||||
| const args = arg({ | ||||
| "--npm-package-name": String, | ||||
| "--help": Boolean, | ||||
| "--config": String, | ||||
| "--spec": String, | ||||
|
|
@@ -37,6 +38,7 @@ const args = arg({ | |||
| "-p": "--page-out-dir", | ||||
| "-o": "--component-out-dir", | ||||
| "-f": "--framework", | ||||
| "-n": "--npm-package-name", | ||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This sets the name of the npm package downloaded later in TryItNow
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Let's leave this flag out. Only about half of the settings are exposed by the CLI anyways, and I've been thinking about removing all but |
||||
| }); | ||||
|
|
||||
| function printHelp() { | ||||
|
|
@@ -48,7 +50,8 @@ Options: | |||
| --spec, -s Path to OpenAPI spec | ||||
| --page-out-dir, -p Output directory for page contents | ||||
| --component-out-dir, -o Output directory for component contents | ||||
| --framework, -f Framework to use (docusaurus, nextra)`); | ||||
| --framework, -f Framework to use (docusaurus, nextra) | ||||
| --npm-package-name, -n npm package to use for the SDK code snippets`); | ||||
| } | ||||
|
|
||||
| if (args["--help"]) { | ||||
|
|
||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| import { basename } from "node:path"; | ||
|
|
||
| import type { Chunk, OperationChunk } from "../types/chunk.ts"; | ||
| import type { | ||
| CodeSamplesResponse, | ||
| CodeSnippet, | ||
| ErrorResponse, | ||
| } from "../types/codeSnippet.ts"; | ||
| import { getSettings } from "./settings.ts"; | ||
|
|
||
| const CODE_SNIPPETS_API_URL = "http://localhost:35290"; | ||
|
|
||
| export type DocsCodeSnippets = Record<OperationChunk["id"], CodeSnippet>; | ||
|
|
||
| export const generateDocsCodeSnippets = async ( | ||
| docsData: Map<string, Chunk>, | ||
| specContents: string | ||
| ): Promise<DocsCodeSnippets> => { | ||
| const { spec, tryItNow } = getSettings(); | ||
| if (!tryItNow) { | ||
| return {}; | ||
| } | ||
|
|
||
| const docsCodeSnippets: DocsCodeSnippets = {}; | ||
|
|
||
| const specFilename = basename(spec); | ||
| // create a by operationId map of the operation chunks | ||
| const operationChunksByOperationId = new Map<string, OperationChunk>(); | ||
| for (const chunk of docsData.values()) { | ||
| if (chunk.chunkType === "operation") { | ||
| operationChunksByOperationId.set(chunk.chunkData.operationId, chunk); | ||
| } | ||
| } | ||
| try { | ||
| const formData = new FormData(); | ||
|
|
||
| const blob = new Blob([specContents]); | ||
| formData.append("language", "typescript"); | ||
| formData.append("schema_file", blob, specFilename); | ||
| formData.append("package_name", tryItNow.npmPackageName); | ||
| formData.append("sdk_class_name", tryItNow.sdkClassName); | ||
|
|
||
| const res = await fetch(`${CODE_SNIPPETS_API_URL}/v1/code_sample/preview`, { | ||
| method: "POST", | ||
| body: formData, | ||
| }); | ||
|
|
||
| const json = (await res.json()) as unknown; | ||
|
|
||
| if (!res.ok) { | ||
| const error = json as ErrorResponse; | ||
| throw new Error(`Failed to generate code sample: ${error.message}`); | ||
| } | ||
| const codeSnippets = (json as CodeSamplesResponse).snippets; | ||
|
|
||
| for (const snippet of codeSnippets) { | ||
| const chunk = operationChunksByOperationId.get(snippet.operationId); | ||
| // only set the usage snippet if the operation id exists in the spec | ||
| if (chunk) { | ||
| docsCodeSnippets[chunk.id] = snippet; | ||
| } | ||
| } | ||
| } catch (error) { | ||
| console.error("There was an error generating code snippets", error); | ||
| return {}; | ||
| } | ||
| return docsCodeSnippets; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ import { fileURLToPath } from "node:url"; | |
| import { unzipSync } from "node:zlib"; | ||
|
|
||
| import type { Chunk } from "../../types/chunk.ts"; | ||
|
|
||
| declare class Go { | ||
| argv: string[]; | ||
| env: { [envKey: string]: string }; | ||
|
|
@@ -32,8 +31,10 @@ export async function getDocsData( | |
| const result = await WebAssembly.instantiate(wasmBuffer, go.importObject); | ||
| void go.run(result.instance); | ||
| const serializedDocsData = await SerializeDocsData(specContents); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh actually hang on, I just noticed we're now calling Instead, let's create a new top-level group of operations at |
||
|
|
||
| const docsData = (JSON.parse(serializedDocsData) as string[]).map( | ||
| (chunk) => JSON.parse(chunk) as Chunk | ||
| ); | ||
|
|
||
| return new Map(docsData.map((chunk) => [chunk.id, chunk])); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| export type CodeSnippet = { | ||
| operationId: string; | ||
| language: string; | ||
| code: string; | ||
| }; | ||
|
|
||
| export type CodeSamplesResponse = { | ||
| snippets: CodeSnippet[]; | ||
| }; | ||
|
|
||
| export type ErrorResponse = { | ||
| message: string; | ||
| statusCode: number; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the default to dark for now due to an issue with the text color not changing when going from "light" mode to "dark" mode.