diff --git a/.gitignore b/.gitignore index ee38f9164c..f2a6a29bf9 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,10 @@ packages/swc-plugin-workflow/build-hash.json .DS_Store +# TypeDoc generated output +/packages/*/typedoc-out +/packages/*/typedoc-out-api + # Generated manifest files copied to static asset directories by builders workbench/nextjs-*/public/.well-known/workflow workbench/sveltekit/static/.well-known/workflow diff --git a/docs/.gitignore b/docs/.gitignore index 0805f529d5..f14bdfe123 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -30,6 +30,9 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts +# typedoc-generated API reference pages +/content/docs/api-reference/*/api/ + # pagefind _pagefind/ diff --git a/docs/app/[lang]/docs/[[...slug]]/page.tsx b/docs/app/[lang]/docs/[[...slug]]/page.tsx index e1bca864c3..d6d2e2c9ba 100644 --- a/docs/app/[lang]/docs/[[...slug]]/page.tsx +++ b/docs/app/[lang]/docs/[[...slug]]/page.tsx @@ -22,7 +22,6 @@ import * as AccordionComponents from '@/components/ui/accordion'; import { Badge } from '@/components/ui/badge'; import { Separator } from '@/components/ui/separator'; import { getLLMText, getPageImage, source } from '@/lib/geistdocs/source'; -import { TSDoc } from '@/lib/tsdoc'; // No-op component for world MDX files rendered outside /worlds/ context // These pages redirect to /worlds/[id] but still get statically generated @@ -70,7 +69,6 @@ const Page = async ({ params }: PageProps<'/[lang]/docs/[[...slug]]'>) => { AgentTraces, FluidComputeCallout, Badge, - TSDoc, Step, Steps, ...AccordionComponents, diff --git a/docs/content/docs/api-reference/vitest/meta.json b/docs/content/docs/api-reference/vitest/meta.json new file mode 100644 index 0000000000..74e2343cc3 --- /dev/null +++ b/docs/content/docs/api-reference/vitest/meta.json @@ -0,0 +1,4 @@ +{ + "title": "@workflow/vitest", + "pages": ["...", "--- Generated API Reference ---", "...api"] +} diff --git a/docs/content/docs/api-reference/workflow-ai/durable-agent.mdx b/docs/content/docs/api-reference/workflow-ai/durable-agent.mdx index ba9de4375b..8021340c4e 100644 --- a/docs/content/docs/api-reference/workflow-ai/durable-agent.mdx +++ b/docs/content/docs/api-reference/workflow-ai/durable-agent.mdx @@ -63,77 +63,45 @@ async function myAgent() { ### Class - +> See the full API reference for [`DurableAgent`](/docs/api-reference/workflow-ai/api/agent/durable-agent/classes/DurableAgent). ### DurableAgentOptions - +> See the full API reference for [`DurableAgentOptions`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/DurableAgentOptions). ### DurableAgentStreamOptions - +> See the full API reference for [`DurableAgentStreamOptions`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/DurableAgentStreamOptions). ### DurableAgentStreamResult The result returned from the `stream()` method: - +> See the full API reference for [`DurableAgentStreamResult`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/DurableAgentStreamResult). ### GenerationSettings Settings that control model generation behavior. These can be set on the constructor or overridden per-stream call: - +> See the full API reference for [`GenerationSettings`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/GenerationSettings). ### PrepareStepInfo Information passed to the `prepareStep` callback: - +> See the full API reference for [`PrepareStepInfo`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/PrepareStepInfo). ### PrepareStepResult Return type from the `prepareStep` callback: - +> See the full API reference for [`PrepareStepResult`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/PrepareStepResult). ### TelemetrySettings Configuration for observability and telemetry: - +> See the full API reference for [`TelemetrySettings`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/TelemetrySettings). ### Callbacks @@ -141,31 +109,19 @@ export default TelemetrySettings;`} Called when streaming completes: - +> See the full API reference for [`StreamTextOnFinishCallback`](/docs/api-reference/workflow-ai/api/agent/durable-agent/type-aliases/StreamTextOnFinishCallback). #### StreamTextOnErrorCallback Called when an error occurs: - +> See the full API reference for [`StreamTextOnErrorCallback`](/docs/api-reference/workflow-ai/api/agent/durable-agent/type-aliases/StreamTextOnErrorCallback). #### StreamTextOnAbortCallback Called when the operation is aborted: - +> See the full API reference for [`StreamTextOnAbortCallback`](/docs/api-reference/workflow-ai/api/agent/durable-agent/type-aliases/StreamTextOnAbortCallback). ### Advanced Types @@ -173,31 +129,19 @@ export default StreamTextOnAbortCallback;`} Function to repair malformed tool calls: - +> See the full API reference for [`ToolCallRepairFunction`](/docs/api-reference/workflow-ai/api/agent/durable-agent/type-aliases/ToolCallRepairFunction). #### StreamTextTransform Transform applied to the stream: - +> See the full API reference for [`StreamTextTransform`](/docs/api-reference/workflow-ai/api/agent/durable-agent/type-aliases/StreamTextTransform). #### OutputSpecification Specification for structured output parsing: - +> See the full API reference for [`OutputSpecification`](/docs/api-reference/workflow-ai/api/agent/durable-agent/interfaces/OutputSpecification). ## Key Features diff --git a/docs/content/docs/api-reference/workflow-ai/meta.json b/docs/content/docs/api-reference/workflow-ai/meta.json new file mode 100644 index 0000000000..a3005a0fcb --- /dev/null +++ b/docs/content/docs/api-reference/workflow-ai/meta.json @@ -0,0 +1,4 @@ +{ + "title": "@workflow/ai", + "pages": ["...", "--- Generated API Reference ---", "...api"] +} diff --git a/docs/content/docs/api-reference/workflow-ai/workflow-chat-transport.mdx b/docs/content/docs/api-reference/workflow-ai/workflow-chat-transport.mdx index bde3bd1d58..974fa7ebc0 100644 --- a/docs/content/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +++ b/docs/content/docs/api-reference/workflow-ai/workflow-chat-transport.mdx @@ -42,19 +42,11 @@ export default function Chat() { ### Class - +> See the full API reference for [`WorkflowChatTransport`](/docs/api-reference/workflow-ai/api/index/classes/WorkflowChatTransport). ### WorkflowChatTransportOptions - +> See the full API reference for [`WorkflowChatTransportOptions`](/docs/api-reference/workflow-ai/api/index/interfaces/WorkflowChatTransportOptions). ## Key Features diff --git a/docs/content/docs/api-reference/workflow-api/get-hook-by-token.mdx b/docs/content/docs/api-reference/workflow-api/get-hook-by-token.mdx index 028c9b4047..170b568d54 100644 --- a/docs/content/docs/api-reference/workflow-api/get-hook-by-token.mdx +++ b/docs/content/docs/api-reference/workflow-api/get-hook-by-token.mdx @@ -27,23 +27,11 @@ export async function POST(request: Request) { ### Parameters - +> See the full API reference for [`getHookByToken`](/docs/api-reference/workflow-api/api/functions/getHookByToken). ### Returns -Returns a `Promise` that resolves to: - - +Returns a `Promise` that resolves to the hook object with run and metadata information. ## Examples diff --git a/docs/content/docs/api-reference/workflow-api/get-run.mdx b/docs/content/docs/api-reference/workflow-api/get-run.mdx index 47be7831de..da8e80ff35 100644 --- a/docs/content/docs/api-reference/workflow-api/get-run.mdx +++ b/docs/content/docs/api-reference/workflow-api/get-run.mdx @@ -21,59 +21,33 @@ const run = getRun("my-run-id"); ### Parameters - +> See the full API reference for [`getRun`](/docs/api-reference/workflow-api/api/functions/getRun). ### Returns Returns a `Run` object: - +> See the full API reference for [`Run`](/docs/api-reference/workflow-api/api/classes/Run). #### WorkflowReadableStream `run.getReadable()` returns a `WorkflowReadableStream` — a standard `ReadableStream` extended with a `getTailIndex()` helper: - +> See the full API reference for [`WorkflowReadableStream`](/docs/api-reference/workflow-api/api/type-aliases/WorkflowReadableStream). `getTailIndex()` returns the index of the last known chunk (0-based), or `-1` when no chunks have been written. This is useful when building [reconnection endpoints](/docs/ai/resumable-streams) that need to inform clients where the stream starts. #### WorkflowReadableStreamOptions - +> See the full API reference for [`WorkflowReadableStreamOptions`](/docs/api-reference/workflow-api/api/interfaces/WorkflowReadableStreamOptions). #### StopSleepOptions - +> See the full API reference for [`StopSleepOptions`](/docs/api-reference/workflow-api/api/interfaces/StopSleepOptions). #### StopSleepResult - +> See the full API reference for [`StopSleepResult`](/docs/api-reference/workflow-api/api/interfaces/StopSleepResult). ## Examples diff --git a/docs/content/docs/api-reference/workflow-api/get-world.mdx b/docs/content/docs/api-reference/workflow-api/get-world.mdx index 69c3396b26..5f7aacfce3 100644 --- a/docs/content/docs/api-reference/workflow-api/get-world.mdx +++ b/docs/content/docs/api-reference/workflow-api/get-world.mdx @@ -25,14 +25,7 @@ This function does not accept any parameters. ### Returns -Returns a `World` object: - - +Returns the [`World`](/docs/deploying/building-a-world) instance. ## World SDK diff --git a/docs/content/docs/api-reference/workflow-api/meta.json b/docs/content/docs/api-reference/workflow-api/meta.json new file mode 100644 index 0000000000..467bc369b1 --- /dev/null +++ b/docs/content/docs/api-reference/workflow-api/meta.json @@ -0,0 +1,4 @@ +{ + "title": "workflow/api", + "pages": ["...", "--- Generated API Reference ---", "...api"] +} diff --git a/docs/content/docs/api-reference/workflow-api/resume-hook.mdx b/docs/content/docs/api-reference/workflow-api/resume-hook.mdx index e98b8c092f..9c28ed24c8 100644 --- a/docs/content/docs/api-reference/workflow-api/resume-hook.mdx +++ b/docs/content/docs/api-reference/workflow-api/resume-hook.mdx @@ -38,23 +38,11 @@ export async function POST(request: Request) { ### Parameters - +> See the full API reference for [`resumeHook`](/docs/api-reference/workflow-api/api/functions/resumeHook). ### Returns -Returns a `Promise` that resolves to: - - +Returns a `Promise` that resolves to the hook object with run and metadata information. ## Examples diff --git a/docs/content/docs/api-reference/workflow-api/resume-webhook.mdx b/docs/content/docs/api-reference/workflow-api/resume-webhook.mdx index b4ee9f2008..fdf5a93088 100644 --- a/docs/content/docs/api-reference/workflow-api/resume-webhook.mdx +++ b/docs/content/docs/api-reference/workflow-api/resume-webhook.mdx @@ -41,12 +41,7 @@ export async function POST(request: Request) { ### Parameters - +> See the full API reference for [`resumeWebhook`](/docs/api-reference/workflow-api/api/functions/resumeWebhook). ### Returns diff --git a/docs/content/docs/api-reference/workflow-api/start.mdx b/docs/content/docs/api-reference/workflow-api/start.mdx index 293ba56741..b5ba7c1032 100644 --- a/docs/content/docs/api-reference/workflow-api/start.mdx +++ b/docs/content/docs/api-reference/workflow-api/start.mdx @@ -20,31 +20,17 @@ const run = await start(myWorkflow); // [!code highlight] ### Parameters - +> See the full API reference for [`start`](/docs/api-reference/workflow-api/api/functions/start). #### StartOptions - +> See the full API reference for [`StartOptions`](/docs/api-reference/workflow-api/api/type-aliases/StartOptions). ### Returns Returns a `Run` object: - +> See the full API reference for [`Run`](/docs/api-reference/workflow-api/api/classes/Run). Learn more about [`WorkflowReadableStreamOptions`](/docs/api-reference/workflow-api/get-run#workflowreadablestreamoptions). diff --git a/docs/content/docs/api-reference/workflow-errors/entity-conflict-error.mdx b/docs/content/docs/api-reference/workflow-errors/entity-conflict-error.mdx index d249089853..2a3eed9834 100644 --- a/docs/content/docs/api-reference/workflow-errors/entity-conflict-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/entity-conflict-error.mdx @@ -35,14 +35,7 @@ try { ### Properties - +> See the full API reference for [`EntityConflictError`](/docs/api-reference/workflow-errors/api/classes/EntityConflictError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/hook-not-found-error.mdx b/docs/content/docs/api-reference/workflow-errors/hook-not-found-error.mdx index 20dd65095d..10280fdf41 100644 --- a/docs/content/docs/api-reference/workflow-errors/hook-not-found-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/hook-not-found-error.mdx @@ -33,16 +33,7 @@ try { ### Properties - +> See the full API reference for [`HookNotFoundError`](/docs/api-reference/workflow-errors/api/classes/HookNotFoundError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/meta.json b/docs/content/docs/api-reference/workflow-errors/meta.json index 690112dffa..aef37e535a 100644 --- a/docs/content/docs/api-reference/workflow-errors/meta.json +++ b/docs/content/docs/api-reference/workflow-errors/meta.json @@ -11,6 +11,8 @@ "throttle-error", "entity-conflict-error", "run-expired-error", - "too-early-error" + "too-early-error", + "--- Generated API Reference ---", + "...api" ] } diff --git a/docs/content/docs/api-reference/workflow-errors/run-expired-error.mdx b/docs/content/docs/api-reference/workflow-errors/run-expired-error.mdx index aa9e6eb4a7..7befdc8927 100644 --- a/docs/content/docs/api-reference/workflow-errors/run-expired-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/run-expired-error.mdx @@ -33,14 +33,7 @@ try { ### Properties - +> See the full API reference for [`RunExpiredError`](/docs/api-reference/workflow-errors/api/classes/RunExpiredError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/step-not-registered-error.mdx b/docs/content/docs/api-reference/workflow-errors/step-not-registered-error.mdx index a4c4ec355b..f60f33e7bc 100644 --- a/docs/content/docs/api-reference/workflow-errors/step-not-registered-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/step-not-registered-error.mdx @@ -25,16 +25,7 @@ if (StepNotRegisteredError.is(error)) { // [!code highlight] ### Properties - +> See the full API reference for [`StepNotRegisteredError`](/docs/api-reference/workflow-errors/api/classes/StepNotRegisteredError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/throttle-error.mdx b/docs/content/docs/api-reference/workflow-errors/throttle-error.mdx index 4d7bc7596c..dff6c96007 100644 --- a/docs/content/docs/api-reference/workflow-errors/throttle-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/throttle-error.mdx @@ -35,16 +35,7 @@ try { ### Properties - +> See the full API reference for [`ThrottleError`](/docs/api-reference/workflow-errors/api/classes/ThrottleError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/too-early-error.mdx b/docs/content/docs/api-reference/workflow-errors/too-early-error.mdx index e333cbd0b7..252b0cb92b 100644 --- a/docs/content/docs/api-reference/workflow-errors/too-early-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/too-early-error.mdx @@ -35,16 +35,7 @@ try { ### Properties - +> See the full API reference for [`TooEarlyError`](/docs/api-reference/workflow-errors/api/classes/TooEarlyError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx b/docs/content/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx index b2eee91ead..d72be414a0 100644 --- a/docs/content/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx @@ -25,16 +25,7 @@ if (WorkflowNotRegisteredError.is(error)) { // [!code highlight] ### Properties - +> See the full API reference for [`WorkflowNotRegisteredError`](/docs/api-reference/workflow-errors/api/classes/WorkflowNotRegisteredError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx b/docs/content/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx index 3c3a6bc5ed..da15333bd5 100644 --- a/docs/content/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx @@ -29,16 +29,7 @@ try { ### Properties - +> See the full API reference for [`WorkflowRunCancelledError`](/docs/api-reference/workflow-errors/api/classes/WorkflowRunCancelledError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx b/docs/content/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx index f4136b4a65..dabb554f53 100644 --- a/docs/content/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx @@ -33,18 +33,7 @@ try { ### Properties - +> See the full API reference for [`WorkflowRunFailedError`](/docs/api-reference/workflow-errors/api/classes/WorkflowRunFailedError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx b/docs/content/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx index b27d7321c7..1c0c7e7d85 100644 --- a/docs/content/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx @@ -29,16 +29,7 @@ try { ### Properties - +> See the full API reference for [`WorkflowRunNotFoundError`](/docs/api-reference/workflow-errors/api/classes/WorkflowRunNotFoundError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-errors/workflow-world-error.mdx b/docs/content/docs/api-reference/workflow-errors/workflow-world-error.mdx index ac12e75ef3..3a040ad55c 100644 --- a/docs/content/docs/api-reference/workflow-errors/workflow-world-error.mdx +++ b/docs/content/docs/api-reference/workflow-errors/workflow-world-error.mdx @@ -37,22 +37,7 @@ try { ### Properties - +> See the full API reference for [`WorkflowWorldError`](/docs/api-reference/workflow-errors/api/classes/WorkflowWorldError). ### Static Methods diff --git a/docs/content/docs/api-reference/workflow-next/meta.json b/docs/content/docs/api-reference/workflow-next/meta.json new file mode 100644 index 0000000000..0fffea2425 --- /dev/null +++ b/docs/content/docs/api-reference/workflow-next/meta.json @@ -0,0 +1,4 @@ +{ + "title": "workflow/next", + "pages": ["...", "--- Generated API Reference ---", "...api"] +} diff --git a/docs/content/docs/api-reference/workflow-serde/meta.json b/docs/content/docs/api-reference/workflow-serde/meta.json index 856b0fc93e..c1dc88f107 100644 --- a/docs/content/docs/api-reference/workflow-serde/meta.json +++ b/docs/content/docs/api-reference/workflow-serde/meta.json @@ -1,3 +1,9 @@ { - "pages": ["...", "workflow-serialize", "workflow-deserialize"] + "pages": [ + "...", + "workflow-serialize", + "workflow-deserialize", + "--- Generated API Reference ---", + "...api" + ] } diff --git a/docs/content/docs/api-reference/workflow-serde/workflow-deserialize.mdx b/docs/content/docs/api-reference/workflow-serde/workflow-deserialize.mdx index 6b2e84846c..dc2f2208b3 100644 --- a/docs/content/docs/api-reference/workflow-serde/workflow-deserialize.mdx +++ b/docs/content/docs/api-reference/workflow-serde/workflow-deserialize.mdx @@ -34,17 +34,7 @@ static [WORKFLOW_DESERIALIZE](data: SerializableData): T ### Parameters - +> See the full API reference for [`WORKFLOW_DESERIALIZE`](/docs/api-reference/workflow-serde/api/variables/WORKFLOW_DESERIALIZE). ### Returns diff --git a/docs/content/docs/api-reference/workflow-serde/workflow-serialize.mdx b/docs/content/docs/api-reference/workflow-serde/workflow-serialize.mdx index 5c70c95e1d..53edc5537f 100644 --- a/docs/content/docs/api-reference/workflow-serde/workflow-serialize.mdx +++ b/docs/content/docs/api-reference/workflow-serde/workflow-serialize.mdx @@ -34,16 +34,7 @@ static [WORKFLOW_SERIALIZE](instance: T): SerializableData ### Parameters - +> See the full API reference for [`WORKFLOW_SERIALIZE`](/docs/api-reference/workflow-serde/api/variables/WORKFLOW_SERIALIZE). ### Returns diff --git a/docs/content/docs/api-reference/workflow/create-hook.mdx b/docs/content/docs/api-reference/workflow/create-hook.mdx index 00e5afccd1..51c51372e8 100644 --- a/docs/content/docs/api-reference/workflow/create-hook.mdx +++ b/docs/content/docs/api-reference/workflow/create-hook.mdx @@ -29,39 +29,19 @@ export async function hookWorkflow() { ### Parameters - +> See the full API reference for [`createHook`](/docs/api-reference/workflow/api/functions/createHook). #### HookOptions - +> See the full API reference for [`HookOptions`](/docs/api-reference/workflow/api/interfaces/HookOptions). ### Returns - +> See the full API reference for [`createHook`](/docs/api-reference/workflow/api/functions/createHook). #### Hook - +> See the full API reference for [`Hook`](/docs/api-reference/workflow/api/interfaces/Hook). The returned `Hook` object also implements `AsyncIterable`, which allows you to iterate over incoming payloads using `for await...of` syntax. diff --git a/docs/content/docs/api-reference/workflow/create-webhook.mdx b/docs/content/docs/api-reference/workflow/create-webhook.mdx index a6d56151b4..c0fe1f6be9 100644 --- a/docs/content/docs/api-reference/workflow/create-webhook.mdx +++ b/docs/content/docs/api-reference/workflow/create-webhook.mdx @@ -35,21 +35,11 @@ export async function webhookWorkflow() { ### Parameters - +> See the full API reference for [`createWebhook`](/docs/api-reference/workflow/api/functions/createWebhook). ### Returns - +> See the full API reference for [`createWebhook`](/docs/api-reference/workflow/api/functions/createWebhook). The returned `Webhook` object has: diff --git a/docs/content/docs/api-reference/workflow/define-hook.mdx b/docs/content/docs/api-reference/workflow/define-hook.mdx index ad0d697f30..34a1782585 100644 --- a/docs/content/docs/api-reference/workflow/define-hook.mdx +++ b/docs/content/docs/api-reference/workflow/define-hook.mdx @@ -37,32 +37,11 @@ export async function nameWorkflow() { ### Parameters - +> See the full API reference for [`defineHook`](/docs/api-reference/workflow/api/functions/defineHook). ### Returns - { - /** - -* Creates a new hook with the defined payload type. - */ - create: (options?: HookOptions) => Hook; - - /** - -* Resumes a hook by sending a payload with the defined type. - */ - resume: (token: string, payload: T) => Promise; -} -export default DefineHook;`} -/> +> See the full API reference for [`TypedHook`](/docs/api-reference/workflow/api/interfaces/TypedHook). ## Examples diff --git a/docs/content/docs/api-reference/workflow/fatal-error.mdx b/docs/content/docs/api-reference/workflow/fatal-error.mdx index 8c31e1e611..a373e8ce71 100644 --- a/docs/content/docs/api-reference/workflow/fatal-error.mdx +++ b/docs/content/docs/api-reference/workflow/fatal-error.mdx @@ -31,14 +31,4 @@ async function fallibleStep() { ### Parameters - +> See the full API reference for [`FatalError`](/docs/api-reference/workflow/api/classes/FatalError). diff --git a/docs/content/docs/api-reference/workflow/fetch.mdx b/docs/content/docs/api-reference/workflow/fetch.mdx index e1d18f44ac..cc5879e337 100644 --- a/docs/content/docs/api-reference/workflow/fetch.mdx +++ b/docs/content/docs/api-reference/workflow/fetch.mdx @@ -35,23 +35,13 @@ async function apiWorkflow() { Accepts the same arguments as web [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch) - +> See the full API reference for [`fetch`](/docs/api-reference/workflow/api/functions/fetch). ### Returns Returns the same response as web [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Window/fetch) - +> See the full API reference for [`fetch`](/docs/api-reference/workflow/api/functions/fetch). ## Examples diff --git a/docs/content/docs/api-reference/workflow/get-step-metadata.mdx b/docs/content/docs/api-reference/workflow/get-step-metadata.mdx index 27cdfaa754..53a1421c16 100644 --- a/docs/content/docs/api-reference/workflow/get-step-metadata.mdx +++ b/docs/content/docs/api-reference/workflow/get-step-metadata.mdx @@ -65,17 +65,8 @@ async function chargeUser(userId: string, amount: number) { ### Parameters - +> See the full API reference for [`getStepMetadata`](/docs/api-reference/workflow/api/functions/getStepMetadata). ### Returns - +> See the full API reference for [`StepMetadata`](/docs/api-reference/workflow/api/interfaces/StepMetadata). diff --git a/docs/content/docs/api-reference/workflow/get-workflow-metadata.mdx b/docs/content/docs/api-reference/workflow/get-workflow-metadata.mdx index 23b3573a2d..1ead506145 100644 --- a/docs/content/docs/api-reference/workflow/get-workflow-metadata.mdx +++ b/docs/content/docs/api-reference/workflow/get-workflow-metadata.mdx @@ -33,17 +33,8 @@ async function testWorkflow() { ### Parameters - +> See the full API reference for [`getWorkflowMetadata`](/docs/api-reference/workflow/api/functions/getWorkflowMetadata). ### Returns - +> See the full API reference for [`WorkflowMetadata`](/docs/api-reference/workflow/api/interfaces/WorkflowMetadata). diff --git a/docs/content/docs/api-reference/workflow/get-writable.mdx b/docs/content/docs/api-reference/workflow/get-writable.mdx index a82257bcd4..6503a12f3b 100644 --- a/docs/content/docs/api-reference/workflow/get-writable.mdx +++ b/docs/content/docs/api-reference/workflow/get-writable.mdx @@ -51,21 +51,11 @@ async function writeToStream(writable: WritableStream) { ### Parameters - +> See the full API reference for [`getWritable`](/docs/api-reference/workflow/api/functions/getWritable). ### Returns - +> See the full API reference for [`getWritable`](/docs/api-reference/workflow/api/functions/getWritable). Returns a `WritableStream` where `W` is the type of data you plan to write to the stream. diff --git a/docs/content/docs/api-reference/workflow/meta.json b/docs/content/docs/api-reference/workflow/meta.json index b695df1dca..17630ac1cb 100644 --- a/docs/content/docs/api-reference/workflow/meta.json +++ b/docs/content/docs/api-reference/workflow/meta.json @@ -1,3 +1,9 @@ { - "pages": ["...", "fatal-error", "retryable-error"] + "pages": [ + "...", + "fatal-error", + "retryable-error", + "--- Generated API Reference ---", + "...api" + ] } diff --git a/docs/content/docs/api-reference/workflow/retryable-error.mdx b/docs/content/docs/api-reference/workflow/retryable-error.mdx index 7783e4c981..53193b64f1 100644 --- a/docs/content/docs/api-reference/workflow/retryable-error.mdx +++ b/docs/content/docs/api-reference/workflow/retryable-error.mdx @@ -35,24 +35,11 @@ The difference between `Error` and `RetryableError` may not be entirely obvious, ### Parameters - +> See the full API reference for [`RetryableError`](/docs/api-reference/workflow/api/classes/RetryableError). #### RetryableErrorOptions - +> See the full API reference for [`RetryableErrorOptions`](/docs/api-reference/workflow/api/interfaces/RetryableErrorOptions). ## Examples diff --git a/docs/content/docs/api-reference/workflow/sleep.mdx b/docs/content/docs/api-reference/workflow/sleep.mdx index 86d7b14f9e..275f93d79e 100644 --- a/docs/content/docs/api-reference/workflow/sleep.mdx +++ b/docs/content/docs/api-reference/workflow/sleep.mdx @@ -30,12 +30,7 @@ async function testWorkflow() { ### Parameters - +> See the full API reference for [`sleep`](/docs/api-reference/workflow/api/functions/sleep). ## Examples diff --git a/docs/copy-api-docs.sh b/docs/copy-api-docs.sh new file mode 100755 index 0000000000..2dbf001177 --- /dev/null +++ b/docs/copy-api-docs.sh @@ -0,0 +1,51 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Copies typedoc-generated API docs from each package into the docs content directory. +# Each package's output goes into an `api/` subdirectory under its API reference section. + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +CONTENT_DIR="$SCRIPT_DIR/content/docs/api-reference" + +copy_docs() { + local src="$1" dest="$2" + if [ ! -d "$src" ]; then + echo " [skip] $src (not found)" + return + fi + rm -rf "$dest" + mkdir -p "$dest" + cp -r "$src"/* "$dest" + echo " [copy] $src -> $dest" +} + +echo "Copying typedoc-generated API docs..." + +# workflow (main package) +copy_docs "$ROOT_DIR/packages/workflow/typedoc-out" "$CONTENT_DIR/workflow/api" + +# workflow/api +copy_docs "$ROOT_DIR/packages/workflow/typedoc-out-api" "$CONTENT_DIR/workflow-api/api" + +# workflow/errors +copy_docs "$ROOT_DIR/packages/errors/typedoc-out" "$CONTENT_DIR/workflow-errors/api" + +# @workflow/serde +copy_docs "$ROOT_DIR/packages/serde/typedoc-out" "$CONTENT_DIR/workflow-serde/api" + +# workflow/next +copy_docs "$ROOT_DIR/packages/next/typedoc-out" "$CONTENT_DIR/workflow-next/api" + +# @workflow/ai +copy_docs "$ROOT_DIR/packages/ai/typedoc-out" "$CONTENT_DIR/workflow-ai/api" + +# @workflow/vitest +copy_docs "$ROOT_DIR/packages/vitest/typedoc-out" "$CONTENT_DIR/vitest/api" + +# Add meta.json to type-aliases directories for clean sidebar labels +find "$CONTENT_DIR" -type d -name "type-aliases" | while read -r dir; do + echo '{ "title": "Type Aliases" }' > "$dir/meta.json" +done + +echo "Done." diff --git a/docs/lib/tsdoc/base.ts b/docs/lib/tsdoc/base.ts deleted file mode 100644 index 7b5393f484..0000000000 --- a/docs/lib/tsdoc/base.ts +++ /dev/null @@ -1,501 +0,0 @@ -import path from 'node:path'; -import type { - ExportedDeclarations, - Node as TsNode, - Symbol as TsSymbol, - Type, -} from 'ts-morph'; -import { Project, SyntaxKind, ts } from 'ts-morph'; -import type { - BaseArgs, - GeneratedDefinition, - GeneratedFunction, - GeneratedType, - Tags, - TypeField, -} from './types'; - -const DEFAULT_FILENAME = '$.ts'; - -const project = new Project({ - compilerOptions: { - exactOptionalPropertyTypes: true, - strictNullChecks: true, - moduleResolution: ts.ModuleResolutionKind.Bundler, - esModuleInterop: true, - allowSyntheticDefaultImports: true, - baseUrl: process.cwd(), - paths: { - '@workflow/core/*': ['./packages/core/src/*'], - }, - }, -}); - -const IGNORED_TYPES = new Set([ - 'Date', - 'RegExp', - 'ReactElement', - 'Element', - 'CSSProperties', -]); - -let compilerObject: ts.TypeChecker; - -/** - * Finds and returns the export declaration for the specified export name - */ -function findExportDeclaration( - sourceFile: ReturnType, - exportName: string -): ExportedDeclarations { - const output: ExportedDeclarations[] = []; - for (const [key, declaration] of sourceFile.getExportedDeclarations()) { - if (key === exportName) output.push(...declaration); - } - - let declaration = output[0]; - if (!declaration) { - // Try to handle re-exports by looking for the actual function - const exportAssignments = sourceFile.getExportAssignments(); - const defaultExport = exportAssignments.find( - (exp) => exp.isExportEquals() === false - ); - - if (defaultExport && exportName === 'default') { - const expression = defaultExport.getExpression(); - if (expression) { - // Try to resolve the symbol from the expression - const symbol = expression.getSymbol(); - if (symbol) { - const declarations = symbol.getDeclarations(); - if (declarations.length > 0) { - declaration = declarations[0] as ExportedDeclarations; - } - } - } - } - - if (!declaration) { - throw new Error( - `Can't find "${exportName}" declaration. This might be a re-exported function from another module. Try providing the full function definition instead of re-exporting.` - ); - } - } - - return declaration; -} - -/** - * Generates a documentation definition for a given code snippet and export name. - */ -export function generateDefinition({ - code, - exportName = 'default', - flattened = false, -}: BaseArgs): GeneratedDefinition & (GeneratedType | GeneratedFunction) { - compilerObject ??= project.getTypeChecker().compilerObject; - - const sourceFile = project.createSourceFile(DEFAULT_FILENAME, code, { - overwrite: true, - }); - - const declaration = findExportDeclaration(sourceFile, exportName); - - const declarationFilePath = declaration.getSourceFile().getFilePath(); - const filePath = path.relative(process.cwd(), declarationFilePath); - const symbol = declaration.getSymbolOrThrow(); - const { comment, tags } = getCommentAndTags(declaration); - const description = ts.displayPartsToString(comment); - - if (tags.returns && typeof tags.returns === 'string') { - tags.returns = replaceJsDocLinks(tags.returns); - } - - const definition: GeneratedDefinition = { - ...(filePath !== DEFAULT_FILENAME && { filePath }), - name: symbol.getName(), - ...(description && { description }), - ...(Object.keys(tags).length && { tags }), - }; - - const declarationType = declaration.getType(); - const callSignatures = declarationType.getCallSignatures(); - const isFunction = callSignatures.length > 0; - - if (!isFunction) { - const entries = declarationType - .getProperties() - .filter((prop) => { - const propName = prop.getName(); - // Filter out Symbol properties and internal methods - if (propName.startsWith('__') || propName.includes('@')) { - return false; - } - // Filter out 'then' method for Promise-like objects - if (propName === 'then') { - return false; - } - return true; - }) - .flatMap((prop) => - getDocEntry({ - symbol: prop, - declaration, - flattened, - }) - ) - .filter((entry) => !entry.tags || !('internal' in entry.tags)); - - if (!entries.length) { - const typeName = declarationType.getText(); - if (typeName === 'any') { - throw new Error( - 'Your type is resolved as "any", it seems like you have an issue in "generateDefinition.code" argument.' - ); - } - throw new Error( - `No properties found, check if your type "${typeName}" exist.` - ); - } - - return { - ...definition, - entries, - }; - } - - return { - ...definition, - signatures: callSignatures.map((signature) => { - const params = signature.getParameters(); - - // Get JSDoc tags from the signature for @param descriptions - const signatureDecl = signature.getDeclaration(); - const signatureTags = - 'getJsDocs' in signatureDecl - ? signatureDecl - .getJsDocs() - .flatMap((jsDoc: any) => - jsDoc - .getTags() - .filter( - (tag: any) => - tag.getTagName() === 'param' || - tag.getTagName() === 'throws' - ) - ) - : []; - - const typeParams = params.flatMap((param) => { - const baseEntry = getDocEntry({ - symbol: param, - declaration, - flattened, - }); - - // Try to find @param description from signature JSDoc - const paramName = param.getName(); - const paramTag = signatureTags.find((tag: any) => { - const tagText = tag.getText(); - return tagText.includes(paramName); - }); - - if (paramTag && !Array.isArray(baseEntry)) { - let tagText = paramTag.getText(); - tagText = tagText.replace(/^\s*\*\s*/, ''); - const match = tagText.match( - new RegExp(`${paramName}\\s*-\\s*(.+?)(?:\\s*\\*)?$`, 's') - ); - if (match) { - baseEntry.description = replaceJsDocLinks( - match[1] - .replace(/\s*\*\s*$/, '') - .replace(/^\s*\*\s*/gm, '') - .trim() - ); - } - } - - return baseEntry; - }); - - const returnType = signature - .getDeclaration() - .getSignature() - .getReturnType(); - - let flattenedReturnType: GeneratedFunction['signatures'][number]['returns'] = - flattened && shouldFlattenType(returnType) - ? returnType.getProperties().flatMap((childProp) => - getDocEntry({ - symbol: childProp, - declaration, - flattened, - }) - ) - : []; - - if (!flattenedReturnType.length) { - flattenedReturnType = { - type: getFormattedText(returnType), - }; - } - - return { - params: typeParams, - returns: flattenedReturnType, - throws: tags.throws as string[] | undefined, - }; - }), - }; -} - -/** - * Gets the comment and tags for a given declaration. - */ -function getCommentAndTags(declaration: ExportedDeclarations): { - comment: ts.SymbolDisplayPart[]; - tags: Tags; -} { - const symbol = declaration.getSymbolOrThrow(); - const comment = symbol.compilerSymbol.getDocumentationComment(compilerObject); - - if (!comment.length) { - const aliasSymbol = declaration.getType().getAliasSymbol(); - if (aliasSymbol) { - return { - comment: - aliasSymbol.compilerSymbol.getDocumentationComment(compilerObject), - tags: getTags(aliasSymbol), - }; - } - } - - return { - comment, - tags: getTags(symbol), - }; -} - -/** - * Gets a documentation entry for a given symbol. - */ -function getDocEntry({ - symbol, - declaration, - flattened, - prefix = '', -}: { - symbol: TsSymbol; - declaration: ExportedDeclarations; - flattened: boolean; - prefix?: string; -}): TypeField | TypeField[] { - const originalSubType = project - .getTypeChecker() - .getTypeOfSymbolAtLocation(symbol, declaration); - const valueDeclaration = symbol.getValueDeclaration(); - const isFunctionParameter = - valueDeclaration && valueDeclaration.getKind() === SyntaxKind.Parameter; - - const subType = isFunctionParameter - ? originalSubType.getNonNullableType() - : originalSubType; - - if (flattened && shouldFlattenType(subType)) { - return subType.getProperties().flatMap((childProp) => { - const childPrefix = isFunctionParameter - ? symbol.getName().replace(/^_+/, '') - : symbol.getName(); - const newPrefix = - typeof +childPrefix === 'number' && !Number.isNaN(+childPrefix) - ? `[${childPrefix}] ${originalSubType.isNullable() ? '?' : ''}` - : childPrefix; - return getDocEntry({ - symbol: childProp, - declaration, - flattened, - prefix: prexify(prefix, newPrefix), - }); - }); - } - - const tags = getTags(symbol); - const name = symbol.getName(); - const typeDescription = replaceJsDocLinks( - ts.displayPartsToString( - symbol.compilerSymbol.getDocumentationComment(compilerObject) - ) - ).replace(/^- /, ''); - - const isOptional = isFunctionParameter - ? (valueDeclaration.asKind(SyntaxKind.Parameter)?.isOptional() ?? false) - : symbol.isOptional(); - - const typeName = getTypeName({ - tags, - symbol, - subType, - valueDeclaration, - }); - - return { - name: prexify(prefix, name), - type: typeName, - ...(typeDescription && { description: typeDescription }), - ...(Object.keys(tags).length && { tags }), - ...(isOptional && { optional: isOptional }), - }; -} - -function getTypeName({ - tags, - symbol, - subType, - valueDeclaration, -}: { - tags: Tags; - symbol: TsSymbol; - subType: Type; - valueDeclaration: TsNode | undefined; -}) { - const aliasSymbol = subType.getAliasSymbol(); - const subTypeTags = aliasSymbol ? getTags(aliasSymbol) : {}; - const remarksValue = tags.remarks || subTypeTags.remarks; - const typeName = - typeof remarksValue === 'string' - ? remarksValue.match(/^`(?.+)`/)?.groups?.name - : undefined; - - if (typeName) { - return typeName; - } - - const declarationNode = symbol - .getDeclarations() - .find( - (d) => - ts.isPropertySignature(d.compilerNode) || ts.isParameter(d.compilerNode) - ); - const typeNode = - declarationNode?.asKind(SyntaxKind.PropertySignature) ?? - declarationNode?.asKind(SyntaxKind.Parameter); - const t = typeNode?.getTypeNode()?.getText(); - - const useTypeNode = - t && - (t.startsWith('Partial<') || - ['React.ReactNode', 'React.ReactElement'].includes(t)); - - if (useTypeNode) { - return t; - } - - const isInline = 'inline' in tags || 'inline' in subTypeTags; - - if (!isInline) { - const typeOf = valueDeclaration?.getType() ?? symbol.getDeclaredType(); - return typeOf.isUnknown() ? 'unknown' : getFormattedText(subType); - } - - const [signature] = subType.getCallSignatures(); - const isFunction = !!signature; - - if (isFunction) { - const params = signature.getParameters().map((param) => { - const paramDecl = param.getDeclarations()[0]!; - const paramType = project - .getTypeChecker() - .getTypeOfSymbolAtLocation(param, paramDecl); - const inlineParamAlias = paramType.getNonNullableType().getAliasSymbol(); - const paramTags = inlineParamAlias && getTags(inlineParamAlias); - - const paramTypeStr = - paramTags && 'inline' in paramTags - ? inlineParamAlias - .getDeclarations()[0]! - .asKindOrThrow(SyntaxKind.TypeAliasDeclaration) - .getTypeNodeOrThrow() - .getText() - : getFormattedText(paramType); - const optional = paramDecl - .asKindOrThrow(SyntaxKind.Parameter) - .isOptional(); - - return `${param.getName()}${optional ? '?' : ''}: ${paramTypeStr}`; - }); - - return `(${params.join(', ')}) => ${getFormattedText(signature.getReturnType())}`; - } - - const [aliasDecl] = aliasSymbol!.getDeclarations(); - if (!aliasDecl) { - throw new Error("Can't find alias declaration for type."); - } - const inlineNode = aliasDecl - .asKindOrThrow(SyntaxKind.TypeAliasDeclaration) - .getTypeNodeOrThrow(); - return inlineNode.getText(); -} - -function prexify(prefix: string, name: string): string { - return prefix ? [prefix, name].join('.') : name; -} - -function shouldFlattenType(t: Type): boolean { - if ( - !t.isObject() || - t.isArray() || - t.isTuple() || - t.getCallSignatures().length > 0 || - t.getText() === '{}' || - !t.getProperties().length - ) { - return false; - } - - try { - const baseName = t.getSymbolOrThrow().getName(); - if (IGNORED_TYPES.has(baseName)) return false; - return t.isInterface() || baseName === '__type' || baseName === '__object'; - } catch { - console.error(`Symbol "${t.getText()}" isn't found.`); - return false; - } -} - -function getTags(prop: TsSymbol): Tags { - const tags: Record = Object.create(null); - for (const tag of prop.getJsDocTags()) { - const tagName = tag.getName(); - const tagValue = ts.displayPartsToString(tag.getText()); - switch (tagName) { - case 'throws': - if (!tags.throws) { - tags.throws = []; - } - (tags.throws as string[]).push(tagValue); - break; - case 'then': - continue; - default: - if (tagName in tags) { - tags[tagName] += `\n${tagValue}`; - } else { - tags[tagName] = tagValue; - } - } - } - return tags; -} - -function getFormattedText(t: Type): string { - return t.getText( - undefined, - ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope - ); -} - -function replaceJsDocLinks(md: string): string { - return md.replaceAll(/{@link (?[^}]*)}/g, '$1'); -} diff --git a/docs/lib/tsdoc/index.ts b/docs/lib/tsdoc/index.ts deleted file mode 100644 index ae6efd1f72..0000000000 --- a/docs/lib/tsdoc/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { generateDefinition } from './base'; -export { TSDoc } from './tsdoc'; -export type * from './types'; diff --git a/docs/lib/tsdoc/tsdoc.tsx b/docs/lib/tsdoc/tsdoc.tsx deleted file mode 100644 index 6642fb48b4..0000000000 --- a/docs/lib/tsdoc/tsdoc.tsx +++ /dev/null @@ -1,435 +0,0 @@ -import cn from 'clsx'; -import Slugger from 'github-slugger'; -import Link from 'next/link'; -import type { FC, ReactElement, ReactNode } from 'react'; -import { Callout } from '@/components/geistdocs/callout'; -import { generateDefinition } from './base'; -import type { GeneratedFunction, TypeField } from './types'; - -type TSDocProps = { - definition: string; - typeLinkMap?: Record; - noParametersContent?: ReactNode; - showSections: ('parameters' | 'returns' | 'throws')[]; -}; - -const classes = { - card: cn('rounded-sm transition-colors'), - anchor: cn( - 'absolute top-2 right-2 text-lg font-black', - 'before:content-["#"] hover:text-foreground', - 'px-2 py-1 opacity-0 group-hover:opacity-100 transition-opacity' - ), -}; - -export const TSDoc: FC = ({ - definition: rawDefinition, - typeLinkMap = {}, - noParametersContent = ( -

- This function does not accept any parameters. -

- ), - showSections = ['parameters', 'returns'], -}) => { - const definition = generateDefinition({ - code: rawDefinition, - }); - const showParameters = showSections.includes('parameters'); - const showReturns = showSections.includes('returns'); - const showThrows = showSections.includes('throws'); - if ('entries' in definition) { - return ( - - ); - } - - const { signatures } = definition; - const withSignatures = signatures.length > 1; - - if (!withSignatures) { - return ( - - ); - } - - return ( -
- This function has multiple signatures. - {signatures.map((signature, index) => ( -
-

Signature {index + 1}

- -
- ))} -
- ); -}; - -function FunctionSignature({ - signature, - index = '', - showParameters = true, - showReturns = true, - showThrows = true, - noParametersContent = ( -

- This function does not accept any parameters. -

- ), - typeLinkMap = {}, -}: { - signature: GeneratedFunction['signatures'][number]; - index?: string | number; - showParameters?: boolean; - showReturns?: boolean; - showThrows?: boolean; - noParametersContent?: ReactNode; - typeLinkMap?: TSDocProps['typeLinkMap']; -}) { - const slugger = new Slugger(); - const unnamedReturnId = `returns${index}`; - - return ( -
- {showParameters && ( -
- {signature.params.length ? ( - - ) : ( - noParametersContent - )} -
- )} - {showReturns && ( -
- {Array.isArray(signature.returns) ? ( -
- - - - - - - - - - {signature.returns.map((prop) => { - const id = slugger.slug(prop.name); - return ( - - - - - - ); - })} - -
NameTypeDescription
- {linkify(prop.description || '', typeLinkMap)} -
-
- ) : ( -
- - {linkify(signature.returns.type, typeLinkMap)} - -
- )} -
- )} - {showThrows && ( -
- {signature.throws?.length ? ( - - - - - - - - - {signature.throws.map((throwsItem, index) => { - const match = throwsItem.match(/^`?([^`\s]+)`?\s*-\s*(.+)$/); - const type = match ? match[1] : throwsItem; - const description = match ? match[2] : ''; - const id = `throws-${index}`; - - return ( - - - - - ); - })} - -
TypeDescription
- - {linkify(type, typeLinkMap)} - - - {description && ( -

- {linkify(description, typeLinkMap)} -

- )} -
- ) : ( -

- This function does not throw any errors. -

- )} -
- )} -
- ); -} - -const Row: FC<{ - children: ReactNode; - id: string; -}> = ({ children, id }) => { - return ( - - {children} - - ); -}; - -const NameCell: FC<{ - name: string; - optional?: boolean; -}> = ({ name, optional }) => { - return ( - - {name && ( - - {name} - - )} - - ); -}; - -const TypeCell: FC<{ - type: string; - typeLinkMap: TSDocProps['typeLinkMap']; -}> = ({ type, typeLinkMap }) => { - return ( - {linkify(type, typeLinkMap)} - ); -}; - -const FieldsTable: FC<{ - fields: TypeField[]; - typeLinkMap: TSDocProps['typeLinkMap']; -}> = ({ fields, typeLinkMap }) => { - const slugger = new Slugger(); - - return ( - - - - - - - - - - {fields.map((field) => { - const id = slugger.slug(field.name); - const tags = field.tags ?? {}; - const description = [ - field.description || tags.description, - tags.deprecated && `**Deprecated**: ${tags.deprecated}`, - ] - .filter(Boolean) - .join('\n'); - - return ( - - - - - - ); - })} - -
NameTypeDescription
- {linkify(description, typeLinkMap)} -
- ); -}; - -function linkify( - text: string, - typeLinkMap: TSDocProps['typeLinkMap'] = {} -): ReactNode { - // Combined regex to match markdown links and inline code - const markdownRegex = /(\[([^\]]+)\]\(([^)]+)\))|(`([^`]+)`)/g; - - // Split the text by markdown elements - const parts: (string | ReactElement)[] = []; - let lastIndex = 0; - let match: RegExpExecArray | null; - - // Reset regex state to ensure consistent behavior across calls - markdownRegex.lastIndex = 0; - match = markdownRegex.exec(text); - while (match !== null) { - // Add text before the match - if (match.index > lastIndex) { - parts.push(text.substring(lastIndex, match.index)); - } - - if (match[1]) { - // It's a markdown link: [text](url) - const linkText = match[2]; - const linkUrl = match[3]; - - // Check if the link text contains inline code - if (linkText.includes('`')) { - const codeParts = linkText.split(/`([^`]+)`/); - const linkContent = codeParts - .map((part, i) => { - if (i % 2 === 1) { - // It's code - return ( - - {part} - - ); - } - return part; - }) - .filter(Boolean); - - parts.push( - - {linkContent} - - ); - } else { - parts.push( - - {linkText} - - ); - } - } else if (match[4]) { - // It's inline code: `code` - const codeText = match[5]; - parts.push( - - {codeText} - - ); - } - - lastIndex = match.index + match[0].length; - match = markdownRegex.exec(text); - } - - // Add any remaining text - if (lastIndex < text.length) { - parts.push(text.substring(lastIndex)); - } - - // If no markdown links were found, use the original logic for type links - if (parts.length === 0) { - const result: (string | ReactElement)[] = []; - const chunks = text.match(/(\w+|\W+)/g) || []; - - for (const chunk of chunks) { - const href = Object.hasOwn(typeLinkMap, chunk) - ? typeLinkMap[chunk] - : undefined; - if (href) { - result.push( - - {chunk} - - ); - continue; - } - if (typeof result.at(-1) === 'string') { - result[result.length - 1] += chunk; - continue; - } - result.push(chunk); - } - return result; - } - - // Process remaining text parts for type links - return parts.flatMap((part, index) => { - if (typeof part !== 'string') return part; - - // Apply type link mapping to text parts - const chunks = part.match(/(\w+|\W+)/g) || []; - const processedChunks: (string | ReactElement)[] = []; - - for (const chunk of chunks) { - const href = Object.hasOwn(typeLinkMap, chunk) - ? typeLinkMap[chunk] - : undefined; - if (href) { - processedChunks.push( - - {chunk} - - ); - } else { - if (typeof processedChunks[processedChunks.length - 1] === 'string') { - processedChunks[processedChunks.length - 1] += chunk; - } else { - processedChunks.push(chunk); - } - } - } - - return processedChunks.length === 1 ? processedChunks[0] : processedChunks; - }); -} diff --git a/docs/lib/tsdoc/types.ts b/docs/lib/tsdoc/types.ts deleted file mode 100644 index d4acce4284..0000000000 --- a/docs/lib/tsdoc/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -export type Tags = Record; - -export type ReturnField = { - type: string; -}; - -export type GeneratedDefinition = { - filePath?: string; - name: string; - description?: string; - tags?: Tags; -}; - -export type GeneratedFunction = { - signatures: { - params: TypeField[]; - returns: TypeField[] | ReturnField; - throws?: string[]; - }[]; -}; - -export type GeneratedType = { - entries: TypeField[]; -}; - -export type TypeField = { - name: string; - type: string; - description?: string; - optional?: boolean; - tags?: Tags; -}; - -export type ThrowField = { - type: string; - description?: string; -}; - -export type BaseArgs = { - code: string; - exportName?: string; - flattened?: boolean; -}; diff --git a/docs/package.json b/docs/package.json index 3879797b6e..a9cd47814d 100644 --- a/docs/package.json +++ b/docs/package.json @@ -8,7 +8,7 @@ "dev": "next dev --turbo", "start": "next start", "postinstall": "fumadocs-mdx", - "prebuild": "node scripts/pack.ts", + "prebuild": "node scripts/pack.ts && ./copy-api-docs.sh", "lint": "biome check", "lint:links": "bun ./scripts/lint.ts", "format": "biome format --write", @@ -56,7 +56,6 @@ "feed": "5.1.0", "fumadocs-core": "16.2.2", "fumadocs-mdx": "14.0.4", - "fumadocs-typescript": "^4.0.13", "fumadocs-ui": "16.2.2", "github-slugger": "^2.0.0", "input-otp": "^1.4.2", @@ -93,7 +92,6 @@ "bun": "^1.3.0", "postcss": "^8.5.6", "tailwindcss": "^4.1.17", - "ts-morph": "^27.0.0", "tw-animate-css": "^1.4.0", "typescript": "catalog:" } diff --git a/package.json b/package.json index 7cf5becf35..c41fa32fff 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ "husky": "^9.1.7", "lint-staged": "^16.2.7", "turbo": "^2.8.11", + "typedoc": "0.28.18", + "typedoc-plugin-frontmatter": "1.3.1", + "typedoc-plugin-markdown": "^4.11.0", "typescript": "catalog:", "vitest": "catalog:" }, @@ -38,6 +41,7 @@ "test:docs": "pnpm --filter @workflow/docs-typecheck test:docs", "bench": "vitest bench packages/core/e2e/bench.bench.ts", "bench:local": "DEPLOYMENT_URL=http://localhost:3000 APP_NAME=nextjs-turbopack vitest bench packages/core/e2e/bench.bench.ts", + "typedoc": "turbo typedoc", "lint": "biome check", "format": "biome format --write", "changeset": "changeset", diff --git a/packages/ai/package.json b/packages/ai/package.json index 89bc11404b..fd534b7c55 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -63,6 +63,7 @@ "build": "tsc", "clean": "tsc --build --clean && rm -rf docs ||:", "test": "vitest run", + "typedoc": "typedoc", "prepack": "mkdir -p docs && cp -r ../../docs/content/docs/ai ./docs/ && cp -r ../../docs/content/docs/api-reference/workflow-ai ./docs/", "postpack": "rm -rf docs" }, diff --git a/packages/ai/typedoc.json b/packages/ai/typedoc.json new file mode 100644 index 0000000000..00f30852e1 --- /dev/null +++ b/packages/ai/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "@workflow/ai", + "entryPoints": ["./src/index.ts", "./src/agent/durable-agent.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/packages/errors/package.json b/packages/errors/package.json index 7caec02b44..9f0689a57b 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -26,7 +26,8 @@ "build": "tsc", "dev": "tsc --watch", "clean": "tsc --build --clean && rm -rf dist", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "typedoc": "typedoc" }, "devDependencies": { "@types/ms": "2.1.0", diff --git a/packages/errors/typedoc.json b/packages/errors/typedoc.json new file mode 100644 index 0000000000..1c06ac273e --- /dev/null +++ b/packages/errors/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "workflow/errors", + "entryPoints": ["./src/index.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/packages/next/package.json b/packages/next/package.json index 0d01c0bb84..0ad40b5800 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -29,6 +29,7 @@ "build": "tsc", "dev": "tsc --watch", "clean": "tsc --build --clean && rm -rf dist docs", + "typedoc": "typedoc", "prepack": "mkdir -p docs && cp ../../docs/content/docs/getting-started/next.mdx ./docs/ && cp -r ../../docs/content/docs/api-reference/workflow-next ./docs/api-reference", "postpack": "rm -rf docs" }, diff --git a/packages/next/typedoc.json b/packages/next/typedoc.json new file mode 100644 index 0000000000..44b4eb8c5f --- /dev/null +++ b/packages/next/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "workflow/next", + "entryPoints": ["./src/index.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/packages/serde/package.json b/packages/serde/package.json index 49f2f823e8..61c36908ce 100644 --- a/packages/serde/package.json +++ b/packages/serde/package.json @@ -26,7 +26,8 @@ "build": "tsc", "dev": "tsc --watch", "clean": "tsc --build --clean && rm -rf dist", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "typedoc": "typedoc" }, "devDependencies": { "@types/node": "catalog:", diff --git a/packages/serde/typedoc.json b/packages/serde/typedoc.json new file mode 100644 index 0000000000..1682271497 --- /dev/null +++ b/packages/serde/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "@workflow/serde", + "entryPoints": ["./src/index.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/packages/vitest/package.json b/packages/vitest/package.json index 7536f71b6a..83a4e438dd 100644 --- a/packages/vitest/package.json +++ b/packages/vitest/package.json @@ -26,7 +26,8 @@ "scripts": { "build": "tsc", "clean": "tsc --build --clean && rm -rf dist ||:", - "dev": "tsc --watch" + "dev": "tsc --watch", + "typedoc": "typedoc" }, "dependencies": { "@workflow/builders": "workspace:*", diff --git a/packages/vitest/typedoc.json b/packages/vitest/typedoc.json new file mode 100644 index 0000000000..a8186495f8 --- /dev/null +++ b/packages/vitest/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "@workflow/vitest", + "entryPoints": ["./src/index.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/packages/workflow/package.json b/packages/workflow/package.json index 98475563ae..b6d353cc4f 100644 --- a/packages/workflow/package.json +++ b/packages/workflow/package.json @@ -61,6 +61,7 @@ "dev": "tsc --watch", "test": "vitest run src", "typecheck": "tsc --noEmit", + "typedoc": "typedoc && typedoc --options typedoc-api.json", "prepack": "cp -r ../../docs/content/docs ./docs", "postpack": "rm -rf docs" }, diff --git a/packages/workflow/typedoc-api.json b/packages/workflow/typedoc-api.json new file mode 100644 index 0000000000..6a99c564cf --- /dev/null +++ b/packages/workflow/typedoc-api.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "workflow/api", + "entryPoints": ["./src/api.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out-api" +} diff --git a/packages/workflow/typedoc.json b/packages/workflow/typedoc.json new file mode 100644 index 0000000000..523f3d718c --- /dev/null +++ b/packages/workflow/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "extends": ["../../typedoc.json"], + "name": "workflow", + "entryPoints": ["./src/index.ts"], + "tsconfig": "./tsconfig.json", + "out": "typedoc-out" +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47678829b6..ca47312189 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -87,6 +87,15 @@ importers: turbo: specifier: ^2.8.11 version: 2.8.12 + typedoc: + specifier: 0.28.18 + version: 0.28.18(typescript@5.9.3) + typedoc-plugin-frontmatter: + specifier: 1.3.1 + version: 1.3.1(typedoc-plugin-markdown@4.11.0(typedoc@0.28.18(typescript@5.9.3))) + typedoc-plugin-markdown: + specifier: ^4.11.0 + version: 4.11.0(typedoc@0.28.18(typescript@5.9.3)) typescript: specifier: 'catalog:' version: 5.9.3 @@ -216,9 +225,6 @@ importers: fumadocs-mdx: specifier: 14.0.4 version: 14.0.4(fumadocs-core@16.2.2(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(vite@7.3.1(@types/node@22.19.0)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.3)) - fumadocs-typescript: - specifier: ^4.0.13 - version: 4.0.13(@types/react@19.1.13)(fumadocs-core@16.2.2(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3))(fumadocs-ui@16.2.2(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(tailwindcss@4.1.18))(typescript@5.9.3) fumadocs-ui: specifier: 16.2.2 version: 16.2.2(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(tailwindcss@4.1.18) @@ -310,9 +316,6 @@ importers: tailwindcss: specifier: ^4.1.17 version: 4.1.18 - ts-morph: - specifier: ^27.0.0 - version: 27.0.0 tw-animate-css: specifier: ^1.4.0 version: 1.4.0 @@ -3789,6 +3792,9 @@ packages: '@formatjs/intl-localematcher@0.6.2': resolution: {integrity: sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==} + '@gerrit0/mini-shiki@3.23.0': + resolution: {integrity: sha512-bEMORlG0cqdjVyCEuU0cDQbORWX+kYCeo0kV1lbxF5bt4r7SID2l9bqsxJEM0zndaxpOUT7riCyIVEuqq/Ynxg==} + '@graphile/logger@0.2.0': resolution: {integrity: sha512-jjcWBokl9eb1gVJ85QmoaQ73CQ52xAaOCF29ukRbYNl6lY+ts0ErTaDYOBlejcbUs2OpaiqYLO5uDhyLFzWw4w==} @@ -7057,6 +7063,9 @@ packages: '@shikijs/engine-oniguruma@3.21.0': resolution: {integrity: sha512-OYknTCct6qiwpQDqDdf3iedRdzj6hFlOPv5hMvI+hkWfCKs5mlJ4TXziBG9nyabLwGulrUjHiCq3xCspSzErYQ==} + '@shikijs/engine-oniguruma@3.23.0': + resolution: {integrity: sha512-1nWINwKXxKKLqPibT5f4pAFLej9oZzQTsby8942OTlsJzOBZ0MWKiwzMsd+jhzu8YPCHAswGnnN1YtQfirL35g==} + '@shikijs/engine-oniguruma@4.0.0': resolution: {integrity: sha512-KXmq4b6Xw16+4+rz5M4NZMoe/tzs5kTOMSJz8+LCyxSrwmxwTBAM/ab85iSO2Gw79E47HkW4B9HPHUXhrNOivw==} engines: {node: '>=20'} @@ -7068,6 +7077,9 @@ packages: '@shikijs/langs@3.21.0': resolution: {integrity: sha512-g6mn5m+Y6GBJ4wxmBYqalK9Sp0CFkUqfNzUy2pJglUginz6ZpWbaWjDB4fbQ/8SHzFjYbtU6Ddlp1pc+PPNDVA==} + '@shikijs/langs@3.23.0': + resolution: {integrity: sha512-2Ep4W3Re5aB1/62RSYQInK9mM3HsLeB91cHqznAJMuylqjzNVAVCMnNWRHFtcNHXsoNRayP9z1qj4Sq3nMqYXg==} + '@shikijs/langs@4.0.0': resolution: {integrity: sha512-dSAT6fBcnOcYZQMWZO8+OmzUKKm+OO0As/qZ3TXLiSy0JsCTEYz1TaX7TDupnYLz7dr0oF2DOTEgPocx1D3aFw==} engines: {node: '>=20'} @@ -7090,6 +7102,9 @@ packages: '@shikijs/themes@3.21.0': resolution: {integrity: sha512-BAE4cr9EDiZyYzwIHEk7JTBJ9CzlPuM4PchfcA5ao1dWXb25nv6hYsoDiBq2aZK9E3dlt3WB78uI96UESD+8Mw==} + '@shikijs/themes@3.23.0': + resolution: {integrity: sha512-5qySYa1ZgAT18HR/ypENL9cUSGOeI2x+4IvYJu4JgVJdizn6kG4ia5Q1jDEOi7gTbN4RbuYtmHh0W3eccOrjMA==} + '@shikijs/themes@4.0.0': resolution: {integrity: sha512-xe42kvxOXan5ouXxULez6qwDNUJkoP6kicfg0wKuJBkeIaHLxZBZa2gEGYutL1q27DQZ5+XoR6caVX+E/aNR5A==} engines: {node: '>=20'} @@ -7104,6 +7119,9 @@ packages: '@shikijs/types@3.21.0': resolution: {integrity: sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA==} + '@shikijs/types@3.23.0': + resolution: {integrity: sha512-3JZ5HXOZfYjsYSk0yPwBrkupyYSLpAE26Qc0HLghhZNGTZg/SKxXIIgoxOpmmeQP0RRSDJTk1/vPfw9tbw+jSQ==} + '@shikijs/types@4.0.0': resolution: {integrity: sha512-LCnfBTtQKNtJyc1qMShZr2dJt1uxNI6pI0/YTc2DSNET91aUvnMGHUHsucVCC5AJVcv5XyBqk2NgYRwd20EjbA==} engines: {node: '>=20'} @@ -7685,12 +7703,6 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - '@ts-morph/common@0.28.0': - resolution: {integrity: sha512-4w6X/oFmvXcwux6y6ExfM/xSqMHw20cYwFJH+BlYrtGa6nwY9qGq8GXnUs1sVYeF2o/KT3S8hAH6sKBI3VOkBg==} - - '@ts-morph/common@0.28.1': - resolution: {integrity: sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g==} - '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -9124,9 +9136,6 @@ packages: cobe@0.6.5: resolution: {integrity: sha512-MA8bu81EFY6JjQpj+FovEuhyJ25khx2Q7Lh+ot/UkCJe5yKyDgzdc6u2lGZIOmsZTXK6Itg1i4lQZIJZbPWnAg==} - code-block-writer@13.0.3: - resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} - codem-isoboxer@0.3.10: resolution: {integrity: sha512-eNk3TRV+xQMJ1PEj0FQGY8KD4m0GPxT487XJ+Iftm7mVa9WpPFDMWqPt+46buiP5j5Wzqe5oMIhqBcAeKfygSA==} @@ -10488,19 +10497,6 @@ packages: vite: optional: true - fumadocs-typescript@4.0.13: - resolution: {integrity: sha512-zmpmqsS2DZeH2wn17X0V5NOQ77mqnjlKjyUcgjNQk/vDPQkdFRxuoLNNBFnGGMizoKMQ30hjRgdGukVSVDgy+g==} - peerDependencies: - '@types/react': '*' - fumadocs-core: ^15.7.0 || ^16.0.0 - fumadocs-ui: ^15.7.0 || ^16.0.0 - typescript: '*' - peerDependenciesMeta: - '@types/react': - optional: true - fumadocs-ui: - optional: true - fumadocs-ui@16.2.2: resolution: {integrity: sha512-qYvPbVRMMFiuzrsmvGYpEj/cT5XyGzvwrrRklrHPMegywY+jxQ0TUeRKHzQgxkkTl0MDPnejRbHHAfafz01/TQ==} peerDependencies: @@ -11439,6 +11435,9 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lint-staged@16.2.7: resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==} engines: {node: '>=20.17'} @@ -11565,6 +11564,9 @@ packages: peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -11596,6 +11598,10 @@ packages: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -11678,6 +11684,9 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-chrome@4.14.0: resolution: {integrity: sha512-IEdFb4blyF15vLvQzLIn6USJBv7Kf2ne+TfLQKBYI5Z0f9VEBVZz5MKy4Uhi0iA9lStl2S9ENIujJRuJIa5OiA==} @@ -13041,6 +13050,10 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -14252,12 +14265,6 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} - ts-morph@27.0.0: - resolution: {integrity: sha512-xcqelpTR5PCuZMs54qp9DE3t7tPgA2v/P1/qdW4ke5b3Y5liTGTYj6a/twT35EQW/H5okRqp1UOqwNlgg0K0eQ==} - - ts-morph@27.0.2: - resolution: {integrity: sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w==} - tsconfck@3.1.6: resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} engines: {node: ^18 || >=20} @@ -14360,6 +14367,24 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + typedoc-plugin-frontmatter@1.3.1: + resolution: {integrity: sha512-wXKnhpiOuG3lY9GGKiKcXNrhKbPYm/jA5wbzGE/kKdwlSu8++ZbEuKA0K2dvIna3F+5EQrv+3AeObHkS1QP7JA==} + peerDependencies: + typedoc-plugin-markdown: '>=4.9.0' + + typedoc-plugin-markdown@4.11.0: + resolution: {integrity: sha512-2iunh2ALyfyh204OF7h2u0kuQ84xB3jFZtFyUr01nThJkLvR8oGGSSDlyt2gyO4kXhvUxDcVbO0y43+qX+wFbw==} + engines: {node: '>= 18'} + peerDependencies: + typedoc: 0.28.x + + typedoc@0.28.18: + resolution: {integrity: sha512-NTWTUOFRQ9+SGKKTuWKUioUkjxNwtS3JDRPVKZAXGHZy2wCA8bdv2iJiyeePn0xkmK+TCCqZFT0X7+2+FLjngA==} + engines: {node: '>= 18', pnpm: '>= 10'} + hasBin: true + peerDependencies: + typescript: 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x || 6.0.x + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -14369,6 +14394,9 @@ packages: resolution: {integrity: sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug==} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} @@ -16996,6 +17024,14 @@ snapshots: dependencies: tslib: 2.8.1 + '@gerrit0/mini-shiki@3.23.0': + dependencies: + '@shikijs/engine-oniguruma': 3.23.0 + '@shikijs/langs': 3.23.0 + '@shikijs/themes': 3.23.0 + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@graphile/logger@0.2.0': {} '@grpc/grpc-js@1.14.0': @@ -21305,6 +21341,11 @@ snapshots: '@shikijs/types': 3.21.0 '@shikijs/vscode-textmate': 10.0.2 + '@shikijs/engine-oniguruma@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/vscode-textmate': 10.0.2 + '@shikijs/engine-oniguruma@4.0.0': dependencies: '@shikijs/types': 4.0.0 @@ -21319,6 +21360,10 @@ snapshots: dependencies: '@shikijs/types': 3.21.0 + '@shikijs/langs@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/langs@4.0.0': dependencies: '@shikijs/types': 4.0.0 @@ -21352,6 +21397,10 @@ snapshots: dependencies: '@shikijs/types': 3.21.0 + '@shikijs/themes@3.23.0': + dependencies: + '@shikijs/types': 3.23.0 + '@shikijs/themes@4.0.0': dependencies: '@shikijs/types': 4.0.0 @@ -21370,6 +21419,11 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + '@shikijs/types@3.23.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.4 + '@shikijs/types@4.0.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 @@ -22142,18 +22196,6 @@ snapshots: '@tokenizer/token@0.3.0': {} - '@ts-morph/common@0.28.0': - dependencies: - minimatch: 10.2.4 - path-browserify: 1.0.1 - tinyglobby: 0.2.15 - - '@ts-morph/common@0.28.1': - dependencies: - minimatch: 10.2.4 - path-browserify: 1.0.1 - tinyglobby: 0.2.15 - '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -24083,8 +24125,6 @@ snapshots: dependencies: phenomenon: 1.6.0 - code-block-writer@13.0.3: {} - codem-isoboxer@0.3.10: {} collapse-white-space@2.1.0: {} @@ -24718,7 +24758,7 @@ snapshots: docker-compose@1.3.1: dependencies: - yaml: 2.8.1 + yaml: 2.8.3 docker-modem@5.0.6: dependencies: @@ -25608,24 +25648,6 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-typescript@4.0.13(@types/react@19.1.13)(fumadocs-core@16.2.2(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3))(fumadocs-ui@16.2.2(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(tailwindcss@4.1.18))(typescript@5.9.3): - dependencies: - estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.2.2(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3) - hast-util-to-estree: 3.1.3 - hast-util-to-jsx-runtime: 2.3.6 - remark: 15.0.1 - remark-rehype: 11.1.2 - tinyglobby: 0.2.15 - ts-morph: 27.0.2 - typescript: 5.9.3 - unist-util-visit: 5.0.0 - optionalDependencies: - '@types/react': 19.1.13 - fumadocs-ui: 16.2.2(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(tailwindcss@4.1.18) - transitivePeerDependencies: - - supports-color - fumadocs-ui@16.2.2(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(lucide-react@0.555.0(react@19.2.3))(next@16.2.1(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react-router@7.13.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react@19.2.3)(tailwindcss@4.1.18): dependencies: '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.13))(@types/react@19.1.13)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) @@ -26632,6 +26654,10 @@ snapshots: lines-and-columns@1.2.4: {} + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + lint-staged@16.2.7: dependencies: commander: 14.0.3 @@ -26773,6 +26799,8 @@ snapshots: dependencies: react: 19.1.0 + lunr@2.3.9: {} + lz-string@1.5.0: {} magic-regexp@0.10.0: @@ -26815,6 +26843,15 @@ snapshots: markdown-extensions@2.0.0: {} + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdown-table@3.0.4: {} marked@14.0.0: {} @@ -27010,6 +27047,8 @@ snapshots: mdn-data@2.12.2: {} + mdurl@2.0.0: {} + media-chrome@4.14.0(react@19.2.3): dependencies: ce-la-react: 0.3.2(react@19.2.3) @@ -29315,6 +29354,8 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode.js@2.3.1: {} + punycode@2.3.1: {} qs@6.14.1: @@ -31045,16 +31086,6 @@ snapshots: ts-dedent@2.2.0: {} - ts-morph@27.0.0: - dependencies: - '@ts-morph/common': 0.28.0 - code-block-writer: 13.0.3 - - ts-morph@27.0.2: - dependencies: - '@ts-morph/common': 0.28.1 - code-block-writer: 13.0.3 - tsconfck@3.1.6(typescript@5.9.3): optionalDependencies: typescript: 5.9.3 @@ -31148,10 +31179,30 @@ snapshots: typedarray@0.0.6: {} + typedoc-plugin-frontmatter@1.3.1(typedoc-plugin-markdown@4.11.0(typedoc@0.28.18(typescript@5.9.3))): + dependencies: + typedoc-plugin-markdown: 4.11.0(typedoc@0.28.18(typescript@5.9.3)) + yaml: 2.8.3 + + typedoc-plugin-markdown@4.11.0(typedoc@0.28.18(typescript@5.9.3)): + dependencies: + typedoc: 0.28.18(typescript@5.9.3) + + typedoc@0.28.18(typescript@5.9.3): + dependencies: + '@gerrit0/mini-shiki': 3.23.0 + lunr: 2.3.9 + markdown-it: 14.1.1 + minimatch: 10.2.4 + typescript: 5.9.3 + yaml: 2.8.3 + typescript@5.9.3: {} ua-parser-js@1.0.41: {} + uc.micro@2.1.0: {} + ufo@1.6.1: {} ufo@1.6.3: {} diff --git a/turbo.json b/turbo.json index 56d6764952..159847385c 100644 --- a/turbo.json +++ b/turbo.json @@ -31,6 +31,17 @@ "dependsOn": ["^build"], "cache": false }, + "typedoc": { + "dependsOn": ["^build"], + "inputs": [ + "src/**", + "typedoc.json", + "typedoc-api.json", + "$TURBO_ROOT$/typedoc.json", + "$TURBO_ROOT$/typedoc-formatter.mjs" + ], + "outputs": ["typedoc-out/**", "typedoc-out-api/**"] + }, "clean": { "cache": false } diff --git a/typedoc-formatter.mjs b/typedoc-formatter.mjs new file mode 100644 index 0000000000..775b3860c9 --- /dev/null +++ b/typedoc-formatter.mjs @@ -0,0 +1,95 @@ +// @ts-check +import { MarkdownPageEvent } from 'typedoc-plugin-markdown'; + +/** + * Custom TypeDoc plugin that: + * 1. Injects `title` and `type` frontmatter for each generated page + * 2. Strips `.mdx` extensions from links (Fumadocs uses clean URLs) + * 3. Escapes remaining unescaped curly braces in inline code spans + * that `sanitizeComments` missed (e.g., JSDoc @example in table cells) + * + * @param {import('typedoc-plugin-markdown').MarkdownApplication} app + */ +export function load(app) { + // Set "title" frontmatter for each page + app.renderer.on( + MarkdownPageEvent.BEGIN, + /** @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page */ + (page) => { + page.frontmatter = { + ...page.frontmatter, + title: page.model.name, + type: 'reference', + }; + } + ); + + // Post-process page contents + app.renderer.on( + MarkdownPageEvent.END, + /** @param {import('typedoc-plugin-markdown').MarkdownPageEvent} page */ + (page) => { + if (!page.contents) return; + + // Strip `.mdx` extensions from links + page.contents = page.contents.replace(/\.mdx/g, ''); + + // Escape any remaining unescaped { and } in the content. + // The `sanitizeComments` typedoc option handles most cases, but + // misses curly braces inside inline code spans within table cells + // (e.g., JSDoc @example blocks rendered inline in property tables). + // MDX treats unescaped `{...}` as JSX expressions which breaks the build. + page.contents = escapeRemainingBraces(page.contents); + } + ); +} + +/** + * Escapes any `{` and `}` that are not already escaped (i.e., not preceded + * by a backslash) and are not inside fenced code blocks. This catches + * cases that `sanitizeComments` misses. + * + * @param {string} content + * @returns {string} + */ +function escapeRemainingBraces(content) { + const lines = content.split('\n'); + let inFencedCodeBlock = false; + const result = []; + + for (const line of lines) { + // Track fenced code block boundaries + if (/^```/.test(line.trimStart())) { + inFencedCodeBlock = !inFencedCodeBlock; + result.push(line); + continue; + } + + if (inFencedCodeBlock) { + result.push(line); + continue; + } + + // Replace unescaped { and } (not preceded by \) + // Preserve anchor tags by temporarily replacing them + const anchors = []; + let processed = line.replace(/]*>[\s\S]*?<\/a>/g, (match) => { + anchors.push(match); + return `__TYPEDOC_ANCHOR_${anchors.length - 1}__`; + }); + + // Escape unescaped braces (not already preceded by backslash) + processed = processed + .replace(/(?