Skip to content

docs: add React Widgets section sourced from uipath-ui-widgets - #770

Open
maninder-uipath wants to merge 1 commit into
mainfrom
docs/react-widgets-section
Open

maninder-uipath wants to merge 1 commit into
mainfrom
docs/react-widgets-section

Conversation

@maninder-uipath

@maninder-uipath maninder-uipath commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Update: #785 has been closed and its content folded into this PR. The whole change — the React Widgets section and the pipeline that sources it from uipath-ui-widgets — is now a single squashed commit here.

uipath-ui-widgets#169 is merged (into develop, the upstream default branch, as f605a7a). The fetch has been re-run against it: 6 pages, zero warnings, and the full site builds with no react-widgets warning. This PR is ready to merge — see Outstanding at the bottom for the two things that are not in this diff.

What

Adds a React Widgets section to the docs site covering the six React widget packages published from UiPath/uipath-ui-widgets.

Only the section overview (docs/react-widgets/index.md) is authored here. Every per-widget page is fetched at docs-build time from the corresponding package README, so the widget repo stays the single source of truth and a docs refresh needs no SDK release — the same arrangement docs/js-functions/ already has with UiPath/coded-functions-js.

Docs-only — no SDK source, no endpoints, nothing to whitelist in Cloudflare.

Why single-source it

The widget pages would otherwise be maintained twice: here, and as each package README upstream. They had already drifted — the upstream multi-file-upload and pdf-viewer examples still build the SDK inside the component body, a bug this work fixed on the docs side only.

How the fetch works

scripts/fetch-widget-docs.mjs resolves the source repo to one commit SHA, fetches packages/<widget>/README.md for every widget mkdocs.yml references, and writes docs/react-widgets/<widget>.md. The output is gitignored and rebuilt on every docs build.

A README also has to render on npm and GitHub, so MkDocs-only syntax is written portably upstream and translated on the way in:

Upstream Rendered
> **Note:** … / > **Warning: A title** !!! note / !!! warning "A title"
<!-- tabs --> + <!-- tab: Title --> === "Title"
<!-- details warning: Title --> ??? warning "Title"
<!-- docs:ignore --> dropped — contributor content stays in the README

Absolute uipath.github.io links (which a README needs so they work from npm) are resolved back to the source page, so a PR preview links within itself.

The script fails the build when a referenced README is gone, and warns when upstream adds a package nothing references, when a link cannot resolve here, or when a README drifts from the contract.

docs.yml accepts a repository_dispatch from uipath-ui-widgets, so merging a README change there refreshes this site immediately. agent_docs/rules.md records that the fetched pages are generated and must never be hand-edited.

Pages

Page Package Covers
Overview (authored here) — Widget index, plus the setup every widget shares: React ^19.2.0, the sdk prop, the light/dark body class, stylesheet imports, exported prop types
DataTable @uipath/ui-widgets-datatable Props, CRUD flows (as tabs), master-detail, field-type table, column/row customization
Multi File Upload @uipath/ui-widgets-multi-file-upload Props, bucket upload example
PDF Viewer @uipath/ui-widgets-pdf-viewer The four source shapes, props, worker configuration, v1 CJK limitation
Conversational Agent Chat @uipath/ui-widgets-conversational-agent-chat ConversationalAgentChat + ConversationalAgentPickerChat, streaming / tool-call / session behavior
Validation Station @uipath/ui-widgets-validation-station Self-fetching vs pre-fetched data sources, props, save + state callbacks, language enum, web-component hosting
External Auth @uipath/ui-widgets-external-auth Provider config, built-in OIDC redirect, SAML caveat

Content corrections (now carried upstream)

The READMEs are developer-facing repo docs and had drifted from the packages they describe. Review of the first draft found four factual errors:

Issue Was Now
Wrong SDK API sdk.entities.getAll(), sdk.buckets.getAll() The modular UiPath from /core exposes no service properties (only initialize, isAuthenticated, getToken, destroy, logout, updateToken). Both tips now construct the service: new Entities(sdk).getAll()
Stale peer deps ^1.3.10 on three pages, >= 1.4.2 on another Matches each manifest: conversational-agent-chat ^1.5.5, validation-station ^1.5.1, the rest ^1.4.1. Re-diffed against the manifests at f605a7a; all six match
Unpublished packages npm install shown as if it works @uipath/ui-widgets-pdf-viewer and @uipath/ui-widgets-external-auth are 1.0.0-beta.1 and return 404 on the public registry. Both pages and the overview now say so
Secret in the browser secret: "your-secret" in five React examples A browser app is a public client and cannot hold a confidential credential. All init examples use the OAuth form, and the overview carries a !!! danger note against shipping a tenant secret to the browser

Also corrected: the overview claimed every widget ships a stylesheet (Validation Station ships none — its styles arrive with the web-component bundle); @uipath/apollo-wind was listed as a user requirement though it installs with the widgets; Validation Station's mandatory configureValidationStationWc() step was missing from the shared setup; and a dangling reference to "compact subcomponents" described a concept the page never introduces.

A second pass caught two more problems:

  • The Validation Station quick start ran initialize() at module scope. Harmless under secret-based auth, but under OAuth it navigates the browser at module-evaluation time. It now sits in an effect behind a loading gate like every other page, with a note that redirectUri must be a route the app serves and must match a registered URI exactly.
  • Multi File Upload and PDF Viewer examples named no scopes, carrying a bare // SDK configuration placeholder. Both now name what they need.

Since the per-widget pages are fetched, these corrections live in uipath-ui-widgets#169 rather than in this diff.

Two things that need a maintainer decision

  1. External Auth is documented but still unpublished. @uipath/ui-widgets-pdf-viewer has since shipped (1.0.0 on the public registry), so that half resolved itself and Bump sdk version to 1.0.0-beta.18 #169 dropped both beta warnings. But @uipath/ui-widgets-external-auth still returns 404, and its page now tells the reader to run npm install @uipath/ui-widgets-external-auth with no caveat. That instruction fails today. Three ways out — publish the package, restore a note to its README upstream, or drop the page from the nav until it ships. The page is fetched, so whichever you pick is a change in uipath-ui-widgets, not here.
  2. @uipath/[email protected] declares an exact peer of @uipath/[email protected]. The page documents ^1.4.1 — what the widget is actually built against — so following it produces an unmet peer dependency against the published version. Documenting 1.1.1 instead would be worse: an exact pin on a peer dependency looks like a manifest bug, and 1.1.1 is several minors stale. For now the page states the discrepancy; the real fix is a multi-file-upload release carrying the corrected peer range.

Editorial decisions

  • Repo-contributor material dropped via <!-- docs:ignore --> — each README's Development and License sections are for people working on the widgets repo, not for SDK consumers reading the docs site.
  • Validation Station's "Migrating from 1.0.x" is collapsed into ??? details blocks. It is real consumer guidance, but it should not dominate the page for someone starting fresh.
  • Cross-linked into the existing site — Entity, Bucket and Conversational Agent service references, OAuth Scopes, Authentication, and Coded Apps / Coded Action Apps.

Nav placement

Top-level React Widgets section, between Coded Action Apps and JS Functions — the widgets are what you render inside a coded app or coded action app. A matching React Widgets block was added to the llms-full-content.txt manifest so the pages land in the LLM-facing bundle alongside Getting Started and the API Reference.

Files

Area Files
Docs docs/react-widgets/index.md (the only tracked page; the rest are fetched)
Fetch pipeline scripts/fetch-widget-docs.mjs, package.json, .gitignore
CI .github/workflows/docs.yml, .github/workflows/docs-pr-preview.yml
Site config mkdocs.yml (nav section + llms-full-content.txt manifest entries)
Tests tests/unit/scripts/fetch-widget-docs.test.ts
Conventions agent_docs/rules.md

Verification

Site build — built and served the full site locally with the pinned docs/requirements.txt toolchain:

  • mkdocs build — all seven pages build with zero warnings; every cross-link and in-page anchor resolves, including oauth-scopes.md#conversational-agent.
  • mkdocs serve — all seven routes return 200; tabs, admonitions and collapsible ??? blocks render, including code blocks nested inside admonitions.
  • Every documented peer-dependency range diffed against its package.json; all six match. npm registry checked per package to confirm which are actually installable.
  • Remaining build warnings are pre-existing and unrelated: stale links inside the typedoc-generated api/ pages, the duplicate-llmstxt-plugin notice, and the js-functions placeholder pages that appear when CODED_FUNCTIONS_DOCS_TOKEN is unset locally.

Fetch pipeline —

  • Round-trip: the converted READMEs from uipath-ui-widgets#169 run through the real script and diffed against the reviewed pages. Only intended differences — the Package: line moves under the title, !!! success becomes !!! check (the type this site's config actually declares), and the pages regain a ## TypeScript section and two Validation Station subcomponent links that existed upstream but not here.
  • Live: fetched from the upstream PR branch with zero warnings; 2 tab blocks, 5 collapsibles and 22 admonitions rendered; every localized link target verified to exist, including the api/interfaces/entity/index.md directory-index case.
  • Drift detection: run against current upstream (unconverted), it correctly warns about the relative link and the non-package H1.
  • 30 unit tests in tests/unit/scripts/fetch-widget-docs.test.ts, following the check-samples.mjs precedent. npm run lint, npm run typecheck, npm run test:unit (2903 tests) all pass.

Outstanding

Neither blocks this PR; both live outside its diff.

  1. SDK_DOCS_DISPATCH_TOKEN is not set on uipath-ui-widgets. Done — the secret is in place and verified. A manual workflow_dispatch of docs-dispatch.yml (run 37470249390) reached the real gh api .../dispatches call and exited 0, with none of the ::warning::SDK_DOCS_DISPATCH_TOKEN is not set annotation the Bump sdk version to 1.0.0-beta.18 #169 merge run produced — so the token carries contents: write here, not merely a non-empty value. The dispatch is a no-op until this merges: repository_dispatch is only honoured for workflows on the default branch, so the trigger this PR adds to docs.yml goes live on merge, and upstream README merges refresh the site from then on.
  2. The External Auth install instruction — see decision 1 above.

🤖 Generated with Claude Code

@maninder-uipath
maninder-uipath requested a review from a team September 22, 2026 05:32
@github-actions

github-actions Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://UiPath.github.io/uipath-typescript/pr-preview/pr-770/

Built to branch gh-pages at 2026-10-06 12:22 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Comment thread docs/react-widgets/multi-file-upload.md Outdated
Comment thread docs/react-widgets/pdf-viewer.md Outdated
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

Review summary

Two pages instantiate new UiPath() directly in the component body without useState/useEffect/initialize(), inconsistent with the canonical pattern shown in index.md and the other five pages:

  • docs/react-widgets/multi-file-upload.md line 38–41 — creates a fresh SDK instance on every render; missing await sdk.initialize(). Suggested fix posted inline.
  • docs/react-widgets/pdf-viewer.md line 22–25 — same pattern; the "coded app" comment is correct for that context, but the example is incomplete for standalone apps.

Everything else looks good: correct subpath imports, production-only URLs, proper cross-links, mkdocs.yml nav entries consistent with the file layout.

@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

1 similar comment
@claude

claude Bot commented Sep 22, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

Comment thread docs/react-widgets/index.md Outdated

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add gif / image of each widget ? this would help users better visualize how each widget looks and works.

we didn't have visuals for the sample apps earlier either, but we received requests to add them for better user understanding.

Comment thread docs/react-widgets/index.md Outdated
Comment thread docs/react-widgets/conversational-agent-chat.md Outdated
Comment thread docs/react-widgets/validation-station.md Outdated
Comment thread docs/react-widgets/validation-station.md Outdated
@claude

claude Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

1 similar comment
@claude

claude Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

✅ No issues found. Checked for bugs and CLAUDE.md compliance.

@Raina451 Raina451 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check this: #770 (comment) , rest lgtm

console.warn("Submit failed:", result?.error);
return;
}
await task.complete({ action: "Completed", type: "DocumentValidation" });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't the type DocumentValidationTask? Better to use TaskType.DocumentValidation

Comment thread docs/react-widgets/multi-file-upload.md Outdated
```

!!! tip "Finding the bucket and folder IDs"
List the buckets you can reach with the Buckets service — the cross-folder `getAll()` response carries the bucket `id` alongside its `folderId`. See the [Bucket service reference](../api/interfaces/BucketServiceModel.md):

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +76 to +77
| `inputSchema` | `InputSchema` | No | Agent input schema. Takes precedence over the schema derived from the resolved agent; use when the caller has the schema but the agent can't be resolved (e.g. an in-progress draft) |
| `isDebugMode` | `boolean` | No | Debug flow: opens an empty conversation up front so inputs are collected in the widget, and submits update the existing conversation instead of creating a new one |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't these internal?

Comment thread docs/react-widgets/multi-file-upload.md Outdated
Comment on lines +28 to +29
!!! warning "The published 1.0.0 pins an older SDK"
`@uipath/[email protected]` — currently the only published version — declares an exact peer of `@uipath/[email protected]`, which the range above does not satisfy, so npm reports an unmet peer dependency. The `^1.4.1` above is what the widget is built against today and what the next release will carry.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think npm install itself would fail?

Comment on lines +50 to +63
const [sdk, setSdk] = useState<UiPath | null>(null);

useEffect(() => {
const init = async () => {
const uipath = new UiPath({
baseUrl: "https://api.uipath.com",
orgName: "your-org",
tenantName: "your-tenant",
clientId: "your-client-id",
redirectUri: "http://localhost:3000/callback",
scope: "<scopes the widgets you use need>",
});
await uipath.initialize();
setSdk(uipath);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

won't this break under strictmode? other samples initialize it outside in useState and guard the effect with a useRef
https://github.com/UiPath/uipath-typescript/blob/main/samples/document-validation-app/src/hooks/AuthProvider.tsx

Comment thread docs/react-widgets/datatable.md Outdated
| `sdk` | `UiPath` | Yes | — | UiPath SDK instance |
| `entityId` | `string` | Yes | — | The UUID of the Data Fabric entity to display |
| `pageSize` | `number` | No | `50` | Number of rows per page |
| `showIdColumn` | `boolean` | No | — | Whether to show the Id column in the grid |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread docs/react-widgets/pdf-viewer.md Outdated
Comment on lines +46 to +47
// Bucket sources need `OR.Buckets`; entity sources need
// `DataFabric.Data.Read`. URL and byte sources need no scope.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

widget only reads right? shound't OR.Buckets.Read be enough?

| `onSaveAsDraft` | **Save as draft** | `(request, result?) => void` | With `sdk` + `data`: uploads `validatedData` straight to the bucket (no `processExtractedData`). Without: emits the request only | Same as above; the host-side equivalent is `saveValidatedDataAsDraft` |
| `onReportException` | **Report as exception** | `(request) => void` | Nothing — the widget never persists exceptions, in either mode. The reason is at `request.exceptionReport.Reason` | Required if you want the report persisted — call `OrchestratorDuModule.submitExceptionReport(...)` yourself |

Submit and draft hand you a `SaveValidatedDataResult` (`{ success, error? }`) — the host owns all UI feedback (toast, retry, etc.); the widget does not surface failures itself. The exception callback hands you `documentId` and `reason` strings ready to forward to the SDK.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the above line it says reason comes from request.exceptionReport.Reason

@swati354

Copy link
Copy Markdown
Collaborator

few UI fixes, please check

  1. noticed back-slashes at few places, please check other places too
Screenshot 2026-09-30 at 12 26 30 PM Screenshot 2026-09-30 at 12 26 55 PM
  1. Lets make react widget bold as well
Screenshot 2026-09-30 at 12 30 38 PM
  1. The validation page seems to be too verbose, please check if few things can be cut/trim. for example this import list, do we need it? won't type cover this?
Screenshot 2026-09-30 at 12 36 52 PM

maninder-uipath added a commit to UiPath/uipath-ui-widgets that referenced this pull request Oct 6, 2026
These READMEs and the React Widgets pages on the SDK docs site were two
near-complete copies of the same text, and had drifted: the multi-file-upload
and pdf-viewer examples here still build the SDK inside the component body,
which UiPath/uipath-typescript#770 fixed on its side.

UiPath/uipath-typescript now fetches packages/<widget>/README.md at docs build
time and renders it as docs/react-widgets/<widget>.md, the same way it already
sources its JS Functions section from UiPath/coded-functions-js. So this brings
the READMEs up to the reviewed content and adopts the conventions that build
expects:

- Fixed examples: the SDK is created once in a useEffect with await
  initialize(), and baseUrl is api.uipath.com, matching every SDK sample.
- MkDocs-only syntax is written portably, since a README also has to render on
  npm and GitHub: `> **Note:** …` for admonitions, `<!-- tabs -->` and
  `<!-- details type: Title -->` for tabs and collapsibles. The fetch script
  translates them; npm renders a blockquote and drops the comments.
- Cross-page links are absolute uipath.github.io URLs, so they resolve from an
  npm page too.
- Development and License sit inside `<!-- docs:ignore -->`, which the fetch
  script strips -- contributor content stays in the README without reaching
  the docs site.
- Validation Station gains the Vite hosting section (staging the web component
  into public/du-vs-wc, and why no vite.config.ts change is needed) and links
  to the four sample apps.

docs-dispatch.yml tells the SDK repo to rebuild when a README lands on develop.
It needs an SDK_DOCS_DISPATCH_TOKEN secret with contents:write on
UiPath/uipath-typescript; without it the step warns and the site picks the
change up on its next build.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
maninder-uipath added a commit to UiPath/uipath-ui-widgets that referenced this pull request Oct 6, 2026
)

* docs: make each package README the single source for its docs page

These READMEs and the React Widgets pages on the SDK docs site were two
near-complete copies of the same text, and had drifted: the multi-file-upload
and pdf-viewer examples here still build the SDK inside the component body,
which UiPath/uipath-typescript#770 fixed on its side.

UiPath/uipath-typescript now fetches packages/<widget>/README.md at docs build
time and renders it as docs/react-widgets/<widget>.md, the same way it already
sources its JS Functions section from UiPath/coded-functions-js. So this brings
the READMEs up to the reviewed content and adopts the conventions that build
expects:

- Fixed examples: the SDK is created once in a useEffect with await
  initialize(), and baseUrl is api.uipath.com, matching every SDK sample.
- MkDocs-only syntax is written portably, since a README also has to render on
  npm and GitHub: `> **Note:** …` for admonitions, `<!-- tabs -->` and
  `<!-- details type: Title -->` for tabs and collapsibles. The fetch script
  translates them; npm renders a blockquote and drops the comments.
- Cross-page links are absolute uipath.github.io URLs, so they resolve from an
  npm page too.
- Development and License sit inside `<!-- docs:ignore -->`, which the fetch
  script strips -- contributor content stays in the README without reaching
  the docs site.
- Validation Station gains the Vite hosting section (staging the web component
  into public/du-vs-wc, and why no vite.config.ts change is needed) and links
  to the four sample apps.

docs-dispatch.yml tells the SDK repo to rebuild when a README lands on develop.
It needs an SDK_DOCS_DISPATCH_TOKEN secret with contents:write on
UiPath/uipath-typescript; without it the step warns and the site picks the
change up on its next build.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* docs: format package READMEs and fix docs details

Run Prettier over the datatable and pdf-viewer READMEs, and along the way:

- document `showIdColumn`'s actual default (`true`)
- point the pdf-viewer SDK-init link at the authentication page
- run the docs dispatch workflow on `uipath-ubuntu-latest`

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

* ci: declare empty permissions for the docs dispatch workflow

zizmor's excessive-permissions audit failed the PR check: docs-dispatch.yml
was the only workflow without a `permissions:` block, so it inherited the
repository default for GITHUB_TOKEN.

The job never uses GITHUB_TOKEN -- the cross-repo dispatch authenticates
with SDK_DOCS_DISPATCH_TOKEN -- so it needs no scopes at all.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
Adds a React Widgets section to the docs site for the @uipath/ui-widgets
packages. The section overview (docs/react-widgets/index.md) is authored
here; every per-widget page is fetched at docs-build time from each
package's README in UiPath/uipath-ui-widgets, so the widget repo stays
the single source of truth and a docs refresh needs no SDK release.

- scripts/fetch-widget-docs.mjs materializes docs/react-widgets/*.md from
  the widget repo, translating the portable README syntax (admonitions,
  tabs, collapsibles, absolute cross-page links) into MkDocs markup
- fetched pages are gitignored and rebuilt on every docs build
- docs.yml accepts a repository_dispatch from uipath-ui-widgets
- agent_docs/rules.md records that the fetched pages are never hand-edited
- unit tests cover the fetch and translation behaviour

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@maninder-uipath
maninder-uipath force-pushed the docs/react-widgets-section branch from 772a458 to 1c06a4c Compare October 6, 2026 12:20
@maninder-uipath maninder-uipath changed the title docs: add React Widgets section for the @uipath/ui-widgets packages docs: add React Widgets section sourced from uipath-ui-widgets Oct 6, 2026
Comment on lines +399 to +414
return lines.map((line) =>
line.replace(absolute, (whole, path, anchor = '') => {
const clean = path.replace(/^\/+|\/+$/g, '');
// The bare site root is the docs home page; anything else has to match a
// real file, or the link keeps its absolute form.
const candidate =
clean === ''
? 'index.md'
: [`${clean}.md`, `${clean}/index.md`].find((rel) => existsSync(join(DOCS_DIR, rel)));
if (!candidate) {
warn(`"${SITE_URL}${path}" matches no page under docs/ -- left as an absolute link`);
return whole;
}
return `](../${candidate}${anchor})`;
}),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every other transform function (convertAdmonitions, convertTabs, convertDetails, checkLinks, stripIgnored) guards with fenceMask before touching a line. localizeSiteLinks skips that guard, so a markdown link containing an absolute site URL inside a fenced code block would get rewritten — turning [Docs](https://uipath.github.io/uipath-typescript/authentication/) inside a ```ts example into a broken relative path.

Suggested change
return lines.map((line) =>
line.replace(absolute, (whole, path, anchor = '') => {
const clean = path.replace(/^\/+|\/+$/g, '');
// The bare site root is the docs home page; anything else has to match a
// real file, or the link keeps its absolute form.
const candidate =
clean === ''
? 'index.md'
: [`${clean}.md`, `${clean}/index.md`].find((rel) => existsSync(join(DOCS_DIR, rel)));
if (!candidate) {
warn(`"${SITE_URL}${path}" matches no page under docs/ -- left as an absolute link`);
return whole;
}
return `](../${candidate}${anchor})`;
}),
);
const fenced = fenceMask(lines);
return lines.map((line, i) => {
if (fenced[i]) return line;
return line.replace(absolute, (whole, path, anchor = '') => {
const clean = path.replace(/^\/+|\/+$/g, '');
// The bare site root is the docs home page; anything else has to match a
// real file, or the link keeps its absolute form.
const candidate =
clean === ''
? 'index.md'
: [`${clean}.md`, `${clean}/index.md`].find((rel) => existsSync(join(DOCS_DIR, rel)));
if (!candidate) {
warn(`"${SITE_URL}${path}" matches no page under docs/ -- left as an absolute link`);
return whole;
}
return `](../${candidate}${anchor})`;
});
});

Comment on lines +298 to +299
});
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convertDetails has the same unclosed-block guard as convertTabs and stripIgnored (each calls fail(...) when no closing marker is found), but only convertTabs and stripIgnored have a "fails on unclosed" test here. The convertDetails error path goes unexercised.

Suggested change
});
});
});
it('fails on an unclosed details block rather than swallowing the rest of the page', () => {
expect(() =>
render('# @uipath/ui-widgets-pdf-viewer\n\n\nbody\n\n## Later section\n'),
).toThrow(/unclosed <!-- details:/);
});
});

@claude

claude Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Review summary

Two issues in the new fetch script and its tests:

  • scripts/fetch-widget-docs.mjs lines 399–414 — localizeSiteLinks is the only transform function that doesn't guard with fenceMask. All siblings (convertAdmonitions, convertTabs, convertDetails, checkLinks, stripIgnored) skip fenced lines. Without the guard, a markdown link like [Docs](https://uipath.github.io/uipath-typescript/authentication/) inside a code block would be rewritten into a broken relative path. Suggestion posted inline.

  • tests/unit/scripts/fetch-widget-docs.test.ts lines 298–299 — convertDetails has the same unclosed-block fail() path as convertTabs and stripIgnored, but only those two have "fails on unclosed" tests. The convertDetails error path is unexercised. Suggestion posted inline.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants