diff --git a/docs-util/packages/typedoc-config/_base.js b/docs-util/packages/typedoc-config/_base.js
index ee874baf83..aafaa94e69 100644
--- a/docs-util/packages/typedoc-config/_base.js
+++ b/docs-util/packages/typedoc-config/_base.js
@@ -14,6 +14,7 @@ module.exports = {
),
pluginsResolvePath: path.join(pathPrefix, "www"),
exclude: [path.join(pathPrefix, "node_modules/**")],
+ excludeInternal: true,
// Uncomment this when debugging
// showConfig: true,
}
diff --git a/docs-util/packages/typedoc-config/extended-tsconfig/tsdoc.json b/docs-util/packages/typedoc-config/extended-tsconfig/tsdoc.json
index 06df94198f..e7fc481823 100644
--- a/docs-util/packages/typedoc-config/extended-tsconfig/tsdoc.json
+++ b/docs-util/packages/typedoc-config/extended-tsconfig/tsdoc.json
@@ -17,6 +17,14 @@
{
"tagName": "@apiIgnore",
"syntaxKind": "modifier"
+ },
+ {
+ "tagName": "@mainSignature",
+ "syntaxKind": "modifier"
+ },
+ {
+ "tagName": "@docHideSignature",
+ "syntaxKind": "modifier"
}
]
}
\ No newline at end of file
diff --git a/docs-util/packages/typedoc-config/extended-tsconfig/workflows.json b/docs-util/packages/typedoc-config/extended-tsconfig/workflows.json
new file mode 100644
index 0000000000..35d3b4171b
--- /dev/null
+++ b/docs-util/packages/typedoc-config/extended-tsconfig/workflows.json
@@ -0,0 +1,6 @@
+{
+ "$schema": "http://json.schemastore.org/tsconfig",
+ "extends": [
+ "../../../../packages/workflows/tsconfig.json"
+ ]
+}
\ No newline at end of file
diff --git a/docs-util/packages/typedoc-config/workflows.js b/docs-util/packages/typedoc-config/workflows.js
new file mode 100644
index 0000000000..199ea0b5db
--- /dev/null
+++ b/docs-util/packages/typedoc-config/workflows.js
@@ -0,0 +1,75 @@
+/* eslint-disable @typescript-eslint/no-var-requires */
+const path = require("path")
+const globalTypedocOptions = require("./_base")
+
+const pathPrefix = path.join(__dirname, "..", "..", "..")
+
+module.exports = {
+ ...globalTypedocOptions,
+ entryPoints: [
+ path.join(pathPrefix, "packages/workflows/src/utils/composer/index.ts"),
+ ],
+ out: [path.join(pathPrefix, "www/apps/docs/content/references/workflows")],
+ tsconfig: path.join(__dirname, "extended-tsconfig", "workflows.json"),
+ name: "Workflows Reference",
+ indexTitle: "Workflows Reference",
+ entryDocument: "index.mdx",
+ hideInPageTOC: true,
+ hideBreadcrumbs: true,
+ formatting: {
+ "*": {
+ expandMembers: true,
+ showCommentsAsHeader: true,
+ sections: {
+ member_sources_definedIn: false,
+ reflection_hierarchy: false,
+ member_sources_inheritedFrom: false,
+ member_sources_implementationOf: false,
+ reflection_implementedBy: false,
+ member_signature_sources: false,
+ reflection_callable: false,
+ reflection_indexable: false,
+ member_signature_title: false,
+ member_signature_returns: false,
+ member_getterSetter: false,
+ },
+ parameterStyle: "component",
+ parameterComponent: "ParameterTypes",
+ mdxImports: [
+ `import ParameterTypes from "@site/src/components/ParameterTypes"`,
+ ],
+ frontmatterData: {
+ displayed_sidebar: "workflowsSidebar",
+ },
+ },
+ "index\\.mdx": {
+ reflectionGroups: {
+ Namespaces: false,
+ Enumerations: false,
+ Classes: false,
+ Interfaces: false,
+ "Type Aliases": false,
+ Variables: false,
+ "Enumeration Members": false,
+ },
+ },
+ functions: {
+ maxLevel: 1,
+ },
+ "classes/StepResponse": {
+ reflectionGroups: {
+ Properties: false,
+ },
+ },
+ transform: {
+ reflectionGroups: {
+ "Type Parameters": false,
+ },
+ },
+ },
+ objectLiteralTypeDeclarationStyle: "component",
+ mdxOutput: true,
+ maxLevel: 2,
+ allReflectionsHaveOwnDocument: true,
+ excludeExternals: true,
+}
diff --git a/docs-util/packages/typedoc-plugin-custom/src/index.ts b/docs-util/packages/typedoc-plugin-custom/src/index.ts
index 7c4bf33481..8525ebdd94 100644
--- a/docs-util/packages/typedoc-plugin-custom/src/index.ts
+++ b/docs-util/packages/typedoc-plugin-custom/src/index.ts
@@ -4,6 +4,7 @@ import { load as frontmatterPlugin } from "./frontmatter-plugin"
import { load as parseOasSchemaPlugin } from "./parse-oas-schema-plugin"
import { load as apiIgnorePlugin } from "./api-ignore"
import { load as eslintExamplePlugin } from "./eslint-example"
+import { load as signatureModifierPlugin } from "./signature-modifier"
export function load(app: Application) {
resolveReferencesPluginLoad(app)
@@ -11,4 +12,5 @@ export function load(app: Application) {
parseOasSchemaPlugin(app)
apiIgnorePlugin(app)
eslintExamplePlugin(app)
+ signatureModifierPlugin(app)
}
diff --git a/docs-util/packages/typedoc-plugin-custom/src/signature-modifier.ts b/docs-util/packages/typedoc-plugin-custom/src/signature-modifier.ts
new file mode 100644
index 0000000000..e335ad47e9
--- /dev/null
+++ b/docs-util/packages/typedoc-plugin-custom/src/signature-modifier.ts
@@ -0,0 +1,21 @@
+import {
+ Application,
+ Context,
+ Converter,
+ ProjectReflection,
+ SignatureReflection,
+} from "typedoc"
+
+export function load(app: Application) {
+ app.converter.on(
+ Converter.EVENT_CREATE_SIGNATURE,
+ (
+ context: Context,
+ signature: SignatureReflection | ProjectReflection | undefined
+ ) => {
+ if (signature?.comment?.hasModifier("@hideSignature")) {
+ context.project.removeReflection(signature)
+ }
+ }
+ )
+}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/returns.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/returns.ts
index 2c3845fa44..557b105917 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/returns.ts
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/returns.ts
@@ -31,13 +31,13 @@ function getReturnFromType(
return ""
}
- const componentItems = returnReflectionComponentFormatter(
- reflection.type,
- reflection.project || theme.project,
- reflection.comment,
- 1,
- maxLevel
- )
+ const componentItems = returnReflectionComponentFormatter({
+ reflectionType: reflection.type,
+ project: reflection.project || theme.project,
+ comment: reflection.comment,
+ level: 1,
+ maxLevel,
+ })
if (parameterStyle === "component") {
return `<${parameterComponent} parameters={${JSON.stringify(
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts
index 3793ff45e1..0bfebe6f1e 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/helpers/signature-title.ts
@@ -15,7 +15,7 @@ export default function (theme: MarkdownTheme) {
theme.getFormattingOptionsForLocation()
if (sections && sections.member_signature_title === false) {
// only show title if there are more than one signatures
- if (!this.parent.signatures || this.parent.signatures?.length <= 1) {
+ if (!this.parent.signatures || this.parent.signatures.length <= 1) {
return ""
}
}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs
index cf79ca1071..2a339b5737 100755
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.declaration.hbs
@@ -12,7 +12,7 @@
{{#if (sectionEnabled "member_declaration_example")}}
-{{{example this 3}}}
+{{{example this 4}}}
{{/if}}
@@ -20,7 +20,7 @@
{{#if typeParameters}}
-{{titleLevel 3}} Type parameters
+{{{titleLevel 4}}} Type Parameters
{{#with typeParameters}}
@@ -40,7 +40,7 @@
{{#with type.declaration.indexSignature}}
-{{titleLevel 3}} Index signature
+{{titleLevel 4}} Index signature
{{{indexSignatureTitle}}}
@@ -58,17 +58,17 @@
{{#if type.declaration.children}}
-{{titleLevel 3}} Call signature
+{{{titleLevel 4}}} Call signature
{{else}}
-{{titleLevel 3}} Type declaration
+{{{titleLevel 4}}} Type declaration
{{/if}}
{{#each type.declaration.signatures}}
-{{> member.signature showSources=false }}
+{{> member.signature showSources=false commentLevel=5 }}
{{/each}}
@@ -82,7 +82,7 @@
{{#with type.declaration}}
-{{titleLevel 3}} Type declaration
+{{{titleLevel 4}}} Type declaration
{{/with}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.getterSetter.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.getterSetter.hbs
index 0657dc1fbd..746961b44c 100755
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.getterSetter.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.getterSetter.hbs
@@ -4,7 +4,7 @@
{{#with getSignature}}
-{{> member.signature accessor="get" showSources=true }}
+{{> member.signature accessor="get" showSources=true commentLevel=4 }}
{{/with}}
@@ -18,7 +18,7 @@
{{#with setSignature}}
-{{> member.signature accessor="set" showSources=true }}
+{{> member.signature accessor="set" showSources=true commentLevel=4 }}
{{/with}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.hbs
index 5062e71e6c..91c0a4f0dd 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.hbs
@@ -2,7 +2,7 @@
{{#if name}}
-{{titleLevel 3}} {{#ifNamedAnchors}} {{/ifNamedAnchors}}{{ escape name }}
+{{titleLevel 4}} {{#ifNamedAnchors}} {{/ifNamedAnchors}}{{ escape name }}
{{/if}}
@@ -14,7 +14,7 @@
{{#each signatures}}
-{{> member.signature showSources=true }}
+{{> member.signature showSources=true commentLevel=../commentLevel }}
{{/each}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.signature.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.signature.hbs
index b8d21bba97..7a50c41def 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.signature.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/member.signature.hbs
@@ -14,10 +14,18 @@
{{/if}}
+{{#if (sectionEnabled "member_signature_example")}}
+
+{{{example this commentLevel}}}
+
+{{/if}}
+
{{#if (sectionEnabled "member_signature_typeParameters")}}
{{#if typeParameters}}
+{{{titleLevel commentLevel}}} Type Parameters
+
{{#with typeParameters}}
{{{typeParameter}}}
@@ -28,25 +36,11 @@
{{/if}}
-{{#if (sectionEnabled "member_signature_example")}}
-
-{{{example this 4}}}
-
-{{/if}}
-
{{#if (sectionEnabled "member_signature_parameters")}}
{{#if parameters}}
-{{#if showSources}}
-
-{{{titleLevel 4}}} Parameters
-
-{{else}}
-
-{{{titleLevel 5}}} Parameters
-
-{{/if}}
+{{{titleLevel commentLevel}}} Parameters
{{#with parameters}}
@@ -62,15 +56,7 @@
{{#if type}}
-{{#if showSources}}
-
-{{{titleLevel 4}}} Returns
-
-{{else}}
-
-{{{titleLevel 5}}} Returns
-
-{{/if}}
+{{{titleLevel commentLevel}}} Returns
{{#if (sectionEnabled "member_signature_returns")}}
@@ -92,7 +78,7 @@
{{#each declaration.signatures}}
-{{> member.signature showSources=false }}
+{{> member.signature showSources=false commentLevel=commentLevel }}
{{/each}}
@@ -126,7 +112,7 @@
{{#if hasVisibleComponent}}
-{{{comments this false true 4 ..}}}
+{{{comments this false true commentLevel ..}}}
{{/if}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.group.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.group.hbs
index 89b24733a9..b32fb78432 100755
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.group.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.group.hbs
@@ -26,7 +26,7 @@ ___
{{#each children}}
-{{> member}}
+{{> member commentLevel=5}}
{{/each}}
@@ -54,7 +54,7 @@ ___
{{#each children}}
-{{> member}}
+{{> member commentLevel=5}}
{{/each}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.hbs
index 08f7e8134a..c00601347a 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/members.hbs
@@ -16,7 +16,7 @@
{{#unless hasOwnDocument}}
-{{> member}}
+{{> member commentLevel=4}}
{{/unless}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/section-title.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/section-title.hbs
new file mode 100644
index 0000000000..e863067f41
--- /dev/null
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/partials/section-title.hbs
@@ -0,0 +1,9 @@
+{{#if showSources}}
+
+{{{titleLevel 4}}} {{{title}}}
+
+{{else}}
+
+{{{titleLevel 5}}} {{{title}}}
+
+{{/if}}
\ No newline at end of file
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.hbs
index 7ae033c574..6c63ea1f9c 100755
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.hbs
@@ -94,7 +94,7 @@
### {{name}}
-{{> member.signature showSources=true }}
+{{> member.signature showSources=true commentLevel=4 }}
{{/each}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.member.hbs b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.member.hbs
index 78129be63b..8b2a6554b2 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.member.hbs
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/resources/templates/reflection.member.hbs
@@ -4,6 +4,6 @@
{{#with model}}
-{{> member}}
+{{> member showSources=false commentLevel=4}}
{{/with}}
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/theme.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/theme.ts
index 6a501e56e4..1b739b1efb 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/theme.ts
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/theme.ts
@@ -5,7 +5,6 @@ import {
PageEvent,
ProjectReflection,
Reflection,
- ReflectionGroup,
ReflectionKind,
RenderTemplate,
Renderer,
@@ -359,22 +358,45 @@ export class MarkdownTheme extends Theme {
this.location = page.url
this.reflection =
page.model instanceof DeclarationReflection ? page.model : undefined
- const options = this.getFormattingOptionsForLocation()
- if (this.reflection && this.reflection.groups) {
- // filter out unwanted groups
- const tempGroups: ReflectionGroup[] = []
- this.reflection.groups.forEach((reflectionGroup) => {
- if (
- !options.reflectionGroups ||
- !(reflectionGroup.title in options.reflectionGroups) ||
- options.reflectionGroups[reflectionGroup.title]
- ) {
- tempGroups.push(reflectionGroup)
- }
- })
- this.reflection.groups = tempGroups
+ if (
+ page.model instanceof DeclarationReflection ||
+ page.model instanceof ProjectReflection
+ ) {
+ this.removeGroups(page.model)
}
+
+ if (
+ this.reflection instanceof DeclarationReflection &&
+ this.reflection.signatures
+ ) {
+ // check if any of its signature has the `@mainSignature` tag
+ // and if so remove other signatures
+ const mainSignatureIndex = this.reflection.signatures.findIndex(
+ (signature) => signature.comment?.hasModifier("@mainSignature")
+ )
+
+ if (mainSignatureIndex !== -1) {
+ const mainSignature = this.reflection.signatures[mainSignatureIndex]
+ this.reflection.signatures = [mainSignature]
+ }
+ }
+ }
+
+ protected removeGroups(model?: DeclarationReflection | ProjectReflection) {
+ if (!model?.groups) {
+ return
+ }
+
+ const options = this.getFormattingOptionsForLocation()
+
+ model.groups = model.groups.filter((reflectionGroup) => {
+ return (
+ !options.reflectionGroups ||
+ !(reflectionGroup.title in options.reflectionGroups) ||
+ options.reflectionGroups[reflectionGroup.title]
+ )
+ })
}
get globalsFile() {
diff --git a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts
index 1155fe2852..eb930e1cdf 100644
--- a/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts
+++ b/docs-util/packages/typedoc-plugin-markdown-medusa/src/utils/return-reflection-formatter.ts
@@ -4,6 +4,7 @@ import {
ProjectReflection,
ReflectionFlags,
SomeType,
+ TypeParameterReflection,
} from "typedoc"
import * as Handlebars from "handlebars"
import getType from "./type-utils"
@@ -14,19 +15,27 @@ import {
} from "./reflection-formatter"
import { MarkdownTheme } from "../theme"
-export function returnReflectionComponentFormatter(
- reflectionType: SomeType,
- project: ProjectReflection,
- comment?: Comment,
- level = 1,
+type ReturnReflectionComponentFormatterParams = {
+ reflectionType: SomeType
+ project: ProjectReflection
+ comment?: Comment
+ level: number
maxLevel?: number | undefined
-): Parameter[] {
+}
+
+export function returnReflectionComponentFormatter({
+ reflectionType,
+ project,
+ comment,
+ level = 1,
+ maxLevel,
+}: ReturnReflectionComponentFormatterParams): Parameter[] {
const typeName = getType(reflectionType, "object", false, true)
const type = getType(reflectionType, "object")
const componentItem: Parameter[] = []
+ const canRetrieveChildren = level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
if (reflectionType.type === "reference") {
- // put type name as a title and its referenced items as children.
- if (reflectionType.typeArguments) {
+ if (reflectionType.typeArguments || reflectionType.refersToTypeParameter) {
const parentKey = componentItem.push({
name: "name" in reflectionType ? reflectionType.name : typeName,
type,
@@ -45,21 +54,30 @@ export function returnReflectionComponentFormatter(
featureFlag: Handlebars.helpers.featureFlag(comment),
children: [],
})
+ const typeArgs = reflectionType.typeArguments
+ ? reflectionType.typeArguments
+ : "typeParameters" in reflectionType
+ ? (reflectionType.typeParameters as TypeParameterReflection[])
+ : undefined
if (
- !isOnlyVoid(reflectionType.typeArguments) &&
- level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
+ typeArgs &&
+ !isOnlyVoid(typeArgs as unknown as SomeType[]) &&
+ canRetrieveChildren
) {
- reflectionType.typeArguments.forEach((typeArg) => {
- const typeArgComponent = returnReflectionComponentFormatter(
- typeArg,
- project,
- undefined,
- level + 1,
- maxLevel
- )
- if (typeArgComponent.length) {
- componentItem[parentKey - 1].children?.push(...typeArgComponent)
+ typeArgs.forEach((typeArg) => {
+ const reflectionTypeArg =
+ typeArg instanceof TypeParameterReflection ? typeArg.type : typeArg
+ if (!reflectionTypeArg) {
+ return
}
+ const typeArgComponent = returnReflectionComponentFormatter({
+ reflectionType: reflectionTypeArg,
+ project,
+ level: level + 1,
+ maxLevel,
+ })
+
+ componentItem[parentKey - 1].children?.push(...typeArgComponent)
})
}
} else {
@@ -107,17 +125,14 @@ export function returnReflectionComponentFormatter(
featureFlag: Handlebars.helpers.featureFlag(comment),
children: [],
})
- if (level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)) {
- const elementTypeItem = returnReflectionComponentFormatter(
- reflectionType.elementType,
+ if (canRetrieveChildren) {
+ const elementTypeItem = returnReflectionComponentFormatter({
+ reflectionType: reflectionType.elementType,
project,
- undefined,
- level + 1,
- maxLevel
- )
- if (elementTypeItem.length) {
- componentItem[parentKey - 1].children?.push(...elementTypeItem)
- }
+ level: level + 1,
+ maxLevel,
+ })
+ componentItem[parentKey - 1].children?.push(...elementTypeItem)
}
} else if (reflectionType.type === "tuple") {
let pushTo: Parameter[] = []
@@ -145,18 +160,15 @@ export function returnReflectionComponentFormatter(
} else {
pushTo = componentItem
}
- if (level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)) {
+ if (canRetrieveChildren) {
reflectionType.elements.forEach((element) => {
- const elementTypeItem = returnReflectionComponentFormatter(
- element,
+ const elementTypeItem = returnReflectionComponentFormatter({
+ reflectionType: element,
project,
- undefined,
- level + 1,
- maxLevel
- )
- if (elementTypeItem.length) {
- pushTo.push(...elementTypeItem)
- }
+ level: level + 1,
+ maxLevel,
+ })
+ pushTo.push(...elementTypeItem)
})
}
} else {
diff --git a/docs-util/packages/utils/src/get-type-children.ts b/docs-util/packages/utils/src/get-type-children.ts
index bfe4b143f7..e3e79dcb25 100644
--- a/docs-util/packages/utils/src/get-type-children.ts
+++ b/docs-util/packages/utils/src/get-type-children.ts
@@ -65,7 +65,15 @@ export function getTypeChildren(
children = getTypeChildren(reflectionType.elementType, project)
}
- return children
+ return filterChildren(children)
+}
+
+const REJECTED_CHILDREN_NAMES = ["__type"]
+
+function filterChildren(children: DeclarationReflection[]) {
+ return children.filter(
+ (child) => !REJECTED_CHILDREN_NAMES.includes(child.name)
+ )
}
function removeChild(name: unknown, children: DeclarationReflection[]) {
diff --git a/packages/workflows/src/utils/composer/create-step.ts b/packages/workflows/src/utils/composer/create-step.ts
index 7e8b0df926..e647ab60d4 100644
--- a/packages/workflows/src/utils/composer/create-step.ts
+++ b/packages/workflows/src/utils/composer/create-step.ts
@@ -16,10 +16,25 @@ import {
} from "./type"
import { proxify } from "./helpers/proxy"
+/**
+ * The type of invocation function passed to a step.
+ *
+ * @typeParam TInput - The type of the input that the function expects.
+ * @typeParam TOutput - The type of the output that the function returns.
+ * @typeParam TCompensateInput - The type of the input that the compensation function expects.
+ *
+ * @returns The expected output based on the type parameter `TOutput`.
+ */
type InvokeFn = (
+ /**
+ * The input of the step.
+ */
input: {
[Key in keyof TInput]: TInput[Key]
},
+ /**
+ * The step's context.
+ */
context: StepExecutionContext
) =>
| void
@@ -32,8 +47,22 @@ type InvokeFn = (
TCompensateInput extends undefined ? TOutput : TCompensateInput
>>
+/**
+ * The type of compensation function passed to a step.
+ *
+ * @typeParam T -
+ * The type of the argument passed to the compensation function. If not specified, then it will be the same type as the invocation function's output.
+ *
+ * @returns There's no expected type to be returned by the compensation function.
+ */
type CompensateFn = (
+ /**
+ * The argument passed to the compensation function.
+ */
input: T | undefined,
+ /**
+ * The step's context.
+ */
context: StepExecutionContext
) => unknown | Promise
@@ -56,6 +85,8 @@ interface ApplyStepOptions<
}
/**
+ * @internal
+ *
* Internal function to create the invoke and compensate handler for a step.
* This is where the inputs and context are passed to the underlying invoke and compensate function.
*
@@ -152,55 +183,77 @@ function applyStep<
}
/**
- * Function which will create a StepFunction to be used inside a createWorkflow composer function.
- * This function will return a function which can be used to bind the step to a workflow.
- * The types of the input to be passed to the step function is defined by the generic of the invoke function provided.
+ * This function creates a {@link StepFunction} that can be used as a step in a workflow constructed by the {@link createWorkflow} function.
*
- * @param name
- * @param invokeFn
- * @param compensateFn
+ * @typeParam TInvokeInput - The type of the expected input parameter to the invocation function.
+ * @typeParam TInvokeResultOutput - The type of the expected output parameter of the invocation function.
+ * @typeParam TInvokeResultCompensateInput - The type of the expected input parameter to the compensation function.
+ *
+ * @returns A step function to be used in a workflow.
*
* @example
- * ```ts
+ * import {
+ * createStep,
+ * StepResponse,
+ * StepExecutionContext,
+ * WorkflowData
+ * } from "@medusajs/workflows"
+ *
* interface CreateProductInput {
* title: string
* }
*
- * interface CreateProductOutput {
- * product: { id: string; title: string }
- * compensateInput: {
- * product_id: string
- * }
- * }
- *
* export const createProductStep = createStep(
- * "createProductStep",
- * async function (input: Step1Input, context: StepExecutionContext): Promise {
- * const productService = context.container.resolve("productService")
- * const product = await productService.create(input)
- * return {
- * product,
- * compensateInput: {
- * product_id: product.id
- * }
- * }
- * },
- * async function (input: { product_id: string }, context: StepExecutionContext) {
- * const productService = context.container.resolve("productService")
+ * "createProductStep",
+ * async function (
+ * input: CreateProductInput,
+ * context
+ * ) {
+ * const productService = context.container.resolve(
+ * "productService"
+ * )
+ * const product = await productService.create(input)
+ * return new StepResponse({
+ * product
+ * }, {
+ * product_id: product.id
+ * })
+ * },
+ * async function (
+ * input,
+ * context
+ * ) {
+ * const productService = context.container.resolve(
+ * "productService"
+ * )
* await productService.delete(input.product_id)
- * })
+ * }
+ * )
*/
export function createStep<
TInvokeInput extends object,
TInvokeResultOutput,
TInvokeResultCompensateInput
>(
+ /**
+ * The name of the step.
+ */
name: string,
+ /**
+ * An invocation function that will be executed when the workflow is executed. The function must return an instance of {@link StepResponse}. The constructor of {@link StepResponse}
+ * accepts the output of the step as a first argument, and optionally as a second argument the data to be passed to the compensation function as a parameter.
+ */
invokeFn: InvokeFn<
TInvokeInput,
TInvokeResultOutput,
TInvokeResultCompensateInput
>,
+ /**
+ * A compensation function that's executed if an error occurs in the workflow. It's used to roll-back actions when errors occur.
+ * It accepts as a parameter the second argument passed to the constructor of the {@link StepResponse} instance returned by the invocation function. If the
+ * invocation function doesn't pass the second argument to `StepResponse` constructor, the compensation function receives the first argument
+ * passed to the `StepResponse` constructor instead.
+ */
compensateFn?: CompensateFn
): StepFunction {
const stepName = name ?? invokeFn.name
diff --git a/packages/workflows/src/utils/composer/create-workflow.ts b/packages/workflows/src/utils/composer/create-workflow.ts
index c9524b5dbc..a2c01e3cdc 100644
--- a/packages/workflows/src/utils/composer/create-workflow.ts
+++ b/packages/workflows/src/utils/composer/create-workflow.ts
@@ -20,6 +20,53 @@ import { proxify } from "./helpers/proxy"
global[SymbolMedusaWorkflowComposerContext] = null
+/**
+ * An exported workflow, which is the type of a workflow constructed by the {@link createWorkflow} function. The exported workflow can be invoked to create
+ * an executable workflow, optionally within a specified container. So, to execute the workflow, you must invoke the exported workflow, then run the
+ * `run` method of the exported workflow.
+ *
+ * @example
+ * To execute a workflow:
+ *
+ * ```ts
+ * myWorkflow()
+ * .run({
+ * input: {
+ * name: "John"
+ * }
+ * })
+ * .then(({ result }) => {
+ * console.log(result)
+ * })
+ * ```
+ *
+ * To specify the container of the workflow, you can pass it as an argument to the call of the exported workflow. This is necessary when executing the workflow
+ * within a Medusa resource such as an API Route or a Subscriber.
+ *
+ * For example:
+ *
+ * ```ts
+ * import type {
+ * MedusaRequest,
+ * MedusaResponse
+ * } from "@medusajs/medusa";
+ * import myWorkflow from "../../../workflows/hello-world";
+ *
+ * export async function GET(
+ * req: MedusaRequest,
+ * res: MedusaResponse
+ * ) {
+ * const { result } = await myWorkflow(req.scope)
+ * .run({
+ * input: {
+ * name: req.query.name as string
+ * }
+ * })
+ *
+ * res.send(result)
+ * }
+ * ```
+ */
type ReturnWorkflow> = {
(
container?: LoadedModule[] | MedusaContainer
@@ -37,32 +84,58 @@ type ReturnWorkflow> = {
} & THooks
/**
- * Creates a new workflow with the given name and composer function.
- * The composer function will compose the workflow by using the step, parallelize and other util functions that
- * will allow to define the flow of event of a workflow.
+ * This function creates a workflow with the provided name and a constructor function.
+ * The constructor function builds the workflow from steps created by the {@link createStep} function.
+ * The returned workflow is an exported workflow of type {@link ReturnWorkflow}, meaning it's not executed right away. To execute it,
+ * invoke the exported workflow, then run its `run` method.
*
- * @param name
- * @param composer
+ * @typeParam TData - The type of the input passed to the composer function.
+ * @typeParam TResult - The type of the output returned by the composer function.
+ * @typeParam THooks - The type of hooks defined in the workflow.
+ *
+ * @returns The created workflow. You can later execute the workflow by invoking it, then using its `run` method.
*
* @example
- * ```ts
- * import { createWorkflow, WorkflowData } from "@medusajs/workflows"
- * import { createProductStep, getProductStep, createPricesStep } from "./steps"
+ * import { createWorkflow } from "@medusajs/workflows"
+ * import { MedusaRequest, MedusaResponse, Product } from "@medusajs/medusa"
+ * import {
+ * createProductStep,
+ * getProductStep,
+ * createPricesStep
+ * } from "./steps"
*
- * interface MyWorkflowData {
+ * interface WorkflowInput {
* title: string
* }
*
- * const myWorkflow = createWorkflow("my-workflow", (input: WorkflowData) => {
- * // Everything here will be executed and resolved later during the execution. Including the data access.
+ * const myWorkflow = createWorkflow<
+ * WorkflowInput,
+ * Product
+ * >("my-workflow", (input) => {
+ * // Everything here will be executed and resolved later
+ * // during the execution. Including the data access.
*
- * const product = createProductStep(input)
- * const prices = createPricesStep(product)
+ * const product = createProductStep(input)
+ * const prices = createPricesStep(product)
+ * return getProductStep(product.id)
+ * }
+ * )
*
- * const id = product.id
- * return getProductStep(product.id)
- * })
- * ```
+ * export async function GET(
+ * req: MedusaRequest,
+ * res: MedusaResponse
+ * ) {
+ * const { result: product } = await myWorkflow(req.scope)
+ * .run({
+ * input: {
+ * title: "Shirt"
+ * }
+ * })
+ *
+ * res.json({
+ * product
+ * })
+ * }
*/
export function createWorkflow<
@@ -70,7 +143,15 @@ export function createWorkflow<
TResult,
THooks extends Record = Record
>(
+ /**
+ * The name of the workflow.
+ */
name: string,
+ /**
+ * The constructor function that is executed when the `run` method in {@link ReturnWorkflow} is used.
+ * The function can't be an arrow function or an asynchronus function. It also can't directly manipulate data.
+ * You'll have to use the {@link transform} function if you need to directly manipulate data.
+ */
composer: (input: WorkflowData) =>
| void
| WorkflowData
diff --git a/packages/workflows/src/utils/composer/helpers/resolve-value.ts b/packages/workflows/src/utils/composer/helpers/resolve-value.ts
index 5a74e19448..c5fb131771 100644
--- a/packages/workflows/src/utils/composer/helpers/resolve-value.ts
+++ b/packages/workflows/src/utils/composer/helpers/resolve-value.ts
@@ -30,6 +30,9 @@ async function resolveProperty(property, transactionContext) {
}
}
+/**
+ * @internal
+ */
export async function resolveValue(input, transactionContext) {
const unwrapInput = async (
inputTOUnwrap: Record,
diff --git a/packages/workflows/src/utils/composer/helpers/step-response.ts b/packages/workflows/src/utils/composer/helpers/step-response.ts
index c9d9bf55cb..a0ccaff81e 100644
--- a/packages/workflows/src/utils/composer/helpers/step-response.ts
+++ b/packages/workflows/src/utils/composer/helpers/step-response.ts
@@ -1,27 +1,64 @@
import { SymbolWorkflowStepResponse } from "./symbol"
+/**
+ * This class is used to create the response returned by a step. A step return its data by returning an instance of `StepResponse`.
+ *
+ * @typeParam TOutput - The type of the output of the step.
+ * @typeParam TCompensateInput -
+ * The type of the compensation input. If the step doesn't specify any compensation input, then the type of `TCompensateInput` is the same
+ * as that of `TOutput`.
+ */
export class StepResponse {
readonly #__type = SymbolWorkflowStepResponse
readonly #output: TOutput
readonly #compensateInput?: TCompensateInput
- constructor(output: TOutput, compensateInput?: TCompensateInput) {
+ /**
+ * The constructor of the StepResponse
+ *
+ * @typeParam TOutput - The type of the output of the step.
+ * @typeParam TCompensateInput -
+ * The type of the compensation input. If the step doesn't specify any compensation input, then the type of `TCompensateInput` is the same
+ * as that of `TOutput`.
+ */
+ constructor(
+ /**
+ * The output of the step.
+ */
+ output: TOutput,
+ /**
+ * The input to be passed as a parameter to the step's compensation function. If not provided, the `output` will be provided instead.
+ */
+ compensateInput?: TCompensateInput
+ ) {
this.#output = output
this.#compensateInput = (compensateInput ?? output) as TCompensateInput
}
+ /**
+ * @internal
+ */
get __type() {
return this.#__type
}
+ /**
+ * @internal
+ */
get output(): TOutput {
return this.#output
}
+ /**
+ * @internal
+ */
get compensateInput(): TCompensateInput {
return this.#compensateInput as TCompensateInput
}
+ /**
+ * @internal
+ */
toJSON() {
return {
__type: this.#__type,
diff --git a/packages/workflows/src/utils/composer/hook.ts b/packages/workflows/src/utils/composer/hook.ts
index e3aa12b093..8fa91c8028 100644
--- a/packages/workflows/src/utils/composer/hook.ts
+++ b/packages/workflows/src/utils/composer/hook.ts
@@ -9,7 +9,100 @@ import {
WorkflowData,
} from "./type"
-export function hook(name: string, value: any): WorkflowData {
+/**
+ *
+ * @ignore
+ *
+ * This function allows you to add hooks in your workflow that provide access to some data. Then, consumers of that workflow can add a handler function that performs
+ * an action with the provided data or modify it.
+ *
+ * For example, in a "create product" workflow, you may add a hook after the product is created, providing access to the created product.
+ * Then, developers using that workflow can hook into that point to access the product, modify its attributes, then return the updated product.
+ *
+ * @typeParam TOutput - The expected output of the hook's handler function.
+ * @returns The output of handler functions of this hook. If there are no handler functions, the output is `undefined`.
+ *
+ * @example
+ * import {
+ * createWorkflow,
+ * StepExecutionContext,
+ * hook,
+ * transform
+ * } from "@medusajs/workflows"
+ * import {
+ * createProductStep,
+ * getProductStep,
+ * createPricesStep
+ * } from "./steps"
+ * import {
+ * MedusaRequest,
+ * MedusaResponse,
+ * Product, ProductService
+ * } from "@medusajs/medusa"
+ *
+ * interface WorkflowInput {
+ * title: string
+ * }
+ *
+ * const myWorkflow = createWorkflow<
+ * WorkflowInput,
+ * Product
+ * >("my-workflow",
+ * function (input) {
+ * const product = createProductStep(input)
+ *
+ * const hookProduct = hook("createdProductHook", product)
+ *
+ * const newProduct = transform({
+ * product,
+ * hookProduct
+ * }, (input) => {
+ * return input.hookProduct || input.product
+ * })
+ *
+ * const prices = createPricesStep(newProduct)
+ *
+ * return getProductStep(product.id)
+ * }
+ * )
+ *
+ * myWorkflow.createdProductHook(
+ * async (product, context: StepExecutionContext) => {
+ * const productService: ProductService = context.container.resolve("productService")
+ *
+ * const updatedProduct = await productService.update(product.id, {
+ * description: "a cool shirt"
+ * })
+ *
+ * return updatedProduct
+ * })
+ *
+ * export async function POST(
+ * req: MedusaRequest,
+ * res: MedusaResponse
+ * ) {
+ * const { result: product } = await myWorkflow(req.scope)
+ * .run({
+ * input: {
+ * title: req.body.title
+ * }
+ * })
+ *
+ * res.json({
+ * product
+ * })
+ * }
+ */
+export function hook(
+ /**
+ * The name of the hook. This will be used by the consumer to add a handler method for the hook.
+ */
+ name: string,
+ /**
+ * The data that a handler function receives as a parameter.
+ */
+ value: any
+): WorkflowData {
const hookBinder = (
global[SymbolMedusaWorkflowComposerContext] as CreateWorkflowComposerContext
).hookBinder
diff --git a/packages/workflows/src/utils/composer/parallelize.ts b/packages/workflows/src/utils/composer/parallelize.ts
index f1cf22a052..fdc8ed50b3 100644
--- a/packages/workflows/src/utils/composer/parallelize.ts
+++ b/packages/workflows/src/utils/composer/parallelize.ts
@@ -2,32 +2,44 @@ import { CreateWorkflowComposerContext, WorkflowData } from "./type"
import { SymbolMedusaWorkflowComposerContext } from "./helpers"
/**
- * Parallelize multiple steps.
- * The steps will be run in parallel. The result of each step will be returned as part of the result array.
- * Each StepResult can be accessed from the resulted array in the order they were passed to the parallelize function.
+ * This function is used to run multiple steps in parallel. The result of each step will be returned as part of the result array.
*
- * @param steps
+ * @typeParam TResult - The type of the expected result.
+ *
+ * @returns The step results. The results are ordered in the array by the order they're passed in the function's parameter.
*
* @example
* ```ts
- * import { createWorkflow, WorkflowData, parallelize } from "@medusajs/workflows"
- * import { createProductStep, getProductStep, createPricesStep, attachProductToSalesChannelStep } from "./steps"
+ * import {
+ * createWorkflow,
+ * parallelize
+ * } from "@medusajs/workflows"
+ * import {
+ * createProductStep,
+ * getProductStep,
+ * createPricesStep,
+ * attachProductToSalesChannelStep
+ * } from "./steps"
*
- * interface MyWorkflowData {
+ * interface WorkflowInput {
* title: string
* }
*
- * const myWorkflow = createWorkflow("my-workflow", (input: WorkflowData) => {
- * const product = createProductStep(input)
+ * const myWorkflow = createWorkflow<
+ * WorkflowInput,
+ * Product
+ * >("my-workflow", (input) => {
+ * const product = createProductStep(input)
*
- * const [prices, productSalesChannel] = parallelize(
+ * const [prices, productSalesChannel] = parallelize(
* createPricesStep(product),
* attachProductToSalesChannelStep(product)
- * )
+ * )
*
- * const id = product.id
- * return getProductStep(product.id)
- * })
+ * const id = product.id
+ * return getProductStep(product.id)
+ * }
+ * )
*/
export function parallelize(
...steps: TResult
diff --git a/packages/workflows/src/utils/composer/transform.ts b/packages/workflows/src/utils/composer/transform.ts
index 42648019e6..03a97d3c6a 100644
--- a/packages/workflows/src/utils/composer/transform.ts
+++ b/packages/workflows/src/utils/composer/transform.ts
@@ -13,14 +13,67 @@ type Func1 = (
type Func = (input: T, context: StepExecutionContext) => U | Promise
+/**
+ *
+ * This function transforms the output of other utility functions.
+ *
+ * For example, if you're using the value(s) of some step(s) as an input to a later step. As you can't directly manipulate data in the workflow constructor function passed to {@link createWorkflow},
+ * the `transform` function provides access to the runtime value of the step(s) output so that you can manipulate them.
+ *
+ * Another example is if you're using the runtime value of some step(s) as the output of a workflow.
+ *
+ * If you're also retrieving the output of a hook and want to check if its value is set, you must use a workflow to get the runtime value of that hook.
+ *
+ * @returns There's no expected value to be returned by the `transform` function.
+ *
+ * @example
+ * import {
+ * createWorkflow,
+ * transform
+ * } from "@medusajs/workflows"
+ * import { step1, step2 } from "./steps"
+ *
+ * type WorkflowInput = {
+ * name: string
+ * }
+ *
+ * type WorkflowOutput = {
+ * message: string
+ * }
+ *
+ * const myWorkflow = createWorkflow<
+ * WorkflowInput,
+ * WorkflowOutput
+ * >
+ * ("hello-world", (input) => {
+ * const str1 = step1(input)
+ * const str2 = step2(input)
+ *
+ * return transform({
+ * str1,
+ * str2
+ * }, (input) => ({
+ * message: `${input.str1}${input.str2}`
+ * }))
+ * })
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
+ /**
+ * The output(s) of other step functions.
+ */
values: T,
+ /**
+ * The transform function used to perform action on the runtime values of the provided `values`.
+ */
...func:
| [Func1]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -30,6 +83,9 @@ export function transform(
| [Func1, Func]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -40,6 +96,9 @@ export function transform(
| [Func1, Func, Func]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -51,6 +110,9 @@ export function transform(
| [Func1, Func, Func, Func]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -63,6 +125,9 @@ export function transform, Func, Func, Func, Func]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -76,6 +141,9 @@ export function transform, Func, Func, Func, Func, Func]
): WorkflowData
+/**
+ * @internal
+ */
// prettier-ignore
// eslint-disable-next-line max-len
export function transform(
@@ -90,14 +158,6 @@ export function transform, Func, Func, Func, Func, Func, Func]
): WorkflowData
-/**
- * Transforms the input value(s) using the provided functions.
- * Allow to perform transformation on the future result of the step(s) to be passed
- * to other steps later on at run time.
- *
- * @param values
- * @param functions
- */
export function transform(
values: any | any[],
...functions: Function[]
diff --git a/packages/workflows/src/utils/composer/type.ts b/packages/workflows/src/utils/composer/type.ts
index 664f7f182e..f6f019d9e8 100644
--- a/packages/workflows/src/utils/composer/type.ts
+++ b/packages/workflows/src/utils/composer/type.ts
@@ -15,6 +15,12 @@ export type StepFunctionResult =
]
: WorkflowData<{ [K in keyof TOutput]: TOutput[K] }>
+/**
+ * A step function to be used in a workflow.
+ *
+ * @typeParam TInput - The type of the input of the step.
+ * @typeParam TOutput - The type of the output of the step.
+ */
export type StepFunction = {
(input: { [K in keyof TInput]: WorkflowData }): WorkflowData<{
[K in keyof TOutput]: TOutput[K]
@@ -28,6 +34,11 @@ export type WorkflowDataProperties = {
__step__: string
}
+/**
+ * This type is used to encapsulate the input or output type of all utils.
+ *
+ * @typeParam T - The type of a step's input or result.
+ */
export type WorkflowData = (T extends object
? {
[Key in keyof T]: WorkflowData
@@ -53,9 +64,21 @@ export type CreateWorkflowComposerContext = {
) => TOutput
}
+/**
+ * The step's context.
+ */
export interface StepExecutionContext {
+ /**
+ * The container used to access resources, such as services, in the step.
+ */
container: MedusaContainer
+ /**
+ * Metadata passed in the input.
+ */
metadata: TransactionPayload["metadata"]
+ /**
+ * {@inheritDoc Context}
+ */
context: Context
}