diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 76e3a023f1..af3c4855fb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ catalogs: '@heroicons/react': specifier: 2.2.0 version: 2.2.0 + '@hey-api/openapi-ts': + specifier: 0.97.0 + version: 0.97.0 '@hono/node-server': specifier: 2.0.0 version: 2.0.0 @@ -1125,6 +1128,9 @@ importers: '@eslint-react/eslint-plugin': specifier: 'catalog:' version: 3.0.0(eslint@10.2.1(jiti@2.6.1))(typescript@6.0.3) + '@hey-api/openapi-ts': + specifier: 'catalog:' + version: 0.97.0(magicast@0.5.2)(typescript@6.0.3) '@hono/node-server': specifier: 'catalog:' version: 2.0.0(hono@4.12.15) @@ -2072,6 +2078,31 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' + '@hey-api/codegen-core@0.8.1': + resolution: {integrity: sha512-Iciv2vUCJTW9lWM/ROvyZLblmcbYJHPuXfzb1SzeDVVn4xEXu2ilLU1pq3fn+09FZ/Y0P7VyvRE47UDU6om8xA==} + engines: {node: '>=22.13.0'} + + '@hey-api/json-schema-ref-parser@1.4.1': + resolution: {integrity: sha512-DoPJGxVApDlktP1yYLjmOrF0YBEqb32ieCbx1S1i09n8TyCgdoh4yQaQ3kp0sMTauH+bwNKPsFh7S8qiWCoKZA==} + engines: {node: '>=22.13.0'} + + '@hey-api/openapi-ts@0.97.0': + resolution: {integrity: sha512-WZkKgrDlZpxKlDv2HkBCzaAYeuM+EtZKFmKGBv9/JblAKpX3JQTROi7PzlCZE3eisetRPSakbcRgn+LGyB7EiQ==} + engines: {node: '>=22.13.0'} + hasBin: true + peerDependencies: + typescript: '>=5.5.3 || >=6.0.0 || 6.0.1-rc' + + '@hey-api/shared@0.4.2': + resolution: {integrity: sha512-4fconS10E0Xr4/acV8G+BkApxaIStxrT0GhB9BDTQWvrFTy5/nV933SyFk8qImcbpKvgv9hpn3N+7bV8oFrbjA==} + engines: {node: '>=22.13.0'} + + '@hey-api/spec-types@0.2.0': + resolution: {integrity: sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg==} + + '@hey-api/types@0.1.4': + resolution: {integrity: sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg==} + '@hono/node-server@2.0.0': resolution: {integrity: sha512-n3GfHwwCvHCkGmOwKfxUPOlbfzuO64Sbc5XC4NGPIXxkuOnJrdgExdRKmHfF924r914WRJPT397GdqLvdYTeyQ==} engines: {node: '>=20'} @@ -2294,6 +2325,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@lexical/clipboard@0.44.0': resolution: {integrity: sha512-nfmNIs7uENqlDI7cm2E4I1Yp8mDJGMhEQIrIV2rNWnL1oeHVXQ7yuYdyoPdcY1zuj/9nvkYBQYUEh0QiGwpETA==} @@ -2369,6 +2403,10 @@ packages: peerDependencies: yjs: '>=13.5.22' + '@lukeed/ms@2.0.2': + resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} + engines: {node: '>=8'} + '@mdx-js/loader@3.1.1': resolution: {integrity: sha512-0TTacJyZ9mDmY+VefuthVshaNIyCGZHJG2fMnGaDttCt8HmjUF7SizlHJpaCDoGnN635nK1wpzfpx/Xx5S4WnQ==} peerDependencies: @@ -4653,6 +4691,10 @@ packages: ajv@6.14.0: resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + ansi-regex@4.1.1: resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} engines: {node: '>=6'} @@ -4792,6 +4834,14 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} + peerDependencies: + magicast: '*' + peerDependenciesMeta: + magicast: + optional: true + cac@7.0.0: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} @@ -4858,6 +4908,10 @@ packages: chevrotain@11.1.2: resolution: {integrity: sha512-opLQzEVriiH1uUQ4Kctsd49bRoFDXGGSC4GUqj7pGyxM3RehRhvTlZJc1FL/Flew2p5uwxa1tUDWKzI4wNM8pg==} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -4931,6 +4985,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -5250,6 +5308,9 @@ packages: resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} engines: {node: '>=12'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + delaunator@5.1.0: resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} @@ -5257,6 +5318,9 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -5309,6 +5373,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dotenv@17.4.2: + resolution: {integrity: sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==} + engines: {node: '>=12'} + echarts-for-react@3.0.6: resolution: {integrity: sha512-4zqLgTGWS3JvkQDXjzkR1k1CHRdpd6by0988TWMJgnvDytegWLbeP/VNZmMa+0VJx2eD7Y632bi2JquXDgiGJg==} peerDependencies: @@ -5893,6 +5961,10 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + giget@3.2.0: + resolution: {integrity: sha512-GvHTWcykIR/fP8cj8dMpuMMkvaeJfPvYnhq0oW+chSeIr+ldX21ifU2Ms6KBoyKZQZmVaUAAhQ2EZ68KJF8a7A==} + hasBin: true + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -7137,6 +7209,9 @@ packages: resolution: {integrity: sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==} engines: {node: '>=14.18.0'} + rc9@3.0.1: + resolution: {integrity: sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ==} + rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -7310,6 +7385,10 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -9332,6 +9411,56 @@ snapshots: dependencies: react: 19.2.5 + '@hey-api/codegen-core@0.8.1(magicast@0.5.2)': + dependencies: + '@hey-api/types': 0.1.4 + ansi-colors: 4.1.3 + c12: 3.3.4(magicast@0.5.2) + color-support: 1.1.3 + transitivePeerDependencies: + - magicast + + '@hey-api/json-schema-ref-parser@1.4.1': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + yaml: 2.8.3 + + '@hey-api/openapi-ts@0.97.0(magicast@0.5.2)(typescript@6.0.3)': + dependencies: + '@hey-api/codegen-core': 0.8.1(magicast@0.5.2) + '@hey-api/json-schema-ref-parser': 1.4.1 + '@hey-api/shared': 0.4.2(magicast@0.5.2) + '@hey-api/spec-types': 0.2.0 + '@hey-api/types': 0.1.4 + '@lukeed/ms': 2.0.2 + ansi-colors: 4.1.3 + color-support: 1.1.3 + commander: 14.0.3 + get-tsconfig: 4.14.0 + typescript: 6.0.3 + transitivePeerDependencies: + - magicast + + '@hey-api/shared@0.4.2(magicast@0.5.2)': + dependencies: + '@hey-api/codegen-core': 0.8.1(magicast@0.5.2) + '@hey-api/json-schema-ref-parser': 1.4.1 + '@hey-api/spec-types': 0.2.0 + '@hey-api/types': 0.1.4 + ansi-colors: 4.1.3 + cross-spawn: 7.0.6 + open: 11.0.0 + semver: 7.7.4 + transitivePeerDependencies: + - magicast + + '@hey-api/spec-types@0.2.0': + dependencies: + '@hey-api/types': 0.1.4 + + '@hey-api/types@0.1.4': {} + '@hono/node-server@2.0.0(hono@4.12.15)': dependencies: hono: 4.12.15 @@ -9517,6 +9646,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jsdevtools/ono@7.1.3': {} + '@lexical/clipboard@0.44.0': dependencies: '@lexical/extension': 0.44.0 @@ -9669,6 +9800,8 @@ snapshots: '@lexical/selection': 0.44.0 lexical: 0.44.0 + '@lukeed/ms@2.0.2': {} + '@mdx-js/loader@3.1.1': dependencies: '@mdx-js/mdx': 3.1.1 @@ -11863,6 +11996,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-colors@4.1.3: {} + ansi-regex@4.1.1: {} ansi-regex@5.0.1: {} @@ -11977,6 +12112,23 @@ snapshots: bytes@3.1.2: {} + c12@3.3.4(magicast@0.5.2): + dependencies: + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.4.2 + exsolve: 1.0.8 + giget: 3.2.0 + jiti: 2.6.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rc9: 3.0.1 + optionalDependencies: + magicast: 0.5.2 + cac@7.0.0: {} camelize@1.0.1: {} @@ -12064,6 +12216,10 @@ snapshots: '@chevrotain/utils': 11.1.2 lodash-es: 4.18.0 + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + chownr@1.1.4: optional: true @@ -12135,6 +12291,8 @@ snapshots: color-name@1.1.4: {} + color-support@1.1.3: {} + comma-separated-tokens@2.0.3: {} commander@14.0.0: {} @@ -12457,12 +12615,16 @@ snapshots: define-lazy-prop@3.0.0: {} + defu@6.1.7: {} + delaunator@5.1.0: dependencies: robust-predicates: 3.0.3 dequal@2.0.3: {} + destr@2.0.5: {} + detect-libc@2.1.2: {} detect-node-es@1.1.0: {} @@ -12511,6 +12673,8 @@ snapshots: dotenv@16.6.1: {} + dotenv@17.4.2: {} + echarts-for-react@3.0.6(echarts@6.0.0)(react@19.2.5): dependencies: echarts: 6.0.0 @@ -13274,6 +13438,8 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + giget@3.2.0: {} + github-from-package@0.0.0: optional: true @@ -14928,6 +15094,11 @@ snapshots: radash@12.1.1: {} + rc9@3.0.1: + dependencies: + defu: 6.1.7 + destr: 2.0.5 + rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -15126,6 +15297,8 @@ snapshots: util-deprecate: 1.0.2 optional: true + readdirp@5.0.0: {} + recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -16330,6 +16503,7 @@ snapshots: time: '@amplitude/analytics-browser@2.42.0': '2026-04-28T17:01:08.442Z' '@amplitude/plugin-session-replay-browser@1.28.1': '2026-04-28T17:01:37.145Z' + '@hey-api/openapi-ts@0.97.0': '2026-04-28T03:33:22.380Z' '@hono/node-server@2.0.0': '2026-04-21T00:25:40.852Z' '@lexical/link@0.44.0': '2026-04-27T14:47:45.477Z' '@lexical/list@0.44.0': '2026-04-27T14:47:48.463Z' diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bba9b50682..8be67e2427 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -68,6 +68,7 @@ catalog: '@formatjs/intl-localematcher': 0.8.4 '@headlessui/react': 2.2.10 '@heroicons/react': 2.2.0 + '@hey-api/openapi-ts': 0.97.0 '@hono/node-server': 2.0.0 '@iconify-json/heroicons': 1.2.3 '@iconify-json/ri': 1.2.10 diff --git a/vite.config.ts b/vite.config.ts index aebcaf8f73..e8f94d964a 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -4,4 +4,8 @@ export default defineConfig({ staged: { '*': 'eslint --fix --pass-on-unpruned-suppressions', }, + fmt: { + singleQuote: true, + semi: false, + }, }) diff --git a/web/contract/generated/enterprise/orpc.gen.ts b/web/contract/generated/enterprise/orpc.gen.ts new file mode 100644 index 0000000000..6b9b76470a --- /dev/null +++ b/web/contract/generated/enterprise/orpc.gen.ts @@ -0,0 +1,138 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import { oc } from '@orpc/contract' +import * as z from 'zod' + +import { + zConsoleSsoOAuth2LoginResponse, + zConsoleSsoOidcLoginResponse, + zConsoleSsoSamlLoginResponse, + zWebAppAuthGetGroupSubjectsQuery, + zWebAppAuthGetGroupSubjectsResponse, + zWebAppAuthGetWebAppAccessModeQuery, + zWebAppAuthGetWebAppAccessModeResponse, + zWebAppAuthGetWebAppWhitelistSubjectsQuery, + zWebAppAuthGetWebAppWhitelistSubjectsResponse, + zWebAppAuthIsUserAllowedToAccessWebAppQuery, + zWebAppAuthIsUserAllowedToAccessWebAppResponse, + zWebAppAuthSearchForWhilteListCandidatesQuery, + zWebAppAuthSearchForWhilteListCandidatesResponse, + zWebAppAuthUpdateWebAppWhitelistSubjectsBody, + zWebAppAuthUpdateWebAppWhitelistSubjectsResponse, +} from './zod.gen' + +export const oAuth2Login = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_OAuth2Login', + path: '/enterprise/sso/oauth2/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoOAuth2LoginResponse) + +export const oidcLogin = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_OIDCLogin', + path: '/enterprise/sso/oidc/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoOidcLoginResponse) + +export const samlLogin = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'ConsoleSSO_SAMLLogin', + path: '/enterprise/sso/saml/login', + tags: ['ConsoleSSO'], + }) + .output(zConsoleSsoSamlLoginResponse) + +export const consoleSso = { + oAuth2Login, + oidcLogin, + samlLogin, +} + +export const getWebAppAccessMode = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetWebAppAccessMode', + path: '/enterprise/webapp/app/access-mode', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetWebAppAccessModeQuery.optional() })) + .output(zWebAppAuthGetWebAppAccessModeResponse) + +export const updateWebAppWhitelistSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'POST', + operationId: 'WebAppAuth_UpdateWebAppWhitelistSubjects', + path: '/enterprise/webapp/app/access-mode', + tags: ['WebAppAuth'], + }) + .input(z.object({ body: zWebAppAuthUpdateWebAppWhitelistSubjectsBody })) + .output(zWebAppAuthUpdateWebAppWhitelistSubjectsResponse) + +export const searchForWhilteListCandidates = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_SearchForWhilteListCandidates', + path: '/enterprise/webapp/app/subject/search', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthSearchForWhilteListCandidatesQuery.optional() })) + .output(zWebAppAuthSearchForWhilteListCandidatesResponse) + +export const getWebAppWhitelistSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetWebAppWhitelistSubjects', + path: '/enterprise/webapp/app/subjects', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetWebAppWhitelistSubjectsQuery.optional() })) + .output(zWebAppAuthGetWebAppWhitelistSubjectsResponse) + +export const getGroupSubjects = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_GetGroupSubjects', + path: '/enterprise/webapp/group/subjects', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthGetGroupSubjectsQuery.optional() })) + .output(zWebAppAuthGetGroupSubjectsResponse) + +export const isUserAllowedToAccessWebApp = oc + .route({ + inputStructure: 'detailed', + method: 'GET', + operationId: 'WebAppAuth_IsUserAllowedToAccessWebApp', + path: '/enterprise/webapp/permission', + tags: ['WebAppAuth'], + }) + .input(z.object({ query: zWebAppAuthIsUserAllowedToAccessWebAppQuery.optional() })) + .output(zWebAppAuthIsUserAllowedToAccessWebAppResponse) + +export const webAppAuth = { + getWebAppAccessMode, + updateWebAppWhitelistSubjects, + searchForWhilteListCandidates, + getWebAppWhitelistSubjects, + getGroupSubjects, + isUserAllowedToAccessWebApp, +} + +export const contract = { + consoleSso, + webAppAuth, +} diff --git a/web/contract/generated/enterprise/types.gen.ts b/web/contract/generated/enterprise/types.gen.ts new file mode 100644 index 0000000000..b747c4baa8 --- /dev/null +++ b/web/contract/generated/enterprise/types.gen.ts @@ -0,0 +1,1103 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}) +} + +export type Account = { + id?: string + email?: string + name?: string +} + +export type AccountDetail = { + account?: Account + status?: string + createdAt?: string + lastActiveAt?: string + workspaces?: Array + groups?: Array +} + +export type AccountDetailGroup = { + id?: string + name?: string +} + +export type AccountInWorkspace = { + workspaceId?: string + workspaceName?: string + role?: string +} + +export type AddGroupAppsRequest = { + id?: string + app_ids?: Array +} + +export type AuthSettingsReply = { + userSsoSettings?: SsoSettings + webSsoSettings?: SsoSettings + dashboardSsoSettings?: SsoSettings + userSsoSamlAcsUrl?: string + userSsoOidcCallbackUrl?: string + userSsoOauth2CallbackUrl?: string + webSsoSamlAcsUrl?: string + webSsoOidcCallbackUrl?: string + webSsoOauth2CallbackUrl?: string + webSsoMembersSamlAcsUrl?: string + webSsoMembersOidcCallbackUrl?: string + webSsoMembersOauth2CallbackUrl?: string + dashboardSsoSamlAcsUrl?: string + dashboardSsoOidcCallbackUrl?: string + dashboardSsoOauth2CallbackUrl?: string +} + +export type AuthSettingsReq = { + ssoType?: string + ssoSettings?: SsoSettings +} + +export type BrandingInfo = { + enabled?: boolean + applicationTitle?: string + loginPageLogo?: string + workspaceLogo?: string + favicon?: string +} + +export type CheckPasswordStatusReply = { + requirePasswordChange?: boolean + changeReason?: number + daysToExpire?: number + message?: string +} + +export type ClearDefaultWorkspaceReply = { + [key: string]: unknown +} + +export type CreateBearerTokenResponse = { + token?: string +} + +export type CreateMemberReply = { + id?: string + password?: string +} + +export type CreateMemberReq = { + name?: string + email?: string + status?: string +} + +export type CreateNewGroupsReq = { + groups?: Array +} + +export type CreateNewGroupsReqGroup = { + name?: string +} + +export type CreateNewGroupsRes = { + groups?: Array +} + +export type CreateResourceGroupRequest = { + name?: string + description?: string +} + +export type CreateSecretKeyReply = { + id?: string + name?: string + secretKey?: string + createdAt?: string + lastActive?: string +} + +export type CreateSecretKeyReq = { + name?: string +} + +export type CreateUserReply = { + id?: string + password?: string +} + +export type CreateUserReq = { + name?: string + email?: string + status?: string +} + +export type CreateWorkspaceReply = { + workspace?: Workspace +} + +export type CreateWorkspaceReq = { + name?: string + email?: string + status?: string +} + +export type CurrentUserReply = { + id?: string + name?: string + email?: string + interfaceLanguage?: string + timezone?: string +} + +export type DashboardSsooidcLoginReply = { + url?: string + state?: string +} + +export type DashboardSsoOauth2LoginReply = { + url?: string + state?: string +} + +export type DashboardSsosamlLoginReply = { + url?: string +} + +export type DeleteGroupsRes = { + message?: string +} + +export type DeleteMemberReply = { + account?: Account +} + +export type DeleteSecretKeyReply = { + message?: string +} + +export type DeleteUserReply = { + account?: Account +} + +export type DeleteWorkspaceReply = { + [key: string]: unknown +} + +export type EndpointReply = { + mode?: number + metricsEndpoint?: OtelExporterEndpoint + tracesEndpoint?: OtelExporterEndpoint +} + +export type EnterpriseSystemUserSettingReply = { + ssoEnforcedForSignin?: boolean + ssoEnforcedForSigninProtocol?: string + enableEmailPasswordLogin?: boolean +} + +export type GetBearerTokenResponse = { + maskedToken?: string +} + +export type GetClusterInfoReply = { + mode?: string + clusterId?: string + verifyMode?: string +} + +export type GetDefaultWorkspaceReply = { + workspaceId?: string + workspace?: Workspace +} + +export type GetGroupSubjectsRes = { + subjects?: Array +} + +export type GetGroupsRes = { + groups?: Array +} + +export type GetJoinedGroupsRes = { + groups?: Array +} + +export type GetLicenseReply = { + license?: LicenseInfo +} + +export type GetLicenseStatusReply = { + status?: string +} + +export type GetMfaInfoReply = { + userEnabled?: boolean + userSetup?: boolean + globalEnabled?: boolean +} + +export type GetMemberReply = { + account?: AccountDetail +} + +export type GetUserReply = { + account?: AccountDetail +} + +export type GetWebAppAccessModeRes = { + accessMode?: string +} + +export type GetWebAppAuthInfoRes = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type GetWebAppWhitelistSubjectsRes = { + groups?: Array + members?: Array +} + +export type GetWebAppWhitelistSubjectsResMember = { + id?: string + name?: string + email?: string + avatar?: string +} + +export type GetWorkspacePermissionReply = { + permission?: WorkspacePermission +} + +export type GetWorkspaceReply = { + workspace?: Workspace +} + +export type GroupAppItem = { + app_id?: string + app_name?: string + workspace_id?: string + workspace_name?: string + app_status?: number + token_usage?: string + rpm?: string + concurrency?: string +} + +export type HealthzReply = { + message?: string + status?: string +} + +export type InfoConfigReply = { + SSOEnforcedForSignin?: boolean + SSOEnforcedForSigninProtocol?: string + SSOEnforcedForWeb?: boolean + SSOEnforcedForWebProtocol?: string + EnableEmailCodeLogin?: boolean + EnableEmailPasswordLogin?: boolean + IsAllowRegister?: boolean + IsAllowCreateWorkspace?: boolean + License?: LicenseStatus + Branding?: BrandingInfo + WebAppAuth?: WebAppAuthInfo + PluginInstallationPermission?: PluginInstallationPermissionInfo +} + +export type InnerAdmission = { + marker?: string + concurrencyGroupIds?: Array +} + +export type InnerBatchGetWebAppAccessModesByIdReq = { + appIds?: Array +} + +export type InnerBatchGetWebAppAccessModesByIdRes = { + accessModes?: { + [key: string]: string + } +} + +export type InnerBatchIsUserAllowedToAccessWebAppReq = { + userId?: string + appIds?: Array +} + +export type InnerBatchIsUserAllowedToAccessWebAppRes = { + permissions?: { + [key: string]: boolean + } +} + +export type InnerCleanAppRes = { + message?: string +} + +export type InnerGetWebAppAccessModeByCodeRes = { + accessMode?: string +} + +export type InnerGetWebAppAccessModeByIdRes = { + accessMode?: string +} + +export type InnerGroupConfig = { + id?: string + enabled?: boolean + membershipId?: string + limits?: Array +} + +export type InnerIsUserAllowedToAccessWebAppRes = { + result?: boolean +} + +export type InnerReleaseAdmissionRequest = { + admission?: InnerAdmission +} + +export type InnerReleaseAdmissionResponse = { + [key: string]: unknown +} + +export type InnerResolveResponse = { + appId?: string + groups?: Array + blocked?: boolean + blockGroupId?: string + blockReason?: string + admission?: InnerAdmission +} + +export type InnerTryAddAccountToDefaultWorkspaceReply = { + workspaceId?: string + joined?: boolean + message?: string +} + +export type InnerTryAddAccountToDefaultWorkspaceReq = { + accountId?: string +} + +export type IsUserAllowedToAccessWebAppRes = { + result?: boolean +} + +export type JoinWorkspaceReply = { + message?: string +} + +export type JoinWorkspaceReq = { + id?: string + email?: string + role?: string +} + +export type LicenseInfo = { + uuid?: string + expiredAt?: string + clusterId?: string + product?: string + limits?: LimitFields +} + +export type LicenseStatus = { + status?: string + expiredAt?: string + workspaces?: ResourceQuota +} + +export type LimitConfig = { + type?: number + threshold?: string + action?: number + reached?: boolean +} + +export type LimitFields = { + workspaceMembers?: number + workspaces?: ResourceQuota +} + +export type ListGroupAppsResponse = { + items?: Array + total?: string +} + +export type ListMembersReply = { + data?: Array + pagination?: Pagination +} + +export type ListResourceGroupsResponse = { + items?: Array + total?: string +} + +export type ListSecretKeysReply = { + data?: Array + pagination?: Pagination +} + +export type ListUsersReply = { + data?: Array + pagination?: Pagination +} + +export type ListWorkspacesReply = { + data?: Array + pagination?: Pagination +} + +export type LoginTypesReply = { + enabledEmailCodeLogin?: boolean + enableEmailPasswordLogin?: boolean + isAllowRegister?: boolean + isAllowCreateWorkspace?: boolean +} + +export type LoginTypesReq = { + enabledEmailCodeLogin?: boolean + enableEmailPasswordLogin?: boolean + isAllowRegister?: boolean + isAllowCreateWorkspace?: boolean +} + +export type MfaBackupCodesRes = { + codes?: Array + validCounts?: number + createdAt?: string +} + +export type MfaDeleteBackupCodesRes = { + message?: string +} + +export type MfaDeleteRes = { + token?: string +} + +export type MfaDownloadBackupCodesSummaryRes = { + content?: string +} + +export type MfaEnrollReq = { + code?: string +} + +export type MfaEnrollRes = { + token?: string +} + +export type MfaGetEnrollInfoRes = { + qrCode?: string + secret?: string +} + +export type MfaModifyRes = { + message?: string +} + +export type OAuth2Config = { + clientId?: string + clientSecret?: string + authUrl?: string + tokenUrl?: string + userinfoUrl?: string + scopes?: string + enablePkce?: boolean +} + +export type OAuth2LoginReply = { + url?: string + state?: string +} + +export type OidcConfig = { + issuerUrl?: string + clientId?: string + clientSecret?: string + enablePkce?: boolean +} + +export type OidcReply = { + url?: string + state?: string +} + +export type OtelExporterEndpoint = { + endpoint?: string + compression?: string + protocol?: number + timeout?: string + headers?: { + [key: string]: string + } + tlsCaPem?: string + tlsInsecure?: boolean + tlsClientCertPem?: string + tlsClientKeyPem?: string + enabled?: boolean + tlsInsecureSkipVerify?: boolean +} + +export type OtelExporterStatusReply = { + connectedAt?: string + bytesPushed?: string + itemsInQueue?: string + logs?: string + status?: number +} + +export type PasswordPolicyConfig = { + minLength?: number + requireDigit?: boolean + requireLowercase?: boolean + requireUppercase?: boolean + requireSpecial?: boolean + forbidRepeated?: boolean + forbidSequential?: boolean + expiryEnabled?: boolean + expiryDays?: number +} + +export type PasswordStrengthReply = { + level?: number +} + +export type PasswordStrengthReq = { + password?: string +} + +export type PluginInstallationPermissionInfo = { + pluginInstallationScope?: string + restrictToMarketplaceOnly?: boolean +} + +export type PluginInstallationSettingsReply = { + pluginInstallationScope?: number + restrictToMarketplaceOnly?: boolean +} + +export type ResetMemberPasswordReply = { + id?: string + password?: string +} + +export type ResetMemberPasswordReq = { + id?: string +} + +export type ResetPasswordReply = { + message?: string +} + +export type ResetPasswordReq = { + currentPassword?: string + newPassword?: string + confirmPassword?: string +} + +export type ResetUserPasswordReply = { + id?: string + password?: string +} + +export type ResetUserPasswordReq = { + id?: string +} + +export type ResourceGroupDetail = { + id?: string + name?: string + description?: string + enabled?: boolean + rpm_limit?: number + rpm_action?: number + concurrency_limit?: number + concurrency_action?: number + token_quota?: string + token_action?: number + created_at?: string + updated_at?: string +} + +export type ResourceGroupItem = { + id?: string + name?: string + description?: string + enabled?: boolean + rpm_limit?: number + concurrency_limit?: number + token_quota?: string + token_usage?: string + app_count?: string + rpm_status?: number + conc_status?: number + created_at?: string + updated_at?: string +} + +export type ResourceQuota = { + used?: number + limit?: number + enabled?: boolean +} + +export type SamlConfig = { + idpSsoUrl?: string + certificate?: string +} + +export type SamlLoginReply = { + url?: string +} + +export type SsoIdPProvider = { + protocol?: string + provider?: string + samlConfig?: SamlConfig + oidcConfig?: OidcConfig + oauth2Config?: OAuth2Config +} + +export type SsoSettings = { + ssoEnforced?: boolean + sessionTimeout?: number + ssoIdpProvider?: SsoIdPProvider +} + +export type SsoSettingsReply = { + enabled?: boolean +} + +export type ScimSettings = { + enabled?: boolean + lastSyncTime?: string +} + +export type SearchAppItem = { + app_id?: string + app_name?: string + workspace_id?: string + workspace_name?: string + app_status?: number + icon?: string + icon_type?: string + icon_background?: string + created_by_name?: string +} + +export type SearchAppsResponse = { + items?: Array + total?: string +} + +export type SearchForWhilteListCandidatesRes = { + subjects?: Array + currPage?: number + hasMore?: boolean +} + +export type SecretKey = { + id?: string + name?: string + secretKeyMasked?: string + createdAt?: string + lastActive?: string +} + +export type SetDefaultWorkspaceReply = { + workspaceId?: string +} + +export type SetDefaultWorkspaceReq = { + id?: string +} + +export type Subject = { + subjectId?: string + subjectType?: string + accountData?: SubjectAccountData + groupData?: SubjectGroupData +} + +export type SubjectAccountData = { + id?: string + name?: string + email?: string + avatar?: string +} + +export type SubjectGroupData = { + id?: string + name?: string + groupSize?: number +} + +export type SystemUserSettingReply = { + isAllowRegister?: boolean + enableEmailPasswordLogin?: boolean +} + +export type SystemUserSettingReq = { + isAllowRegister?: boolean + enableEmailPasswordLogin?: boolean +} + +export type TestConnectionReply = { + success?: boolean + error?: string +} + +export type ToggleEndpointRequest = { + enabled?: boolean +} + +export type UpdateAccessModeReq = { + appId?: string + accessMode?: string +} + +export type UpdateAccessModeRes = { + message?: string +} + +export type UpdateBrandingInfoReq = { + enabled?: boolean + applicationTitle?: string + loginPageLogo?: string + workspaceLogo?: string + favicon?: string +} + +export type UpdateGroupSubjectsReq = { + groupId?: string + subjects?: Array +} + +export type UpdateGroupSubjectsRes = { + message?: string +} + +export type UpdateGroupsReq = { + groups?: Array +} + +export type UpdateGroupsReqGroup = { + id?: string + name?: string +} + +export type UpdateGroupsRes = { + groups?: Array +} + +export type UpdateJoinedGroupsReq = { + accountId?: string + groupIds?: Array +} + +export type UpdateJoinedGroupsRes = { + message?: string +} + +export type UpdateLicenseReply = { + message?: string +} + +export type UpdateLicenseReq = { + licenseId?: string +} + +export type UpdateMfaStatusReq = { + enabled?: boolean +} + +export type UpdateMfaStatusRes = { + message?: string +} + +export type UpdateMemberReply = { + account?: Account +} + +export type UpdateMemberReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type UpdateMembersInGroupsReq = { + groupId?: string + accountIds?: Array +} + +export type UpdateMembersInGroupsRes = { + message?: string +} + +export type UpdateOfflineLicenseReply = { + message?: string +} + +export type UpdateOfflineLicenseReq = { + offlineCode?: string +} + +export type UpdatePluginInstallationSettingsRequest = { + pluginInstallationScope?: number + restrictToMarketplaceOnly?: boolean +} + +export type UpdateResourceGroupRequest = { + id?: string + name?: string + description?: string + enabled?: boolean + rpm_limit?: number + rpm_action?: number + concurrency_limit?: number + concurrency_action?: number + token_quota?: string + token_action?: number +} + +export type UpdateUserReply = { + account?: AccountDetail +} + +export type UpdateUserReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type UpdateWebAppAuthInfoReq = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type UpdateWebAppAuthInfoRes = { + message?: string +} + +export type UpdateWebAppWhitelistSubjectsReq = { + appId?: string + subjects?: Array + accessMode?: string +} + +export type UpdateWebAppWhitelistSubjectsRes = { + message?: string +} + +export type UpdateWorkspacePermissionReply = { + message?: string + permission?: WorkspacePermission +} + +export type UpdateWorkspacePermissionReq = { + id?: string + permission?: WorkspacePermission +} + +export type UpdateWorkspaceReply = { + workspace?: Workspace +} + +export type UpdateWorkspaceReq = { + id?: string + name?: string + email?: string + status?: string +} + +export type WebAppAuthInfo = { + allowSso?: boolean + allowEmailCodeLogin?: boolean + allowEmailPasswordLogin?: boolean +} + +export type WebOAuth2LoginReply = { + url?: string + state?: string +} + +export type WebOidcLoginReply = { + url?: string +} + +export type WebSamlLoginReply = { + url?: string +} + +export type Workspace = { + id?: string + name?: string + status?: string + createdAt?: string + owner?: Account +} + +export type WorkspaceInfoReply = { + WorkspaceMembers?: ResourceQuota +} + +export type WorkspacePermission = { + workspaceId?: string + allowMemberInvite?: boolean + allowOwnerTransfer?: boolean +} + +export type Pagination = { + totalCount?: number + perPage?: number + currentPage?: number + totalPages?: number +} + +export type ConsoleSsoOAuth2LoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/oauth2/login' +} + +export type ConsoleSsoOAuth2LoginResponses = { + 200: OAuth2LoginReply +} + +export type ConsoleSsoOAuth2LoginResponse + = ConsoleSsoOAuth2LoginResponses[keyof ConsoleSsoOAuth2LoginResponses] + +export type ConsoleSsoOidcLoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/oidc/login' +} + +export type ConsoleSsoOidcLoginResponses = { + 200: OidcReply +} + +export type ConsoleSsoOidcLoginResponse + = ConsoleSsoOidcLoginResponses[keyof ConsoleSsoOidcLoginResponses] + +export type ConsoleSsoSamlLoginData = { + body?: never + path?: never + query?: never + url: '/enterprise/sso/saml/login' +} + +export type ConsoleSsoSamlLoginResponses = { + 200: SamlLoginReply +} + +export type ConsoleSsoSamlLoginResponse + = ConsoleSsoSamlLoginResponses[keyof ConsoleSsoSamlLoginResponses] + +export type WebAppAuthGetWebAppAccessModeData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/app/access-mode' +} + +export type WebAppAuthGetWebAppAccessModeResponses = { + 200: GetWebAppAccessModeRes +} + +export type WebAppAuthGetWebAppAccessModeResponse + = WebAppAuthGetWebAppAccessModeResponses[keyof WebAppAuthGetWebAppAccessModeResponses] + +export type WebAppAuthUpdateWebAppWhitelistSubjectsData = { + body: UpdateWebAppWhitelistSubjectsReq + path?: never + query?: never + url: '/enterprise/webapp/app/access-mode' +} + +export type WebAppAuthUpdateWebAppWhitelistSubjectsResponses = { + 200: UpdateWebAppWhitelistSubjectsRes +} + +export type WebAppAuthUpdateWebAppWhitelistSubjectsResponse + = WebAppAuthUpdateWebAppWhitelistSubjectsResponses[keyof WebAppAuthUpdateWebAppWhitelistSubjectsResponses] + +export type WebAppAuthSearchForWhilteListCandidatesData = { + body?: never + path?: never + query?: { + keyword?: string + pageNumber?: number + resultsPerPage?: number + groupId?: string + } + url: '/enterprise/webapp/app/subject/search' +} + +export type WebAppAuthSearchForWhilteListCandidatesResponses = { + 200: SearchForWhilteListCandidatesRes +} + +export type WebAppAuthSearchForWhilteListCandidatesResponse + = WebAppAuthSearchForWhilteListCandidatesResponses[keyof WebAppAuthSearchForWhilteListCandidatesResponses] + +export type WebAppAuthGetWebAppWhitelistSubjectsData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/app/subjects' +} + +export type WebAppAuthGetWebAppWhitelistSubjectsResponses = { + 200: GetWebAppWhitelistSubjectsRes +} + +export type WebAppAuthGetWebAppWhitelistSubjectsResponse + = WebAppAuthGetWebAppWhitelistSubjectsResponses[keyof WebAppAuthGetWebAppWhitelistSubjectsResponses] + +export type WebAppAuthGetGroupSubjectsData = { + body?: never + path?: never + query?: { + groupId?: string + } + url: '/enterprise/webapp/group/subjects' +} + +export type WebAppAuthGetGroupSubjectsResponses = { + 200: GetGroupSubjectsRes +} + +export type WebAppAuthGetGroupSubjectsResponse + = WebAppAuthGetGroupSubjectsResponses[keyof WebAppAuthGetGroupSubjectsResponses] + +export type WebAppAuthIsUserAllowedToAccessWebAppData = { + body?: never + path?: never + query?: { + appId?: string + } + url: '/enterprise/webapp/permission' +} + +export type WebAppAuthIsUserAllowedToAccessWebAppResponses = { + 200: IsUserAllowedToAccessWebAppRes +} + +export type WebAppAuthIsUserAllowedToAccessWebAppResponse + = WebAppAuthIsUserAllowedToAccessWebAppResponses[keyof WebAppAuthIsUserAllowedToAccessWebAppResponses] diff --git a/web/contract/generated/enterprise/zod.gen.ts b/web/contract/generated/enterprise/zod.gen.ts new file mode 100644 index 0000000000..cef500a906 --- /dev/null +++ b/web/contract/generated/enterprise/zod.gen.ts @@ -0,0 +1,1183 @@ +// This file is auto-generated by @hey-api/openapi-ts + +import * as z from 'zod' + +/** + * Account represents a basic user account + */ +export const zAccount = z.object({ + id: z.string().optional(), + email: z.string().optional(), + name: z.string().optional(), +}) + +export const zAccountDetailGroup = z.object({ + id: z.string().optional(), + name: z.string().optional(), +}) + +/** + * AccountInWorkspace represents account's role in a workspace + */ +export const zAccountInWorkspace = z.object({ + workspaceId: z.string().optional(), + workspaceName: z.string().optional(), + role: z.string().optional(), +}) + +/** + * AccountDetail contains detailed account information + */ +export const zAccountDetail = z.object({ + account: zAccount.optional(), + status: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActiveAt: z.iso.datetime().optional(), + workspaces: z.array(zAccountInWorkspace).optional(), + groups: z.array(zAccountDetailGroup).optional(), +}) + +export const zAddGroupAppsRequest = z.object({ + id: z.string().optional(), + app_ids: z.array(z.string()).optional(), +}) + +export const zBrandingInfo = z.object({ + enabled: z.boolean().optional(), + applicationTitle: z.string().optional(), + loginPageLogo: z.string().optional(), + workspaceLogo: z.string().optional(), + favicon: z.string().optional(), +}) + +export const zCheckPasswordStatusReply = z.object({ + requirePasswordChange: z.boolean().optional(), + changeReason: z.int().optional(), + daysToExpire: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + message: z.string().optional(), +}) + +export const zClearDefaultWorkspaceReply = z.record(z.string(), z.unknown()) + +export const zCreateBearerTokenResponse = z.object({ + token: z.string().optional(), +}) + +export const zCreateMemberReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +/** + * Create member messages + */ +export const zCreateMemberReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zCreateNewGroupsReqGroup = z.object({ + name: z.string().optional(), +}) + +export const zCreateNewGroupsReq = z.object({ + groups: z.array(zCreateNewGroupsReqGroup).optional(), +}) + +export const zCreateResourceGroupRequest = z.object({ + name: z.string().optional(), + description: z.string().optional(), +}) + +export const zCreateSecretKeyReply = z.object({ + id: z.string().optional(), + name: z.string().optional(), + secretKey: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActive: z.iso.datetime().optional(), +}) + +export const zCreateSecretKeyReq = z.object({ + name: z.string().optional(), +}) + +export const zCreateUserReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +export const zCreateUserReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +/** + * Create workspace messages + */ +export const zCreateWorkspaceReq = z.object({ + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zCurrentUserReply = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + interfaceLanguage: z.string().optional(), + timezone: z.string().optional(), +}) + +export const zDashboardSsooidcLoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zDashboardSsoOauth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +/** + * Dashboard SSO Login messages + */ +export const zDashboardSsosamlLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zDeleteGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zDeleteMemberReply = z.object({ + account: zAccount.optional(), +}) + +export const zDeleteSecretKeyReply = z.object({ + message: z.string().optional(), +}) + +export const zDeleteUserReply = z.object({ + account: zAccount.optional(), +}) + +export const zDeleteWorkspaceReply = z.record(z.string(), z.unknown()) + +/** + * System user setting messages + */ +export const zEnterpriseSystemUserSettingReply = z.object({ + ssoEnforcedForSignin: z.boolean().optional(), + ssoEnforcedForSigninProtocol: z.string().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zGetBearerTokenResponse = z.object({ + maskedToken: z.string().optional(), +}) + +export const zGetClusterInfoReply = z.object({ + mode: z.string().optional(), + clusterId: z.string().optional(), + verifyMode: z.string().optional(), +}) + +export const zGetLicenseStatusReply = z.object({ + status: z.string().optional(), +}) + +export const zGetMfaInfoReply = z.object({ + userEnabled: z.boolean().optional(), + userSetup: z.boolean().optional(), + globalEnabled: z.boolean().optional(), +}) + +export const zGetMemberReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zGetUserReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zGetWebAppAccessModeRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zGetWebAppAuthInfoRes = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +export const zGetWebAppWhitelistSubjectsResMember = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + avatar: z.string().optional(), +}) + +export const zGroupAppItem = z.object({ + app_id: z.string().optional(), + app_name: z.string().optional(), + workspace_id: z.string().optional(), + workspace_name: z.string().optional(), + app_status: z.int().optional(), + token_usage: z.string().optional(), + rpm: z.string().optional(), + concurrency: z.string().optional(), +}) + +export const zHealthzReply = z.object({ + message: z.string().optional(), + status: z.string().optional(), +}) + +export const zInnerAdmission = z.object({ + marker: z.string().optional(), + concurrencyGroupIds: z.array(z.string()).optional(), +}) + +export const zInnerBatchGetWebAppAccessModesByIdReq = z.object({ + appIds: z.array(z.string()).optional(), +}) + +export const zInnerBatchGetWebAppAccessModesByIdRes = z.object({ + accessModes: z.record(z.string(), z.string()).optional(), +}) + +export const zInnerBatchIsUserAllowedToAccessWebAppReq = z.object({ + userId: z.string().optional(), + appIds: z.array(z.string()).optional(), +}) + +export const zInnerBatchIsUserAllowedToAccessWebAppRes = z.object({ + permissions: z.record(z.string(), z.boolean()).optional(), +}) + +export const zInnerCleanAppRes = z.object({ + message: z.string().optional(), +}) + +export const zInnerGetWebAppAccessModeByCodeRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zInnerGetWebAppAccessModeByIdRes = z.object({ + accessMode: z.string().optional(), +}) + +export const zInnerIsUserAllowedToAccessWebAppRes = z.object({ + result: z.boolean().optional(), +}) + +export const zInnerReleaseAdmissionRequest = z.object({ + admission: zInnerAdmission.optional(), +}) + +export const zInnerReleaseAdmissionResponse = z.record(z.string(), z.unknown()) + +export const zInnerTryAddAccountToDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), + joined: z.boolean().optional(), + message: z.string().optional(), +}) + +/** + * Inner API messages + */ +export const zInnerTryAddAccountToDefaultWorkspaceReq = z.object({ + accountId: z.string().optional(), +}) + +export const zIsUserAllowedToAccessWebAppRes = z.object({ + result: z.boolean().optional(), +}) + +export const zJoinWorkspaceReply = z.object({ + message: z.string().optional(), +}) + +/** + * Join workspace messages + */ +export const zJoinWorkspaceReq = z.object({ + id: z.string().optional(), + email: z.string().optional(), + role: z.string().optional(), +}) + +export const zLimitConfig = z.object({ + type: z.int().optional(), + threshold: z.string().optional(), + action: z.int().optional(), + reached: z.boolean().optional(), +}) + +export const zInnerGroupConfig = z.object({ + id: z.string().optional(), + enabled: z.boolean().optional(), + membershipId: z.string().optional(), + limits: z.array(zLimitConfig).optional(), +}) + +export const zInnerResolveResponse = z.object({ + appId: z.string().optional(), + groups: z.array(zInnerGroupConfig).optional(), + blocked: z.boolean().optional(), + blockGroupId: z.string().optional(), + blockReason: z.string().optional(), + admission: zInnerAdmission.optional(), +}) + +export const zListGroupAppsResponse = z.object({ + items: z.array(zGroupAppItem).optional(), + total: z.string().optional(), +}) + +export const zLoginTypesReply = z.object({ + enabledEmailCodeLogin: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), + isAllowRegister: z.boolean().optional(), + isAllowCreateWorkspace: z.boolean().optional(), +}) + +export const zLoginTypesReq = z.object({ + enabledEmailCodeLogin: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), + isAllowRegister: z.boolean().optional(), + isAllowCreateWorkspace: z.boolean().optional(), +}) + +export const zMfaBackupCodesRes = z.object({ + codes: z.array(z.string()).optional(), + validCounts: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + createdAt: z.iso.datetime().optional(), +}) + +export const zMfaDeleteBackupCodesRes = z.object({ + message: z.string().optional(), +}) + +export const zMfaDeleteRes = z.object({ + token: z.string().optional(), +}) + +export const zMfaDownloadBackupCodesSummaryRes = z.object({ + content: z.string().optional(), +}) + +export const zMfaEnrollReq = z.object({ + code: z.string().optional(), +}) + +export const zMfaEnrollRes = z.object({ + token: z.string().optional(), +}) + +export const zMfaGetEnrollInfoRes = z.object({ + qrCode: z.string().optional(), + secret: z.string().optional(), +}) + +export const zMfaModifyRes = z.object({ + message: z.string().optional(), +}) + +export const zOAuth2Config = z.object({ + clientId: z.string().optional(), + clientSecret: z.string().optional(), + authUrl: z.string().optional(), + tokenUrl: z.string().optional(), + userinfoUrl: z.string().optional(), + scopes: z.string().optional(), + enablePkce: z.boolean().optional(), +}) + +export const zOAuth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zOidcConfig = z.object({ + issuerUrl: z.string().optional(), + clientId: z.string().optional(), + clientSecret: z.string().optional(), + enablePkce: z.boolean().optional(), +}) + +export const zOidcReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zOtelExporterEndpoint = z.object({ + endpoint: z.string().optional(), + compression: z.string().optional(), + protocol: z.int().optional(), + timeout: z + .string() + .regex(/^-?(?:0|[1-9]\d{0,11})(?:\.\d{1,9})?s$/) + .optional(), + headers: z.record(z.string(), z.string()).optional(), + tlsCaPem: z.string().optional(), + tlsInsecure: z.boolean().optional(), + tlsClientCertPem: z.string().optional(), + tlsClientKeyPem: z.string().optional(), + enabled: z.boolean().optional(), + tlsInsecureSkipVerify: z.boolean().optional(), +}) + +export const zEndpointReply = z.object({ + mode: z.int().optional(), + metricsEndpoint: zOtelExporterEndpoint.optional(), + tracesEndpoint: zOtelExporterEndpoint.optional(), +}) + +export const zOtelExporterStatusReply = z.object({ + connectedAt: z.iso.datetime().optional(), + bytesPushed: z.string().optional(), + itemsInQueue: z.string().optional(), + logs: z.string().optional(), + status: z.int().optional(), +}) + +export const zPasswordPolicyConfig = z.object({ + minLength: z + .int() + .min(0, { error: 'Invalid value: Expected uint32 to be >= 0' }) + .max(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + .optional(), + requireDigit: z.boolean().optional(), + requireLowercase: z.boolean().optional(), + requireUppercase: z.boolean().optional(), + requireSpecial: z.boolean().optional(), + forbidRepeated: z.boolean().optional(), + forbidSequential: z.boolean().optional(), + expiryEnabled: z.boolean().optional(), + expiryDays: z + .int() + .min(0, { error: 'Invalid value: Expected uint32 to be >= 0' }) + .max(4294967295, { error: 'Invalid value: Expected uint32 to be <= 4294967295' }) + .optional(), +}) + +export const zPasswordStrengthReply = z.object({ + level: z.int().optional(), +}) + +export const zPasswordStrengthReq = z.object({ + password: z.string().optional(), +}) + +export const zPluginInstallationPermissionInfo = z.object({ + pluginInstallationScope: z.string().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zPluginInstallationSettingsReply = z.object({ + pluginInstallationScope: z.int().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zResetMemberPasswordReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +/** + * Reset member password messages + */ +export const zResetMemberPasswordReq = z.object({ + id: z.string().optional(), +}) + +export const zResetPasswordReply = z.object({ + message: z.string().optional(), +}) + +/** + * Password reset messages + */ +export const zResetPasswordReq = z.object({ + currentPassword: z.string().optional(), + newPassword: z.string().optional(), + confirmPassword: z.string().optional(), +}) + +export const zResetUserPasswordReply = z.object({ + id: z.string().optional(), + password: z.string().optional(), +}) + +export const zResetUserPasswordReq = z.object({ + id: z.string().optional(), +}) + +export const zResourceGroupDetail = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + enabled: z.boolean().optional(), + rpm_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + rpm_action: z.int().optional(), + concurrency_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + concurrency_action: z.int().optional(), + token_quota: z.string().optional(), + token_action: z.int().optional(), + created_at: z.string().optional(), + updated_at: z.string().optional(), +}) + +export const zResourceGroupItem = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + enabled: z.boolean().optional(), + rpm_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + concurrency_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + token_quota: z.string().optional(), + token_usage: z.string().optional(), + app_count: z.string().optional(), + rpm_status: z.int().optional(), + conc_status: z.int().optional(), + created_at: z.string().optional(), + updated_at: z.string().optional(), +}) + +export const zListResourceGroupsResponse = z.object({ + items: z.array(zResourceGroupItem).optional(), + total: z.string().optional(), +}) + +/** + * ResourceQuota represents usage quota for a resource + */ +export const zResourceQuota = z.object({ + used: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + enabled: z.boolean().optional(), +}) + +export const zLicenseStatus = z.object({ + status: z.string().optional(), + expiredAt: z.string().optional(), + workspaces: zResourceQuota.optional(), +}) + +export const zLimitFields = z.object({ + workspaceMembers: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + workspaces: zResourceQuota.optional(), +}) + +/** + * License information + */ +export const zLicenseInfo = z.object({ + uuid: z.string().optional(), + expiredAt: z.iso.datetime().optional(), + clusterId: z.string().optional(), + product: z.string().optional(), + limits: zLimitFields.optional(), +}) + +/** + * License RPC messages + */ +export const zGetLicenseReply = z.object({ + license: zLicenseInfo.optional(), +}) + +/** + * SSO Configuration messages + */ +export const zSamlConfig = z.object({ + idpSsoUrl: z.string().optional(), + certificate: z.string().optional(), +}) + +export const zSamlLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zSsoIdPProvider = z.object({ + protocol: z.string().optional(), + provider: z.string().optional(), + samlConfig: zSamlConfig.optional(), + oidcConfig: zOidcConfig.optional(), + oauth2Config: zOAuth2Config.optional(), +}) + +export const zSsoSettings = z.object({ + ssoEnforced: z.boolean().optional(), + sessionTimeout: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + ssoIdpProvider: zSsoIdPProvider.optional(), +}) + +export const zAuthSettingsReply = z.object({ + userSsoSettings: zSsoSettings.optional(), + webSsoSettings: zSsoSettings.optional(), + dashboardSsoSettings: zSsoSettings.optional(), + userSsoSamlAcsUrl: z.string().optional(), + userSsoOidcCallbackUrl: z.string().optional(), + userSsoOauth2CallbackUrl: z.string().optional(), + webSsoSamlAcsUrl: z.string().optional(), + webSsoOidcCallbackUrl: z.string().optional(), + webSsoOauth2CallbackUrl: z.string().optional(), + webSsoMembersSamlAcsUrl: z.string().optional(), + webSsoMembersOidcCallbackUrl: z.string().optional(), + webSsoMembersOauth2CallbackUrl: z.string().optional(), + dashboardSsoSamlAcsUrl: z.string().optional(), + dashboardSsoOidcCallbackUrl: z.string().optional(), + dashboardSsoOauth2CallbackUrl: z.string().optional(), +}) + +export const zAuthSettingsReq = z.object({ + ssoType: z.string().optional(), + ssoSettings: zSsoSettings.optional(), +}) + +export const zSsoSettingsReply = z.object({ + enabled: z.boolean().optional(), +}) + +export const zScimSettings = z.object({ + enabled: z.boolean().optional(), + lastSyncTime: z.iso.datetime().optional(), +}) + +export const zSearchAppItem = z.object({ + app_id: z.string().optional(), + app_name: z.string().optional(), + workspace_id: z.string().optional(), + workspace_name: z.string().optional(), + app_status: z.int().optional(), + icon: z.string().optional(), + icon_type: z.string().optional(), + icon_background: z.string().optional(), + created_by_name: z.string().optional(), +}) + +export const zSearchAppsResponse = z.object({ + items: z.array(zSearchAppItem).optional(), + total: z.string().optional(), +}) + +export const zSecretKey = z.object({ + id: z.string().optional(), + name: z.string().optional(), + secretKeyMasked: z.string().optional(), + createdAt: z.iso.datetime().optional(), + lastActive: z.iso.datetime().optional(), +}) + +export const zSetDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), +}) + +export const zSetDefaultWorkspaceReq = z.object({ + id: z.string().optional(), +}) + +export const zSubjectAccountData = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + avatar: z.string().optional(), +}) + +export const zSubjectGroupData = z.object({ + id: z.string().optional(), + name: z.string().optional(), + groupSize: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zCreateNewGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetJoinedGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zGetWebAppWhitelistSubjectsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), + members: z.array(zGetWebAppWhitelistSubjectsResMember).optional(), +}) + +/** + * Subject represents a subject (user or group) in access control + */ +export const zSubject = z.object({ + subjectId: z.string().optional(), + subjectType: z.string().optional(), + accountData: zSubjectAccountData.optional(), + groupData: zSubjectGroupData.optional(), +}) + +export const zGetGroupSubjectsRes = z.object({ + subjects: z.array(zSubject).optional(), +}) + +export const zSearchForWhilteListCandidatesRes = z.object({ + subjects: z.array(zSubject).optional(), + currPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + hasMore: z.boolean().optional(), +}) + +export const zSystemUserSettingReply = z.object({ + isAllowRegister: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zSystemUserSettingReq = z.object({ + isAllowRegister: z.boolean().optional(), + enableEmailPasswordLogin: z.boolean().optional(), +}) + +export const zTestConnectionReply = z.object({ + success: z.boolean().optional(), + error: z.string().optional(), +}) + +export const zToggleEndpointRequest = z.object({ + enabled: z.boolean().optional(), +}) + +export const zUpdateAccessModeReq = z.object({ + appId: z.string().optional(), + accessMode: z.string().optional(), +}) + +export const zUpdateAccessModeRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateBrandingInfoReq = z.object({ + enabled: z.boolean().optional(), + applicationTitle: z.string().optional(), + loginPageLogo: z.string().optional(), + workspaceLogo: z.string().optional(), + favicon: z.string().optional(), +}) + +export const zUpdateGroupSubjectsReq = z.object({ + groupId: z.string().optional(), + subjects: z.array(zSubject).optional(), +}) + +export const zUpdateGroupSubjectsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateGroupsReqGroup = z.object({ + id: z.string().optional(), + name: z.string().optional(), +}) + +export const zUpdateGroupsReq = z.object({ + groups: z.array(zUpdateGroupsReqGroup).optional(), +}) + +export const zUpdateGroupsRes = z.object({ + groups: z.array(zSubjectGroupData).optional(), +}) + +export const zUpdateJoinedGroupsReq = z.object({ + accountId: z.string().optional(), + groupIds: z.array(z.string()).optional(), +}) + +export const zUpdateJoinedGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateLicenseReply = z.object({ + message: z.string().optional(), +}) + +export const zUpdateLicenseReq = z.object({ + licenseId: z.string().optional(), +}) + +export const zUpdateMfaStatusReq = z.object({ + enabled: z.boolean().optional(), +}) + +export const zUpdateMfaStatusRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateMemberReply = z.object({ + account: zAccount.optional(), +}) + +/** + * Update member messages + */ +export const zUpdateMemberReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zUpdateMembersInGroupsReq = z.object({ + groupId: z.string().optional(), + accountIds: z.array(z.string()).optional(), +}) + +export const zUpdateMembersInGroupsRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateOfflineLicenseReply = z.object({ + message: z.string().optional(), +}) + +export const zUpdateOfflineLicenseReq = z.object({ + offlineCode: z.string().optional(), +}) + +export const zUpdatePluginInstallationSettingsRequest = z.object({ + pluginInstallationScope: z.int().optional(), + restrictToMarketplaceOnly: z.boolean().optional(), +}) + +export const zUpdateResourceGroupRequest = z.object({ + id: z.string().optional(), + name: z.string().optional(), + description: z.string().optional(), + enabled: z.boolean().optional(), + rpm_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + rpm_action: z.int().optional(), + concurrency_limit: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + concurrency_action: z.int().optional(), + token_quota: z.string().optional(), + token_action: z.int().optional(), +}) + +export const zUpdateUserReply = z.object({ + account: zAccountDetail.optional(), +}) + +export const zUpdateUserReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +/** + * Web app auth info messages + */ +export const zUpdateWebAppAuthInfoReq = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +export const zUpdateWebAppAuthInfoRes = z.object({ + message: z.string().optional(), +}) + +export const zUpdateWebAppWhitelistSubjectsReq = z.object({ + appId: z.string().optional(), + subjects: z.array(zSubject).optional(), + accessMode: z.string().optional(), +}) + +export const zUpdateWebAppWhitelistSubjectsRes = z.object({ + message: z.string().optional(), +}) + +/** + * Update workspace messages + */ +export const zUpdateWorkspaceReq = z.object({ + id: z.string().optional(), + name: z.string().optional(), + email: z.string().optional(), + status: z.string().optional(), +}) + +export const zWebAppAuthInfo = z.object({ + allowSso: z.boolean().optional(), + allowEmailCodeLogin: z.boolean().optional(), + allowEmailPasswordLogin: z.boolean().optional(), +}) + +/** + * Info configuration messages + */ +export const zInfoConfigReply = z.object({ + SSOEnforcedForSignin: z.boolean().optional(), + SSOEnforcedForSigninProtocol: z.string().optional(), + SSOEnforcedForWeb: z.boolean().optional(), + SSOEnforcedForWebProtocol: z.string().optional(), + EnableEmailCodeLogin: z.boolean().optional(), + EnableEmailPasswordLogin: z.boolean().optional(), + IsAllowRegister: z.boolean().optional(), + IsAllowCreateWorkspace: z.boolean().optional(), + License: zLicenseStatus.optional(), + Branding: zBrandingInfo.optional(), + WebAppAuth: zWebAppAuthInfo.optional(), + PluginInstallationPermission: zPluginInstallationPermissionInfo.optional(), +}) + +export const zWebOAuth2LoginReply = z.object({ + url: z.string().optional(), + state: z.string().optional(), +}) + +export const zWebOidcLoginReply = z.object({ + url: z.string().optional(), +}) + +export const zWebSamlLoginReply = z.object({ + url: z.string().optional(), +}) + +/** + * Workspace represents a workspace entity + */ +export const zWorkspace = z.object({ + id: z.string().optional(), + name: z.string().optional(), + status: z.string().optional(), + createdAt: z.iso.datetime().optional(), + owner: zAccount.optional(), +}) + +export const zCreateWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zGetDefaultWorkspaceReply = z.object({ + workspaceId: z.string().optional(), + workspace: zWorkspace.optional(), +}) + +export const zGetWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zUpdateWorkspaceReply = z.object({ + workspace: zWorkspace.optional(), +}) + +export const zWorkspaceInfoReply = z.object({ + WorkspaceMembers: zResourceQuota.optional(), +}) + +/** + * Workspace permission + */ +export const zWorkspacePermission = z.object({ + workspaceId: z.string().optional(), + allowMemberInvite: z.boolean().optional(), + allowOwnerTransfer: z.boolean().optional(), +}) + +export const zGetWorkspacePermissionReply = z.object({ + permission: zWorkspacePermission.optional(), +}) + +export const zUpdateWorkspacePermissionReply = z.object({ + message: z.string().optional(), + permission: zWorkspacePermission.optional(), +}) + +/** + * Update workspace permission messages + */ +export const zUpdateWorkspacePermissionReq = z.object({ + id: z.string().optional(), + permission: zWorkspacePermission.optional(), +}) + +/** + * Pagination : Just for pagination by page + */ +export const zPagination = z.object({ + totalCount: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + perPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + currentPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + totalPages: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), +}) + +export const zListMembersReply = z.object({ + data: z.array(zAccountDetail).optional(), + pagination: zPagination.optional(), +}) + +export const zListSecretKeysReply = z.object({ + data: z.array(zSecretKey).optional(), + pagination: zPagination.optional(), +}) + +export const zListUsersReply = z.object({ + data: z.array(zAccountDetail).optional(), + pagination: zPagination.optional(), +}) + +export const zListWorkspacesReply = z.object({ + data: z.array(zWorkspace).optional(), + pagination: zPagination.optional(), +}) + +/** + * OK + */ +export const zConsoleSsoOAuth2LoginResponse = zOAuth2LoginReply + +/** + * OK + */ +export const zConsoleSsoOidcLoginResponse = zOidcReply + +/** + * OK + */ +export const zConsoleSsoSamlLoginResponse = zSamlLoginReply + +export const zWebAppAuthGetWebAppAccessModeQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetWebAppAccessModeResponse = zGetWebAppAccessModeRes + +export const zWebAppAuthUpdateWebAppWhitelistSubjectsBody = zUpdateWebAppWhitelistSubjectsReq + +/** + * OK + */ +export const zWebAppAuthUpdateWebAppWhitelistSubjectsResponse = zUpdateWebAppWhitelistSubjectsRes + +export const zWebAppAuthSearchForWhilteListCandidatesQuery = z.object({ + keyword: z.string().optional(), + pageNumber: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + resultsPerPage: z + .int() + .min(-2147483648, { error: 'Invalid value: Expected int32 to be >= -2147483648' }) + .max(2147483647, { error: 'Invalid value: Expected int32 to be <= 2147483647' }) + .optional(), + groupId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthSearchForWhilteListCandidatesResponse = zSearchForWhilteListCandidatesRes + +export const zWebAppAuthGetWebAppWhitelistSubjectsQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetWebAppWhitelistSubjectsResponse = zGetWebAppWhitelistSubjectsRes + +export const zWebAppAuthGetGroupSubjectsQuery = z.object({ + groupId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthGetGroupSubjectsResponse = zGetGroupSubjectsRes + +export const zWebAppAuthIsUserAllowedToAccessWebAppQuery = z.object({ + appId: z.string().optional(), +}) + +/** + * OK + */ +export const zWebAppAuthIsUserAllowedToAccessWebAppResponse = zIsUserAllowedToAccessWebAppRes diff --git a/web/contract/router.ts b/web/contract/router.ts index 086b94f248..4519160d05 100644 --- a/web/contract/router.ts +++ b/web/contract/router.ts @@ -42,6 +42,7 @@ import { workflowDraftUpdateFeaturesContract, } from './console/workflow' import { workflowCommentContracts } from './console/workflow-comment' +import { contract as enterpriseContract } from './generated/enterprise/orpc.gen' import { collectionPluginsContract, collectionsContract, searchAdvancedContract, templateDetailContract } from './marketplace' export const marketplaceRouterContract = { @@ -54,6 +55,7 @@ export const marketplaceRouterContract = { export type MarketPlaceInputs = InferContractRouterInputs export const consoleRouterContract = { + enterprise: enterpriseContract, account: { avatar: accountAvatarContract, }, diff --git a/web/knip.config.ts b/web/knip.config.ts index d6b71b4af9..1670155aad 100644 --- a/web/knip.config.ts +++ b/web/knip.config.ts @@ -8,9 +8,11 @@ const config: KnipConfig = { 'scripts/**/*.{js,ts,mjs}', 'bin/**/*.{js,ts,mjs}', 'tsslint.config.ts', + 'openapi-ts.*.config.ts', ], ignore: [ 'public/**', + 'contract/generated/**', ], ignoreBinaries: [ 'only-allow', diff --git a/web/openapi-ts.enterprise.config.ts b/web/openapi-ts.enterprise.config.ts new file mode 100644 index 0000000000..3a9086ee3f --- /dev/null +++ b/web/openapi-ts.enterprise.config.ts @@ -0,0 +1,119 @@ +import fs from 'node:fs' +import path from 'node:path' +import { fileURLToPath } from 'node:url' +import { defineConfig } from '@hey-api/openapi-ts' +import yaml from 'js-yaml' + +type JsonObject = Record + +type OpenApiDocument = JsonObject & { + paths?: Record +} + +type ContractOperation = { + id: string + operationId?: string + tags?: readonly string[] +} + +const currentDir = path.dirname(fileURLToPath(import.meta.url)) +const enterpriseServerDir = process.env.DIFY_ENTERPRISE_SERVER + ? path.resolve(process.env.DIFY_ENTERPRISE_SERVER) + : path.resolve(currentDir, '../../dify-enterprise/server') +const enterpriseOpenApiPath = path.join(enterpriseServerDir, 'pkg/apis/enterprise/openapi.yaml') + +const isConsoleApiPath = (routePath: string) => routePath.startsWith('/console/api/') + +const stripConsoleApiPrefix = (routePath: string) => { + if (isConsoleApiPath(routePath)) + return routePath.replace('/console/api', '') + + return routePath +} + +const stripSchemaNamePrefix = (schemaName: string) => { + return schemaName + .replace(/^dify\.enterprise\.api\.enterprise\./, '') + .replace(/^pagination\./, '') +} + +const contractNameSegments = (operation: ContractOperation) => { + const operationId = operation.operationId || operation.id + const tag = operation.tags?.[0] + const tagPrefixPattern = tag ? new RegExp(`^${tag}[._/-]`) : undefined + const name = tagPrefixPattern ? operationId.replace(tagPrefixPattern, '') : operationId + const segments = name.split(/[._/-]+/).filter(Boolean) + + return segments.length > 0 ? segments : [operationId] +} + +const contractPathSegments = (operation: ContractOperation) => { + return [operation.tags?.[0] || 'default', ...contractNameSegments(operation)] +} + +const normalizeEnterpriseOpenApi = () => { + const openApi = yaml.load(fs.readFileSync(enterpriseOpenApiPath, 'utf8')) + + if (!openApi || typeof openApi !== 'object' || Array.isArray(openApi)) + throw new Error(`Invalid enterprise OpenAPI document: ${enterpriseOpenApiPath}`) + + const document = openApi as OpenApiDocument + const paths = document.paths ?? {} + + document.paths = Object.fromEntries( + Object.entries(paths) + .filter(([routePath]) => isConsoleApiPath(routePath)) + .map(([routePath, pathItem]) => [stripConsoleApiPrefix(routePath), pathItem]), + ) + + return document +} + +export default defineConfig({ + input: normalizeEnterpriseOpenApi(), + output: { + entryFile: false, + path: 'contract/generated/enterprise', + fileName: { + suffix: '.gen', + }, + postProcess: [ + { + command: 'vp', + args: ['fmt', '{{path}}'], + }, + { + command: 'eslint', + args: ['--fix', '{{path}}'], + }, + ], + }, + parser: { + transforms: { + schemaName: stripSchemaNamePrefix, + }, + }, + plugins: [ + { + name: '@hey-api/typescript', + comments: false, + }, + 'zod', + { + name: 'orpc', + contracts: { + strategy: 'single', + contractName: { + name: '{{name}}', + casing: 'camelCase', + }, + nesting: contractPathSegments, + segmentName: { + name: '{{name}}', + casing: 'camelCase', + }, + }, + validator: 'zod', + }, + ], +}) diff --git a/web/package.json b/web/package.json index 3b410a3559..abd1d24dcd 100644 --- a/web/package.json +++ b/web/package.json @@ -31,6 +31,7 @@ "dev:proxy": "tsx ./scripts/dev-hono-proxy.ts", "dev:vinext": "vinext dev", "gen-doc-paths": "tsx ./scripts/gen-doc-paths.ts", + "gen-enterprise-contract": "openapi-ts -f openapi-ts.enterprise.config.ts", "gen-icons": "pnpm --filter @dify/iconify-collections generate && node ./scripts/gen-icons.mjs && eslint --fix app/components/base/icons/src/", "i18n:check": "tsx ./scripts/check-i18n.js", "knip": "knip", @@ -158,6 +159,7 @@ "@dify/tsconfig": "workspace:*", "@egoist/tailwindcss-icons": "catalog:", "@eslint-react/eslint-plugin": "catalog:", + "@hey-api/openapi-ts": "catalog:", "@hono/node-server": "catalog:", "@iconify-json/heroicons": "catalog:", "@iconify-json/ri": "catalog:", diff --git a/web/plugins/vite/code-inspector.ts b/web/plugins/vite/code-inspector.ts index fe5e3ee769..180e8d37cb 100644 --- a/web/plugins/vite/code-inspector.ts +++ b/web/plugins/vite/code-inspector.ts @@ -2,7 +2,7 @@ import type { Plugin } from 'vite' import fs from 'node:fs' import path from 'node:path' import { codeInspectorPlugin } from 'code-inspector-plugin' -import { injectClientSnippet, normalizeViteModuleId } from './utils' +import { injectClientSnippet, normalizeViteModuleId } from './utils.ts' type CodeInspectorPluginOptions = { injectTarget: string diff --git a/web/plugins/vite/custom-i18n-hmr.ts b/web/plugins/vite/custom-i18n-hmr.ts index 0e65c5727a..d3e55b4cc4 100644 --- a/web/plugins/vite/custom-i18n-hmr.ts +++ b/web/plugins/vite/custom-i18n-hmr.ts @@ -1,6 +1,6 @@ import type { Plugin } from 'vite' import fs from 'node:fs' -import { injectClientSnippet, normalizeViteModuleId } from './utils' +import { injectClientSnippet, normalizeViteModuleId } from './utils.ts' type CustomI18nHmrPluginOptions = { injectTarget: string diff --git a/web/plugins/vite/next-static-image-test.ts b/web/plugins/vite/next-static-image-test.ts index cd1bd65c3b..d5323e3312 100644 --- a/web/plugins/vite/next-static-image-test.ts +++ b/web/plugins/vite/next-static-image-test.ts @@ -1,6 +1,6 @@ import type { Plugin } from 'vite' import path from 'node:path' -import { normalizeViteModuleId } from './utils' +import { normalizeViteModuleId } from './utils.ts' type NextStaticImageTestPluginOptions = { projectRoot: string diff --git a/web/tsconfig.json b/web/tsconfig.json index cf4110bbb5..3d6909c79d 100644 --- a/web/tsconfig.json +++ b/web/tsconfig.json @@ -15,6 +15,7 @@ "vitest/globals", "node" ], + "allowImportingTsExtensions": true, "allowJs": true }, "include": [ diff --git a/web/vite.config.ts b/web/vite.config.ts index 60c406aa35..3107a8fc60 100644 --- a/web/vite.config.ts +++ b/web/vite.config.ts @@ -4,10 +4,10 @@ import react from '@vitejs/plugin-react' import vinext from 'vinext' import Inspect from 'vite-plugin-inspect' import { defineConfig } from 'vite-plus' -import { createCodeInspectorPlugin, createForceInspectorClientInjectionPlugin } from './plugins/vite/code-inspector' -import { customI18nHmrPlugin } from './plugins/vite/custom-i18n-hmr' -import { getRootClientInjectTarget } from './plugins/vite/inject-target' -import { nextStaticImageTestPlugin } from './plugins/vite/next-static-image-test' +import { createCodeInspectorPlugin, createForceInspectorClientInjectionPlugin } from './plugins/vite/code-inspector.ts' +import { customI18nHmrPlugin } from './plugins/vite/custom-i18n-hmr.ts' +import { getRootClientInjectTarget } from './plugins/vite/inject-target.ts' +import { nextStaticImageTestPlugin } from './plugins/vite/next-static-image-test.ts' const projectRoot = fileURLToPath(new URL('.', import.meta.url)) const isCI = !!process.env.CI