Skip to content

Commit c591545

Browse files
authored
docs-util: add examples generator for workflows and steps (#10914)
* initial changes * docs-util: generate examples for workflows and steps
1 parent e82645b commit c591545

File tree

17 files changed

+810
-142
lines changed

17 files changed

+810
-142
lines changed

www/apps/resources/components/MDXComponents/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {
55
TypeList,
66
WorkflowDiagram,
77
SourceCodeLink,
8+
CodeTabs,
9+
CodeTab,
810
} from "docs-ui"
911
import { CommerceModuleSections } from "../CommerceModuleSections"
1012

@@ -15,6 +17,8 @@ const MDXComponents: MDXComponentsType = {
1517
WorkflowDiagram,
1618
CommerceModuleSections,
1719
SourceCodeLink,
20+
CodeTabs,
21+
CodeTab,
1822
}
1923

2024
export default MDXComponents

www/utils/packages/docs-generator/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
"type": "module",
1818
"exports": "./dist/index.js",
1919
"dependencies": {
20-
"@faker-js/faker": "^8.4.0",
2120
"@octokit/core": "^5.0.2",
2221
"chalk": "^5.4.1",
2322
"commander": "^11.1.0",
@@ -27,7 +26,6 @@
2726
"openai": "^4.29.1",
2827
"openapi-types": "^12.1.3",
2928
"pluralize": "^8.0.0",
30-
"prettier": "^3.2.4",
3129
"ts-node": "^10.9.1",
3230
"typescript": "^5.6.2",
3331
"utils": "*",

www/utils/packages/docs-generator/src/classes/examples/oas.ts

Lines changed: 10 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1-
import { faker } from "@faker-js/faker"
21
import { OpenAPIV3 } from "openapi-types"
32
import { OasArea } from "../kinds/oas.js"
43
import { CodeSample } from "../../types/index.js"
5-
import { capitalize, kebabToCamel, wordsToCamel, wordsToKebab } from "utils"
4+
import {
5+
capitalize,
6+
getFakeStrValue,
7+
kebabToCamel,
8+
wordsToCamel,
9+
wordsToKebab,
10+
} from "utils"
611
import { API_ROUTE_PARAM_REGEX } from "../../constants.js"
712

813
type CodeSampleData = Omit<CodeSample, "source">
@@ -274,7 +279,7 @@ class OasExamplesGenerator {
274279
? this.getSchemaRequiredData(
275280
typedChildProp as OpenAPIV3.SchemaObject
276281
)
277-
: this.getFakeValue({
282+
: getFakeStrValue({
278283
name: childName,
279284
type: typedChildProp.type,
280285
format: typedChildProp.format,
@@ -296,7 +301,7 @@ class OasExamplesGenerator {
296301
? this.getSchemaRequiredData(
297302
property.items as OpenAPIV3.SchemaObject
298303
)
299-
: this.getFakeValue({
304+
: getFakeStrValue({
300305
name: propertyName,
301306
type: propertyItems.type,
302307
format: propertyItems.format,
@@ -305,7 +310,7 @@ class OasExamplesGenerator {
305310
}
306311
} else if (property.type) {
307312
// retrieve fake value for all other types
308-
value = this.getFakeValue({
313+
value = getFakeStrValue({
309314
name: propertyName,
310315
type: property.type,
311316
format: property.format,
@@ -320,64 +325,6 @@ class OasExamplesGenerator {
320325

321326
return data
322327
}
323-
324-
/**
325-
* Retrieve the fake value of a property. The value is used in examples.
326-
*
327-
* @param param0 - The property's details
328-
* @returns The fake value
329-
*/
330-
getFakeValue({
331-
name,
332-
type,
333-
format,
334-
}: {
335-
/**
336-
* The name of the property. It can help when generating the fake value.
337-
* For example, if the name is `id`, the fake value generated will be of the format `id_<randomstring>`.
338-
*/
339-
name: string
340-
/**
341-
* The type of the property.
342-
*/
343-
type: OpenAPIV3.NonArraySchemaObjectType | "array"
344-
/**
345-
* The OAS format of the property. For example, `date-time`.
346-
*/
347-
format?: string
348-
}): unknown {
349-
let value: unknown
350-
351-
switch (true) {
352-
case type === "string" && format === "date-time":
353-
value = faker.date.future().toISOString()
354-
break
355-
case type === "boolean":
356-
value = faker.datatype.boolean()
357-
break
358-
case type === "integer" || type === "number":
359-
value = faker.number.int()
360-
break
361-
case type === "array":
362-
value = []
363-
break
364-
case type === "string":
365-
value = faker.helpers
366-
.mustache(`{{${name}}}`, {
367-
id: () =>
368-
`id_${faker.string.alphanumeric({
369-
length: { min: 10, max: 20 },
370-
})}`,
371-
name: () => faker.person.firstName(),
372-
email: () => faker.internet.email(),
373-
password: () => faker.internet.password({ length: 8 }),
374-
currency: () => faker.finance.currencyCode(),
375-
})
376-
.replace(`{{${name}}}`, "{value}")
377-
}
378-
379-
return value !== undefined ? value : "{value}"
380-
}
381328
}
382329

383330
export default OasExamplesGenerator

www/utils/packages/docs-generator/src/classes/helpers/formatter.ts

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import path from "path"
44
import dirname from "../../utils/dirname.js"
55
import { minimatch } from "minimatch"
66
import { existsSync } from "fs"
7-
import * as prettier from "prettier"
87
import getRelativePaths from "../../utils/get-relative-paths.js"
8+
import { formatWithPrettier } from "utils"
99

1010
/**
1111
* A class used to apply formatting to files using ESLint and other formatting options.
@@ -174,10 +174,7 @@ class Formatter {
174174
content: string,
175175
fileName: string
176176
): Promise<string> {
177-
const prettifiedContent = await this.formatStrWithPrettier(
178-
content,
179-
fileName
180-
)
177+
const prettifiedContent = await formatWithPrettier(content, fileName)
181178
const relevantConfig = await this.getESLintOverridesConfigForFile(fileName)
182179

183180
const eslint = new ESLint({
@@ -203,27 +200,6 @@ class Formatter {
203200
return newContent
204201
}
205202

206-
/**
207-
* Format a file's content with prettier.
208-
*
209-
* @param content - The content to format.
210-
* @param fileName - The name of the file the content belongs to.
211-
* @returns The formatted content
212-
*/
213-
async formatStrWithPrettier(
214-
content: string,
215-
fileName: string
216-
): Promise<string> {
217-
// load config of the file
218-
const prettierConfig = (await prettier.resolveConfig(fileName)) || undefined
219-
220-
if (prettierConfig && !prettierConfig.parser) {
221-
prettierConfig.parser = "babel-ts"
222-
}
223-
224-
return await prettier.format(content, prettierConfig)
225-
}
226-
227203
/**
228204
* Applies all formatting types to a string.
229205
*

www/utils/packages/typedoc-plugin-markdown-medusa/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"typedoc": "0.27.x"
2323
},
2424
"devDependencies": {
25+
"@types/js-beautify": "^1.14.3",
2526
"@types/node": "^20.12.10",
2627
"copyfiles": "^2.4.1",
2728
"typedoc": "^0.27.5",
@@ -36,6 +37,7 @@
3637
],
3738
"dependencies": {
3839
"handlebars": "^4.7.8",
40+
"js-beautify": "^1.15.1",
3941
"utils": "*"
4042
}
4143
}

www/utils/packages/typedoc-plugin-markdown-medusa/src/render-utils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ import ifMemberShowTitleHelper from "./resources/helpers/if-member-show-title.js
7878
import signatureCommentHelper from "./resources/helpers/signature-comment.js"
7979
import versionHelper from "./resources/helpers/version.js"
8080
import sourceCodeLinkHelper from "./resources/helpers/source-code-link.js"
81+
import workflowExamplesHelper from "./resources/helpers/workflow-examples.js"
82+
import stepExamplesHelper from "./resources/helpers/step-examples.js"
8183
import { MarkdownTheme } from "./theme.js"
8284
import { getDirname } from "utils"
8385

@@ -187,4 +189,6 @@ export function registerHelpers(theme: MarkdownTheme) {
187189
signatureCommentHelper()
188190
versionHelper()
189191
sourceCodeLinkHelper()
192+
workflowExamplesHelper()
193+
stepExamplesHelper()
190194
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import Handlebars from "handlebars"
2+
import { DeclarationReflection, SignatureReflection } from "typedoc"
3+
import { getReflectionTypeFakeValueStr, getStepInputType } from "utils"
4+
import pkg from "js-beautify"
5+
6+
const { js_beautify } = pkg
7+
8+
export default function () {
9+
Handlebars.registerHelper(
10+
"stepExamples",
11+
function (this: SignatureReflection): string {
12+
const stepReflection = this.parent
13+
14+
const exampleTags = stepReflection.comment?.blockTags.filter(
15+
(tag) => tag.tag === "@example"
16+
)
17+
18+
if (exampleTags?.length) {
19+
return Handlebars.helpers.example(stepReflection)
20+
}
21+
22+
return generateStepExample(stepReflection)
23+
}
24+
)
25+
}
26+
27+
function generateStepExample(stepReflection: DeclarationReflection): string {
28+
if (!stepReflection.signatures?.length) {
29+
return ""
30+
}
31+
const inputType = getStepInputType(stepReflection.signatures[0])
32+
const inputStr = inputType
33+
? `${getReflectionTypeFakeValueStr({
34+
reflectionType: inputType,
35+
name: "",
36+
})}`
37+
: ""
38+
39+
// generate example
40+
return `
41+
\`\`\`ts title="src/workflows/my-workflow.ts"
42+
${js_beautify(
43+
`import { createWorkflow } from "@medusajs/framework/workflows-sdk"
44+
import { ${stepReflection.name} } from "@medusajs/medusa/core-flows"
45+
46+
const myWorkflow = createWorkflow(
47+
"my-workflow",
48+
() => {
49+
const data = ${stepReflection.name}(${inputStr})
50+
}
51+
)`,
52+
{
53+
indent_size: 2,
54+
brace_style: "preserve-inline",
55+
wrap_line_length: 80,
56+
}
57+
)}
58+
\`\`\`
59+
`
60+
}

0 commit comments

Comments
 (0)