Skip to content

feat(samples): add SDK Playground — version-aware method explorer coded app - #625

Draft
Sarath1018 wants to merge 2 commits into
mainfrom
feat/sdk-playground-sample
Draft

feat(samples): add SDK Playground — version-aware method explorer coded app#625
Sarath1018 wants to merge 2 commits into
mainfrom
feat/sdk-playground-sample

Conversation

@Sarath1018

@Sarath1018 Sarath1018 commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

What

A new sample under samples/sdk-playground — a Swagger-style explorer for the SDK, deployable as a UiPath coded app. Pick any published SDK version, browse every service and method that version exposes, fill in parameters through a generated form, and execute the call live against a tenant.

No SDK source is changed — this PR adds a sample app and its Template Gallery entry only.

How it works

Version-aware method catalog

Six SDK versions (latest patch of every published minor line) are installed side by side via npm aliases:

"sdk-v1_5_5": "npm:@uipath/uipath-typescript@1.5.5"

scripts/generate-manifests.mjs (ts-morph) parses each installed version's published .d.ts files, extracts every {Entity}ServiceModel interface (methods, parameters, enum values, object shapes, JSDoc descriptions and @example blocks), and emits one manifest JSON per version plus a statically-analyzable lazy-import registry. The catalog can never drift from what a version actually ships, and each version is its own Vite chunk — the browser downloads only the selected one.

Version Services Methods
1.0.0 12 58
1.1.3 17 80
1.2.2 19 85
1.3.11 21 129
1.4.2 26 152
1.5.5 30 180

Adding a future version = one alias line in package.json + npm run manifests.

Connection modes

Mode Auth Use case
Platform new UiPath() reading meta tags injected by UiPath Apps Deployed as coded app — zero config, runs as signed-in user
PAT org/tenant/base URL + personal access token Local dev, cross-tenant testing
OAuth Non-Confidential External Application App ID + redirect URI + scopes (PKCE) Endpoints that reject PAT auth

Generated forms & execution

  • Enums → dropdowns, Date → datetime pickers, booleans → selects, object params → JSON editor with a shape hint from the manifest
  • The SDK's own @example JSDoc renders inline per method
  • Responses show duration, pretty JSON, and any SDK-bound entity methods (e.g. task.assign()) as badges
  • Every configured call can be copied as a runnable TypeScript snippet (credentials always masked)

Security notes

  • PAT is held in memory only — never persisted, logged, or embedded in snippets
  • OAuth mode persists only public identifiers (App ID, org/tenant, scopes, redirect URI) to sessionStorage to survive the sign-in redirect; tokens are managed by the SDK
  • Changing credentials or version always disposes the old client and builds a fresh one — no token reuse across tenants
  • OAuth resume on page load never initiates a redirect; it only completes a pending callback or reuses a cached token

Example usage

cd samples/sdk-playground
npm install
npm run dev     # generates manifests, starts Vite on :5173

Then: pick a version → Connect (PAT or OAuth) → choose a method in the tree → fill params → Run.

Verification

  • npm run build clean (typecheck + Vite production build, ~3.8 MB dist, per-version code splitting confirmed)
  • Headless-Chrome smoke test: UI renders with version picker, connection panel, and full service tree (30 services / 180 methods on 1.5.5)
  • Manifest generation verified across all six versions

Files

Area Files
Sample app samples/sdk-playground/ (Vite + React, TypeScript strict)
Manifest generator samples/sdk-playground/scripts/generate-manifests.mjs
Generated manifests samples/sdk-playground/src/manifests/*.json (6 versions)
Version registry samples/sdk-playground/src/sdk/registry.gen.ts
SDK client layer samples/sdk-playground/src/sdk/client.ts
UI samples/sdk-playground/src/components/*
Preview samples/sdk-playground/screenshots/preview.gif
Docs docs/samples/index.md (Template Gallery: new "Developer Tools" category + entry)

Reviewer note: this adds a new dev-tools gallery category rather than reusing an existing id — no existing category (Action Apps / Agents / Dashboards / Data Fabric / Document / Process) fits a developer tool. Deliberate deviation, flagged for explicit approval.

Review

sdk-review ran for 2 iterations — 6 findings fixed in the second commit (banned cast, in-flight connect race on version switching, snippet argument alignment + import specifiers, manifest shape-hint garbage from array types, missing preview GIF). Regenerated manifests verified byte-identical to generator output; no Array.prototype leakage remains.

TODO before marking ready

  • Live end-to-end run against a tenant with real credentials
  • Optional: replace the static preview.gif with a recorded walkthrough

🤖 Generated with Claude Code

Swagger-style explorer for the SDK: pick any published SDK version
(1.0.0-1.5.5, latest patch per minor line), browse every service and
method that version exposes via manifests generated from its published
.d.ts files, fill parameters in a generated form, and run calls live.

Connection modes: platform-injected (coded-app deployment), PAT
(memory-only secret), and OAuth PKCE via external application App ID.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 28, 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-625/

Built to branch gh-pages at 2026-07-28 05:20 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

if (t.isString()) return { kind: 'string' };
if (t.isNumber()) return { kind: 'number' };
if (t.isBoolean()) return { kind: 'boolean' };
if (t.isString() || t.isStringLiteral()) return { kind: 'string' };

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.

Dead code / latent bug: t.isString() was already checked on line 73, so this branch can never execute. The t.isStringLiteral() case is silently dropped, meaning a parameter whose type is a single string literal (e.g. "ascending") falls through to return { kind: 'json' } and gets a JSON textarea instead of a plain text input.

Fix: merge the isStringLiteral() test into the line 73 check and delete this line.

Suggested change
if (t.isString() || t.isStringLiteral()) return { kind: 'string' };
if (t.isString() || t.isStringLiteral()) return { kind: 'string' };

And delete the duplicate on line 76 (the current if (t.isString() || t.isStringLiteral()) line shown here).

Comment on lines +69 to +70
`import { UiPath } from '@uipath/uipath-typescript@${version}/core';`,
`import { ${service.name} } from '@uipath/uipath-typescript@${version}/${service.subpath}';`,

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.

@uipath/uipath-typescript@${version}/core is not valid Node.js/TypeScript module syntax — you can't embed a version in a subpath specifier. Pasting this snippet into a project will fail at module resolution (Cannot find module '@uipath/uipath-typescript@1.5.5/core').

The version should be conveyed as a comment, with the import path being the bare package name as the user would have it installed:

Suggested change
`import { UiPath } from '@uipath/uipath-typescript@${version}/core';`,
`import { ${service.name} } from '@uipath/uipath-typescript@${version}/${service.subpath}';`,
`// SDK version used: ${version}`,
`import { UiPath } from '@uipath/uipath-typescript/core';`,
`import { ${service.name} } from '@uipath/uipath-typescript/${service.subpath}';`,

Comment thread docs/samples/index.md Outdated
{ "id": "action-app-with-image", "title": "Action App — Image", "description": "Coded Action App for loan-application review. Reviewers assess applicant details, view a bundled loan-application image, and complete the task with an Approve or Reject decision.", "category": "action-apps", "framework": "React", "tags": ["Action Center","Coded Action App","Images"], "path": "samples/coded-action-apps/action-app-with-image", "preview": null },
{ "id": "action-app-with-storage-bucket-document", "title": "Action App — Storage Bucket Document", "description": "Coded Action App for loan-application review that loads its document from a Storage Bucket by bucket name and file path, as opposed to receiving a direct file attachment.", "category": "action-apps", "framework": "React", "tags": ["Action Center","Coded Action App","Storage Buckets","Documents"], "path": "samples/coded-action-apps/action-app-with-storage-bucket-document", "preview": null }
{ "id": "action-app-with-storage-bucket-document", "title": "Action App — Storage Bucket Document", "description": "Coded Action App for loan-application review that loads its document from a Storage Bucket by bucket name and file path, as opposed to receiving a direct file attachment.", "category": "action-apps", "framework": "React", "tags": ["Action Center","Coded Action App","Storage Buckets","Documents"], "path": "samples/coded-action-apps/action-app-with-storage-bucket-document", "preview": null },
{ "id": "sdk-playground", "title": "SDK Playground", "description": "Swagger-style explorer for the SDK. Pick any published SDK version, browse every service and method it exposes via auto-generated manifests, fill parameters in a generated form, and run calls live with platform-injected or custom credentials.", "category": "dev-tools", "framework": "React", "tags": ["Playground","API Explorer","Versioning","Coded App"], "path": "samples/sdk-playground", "preview": null }

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.

CLAUDE.md requirement (samples & Template Gallery section): every app under samples/ must ship a preview GIF at samples/<app>/screenshots/preview.gif before merging. "preview": null leaves an empty poster tile in the gallery. This is a hard gate — the PR cannot leave DRAFT status without it.

The PR TODO already tracks this, but flagging here so it doesn't get missed at review time.

@claude

claude Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review summary

Three issues found, all actionable:

1. Bug — dead code / misclassified param types (generate-manifests.mjs line 76)
The t.isStringLiteral() branch is unreachable because t.isString() is already checked three lines earlier. A parameter typed as a single string literal falls through to kind: 'json' and renders as a JSON textarea. Fix: merge isStringLiteral() into the isString() check on line 73 and delete line 76.

2. Bug — generated snippets have invalid import paths (MethodPanel.tsx lines 69-70)
@uipath/uipath-typescript@${version}/core is not valid module syntax. The generated snippet fails to resolve. Fix: use @uipath/uipath-typescript/core and add the version as a comment line.

3. Missing preview GIF (docs/samples/index.md line 143)
CLAUDE.md requires every sample to ship samples/<app>/screenshots/preview.gif before merging. Already in the PR TODO but flagged as a hard gate before leaving DRAFT.

- replace as-unknown-as cast in disposeClient with intersection cast
- guard connect/version-switch/OAuth-resume against stale in-flight
  client resolutions (epoch counter; superseded clients are disposed)
- snippet builder: keep interior omitted optionals as explicit undefined
  and use valid import specifiers (version in npm install comment)
- manifest generator: skip Array.prototype members, well-known symbols,
  and method signatures in object shape hints; manifests regenerated
- add screenshots/preview.gif and point the gallery entry at it

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@claude

claude Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

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

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.

1 participant