From d720acadddd960f47087c05d5b8567e33c007894 Mon Sep 17 00:00:00 2001 From: Sarath1018 Date: Tue, 28 Jul 2026 10:36:19 +0530 Subject: [PATCH 1/2] feat(samples): add SDK Playground coded app 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 --- docs/samples/index.md | 4 +- samples/sdk-playground/.gitignore | 5 + samples/sdk-playground/.npmrc | 1 + samples/sdk-playground/README.md | 42 + samples/sdk-playground/index.html | 18 + samples/sdk-playground/package-lock.json | 1384 +++ samples/sdk-playground/package.json | 31 + .../scripts/generate-manifests.mjs | 256 + samples/sdk-playground/src/App.tsx | 235 + .../src/components/ConnectionPanel.tsx | 132 + .../src/components/MethodPanel.tsx | 169 + .../src/components/ResponseViewer.tsx | 68 + .../src/components/ServiceTree.tsx | 86 + samples/sdk-playground/src/main.tsx | 13 + .../sdk-playground/src/manifests/1.0.0.json | 3234 ++++++ .../sdk-playground/src/manifests/1.1.3.json | 3897 +++++++ .../sdk-playground/src/manifests/1.2.2.json | 4088 +++++++ .../sdk-playground/src/manifests/1.3.11.json | 6205 +++++++++++ .../sdk-playground/src/manifests/1.4.2.json | 7706 +++++++++++++ .../sdk-playground/src/manifests/1.5.5.json | 9740 +++++++++++++++++ samples/sdk-playground/src/sdk/client.ts | 259 + .../sdk-playground/src/sdk/registry.gen.ts | 133 + samples/sdk-playground/src/styles.css | 469 + samples/sdk-playground/src/types/json.d.ts | 7 + samples/sdk-playground/src/types/manifest.ts | 36 + samples/sdk-playground/tsconfig.json | 21 + samples/sdk-playground/vite.config.ts | 12 + 27 files changed, 38250 insertions(+), 1 deletion(-) create mode 100644 samples/sdk-playground/.gitignore create mode 100644 samples/sdk-playground/.npmrc create mode 100644 samples/sdk-playground/README.md create mode 100644 samples/sdk-playground/index.html create mode 100644 samples/sdk-playground/package-lock.json create mode 100644 samples/sdk-playground/package.json create mode 100644 samples/sdk-playground/scripts/generate-manifests.mjs create mode 100644 samples/sdk-playground/src/App.tsx create mode 100644 samples/sdk-playground/src/components/ConnectionPanel.tsx create mode 100644 samples/sdk-playground/src/components/MethodPanel.tsx create mode 100644 samples/sdk-playground/src/components/ResponseViewer.tsx create mode 100644 samples/sdk-playground/src/components/ServiceTree.tsx create mode 100644 samples/sdk-playground/src/main.tsx create mode 100644 samples/sdk-playground/src/manifests/1.0.0.json create mode 100644 samples/sdk-playground/src/manifests/1.1.3.json create mode 100644 samples/sdk-playground/src/manifests/1.2.2.json create mode 100644 samples/sdk-playground/src/manifests/1.3.11.json create mode 100644 samples/sdk-playground/src/manifests/1.4.2.json create mode 100644 samples/sdk-playground/src/manifests/1.5.5.json create mode 100644 samples/sdk-playground/src/sdk/client.ts create mode 100644 samples/sdk-playground/src/sdk/registry.gen.ts create mode 100644 samples/sdk-playground/src/styles.css create mode 100644 samples/sdk-playground/src/types/json.d.ts create mode 100644 samples/sdk-playground/src/types/manifest.ts create mode 100644 samples/sdk-playground/tsconfig.json create mode 100644 samples/sdk-playground/vite.config.ts diff --git a/docs/samples/index.md b/docs/samples/index.md index c7d96b30c..e634807f3 100644 --- a/docs/samples/index.md +++ b/docs/samples/index.md @@ -123,6 +123,7 @@ Browse, filter, and clone the official `@uipath/uipath-typescript` sample apps. { "id": "agents", "label": "Agents", "accent": ["#7C5CFC", "#A78BFA"] }, { "id": "dashboards", "label": "Dashboards", "accent": ["#0EA5A4", "#2DD4C4"] }, { "id": "data-fabric", "label": "Data Fabric", "accent": ["#2563EB", "#5B8DEF"] }, + { "id": "dev-tools", "label": "Developer Tools", "accent": ["#475569", "#94A3B8"] }, { "id": "document", "label": "Document / HITL", "accent": ["#0F9D6B", "#34D399"] }, { "id": "process", "label": "Process Orchestration", "accent": ["#DB2777", "#F472B6"] } ], @@ -138,7 +139,8 @@ Browse, filter, and clone the official `@uipath/uipath-typescript` sample apps. { "id": "action-app-with-document", "title": "Action App — Bundled Document", "description": "Coded Action App for loan-application review. Reviewers assess applicant details, view a bundled sample PDF, and complete the task with an Approve or Reject decision.", "category": "action-apps", "framework": "React", "tags": ["Action Center","Coded Action App","Documents"], "path": "samples/coded-action-apps/action-app-with-document", "preview": null }, { "id": "action-app-with-file-attachment-document", "title": "Action App — File Attachment", "description": "Coded Action App for loan-application review with direct file attachments. Preview and download a directly attached PDF, as opposed to referencing files from Storage Buckets.", "category": "action-apps", "framework": "React", "tags": ["Action Center","Coded Action App","File Attachments","Documents"], "path": "samples/coded-action-apps/action-app-with-file-attachment-document", "preview": null }, { "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 } ] } diff --git a/samples/sdk-playground/.gitignore b/samples/sdk-playground/.gitignore new file mode 100644 index 000000000..6600b2a38 --- /dev/null +++ b/samples/sdk-playground/.gitignore @@ -0,0 +1,5 @@ +node_modules +dist +.env +.env.* +*.local diff --git a/samples/sdk-playground/.npmrc b/samples/sdk-playground/.npmrc new file mode 100644 index 000000000..74b802783 --- /dev/null +++ b/samples/sdk-playground/.npmrc @@ -0,0 +1 @@ +@uipath:registry=https://registry.npmjs.org/ diff --git a/samples/sdk-playground/README.md b/samples/sdk-playground/README.md new file mode 100644 index 000000000..67fc1b8a4 --- /dev/null +++ b/samples/sdk-playground/README.md @@ -0,0 +1,42 @@ +# UiPath SDK Playground + +A Swagger-style explorer for the UiPath TypeScript SDK, built as a coded app. Pick an SDK version, browse every service and method that version exposes, fill in parameters through a generated form, and run the call live — against either the platform-injected connection or custom credentials. + +## Features + +- **Version-aware method catalog** — six SDK versions installed side by side (latest patch of every minor line, `1.0.0` → `1.5.5`). A build-time script extracts each version's services, methods, parameters, enums, and JSDoc from its published `.d.ts` files, so the catalog can never drift from what the version actually ships. +- **Live execution** — each version is code-split into its own lazy chunk; the browser downloads and instantiates only the selected version. Switching versions rebuilds the SDK client from scratch. +- **Connection modes** + - *Platform default*: `new UiPath()` reads the meta tags UiPath Apps injects when this is deployed as a coded app — no configuration needed. + - *PAT*: org, tenant, base URL, and a personal access token, for local development or cross-tenant testing. + - *OAuth*: a Non-Confidential External Application's App ID (client ID), redirect URI, and scopes. Sign-in runs the SDK's PKCE flow via the UiPath identity server; needed for endpoints that reject PAT auth. The registered redirect URI must match the field value exactly (`http://localhost:5173` for local dev). +- **Generated forms** — enums become dropdowns, `Date` params become date pickers, object params get a JSON editor with a shape hint, and the SDK's own `@example` JSDoc is shown inline. +- **Copy as TypeScript** — every configured call can be copied as a runnable snippet (credentials always masked). +- **Bound-method discovery** — responses that carry SDK-attached entity methods (e.g. `task.assign()`) list them next to the JSON output. + +## Getting started + +```bash +npm install +npm run dev # generates manifests, then starts Vite +``` + +`npm run build` regenerates manifests, typechecks, and produces `dist/` for deployment as a coded app. + +## Adding or removing an SDK version + +1. Add/remove the alias in `package.json`: + ```json + "sdk-v1_6_0": "npm:@uipath/uipath-typescript@1.6.0" + ``` +2. `npm install && npm run manifests` + +The generator (`scripts/generate-manifests.mjs`) discovers aliases automatically, emits `src/manifests/.json`, and rewrites the lazy-import registry (`src/sdk/registry.gen.ts`). Nothing else to touch. + +## Security notes + +- The personal access token is held **in memory only** — never persisted to localStorage/sessionStorage, never logged, never embedded in generated code snippets. Reload the tab and it's gone. +- OAuth mode persists only **public identifiers** (App ID, org/tenant, scopes, redirect URI) to sessionStorage so the connection survives the sign-in redirect — never tokens or secrets. Token storage and the PKCE exchange are handled by the SDK itself. +- Changing credentials, org/tenant, or SDK version always disposes the old SDK client and builds a fresh one, so a token obtained for one tenant is never reused against another. +- All calls execute in the browser with the entered token's permissions — server-side authorization applies exactly as it would for any SDK consumer. +- Do not hardcode credentials or tenant identifiers in `index.html` or commit `.env` files (ignored via `.gitignore`). diff --git a/samples/sdk-playground/index.html b/samples/sdk-playground/index.html new file mode 100644 index 000000000..7496bd290 --- /dev/null +++ b/samples/sdk-playground/index.html @@ -0,0 +1,18 @@ + + + + + + + UiPath SDK Playground + + +
+ + + diff --git a/samples/sdk-playground/package-lock.json b/samples/sdk-playground/package-lock.json new file mode 100644 index 000000000..cf8aea2e0 --- /dev/null +++ b/samples/sdk-playground/package-lock.json @@ -0,0 +1,1384 @@ +{ + "name": "sdk-playground", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "sdk-playground", + "version": "0.0.0", + "dependencies": { + "react": "^19.2.0", + "react-dom": "^19.2.0", + "sdk-v1_0_0": "npm:@uipath/uipath-typescript@1.0.0", + "sdk-v1_1_3": "npm:@uipath/uipath-typescript@1.1.3", + "sdk-v1_2_2": "npm:@uipath/uipath-typescript@1.2.2", + "sdk-v1_3_11": "npm:@uipath/uipath-typescript@1.3.11", + "sdk-v1_4_2": "npm:@uipath/uipath-typescript@1.4.2", + "sdk-v1_5_5": "npm:@uipath/uipath-typescript@1.5.5" + }, + "devDependencies": { + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "@vitejs/plugin-react": "^6.0.3", + "ts-morph": "^28.0.0", + "typescript": "^5.9.3", + "vite": "^8.1.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz", + "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/api-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.204.0.tgz", + "integrity": "sha512-DqxY8yoAaiBPivoJD4UtgrMS8gEmzZ5lnaxzPojzLVHBGqPxgWm4zcuvcUHZiqQ6kRX2Klel2r9y8cA2HAtqpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.1.0.tgz", + "integrity": "sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.1.0.tgz", + "integrity": "sha512-1CJjf3LCvoefUOgegxi8h6r4B/wLSzInyhGP2UmIBYNlo4Qk5CZ73e1eEyWmfXvFtm1ybkmfb2DqWvspsYLrWw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.1.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.204.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.204.0.tgz", + "integrity": "sha512-y32iNNmpMUVFWSqbNrXE8xY/6EMge+HX3PXsMnCDV4cXT4SNT+W/3NgyMDf80KJL0fUK17/a0NmfXcrBhkFWrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.204.0", + "@opentelemetry/core": "2.1.0", + "@opentelemetry/resources": "2.1.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" + }, + "node_modules/@ts-morph/common": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.29.0.tgz", + "integrity": "sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^10.0.1", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.14" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@uipath/core-telemetry": { + "version": "1.0.0-beta.3", + "resolved": "https://registry.npmjs.org/@uipath/core-telemetry/-/core-telemetry-1.0.0-beta.3.tgz", + "integrity": "sha512-e/IHHJ77tygw/LvFRSEQ/bxFlmTivrk0ApeRIsPqTpwxXNEryGxLzSjWCRflAKs3EYj+jiwEYRWINpodMjmrqw==", + "license": "MIT", + "dependencies": { + "@opentelemetry/sdk-logs": "^0.204.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.4.tgz", + "integrity": "sha512-XcCQz0TBpBgljhj0gMuuDj49i6Ytqh5q1osT/Gp5uAVJUCTWxyskk/l1jwYYiu2xcNHHipdMz40EGfM1VdamVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + } + } + }, + "node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/brace-expansion": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", + "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "dev": true, + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/engine.io-client": { + "version": "6.6.6", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.6.6.tgz", + "integrity": "sha512-iY6QdftLQ9pyiPoX082bpf/u1UewnOaJrtJIF9T0++QB34lZrj0uP+Q/bj8AlUsAxqhnkTV2BS8SBZSxOmoV5Q==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.21.0", + "xmlhttprequest-ssl": "~2.1.1" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.8.tgz", + "integrity": "sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.8", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.8.tgz", + "integrity": "sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.8" + } + }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/sdk-v1_0_0": { + "name": "@uipath/uipath-typescript", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.0.0.tgz", + "integrity": "sha512-m2AO2lVs+esj2SM8Q+1cwMtxVeyQQ3B6d94TM3A1Je6XaBl3WnvX+1nA7YElxSG3YjiEeYd2EUhcsj7x3VqWdw==", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@opentelemetry/sdk-logs": "^0.204.0" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/sdk-v1_1_3": { + "name": "@uipath/uipath-typescript", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.1.3.tgz", + "integrity": "sha512-ffwJlmve65gFjW8QiQoYMiyBNS9se0K/jTyFJAX13p9aJbNdf23iW/DQB2qtfRgDDjkGrPNDZ5yknzmTaCferA==", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@opentelemetry/sdk-logs": "^0.204.0", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/sdk-v1_2_2": { + "name": "@uipath/uipath-typescript", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.2.2.tgz", + "integrity": "sha512-wLi5P7m3k07C+JB3VXhRJlNslxCQ5R7N3SQ+Yoh6fw11s9kZOc8m4d9qteHwVL9eP3VW7T7Wd39DuJr40HnS/Q==", + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@opentelemetry/sdk-logs": "^0.204.0", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/sdk-v1_3_11": { + "name": "@uipath/uipath-typescript", + "version": "1.3.11", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.3.11.tgz", + "integrity": "sha512-U0U6+KzuD8RSkKshrg/Q9YiVublWxbHgJGpSs16daqvT/augVc2fNG475fW2ggjYbOssEUtErQJYvAJUZ22MRw==", + "license": "MIT", + "dependencies": { + "@uipath/core-telemetry": "^1.0.0-beta.2", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/sdk-v1_4_2": { + "name": "@uipath/uipath-typescript", + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.4.2.tgz", + "integrity": "sha512-mElaUm3mKHuEBPRLaMWdJoAqqjmTQDNpqoeXYtu3fBQcnaikeh8Dc5a6MBa3wog2hoss7S8faf/uKC0t5xmYPQ==", + "license": "MIT", + "dependencies": { + "@uipath/core-telemetry": "^1.0.0-beta.3", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/sdk-v1_5_5": { + "name": "@uipath/uipath-typescript", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@uipath/uipath-typescript/-/uipath-typescript-1.5.5.tgz", + "integrity": "sha512-eav7AZruBwqiuM1glrXN2jtGxZfRS73yV2MVE/JKPIYj8eGcv0t+tgDxZ0pFrcB21+X/j88qnsGtOOk8izTwSw==", + "license": "MIT", + "dependencies": { + "@uipath/core-telemetry": "^1.0.0-beta.3", + "socket.io-client": "^4.8.1" + }, + "peerDependencies": { + "zod": "^4.2.1" + } + }, + "node_modules/socket.io-client": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.8.3.tgz", + "integrity": "sha512-uP0bpjWrjQmUt5DTHq9RuoCBdFJF10cdX9X+a368j/Ft0wmaVgxlrjvK3kjvgCODOMMOz9lcaRzxmso0bTWZ/g==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1", + "engine.io-client": "~6.6.1", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.7", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.7.tgz", + "integrity": "sha512-IH/iSeO9T6gz1KkFleGDWkG9N3dl4jXVYUtMhIqH10Md0ttMer8nUNWiP1DKuNrybD2xBrixLJdCC9J6ECoYkg==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.4.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-morph": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-28.0.0.tgz", + "integrity": "sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.29.0", + "code-block-writer": "^13.0.3" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/vite": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz", + "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.17", + "rolldown": "~1.1.5", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/ws": { + "version": "8.21.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.1.tgz", + "integrity": "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", + "integrity": "sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/zod": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/samples/sdk-playground/package.json b/samples/sdk-playground/package.json new file mode 100644 index 000000000..ea12bd1c3 --- /dev/null +++ b/samples/sdk-playground/package.json @@ -0,0 +1,31 @@ +{ + "name": "sdk-playground", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "manifests": "node scripts/generate-manifests.mjs", + "dev": "npm run manifests && vite", + "typecheck": "tsc --noEmit", + "build": "npm run manifests && tsc --noEmit && vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.2.0", + "react-dom": "^19.2.0", + "sdk-v1_0_0": "npm:@uipath/uipath-typescript@1.0.0", + "sdk-v1_1_3": "npm:@uipath/uipath-typescript@1.1.3", + "sdk-v1_2_2": "npm:@uipath/uipath-typescript@1.2.2", + "sdk-v1_3_11": "npm:@uipath/uipath-typescript@1.3.11", + "sdk-v1_4_2": "npm:@uipath/uipath-typescript@1.4.2", + "sdk-v1_5_5": "npm:@uipath/uipath-typescript@1.5.5" + }, + "devDependencies": { + "@types/react": "^19.2.2", + "@types/react-dom": "^19.2.2", + "@vitejs/plugin-react": "^6.0.3", + "ts-morph": "^28.0.0", + "typescript": "^5.9.3", + "vite": "^8.1.0" + } +} diff --git a/samples/sdk-playground/scripts/generate-manifests.mjs b/samples/sdk-playground/scripts/generate-manifests.mjs new file mode 100644 index 000000000..06e88c948 --- /dev/null +++ b/samples/sdk-playground/scripts/generate-manifests.mjs @@ -0,0 +1,256 @@ +/** + * Generates per-version method manifests + a lazy-import registry for the playground. + * + * For each `sdk-vX_Y_Z` npm alias installed in node_modules: + * 1. Reads the alias package.json `exports` map to discover service subpaths. + * 2. Parses each subpath's rolled-up `.d.ts` with ts-morph and extracts every + * `{Entity}ServiceModel` interface implemented by a service class: + * method names, JSDoc, parameters (with enum values and object shapes). + * 3. Reads the subpath's `.mjs` export statement to find the public alias + * (e.g. `TaskService as Tasks`). + * + * Emits: + * src/manifests/.json — one manifest per version + * src/sdk/registry.gen.ts — static import thunks (Vite-analyzable) + */ +import { Project } from 'ts-morph'; +import { readFileSync, writeFileSync, readdirSync, existsSync, mkdirSync } from 'node:fs'; +import { join, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..'); +const NODE_MODULES = join(ROOT, 'node_modules'); +const MANIFEST_DIR = join(ROOT, 'src', 'manifests'); +const GEN_FILE = join(ROOT, 'src', 'sdk', 'registry.gen.ts'); + +// Subpaths that expose infrastructure rather than user-facing services +const SKIP_SUBPATHS = new Set(['.', './core', './package.json']); +// BaseService/HTTP plumbing that must never surface as callable methods +const SKIP_METHODS = new Set(['get', 'post', 'put', 'delete', 'patch', 'head', 'options']); +const MAX_OBJECT_PROPS = 60; + +const aliases = readdirSync(NODE_MODULES) + .filter((d) => /^sdk-v\d+_\d+_\d+$/.test(d)) + .sort(); + +if (aliases.length === 0) { + console.error('No sdk-vX_Y_Z aliases found in node_modules — run npm install first.'); + process.exit(1); +} + +mkdirSync(MANIFEST_DIR, { recursive: true }); +mkdirSync(dirname(GEN_FILE), { recursive: true }); + +/** Extracts `Original as Alias` pairs from the runtime .mjs export statement. */ +function readRuntimeAliases(mjsPath) { + const map = new Map(); + if (!existsSync(mjsPath)) return map; + const source = readFileSync(mjsPath, 'utf8'); + const exportBlocks = source.match(/export\s*\{[^}]*\}/g) ?? []; + for (const block of exportBlocks) { + for (const m of block.matchAll(/(\w+)\s+as\s+(\w+)/g)) { + map.set(m[1], m[2]); + } + } + return map; +} + +function classifyType(type, typeText) { + // unwrap `T | undefined` from optional params + const parts = type.isUnion() ? type.getUnionTypes().filter((t) => !t.isUndefined() && !t.isNull()) : [type]; + const t = parts.length === 1 ? parts[0] : type; + + if (typeText === 'Date' || t.getText().endsWith('Date')) return { kind: 'date' }; + if (parts.length > 1 && parts.every((p) => p.isStringLiteral() || p.isNumberLiteral())) { + return { kind: 'enum', enumValues: parts.map((p) => p.getLiteralValue()) }; + } + if (t.isEnum() || t.isEnumLiteral()) { + const values = (t.isEnum() ? t.getUnionTypes() : [t]) + .map((u) => u.getLiteralValue()) + .filter((v) => v !== undefined); + return { kind: 'enum', enumValues: values }; + } + 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' }; + return { kind: 'json' }; +} + +function extractObjectShape(type) { + const parts = type.isUnion() ? type.getUnionTypes().filter((t) => !t.isUndefined() && !t.isNull()) : [type]; + if (parts.length !== 1) return undefined; + const props = parts[0].getProperties().slice(0, MAX_OBJECT_PROPS); + if (props.length === 0) return undefined; + const shape = []; + for (const p of props) { + const decl = p.getDeclarations()[0]; + if (!decl) continue; + const declText = decl.getText(); + // skip methods on response-ish shapes + if (/^\s*\w+\s*[(<]/.test(declText) && !declText.includes(':')) continue; + shape.push({ + name: p.getName(), + optional: p.isOptional?.() ?? declText.includes('?:'), + typeText: truncate(declText.split(/:(.+)/)[1]?.trim()?.replace(/;$/, '') ?? 'unknown', 120), + }); + } + return shape.length > 0 ? shape : undefined; +} + +function truncate(text, max) { + return text.length > max ? `${text.slice(0, max)}…` : text; +} + +function extractJsDoc(node) { + const docs = node.getJsDocs?.() ?? []; + if (docs.length === 0) return {}; + const doc = docs[docs.length - 1]; + const description = doc.getDescription().trim() || undefined; + const example = doc + .getTags() + .filter((t) => t.getTagName() === 'example') + .map((t) => t.getCommentText()?.trim()) + .filter(Boolean)[0]; + return { description, example }; +} + +const registryEntries = []; +const summary = []; + +for (const alias of aliases) { + const version = alias.replace('sdk-v', '').replaceAll('_', '.'); + const pkgDir = join(NODE_MODULES, alias); + const pkg = JSON.parse(readFileSync(join(pkgDir, 'package.json'), 'utf8')); + const subpaths = Object.keys(pkg.exports ?? {}).filter((s) => !SKIP_SUBPATHS.has(s)); + + const project = new Project({ + compilerOptions: { skipLibCheck: true }, + skipAddingFilesFromTsConfig: true, + }); + + const services = []; + const moduleSubpaths = []; + + for (const subpath of subpaths) { + const sub = subpath.replace('./', ''); + const dtsPath = join(pkgDir, 'dist', sub, 'index.d.ts'); + const mjsPath = join(pkgDir, 'dist', sub, 'index.mjs'); + if (!existsSync(dtsPath)) continue; + + const file = project.addSourceFileAtPath(dtsPath); + const runtimeAliases = readRuntimeAliases(mjsPath); + let moduleHasService = false; + + for (const cls of file.getClasses()) { + const impl = cls + .getImplements() + .map((i) => i.getExpression().getText()) + .find((n) => n.endsWith('ServiceModel')); + if (!impl) continue; + const model = file.getInterface(impl); + if (!model) continue; + const className = cls.getName(); + if (!className || !runtimeAliases.has(className)) { + // not exported from this module's runtime — likely a dependency rolled into the d.ts + if (!className) continue; + const isExported = readFileSync(mjsPath, 'utf8').includes(className); + if (!isExported) continue; + } + + const methods = []; + for (const method of model.getMethods()) { + const name = method.getName(); + if (SKIP_METHODS.has(name) || name.startsWith('_')) continue; + const { description, example } = extractJsDoc(method); + const params = method.getParameters().map((param) => { + const typeNode = param.getTypeNode(); + const typeText = truncate(typeNode ? typeNode.getText() : param.getType().getText(), 160); + const type = param.getType(); + const classified = classifyType(type, typeText); + const entry = { + name: param.getName(), + optional: param.isOptional() || param.hasQuestionToken(), + typeText, + ...classified, + }; + if (classified.kind === 'json') { + const properties = extractObjectShape(type); + if (properties) entry.properties = properties; + } + return entry; + }); + methods.push({ + name, + description, + example, + params, + returnType: truncate(method.getReturnTypeNode()?.getText() ?? '', 200), + }); + } + if (methods.length === 0) continue; + + services.push({ + name: runtimeAliases.get(className) ?? className, + className, + subpath: sub, + methods, + }); + moduleHasService = true; + } + + if (moduleHasService) moduleSubpaths.push(sub); + } + + services.sort((a, b) => a.name.localeCompare(b.name)); + const manifest = { version, services }; + writeFileSync(join(MANIFEST_DIR, `${version}.json`), JSON.stringify(manifest, null, 2)); + registryEntries.push({ version, alias, moduleSubpaths }); + summary.push(`${version}: ${services.length} services, ${services.reduce((n, s) => n + s.methods.length, 0)} methods`); +} + +// semver-descending so the picker defaults to the newest version +registryEntries.sort((a, b) => { + const pa = a.version.split('.').map(Number); + const pb = b.version.split('.').map(Number); + return pb[0] - pa[0] || pb[1] - pa[1] || pb[2] - pa[2]; +}); + +const gen = `// AUTO-GENERATED by scripts/generate-manifests.mjs — do not edit. +import type { VersionManifest } from '../types/manifest'; + +export interface SdkModule { + [exportName: string]: unknown; +} + +export interface VersionEntry { + manifest: () => Promise; + core: () => Promise; + modules: Record Promise>; +} + +function mod(loader: () => Promise): () => Promise { + return () => loader().then((m) => m as SdkModule); +} + +export const SDK_VERSIONS: Record = { +${registryEntries + .map( + (e) => ` '${e.version}': { + manifest: () => import('../manifests/${e.version}.json').then((m) => m.default as VersionManifest), + core: mod(() => import('${e.alias}/core')), + modules: { +${e.moduleSubpaths.map((s) => ` '${s}': mod(() => import('${e.alias}/${s}')),`).join('\n')} + }, + },` + ) + .join('\n')} +}; + +export const VERSION_LIST = Object.keys(SDK_VERSIONS); +`; +writeFileSync(GEN_FILE, gen); + +console.log('Generated manifests:'); +for (const line of summary) console.log(` ${line}`); +console.log(`Registry: ${GEN_FILE}`); diff --git a/samples/sdk-playground/src/App.tsx b/samples/sdk-playground/src/App.tsx new file mode 100644 index 000000000..b640ed27a --- /dev/null +++ b/samples/sdk-playground/src/App.tsx @@ -0,0 +1,235 @@ +import { useCallback, useEffect, useRef, useState } from 'react'; +import { SDK_VERSIONS, VERSION_LIST } from './sdk/registry.gen'; +import { + clearOAuthConnection, + createClient, + createService, + disposeClient, + invokeMethod, + loadOAuthConnection, + resumeClient, + saveOAuthConnection, + type ConnectionConfig, + type PlaygroundClient, +} from './sdk/client'; +import type { MethodManifest, ServiceManifest, VersionManifest } from './types/manifest'; +import { ConnectionPanel, type ConnectionStatus } from './components/ConnectionPanel'; +import { ServiceTree } from './components/ServiceTree'; +import { MethodPanel } from './components/MethodPanel'; +import type { InvocationResult } from './components/ResponseViewer'; + +interface Selection { + service: ServiceManifest; + method: MethodManifest; +} + +export function App() { + const [version, setVersion] = useState(VERSION_LIST[0] ?? ''); + const [manifest, setManifest] = useState(null); + const [selection, setSelection] = useState(null); + + const [status, setStatus] = useState('disconnected'); + const [statusDetail, setStatusDetail] = useState(); + const clientRef = useRef(null); + const configRef = useRef(null); + + const [running, setRunning] = useState(false); + const [result, setResult] = useState(null); + + // Load the manifest whenever the version changes; keep the selection if the + // same service+method still exists in the newly selected version. + useEffect(() => { + let cancelled = false; + setManifest(null); + SDK_VERSIONS[version] + ?.manifest() + .then((m) => { + if (cancelled) return; + setManifest(m); + setSelection((prev) => { + if (!prev) return null; + const service = m.services.find((s) => s.name === prev.service.name); + const method = service?.methods.find((mm) => mm.name === prev.method.name); + return service && method ? { service, method } : null; + }); + setResult(null); + }) + .catch(() => { + if (!cancelled) setManifest(null); + }); + return () => { + cancelled = true; + }; + }, [version]); + + // The SDK client is version-specific: switching versions or credentials + // always tears down the old instance so no token or socket carries over. + const teardown = useCallback(() => { + disposeClient(clientRef.current); + clientRef.current = null; + setStatus('disconnected'); + }, []); + + const connect = useCallback( + async (config: ConnectionConfig) => { + teardown(); + setStatus('connecting'); + setStatusDetail(undefined); + try { + if (config.mode === 'oauth') { + // initialize() navigates to the identity server — persist the public + // config (never the PAT) so the connection resumes after redirect + saveOAuthConnection(version, config); + } else { + clearOAuthConnection(); + } + const client = await createClient(version, config); + clientRef.current = client; + configRef.current = config; + setStatus('connected'); + } catch (err) { + configRef.current = null; + if (config.mode === 'oauth') clearOAuthConnection(); + setStatus('error'); + setStatusDetail(err instanceof Error ? err.message : String(err)); + } + }, + [version, teardown] + ); + + // Resume an OAuth connection after the identity-server redirect (or reuse a + // cached token on reload) — never starts a new sign-in. Ref-guarded: React + // StrictMode double-invokes effects in dev, and the OAuth callback code is + // single-use — completing it twice fails the second exchange. + const didResumeOAuth = useRef(false); + useEffect(() => { + if (didResumeOAuth.current) return; + didResumeOAuth.current = true; + const stored = loadOAuthConnection(); + if (!stored) return; + setVersion(stored.version); + setStatus('connecting'); + resumeClient(stored.version, stored.config) + .then((client) => { + if (client) { + clientRef.current = client; + configRef.current = stored.config; + setStatus('connected'); + } else { + // sign-in required — leave it to an explicit click on Connect + setStatus('disconnected'); + } + }) + .catch((err) => { + clearOAuthConnection(); + setStatus('error'); + setStatusDetail(err instanceof Error ? err.message : String(err)); + }); + }, []); + + // Version switch with an active connection: rebuild the client on the new + // version using the same (still in-memory) config. + const changeVersion = useCallback( + (next: string) => { + setVersion(next); + setResult(null); + if (clientRef.current && configRef.current) { + const config = configRef.current; + teardown(); + setStatus('connecting'); + if (config.mode === 'oauth') saveOAuthConnection(next, config); + createClient(next, config) + .then((client) => { + clientRef.current = client; + setStatus('connected'); + }) + .catch((err) => { + setStatus('error'); + setStatusDetail(err instanceof Error ? err.message : String(err)); + }); + } + }, + [teardown] + ); + + useEffect(() => () => disposeClient(clientRef.current), []); + + const run = useCallback( + async (values: Record) => { + const client = clientRef.current; + if (!client || !selection) return; + setRunning(true); + setResult(null); + const started = performance.now(); + try { + const instance = await createService(client, selection.service); + const data = await invokeMethod(instance, selection.method, values); + setResult({ ok: true, data, durationMs: Math.round(performance.now() - started) }); + } catch (err) { + setResult({ + ok: false, + error: err instanceof Error ? `${err.name}: ${err.message}` : String(err), + durationMs: Math.round(performance.now() - started), + }); + } finally { + setRunning(false); + } + }, + [selection] + ); + + return ( +
+
+

UiPath SDK Playground

+ +
+ +
+
+ + { + setSelection({ service, method }); + setResult(null); + }} + /> +
+ + {selection ? ( + + ) : ( +
+

Select a method from the tree to inspect and run it.

+ {manifest && ( +

+ SDK {manifest.version} exposes {manifest.services.length} services with{' '} + {manifest.services.reduce((n, s) => n + s.methods.length, 0)} methods. +

+ )} +
+ )} +
+
+ ); +} diff --git a/samples/sdk-playground/src/components/ConnectionPanel.tsx b/samples/sdk-playground/src/components/ConnectionPanel.tsx new file mode 100644 index 000000000..60bda50b6 --- /dev/null +++ b/samples/sdk-playground/src/components/ConnectionPanel.tsx @@ -0,0 +1,132 @@ +import { useState } from 'react'; +import { loadOAuthConnection, type ConnectionConfig } from '../sdk/client'; + +export type ConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error'; + +interface ConnectionPanelProps { + status: ConnectionStatus; + statusDetail?: string; + onConnect: (config: ConnectionConfig) => void; +} + +/** + * Org / tenant / credential entry with fallback to platform-injected defaults. + * + * PAT mode: the secret is kept in component state only — never persisted, + * never echoed into snippets or logs. + * OAuth mode: public identifiers only (App ID, scopes, redirect URI); the + * config is restored from sessionStorage after the identity-server redirect. + */ +export function ConnectionPanel({ status, statusDetail, onConnect }: ConnectionPanelProps) { + // prefill OAuth fields when resuming after a redirect round-trip + const stored = loadOAuthConnection()?.config; + + const [mode, setMode] = useState(stored ? 'oauth' : 'default'); + const [baseUrl, setBaseUrl] = useState(stored?.baseUrl ?? 'https://cloud.uipath.com'); + const [orgName, setOrgName] = useState(stored?.orgName ?? ''); + const [tenantName, setTenantName] = useState(stored?.tenantName ?? ''); + const [secret, setSecret] = useState(''); + const [clientId, setClientId] = useState(stored?.clientId ?? ''); + const [redirectUri, setRedirectUri] = useState(stored?.redirectUri ?? window.location.origin); + const [scope, setScope] = useState(stored?.scope ?? ''); + + const baseReady = baseUrl.trim() !== '' && orgName.trim() !== '' && tenantName.trim() !== ''; + const ready = + mode === 'default' || + (mode === 'custom' && baseReady && secret !== '') || + (mode === 'oauth' && baseReady && clientId.trim() !== '' && redirectUri.trim() !== '' && scope.trim() !== ''); + const canConnect = status !== 'connecting' && ready; + + const handleConnect = () => { + onConnect({ mode, baseUrl, orgName, tenantName, secret, clientId, redirectUri, scope }); + }; + + return ( +
+
+

Connection

+ + {status === 'connected' ? 'Connected' : status === 'connecting' ? 'Connecting…' : status === 'error' ? 'Error' : 'Not connected'} + +
+ +
+ + + +
+ + {mode === 'default' && ( +

+ Uses the org, tenant, and auth injected by UiPath Apps when this playground is deployed as a coded app. For + local development, switch to PAT or OAuth. +

+ )} + + {mode !== 'default' && ( +
+ + + + + {mode === 'custom' && ( + <> + +

+ The secret stays in memory for this tab only — it is never stored, logged, or included in generated + code snippets. Calls run with this token's permissions. +

+ + )} + + {mode === 'oauth' && ( + <> + + + +

+ Register a Non-Confidential External Application whose redirect URI matches the value + above exactly. Connecting redirects to the UiPath sign-in page and returns here. +

+ + )} +
+ )} + + + {status === 'error' && statusDetail &&

{statusDetail}

} +
+ ); +} diff --git a/samples/sdk-playground/src/components/MethodPanel.tsx b/samples/sdk-playground/src/components/MethodPanel.tsx new file mode 100644 index 000000000..0b96d2619 --- /dev/null +++ b/samples/sdk-playground/src/components/MethodPanel.tsx @@ -0,0 +1,169 @@ +import { useEffect, useMemo, useState } from 'react'; +import type { MethodManifest, ParamManifest, ServiceManifest } from '../types/manifest'; +import { ResponseViewer, type InvocationResult } from './ResponseViewer'; + +interface MethodPanelProps { + service: ServiceManifest; + method: MethodManifest; + version: string; + connected: boolean; + running: boolean; + result: InvocationResult | null; + onRun: (values: Record) => void; +} + +function ParamInput({ param, value, onChange }: { param: ParamManifest; value: string; onChange: (v: string) => void }) { + switch (param.kind) { + case 'boolean': + return ( + + ); + case 'enum': + return ( + + ); + case 'date': + return onChange(e.target.value)} />; + case 'number': + return onChange(e.target.value)} placeholder={param.typeText} />; + case 'json': + return ( +