From 4ea2e323661739c1a299572da80e3d92a5556dc5 Mon Sep 17 00:00:00 2001 From: Paul Rastoin <45004772+prastoin@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:10:25 +0100 Subject: [PATCH] Refactor twenty client sdk provisioning for logic function and front-component (#18544) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 1. The `twenty-client-sdk` Package (Source of Truth) The monorepo package at `packages/twenty-client-sdk` ships with: - A **pre-built metadata client** (static, generated from a fixed schema) - A **stub core client** that throws at runtime (`CoreApiClient was not generated...`) - Both ESM (`.mjs`) and CJS (`.cjs`) bundles in `dist/` - A `package.json` with proper `exports` map for `twenty-client-sdk/core`, `twenty-client-sdk/metadata`, and `twenty-client-sdk/generate` ## 2. Generation & Upload (Server-Side, at Migration Time) **When**: `WorkspaceMigrationRunnerService.run()` executes after a metadata schema change. **What happens in `SdkClientGenerationService.generateAndStore()`**: 1. Copies the stub `twenty-client-sdk` package from the server's assets (resolved via `SDK_CLIENT_PACKAGE_DIRNAME` — from `dist/assets/twenty-client-sdk/` in production, or from `node_modules` in dev) 2. Filters out `node_modules/` and `src/` during copy — only `package.json` + `dist/` are kept (like an npm publish) 3. Calls `replaceCoreClient()` which uses `@genql/cli` to introspect the **application-scoped** GraphQL schema and generates a real `CoreApiClient`, then compiles it to ESM+CJS and overwrites `dist/core.mjs` and `dist/core.cjs` 4. Archives the **entire package** (with `package.json` + `dist/`) into `twenty-client-sdk.zip` 5. Uploads the single archive to S3 under `FileFolder.GeneratedSdkClient` 6. Sets `isSdkLayerStale = true` on the `ApplicationEntity` in the database ## 3. Invalidation Signal The `isSdkLayerStale` boolean column on `ApplicationEntity` is the invalidation mechanism: - **Set to `true`** by `generateAndStore()` after uploading a new client archive - **Checked** by both logic function drivers before execution — if `true`, they rebuild their local layer - **Set back to `false`** by `markSdkLayerFresh()` after the driver has successfully consumed the new archive Default is `false` so existing applications without a generated client aren't affected. ## 4a. Logic Functions — Local Driver **`ensureSdkLayer()`** is called before every execution: 1. Checks if the local SDK layer directory exists AND `isSdkLayerStale` is `false` → early return 2. Otherwise, cleans the local layer directory 3. Calls `downloadAndExtractToPackage()` which streams the zip from S3 directly to disk and extracts the full package into `/sdk/-/node_modules/twenty-client-sdk/` 4. Calls `markSdkLayerFresh()` to set `isSdkLayerStale = false` **At execution time**, `assembleNodeModules()` symlinks everything from the deps layer's `node_modules/` **except** `twenty-client-sdk`, which is symlinked from the SDK layer instead. This ensures the logic function's `import ... from 'twenty-client-sdk/core'` resolves to the generated client. ## 4b. Logic Functions — Lambda Driver **`ensureSdkLayer()`** is called during `build()`: 1. Checks if `isSdkLayerStale` is `false` and an existing Lambda layer ARN exists → early return 2. Otherwise, deletes all existing layer versions for this SDK layer name 3. Calls `downloadArchiveBuffer()` to get the raw zip from S3 (no disk extraction) 4. Calls `reprefixZipEntries()` which streams the zip entries into a **new zip** with the path prefix `nodejs/node_modules/twenty-client-sdk/` — this is the Lambda layer convention path. All done in memory, no disk round-trip 5. Publishes the re-prefixed zip as a new Lambda layer via `publishLayer()` 6. Calls `markSdkLayerFresh()` **At function creation**, the Lambda is created with **two layers**: `[depsLayerArn, sdkLayerArn]`. The SDK layer is listed last so it overwrites the stub `twenty-client-sdk` from the deps layer (later layers take precedence in Lambda's `/opt` merge). ## 5. Front Components Front components are built by `app:build` with `twenty-client-sdk/core` and `twenty-client-sdk/metadata` as **esbuild externals**. The stored `.mjs` in S3 has unresolved bare import specifiers like `import { CoreApiClient } from 'twenty-client-sdk/core'`. SDK import resolution is split between the **frontend host** (fetching & caching SDK modules) and the **Web Worker** (rewriting imports): **Server endpoints**: - `GET /rest/front-components/:id` — `FrontComponentService.getBuiltComponentStream()` returns the **raw `.mjs`** directly from file storage. No bundling, no SDK injection. - `GET /rest/sdk-client/:applicationId/:moduleName` — `SdkClientController` reads a single file (e.g. `dist/core.mjs`) from the generated SDK archive via `SdkClientGenerationService.readFileFromArchive()` and serves it as JavaScript. **Frontend host** (`FrontComponentRenderer` in `twenty-front`): 1. Queries `FindOneFrontComponent` which returns `applicationId`, `builtComponentChecksum`, `usesSdkClient`, and `applicationTokenPair` 2. If `usesSdkClient` is `true`, renders `FrontComponentRendererWithSdkClient` which calls the `useApplicationSdkClient` hook 3. `useApplicationSdkClient({ applicationId, accessToken })` checks the Jotai atom family cache for existing blob URLs. On cache miss, fetches both SDK modules from `GET /rest/sdk-client/:applicationId/core` and `/metadata`, creates **blob URLs** for each, and stores them in the atom family 4. Once the blob URLs are cached, passes them as `sdkClientUrls` (already blob URLs, not server URLs) to `SharedFrontComponentRenderer` → `FrontComponentWorkerEffect` → worker's `render()` call via `HostToWorkerRenderContext` **Worker** (`remote-worker.ts` in `twenty-sdk`): 1. Fetches the raw component `.mjs` source as text 2. If `sdkClientUrls` are provided and the source contains SDK import specifiers (`twenty-client-sdk/core`, `twenty-client-sdk/metadata`), **rewrites** the bare specifiers to the blob URLs received from the host (e.g. `'twenty-client-sdk/core'` → `'blob:...'`) 3. Creates a blob URL for the rewritten source and `import()`s it 4. Revokes only the component blob URL after the module is loaded — the SDK blob URLs are owned and managed by the host's Jotai cache This approach eliminates server-side esbuild bundling on every request, caches SDK modules per application in the frontend, and keeps the worker's job to a simple string rewrite. ## Summary Diagram ``` app:build (SDK) └─ twenty-client-sdk stub (metadata=real, core=stub) │ ▼ WorkspaceMigrationRunnerService.run() └─ SdkClientGenerationService.generateAndStore() ├─ Copy stub package (package.json + dist/) ├─ replaceCoreClient() → regenerate core.mjs/core.cjs ├─ Zip entire package → upload to S3 └─ Set isSdkLayerStale = true │ ┌────────┴────────────────────┐ ▼ ▼ Logic Functions Front Components │ │ ├─ Local Driver ├─ GET /rest/sdk-client/:appId/core │ └─ downloadAndExtract │ → core.mjs from archive │ → symlink into │ │ node_modules ├─ Host (useApplicationSdkClient) │ │ ├─ Fetch SDK modules └─ Lambda Driver │ ├─ Create blob URLs └─ downloadArchiveBuffer │ └─ Cache in Jotai atom family → reprefixZipEntries │ → publish as Lambda ├─ GET /rest/front-components/:id layer │ → raw .mjs (no bundling) │ └─ Worker (browser) ├─ Fetch component .mjs ├─ Rewrite imports → blob URLs └─ import() rewritten source ``` ## Next PR - Estimate perf improvement by implementing a redis caching for front component client storage ( we don't even cache front comp initially ) - Implem frontent blob invalidation sse event from server --------- Co-authored-by: Charles Bochet --- .../spawn-twenty-docker-image/action.yaml | 22 +- .github/verdaccio-config.yaml | 3 + .github/workflows/ci-create-app-e2e.yaml | 24 +- .github/workflows/ci-server.yaml | 10 +- package.json | 1 + packages/create-twenty-app/README.md | 3 +- .../src/utils/__tests__/app-template.spec.ts | 35 +- .../src/utils/__tests__/test-template.spec.ts | 8 +- .../src/utils/app-template.ts | 165 +- .../src/utils/test-template.ts | 32 +- .../src/fields/postCardCategoryField.ts | 2 +- .../src/fields/postCardNumber.field.ts | 2 +- .../src/objects/recipient.object.ts | 4 +- .../hello-world/.github/workflows/ci.yml | 42 + packages/twenty-apps/hello-world/LLMS.md | 1 + packages/twenty-apps/hello-world/package.json | 3 +- .../__tests__/app-install.integration-test.ts | 30 +- .../hello-world/src/agents/example-agent.ts | 13 + .../hello-world/src/application-config.ts | 2 +- .../hello-world/src/fields/example-field.ts | 2 +- .../src/front-components/hello-world.tsx | 42 +- .../create-hello-world-company.ts | 35 + .../src/logic-functions/hello-world.ts | 2 +- .../src/logic-functions/post-install.ts | 2 +- .../src/logic-functions/pre-install.ts | 2 +- .../example-navigation-menu-item.ts | 2 +- .../hello-world/src/objects/example-object.ts | 4 +- .../example-record-page-layout.ts | 31 + .../hello-world/src/roles/default-role.ts | 2 +- .../hello-world/src/skills/example-skill.ts | 2 +- .../hello-world/src/views/example-view.ts | 4 +- packages/twenty-apps/hello-world/yarn.lock | 238 +- packages/twenty-client-sdk/.oxlintrc.json | 47 + packages/twenty-client-sdk/.prettierignore | 2 + packages/twenty-client-sdk/package.json | 60 + packages/twenty-client-sdk/project.json | 44 + .../scripts/generate-metadata-client.ts | 65 + .../src/core/generated/index.ts | 10 + .../src/core/generated}/schema.ts | 0 packages/twenty-client-sdk/src/core/index.ts | 2 + .../__tests__/client-wrapper-auth.test.ts} | 75 +- .../src/generate/client-wrapper.ts | 51 + .../src/generate/fs-utils.ts | 41 + .../src/generate/generate-core-client.ts | 122 + .../src/generate/generate-metadata-client.ts | 48 + .../twenty-client-sdk/src/generate/index.ts | 6 + .../src/generate/raw-imports.d.ts | 4 + .../src/generate/twenty-client-template.ts | 434 + .../src/metadata/generated}/index.ts | 2 +- .../metadata/generated}/runtime/batcher.ts | 0 .../generated}/runtime/createClient.ts | 0 .../src/metadata/generated}/runtime/error.ts | 0 .../metadata/generated}/runtime/fetcher.ts | 0 .../runtime/generateGraphqlOperation.ts | 0 .../src/metadata/generated}/runtime/index.ts | 0 .../generated}/runtime/linkTypeMap.ts | 0 .../generated}/runtime/typeSelection.ts | 0 .../src/metadata/generated}/runtime/types.ts | 0 .../src/metadata/generated}/schema.graphql | 3082 +++--- .../src/metadata/generated}/schema.ts | 5795 +++++------ .../src/metadata/generated}/types.ts | 8769 +++++++++-------- .../twenty-client-sdk/src/metadata/index.ts | 2 + packages/twenty-client-sdk/tsconfig.json | 19 + packages/twenty-client-sdk/tsconfig.lib.json | 17 + packages/twenty-client-sdk/vite.config.ts | 78 + packages/twenty-client-sdk/vitest.config.ts | 14 + .../developers/extend/capabilities/apps.mdx | 10 +- .../src/generated-metadata/graphql.ts | 6 +- .../components/FrontComponentRenderer.tsx | 37 +- .../FrontComponentRendererWithSdkClient.tsx | 58 + .../components/SdkClientBlobUrlsEffect.tsx | 49 + .../graphql/queries/findOneFrontComponent.ts | 1 + .../states/sdkClientFamilyState.ts | 20 + .../utils/fetchSdkClientBlobUrls.ts | 55 + .../utils/getSdkClientUrls.ts | 6 + .../modules/users/hooks/useLoadCurrentUser.ts | 2 +- packages/twenty-sdk/.oxlintrc.json | 2 +- packages/twenty-sdk/.prettierignore | 1 - packages/twenty-sdk/package.json | 9 +- packages/twenty-sdk/project.json | 10 - .../scripts/generate-metadata-client.ts | 42 - .../__e2e__/function-execute.e2e-spec.ts | 22 +- .../app-dev/expected-manifest.ts | 2 +- .../app-dev/expected-manifest.ts | 13 +- .../utils/normalize-manifest.util.ts | 3 - .../src/cli/commands/app-command.ts | 15 +- .../twenty-sdk/src/cli/commands/deploy.ts | 44 +- .../twenty-sdk/src/cli/commands/install.ts | 32 + .../src/cli/constants/clients-dir.ts | 2 - .../twenty-sdk/src/cli/operations/build.ts | 45 +- .../twenty-sdk/src/cli/operations/deploy.ts | 43 +- .../twenty-sdk/src/cli/operations/index.ts | 2 + .../twenty-sdk/src/cli/operations/install.ts | 57 + packages/twenty-sdk/src/cli/types.ts | 1 + .../build/common/build-application.ts | 17 +- .../build/common/esbuild-result-processor.ts | 11 + .../utilities/build/common/esbuild-watcher.ts | 24 +- .../front-component-external-modules.ts | 5 +- .../common/restartable-watcher-interface.ts | 1 + .../__tests__/manifest-validate.spec.ts | 1 - .../build/manifest/manifest-build.ts | 1 - .../manifest-extract-config-from-file.ts | 6 +- .../manifest/manifest-update-checksums.ts | 46 +- .../cli/utilities/client/client-service.ts | 144 +- .../dev-mode-orchestrator-state.ts | 1 + .../dev/orchestrator/dev-mode-orchestrator.ts | 4 - .../steps/start-watchers-orchestrator-step.ts | 2 + .../steps/upload-files-orchestrator-step.ts | 52 +- .../src/clients/generated/core/index.ts | 2 - packages/twenty-sdk/src/clients/index.ts | 4 - .../components/FrontComponentRenderer.tsx | 5 + .../src/front-component-renderer/index.ts | 5 +- .../components/FrontComponentWorkerEffect.tsx | 5 + .../remote/worker/remote-worker.ts | 72 +- .../types/HostToWorkerRenderContext.ts | 6 + .../src/sdk/application/application-config.ts | 1 - .../src/sdk/front-component-config.ts | 1 + packages/twenty-sdk/vite.config.node.ts | 1 - packages/twenty-server/package.json | 1 + packages/twenty-server/project.json | 6 +- ...enerate-application-sdk-clients.command.ts | 67 + .../1-20-upgrade-version-command.module.ts | 7 + .../upgrade.command.ts | 3 + ...0-add-is-sdk-layer-stale-to-application.ts | 19 + ...-add-uses-sdk-client-to-front-component.ts | 19 + .../api/graphql/core-graphql-api.module.ts | 4 +- ...nner-graphql-api-exception-handler.util.ts | 4 + .../workspace-query-runner.module.ts | 2 - .../workspace-graphql-schema.exception.ts | 36 + .../gql-type.generator.ts | 91 +- ...etadata-create-gql-input-type.generator.ts | 3 +- ...etadata-update-gql-input-type.generator.ts | 3 +- .../type-generators.ts | 181 +- .../storages/gql-types.storage.ts | 31 +- .../workspace-graphql-schema.factory.ts | 55 +- .../workspace-schema-builder.module.ts | 14 +- .../application-development.module.ts | 2 + .../application-development.resolver.ts | 52 +- .../application-install.module.ts | 2 + .../application-install.service.ts | 32 +- .../application-manifest-migration.service.ts | 10 +- .../application-sync.service.ts | 9 +- ...-to-universal-flat-front-component.util.ts | 1 + .../application/application.entity.ts | 3 + .../engine/core-modules/auth/auth.module.ts | 12 - .../engine/core-modules/core-engine.module.ts | 12 +- .../file/interfaces/file-folder.interface.ts | 3 + .../drivers/lambda.driver.ts | 259 +- .../drivers/local.driver.ts | 168 +- .../logic-function-driver.factory.ts | 4 + .../logic-function/logic-function.module.ts | 2 + .../constants/allowed-sdk-modules.ts | 3 + .../constants/sdk-client-package-dirname.ts | 13 + .../controllers/sdk-client.controller.ts | 69 + .../exceptions/sdk-client.exception.ts | 42 + .../sdk-client/sdk-client-archive.service.ts | 166 + .../sdk-client-generation.service.ts | 131 + .../sdk-client/sdk-client.module.ts | 21 + .../calendar-channel-metadata.module.ts | 2 - .../command-menu-item.service.ts | 12 +- .../connected-account-metadata.module.ts | 2 - ...ompare-and-stringify.constant.spec.ts.snap | 1 + ...configuration-by-metadata-name.constant.ts | 5 + ...-to-flat-field-metadatas-to-create.spec.ts | 1 + ...-relation-flat-field-metadata-pair.spec.ts | 1 + ...-to-flat-front-component-to-create.util.ts | 1 + ...t-component-to-front-component-dto.util.ts | 1 + ...ent-entity-to-flat-front-component.util.ts | 1 + .../dtos/front-component.dto.ts | 4 + .../entities/front-component.entity.ts | 3 + .../front-component.service.ts | 2 +- .../message-channel-metadata.module.ts | 2 - .../message-folder-metadata.module.ts | 2 - .../webhook/webhook.module.ts | 4 +- .../dev-seeder/dev-seeder.module.ts | 2 + .../dev-seeder/services/dev-seeder.service.ts | 22 +- .../workspace-manager.module.ts | 4 +- .../workspace-manager.service.ts | 18 +- ...igration-validate-build-and-run-service.ts | 51 +- .../workspace-migration-runner.service.ts | 47 +- .../workspace-member-query-hook.module.ts | 2 - .../app-distribution.integration-spec.ts | 1 - .../utils/build-base-manifest.util.ts | 1 - .../src/application/applicationType.ts | 1 - .../constants/ApiClientDirectory.ts | 1 - .../application/frontComponentManifestType.ts | 1 + .../twenty-shared/src/application/index.ts | 1 - .../twenty-shared/src/types/FileFolder.ts | 1 + yarn.lock | 19 + 189 files changed, 12487 insertions(+), 9856 deletions(-) create mode 100644 packages/twenty-apps/hello-world/.github/workflows/ci.yml create mode 100644 packages/twenty-apps/hello-world/src/agents/example-agent.ts create mode 100644 packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts create mode 100644 packages/twenty-apps/hello-world/src/page-layouts/example-record-page-layout.ts create mode 100644 packages/twenty-client-sdk/.oxlintrc.json create mode 100644 packages/twenty-client-sdk/.prettierignore create mode 100644 packages/twenty-client-sdk/package.json create mode 100644 packages/twenty-client-sdk/project.json create mode 100644 packages/twenty-client-sdk/scripts/generate-metadata-client.ts create mode 100644 packages/twenty-client-sdk/src/core/generated/index.ts rename packages/{twenty-sdk/src/clients/generated/core => twenty-client-sdk/src/core/generated}/schema.ts (100%) create mode 100644 packages/twenty-client-sdk/src/core/index.ts rename packages/{twenty-sdk/src/cli/utilities/client/__tests__/clientServiceGeneratedClientAuth.test.ts => twenty-client-sdk/src/generate/__tests__/client-wrapper-auth.test.ts} (88%) create mode 100644 packages/twenty-client-sdk/src/generate/client-wrapper.ts create mode 100644 packages/twenty-client-sdk/src/generate/fs-utils.ts create mode 100644 packages/twenty-client-sdk/src/generate/generate-core-client.ts create mode 100644 packages/twenty-client-sdk/src/generate/generate-metadata-client.ts create mode 100644 packages/twenty-client-sdk/src/generate/index.ts create mode 100644 packages/twenty-client-sdk/src/generate/raw-imports.d.ts create mode 100644 packages/twenty-client-sdk/src/generate/twenty-client-template.ts rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/index.ts (99%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/batcher.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/createClient.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/error.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/fetcher.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/generateGraphqlOperation.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/index.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/linkTypeMap.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/typeSelection.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/runtime/types.ts (100%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/schema.graphql (99%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/schema.ts (99%) rename packages/{twenty-sdk/src/clients/generated/metadata => twenty-client-sdk/src/metadata/generated}/types.ts (97%) create mode 100644 packages/twenty-client-sdk/src/metadata/index.ts create mode 100644 packages/twenty-client-sdk/tsconfig.json create mode 100644 packages/twenty-client-sdk/tsconfig.lib.json create mode 100644 packages/twenty-client-sdk/vite.config.ts create mode 100644 packages/twenty-client-sdk/vitest.config.ts create mode 100644 packages/twenty-front/src/modules/front-components/components/FrontComponentRendererWithSdkClient.tsx create mode 100644 packages/twenty-front/src/modules/front-components/components/SdkClientBlobUrlsEffect.tsx create mode 100644 packages/twenty-front/src/modules/front-components/states/sdkClientFamilyState.ts create mode 100644 packages/twenty-front/src/modules/front-components/utils/fetchSdkClientBlobUrls.ts create mode 100644 packages/twenty-front/src/modules/front-components/utils/getSdkClientUrls.ts delete mode 100644 packages/twenty-sdk/scripts/generate-metadata-client.ts create mode 100644 packages/twenty-sdk/src/cli/commands/install.ts delete mode 100644 packages/twenty-sdk/src/cli/constants/clients-dir.ts create mode 100644 packages/twenty-sdk/src/cli/operations/install.ts delete mode 100644 packages/twenty-sdk/src/clients/generated/core/index.ts delete mode 100644 packages/twenty-sdk/src/clients/index.ts create mode 100644 packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1773000000000-add-is-sdk-layer-stale-to-application.ts create mode 100644 packages/twenty-server/src/database/typeorm/core/migrations/common/1773100000000-add-uses-sdk-client-to-front-component.ts create mode 100644 packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/exceptions/workspace-graphql-schema.exception.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/constants/allowed-sdk-modules.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/constants/sdk-client-package-dirname.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/controllers/sdk-client.controller.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/exceptions/sdk-client.exception.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-archive.service.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-generation.service.ts create mode 100644 packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client.module.ts delete mode 100644 packages/twenty-shared/src/application/constants/ApiClientDirectory.ts diff --git a/.github/actions/spawn-twenty-docker-image/action.yaml b/.github/actions/spawn-twenty-docker-image/action.yaml index 53e311d3d58..b0e268ca5ec 100644 --- a/.github/actions/spawn-twenty-docker-image/action.yaml +++ b/.github/actions/spawn-twenty-docker-image/action.yaml @@ -3,12 +3,13 @@ description: > Starts a full Twenty instance (server, worker, database, redis) using Docker Compose. The server is available at http://localhost:3000 for subsequent steps in the caller's job. - Pulls the specified semver image tag from Docker Hub. + Accepts "latest" (pulls the latest Docker Hub image, checks out main) or a + semver tag (e.g., v0.40.0). Designed to be consumed from external repositories (e.g., twenty-app). inputs: twenty-version: - description: 'Twenty Docker Hub image tag as semver (e.g., v0.40.0, v1.0.0).' + description: 'Twenty Docker Hub image tag — either "latest" or a semver tag (e.g., v0.40.0).' required: true twenty-repository: description: 'Twenty repository to checkout docker compose files from.' @@ -30,12 +31,19 @@ outputs: runs: using: 'composite' steps: - - name: Validate version + - name: Resolve version + id: resolve shell: bash run: | VERSION="${{ inputs.twenty-version }}" - if ! echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then - echo "::error::twenty-version must be a semver tag (e.g., v0.40.0). Got: '$VERSION'" + if [ "$VERSION" = "latest" ]; then + echo "docker-tag=latest" >> "$GITHUB_OUTPUT" + echo "git-ref=main" >> "$GITHUB_OUTPUT" + elif echo "$VERSION" | grep -qE '^v[0-9]+\.[0-9]+\.[0-9]+$'; then + echo "docker-tag=$VERSION" >> "$GITHUB_OUTPUT" + echo "git-ref=$VERSION" >> "$GITHUB_OUTPUT" + else + echo "::error::twenty-version must be \"latest\" or a semver tag (e.g., v0.40.0). Got: '$VERSION'" exit 1 fi @@ -43,7 +51,7 @@ runs: uses: actions/checkout@v4 with: repository: ${{ inputs.twenty-repository }} - ref: ${{ inputs.twenty-version }} + ref: ${{ steps.resolve.outputs.git-ref }} token: ${{ inputs.github-token }} sparse-checkout: | packages/twenty-docker @@ -56,7 +64,7 @@ runs: run: | cp .env.example .env echo "" >> .env - echo "TAG=${{ inputs.twenty-version }}" >> .env + echo "TAG=${{ steps.resolve.outputs.docker-tag }}" >> .env echo "APP_SECRET=replace_me_with_a_random_string" >> .env echo "SERVER_URL=http://localhost:3000" >> .env diff --git a/.github/verdaccio-config.yaml b/.github/verdaccio-config.yaml index 99bbc93460c..6c74a4c3f46 100644 --- a/.github/verdaccio-config.yaml +++ b/.github/verdaccio-config.yaml @@ -10,6 +10,9 @@ packages: 'twenty-sdk': access: $all publish: $all + 'twenty-client-sdk': + access: $all + publish: $all 'create-twenty-app': access: $all publish: $all diff --git a/.github/workflows/ci-create-app-e2e.yaml b/.github/workflows/ci-create-app-e2e.yaml index c8bd18fe262..796afccc237 100644 --- a/.github/workflows/ci-create-app-e2e.yaml +++ b/.github/workflows/ci-create-app-e2e.yaml @@ -21,10 +21,12 @@ jobs: files: | packages/create-twenty-app/** packages/twenty-sdk/** + packages/twenty-client-sdk/** packages/twenty-shared/** packages/twenty-server/** !packages/create-twenty-app/package.json !packages/twenty-sdk/package.json + !packages/twenty-client-sdk/package.json !packages/twenty-shared/package.json !packages/twenty-server/package.json create-app-e2e: @@ -64,11 +66,12 @@ jobs: run: | CI_VERSION="0.0.0-ci.$(date +%s)" echo "CI_VERSION=$CI_VERSION" >> $GITHUB_ENV - npx nx run-many -t set-local-version -p twenty-sdk create-twenty-app --releaseVersion=$CI_VERSION + npx nx run-many -t set-local-version -p twenty-sdk twenty-client-sdk create-twenty-app --releaseVersion=$CI_VERSION - name: Build packages run: | npx nx build twenty-sdk + npx nx build twenty-client-sdk npx nx build create-twenty-app - name: Install and start Verdaccio @@ -88,7 +91,7 @@ jobs: run: | npm set //localhost:4873/:_authToken "ci-auth-token" - for pkg in twenty-sdk create-twenty-app; do + for pkg in twenty-sdk twenty-client-sdk create-twenty-app; do cd packages/$pkg npm publish --registry http://localhost:4873 --tag ci cd ../.. @@ -153,11 +156,15 @@ jobs: cd /tmp/e2e-test-workspace/test-app npx --no-install twenty remote add --token $SEED_API_KEY --url http://localhost:3000 - - name: Build scaffolded app + - name: Deploy scaffolded app run: | cd /tmp/e2e-test-workspace/test-app - npx --no-install twenty build - test -d .twenty/output + npx --no-install twenty deploy + + - name: Install scaffolded app + run: | + cd /tmp/e2e-test-workspace/test-app + npx --no-install twenty install - name: Execute hello-world logic function run: | @@ -166,6 +173,13 @@ jobs: echo "$EXEC_OUTPUT" echo "$EXEC_OUTPUT" | grep -q "Hello, World!" + - name: Execute create-hello-world-company logic function + run: | + cd /tmp/e2e-test-workspace/test-app + EXEC_OUTPUT=$(npx --no-install twenty exec --functionName create-hello-world-company) + echo "$EXEC_OUTPUT" + echo "$EXEC_OUTPUT" | grep -q "Created company" + - name: Run scaffolded app integration test env: TWENTY_API_URL: http://localhost:3000 diff --git a/.github/workflows/ci-server.yaml b/.github/workflows/ci-server.yaml index 06011978edf..77f69aefec6 100644 --- a/.github/workflows/ci-server.yaml +++ b/.github/workflows/ci-server.yaml @@ -25,7 +25,7 @@ jobs: packages/twenty-server/** packages/twenty-front/src/generated/** packages/twenty-front/src/generated-metadata/** - packages/twenty-sdk/src/clients/generated/metadata/** + packages/twenty-client-sdk/** packages/twenty-emails/** packages/twenty-shared/** @@ -177,14 +177,14 @@ jobs: HAS_ERRORS=true fi - npx nx run twenty-sdk:generate-metadata-client + npx nx run twenty-client-sdk:generate-metadata-client - if ! git diff --quiet -- packages/twenty-sdk/src/clients/generated/metadata; then - echo "::error::SDK metadata client changes detected. Please run 'npx nx run twenty-sdk:generate-metadata-client' and commit the changes." + if ! git diff --quiet -- packages/twenty-client-sdk/src/metadata/generated; then + echo "::error::SDK metadata client changes detected. Please run 'npx nx run twenty-client-sdk:generate-metadata-client' and commit the changes." echo "" echo "The following SDK metadata client changes were detected:" echo "===================================================" - git diff -- packages/twenty-sdk/src/clients/generated/metadata + git diff -- packages/twenty-client-sdk/src/metadata/generated echo "===================================================" echo "" HAS_ERRORS=true diff --git a/package.json b/package.json index 3dad76cb167..ab15ca6e1f6 100644 --- a/package.json +++ b/package.json @@ -207,6 +207,7 @@ "packages/twenty-e2e-testing", "packages/twenty-shared", "packages/twenty-sdk", + "packages/twenty-client-sdk", "packages/twenty-apps", "packages/twenty-cli", "packages/create-twenty-app", diff --git a/packages/create-twenty-app/README.md b/packages/create-twenty-app/README.md index 488618aefff..c16152d03f5 100644 --- a/packages/create-twenty-app/README.md +++ b/packages/create-twenty-app/README.md @@ -44,6 +44,7 @@ yarn twenty server start # Start local Twenty server yarn twenty remote add --local # Authenticate via OAuth # Start dev mode: watches, builds, and syncs local changes to your workspace +# (also auto-generates typed CoreApiClient — MetadataApiClient ships pre-built — both available via `twenty-client-sdk`) yarn twenty dev # Watch your application's function logs @@ -135,7 +136,7 @@ npx create-twenty-app@latest my-app --port 3000 - Use `yarn twenty remote add --local` to authenticate with your Twenty workspace via OAuth. - Explore the generated project and add your first entity with `yarn twenty add` (logic functions, front components, objects, roles, views, navigation menu items, skills). - Use `yarn twenty dev` while you iterate — it watches, builds, and syncs changes to your workspace in real time. -- `CoreApiClient` (for workspace data via `/graphql`) is auto-generated by `yarn twenty dev`. `MetadataApiClient` (for workspace configuration and file uploads via `/metadata`) ships pre-built with the SDK. Both are available via `import { CoreApiClient, MetadataApiClient } from 'twenty-sdk/clients'`. +- `CoreApiClient` is auto-generated by `yarn twenty dev`. `MetadataApiClient` (for workspace configuration and file uploads via `/metadata`) ships pre-built with the SDK. Both are available via `import { CoreApiClient } from 'twenty-client-sdk/core'` and `import { MetadataApiClient } from 'twenty-client-sdk/metadata'`. ## Build and publish your application diff --git a/packages/create-twenty-app/src/utils/__tests__/app-template.spec.ts b/packages/create-twenty-app/src/utils/__tests__/app-template.spec.ts index c70b2aca9e5..a8feb44ae83 100644 --- a/packages/create-twenty-app/src/utils/__tests__/app-template.spec.ts +++ b/packages/create-twenty-app/src/utils/__tests__/app-template.spec.ts @@ -106,6 +106,9 @@ describe('copyBaseApplicationProject', () => { expect(packageJson.devDependencies['twenty-sdk']).toBe( createTwentyAppPackageJson.version, ); + expect(packageJson.devDependencies['twenty-client-sdk']).toBe( + createTwentyAppPackageJson.version, + ); expect(packageJson.scripts['twenty']).toBe('twenty'); }); @@ -362,11 +365,21 @@ describe('copyBaseApplicationProject', () => { join(srcPath, 'logic-functions', 'hello-world.ts'), ), ).toBe(true); + expect( + await fs.pathExists( + join(srcPath, 'logic-functions', 'create-hello-world-company.ts'), + ), + ).toBe(true); expect( await fs.pathExists( join(srcPath, 'front-components', 'hello-world.tsx'), ), ).toBe(true); + expect( + await fs.pathExists( + join(srcPath, 'page-layouts', 'example-record-page-layout.ts'), + ), + ).toBe(true); expect( await fs.pathExists(join(srcPath, 'views', 'example-view.ts')), ).toBe(true); @@ -448,11 +461,21 @@ describe('copyBaseApplicationProject', () => { join(srcPath, 'logic-functions', 'hello-world.ts'), ), ).toBe(false); + expect( + await fs.pathExists( + join(srcPath, 'logic-functions', 'create-hello-world-company.ts'), + ), + ).toBe(false); expect( await fs.pathExists( join(srcPath, 'front-components', 'hello-world.tsx'), ), ).toBe(false); + expect( + await fs.pathExists( + join(srcPath, 'page-layouts', 'example-record-page-layout.ts'), + ), + ).toBe(false); expect( await fs.pathExists(join(srcPath, 'views', 'example-view.ts')), ).toBe(false); @@ -480,7 +503,7 @@ describe('copyBaseApplicationProject', () => { }); describe('selective examples', () => { - it('should create only front component when only that option is enabled', async () => { + it('should create front component and page layout when only front component option is enabled', async () => { await copyBaseApplicationProject({ appName: 'my-test-app', appDisplayName: 'My Test App', @@ -506,6 +529,11 @@ describe('copyBaseApplicationProject', () => { join(srcPath, 'front-components', 'hello-world.tsx'), ), ).toBe(true); + expect( + await fs.pathExists( + join(srcPath, 'page-layouts', 'example-record-page-layout.ts'), + ), + ).toBe(true); expect( await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')), ).toBe(false); @@ -545,6 +573,11 @@ describe('copyBaseApplicationProject', () => { join(srcPath, 'logic-functions', 'hello-world.ts'), ), ).toBe(true); + expect( + await fs.pathExists( + join(srcPath, 'logic-functions', 'create-hello-world-company.ts'), + ), + ).toBe(true); expect( await fs.pathExists(join(srcPath, 'objects', 'example-object.ts')), ).toBe(false); diff --git a/packages/create-twenty-app/src/utils/__tests__/test-template.spec.ts b/packages/create-twenty-app/src/utils/__tests__/test-template.spec.ts index 0c45baea498..64920f9f95c 100644 --- a/packages/create-twenty-app/src/utils/__tests__/test-template.spec.ts +++ b/packages/create-twenty-app/src/utils/__tests__/test-template.spec.ts @@ -47,15 +47,17 @@ describe('scaffoldIntegrationTest', () => { const content = await fs.readFile(testPath, 'utf8'); expect(content).toContain( - "import { appBuild, appUninstall } from 'twenty-sdk/cli'", + "import { appBuild, appDeploy, appInstall, appUninstall } from 'twenty-sdk/cli'", ); expect(content).toContain( - "import { MetadataApiClient } from 'twenty-sdk/clients'", + "import { MetadataApiClient } from 'twenty-client-sdk/metadata'", ); expect(content).toContain( "import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/application-config'", ); expect(content).toContain('appBuild'); + expect(content).toContain('appDeploy'); + expect(content).toContain('appInstall'); expect(content).toContain('appUninstall'); expect(content).toContain('new MetadataApiClient()'); expect(content).toContain('findManyApplications'); @@ -136,7 +138,7 @@ describe('scaffoldIntegrationTest', () => { expect(content).toContain('yarn install --immutable'); expect(content).toContain('yarn test'); expect(content).toContain('TWENTY_API_URL'); - expect(content).toContain('TWENTY_TEST_API_KEY'); + expect(content).toContain('TWENTY_API_KEY'); }); }); diff --git a/packages/create-twenty-app/src/utils/app-template.ts b/packages/create-twenty-app/src/utils/app-template.ts index 98f5cc7ef98..572108afc61 100644 --- a/packages/create-twenty-app/src/utils/app-template.ts +++ b/packages/create-twenty-app/src/utils/app-template.ts @@ -34,6 +34,8 @@ export const copyBaseApplicationProject = async ({ await createGitignore(appDirectory); + await createNvmrc(appDirectory); + await createPublicAssetDirectory(appDirectory); const sourceFolderPath = join(appDirectory, SRC_FOLDER); @@ -69,6 +71,12 @@ export const copyBaseApplicationProject = async ({ fileFolder: 'logic-functions', fileName: 'hello-world.ts', }); + + await createCreateCompanyFunction({ + appDirectory: sourceFolderPath, + fileFolder: 'logic-functions', + fileName: 'create-hello-world-company.ts', + }); } if (exampleOptions.includeExampleFrontComponent) { @@ -77,6 +85,12 @@ export const copyBaseApplicationProject = async ({ fileFolder: 'front-components', fileName: 'hello-world.tsx', }); + + await createExamplePageLayout({ + appDirectory: sourceFolderPath, + fileFolder: 'page-layouts', + fileName: 'example-record-page-layout.ts', + }); } if (exampleOptions.includeExampleView) { @@ -186,6 +200,10 @@ yarn-error.log* await fs.writeFile(join(appDirectory, '.gitignore'), gitignoreContent); }; +const createNvmrc = async (appDirectory: string) => { + await fs.writeFile(join(appDirectory, '.nvmrc'), '24.5.0\n'); +}; + const createDefaultRoleConfig = async ({ displayName, appDirectory, @@ -230,19 +248,59 @@ const createDefaultFrontComponent = async ({ }) => { const universalIdentifier = v4(); - const content = `import { defineFrontComponent } from 'twenty-sdk'; + const content = `import { useEffect, useState } from 'react'; +import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core'; +import { defineFrontComponent } from 'twenty-sdk'; + +export const HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER = + '${universalIdentifier}'; export const HelloWorld = () => { + const client = new CoreApiClient(); + const [data, setData] = useState< + Pick | undefined + >(undefined); + + useEffect(() => { + const fetchData = async () => { + const response = await client.query({ + company: { + name: true, + id: true, + __args: { + filter: { + position: { + eq: 1, + }, + }, + }, + }, + }); + + setData(response.company); + }; + + fetchData(); + }, []); + return (

Hello, World!

This is your first front component.

+ {data ? ( +
+

Company name: {data.name}

+

Company id: {data.id}

+
+ ) : ( +

Company not found

+ )}
); }; export default defineFrontComponent({ - universalIdentifier: '${universalIdentifier}', + universalIdentifier: HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, name: 'hello-world-front-component', description: 'A sample front component', component: HelloWorld, @@ -253,6 +311,56 @@ export default defineFrontComponent({ await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content); }; +const createExamplePageLayout = async ({ + appDirectory, + fileFolder, + fileName, +}: { + appDirectory: string; + fileFolder?: string; + fileName: string; +}) => { + const pageLayoutUniversalIdentifier = v4(); + const tabUniversalIdentifier = v4(); + const widgetUniversalIdentifier = v4(); + + const content = `import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'; +import { HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/front-components/hello-world'; +import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk'; + +export default definePageLayout({ + universalIdentifier: '${pageLayoutUniversalIdentifier}', + name: 'Example Record Page', + type: 'RECORD_PAGE', + objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, + tabs: [ + { + universalIdentifier: '${tabUniversalIdentifier}', + title: 'Hello World', + position: 50, + icon: 'IconWorld', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + widgets: [ + { + universalIdentifier: '${widgetUniversalIdentifier}', + title: 'Hello World', + type: 'FRONT_COMPONENT', + configuration: { + configurationType: 'FRONT_COMPONENT', + frontComponentUniversalIdentifier: + HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, + }, + }, + ], + }, + ], +}); +`; + + await fs.ensureDir(join(appDirectory, fileFolder ?? '')); + await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content); +}; + const createDefaultFunction = async ({ appDirectory, fileFolder, @@ -288,6 +396,58 @@ export default defineLogicFunction({ await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content); }; +const createCreateCompanyFunction = async ({ + appDirectory, + fileFolder, + fileName, +}: { + appDirectory: string; + fileFolder?: string; + fileName: string; +}) => { + const universalIdentifier = v4(); + + const content = `import { CoreApiClient } from 'twenty-client-sdk/core'; +import { defineLogicFunction } from 'twenty-sdk'; + +const handler = async (): Promise<{ message: string }> => { + const client = new CoreApiClient(); + + const { createCompany } = await client.mutation({ + createCompany: { + __args: { + data: { + name: 'Hello World', + }, + }, + id: true, + name: true, + }, + }); + + return { + message: \`Created company "\${createCompany?.name}" with id \${createCompany?.id}\`, + }; +}; + +export default defineLogicFunction({ + universalIdentifier: '${universalIdentifier}', + name: 'create-hello-world-company', + description: 'Creates a company called Hello World', + timeoutSeconds: 5, + handler, + httpRouteTriggerSettings: { + path: '/create-hello-world-company', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); +`; + + await fs.ensureDir(join(appDirectory, fileFolder ?? '')); + await fs.writeFile(join(appDirectory, fileFolder ?? '', fileName), content); +}; + const createDefaultPreInstallFunction = async ({ appDirectory, fileFolder, @@ -615,6 +775,7 @@ const createPackageJson = async ({ 'react-dom': '^19.0.0', oxlint: '^0.16.0', 'twenty-sdk': createTwentyAppPackageJson.version, + 'twenty-client-sdk': createTwentyAppPackageJson.version, }; if (includeExampleIntegrationTest) { diff --git a/packages/create-twenty-app/src/utils/test-template.ts b/packages/create-twenty-app/src/utils/test-template.ts index 46bd85d4505..0ea50c8b421 100644 --- a/packages/create-twenty-app/src/utils/test-template.ts +++ b/packages/create-twenty-app/src/utils/test-template.ts @@ -149,18 +149,17 @@ const createIntegrationTest = async ({ fileName: string; }) => { const content = `import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/application-config'; -import { appBuild, appUninstall } from 'twenty-sdk/cli'; -import { MetadataApiClient } from 'twenty-sdk/clients'; +import { appBuild, appDeploy, appInstall, appUninstall } from 'twenty-sdk/cli'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; const APP_PATH = process.cwd(); describe('App installation', () => { - let appInstalled = false; - beforeAll(async () => { const buildResult = await appBuild({ appPath: APP_PATH, + tarball: true, onProgress: (message: string) => console.log(\`[build] \${message}\`), }); @@ -170,14 +169,27 @@ describe('App installation', () => { ); } - appInstalled = true; + const deployResult = await appDeploy({ + tarballPath: buildResult.data.tarballPath!, + onProgress: (message: string) => console.log(\`[deploy] \${message}\`), + }); + + if (!deployResult.success) { + throw new Error( + \`Deploy failed: \${deployResult.error?.message ?? 'Unknown error'}\`, + ); + } + + const installResult = await appInstall({ appPath: APP_PATH }); + + if (!installResult.success) { + throw new Error( + \`Install failed: \${installResult.error?.message ?? 'Unknown error'}\`, + ); + } }); afterAll(async () => { - if (!appInstalled) { - return; - } - const uninstallResult = await appUninstall({ appPath: APP_PATH }); if (!uninstallResult.success) { @@ -257,7 +269,7 @@ jobs: run: yarn test env: TWENTY_API_URL: \${{ steps.twenty.outputs.server-url }} - TWENTY_TEST_API_KEY: \${{ steps.twenty.outputs.access-token }} + TWENTY_API_KEY: \${{ steps.twenty.outputs.access-token }} `; const workflowDir = join(appDirectory, '.github', 'workflows'); diff --git a/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardCategoryField.ts b/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardCategoryField.ts index 6a21a9efdf9..e9fb6565c8b 100644 --- a/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardCategoryField.ts +++ b/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardCategoryField.ts @@ -3,7 +3,7 @@ import { POST_CARD_UNIVERSAL_IDENTIFIER } from '../objects/post-card.object'; export default defineField({ objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER, - universalIdentifier: '8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e', + universalIdentifier: 'b602dbd9-e511-49ce-b6d3-b697218dc69c', type: FieldType.SELECT, name: 'category', label: 'Category', diff --git a/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardNumber.field.ts b/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardNumber.field.ts index 94d924865aa..f3f3ad98b02 100644 --- a/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardNumber.field.ts +++ b/packages/twenty-apps/fixtures/postcard-app/src/fields/postCardNumber.field.ts @@ -3,7 +3,7 @@ import { POST_CARD_UNIVERSAL_IDENTIFIER } from '../objects/post-card.object'; export default defineField({ objectUniversalIdentifier: POST_CARD_UNIVERSAL_IDENTIFIER, - universalIdentifier: '7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d', + universalIdentifier: '7b57bd63-5a4c-46ca-9d52-42c8f02d1df6', type: FieldType.NUMBER, name: 'priority', label: 'Priority', diff --git a/packages/twenty-apps/fixtures/postcard-app/src/objects/recipient.object.ts b/packages/twenty-apps/fixtures/postcard-app/src/objects/recipient.object.ts index e636f782a0f..5febca5faa5 100644 --- a/packages/twenty-apps/fixtures/postcard-app/src/objects/recipient.object.ts +++ b/packages/twenty-apps/fixtures/postcard-app/src/objects/recipient.object.ts @@ -25,8 +25,8 @@ export default defineObject({ { universalIdentifier: 'd3a2b3c4-5e6f-4a7b-8c9d-0e1f2a3b4c5d', type: FieldType.ADDRESS, - label: 'Address', - name: 'address', + label: 'Mailing Address', + name: 'mailingAddress', icon: 'IconHome', }, ], diff --git a/packages/twenty-apps/hello-world/.github/workflows/ci.yml b/packages/twenty-apps/hello-world/.github/workflows/ci.yml new file mode 100644 index 00000000000..92bd0e994f9 --- /dev/null +++ b/packages/twenty-apps/hello-world/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +on: + push: + branches: + - main + pull_request: {} + +env: + TWENTY_VERSION: latest + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Spawn Twenty instance + id: twenty + uses: twentyhq/twenty/.github/actions/spawn-twenty-docker-image@main + with: + twenty-version: ${{ env.TWENTY_VERSION }} + github-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Enable Corepack + run: corepack enable + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --immutable + + - name: Run integration tests + run: yarn test + env: + TWENTY_API_URL: ${{ steps.twenty.outputs.server-url }} + TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }} diff --git a/packages/twenty-apps/hello-world/LLMS.md b/packages/twenty-apps/hello-world/LLMS.md index c08c2475f18..b165db0d146 100644 --- a/packages/twenty-apps/hello-world/LLMS.md +++ b/packages/twenty-apps/hello-world/LLMS.md @@ -4,6 +4,7 @@ - Rich app example: https://github.com/twentyhq/twenty/tree/main/packages/twenty-sdk/src/app-seeds/rich-app ## UUID requirement + - All generated UUIDs must be valid UUID v4. ## Common Pitfalls diff --git a/packages/twenty-apps/hello-world/package.json b/packages/twenty-apps/hello-world/package.json index 8c9e233820d..f896e9ba264 100644 --- a/packages/twenty-apps/hello-world/package.json +++ b/packages/twenty-apps/hello-world/package.json @@ -20,7 +20,8 @@ "@types/react": "^18.2.0", "oxlint": "^0.16.0", "react": "^18.2.0", - "twenty-sdk": "0.6.4", + "twenty-client-sdk": "portal:../../twenty-client-sdk", + "twenty-sdk": "portal:../../twenty-sdk", "typescript": "^5.9.3", "vite-tsconfig-paths": "^4.2.1", "vitest": "^3.1.1" diff --git a/packages/twenty-apps/hello-world/src/__tests__/app-install.integration-test.ts b/packages/twenty-apps/hello-world/src/__tests__/app-install.integration-test.ts index 8f6945211cb..58002036a4b 100644 --- a/packages/twenty-apps/hello-world/src/__tests__/app-install.integration-test.ts +++ b/packages/twenty-apps/hello-world/src/__tests__/app-install.integration-test.ts @@ -1,16 +1,15 @@ import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/application-config'; -import { appBuild, appUninstall } from 'twenty-sdk/cli'; -import { MetadataApiClient } from 'twenty-sdk/clients'; +import { appBuild, appDeploy, appInstall, appUninstall } from 'twenty-sdk/cli'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; import { afterAll, beforeAll, describe, expect, it } from 'vitest'; const APP_PATH = process.cwd(); describe('App installation', () => { - let appInstalled = false; - beforeAll(async () => { const buildResult = await appBuild({ appPath: APP_PATH, + tarball: true, onProgress: (message: string) => console.log(`[build] ${message}`), }); @@ -20,14 +19,27 @@ describe('App installation', () => { ); } - appInstalled = true; + const deployResult = await appDeploy({ + tarballPath: buildResult.data.tarballPath!, + onProgress: (message: string) => console.log(`[deploy] ${message}`), + }); + + if (!deployResult.success) { + throw new Error( + `Deploy failed: ${deployResult.error?.message ?? 'Unknown error'}`, + ); + } + + const installResult = await appInstall({ appPath: APP_PATH }); + + if (!installResult.success) { + throw new Error( + `Install failed: ${installResult.error?.message ?? 'Unknown error'}`, + ); + } }); afterAll(async () => { - if (!appInstalled) { - return; - } - const uninstallResult = await appUninstall({ appPath: APP_PATH }); if (!uninstallResult.success) { diff --git a/packages/twenty-apps/hello-world/src/agents/example-agent.ts b/packages/twenty-apps/hello-world/src/agents/example-agent.ts new file mode 100644 index 00000000000..5fbec3c5e29 --- /dev/null +++ b/packages/twenty-apps/hello-world/src/agents/example-agent.ts @@ -0,0 +1,13 @@ +import { defineAgent } from 'twenty-sdk'; + +export const EXAMPLE_AGENT_UNIVERSAL_IDENTIFIER = + '110bebc2-f116-46b6-a35d-61e91c3c0a43'; + +export default defineAgent({ + universalIdentifier: EXAMPLE_AGENT_UNIVERSAL_IDENTIFIER, + name: 'example-agent', + label: 'Example Agent', + description: 'A sample AI agent for your application', + icon: 'IconRobot', + prompt: 'You are a helpful assistant. Help users with their questions and tasks.', +}); diff --git a/packages/twenty-apps/hello-world/src/application-config.ts b/packages/twenty-apps/hello-world/src/application-config.ts index 7956f15e771..d2a71554dd1 100644 --- a/packages/twenty-apps/hello-world/src/application-config.ts +++ b/packages/twenty-apps/hello-world/src/application-config.ts @@ -2,7 +2,7 @@ import { defineApplication } from 'twenty-sdk'; import { DEFAULT_ROLE_UNIVERSAL_IDENTIFIER } from 'src/roles/default-role'; export const APPLICATION_UNIVERSAL_IDENTIFIER = - '6563e091-9f5b-4026-a3ea-7e3b3d09e218'; + 'bb1decf6-dee5-43ef-b881-9799f97b02a8'; export default defineApplication({ universalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER, diff --git a/packages/twenty-apps/hello-world/src/fields/example-field.ts b/packages/twenty-apps/hello-world/src/fields/example-field.ts index 4500aa2950f..2c99c57b040 100644 --- a/packages/twenty-apps/hello-world/src/fields/example-field.ts +++ b/packages/twenty-apps/hello-world/src/fields/example-field.ts @@ -3,7 +3,7 @@ import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object' export default defineField({ objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, - universalIdentifier: '770d32c2-cf12-4ab2-b66d-73f92dc239b5', + universalIdentifier: 'be08a7c6-2586-4d91-9fa7-0a44e6eae30c', type: FieldType.NUMBER, name: 'priority', label: 'Priority', diff --git a/packages/twenty-apps/hello-world/src/front-components/hello-world.tsx b/packages/twenty-apps/hello-world/src/front-components/hello-world.tsx index bde03498ae0..ab0246e9fd0 100644 --- a/packages/twenty-apps/hello-world/src/front-components/hello-world.tsx +++ b/packages/twenty-apps/hello-world/src/front-components/hello-world.tsx @@ -1,16 +1,56 @@ +import { useEffect, useState } from 'react'; +import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core'; import { defineFrontComponent } from 'twenty-sdk'; +export const HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER = + '7a758f23-5e7d-497d-98c9-7ca8d6c085b0'; + export const HelloWorld = () => { + const client = new CoreApiClient(); + const [data, setData] = useState< + Pick | undefined + >(undefined); + + useEffect(() => { + const fetchData = async () => { + const response = await client.query({ + company: { + name: true, + id: true, + __args: { + filter: { + position: { + eq: 1, + }, + }, + }, + }, + }); + + setData(response.company); + }; + + fetchData(); + }, []); + return (

Hello, World!

This is your first front component.

+ {data ? ( +
+

Company name: {data.name}

+

Company id: {data.id}

+
+ ) : ( +

Company not found

+ )}
); }; export default defineFrontComponent({ - universalIdentifier: 'd371f098-5b2c-42f0-898d-94459f1ee337', + universalIdentifier: HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, name: 'hello-world-front-component', description: 'A sample front component', component: HelloWorld, diff --git a/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts b/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts new file mode 100644 index 00000000000..4388f3c03cb --- /dev/null +++ b/packages/twenty-apps/hello-world/src/logic-functions/create-hello-world-company.ts @@ -0,0 +1,35 @@ +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { defineLogicFunction } from 'twenty-sdk'; + +const handler = async (): Promise<{ message: string }> => { + const client = new CoreApiClient(); + + const { createCompany } = await client.mutation({ + createCompany: { + __args: { + data: { + name: 'Hello World', + }, + }, + id: true, + name: true, + }, + }); + + return { + message: `Created company "${createCompany?.name}" with id ${createCompany?.id}`, + }; +}; + +export default defineLogicFunction({ + universalIdentifier: '94abaa53-d265-4fa4-ae52-1d7ea711ecf2', + name: 'create-hello-world-company', + description: 'Creates a company called Hello World', + timeoutSeconds: 5, + handler, + httpRouteTriggerSettings: { + path: '/create-hello-world-company', + httpMethod: 'POST', + isAuthRequired: true, + }, +}); diff --git a/packages/twenty-apps/hello-world/src/logic-functions/hello-world.ts b/packages/twenty-apps/hello-world/src/logic-functions/hello-world.ts index 13add55a3c9..f1f4eea31b8 100644 --- a/packages/twenty-apps/hello-world/src/logic-functions/hello-world.ts +++ b/packages/twenty-apps/hello-world/src/logic-functions/hello-world.ts @@ -5,7 +5,7 @@ const handler = async (): Promise<{ message: string }> => { }; export default defineLogicFunction({ - universalIdentifier: '2baa26eb-9aaf-4856-a4f4-30d6fd6480ee', + universalIdentifier: 'b05e4b30-72d4-4d7f-8091-32e037b601da', name: 'hello-world-logic-function', description: 'A simple logic function', timeoutSeconds: 5, diff --git a/packages/twenty-apps/hello-world/src/logic-functions/post-install.ts b/packages/twenty-apps/hello-world/src/logic-functions/post-install.ts index a058c8fd5ed..daa29efbe2b 100644 --- a/packages/twenty-apps/hello-world/src/logic-functions/post-install.ts +++ b/packages/twenty-apps/hello-world/src/logic-functions/post-install.ts @@ -5,7 +5,7 @@ const handler = async (payload: InstallLogicFunctionPayload): Promise => { }; export default definePostInstallLogicFunction({ - universalIdentifier: '7a3f4684-51db-494d-833b-a747a3b90507', + universalIdentifier: '8c726dcc-1709-4eac-aa8b-f99960a9ec1b', name: 'post-install', description: 'Runs after installation to set up the application.', timeoutSeconds: 300, diff --git a/packages/twenty-apps/hello-world/src/logic-functions/pre-install.ts b/packages/twenty-apps/hello-world/src/logic-functions/pre-install.ts index 0a9890c3083..ddae8236ac1 100644 --- a/packages/twenty-apps/hello-world/src/logic-functions/pre-install.ts +++ b/packages/twenty-apps/hello-world/src/logic-functions/pre-install.ts @@ -5,7 +5,7 @@ const handler = async (payload: InstallLogicFunctionPayload): Promise => { }; export default definePreInstallLogicFunction({ - universalIdentifier: '1272ffdb-8e2f-492c-ab37-66c2b97e9c23', + universalIdentifier: 'f8ad4b09-6a12-4b12-a52a-3472d3a78dc7', name: 'pre-install', description: 'Runs before installation to prepare the application.', timeoutSeconds: 300, diff --git a/packages/twenty-apps/hello-world/src/navigation-menu-items/example-navigation-menu-item.ts b/packages/twenty-apps/hello-world/src/navigation-menu-items/example-navigation-menu-item.ts index 57d10fae8dc..3c28e92f5d0 100644 --- a/packages/twenty-apps/hello-world/src/navigation-menu-items/example-navigation-menu-item.ts +++ b/packages/twenty-apps/hello-world/src/navigation-menu-items/example-navigation-menu-item.ts @@ -3,7 +3,7 @@ import { NavigationMenuItemType } from 'twenty-shared/types'; import { EXAMPLE_VIEW_UNIVERSAL_IDENTIFIER } from 'src/views/example-view'; export default defineNavigationMenuItem({ - universalIdentifier: '10f90627-e9c2-44b7-9742-bed77e3d1b17', + universalIdentifier: '9327db91-afa1-41b6-bd9d-2b51a26efb4c', name: 'example-navigation-menu-item', icon: 'IconList', color: 'blue', diff --git a/packages/twenty-apps/hello-world/src/objects/example-object.ts b/packages/twenty-apps/hello-world/src/objects/example-object.ts index 33b358ab240..1284bb2a35b 100644 --- a/packages/twenty-apps/hello-world/src/objects/example-object.ts +++ b/packages/twenty-apps/hello-world/src/objects/example-object.ts @@ -1,10 +1,10 @@ import { defineObject, FieldType } from 'twenty-sdk'; export const EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER = - 'dfd43356-39b3-4b55-b4a7-279bec689928'; + '47fd9bd9-392b-4d9f-9091-9a91b1edf519'; export const NAME_FIELD_UNIVERSAL_IDENTIFIER = - 'd2d7f6cd-33f6-456f-bf00-17adeca926ba'; + '2d9ff841-cf8e-44ec-ad8e-468455f7eebd'; export default defineObject({ universalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, diff --git a/packages/twenty-apps/hello-world/src/page-layouts/example-record-page-layout.ts b/packages/twenty-apps/hello-world/src/page-layouts/example-record-page-layout.ts new file mode 100644 index 00000000000..726242c6aa2 --- /dev/null +++ b/packages/twenty-apps/hello-world/src/page-layouts/example-record-page-layout.ts @@ -0,0 +1,31 @@ +import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'; +import { HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER } from 'src/front-components/hello-world'; +import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk'; + +export default definePageLayout({ + universalIdentifier: '203aeb94-6701-46d6-9af1-be2bbcc9e134', + name: 'Example Record Page', + type: 'RECORD_PAGE', + objectUniversalIdentifier: EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, + tabs: [ + { + universalIdentifier: '6ed26b60-a51d-4ad7-86dd-1c04c7f3cac5', + title: 'Hello World', + position: 50, + icon: 'IconWorld', + layoutMode: PageLayoutTabLayoutMode.CANVAS, + widgets: [ + { + universalIdentifier: 'aa4234e0-2e5f-4c02-a96a-573449e2351d', + title: 'Hello World', + type: 'FRONT_COMPONENT', + configuration: { + configurationType: 'FRONT_COMPONENT', + frontComponentUniversalIdentifier: + HELLO_WORLD_FRONT_COMPONENT_UNIVERSAL_IDENTIFIER, + }, + }, + ], + }, + ], +}); diff --git a/packages/twenty-apps/hello-world/src/roles/default-role.ts b/packages/twenty-apps/hello-world/src/roles/default-role.ts index 721b630d4c7..583eea4c749 100644 --- a/packages/twenty-apps/hello-world/src/roles/default-role.ts +++ b/packages/twenty-apps/hello-world/src/roles/default-role.ts @@ -1,7 +1,7 @@ import { defineRole } from 'twenty-sdk'; export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER = - '9238bc7b-d38f-4a1c-9d19-31ab7bc67a2f'; + 'c38f4d11-760c-4d5c-89ed-e569c28b7b70'; export default defineRole({ universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER, diff --git a/packages/twenty-apps/hello-world/src/skills/example-skill.ts b/packages/twenty-apps/hello-world/src/skills/example-skill.ts index b8f942a4668..640e54a2cdd 100644 --- a/packages/twenty-apps/hello-world/src/skills/example-skill.ts +++ b/packages/twenty-apps/hello-world/src/skills/example-skill.ts @@ -1,7 +1,7 @@ import { defineSkill } from 'twenty-sdk'; export const EXAMPLE_SKILL_UNIVERSAL_IDENTIFIER = - 'd0940029-9d3c-40be-903a-52d65393028f'; + '90cf9144-4811-4653-93a2-9a6780fe6aac'; export default defineSkill({ universalIdentifier: EXAMPLE_SKILL_UNIVERSAL_IDENTIFIER, diff --git a/packages/twenty-apps/hello-world/src/views/example-view.ts b/packages/twenty-apps/hello-world/src/views/example-view.ts index 5326d89769b..7f18513a2c8 100644 --- a/packages/twenty-apps/hello-world/src/views/example-view.ts +++ b/packages/twenty-apps/hello-world/src/views/example-view.ts @@ -1,7 +1,7 @@ import { defineView, ViewKey } from 'twenty-sdk'; import { EXAMPLE_OBJECT_UNIVERSAL_IDENTIFIER, NAME_FIELD_UNIVERSAL_IDENTIFIER } from 'src/objects/example-object'; -export const EXAMPLE_VIEW_UNIVERSAL_IDENTIFIER = 'e004df40-29f3-47ba-b39d-d3a5c444367a'; +export const EXAMPLE_VIEW_UNIVERSAL_IDENTIFIER = '965e3776-b966-4be8-83f7-6cd3bce5e1bd'; export default defineView({ universalIdentifier: EXAMPLE_VIEW_UNIVERSAL_IDENTIFIER, @@ -12,7 +12,7 @@ export default defineView({ position: 0, fields: [ { - universalIdentifier: '496c40c2-5766-419c-93bf-20fdad3f34bb', + universalIdentifier: 'f926bdb7-6af7-4683-9a09-adbca56c29f0', fieldMetadataUniversalIdentifier: NAME_FIELD_UNIVERSAL_IDENTIFIER, position: 0, isVisible: true, diff --git a/packages/twenty-apps/hello-world/yarn.lock b/packages/twenty-apps/hello-world/yarn.lock index f7ae21d9ce2..571eb2ec244 100644 --- a/packages/twenty-apps/hello-world/yarn.lock +++ b/packages/twenty-apps/hello-world/yarn.lock @@ -352,9 +352,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/aix-ppc64@npm:0.27.3" +"@esbuild/aix-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/aix-ppc64@npm:0.27.4" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard @@ -366,9 +366,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-arm64@npm:0.27.3" +"@esbuild/android-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm64@npm:0.27.4" conditions: os=android & cpu=arm64 languageName: node linkType: hard @@ -380,9 +380,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-arm@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-arm@npm:0.27.3" +"@esbuild/android-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm@npm:0.27.4" conditions: os=android & cpu=arm languageName: node linkType: hard @@ -394,9 +394,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/android-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-x64@npm:0.27.3" +"@esbuild/android-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-x64@npm:0.27.4" conditions: os=android & cpu=x64 languageName: node linkType: hard @@ -408,9 +408,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/darwin-arm64@npm:0.27.3" +"@esbuild/darwin-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-arm64@npm:0.27.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -422,9 +422,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/darwin-x64@npm:0.27.3" +"@esbuild/darwin-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-x64@npm:0.27.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard @@ -436,9 +436,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/freebsd-arm64@npm:0.27.3" +"@esbuild/freebsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-arm64@npm:0.27.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard @@ -450,9 +450,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/freebsd-x64@npm:0.27.3" +"@esbuild/freebsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-x64@npm:0.27.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard @@ -464,9 +464,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-arm64@npm:0.27.3" +"@esbuild/linux-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm64@npm:0.27.4" conditions: os=linux & cpu=arm64 languageName: node linkType: hard @@ -478,9 +478,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-arm@npm:0.27.3" +"@esbuild/linux-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm@npm:0.27.4" conditions: os=linux & cpu=arm languageName: node linkType: hard @@ -492,9 +492,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-ia32@npm:0.27.3" +"@esbuild/linux-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ia32@npm:0.27.4" conditions: os=linux & cpu=ia32 languageName: node linkType: hard @@ -506,9 +506,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-loong64@npm:0.27.3" +"@esbuild/linux-loong64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-loong64@npm:0.27.4" conditions: os=linux & cpu=loong64 languageName: node linkType: hard @@ -520,9 +520,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-mips64el@npm:0.27.3" +"@esbuild/linux-mips64el@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-mips64el@npm:0.27.4" conditions: os=linux & cpu=mips64el languageName: node linkType: hard @@ -534,9 +534,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-ppc64@npm:0.27.3" +"@esbuild/linux-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ppc64@npm:0.27.4" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard @@ -548,9 +548,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-riscv64@npm:0.27.3" +"@esbuild/linux-riscv64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-riscv64@npm:0.27.4" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard @@ -562,9 +562,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-s390x@npm:0.27.3" +"@esbuild/linux-s390x@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-s390x@npm:0.27.4" conditions: os=linux & cpu=s390x languageName: node linkType: hard @@ -576,9 +576,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-x64@npm:0.27.3" +"@esbuild/linux-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-x64@npm:0.27.4" conditions: os=linux & cpu=x64 languageName: node linkType: hard @@ -590,9 +590,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/netbsd-arm64@npm:0.27.3" +"@esbuild/netbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-arm64@npm:0.27.4" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard @@ -604,9 +604,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/netbsd-x64@npm:0.27.3" +"@esbuild/netbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-x64@npm:0.27.4" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard @@ -618,9 +618,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openbsd-arm64@npm:0.27.3" +"@esbuild/openbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-arm64@npm:0.27.4" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard @@ -632,9 +632,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openbsd-x64@npm:0.27.3" +"@esbuild/openbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-x64@npm:0.27.4" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard @@ -646,9 +646,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openharmony-arm64@npm:0.27.3" +"@esbuild/openharmony-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openharmony-arm64@npm:0.27.4" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard @@ -660,9 +660,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/sunos-x64@npm:0.27.3" +"@esbuild/sunos-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/sunos-x64@npm:0.27.4" conditions: os=sunos & cpu=x64 languageName: node linkType: hard @@ -674,9 +674,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-arm64@npm:0.27.3" +"@esbuild/win32-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-arm64@npm:0.27.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard @@ -688,9 +688,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-ia32@npm:0.27.3" +"@esbuild/win32-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-ia32@npm:0.27.4" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard @@ -702,9 +702,9 @@ __metadata: languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-x64@npm:0.27.3" +"@esbuild/win32-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-x64@npm:0.27.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1541,11 +1541,11 @@ __metadata: linkType: hard "@types/node@npm:*": - version: 25.3.5 - resolution: "@types/node@npm:25.3.5" + version: 25.5.0 + resolution: "@types/node@npm:25.5.0" dependencies: undici-types: "npm:~7.18.0" - checksum: 10c0/4cf0834a6f6933bf0aca6afead117ae3db3b8f02a5f7187a24f871db0fb9344e5e46573ba387bc53b7505e1e219c4c535cbe67221ced95bb5ad98573223b19d0 + checksum: 10c0/70c508165b6758c4f88d4f91abca526c3985eee1985503d4c2bd994dbaf588e52ac57e571160f18f117d76e963570ac82bd20e743c18987e82564312b3b62119 languageName: node linkType: hard @@ -3408,35 +3408,35 @@ __metadata: linkType: hard "esbuild@npm:^0.27.0": - version: 0.27.3 - resolution: "esbuild@npm:0.27.3" + version: 0.27.4 + resolution: "esbuild@npm:0.27.4" dependencies: - "@esbuild/aix-ppc64": "npm:0.27.3" - "@esbuild/android-arm": "npm:0.27.3" - "@esbuild/android-arm64": "npm:0.27.3" - "@esbuild/android-x64": "npm:0.27.3" - "@esbuild/darwin-arm64": "npm:0.27.3" - "@esbuild/darwin-x64": "npm:0.27.3" - "@esbuild/freebsd-arm64": "npm:0.27.3" - "@esbuild/freebsd-x64": "npm:0.27.3" - "@esbuild/linux-arm": "npm:0.27.3" - "@esbuild/linux-arm64": "npm:0.27.3" - "@esbuild/linux-ia32": "npm:0.27.3" - "@esbuild/linux-loong64": "npm:0.27.3" - "@esbuild/linux-mips64el": "npm:0.27.3" - "@esbuild/linux-ppc64": "npm:0.27.3" - "@esbuild/linux-riscv64": "npm:0.27.3" - "@esbuild/linux-s390x": "npm:0.27.3" - "@esbuild/linux-x64": "npm:0.27.3" - "@esbuild/netbsd-arm64": "npm:0.27.3" - "@esbuild/netbsd-x64": "npm:0.27.3" - "@esbuild/openbsd-arm64": "npm:0.27.3" - "@esbuild/openbsd-x64": "npm:0.27.3" - "@esbuild/openharmony-arm64": "npm:0.27.3" - "@esbuild/sunos-x64": "npm:0.27.3" - "@esbuild/win32-arm64": "npm:0.27.3" - "@esbuild/win32-ia32": "npm:0.27.3" - "@esbuild/win32-x64": "npm:0.27.3" + "@esbuild/aix-ppc64": "npm:0.27.4" + "@esbuild/android-arm": "npm:0.27.4" + "@esbuild/android-arm64": "npm:0.27.4" + "@esbuild/android-x64": "npm:0.27.4" + "@esbuild/darwin-arm64": "npm:0.27.4" + "@esbuild/darwin-x64": "npm:0.27.4" + "@esbuild/freebsd-arm64": "npm:0.27.4" + "@esbuild/freebsd-x64": "npm:0.27.4" + "@esbuild/linux-arm": "npm:0.27.4" + "@esbuild/linux-arm64": "npm:0.27.4" + "@esbuild/linux-ia32": "npm:0.27.4" + "@esbuild/linux-loong64": "npm:0.27.4" + "@esbuild/linux-mips64el": "npm:0.27.4" + "@esbuild/linux-ppc64": "npm:0.27.4" + "@esbuild/linux-riscv64": "npm:0.27.4" + "@esbuild/linux-s390x": "npm:0.27.4" + "@esbuild/linux-x64": "npm:0.27.4" + "@esbuild/netbsd-arm64": "npm:0.27.4" + "@esbuild/netbsd-x64": "npm:0.27.4" + "@esbuild/openbsd-arm64": "npm:0.27.4" + "@esbuild/openbsd-x64": "npm:0.27.4" + "@esbuild/openharmony-arm64": "npm:0.27.4" + "@esbuild/sunos-x64": "npm:0.27.4" + "@esbuild/win32-arm64": "npm:0.27.4" + "@esbuild/win32-ia32": "npm:0.27.4" + "@esbuild/win32-x64": "npm:0.27.4" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -3492,7 +3492,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10c0/fdc3f87a3f08b3ef98362f37377136c389a0d180fda4b8d073b26ba930cf245521db0a368f119cc7624bc619248fff1439f5811f062d853576f8ffa3df8ee5f1 + checksum: 10c0/2a1c2bcccda279f2afd72a7f8259860cb4483b32453d17878e1ecb4ac416b9e7c1001e7aa0a25ba4c29c1e250a3ceaae5d8bb72a119815bc8db4e9b5f5321490 languageName: node linkType: hard @@ -3906,6 +3906,7 @@ __metadata: "@types/react": "npm:^18.2.0" oxlint: "npm:^0.16.0" react: "npm:^18.2.0" + twenty-client-sdk: "portal:../../twenty-client-sdk" twenty-sdk: "portal:../../twenty-sdk" typescript: "npm:^5.9.3" vite-tsconfig-paths: "npm:^4.2.1" @@ -4952,9 +4953,9 @@ __metadata: linkType: hard "preact@npm:^10.28.3": - version: 10.28.4 - resolution: "preact@npm:10.28.4" - checksum: 10c0/712384e92d6c676c8f4c230eab81329a66acfecf700390aebfe5fc46168fa3686345d47f2292068dcc0a6d86425a3d9a3d743730e356e867a8402442afb989db + version: 10.29.0 + resolution: "preact@npm:10.29.0" + checksum: 10c0/d111381e5b48335e3a797a03adb83521cf5e9bdf880570fb2eff4fe9da9c82e6dedcbdf54538b1ed8f60bf813a0df0f4891b03dc32140ad93f8f720a8812dd5c languageName: node linkType: hard @@ -5750,6 +5751,17 @@ __metadata: languageName: node linkType: hard +"twenty-client-sdk@portal:../../twenty-client-sdk::locator=hello-world%40workspace%3A.": + version: 0.0.0-use.local + resolution: "twenty-client-sdk@portal:../../twenty-client-sdk::locator=hello-world%40workspace%3A." + dependencies: + "@genql/cli": "npm:^3.0.3" + "@genql/runtime": "npm:^2.10.0" + esbuild: "npm:^0.25.0" + graphql: "npm:^16.8.1" + languageName: node + linkType: soft + "twenty-sdk@portal:../../twenty-sdk::locator=hello-world%40workspace%3A.": version: 0.0.0-use.local resolution: "twenty-sdk@portal:../../twenty-sdk::locator=hello-world%40workspace%3A." diff --git a/packages/twenty-client-sdk/.oxlintrc.json b/packages/twenty-client-sdk/.oxlintrc.json new file mode 100644 index 00000000000..88218016ce4 --- /dev/null +++ b/packages/twenty-client-sdk/.oxlintrc.json @@ -0,0 +1,47 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "import", "unicorn"], + "categories": { + "correctness": "off" + }, + "ignorePatterns": ["node_modules", "dist", "generated"], + "rules": { + "func-style": ["error", "declaration", { "allowArrowFunctions": true }], + "no-console": "off", + "no-control-regex": "off", + "no-debugger": "error", + "no-duplicate-imports": "error", + "no-undef": "off", + "no-unused-vars": "off", + "no-redeclare": "off", + "import/no-duplicates": "error", + "typescript/no-redeclare": "error", + "typescript/ban-ts-comment": "error", + "typescript/consistent-type-imports": [ + "error", + { + "prefer": "type-imports", + "fixStyle": "inline-type-imports" + } + ], + "typescript/explicit-function-return-type": "off", + "typescript/explicit-module-boundary-types": "off", + "typescript/no-empty-object-type": [ + "error", + { + "allowInterfaces": "with-single-extends" + } + ], + "typescript/no-empty-function": "off", + "typescript/no-explicit-any": "off", + "typescript/no-unused-vars": [ + "warn", + { + "vars": "all", + "varsIgnorePattern": "^_", + "args": "after-used", + "argsIgnorePattern": "^_" + } + ] + } +} diff --git a/packages/twenty-client-sdk/.prettierignore b/packages/twenty-client-sdk/.prettierignore new file mode 100644 index 00000000000..562ebe0503a --- /dev/null +++ b/packages/twenty-client-sdk/.prettierignore @@ -0,0 +1,2 @@ +dist +generated diff --git a/packages/twenty-client-sdk/package.json b/packages/twenty-client-sdk/package.json new file mode 100644 index 00000000000..4bad290a9ab --- /dev/null +++ b/packages/twenty-client-sdk/package.json @@ -0,0 +1,60 @@ +{ + "name": "twenty-client-sdk", + "version": "0.7.0-canary.0", + "sideEffects": false, + "license": "AGPL-3.0", + "scripts": { + "build": "npx rimraf dist && npx vite build && tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist" + }, + "exports": { + "./core": { + "types": "./dist/core/index.d.ts", + "import": "./dist/core.mjs", + "require": "./dist/core.cjs" + }, + "./metadata": { + "types": "./dist/metadata/index.d.ts", + "import": "./dist/metadata.mjs", + "require": "./dist/metadata.cjs" + }, + "./generate": { + "types": "./dist/generate/index.d.ts", + "import": "./dist/generate.mjs", + "require": "./dist/generate.cjs" + } + }, + "typesVersions": { + "*": { + "core": [ + "dist/core/index.d.ts" + ], + "metadata": [ + "dist/metadata/index.d.ts" + ], + "generate": [ + "dist/generate/index.d.ts" + ] + } + }, + "files": [ + "dist" + ], + "dependencies": { + "@genql/cli": "^3.0.3", + "@genql/runtime": "^2.10.0", + "esbuild": "^0.25.0", + "graphql": "^16.8.1" + }, + "devDependencies": { + "twenty-shared": "workspace:*", + "typescript": "^5.9.2", + "vite": "^7.0.0", + "vite-plugin-dts": "^4.5.4", + "vite-tsconfig-paths": "^4.2.1", + "vitest": "^4.0.18" + }, + "engines": { + "node": "^24.5.0", + "yarn": "^4.0.2" + } +} diff --git a/packages/twenty-client-sdk/project.json b/packages/twenty-client-sdk/project.json new file mode 100644 index 00000000000..93498eae204 --- /dev/null +++ b/packages/twenty-client-sdk/project.json @@ -0,0 +1,44 @@ +{ + "name": "twenty-client-sdk", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/twenty-client-sdk/src", + "projectType": "library", + "tags": ["scope:sdk"], + "targets": { + "build": { + "executor": "nx:run-commands", + "cache": true, + "inputs": ["production", "^production"], + "dependsOn": ["^build"], + "outputs": ["{projectRoot}/dist"], + "options": { + "cwd": "{projectRoot}", + "commands": [ + "npx rimraf dist && npx vite build", + "tsgo -p tsconfig.lib.json --declaration --emitDeclarationOnly --noEmit false --outDir dist --rootDir src && npx tsc-alias -p tsconfig.lib.json --outDir dist" + ], + "parallel": false + } + }, + "generate-metadata-client": { + "executor": "nx:run-commands", + "cache": false, + "dependsOn": ["^build"], + "outputs": ["{projectRoot}/src/metadata/generated"], + "options": { + "cwd": "packages/twenty-client-sdk", + "command": "tsx scripts/generate-metadata-client.ts" + } + }, + "test": { + "executor": "@nx/vitest:test", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "config": "{projectRoot}/vitest.config.ts" + } + }, + "set-local-version": {}, + "typecheck": {}, + "lint": {} + } +} diff --git a/packages/twenty-client-sdk/scripts/generate-metadata-client.ts b/packages/twenty-client-sdk/scripts/generate-metadata-client.ts new file mode 100644 index 00000000000..dd32c773cca --- /dev/null +++ b/packages/twenty-client-sdk/scripts/generate-metadata-client.ts @@ -0,0 +1,65 @@ +import { readFile } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +import { getIntrospectionQuery, buildClientSchema, printSchema } from 'graphql'; + +import { generateMetadataClient } from '../src/generate/generate-metadata-client'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +const TEMPLATE_PATH = path.resolve( + __dirname, + '..', + 'src', + 'generate', + 'twenty-client-template.ts', +); + +const introspectSchema = async (url: string): Promise => { + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ query: getIntrospectionQuery() }), + }); + + const json = await response.json(); + + if (json.errors) { + throw new Error( + `GraphQL introspection errors: ${JSON.stringify(json.errors)}`, + ); + } + + return printSchema(buildClientSchema(json.data)); +}; + +const main = async () => { + const serverUrl = process.env.TWENTY_API_URL ?? 'http://localhost:3000'; + + const schema = await introspectSchema(`${serverUrl}/metadata`); + + const clientWrapperTemplateSource = await readFile(TEMPLATE_PATH, 'utf-8'); + + const outputPath = path.resolve( + __dirname, + '..', + 'src', + 'metadata', + 'generated', + ); + + await generateMetadataClient({ + schema, + outputPath, + clientWrapperTemplateSource, + }); + + console.log(`Metadata client generated at ${outputPath}`); +}; + +main().catch((error) => { + console.error('Failed to generate metadata client:', error); + process.exit(1); +}); diff --git a/packages/twenty-client-sdk/src/core/generated/index.ts b/packages/twenty-client-sdk/src/core/generated/index.ts new file mode 100644 index 00000000000..c93d2f984ab --- /dev/null +++ b/packages/twenty-client-sdk/src/core/generated/index.ts @@ -0,0 +1,10 @@ +// Stub — replaced at runtime by the generated client when the app +// is installed on a Twenty instance or during `twenty app:dev`. +export class CoreApiClient { + constructor() { + throw new Error( + 'CoreApiClient was not generated. ' + + 'Install this app on a Twenty instance or run `twenty app:dev`.', + ); + } +} diff --git a/packages/twenty-sdk/src/clients/generated/core/schema.ts b/packages/twenty-client-sdk/src/core/generated/schema.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/core/schema.ts rename to packages/twenty-client-sdk/src/core/generated/schema.ts diff --git a/packages/twenty-client-sdk/src/core/index.ts b/packages/twenty-client-sdk/src/core/index.ts new file mode 100644 index 00000000000..ed87e42b198 --- /dev/null +++ b/packages/twenty-client-sdk/src/core/index.ts @@ -0,0 +1,2 @@ +export { CoreApiClient } from './generated/index'; +export * as CoreSchema from './generated/schema'; diff --git a/packages/twenty-sdk/src/cli/utilities/client/__tests__/clientServiceGeneratedClientAuth.test.ts b/packages/twenty-client-sdk/src/generate/__tests__/client-wrapper-auth.test.ts similarity index 88% rename from packages/twenty-sdk/src/cli/utilities/client/__tests__/clientServiceGeneratedClientAuth.test.ts rename to packages/twenty-client-sdk/src/generate/__tests__/client-wrapper-auth.test.ts index 9bf73875e0c..d85ce69b2c0 100644 --- a/packages/twenty-sdk/src/cli/utilities/client/__tests__/clientServiceGeneratedClientAuth.test.ts +++ b/packages/twenty-client-sdk/src/generate/__tests__/client-wrapper-auth.test.ts @@ -1,8 +1,10 @@ -import { transform } from 'esbuild'; -import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; +import { readFileSync } from 'node:fs'; +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { pathToFileURL } from 'node:url'; + +import { transform } from 'esbuild'; import { afterAll, beforeAll, @@ -13,17 +15,12 @@ import { vi, } from 'vitest'; -vi.mock('@/cli/constants/clients-dir', () => ({ - CLIENTS_GENERATED_DIR: 'src/clients/generated', -})); +import { buildClientWrapperSource } from '../client-wrapper'; -vi.mock('twenty-shared/application', () => ({ - DEFAULT_APP_ACCESS_TOKEN_NAME: 'TWENTY_APP_ACCESS_TOKEN', - DEFAULT_API_KEY_NAME: 'TWENTY_API_KEY', - DEFAULT_API_URL_NAME: 'TWENTY_API_URL', -})); - -import { ClientService } from '@/cli/utilities/client/client-service'; +const twentyClientTemplateSource = readFileSync( + join(__dirname, '..', 'twenty-client-template.ts'), + 'utf-8', +); type TwentyClassType = new (options?: { url?: string; @@ -110,59 +107,33 @@ const getAuthorizationHeaderValue = (requestInit: RequestInit | undefined) => { return new Headers(requestInit?.headers).get('Authorization'); }; -describe('ClientService generated Twenty auth behavior', () => { - let temporaryGeneratedClientDirectory: string; +describe('Generated client wrapper auth behavior', () => { + let temporaryDir: string; let TwentyClass: TwentyClassType; beforeAll(async () => { - temporaryGeneratedClientDirectory = await mkdtemp( - join(tmpdir(), 'twenty-generated-client-'), - ); + temporaryDir = await mkdtemp(join(tmpdir(), 'twenty-generated-client-')); - const temporaryGeneratedIndexTsPath = join( - temporaryGeneratedClientDirectory, - 'index.ts', - ); - - await writeFile(temporaryGeneratedIndexTsPath, stubGeneratedIndexSource); - - const clientService = new ClientService(); - await ( - clientService as unknown as { - injectClientWrapper: ( - output: string, - options: { - apiClientName: string; - defaultUrl: string; - includeUploadFile: boolean; - }, - ) => Promise; - } - ).injectClientWrapper(temporaryGeneratedClientDirectory, { + const wrapperSource = buildClientWrapperSource(twentyClientTemplateSource, { apiClientName: 'MetadataApiClient', defaultUrl: '`${process.env.TWENTY_API_URL}/metadata`', includeUploadFile: true, }); - const generatedIndexContent = await readFile( - temporaryGeneratedIndexTsPath, - 'utf-8', - ); + const fullSource = stubGeneratedIndexSource + wrapperSource; - const transpiledModule = await transform(generatedIndexContent, { + const transpiledModule = await transform(fullSource, { loader: 'ts', format: 'esm', target: 'es2022', }); - const temporaryGeneratedIndexMjsPath = join( - temporaryGeneratedClientDirectory, - 'index.mjs', - ); - await writeFile(temporaryGeneratedIndexMjsPath, transpiledModule.code); + const outputPath = join(temporaryDir, 'index.mjs'); + + await writeFile(outputPath, transpiledModule.code); const generatedModule = await import( - `${pathToFileURL(temporaryGeneratedIndexMjsPath).href}?t=${Date.now()}` + `${pathToFileURL(outputPath).href}?t=${Date.now()}` ); TwentyClass = generatedModule.MetadataApiClient as TwentyClassType; @@ -176,11 +147,8 @@ describe('ClientService generated Twenty auth behavior', () => { }); afterAll(async () => { - if (temporaryGeneratedClientDirectory) { - await rm(temporaryGeneratedClientDirectory, { - recursive: true, - force: true, - }); + if (temporaryDir) { + await rm(temporaryDir, { recursive: true, force: true }); } }); @@ -303,6 +271,7 @@ describe('ClientService generated Twenty auth behavior', () => { .fn<() => Promise>() .mockImplementation(async () => { await Promise.resolve(); + return 'fresh-token'; }); diff --git a/packages/twenty-client-sdk/src/generate/client-wrapper.ts b/packages/twenty-client-sdk/src/generate/client-wrapper.ts new file mode 100644 index 00000000000..232f8587cb4 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/client-wrapper.ts @@ -0,0 +1,51 @@ +type ClientWrapperOptions = { + apiClientName: string; + defaultUrl: string; + includeUploadFile: boolean; +}; + +const STRIPPED_TYPES_START = '// __STRIPPED_DURING_INJECTION_START__'; +const STRIPPED_TYPES_END = '// __STRIPPED_DURING_INJECTION_END__'; +const UPLOAD_FILE_START = '// __UPLOAD_FILE_START__'; +const UPLOAD_FILE_END = '// __UPLOAD_FILE_END__'; + +const escapeRegExp = (value: string): string => + value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + +export const buildClientWrapperSource = ( + templateSource: string, + options: ClientWrapperOptions, +): string => { + let source = templateSource; + + source = source.replace( + new RegExp( + `${escapeRegExp(STRIPPED_TYPES_START)}[\\s\\S]*?${escapeRegExp(STRIPPED_TYPES_END)}\\n?`, + ), + '', + ); + + source = source.replace("'__TWENTY_DEFAULT_URL__'", options.defaultUrl); + + source = source.replace(/TwentyGeneratedClient/g, options.apiClientName); + + if (!options.includeUploadFile) { + source = source.replace( + new RegExp( + `\\s*${escapeRegExp(UPLOAD_FILE_START)}[\\s\\S]*?${escapeRegExp(UPLOAD_FILE_END)}\\n?`, + ), + '\n', + ); + } else { + source = source.replace( + new RegExp(`\\s*${escapeRegExp(UPLOAD_FILE_START)}\\n`), + '\n', + ); + source = source.replace( + new RegExp(`\\s*${escapeRegExp(UPLOAD_FILE_END)}\\n`), + '\n', + ); + } + + return `\n// ${options.apiClientName} (auto-injected by twenty-client-sdk)\n${source}`; +}; diff --git a/packages/twenty-client-sdk/src/generate/fs-utils.ts b/packages/twenty-client-sdk/src/generate/fs-utils.ts new file mode 100644 index 00000000000..150c5c10ec1 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/fs-utils.ts @@ -0,0 +1,41 @@ +import { cp, mkdir, readdir, rename as fsRename, rm } from 'node:fs/promises'; +import { join } from 'node:path'; + +export const ensureDir = (dirPath: string) => + mkdir(dirPath, { recursive: true }); + +export const emptyDir = async (dirPath: string): Promise => { + let entries: string[]; + + try { + entries = await readdir(dirPath); + } catch (error: unknown) { + if (error instanceof Error && 'code' in error && error.code === 'ENOENT') { + await mkdir(dirPath, { recursive: true }); + return; + } + throw error; + } + + await Promise.all( + entries.map((entry) => + rm(join(dirPath, entry), { recursive: true, force: true }), + ), + ); +}; + +export const move = async (src: string, dest: string): Promise => { + try { + await fsRename(src, dest); + } catch (error: unknown) { + if (error instanceof Error && 'code' in error && error.code === 'EXDEV') { + await cp(src, dest, { recursive: true }); + await rm(src, { recursive: true, force: true }); + } else { + throw error; + } + } +}; + +export const remove = (filePath: string) => + rm(filePath, { recursive: true, force: true }); diff --git a/packages/twenty-client-sdk/src/generate/generate-core-client.ts b/packages/twenty-client-sdk/src/generate/generate-core-client.ts new file mode 100644 index 00000000000..c2d46e2c24c --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/generate-core-client.ts @@ -0,0 +1,122 @@ +import { appendFile, copyFile, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { generate } from '@genql/cli'; +import { build } from 'esbuild'; +import { DEFAULT_API_URL_NAME } from 'twenty-shared/application'; + +import { buildClientWrapperSource } from './client-wrapper'; +import { emptyDir, ensureDir, move, remove } from './fs-utils'; +import twentyClientTemplateSource from './twenty-client-template.ts?raw'; + +const COMMON_SCALAR_TYPES = { + DateTime: 'string', + JSON: 'Record', + UUID: 'string', +}; + +export const GENERATED_CORE_DIR = 'core/generated'; + +// Generates the core API client from a GraphQL schema string. +// Produces both TypeScript source and compiled ESM/CJS bundles. +export const generateCoreClientFromSchema = async ({ + schema, + outputPath, + clientWrapperTemplateSource, +}: { + schema: string; + outputPath: string; + clientWrapperTemplateSource?: string; +}): Promise => { + const templateSource = + clientWrapperTemplateSource ?? twentyClientTemplateSource; + const tempPath = `${outputPath}.tmp`; + + await ensureDir(tempPath); + await emptyDir(tempPath); + + try { + await generate({ + schema, + output: tempPath, + scalarTypes: COMMON_SCALAR_TYPES, + }); + + const clientContent = buildClientWrapperSource(templateSource, { + apiClientName: 'CoreApiClient', + defaultUrl: `\`\${process.env.${DEFAULT_API_URL_NAME}}/graphql\``, + includeUploadFile: true, + }); + + await appendFile(join(tempPath, 'index.ts'), clientContent); + + await remove(outputPath); + await move(tempPath, outputPath); + + await compileGeneratedClient(outputPath); + } catch (error) { + await remove(tempPath); + throw error; + } +}; + +// Generates the core client and replaces the pre-built stub inside +// an installed twenty-client-sdk package (dist/core.mjs and dist/core.cjs). +// Generated source files are kept in dist/generated-core/ for consumers +// that need the raw .ts files (e.g. the app:dev upload step). +export const replaceCoreClient = async ({ + packageRoot, + schema, +}: { + packageRoot: string; + schema: string; +}): Promise => { + const generatedPath = join(packageRoot, 'dist', GENERATED_CORE_DIR); + + await generateCoreClientFromSchema({ schema, outputPath: generatedPath }); + + await copyFile( + join(generatedPath, 'index.mjs'), + join(packageRoot, 'dist', 'core.mjs'), + ); + await copyFile( + join(generatedPath, 'index.cjs'), + join(packageRoot, 'dist', 'core.cjs'), + ); +}; + +const compileGeneratedClient = async (generatedDir: string): Promise => { + const entryPoint = join(generatedDir, 'index.ts'); + const outfile = join(generatedDir, 'index.mjs'); + + await build({ + entryPoints: [entryPoint], + outfile, + bundle: true, + format: 'esm', + platform: 'node', + target: 'node18', + sourcemap: false, + minify: false, + }); + + await build({ + entryPoints: [entryPoint], + outfile: join(generatedDir, 'index.cjs'), + bundle: true, + format: 'cjs', + platform: 'node', + target: 'node18', + sourcemap: false, + minify: false, + }); + + await writeFile( + join(generatedDir, 'package.json'), + JSON.stringify( + { type: 'module', main: 'index.mjs', module: 'index.mjs' }, + null, + 2, + ), + ); +}; diff --git a/packages/twenty-client-sdk/src/generate/generate-metadata-client.ts b/packages/twenty-client-sdk/src/generate/generate-metadata-client.ts new file mode 100644 index 00000000000..9e3d0de3f82 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/generate-metadata-client.ts @@ -0,0 +1,48 @@ +import { appendFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +import { generate } from '@genql/cli'; +import { DEFAULT_API_URL_NAME } from 'twenty-shared/application'; + +import { buildClientWrapperSource } from './client-wrapper'; +import { emptyDir, ensureDir } from './fs-utils'; +import twentyClientTemplateSource from './twenty-client-template.ts?raw'; + +const COMMON_SCALAR_TYPES = { + DateTime: 'string', + JSON: 'Record', + UUID: 'string', +}; + +export const generateMetadataClient = async ({ + schema, + outputPath, + clientWrapperTemplateSource, +}: { + schema: string; + outputPath: string; + clientWrapperTemplateSource?: string; +}): Promise => { + const templateSource = + clientWrapperTemplateSource ?? twentyClientTemplateSource; + + await ensureDir(outputPath); + await emptyDir(outputPath); + + await generate({ + schema, + output: outputPath, + scalarTypes: { + ...COMMON_SCALAR_TYPES, + Upload: 'File', + }, + }); + + const clientContent = buildClientWrapperSource(templateSource, { + apiClientName: 'MetadataApiClient', + defaultUrl: `\`\${process.env.${DEFAULT_API_URL_NAME}}/metadata\``, + includeUploadFile: true, + }); + + await appendFile(join(outputPath, 'index.ts'), clientContent); +}; diff --git a/packages/twenty-client-sdk/src/generate/index.ts b/packages/twenty-client-sdk/src/generate/index.ts new file mode 100644 index 00000000000..86490f44199 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/index.ts @@ -0,0 +1,6 @@ +export { + GENERATED_CORE_DIR, + generateCoreClientFromSchema, + replaceCoreClient, +} from './generate-core-client'; +export { generateMetadataClient } from './generate-metadata-client'; diff --git a/packages/twenty-client-sdk/src/generate/raw-imports.d.ts b/packages/twenty-client-sdk/src/generate/raw-imports.d.ts new file mode 100644 index 00000000000..e13e7701299 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/raw-imports.d.ts @@ -0,0 +1,4 @@ +declare module '*.ts?raw' { + const content: string; + export default content; +} diff --git a/packages/twenty-client-sdk/src/generate/twenty-client-template.ts b/packages/twenty-client-sdk/src/generate/twenty-client-template.ts new file mode 100644 index 00000000000..936157d9775 --- /dev/null +++ b/packages/twenty-client-sdk/src/generate/twenty-client-template.ts @@ -0,0 +1,434 @@ +// Ambient type stubs for the genql-generated code this template gets +// injected into. They enable full typecheck/lint on this file. +// __STRIPPED_DURING_INJECTION_START__ +type QueryGenqlSelection = Record; +type MutationGenqlSelection = Record; +type GraphqlOperation = Record; + +type ClientOptions = { + url?: string; + headers?: HeadersInit | (() => HeadersInit | Promise); + fetcher?: ( + operation: GraphqlOperation | GraphqlOperation[], + ) => Promise; + fetch?: typeof globalThis.fetch; + batch?: unknown; +}; + +type Client = { + query: ( + request: QueryGenqlSelection & { __name?: string }, + ) => Promise; + mutation: ( + request: MutationGenqlSelection & { __name?: string }, + ) => Promise; +}; + +declare function createClient(options: ClientOptions): Client; + +declare class GenqlError extends Error { + constructor(errors: unknown, data: unknown); +} +// __STRIPPED_DURING_INJECTION_END__ + +const APP_ACCESS_TOKEN_ENV_KEY = 'TWENTY_APP_ACCESS_TOKEN'; +const API_KEY_ENV_KEY = 'TWENTY_API_KEY'; + +type TwentyGeneratedClientOptions = ClientOptions; + +type ProcessEnvironment = Record; + +type GraphqlErrorPayloadEntry = { + message?: string; + extensions?: { code?: string }; +}; + +type GraphqlResponsePayload = { + data?: Record; + errors?: GraphqlErrorPayloadEntry[]; +}; + +type GraphqlResponse = { + status: number; + statusText: string; + payload: GraphqlResponsePayload | null; + rawBody: string; +}; + +const getProcessEnvironment = (): ProcessEnvironment => { + const processObject = ( + globalThis as { process?: { env?: ProcessEnvironment } } + ).process; + + return processObject?.env ?? {}; +}; + +const getTokenFromAuthorizationHeader = ( + authorizationHeader: string | undefined, +): string | null => { + if (typeof authorizationHeader !== 'string') { + return null; + } + + const trimmedAuthorizationHeader = authorizationHeader.trim(); + + if (trimmedAuthorizationHeader.length === 0) { + return null; + } + + if (trimmedAuthorizationHeader === 'Bearer') { + return null; + } + + if (trimmedAuthorizationHeader.startsWith('Bearer ')) { + return trimmedAuthorizationHeader.slice('Bearer '.length).trim(); + } + + return trimmedAuthorizationHeader; +}; + +const getTokenFromHeaders = ( + headers: HeadersInit | undefined, +): string | null => { + if (!headers) { + return null; + } + + if (headers instanceof Headers) { + return getTokenFromAuthorizationHeader( + headers.get('Authorization') ?? undefined, + ); + } + + if (Array.isArray(headers)) { + const matchedAuthorizationHeader = headers.find( + ([headerName]) => headerName.toLowerCase() === 'authorization', + ); + + return getTokenFromAuthorizationHeader(matchedAuthorizationHeader?.[1]); + } + + const headersRecord = headers as Record; + + return getTokenFromAuthorizationHeader( + headersRecord.Authorization ?? headersRecord.authorization, + ); +}; + +const hasAuthenticationErrorInGraphqlPayload = ( + payload: GraphqlResponsePayload | null, +): boolean => { + if (!payload?.errors) { + return false; + } + + return payload.errors.some((graphqlError) => { + return ( + graphqlError.extensions?.code === 'UNAUTHENTICATED' || + graphqlError.message?.toLowerCase() === 'unauthorized' + ); + }); +}; + +const defaultOptions: TwentyGeneratedClientOptions = { + url: '__TWENTY_DEFAULT_URL__', + headers: { + 'Content-Type': 'application/json', + }, +}; + +export class TwentyGeneratedClient { + private client: Client; + private url: string; + private requestOptions: RequestInit; + private headers: HeadersInit | (() => HeadersInit | Promise); + private fetchImplementation: typeof globalThis.fetch | null; + private authorizationToken: string | null; + private refreshAccessTokenPromise: Promise | null = null; + + constructor(options?: TwentyGeneratedClientOptions) { + const merged: TwentyGeneratedClientOptions = { + ...defaultOptions, + ...options, + }; + + const { + url, + headers, + fetch: customFetchImplementation, + fetcher: _fetcher, + batch: _batch, + ...requestOptions + } = merged; + + this.url = url ?? ''; + this.requestOptions = requestOptions; + this.headers = headers ?? {}; + this.fetchImplementation = + customFetchImplementation ?? globalThis.fetch ?? null; + + const processEnvironment = getProcessEnvironment(); + const tokenFromHeaders = getTokenFromHeaders( + typeof headers === 'function' ? undefined : headers, + ); + + // Priority: explicit header > app access token > api key (legacy). + this.authorizationToken = + tokenFromHeaders ?? + processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] ?? + processEnvironment[API_KEY_ENV_KEY] ?? + null; + + this.client = createClient({ + ...merged, + headers: undefined, + fetcher: async (operation) => + this.executeGraphqlRequestWithOptionalRefresh({ + operation, + }), + }); + } + + query(request: R & { __name?: string }) { + return this.client.query(request); + } + + mutation(request: R & { __name?: string }) { + return this.client.mutation(request); + } + + // __UPLOAD_FILE_START__ + async uploadFile( + fileBuffer: Buffer, + filename: string, + contentType: string = 'application/octet-stream', + fieldMetadataUniversalIdentifier: string, + ): Promise<{ + id: string; + path: string; + size: number; + createdAt: string; + url: string; + }> { + const form = new FormData(); + + form.append( + 'operations', + JSON.stringify({ + query: `mutation UploadFilesFieldFileByUniversalIdentifier($file: Upload!, $fieldMetadataUniversalIdentifier: String!) { + uploadFilesFieldFileByUniversalIdentifier(file: $file, fieldMetadataUniversalIdentifier: $fieldMetadataUniversalIdentifier) { id path size createdAt url } + }`, + variables: { + file: null, + fieldMetadataUniversalIdentifier, + }, + }), + ); + form.append('map', JSON.stringify({ '0': ['variables.file'] })); + form.append( + '0', + new Blob([fileBuffer as BlobPart], { type: contentType }), + filename, + ); + + const result = await this.executeGraphqlRequestWithOptionalRefresh({ + operation: form, + headers: {}, + requestInit: { + method: 'POST', + }, + }); + + if (result.errors) { + throw new GenqlError(result.errors, result.data); + } + + const data = result.data as Record; + + return data.uploadFilesFieldFileByUniversalIdentifier as { + id: string; + path: string; + size: number; + createdAt: string; + url: string; + }; + } + // __UPLOAD_FILE_END__ + + private async executeGraphqlRequestWithOptionalRefresh({ + operation, + headers, + requestInit, + }: { + operation: GraphqlOperation | GraphqlOperation[] | FormData; + headers?: HeadersInit; + requestInit?: RequestInit; + }) { + const firstResponse = await this.executeGraphqlRequest({ + operation, + headers, + requestInit, + token: this.authorizationToken, + }); + + if (this.shouldRefreshToken(firstResponse)) { + const refreshedAccessToken = await this.requestRefreshedAccessToken(); + + if (refreshedAccessToken) { + const retryResponse = await this.executeGraphqlRequest({ + operation, + headers, + requestInit, + token: refreshedAccessToken, + }); + + return this.assertResponseIsSuccessful(retryResponse); + } + } + + return this.assertResponseIsSuccessful(firstResponse); + } + + private async executeGraphqlRequest({ + operation, + headers, + requestInit, + token, + }: { + operation: GraphqlOperation | GraphqlOperation[] | FormData; + headers?: HeadersInit; + requestInit?: RequestInit; + token: string | null; + }): Promise { + if (!this.fetchImplementation) { + throw new Error( + 'Global `fetch` function is not available, ' + + 'pass a fetch implementation to the Twenty client', + ); + } + + const resolvedHeaders = await this.resolveHeaders(); + const requestHeaders = new Headers(resolvedHeaders); + + if (headers) { + new Headers(headers).forEach((value, key) => + requestHeaders.set(key, value), + ); + } + + if (operation instanceof FormData) { + requestHeaders.delete('Content-Type'); + } else { + requestHeaders.set('Content-Type', 'application/json'); + } + + if (token) { + requestHeaders.set('Authorization', `Bearer ${token}`); + } else { + requestHeaders.delete('Authorization'); + } + + const response = await this.fetchImplementation.call(globalThis, this.url, { + ...this.requestOptions, + ...requestInit, + method: requestInit?.method ?? 'POST', + headers: requestHeaders, + body: + operation instanceof FormData ? operation : JSON.stringify(operation), + }); + + const rawBody = await response.text(); + let payload: GraphqlResponsePayload | null = null; + + if (rawBody.trim().length > 0) { + try { + payload = JSON.parse(rawBody) as GraphqlResponsePayload; + } catch { + payload = null; + } + } + + return { + status: response.status, + statusText: response.statusText, + payload, + rawBody, + }; + } + + private async resolveHeaders(): Promise { + if (typeof this.headers === 'function') { + return (await this.headers()) ?? {}; + } + + return this.headers ?? {}; + } + + private shouldRefreshToken(response: GraphqlResponse): boolean { + if (response.status === 401) { + return true; + } + + return hasAuthenticationErrorInGraphqlPayload(response.payload); + } + + private assertResponseIsSuccessful(response: GraphqlResponse) { + if (response.status < 200 || response.status >= 300) { + throw new Error(`${response.statusText}: ${response.rawBody}`); + } + + if (response.payload === null) { + throw new Error('Invalid JSON response'); + } + + return response.payload; + } + + private async requestRefreshedAccessToken(): Promise { + const refreshAccessTokenFunction = ( + globalThis as { + frontComponentHostCommunicationApi?: { + requestAccessTokenRefresh?: () => Promise; + }; + } + ).frontComponentHostCommunicationApi?.requestAccessTokenRefresh; + + if (typeof refreshAccessTokenFunction !== 'function') { + return null; + } + + if (!this.refreshAccessTokenPromise) { + this.refreshAccessTokenPromise = refreshAccessTokenFunction() + .then((refreshedAccessToken) => { + if ( + typeof refreshedAccessToken !== 'string' || + refreshedAccessToken.length === 0 + ) { + return null; + } + + this.setAuthorizationToken(refreshedAccessToken); + + return refreshedAccessToken; + }) + .catch((refreshError: unknown) => { + console.error('Twenty client: token refresh failed', refreshError); + + return null; + }) + .finally(() => { + this.refreshAccessTokenPromise = null; + }); + } + + return this.refreshAccessTokenPromise; + } + + private setAuthorizationToken(token: string) { + this.authorizationToken = token; + + const processEnvironment = getProcessEnvironment(); + + processEnvironment[APP_ACCESS_TOKEN_ENV_KEY] = token; + } +} diff --git a/packages/twenty-sdk/src/clients/generated/metadata/index.ts b/packages/twenty-client-sdk/src/metadata/generated/index.ts similarity index 99% rename from packages/twenty-sdk/src/clients/generated/metadata/index.ts rename to packages/twenty-client-sdk/src/metadata/generated/index.ts index 52c63ce6903..695fccc606b 100644 --- a/packages/twenty-sdk/src/clients/generated/metadata/index.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/index.ts @@ -78,7 +78,7 @@ export const generateSubscriptionOp: ( ) } -// MetadataApiClient (auto-injected by twenty-sdk) +// MetadataApiClient (auto-injected by twenty-client-sdk) // Ambient type stubs for the genql-generated code this template gets // injected into. They enable full typecheck/lint on this file. diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/batcher.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/batcher.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/batcher.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/batcher.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/createClient.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/createClient.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/createClient.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/createClient.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/error.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/error.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/error.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/error.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/fetcher.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/fetcher.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/fetcher.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/fetcher.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/generateGraphqlOperation.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/generateGraphqlOperation.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/generateGraphqlOperation.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/generateGraphqlOperation.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/index.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/index.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/index.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/index.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/linkTypeMap.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/linkTypeMap.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/linkTypeMap.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/linkTypeMap.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/typeSelection.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/typeSelection.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/typeSelection.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/typeSelection.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/runtime/types.ts b/packages/twenty-client-sdk/src/metadata/generated/runtime/types.ts similarity index 100% rename from packages/twenty-sdk/src/clients/generated/metadata/runtime/types.ts rename to packages/twenty-client-sdk/src/metadata/generated/runtime/types.ts diff --git a/packages/twenty-sdk/src/clients/generated/metadata/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql similarity index 99% rename from packages/twenty-sdk/src/clients/generated/metadata/schema.graphql rename to packages/twenty-client-sdk/src/metadata/generated/schema.graphql index 49608a7fa1a..21714aafe02 100644 --- a/packages/twenty-sdk/src/clients/generated/metadata/schema.graphql +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql @@ -1458,431 +1458,6 @@ type SendInvitations { result: [WorkspaceInvitation!]! } -type ResendEmailVerificationToken { - success: Boolean! -} - -type WorkspaceUrls { - customUrl: String - subdomainUrl: String! -} - -type SSOConnection { - type: IdentityProviderType! - id: UUID! - issuer: String! - name: String! - status: SSOIdentityProviderStatus! -} - -enum IdentityProviderType { - OIDC - SAML -} - -enum SSOIdentityProviderStatus { - Active - Inactive - Error -} - -type AvailableWorkspace { - id: UUID! - displayName: String - loginToken: String - personalInviteToken: String - inviteHash: String - workspaceUrls: WorkspaceUrls! - logo: String - sso: [SSOConnection!]! -} - -type AvailableWorkspaces { - availableWorkspacesForSignIn: [AvailableWorkspace!]! - availableWorkspacesForSignUp: [AvailableWorkspace!]! -} - -type DeletedWorkspaceMember { - id: UUID! - name: FullName! - userEmail: String! - avatarUrl: String - userWorkspaceId: UUID -} - -type BillingEntitlement { - key: BillingEntitlementKey! - value: Boolean! -} - -enum BillingEntitlementKey { - SSO - CUSTOM_DOMAIN - RLS - AUDIT_LOGS -} - -type DomainRecord { - validationType: String! - type: String! - status: String! - key: String! - value: String! -} - -type DomainValidRecords { - id: UUID! - domain: String! - records: [DomainRecord!]! -} - -type FeatureFlag { - key: FeatureFlagKey! - value: Boolean! -} - -enum FeatureFlagKey { - IS_UNIQUE_INDEXES_ENABLED - IS_JSON_FILTER_ENABLED - IS_AI_ENABLED - IS_APPLICATION_ENABLED - IS_MARKETPLACE_ENABLED - IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED - IS_PUBLIC_DOMAIN_ENABLED - IS_EMAILING_DOMAIN_ENABLED - IS_DASHBOARD_V2_ENABLED - IS_ATTACHMENT_MIGRATED - IS_NOTE_TARGET_MIGRATED - IS_TASK_TARGET_MIGRATED - IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED - IS_JUNCTION_RELATIONS_ENABLED - IS_COMMAND_MENU_ITEM_ENABLED - IS_NAVIGATION_MENU_ITEM_ENABLED - IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED - IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED - IS_DRAFT_EMAIL_ENABLED - IS_USAGE_ANALYTICS_ENABLED - IS_RICH_TEXT_V1_MIGRATED - IS_DIRECT_GRAPHQL_EXECUTION_ENABLED - IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED - IS_CONNECTED_ACCOUNT_MIGRATED - IS_GRAPHQL_QUERY_TIMING_ENABLED -} - -type SSOIdentityProvider { - id: UUID! - name: String! - type: IdentityProviderType! - status: SSOIdentityProviderStatus! - issuer: String! -} - -type AuthProviders { - sso: [SSOIdentityProvider!]! - google: Boolean! - magicLink: Boolean! - password: Boolean! - microsoft: Boolean! -} - -type AuthBypassProviders { - google: Boolean! - password: Boolean! - microsoft: Boolean! -} - -type PublicWorkspaceData { - id: UUID! - authProviders: AuthProviders! - authBypassProviders: AuthBypassProviders - logo: String - displayName: String - workspaceUrls: WorkspaceUrls! -} - -type IndexEdge { - """The node containing the Index""" - node: Index! - - """Cursor for this node.""" - cursor: ConnectionCursor! -} - -type PageInfo { - """true if paging forward and there are more records.""" - hasNextPage: Boolean - - """true if paging backwards and there are more records.""" - hasPreviousPage: Boolean - - """The cursor of the first returned record.""" - startCursor: ConnectionCursor - - """The cursor of the last returned record.""" - endCursor: ConnectionCursor -} - -type IndexConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [IndexEdge!]! -} - -type IndexFieldEdge { - """The node containing the IndexField""" - node: IndexField! - - """Cursor for this node.""" - cursor: ConnectionCursor! -} - -type IndexIndexFieldMetadatasConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [IndexFieldEdge!]! -} - -type ObjectEdge { - """The node containing the Object""" - node: Object! - - """Cursor for this node.""" - cursor: ConnectionCursor! -} - -type IndexObjectMetadataConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [ObjectEdge!]! -} - -type ObjectRecordCount { - objectNamePlural: String! - totalCount: Int! -} - -type ObjectConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [ObjectEdge!]! -} - -type ObjectIndexMetadatasConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [IndexEdge!]! -} - -type FieldEdge { - """The node containing the Field""" - node: Field! - - """Cursor for this node.""" - cursor: ConnectionCursor! -} - -type ObjectFieldsConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [FieldEdge!]! -} - -type UpsertRowLevelPermissionPredicatesResult { - predicates: [RowLevelPermissionPredicate!]! - predicateGroups: [RowLevelPermissionPredicateGroup!]! -} - -type VersionDistributionEntry { - version: String! - count: Int! -} - -type ApplicationRegistrationStats { - activeInstalls: Int! - mostInstalledVersion: String - versionDistribution: [VersionDistributionEntry!]! -} - -type CreateApplicationRegistration { - applicationRegistration: ApplicationRegistration! - clientSecret: String! -} - -type PublicApplicationRegistration { - id: UUID! - name: String! - logoUrl: String - websiteUrl: String - oAuthScopes: [String!]! -} - -type RotateClientSecret { - clientSecret: String! -} - -type Relation { - type: RelationType! - sourceObjectMetadata: Object! - targetObjectMetadata: Object! - sourceFieldMetadata: Field! - targetFieldMetadata: Field! -} - -"""Relation type""" -enum RelationType { - ONE_TO_MANY - MANY_TO_ONE -} - -type FieldConnection { - """Paging information""" - pageInfo: PageInfo! - - """Array of edges.""" - edges: [FieldEdge!]! -} - -type DeleteSso { - identityProviderId: UUID! -} - -type EditSso { - id: UUID! - type: IdentityProviderType! - issuer: String! - name: String! - status: SSOIdentityProviderStatus! -} - -type WorkspaceNameAndId { - displayName: String - id: UUID! -} - -type FindAvailableSSOIDP { - type: IdentityProviderType! - id: UUID! - issuer: String! - name: String! - status: SSOIdentityProviderStatus! - workspace: WorkspaceNameAndId! -} - -type SetupSso { - id: UUID! - type: IdentityProviderType! - issuer: String! - name: String! - status: SSOIdentityProviderStatus! -} - -type DeleteTwoFactorAuthenticationMethod { - """Boolean that confirms query was dispatched""" - success: Boolean! -} - -type InitiateTwoFactorAuthenticationProvisioning { - uri: String! -} - -type VerifyTwoFactorAuthenticationMethod { - success: Boolean! -} - -type AuthorizeApp { - redirectUrl: String! -} - -type AuthToken { - token: String! - expiresAt: DateTime! -} - -type AuthTokenPair { - accessOrWorkspaceAgnosticToken: AuthToken! - refreshToken: AuthToken! -} - -type AvailableWorkspacesAndAccessTokens { - tokens: AuthTokenPair! - availableWorkspaces: AvailableWorkspaces! -} - -type EmailPasswordResetLink { - """Boolean that confirms query was dispatched""" - success: Boolean! -} - -type GetAuthorizationUrlForSSO { - authorizationURL: String! - type: String! - id: UUID! -} - -type InvalidatePassword { - """Boolean that confirms query was dispatched""" - success: Boolean! -} - -type WorkspaceUrlsAndId { - workspaceUrls: WorkspaceUrls! - id: UUID! -} - -type SignUp { - loginToken: AuthToken! - workspace: WorkspaceUrlsAndId! -} - -type TransientToken { - transientToken: AuthToken! -} - -type ValidatePasswordResetToken { - id: UUID! - email: String! - hasPassword: Boolean! -} - -type VerifyEmailAndGetLoginToken { - loginToken: AuthToken! - workspaceUrls: WorkspaceUrls! -} - -type ApiKeyToken { - token: String! -} - -type AuthTokens { - tokens: AuthTokenPair! -} - -type LoginToken { - loginToken: AuthToken! -} - -type CheckUserExist { - exists: Boolean! - availableWorkspacesCount: Float! - isEmailVerified: Boolean! -} - -type WorkspaceInviteHashValid { - isValid: Boolean! -} - type RecordIdentifier { id: UUID! labelIdentifier: String! @@ -1992,60 +1567,819 @@ enum LogicFunctionExecutionStatus { ERROR } -type LogicFunctionLogs { - """Execution Logs""" - logs: String! +type BillingTrialPeriod { + duration: Float! + isCreditCardRequired: Boolean! } -type ToolIndexEntry { +type WorkspaceUrls { + customUrl: String + subdomainUrl: String! +} + +type SSOIdentityProvider { + id: UUID! + name: String! + type: IdentityProviderType! + status: SSOIdentityProviderStatus! + issuer: String! +} + +enum IdentityProviderType { + OIDC + SAML +} + +enum SSOIdentityProviderStatus { + Active + Inactive + Error +} + +type AuthProviders { + sso: [SSOIdentityProvider!]! + google: Boolean! + magicLink: Boolean! + password: Boolean! + microsoft: Boolean! +} + +type AuthBypassProviders { + google: Boolean! + password: Boolean! + microsoft: Boolean! +} + +type PublicWorkspaceData { + id: UUID! + authProviders: AuthProviders! + authBypassProviders: AuthBypassProviders + logo: String + displayName: String + workspaceUrls: WorkspaceUrls! +} + +type NativeModelCapabilities { + webSearch: Boolean + twitterSearch: Boolean +} + +type ClientAIModelConfig { + modelId: String! + label: String! + modelFamily: ModelFamily + modelFamilyLabel: String + sdkPackage: String + inputCostPerMillionTokensInCredits: Float! + outputCostPerMillionTokensInCredits: Float! + nativeCapabilities: NativeModelCapabilities + isDeprecated: Boolean + isRecommended: Boolean + providerName: String + dataResidency: String +} + +enum ModelFamily { + GPT + CLAUDE + GEMINI + MISTRAL + GROK +} + +type AdminAIModelConfig { + modelId: String! + label: String! + modelFamily: ModelFamily + modelFamilyLabel: String + sdkPackage: String + isAvailable: Boolean! + isAdminEnabled: Boolean! + isDeprecated: Boolean + isRecommended: Boolean + contextWindowTokens: Float + maxOutputTokens: Float + inputCostPerMillionTokens: Float + outputCostPerMillionTokens: Float + providerName: String + providerLabel: String + name: String + dataResidency: String +} + +type AdminAIModels { + models: [AdminAIModelConfig!]! + defaultSmartModelId: String + defaultFastModelId: String +} + +type Billing { + isBillingEnabled: Boolean! + billingUrl: String + trialPeriods: [BillingTrialPeriod!]! +} + +type Support { + supportDriver: SupportDriver! + supportFrontChatId: String +} + +enum SupportDriver { + NONE + FRONT +} + +type Sentry { + environment: String + release: String + dsn: String +} + +type Captcha { + provider: CaptchaDriverType + siteKey: String +} + +enum CaptchaDriverType { + GOOGLE_RECAPTCHA + TURNSTILE +} + +type ApiConfig { + mutationMaximumAffectedRecords: Float! +} + +type PublicFeatureFlagMetadata { + label: String! + description: String! + imagePath: String +} + +type PublicFeatureFlag { + key: FeatureFlagKey! + metadata: PublicFeatureFlagMetadata! +} + +enum FeatureFlagKey { + IS_UNIQUE_INDEXES_ENABLED + IS_JSON_FILTER_ENABLED + IS_AI_ENABLED + IS_APPLICATION_ENABLED + IS_MARKETPLACE_ENABLED + IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED + IS_PUBLIC_DOMAIN_ENABLED + IS_EMAILING_DOMAIN_ENABLED + IS_DASHBOARD_V2_ENABLED + IS_ATTACHMENT_MIGRATED + IS_NOTE_TARGET_MIGRATED + IS_TASK_TARGET_MIGRATED + IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED + IS_JUNCTION_RELATIONS_ENABLED + IS_COMMAND_MENU_ITEM_ENABLED + IS_NAVIGATION_MENU_ITEM_ENABLED + IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED + IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED + IS_DRAFT_EMAIL_ENABLED + IS_USAGE_ANALYTICS_ENABLED + IS_RICH_TEXT_V1_MIGRATED + IS_DIRECT_GRAPHQL_EXECUTION_ENABLED + IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED + IS_CONNECTED_ACCOUNT_MIGRATED + IS_GRAPHQL_QUERY_TIMING_ENABLED +} + +type ClientConfig { + appVersion: String + authProviders: AuthProviders! + billing: Billing! + aiModels: [ClientAIModelConfig!]! + signInPrefilled: Boolean! + isMultiWorkspaceEnabled: Boolean! + isEmailVerificationRequired: Boolean! + defaultSubdomain: String + frontDomain: String! + analyticsEnabled: Boolean! + support: Support! + isAttachmentPreviewEnabled: Boolean! + sentry: Sentry! + captcha: Captcha! + api: ApiConfig! + canManageFeatureFlags: Boolean! + publicFeatureFlags: [PublicFeatureFlag!]! + isMicrosoftMessagingEnabled: Boolean! + isMicrosoftCalendarEnabled: Boolean! + isGoogleMessagingEnabled: Boolean! + isGoogleCalendarEnabled: Boolean! + isConfigVariablesInDbEnabled: Boolean! + isImapSmtpCaldavEnabled: Boolean! + allowRequestsToTwentyIcons: Boolean! + calendarBookingPageId: String + isCloudflareIntegrationEnabled: Boolean! + isClickHouseConfigured: Boolean! +} + +type ConfigVariable { name: String! description: String! - category: String! - objectName: String - inputSchema: JSON + value: JSON + isSensitive: Boolean! + source: ConfigSource! + isEnvOnly: Boolean! + type: ConfigVariableType! + options: JSON } -type AgentMessagePart { +enum ConfigSource { + ENVIRONMENT + DATABASE + DEFAULT +} + +enum ConfigVariableType { + BOOLEAN + NUMBER + ARRAY + STRING + ENUM + JSON +} + +type ConfigVariablesGroupData { + variables: [ConfigVariable!]! + name: ConfigVariablesGroup! + description: String! + isHiddenOnLoad: Boolean! +} + +enum ConfigVariablesGroup { + SERVER_CONFIG + RATE_LIMITING + STORAGE_CONFIG + GOOGLE_AUTH + MICROSOFT_AUTH + EMAIL_SETTINGS + LOGGING + ADVANCED_SETTINGS + BILLING_CONFIG + CAPTCHA_CONFIG + CLOUDFLARE_CONFIG + LLM + LOGIC_FUNCTION_CONFIG + CODE_INTERPRETER_CONFIG + SSL + SUPPORT_CHAT_CONFIG + ANALYTICS_CONFIG + TOKENS_DURATION + AWS_SES_SETTINGS +} + +type ConfigVariables { + groups: [ConfigVariablesGroupData!]! +} + +type JobOperationResult { + jobId: String! + success: Boolean! + error: String +} + +type DeleteJobsResponse { + deletedCount: Int! + results: [JobOperationResult!]! +} + +type QueueJob { + id: String! + name: String! + data: JSON + state: JobState! + timestamp: Float + failedReason: String + processedOn: Float + finishedOn: Float + attemptsMade: Float! + returnValue: JSON + logs: [String!] + stackTrace: [String!] +} + +"""Job state in the queue""" +enum JobState { + COMPLETED + FAILED + ACTIVE + WAITING + DELAYED + PRIORITIZED + WAITING_CHILDREN +} + +type QueueRetentionConfig { + completedMaxAge: Float! + completedMaxCount: Float! + failedMaxAge: Float! + failedMaxCount: Float! +} + +type QueueJobsResponse { + jobs: [QueueJob!]! + count: Float! + totalCount: Float! + hasMore: Boolean! + retentionConfig: QueueRetentionConfig! +} + +type RetryJobsResponse { + retriedCount: Int! + results: [JobOperationResult!]! +} + +type SystemHealthService { + id: HealthIndicatorId! + label: String! + status: AdminPanelHealthServiceStatus! +} + +enum HealthIndicatorId { + database + redis + worker + connectedAccount + app +} + +enum AdminPanelHealthServiceStatus { + OPERATIONAL + OUTAGE +} + +type SystemHealth { + services: [SystemHealthService!]! +} + +type FeatureFlag { + key: FeatureFlagKey! + value: Boolean! +} + +type UserInfo { id: UUID! - messageId: UUID! - orderIndex: Int! - type: String! - textContent: String - reasoningContent: String - toolName: String - toolCallId: String - toolInput: JSON - toolOutput: JSON - state: String - errorMessage: String - errorDetails: JSON - sourceUrlSourceId: String - sourceUrlUrl: String - sourceUrlTitle: String - sourceDocumentSourceId: String - sourceDocumentMediaType: String - sourceDocumentTitle: String - sourceDocumentFilename: String - fileMediaType: String - fileFilename: String - fileId: UUID - fileUrl: String - providerMetadata: JSON - createdAt: DateTime! + email: String! + firstName: String + lastName: String } -type Skill { +type WorkspaceInfo { id: UUID! name: String! + allowImpersonation: Boolean! + logo: String + totalUsers: Float! + workspaceUrls: WorkspaceUrls! + users: [UserInfo!]! + featureFlags: [FeatureFlag!]! +} + +type UserLookup { + user: UserInfo! + workspaces: [WorkspaceInfo!]! +} + +type VersionInfo { + currentVersion: String + latestVersion: String! +} + +type AdminPanelWorkerQueueHealth { + id: String! + queueName: String! + status: AdminPanelHealthServiceStatus! +} + +type AdminPanelHealthServiceData { + id: HealthIndicatorId! label: String! - icon: String - description: String - content: String! - isCustom: Boolean! - isActive: Boolean! - applicationId: UUID - createdAt: DateTime! - updatedAt: DateTime! + description: String! + status: AdminPanelHealthServiceStatus! + errorMessage: String + details: String + queues: [AdminPanelWorkerQueueHealth!] +} + +type ModelsDevModelSuggestion { + modelId: String! + name: String! + inputCostPerMillionTokens: Float! + outputCostPerMillionTokens: Float! + cachedInputCostPerMillionTokens: Float + cacheCreationCostPerMillionTokens: Float + contextWindowTokens: Float! + maxOutputTokens: Float! + modalities: [String!]! + supportsReasoning: Boolean! +} + +type ModelsDevProviderSuggestion { + id: String! + modelCount: Float! + npm: String! +} + +type QueueMetricsDataPoint { + x: Float! + y: Float! +} + +type QueueMetricsSeries { + id: String! + data: [QueueMetricsDataPoint!]! +} + +type WorkerQueueMetrics { + failed: Float! + completed: Float! + waiting: Float! + active: Float! + delayed: Float! + failureRate: Float! + failedData: [Float!] + completedData: [Float!] +} + +type QueueMetricsData { + queueName: String! + workers: Float! + timeRange: QueueMetricsTimeRange! + details: WorkerQueueMetrics + data: [QueueMetricsSeries!]! +} + +enum QueueMetricsTimeRange { + SevenDays + OneDay + TwelveHours + FourHours + OneHour +} + +type VersionDistributionEntry { + version: String! + count: Int! +} + +type ApplicationRegistrationStats { + activeInstalls: Int! + mostInstalledVersion: String + versionDistribution: [VersionDistributionEntry!]! +} + +type CreateApplicationRegistration { + applicationRegistration: ApplicationRegistration! + clientSecret: String! +} + +type PublicApplicationRegistration { + id: UUID! + name: String! + logoUrl: String + websiteUrl: String + oAuthScopes: [String!]! +} + +type RotateClientSecret { + clientSecret: String! +} + +type ResendEmailVerificationToken { + success: Boolean! +} + +type DeleteSso { + identityProviderId: UUID! +} + +type EditSso { + id: UUID! + type: IdentityProviderType! + issuer: String! + name: String! + status: SSOIdentityProviderStatus! +} + +type WorkspaceNameAndId { + displayName: String + id: UUID! +} + +type FindAvailableSSOIDP { + type: IdentityProviderType! + id: UUID! + issuer: String! + name: String! + status: SSOIdentityProviderStatus! + workspace: WorkspaceNameAndId! +} + +type SetupSso { + id: UUID! + type: IdentityProviderType! + issuer: String! + name: String! + status: SSOIdentityProviderStatus! +} + +type SSOConnection { + type: IdentityProviderType! + id: UUID! + issuer: String! + name: String! + status: SSOIdentityProviderStatus! +} + +type AvailableWorkspace { + id: UUID! + displayName: String + loginToken: String + personalInviteToken: String + inviteHash: String + workspaceUrls: WorkspaceUrls! + logo: String + sso: [SSOConnection!]! +} + +type AvailableWorkspaces { + availableWorkspacesForSignIn: [AvailableWorkspace!]! + availableWorkspacesForSignUp: [AvailableWorkspace!]! +} + +type DeletedWorkspaceMember { + id: UUID! + name: FullName! + userEmail: String! + avatarUrl: String + userWorkspaceId: UUID +} + +type BillingEntitlement { + key: BillingEntitlementKey! + value: Boolean! +} + +enum BillingEntitlementKey { + SSO + CUSTOM_DOMAIN + RLS + AUDIT_LOGS +} + +type DomainRecord { + validationType: String! + type: String! + status: String! + key: String! + value: String! +} + +type DomainValidRecords { + id: UUID! + domain: String! + records: [DomainRecord!]! +} + +type IndexEdge { + """The node containing the Index""" + node: Index! + + """Cursor for this node.""" + cursor: ConnectionCursor! +} + +type PageInfo { + """true if paging forward and there are more records.""" + hasNextPage: Boolean + + """true if paging backwards and there are more records.""" + hasPreviousPage: Boolean + + """The cursor of the first returned record.""" + startCursor: ConnectionCursor + + """The cursor of the last returned record.""" + endCursor: ConnectionCursor +} + +type IndexConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [IndexEdge!]! +} + +type IndexFieldEdge { + """The node containing the IndexField""" + node: IndexField! + + """Cursor for this node.""" + cursor: ConnectionCursor! +} + +type IndexIndexFieldMetadatasConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [IndexFieldEdge!]! +} + +type ObjectEdge { + """The node containing the Object""" + node: Object! + + """Cursor for this node.""" + cursor: ConnectionCursor! +} + +type IndexObjectMetadataConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [ObjectEdge!]! +} + +type ObjectRecordCount { + objectNamePlural: String! + totalCount: Int! +} + +type ObjectConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [ObjectEdge!]! +} + +type ObjectIndexMetadatasConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [IndexEdge!]! +} + +type FieldEdge { + """The node containing the Field""" + node: Field! + + """Cursor for this node.""" + cursor: ConnectionCursor! +} + +type ObjectFieldsConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [FieldEdge!]! +} + +type UpsertRowLevelPermissionPredicatesResult { + predicates: [RowLevelPermissionPredicate!]! + predicateGroups: [RowLevelPermissionPredicateGroup!]! +} + +type Relation { + type: RelationType! + sourceObjectMetadata: Object! + targetObjectMetadata: Object! + sourceFieldMetadata: Field! + targetFieldMetadata: Field! +} + +"""Relation type""" +enum RelationType { + ONE_TO_MANY + MANY_TO_ONE +} + +type FieldConnection { + """Paging information""" + pageInfo: PageInfo! + + """Array of edges.""" + edges: [FieldEdge!]! +} + +type DeleteTwoFactorAuthenticationMethod { + """Boolean that confirms query was dispatched""" + success: Boolean! +} + +type InitiateTwoFactorAuthenticationProvisioning { + uri: String! +} + +type VerifyTwoFactorAuthenticationMethod { + success: Boolean! +} + +type AuthorizeApp { + redirectUrl: String! +} + +type AuthToken { + token: String! + expiresAt: DateTime! +} + +type AuthTokenPair { + accessOrWorkspaceAgnosticToken: AuthToken! + refreshToken: AuthToken! +} + +type AvailableWorkspacesAndAccessTokens { + tokens: AuthTokenPair! + availableWorkspaces: AvailableWorkspaces! +} + +type EmailPasswordResetLink { + """Boolean that confirms query was dispatched""" + success: Boolean! +} + +type GetAuthorizationUrlForSSO { + authorizationURL: String! + type: String! + id: UUID! +} + +type InvalidatePassword { + """Boolean that confirms query was dispatched""" + success: Boolean! +} + +type WorkspaceUrlsAndId { + workspaceUrls: WorkspaceUrls! + id: UUID! +} + +type SignUp { + loginToken: AuthToken! + workspace: WorkspaceUrlsAndId! +} + +type TransientToken { + transientToken: AuthToken! +} + +type ValidatePasswordResetToken { + id: UUID! + email: String! + hasPassword: Boolean! +} + +type VerifyEmailAndGetLoginToken { + loginToken: AuthToken! + workspaceUrls: WorkspaceUrls! +} + +type ApiKeyToken { + token: String! +} + +type AuthTokens { + tokens: AuthTokenPair! +} + +type LoginToken { + loginToken: AuthToken! +} + +type CheckUserExist { + exists: Boolean! + availableWorkspacesCount: Float! + isEmailVerified: Boolean! +} + +type WorkspaceInviteHashValid { + isValid: Boolean! +} + +type Impersonate { + loginToken: AuthToken! + workspace: WorkspaceUrlsAndId! +} + +type DevelopmentApplication { + id: String! + universalIdentifier: String! +} + +type WorkspaceMigration { + applicationUniversalIdentifier: String! + actions: JSON! } type ApplicationTokenPair { @@ -2053,6 +2387,216 @@ type ApplicationTokenPair { applicationRefreshToken: AuthToken! } +type File { + id: UUID! + path: String! + size: Float! + createdAt: DateTime! +} + +type MarketplaceAppField { + name: String! + type: String! + label: String! + description: String + icon: String + objectUniversalIdentifier: String + universalIdentifier: String +} + +type MarketplaceAppObject { + universalIdentifier: String! + nameSingular: String! + namePlural: String! + labelSingular: String! + labelPlural: String! + description: String + icon: String + fields: [MarketplaceAppField!]! +} + +type MarketplaceAppLogicFunction { + name: String! + description: String + timeoutSeconds: Int +} + +type MarketplaceAppFrontComponent { + name: String! + description: String +} + +type MarketplaceAppRoleObjectPermission { + objectUniversalIdentifier: String! + canReadObjectRecords: Boolean + canUpdateObjectRecords: Boolean + canSoftDeleteObjectRecords: Boolean + canDestroyObjectRecords: Boolean +} + +type MarketplaceAppRoleFieldPermission { + objectUniversalIdentifier: String! + fieldUniversalIdentifier: String! + canReadFieldValue: Boolean + canUpdateFieldValue: Boolean +} + +type MarketplaceAppDefaultRole { + id: String! + label: String! + description: String + canReadAllObjectRecords: Boolean! + canUpdateAllObjectRecords: Boolean! + canSoftDeleteAllObjectRecords: Boolean! + canDestroyAllObjectRecords: Boolean! + canUpdateAllSettings: Boolean! + canAccessAllTools: Boolean! + objectPermissions: [MarketplaceAppRoleObjectPermission!]! + fieldPermissions: [MarketplaceAppRoleFieldPermission!]! + permissionFlags: [String!]! +} + +type MarketplaceApp { + id: String! + name: String! + description: String! + icon: String! + version: String! + author: String! + category: String! + logo: String + screenshots: [String!]! + aboutDescription: String! + providers: [String!]! + websiteUrl: String + termsUrl: String + objects: [MarketplaceAppObject!]! + fields: [MarketplaceAppField!]! + logicFunctions: [MarketplaceAppLogicFunction!]! + frontComponents: [MarketplaceAppFrontComponent!]! + defaultRole: MarketplaceAppDefaultRole + sourcePackage: String + isFeatured: Boolean! +} + +type PublicDomain { + id: UUID! + domain: String! + isValidated: Boolean! + createdAt: DateTime! +} + +type VerificationRecord { + type: String! + key: String! + value: String! + priority: Float +} + +type EmailingDomain { + id: UUID! + createdAt: DateTime! + updatedAt: DateTime! + domain: String! + driver: EmailingDomainDriver! + status: EmailingDomainStatus! + verificationRecords: [VerificationRecord!] + verifiedAt: DateTime +} + +enum EmailingDomainDriver { + AWS_SES +} + +enum EmailingDomainStatus { + PENDING + VERIFIED + FAILED + TEMPORARY_FAILURE +} + +type AutocompleteResult { + text: String! + placeId: String! +} + +type Location { + lat: Float + lng: Float +} + +type PlaceDetailsResult { + state: String + postcode: String + city: String + country: String + location: Location +} + +type ConnectionParametersOutput { + host: String! + port: Float! + username: String + password: String! + secure: Boolean +} + +type ImapSmtpCaldavConnectionParameters { + IMAP: ConnectionParametersOutput + SMTP: ConnectionParametersOutput + CALDAV: ConnectionParametersOutput +} + +type ConnectedImapSmtpCaldavAccount { + id: UUID! + handle: String! + provider: String! + accountOwnerId: UUID! + connectionParameters: ImapSmtpCaldavConnectionParameters +} + +type ImapSmtpCaldavConnectionSuccess { + success: Boolean! + connectedAccountId: String! +} + +type PostgresCredentials { + id: UUID! + user: String! + password: String! + workspaceId: UUID! +} + +type UsageBreakdownItem { + key: String! + label: String + creditsUsed: Float! +} + +type UsageTimeSeries { + date: String! + creditsUsed: Float! +} + +type UsageUserDaily { + userWorkspaceId: String! + dailyUsage: [UsageTimeSeries!]! +} + +type UsageAnalytics { + usageByUser: [UsageBreakdownItem!]! + usageByOperationType: [UsageBreakdownItem!]! + timeSeries: [UsageTimeSeries!]! + periodStart: DateTime! + periodEnd: DateTime! + userDailyUsage: UsageUserDaily +} + +type LogicFunctionLogs { + """Execution Logs""" + logs: String! +} + type FrontComponent { id: UUID! name: String! @@ -2066,6 +2610,7 @@ type FrontComponent { createdAt: DateTime! updatedAt: DateTime! isHeadless: Boolean! + usesSdkClient: Boolean! applicationTokenPair: ApplicationTokenPair } @@ -2157,6 +2702,146 @@ enum CommandMenuItemAvailabilityType { FALLBACK } +type ToolIndexEntry { + name: String! + description: String! + category: String! + objectName: String + inputSchema: JSON +} + +type AgentMessagePart { + id: UUID! + messageId: UUID! + orderIndex: Int! + type: String! + textContent: String + reasoningContent: String + toolName: String + toolCallId: String + toolInput: JSON + toolOutput: JSON + state: String + errorMessage: String + errorDetails: JSON + sourceUrlSourceId: String + sourceUrlUrl: String + sourceUrlTitle: String + sourceDocumentSourceId: String + sourceDocumentMediaType: String + sourceDocumentTitle: String + sourceDocumentFilename: String + fileMediaType: String + fileFilename: String + fileId: UUID + fileUrl: String + providerMetadata: JSON + createdAt: DateTime! +} + +type ChannelSyncSuccess { + success: Boolean! +} + +type BarChartSeries { + key: String! + label: String! +} + +type BarChartData { + data: [JSON!]! + indexBy: String! + keys: [String!]! + series: [BarChartSeries!]! + xAxisLabel: String! + yAxisLabel: String! + showLegend: Boolean! + showDataLabels: Boolean! + layout: BarChartLayout! + groupMode: BarChartGroupMode! + hasTooManyGroups: Boolean! + formattedToRawLookup: JSON! +} + +type LineChartDataPoint { + x: String! + y: Float! +} + +type LineChartSeries { + id: String! + label: String! + data: [LineChartDataPoint!]! +} + +type LineChartData { + series: [LineChartSeries!]! + xAxisLabel: String! + yAxisLabel: String! + showLegend: Boolean! + showDataLabels: Boolean! + hasTooManyGroups: Boolean! + formattedToRawLookup: JSON! +} + +type PieChartDataItem { + id: String! + value: Float! +} + +type PieChartData { + data: [PieChartDataItem!]! + showLegend: Boolean! + showDataLabels: Boolean! + showCenterMetric: Boolean! + hasTooManyGroups: Boolean! + formattedToRawLookup: JSON! +} + +type DuplicatedDashboard { + id: UUID! + title: String + pageLayoutId: UUID + position: Float! + createdAt: String! + updatedAt: String! +} + +type EventLogRecord { + event: String! + timestamp: DateTime! + userId: String + properties: JSON + recordId: String + objectMetadataId: String + isCustom: Boolean +} + +type EventLogPageInfo { + endCursor: String + hasNextPage: Boolean! +} + +type EventLogQueryResult { + records: [EventLogRecord!]! + totalCount: Int! + pageInfo: EventLogPageInfo! +} + +type Skill { + id: UUID! + name: String! + label: String! + icon: String + description: String + content: String! + isCustom: Boolean! + isActive: Boolean! + applicationId: UUID + createdAt: DateTime! + updatedAt: DateTime! +} + type AgentChatThread { id: UUID! title: String @@ -2447,705 +3132,35 @@ type Webhook { deletedAt: DateTime } -type BillingTrialPeriod { - duration: Float! - isCreditCardRequired: Boolean! -} - -type NativeModelCapabilities { - webSearch: Boolean - twitterSearch: Boolean -} - -type ClientAIModelConfig { - modelId: String! - label: String! - modelFamily: ModelFamily - modelFamilyLabel: String - sdkPackage: String - inputCostPerMillionTokensInCredits: Float! - outputCostPerMillionTokensInCredits: Float! - nativeCapabilities: NativeModelCapabilities - isDeprecated: Boolean - isRecommended: Boolean - providerName: String - dataResidency: String -} - -enum ModelFamily { - GPT - CLAUDE - GEMINI - MISTRAL - GROK -} - -type AdminAIModelConfig { - modelId: String! - label: String! - modelFamily: ModelFamily - modelFamilyLabel: String - sdkPackage: String - isAvailable: Boolean! - isAdminEnabled: Boolean! - isDeprecated: Boolean - isRecommended: Boolean - contextWindowTokens: Float - maxOutputTokens: Float - inputCostPerMillionTokens: Float - outputCostPerMillionTokens: Float - providerName: String - providerLabel: String - name: String - dataResidency: String -} - -type AdminAIModels { - models: [AdminAIModelConfig!]! - defaultSmartModelId: String - defaultFastModelId: String -} - -type Billing { - isBillingEnabled: Boolean! - billingUrl: String - trialPeriods: [BillingTrialPeriod!]! -} - -type Support { - supportDriver: SupportDriver! - supportFrontChatId: String -} - -enum SupportDriver { - NONE - FRONT -} - -type Sentry { - environment: String - release: String - dsn: String -} - -type Captcha { - provider: CaptchaDriverType - siteKey: String -} - -enum CaptchaDriverType { - GOOGLE_RECAPTCHA - TURNSTILE -} - -type ApiConfig { - mutationMaximumAffectedRecords: Float! -} - -type PublicFeatureFlagMetadata { - label: String! - description: String! - imagePath: String -} - -type PublicFeatureFlag { - key: FeatureFlagKey! - metadata: PublicFeatureFlagMetadata! -} - -type ClientConfig { - appVersion: String - authProviders: AuthProviders! - billing: Billing! - aiModels: [ClientAIModelConfig!]! - signInPrefilled: Boolean! - isMultiWorkspaceEnabled: Boolean! - isEmailVerificationRequired: Boolean! - defaultSubdomain: String - frontDomain: String! - analyticsEnabled: Boolean! - support: Support! - isAttachmentPreviewEnabled: Boolean! - sentry: Sentry! - captcha: Captcha! - api: ApiConfig! - canManageFeatureFlags: Boolean! - publicFeatureFlags: [PublicFeatureFlag!]! - isMicrosoftMessagingEnabled: Boolean! - isMicrosoftCalendarEnabled: Boolean! - isGoogleMessagingEnabled: Boolean! - isGoogleCalendarEnabled: Boolean! - isConfigVariablesInDbEnabled: Boolean! - isImapSmtpCaldavEnabled: Boolean! - allowRequestsToTwentyIcons: Boolean! - calendarBookingPageId: String - isCloudflareIntegrationEnabled: Boolean! - isClickHouseConfigured: Boolean! -} - -type ConfigVariable { - name: String! - description: String! - value: JSON - isSensitive: Boolean! - source: ConfigSource! - isEnvOnly: Boolean! - type: ConfigVariableType! - options: JSON -} - -enum ConfigSource { - ENVIRONMENT - DATABASE - DEFAULT -} - -enum ConfigVariableType { - BOOLEAN - NUMBER - ARRAY - STRING - ENUM - JSON -} - -type ConfigVariablesGroupData { - variables: [ConfigVariable!]! - name: ConfigVariablesGroup! - description: String! - isHiddenOnLoad: Boolean! -} - -enum ConfigVariablesGroup { - SERVER_CONFIG - RATE_LIMITING - STORAGE_CONFIG - GOOGLE_AUTH - MICROSOFT_AUTH - EMAIL_SETTINGS - LOGGING - ADVANCED_SETTINGS - BILLING_CONFIG - CAPTCHA_CONFIG - CLOUDFLARE_CONFIG - LLM - LOGIC_FUNCTION_CONFIG - CODE_INTERPRETER_CONFIG - SSL - SUPPORT_CHAT_CONFIG - ANALYTICS_CONFIG - TOKENS_DURATION - AWS_SES_SETTINGS -} - -type ConfigVariables { - groups: [ConfigVariablesGroupData!]! -} - -type JobOperationResult { - jobId: String! - success: Boolean! - error: String -} - -type DeleteJobsResponse { - deletedCount: Int! - results: [JobOperationResult!]! -} - -type QueueJob { - id: String! - name: String! - data: JSON - state: JobState! - timestamp: Float - failedReason: String - processedOn: Float - finishedOn: Float - attemptsMade: Float! - returnValue: JSON - logs: [String!] - stackTrace: [String!] -} - -"""Job state in the queue""" -enum JobState { - COMPLETED - FAILED - ACTIVE - WAITING - DELAYED - PRIORITIZED - WAITING_CHILDREN -} - -type QueueRetentionConfig { - completedMaxAge: Float! - completedMaxCount: Float! - failedMaxAge: Float! - failedMaxCount: Float! -} - -type QueueJobsResponse { - jobs: [QueueJob!]! - count: Float! - totalCount: Float! - hasMore: Boolean! - retentionConfig: QueueRetentionConfig! -} - -type RetryJobsResponse { - retriedCount: Int! - results: [JobOperationResult!]! -} - -type SystemHealthService { - id: HealthIndicatorId! - label: String! - status: AdminPanelHealthServiceStatus! -} - -enum HealthIndicatorId { - database - redis - worker - connectedAccount - app -} - -enum AdminPanelHealthServiceStatus { - OPERATIONAL - OUTAGE -} - -type SystemHealth { - services: [SystemHealthService!]! -} - -type UserInfo { - id: UUID! - email: String! - firstName: String - lastName: String -} - -type WorkspaceInfo { - id: UUID! - name: String! - allowImpersonation: Boolean! - logo: String - totalUsers: Float! - workspaceUrls: WorkspaceUrls! - users: [UserInfo!]! - featureFlags: [FeatureFlag!]! -} - -type UserLookup { - user: UserInfo! - workspaces: [WorkspaceInfo!]! -} - -type VersionInfo { - currentVersion: String - latestVersion: String! -} - -type AdminPanelWorkerQueueHealth { - id: String! - queueName: String! - status: AdminPanelHealthServiceStatus! -} - -type AdminPanelHealthServiceData { - id: HealthIndicatorId! - label: String! - description: String! - status: AdminPanelHealthServiceStatus! - errorMessage: String - details: String - queues: [AdminPanelWorkerQueueHealth!] -} - -type ModelsDevModelSuggestion { - modelId: String! - name: String! - inputCostPerMillionTokens: Float! - outputCostPerMillionTokens: Float! - cachedInputCostPerMillionTokens: Float - cacheCreationCostPerMillionTokens: Float - contextWindowTokens: Float! - maxOutputTokens: Float! - modalities: [String!]! - supportsReasoning: Boolean! -} - -type ModelsDevProviderSuggestion { - id: String! - modelCount: Float! - npm: String! -} - -type QueueMetricsDataPoint { - x: Float! - y: Float! -} - -type QueueMetricsSeries { - id: String! - data: [QueueMetricsDataPoint!]! -} - -type WorkerQueueMetrics { - failed: Float! - completed: Float! - waiting: Float! - active: Float! - delayed: Float! - failureRate: Float! - failedData: [Float!] - completedData: [Float!] -} - -type QueueMetricsData { - queueName: String! - workers: Float! - timeRange: QueueMetricsTimeRange! - details: WorkerQueueMetrics - data: [QueueMetricsSeries!]! -} - -enum QueueMetricsTimeRange { - SevenDays - OneDay - TwelveHours - FourHours - OneHour -} - -type Impersonate { - loginToken: AuthToken! - workspace: WorkspaceUrlsAndId! -} - -type DevelopmentApplication { - id: String! - universalIdentifier: String! -} - -type WorkspaceMigration { - applicationUniversalIdentifier: String! - actions: JSON! -} - -type File { - id: UUID! - path: String! - size: Float! - createdAt: DateTime! -} - -type MarketplaceAppField { - name: String! - type: String! - label: String! - description: String - icon: String - objectUniversalIdentifier: String - universalIdentifier: String -} - -type MarketplaceAppObject { - universalIdentifier: String! - nameSingular: String! - namePlural: String! - labelSingular: String! - labelPlural: String! - description: String - icon: String - fields: [MarketplaceAppField!]! -} - -type MarketplaceAppLogicFunction { - name: String! - description: String - timeoutSeconds: Int -} - -type MarketplaceAppFrontComponent { - name: String! - description: String -} - -type MarketplaceAppRoleObjectPermission { - objectUniversalIdentifier: String! - canReadObjectRecords: Boolean - canUpdateObjectRecords: Boolean - canSoftDeleteObjectRecords: Boolean - canDestroyObjectRecords: Boolean -} - -type MarketplaceAppRoleFieldPermission { - objectUniversalIdentifier: String! - fieldUniversalIdentifier: String! - canReadFieldValue: Boolean - canUpdateFieldValue: Boolean -} - -type MarketplaceAppDefaultRole { - id: String! - label: String! - description: String - canReadAllObjectRecords: Boolean! - canUpdateAllObjectRecords: Boolean! - canSoftDeleteAllObjectRecords: Boolean! - canDestroyAllObjectRecords: Boolean! - canUpdateAllSettings: Boolean! - canAccessAllTools: Boolean! - objectPermissions: [MarketplaceAppRoleObjectPermission!]! - fieldPermissions: [MarketplaceAppRoleFieldPermission!]! - permissionFlags: [String!]! -} - -type MarketplaceApp { - id: String! - name: String! - description: String! - icon: String! - version: String! - author: String! - category: String! - logo: String - screenshots: [String!]! - aboutDescription: String! - providers: [String!]! - websiteUrl: String - termsUrl: String - objects: [MarketplaceAppObject!]! - fields: [MarketplaceAppField!]! - logicFunctions: [MarketplaceAppLogicFunction!]! - frontComponents: [MarketplaceAppFrontComponent!]! - defaultRole: MarketplaceAppDefaultRole - sourcePackage: String - isFeatured: Boolean! -} - -type UsageBreakdownItem { - key: String! - label: String - creditsUsed: Float! -} - -type UsageTimeSeries { - date: String! - creditsUsed: Float! -} - -type UsageUserDaily { - userWorkspaceId: String! - dailyUsage: [UsageTimeSeries!]! -} - -type UsageAnalytics { - usageByUser: [UsageBreakdownItem!]! - usageByOperationType: [UsageBreakdownItem!]! - timeSeries: [UsageTimeSeries!]! - periodStart: DateTime! - periodEnd: DateTime! - userDailyUsage: UsageUserDaily -} - -type PublicDomain { - id: UUID! - domain: String! - isValidated: Boolean! - createdAt: DateTime! -} - -type VerificationRecord { - type: String! - key: String! - value: String! - priority: Float -} - -type EmailingDomain { - id: UUID! - createdAt: DateTime! - updatedAt: DateTime! - domain: String! - driver: EmailingDomainDriver! - status: EmailingDomainStatus! - verificationRecords: [VerificationRecord!] - verifiedAt: DateTime -} - -enum EmailingDomainDriver { - AWS_SES -} - -enum EmailingDomainStatus { - PENDING - VERIFIED - FAILED - TEMPORARY_FAILURE -} - -type AutocompleteResult { - text: String! - placeId: String! -} - -type Location { - lat: Float - lng: Float -} - -type PlaceDetailsResult { - state: String - postcode: String - city: String - country: String - location: Location -} - -type ConnectionParametersOutput { - host: String! - port: Float! - username: String - password: String! - secure: Boolean -} - -type ImapSmtpCaldavConnectionParameters { - IMAP: ConnectionParametersOutput - SMTP: ConnectionParametersOutput - CALDAV: ConnectionParametersOutput -} - -type ConnectedImapSmtpCaldavAccount { - id: UUID! - handle: String! - provider: String! - accountOwnerId: UUID! - connectionParameters: ImapSmtpCaldavConnectionParameters -} - -type ImapSmtpCaldavConnectionSuccess { - success: Boolean! - connectedAccountId: String! -} - -type PostgresCredentials { - id: UUID! - user: String! - password: String! - workspaceId: UUID! -} - -type ChannelSyncSuccess { - success: Boolean! -} - -type BarChartSeries { - key: String! - label: String! -} - -type BarChartData { - data: [JSON!]! - indexBy: String! - keys: [String!]! - series: [BarChartSeries!]! - xAxisLabel: String! - yAxisLabel: String! - showLegend: Boolean! - showDataLabels: Boolean! - layout: BarChartLayout! - groupMode: BarChartGroupMode! - hasTooManyGroups: Boolean! - formattedToRawLookup: JSON! -} - -type LineChartDataPoint { - x: String! - y: Float! -} - -type LineChartSeries { - id: String! - label: String! - data: [LineChartDataPoint!]! -} - -type LineChartData { - series: [LineChartSeries!]! - xAxisLabel: String! - yAxisLabel: String! - showLegend: Boolean! - showDataLabels: Boolean! - hasTooManyGroups: Boolean! - formattedToRawLookup: JSON! -} - -type PieChartDataItem { - id: String! - value: Float! -} - -type PieChartData { - data: [PieChartDataItem!]! - showLegend: Boolean! - showDataLabels: Boolean! - showCenterMetric: Boolean! - hasTooManyGroups: Boolean! - formattedToRawLookup: JSON! -} - -type DuplicatedDashboard { - id: UUID! - title: String - pageLayoutId: UUID - position: Float! - createdAt: String! - updatedAt: String! -} - -type EventLogRecord { - event: String! - timestamp: DateTime! - userId: String - properties: JSON - recordId: String - objectMetadataId: String - isCustom: Boolean -} - -type EventLogPageInfo { - endCursor: String - hasNextPage: Boolean! -} - -type EventLogQueryResult { - records: [EventLogRecord!]! - totalCount: Int! - pageInfo: EventLogPageInfo! -} - type Query { navigationMenuItems: [NavigationMenuItem!]! navigationMenuItem(id: UUID!): NavigationMenuItem - getPageLayoutWidgets(pageLayoutTabId: String!): [PageLayoutWidget!]! - getPageLayoutWidget(id: String!): PageLayoutWidget! - getPageLayoutTabs(pageLayoutId: String!): [PageLayoutTab!]! - getPageLayoutTab(id: String!): PageLayoutTab! - getPageLayouts(objectMetadataId: String, pageLayoutType: PageLayoutType): [PageLayout!]! - getPageLayout(id: String!): PageLayout + getViewFilterGroups(viewId: String): [ViewFilterGroup!]! + getViewFilterGroup(id: String!): ViewFilterGroup + getViewFilters(viewId: String): [ViewFilter!]! + getViewFilter(id: String!): ViewFilter getViews(objectMetadataId: String, viewTypes: [ViewType!]): [View!]! getView(id: String!): View getViewSorts(viewId: String): [ViewSort!]! getViewSort(id: String!): ViewSort getViewFieldGroups(viewId: String!): [ViewFieldGroup!]! getViewFieldGroup(id: String!): ViewFieldGroup + apiKeys: [ApiKey!]! + apiKey(input: GetApiKeyInput!): ApiKey + enterprisePortalSession(returnUrlPath: String): String + enterpriseCheckoutSession(billingInterval: String): String + enterpriseSubscriptionStatus: EnterpriseSubscriptionStatusDTO + billingPortalSession(returnUrlPath: String): BillingSession! + listPlans: [BillingPlan!]! + getMeteredProductsUsage: [BillingMeteredProductUsage!]! + findWorkspaceInvitations: [WorkspaceInvitation!]! + getApprovedAccessDomains: [ApprovedAccessDomain!]! + getPageLayoutTabs(pageLayoutId: String!): [PageLayoutTab!]! + getPageLayoutTab(id: String!): PageLayoutTab! + getPageLayouts(objectMetadataId: String, pageLayoutType: PageLayoutType): [PageLayout!]! + getPageLayout(id: String!): PageLayout + getPageLayoutWidgets(pageLayoutTabId: String!): [PageLayoutWidget!]! + getPageLayoutWidget(id: String!): PageLayoutWidget! findOneLogicFunction(input: LogicFunctionIdInput!): LogicFunction! findManyLogicFunctions: [LogicFunction!]! getAvailablePackages(input: LogicFunctionIdInput!): JSON! @@ -3181,17 +3196,7 @@ type Query { ): IndexConnection! findManyAgents: [Agent!]! findOneAgent(input: AgentIdInput!): Agent! - billingPortalSession(returnUrlPath: String): BillingSession! - listPlans: [BillingPlan!]! - getMeteredProductsUsage: [BillingMeteredProductUsage!]! - enterprisePortalSession(returnUrlPath: String): String - enterpriseCheckoutSession(billingInterval: String): String - enterpriseSubscriptionStatus: EnterpriseSubscriptionStatusDTO getRoles: [Role!]! - findWorkspaceInvitations: [WorkspaceInvitation!]! - getApprovedAccessDomains: [ApprovedAccessDomain!]! - apiKeys: [ApiKey!]! - apiKey(input: GetApiKeyInput!): ApiKey getToolIndex: [ToolIndexEntry!]! getToolInputSchema(toolName: String!): JSON field( @@ -3207,25 +3212,6 @@ type Query { ): FieldConnection! getViewGroups(viewId: String): [ViewGroup!]! getViewGroup(id: String!): ViewGroup - getViewFilters(viewId: String): [ViewFilter!]! - getViewFilter(id: String!): ViewFilter - getViewFilterGroups(viewId: String): [ViewFilterGroup!]! - getViewFilterGroup(id: String!): ViewFilterGroup - currentUser: User! - currentWorkspace: Workspace! - getPublicWorkspaceDataByDomain(origin: String): PublicWorkspaceData! - findApplicationRegistrationByClientId(clientId: String!): PublicApplicationRegistration - findApplicationRegistrationByUniversalIdentifier(universalIdentifier: String!): ApplicationRegistration - findManyApplicationRegistrations: [ApplicationRegistration!]! - findOneApplicationRegistration(id: String!): ApplicationRegistration! - findApplicationRegistrationStats(id: String!): ApplicationRegistrationStats! - findApplicationRegistrationVariables(applicationRegistrationId: String!): [ApplicationRegistrationVariable!]! - applicationRegistrationTarballUrl(id: String!): String - checkUserExists(email: String!, captchaToken: String): CheckUserExist! - checkWorkspaceInviteHashIsValid(inviteHash: String!): WorkspaceInviteHashValid! - findWorkspaceFromInviteHash(inviteHash: String!): Workspace! - validatePasswordResetToken(passwordResetToken: String!): ValidatePasswordResetToken! - getSSOIdentityProviders: [FindAvailableSSOIDP!]! myMessageFolders(messageChannelId: UUID): [MessageFolder!]! myMessageChannels(connectedAccountId: UUID): [MessageChannel!]! myConnectedAccounts: [ConnectedAccountDTO!]! @@ -3254,6 +3240,21 @@ type Query { pieChartData(input: PieChartDataInput!): PieChartData! lineChartData(input: LineChartDataInput!): LineChartData! barChartData(input: BarChartDataInput!): BarChartData! + checkUserExists(email: String!, captchaToken: String): CheckUserExist! + checkWorkspaceInviteHashIsValid(inviteHash: String!): WorkspaceInviteHashValid! + findWorkspaceFromInviteHash(inviteHash: String!): Workspace! + validatePasswordResetToken(passwordResetToken: String!): ValidatePasswordResetToken! + findApplicationRegistrationByClientId(clientId: String!): PublicApplicationRegistration + findApplicationRegistrationByUniversalIdentifier(universalIdentifier: String!): ApplicationRegistration + findManyApplicationRegistrations: [ApplicationRegistration!]! + findOneApplicationRegistration(id: String!): ApplicationRegistration! + findApplicationRegistrationStats(id: String!): ApplicationRegistrationStats! + findApplicationRegistrationVariables(applicationRegistrationId: String!): [ApplicationRegistrationVariable!]! + applicationRegistrationTarballUrl(id: String!): String + currentUser: User! + currentWorkspace: Workspace! + getPublicWorkspaceDataByDomain(origin: String): PublicWorkspaceData! + getSSOIdentityProviders: [FindAvailableSSOIDP!]! getConnectedImapSmtpCaldavAccount(id: UUID!): ConnectedImapSmtpCaldavAccount! getAutoCompleteAddress(address: String!, token: String!, country: String, isFieldCity: Boolean): [AutocompleteResult!]! getAddressDetails(placeId: String!, token: String!): PlaceDetailsResult! @@ -3279,6 +3280,10 @@ type Query { getUsageAnalytics(input: UsageAnalyticsInput): UsageAnalytics! } +input GetApiKeyInput { + id: UUID! +} + input LogicFunctionIdInput { """The id of the function.""" id: ID! @@ -3289,10 +3294,6 @@ input AgentIdInput { id: UUID! } -input GetApiKeyInput { - id: UUID! -} - input AgentChatThreadFilter { and: [AgentChatThreadFilter!] or: [AgentChatThreadFilter!] @@ -3403,18 +3404,14 @@ type Mutation { uploadWorkspaceMemberProfilePicture(file: Upload!): FileWithSignedUrl! uploadFilesFieldFile(file: Upload!, fieldMetadataId: String!): FileWithSignedUrl! uploadFilesFieldFileByUniversalIdentifier(file: Upload!, fieldMetadataUniversalIdentifier: String!): FileWithSignedUrl! - createObjectEvent(event: String!, recordId: UUID!, objectMetadataId: UUID!, properties: JSON): Analytics! - trackAnalytics(type: AnalyticsType!, name: String, event: String, properties: JSON): Analytics! - createPageLayoutWidget(input: CreatePageLayoutWidgetInput!): PageLayoutWidget! - updatePageLayoutWidget(id: String!, input: UpdatePageLayoutWidgetInput!): PageLayoutWidget! - destroyPageLayoutWidget(id: String!): Boolean! - createPageLayoutTab(input: CreatePageLayoutTabInput!): PageLayoutTab! - updatePageLayoutTab(id: String!, input: UpdatePageLayoutTabInput!): PageLayoutTab! - destroyPageLayoutTab(id: String!): Boolean! - createPageLayout(input: CreatePageLayoutInput!): PageLayout! - updatePageLayout(id: String!, input: UpdatePageLayoutInput!): PageLayout! - destroyPageLayout(id: String!): Boolean! - updatePageLayoutWithTabsAndWidgets(id: String!, input: UpdatePageLayoutWithTabsInput!): PageLayout! + createViewFilterGroup(input: CreateViewFilterGroupInput!): ViewFilterGroup! + updateViewFilterGroup(id: String!, input: UpdateViewFilterGroupInput!): ViewFilterGroup! + deleteViewFilterGroup(id: String!): Boolean! + destroyViewFilterGroup(id: String!): Boolean! + createViewFilter(input: CreateViewFilterInput!): ViewFilter! + updateViewFilter(input: UpdateViewFilterInput!): ViewFilter! + deleteViewFilter(input: DeleteViewFilterInput!): ViewFilter! + destroyViewFilter(input: DestroyViewFilterInput!): ViewFilter! createView(input: CreateViewInput!): View! updateView(id: String!, input: UpdateViewInput!): View! deleteView(id: String!): Boolean! @@ -3429,6 +3426,40 @@ type Mutation { deleteViewFieldGroup(input: DeleteViewFieldGroupInput!): ViewFieldGroup! destroyViewFieldGroup(input: DestroyViewFieldGroupInput!): ViewFieldGroup! upsertFieldsWidget(input: UpsertFieldsWidgetInput!): View! + createApiKey(input: CreateApiKeyInput!): ApiKey! + updateApiKey(input: UpdateApiKeyInput!): ApiKey + revokeApiKey(input: RevokeApiKeyInput!): ApiKey + assignRoleToApiKey(apiKeyId: UUID!, roleId: UUID!): Boolean! + createObjectEvent(event: String!, recordId: UUID!, objectMetadataId: UUID!, properties: JSON): Analytics! + trackAnalytics(type: AnalyticsType!, name: String, event: String, properties: JSON): Analytics! + refreshEnterpriseValidityToken: Boolean! + setEnterpriseKey(enterpriseKey: String!): EnterpriseLicenseInfoDTO! + skipSyncEmailOnboardingStep: OnboardingStepSuccess! + skipBookOnboardingStep: OnboardingStepSuccess! + checkoutSession(recurringInterval: SubscriptionInterval!, plan: BillingPlanKey! = PRO, requirePaymentMethod: Boolean! = true, successUrlPath: String): BillingSession! + switchSubscriptionInterval: BillingUpdate! + switchBillingPlan: BillingUpdate! + cancelSwitchBillingPlan: BillingUpdate! + cancelSwitchBillingInterval: BillingUpdate! + setMeteredSubscriptionPrice(priceId: String!): BillingUpdate! + endSubscriptionTrialPeriod: BillingEndTrialPeriod! + cancelSwitchMeteredPrice: BillingUpdate! + deleteWorkspaceInvitation(appTokenId: String!): String! + resendWorkspaceInvitation(appTokenId: String!): SendInvitations! + sendInvitations(emails: [String!]!, roleId: UUID): SendInvitations! + createApprovedAccessDomain(input: CreateApprovedAccessDomainInput!): ApprovedAccessDomain! + deleteApprovedAccessDomain(input: DeleteApprovedAccessDomainInput!): Boolean! + validateApprovedAccessDomain(input: ValidateApprovedAccessDomainInput!): ApprovedAccessDomain! + createPageLayoutTab(input: CreatePageLayoutTabInput!): PageLayoutTab! + updatePageLayoutTab(id: String!, input: UpdatePageLayoutTabInput!): PageLayoutTab! + destroyPageLayoutTab(id: String!): Boolean! + createPageLayout(input: CreatePageLayoutInput!): PageLayout! + updatePageLayout(id: String!, input: UpdatePageLayoutInput!): PageLayout! + destroyPageLayout(id: String!): Boolean! + updatePageLayoutWithTabsAndWidgets(id: String!, input: UpdatePageLayoutWithTabsInput!): PageLayout! + createPageLayoutWidget(input: CreatePageLayoutWidgetInput!): PageLayoutWidget! + updatePageLayoutWidget(id: String!, input: UpdatePageLayoutWidgetInput!): PageLayoutWidget! + destroyPageLayoutWidget(id: String!): Boolean! deleteOneLogicFunction(input: LogicFunctionIdInput!): LogicFunction! createOneLogicFunction(input: CreateLogicFunctionFromSourceInput!): LogicFunction! executeOneLogicFunction(input: ExecuteOneLogicFunctionInput!): LogicFunctionExecutionResult! @@ -3450,16 +3481,6 @@ type Mutation { createOneAgent(input: CreateAgentInput!): Agent! updateOneAgent(input: UpdateAgentInput!): Agent! deleteOneAgent(input: AgentIdInput!): Agent! - checkoutSession(recurringInterval: SubscriptionInterval!, plan: BillingPlanKey! = PRO, requirePaymentMethod: Boolean! = true, successUrlPath: String): BillingSession! - switchSubscriptionInterval: BillingUpdate! - switchBillingPlan: BillingUpdate! - cancelSwitchBillingPlan: BillingUpdate! - cancelSwitchBillingInterval: BillingUpdate! - setMeteredSubscriptionPrice(priceId: String!): BillingUpdate! - endSubscriptionTrialPeriod: BillingEndTrialPeriod! - cancelSwitchMeteredPrice: BillingUpdate! - refreshEnterpriseValidityToken: Boolean! - setEnterpriseKey(enterpriseKey: String!): EnterpriseLicenseInfoDTO! updateWorkspaceMemberRole(workspaceMemberId: UUID!, roleId: UUID!): WorkspaceMember! createOneRole(createRoleInput: CreateRoleInput!): Role! updateOneRole(updateRoleInput: UpdateRoleInput!): Role! @@ -3470,18 +3491,6 @@ type Mutation { upsertRowLevelPermissionPredicates(input: UpsertRowLevelPermissionPredicatesInput!): UpsertRowLevelPermissionPredicatesResult! assignRoleToAgent(agentId: UUID!, roleId: UUID!): Boolean! removeRoleFromAgent(agentId: UUID!): Boolean! - skipSyncEmailOnboardingStep: OnboardingStepSuccess! - skipBookOnboardingStep: OnboardingStepSuccess! - deleteWorkspaceInvitation(appTokenId: String!): String! - resendWorkspaceInvitation(appTokenId: String!): SendInvitations! - sendInvitations(emails: [String!]!, roleId: UUID): SendInvitations! - createApprovedAccessDomain(input: CreateApprovedAccessDomainInput!): ApprovedAccessDomain! - deleteApprovedAccessDomain(input: DeleteApprovedAccessDomainInput!): Boolean! - validateApprovedAccessDomain(input: ValidateApprovedAccessDomainInput!): ApprovedAccessDomain! - createApiKey(input: CreateApiKeyInput!): ApiKey! - updateApiKey(input: UpdateApiKeyInput!): ApiKey - revokeApiKey(input: RevokeApiKeyInput!): ApiKey - assignRoleToApiKey(apiKeyId: UUID!, roleId: UUID!): Boolean! createOneField(input: CreateOneFieldMetadataInput!): Field! updateOneField(input: UpdateOneFieldMetadataInput!): Field! deleteOneField(input: DeleteOneFieldInput!): Field! @@ -3490,55 +3499,6 @@ type Mutation { updateViewGroup(input: UpdateViewGroupInput!): ViewGroup! deleteViewGroup(input: DeleteViewGroupInput!): ViewGroup! destroyViewGroup(input: DestroyViewGroupInput!): ViewGroup! - createViewFilter(input: CreateViewFilterInput!): ViewFilter! - updateViewFilter(input: UpdateViewFilterInput!): ViewFilter! - deleteViewFilter(input: DeleteViewFilterInput!): ViewFilter! - destroyViewFilter(input: DestroyViewFilterInput!): ViewFilter! - createViewFilterGroup(input: CreateViewFilterGroupInput!): ViewFilterGroup! - updateViewFilterGroup(id: String!, input: UpdateViewFilterGroupInput!): ViewFilterGroup! - deleteViewFilterGroup(id: String!): Boolean! - destroyViewFilterGroup(id: String!): Boolean! - deleteUser: User! - deleteUserFromWorkspace(workspaceMemberIdToDelete: String!): UserWorkspace! - updateUserEmail(newEmail: String!, verifyEmailRedirectPath: String): Boolean! - resendEmailVerificationToken(email: String!, origin: String!): ResendEmailVerificationToken! - activateWorkspace(data: ActivateWorkspaceInput!): Workspace! - updateWorkspace(data: UpdateWorkspaceInput!): Workspace! - deleteCurrentWorkspace: Workspace! - checkCustomDomainValidRecords: DomainValidRecords - createApplicationRegistration(input: CreateApplicationRegistrationInput!): CreateApplicationRegistration! - updateApplicationRegistration(input: UpdateApplicationRegistrationInput!): ApplicationRegistration! - deleteApplicationRegistration(id: String!): Boolean! - rotateApplicationRegistrationClientSecret(id: String!): RotateClientSecret! - createApplicationRegistrationVariable(input: CreateApplicationRegistrationVariableInput!): ApplicationRegistrationVariable! - updateApplicationRegistrationVariable(input: UpdateApplicationRegistrationVariableInput!): ApplicationRegistrationVariable! - deleteApplicationRegistrationVariable(id: String!): Boolean! - uploadAppTarball(file: Upload!, universalIdentifier: String): ApplicationRegistration! - transferApplicationRegistrationOwnership(applicationRegistrationId: String!, targetWorkspaceSubdomain: String!): ApplicationRegistration! - getAuthorizationUrlForSSO(input: GetAuthorizationUrlForSSOInput!): GetAuthorizationUrlForSSO! - getLoginTokenFromCredentials(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String, origin: String!): LoginToken! - signIn(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String): AvailableWorkspacesAndAccessTokens! - verifyEmailAndGetLoginToken(emailVerificationToken: String!, email: String!, captchaToken: String, origin: String!): VerifyEmailAndGetLoginToken! - verifyEmailAndGetWorkspaceAgnosticToken(emailVerificationToken: String!, email: String!, captchaToken: String): AvailableWorkspacesAndAccessTokens! - getAuthTokensFromOTP(otp: String!, loginToken: String!, captchaToken: String, origin: String!): AuthTokens! - signUp(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String): AvailableWorkspacesAndAccessTokens! - signUpInWorkspace(email: String!, password: String!, workspaceId: UUID, workspaceInviteHash: String, workspacePersonalInviteToken: String, captchaToken: String, locale: String, verifyEmailRedirectPath: String): SignUp! - signUpInNewWorkspace: SignUp! - generateTransientToken: TransientToken! - getAuthTokensFromLoginToken(loginToken: String!, origin: String!): AuthTokens! - authorizeApp(clientId: String!, codeChallenge: String, redirectUrl: String!, state: String, scope: String): AuthorizeApp! - renewToken(appToken: String!): AuthTokens! - generateApiKeyToken(apiKeyId: UUID!, expiresAt: String!): ApiKeyToken! - emailPasswordResetLink(email: String!, workspaceId: UUID): EmailPasswordResetLink! - updatePasswordViaResetToken(passwordResetToken: String!, newPassword: String!): InvalidatePassword! - initiateOTPProvisioning(loginToken: String!, origin: String!): InitiateTwoFactorAuthenticationProvisioning! - initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning! - deleteTwoFactorAuthenticationMethod(twoFactorAuthenticationMethodId: UUID!): DeleteTwoFactorAuthenticationMethod! - verifyTwoFactorAuthenticationMethodForAuthenticatedUser(otp: String!): VerifyTwoFactorAuthenticationMethod! - createOIDCIdentityProvider(input: SetupOIDCSsoInput!): SetupSso! - createSAMLIdentityProvider(input: SetupSAMLSsoInput!): SetupSso! - deleteSSOIdentityProvider(input: DeleteSsoInput!): DeleteSso! - editSSOIdentityProvider(input: EditSsoInput!): EditSso! updateMessageFolder(input: UpdateMessageFolderInput!): MessageFolder! updateMessageFolders(input: UpdateMessageFoldersInput!): [MessageFolder!]! updateMessageChannel(input: UpdateMessageChannelInput!): MessageChannel! @@ -3556,6 +3516,47 @@ type Mutation { evaluateAgentTurn(turnId: UUID!): AgentTurnEvaluation! runEvaluationInput(agentId: UUID!, input: String!): AgentTurn! duplicateDashboard(id: UUID!): DuplicatedDashboard! + getAuthorizationUrlForSSO(input: GetAuthorizationUrlForSSOInput!): GetAuthorizationUrlForSSO! + getLoginTokenFromCredentials(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String, origin: String!): LoginToken! + signIn(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String): AvailableWorkspacesAndAccessTokens! + verifyEmailAndGetLoginToken(emailVerificationToken: String!, email: String!, captchaToken: String, origin: String!): VerifyEmailAndGetLoginToken! + verifyEmailAndGetWorkspaceAgnosticToken(emailVerificationToken: String!, email: String!, captchaToken: String): AvailableWorkspacesAndAccessTokens! + getAuthTokensFromOTP(otp: String!, loginToken: String!, captchaToken: String, origin: String!): AuthTokens! + signUp(email: String!, password: String!, captchaToken: String, locale: String, verifyEmailRedirectPath: String): AvailableWorkspacesAndAccessTokens! + signUpInWorkspace(email: String!, password: String!, workspaceId: UUID, workspaceInviteHash: String, workspacePersonalInviteToken: String, captchaToken: String, locale: String, verifyEmailRedirectPath: String): SignUp! + signUpInNewWorkspace: SignUp! + generateTransientToken: TransientToken! + getAuthTokensFromLoginToken(loginToken: String!, origin: String!): AuthTokens! + authorizeApp(clientId: String!, codeChallenge: String, redirectUrl: String!, state: String, scope: String): AuthorizeApp! + renewToken(appToken: String!): AuthTokens! + generateApiKeyToken(apiKeyId: UUID!, expiresAt: String!): ApiKeyToken! + emailPasswordResetLink(email: String!, workspaceId: UUID): EmailPasswordResetLink! + updatePasswordViaResetToken(passwordResetToken: String!, newPassword: String!): InvalidatePassword! + createApplicationRegistration(input: CreateApplicationRegistrationInput!): CreateApplicationRegistration! + updateApplicationRegistration(input: UpdateApplicationRegistrationInput!): ApplicationRegistration! + deleteApplicationRegistration(id: String!): Boolean! + rotateApplicationRegistrationClientSecret(id: String!): RotateClientSecret! + createApplicationRegistrationVariable(input: CreateApplicationRegistrationVariableInput!): ApplicationRegistrationVariable! + updateApplicationRegistrationVariable(input: UpdateApplicationRegistrationVariableInput!): ApplicationRegistrationVariable! + deleteApplicationRegistrationVariable(id: String!): Boolean! + uploadAppTarball(file: Upload!, universalIdentifier: String): ApplicationRegistration! + transferApplicationRegistrationOwnership(applicationRegistrationId: String!, targetWorkspaceSubdomain: String!): ApplicationRegistration! + initiateOTPProvisioning(loginToken: String!, origin: String!): InitiateTwoFactorAuthenticationProvisioning! + initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning! + deleteTwoFactorAuthenticationMethod(twoFactorAuthenticationMethodId: UUID!): DeleteTwoFactorAuthenticationMethod! + verifyTwoFactorAuthenticationMethodForAuthenticatedUser(otp: String!): VerifyTwoFactorAuthenticationMethod! + deleteUser: User! + deleteUserFromWorkspace(workspaceMemberIdToDelete: String!): UserWorkspace! + updateUserEmail(newEmail: String!, verifyEmailRedirectPath: String): Boolean! + resendEmailVerificationToken(email: String!, origin: String!): ResendEmailVerificationToken! + activateWorkspace(data: ActivateWorkspaceInput!): Workspace! + updateWorkspace(data: UpdateWorkspaceInput!): Workspace! + deleteCurrentWorkspace: Workspace! + checkCustomDomainValidRecords: DomainValidRecords + createOIDCIdentityProvider(input: SetupOIDCSsoInput!): SetupSso! + createSAMLIdentityProvider(input: SetupSAMLSsoInput!): SetupSso! + deleteSSOIdentityProvider(input: DeleteSsoInput!): DeleteSso! + editSSOIdentityProvider(input: EditSsoInput!): EditSso! impersonate(userId: UUID!, workspaceId: UUID!): Impersonate! startChannelSync(connectedAccountId: UUID!): ChannelSyncSuccess! saveImapSmtpCaldavAccount(accountOwnerId: UUID!, handle: String!, connectionParameters: EmailAccountConnectionParameters!, id: UUID): ImapSmtpCaldavConnectionSuccess! @@ -3642,90 +3643,58 @@ input UpdateNavigationMenuItemInput { """The `Upload` scalar type represents a file upload.""" scalar Upload -enum AnalyticsType { - PAGEVIEW - TRACK +input CreateViewFilterGroupInput { + id: UUID + parentViewFilterGroupId: UUID + logicalOperator: ViewFilterGroupLogicalOperator = AND + positionInViewFilterGroup: Float + viewId: UUID! } -input CreatePageLayoutWidgetInput { - pageLayoutTabId: UUID! - title: String! - type: WidgetType! - objectMetadataId: UUID - gridPosition: GridPositionInput! - position: JSON - configuration: JSON! +input UpdateViewFilterGroupInput { + id: UUID + parentViewFilterGroupId: UUID + logicalOperator: ViewFilterGroupLogicalOperator = AND + positionInViewFilterGroup: Float + viewId: UUID } -input GridPositionInput { - row: Float! - column: Float! - rowSpan: Float! - columnSpan: Float! +input CreateViewFilterInput { + id: UUID + fieldMetadataId: UUID! + operand: ViewFilterOperand = CONTAINS + value: JSON! + viewFilterGroupId: UUID + positionInViewFilterGroup: Float + subFieldName: String + viewId: UUID! } -input UpdatePageLayoutWidgetInput { - title: String - type: WidgetType - objectMetadataId: UUID - gridPosition: GridPositionInput - position: JSON - configuration: JSON - conditionalDisplay: JSON -} - -input CreatePageLayoutTabInput { - title: String! - position: Float - pageLayoutId: UUID! - layoutMode: PageLayoutTabLayoutMode = GRID -} - -input UpdatePageLayoutTabInput { - title: String - position: Float - icon: String - layoutMode: PageLayoutTabLayoutMode -} - -input CreatePageLayoutInput { - name: String! - type: PageLayoutType = RECORD_PAGE - objectMetadataId: UUID -} - -input UpdatePageLayoutInput { - name: String - type: PageLayoutType - objectMetadataId: UUID -} - -input UpdatePageLayoutWithTabsInput { - name: String! - type: PageLayoutType! - objectMetadataId: UUID - tabs: [UpdatePageLayoutTabWithWidgetsInput!]! -} - -input UpdatePageLayoutTabWithWidgetsInput { +input UpdateViewFilterInput { + """The id of the view filter to update""" id: UUID! - title: String! - position: Float! - icon: String - layoutMode: PageLayoutTabLayoutMode = GRID - widgets: [UpdatePageLayoutWidgetWithIdInput!]! + + """The view filter to update""" + update: UpdateViewFilterInputUpdates! } -input UpdatePageLayoutWidgetWithIdInput { +input UpdateViewFilterInputUpdates { + fieldMetadataId: UUID + operand: ViewFilterOperand + value: JSON + viewFilterGroupId: UUID + positionInViewFilterGroup: Float + subFieldName: String +} + +input DeleteViewFilterInput { + """The id of the view filter to delete.""" + id: UUID! +} + +input DestroyViewFilterInput { + """The id of the view filter to destroy.""" id: UUID! - pageLayoutTabId: UUID! - title: String! - type: WidgetType! - objectMetadataId: UUID - gridPosition: GridPositionInput! - position: JSON - configuration: JSON - conditionalDisplay: JSON } input CreateViewInput { @@ -3858,6 +3827,124 @@ input UpsertFieldsWidgetFieldInput { position: Float! } +input CreateApiKeyInput { + name: String! + expiresAt: String! + revokedAt: String + roleId: UUID! +} + +input UpdateApiKeyInput { + id: UUID! + name: String + expiresAt: String + revokedAt: String +} + +input RevokeApiKeyInput { + id: UUID! +} + +enum AnalyticsType { + PAGEVIEW + TRACK +} + +input CreateApprovedAccessDomainInput { + domain: String! + email: String! +} + +input DeleteApprovedAccessDomainInput { + id: UUID! +} + +input ValidateApprovedAccessDomainInput { + validationToken: String! + approvedAccessDomainId: UUID! +} + +input CreatePageLayoutTabInput { + title: String! + position: Float + pageLayoutId: UUID! + layoutMode: PageLayoutTabLayoutMode = GRID +} + +input UpdatePageLayoutTabInput { + title: String + position: Float + icon: String + layoutMode: PageLayoutTabLayoutMode +} + +input CreatePageLayoutInput { + name: String! + type: PageLayoutType = RECORD_PAGE + objectMetadataId: UUID +} + +input UpdatePageLayoutInput { + name: String + type: PageLayoutType + objectMetadataId: UUID +} + +input UpdatePageLayoutWithTabsInput { + name: String! + type: PageLayoutType! + objectMetadataId: UUID + tabs: [UpdatePageLayoutTabWithWidgetsInput!]! +} + +input UpdatePageLayoutTabWithWidgetsInput { + id: UUID! + title: String! + position: Float! + icon: String + layoutMode: PageLayoutTabLayoutMode = GRID + widgets: [UpdatePageLayoutWidgetWithIdInput!]! +} + +input UpdatePageLayoutWidgetWithIdInput { + id: UUID! + pageLayoutTabId: UUID! + title: String! + type: WidgetType! + objectMetadataId: UUID + gridPosition: GridPositionInput! + position: JSON + configuration: JSON + conditionalDisplay: JSON +} + +input GridPositionInput { + row: Float! + column: Float! + rowSpan: Float! + columnSpan: Float! +} + +input CreatePageLayoutWidgetInput { + pageLayoutTabId: UUID! + title: String! + type: WidgetType! + objectMetadataId: UUID + gridPosition: GridPositionInput! + position: JSON + configuration: JSON! +} + +input UpdatePageLayoutWidgetInput { + title: String + type: WidgetType + objectMetadataId: UUID + gridPosition: GridPositionInput + position: JSON + configuration: JSON + conditionalDisplay: JSON +} + input CreateLogicFunctionFromSourceInput { id: UUID universalIdentifier: UUID @@ -4160,38 +4247,6 @@ input RowLevelPermissionPredicateGroupInput { positionInRowLevelPermissionPredicateGroup: Float } -input CreateApprovedAccessDomainInput { - domain: String! - email: String! -} - -input DeleteApprovedAccessDomainInput { - id: UUID! -} - -input ValidateApprovedAccessDomainInput { - validationToken: String! - approvedAccessDomainId: UUID! -} - -input CreateApiKeyInput { - name: String! - expiresAt: String! - revokedAt: String - roleId: UUID! -} - -input UpdateApiKeyInput { - id: UUID! - name: String - expiresAt: String - revokedAt: String -} - -input RevokeApiKeyInput { - id: UUID! -} - input CreateOneFieldMetadataInput { """The record to create""" field: CreateFieldInput! @@ -4283,167 +4338,6 @@ input DestroyViewGroupInput { id: UUID! } -input CreateViewFilterInput { - id: UUID - fieldMetadataId: UUID! - operand: ViewFilterOperand = CONTAINS - value: JSON! - viewFilterGroupId: UUID - positionInViewFilterGroup: Float - subFieldName: String - viewId: UUID! -} - -input UpdateViewFilterInput { - """The id of the view filter to update""" - id: UUID! - - """The view filter to update""" - update: UpdateViewFilterInputUpdates! -} - -input UpdateViewFilterInputUpdates { - fieldMetadataId: UUID - operand: ViewFilterOperand - value: JSON - viewFilterGroupId: UUID - positionInViewFilterGroup: Float - subFieldName: String -} - -input DeleteViewFilterInput { - """The id of the view filter to delete.""" - id: UUID! -} - -input DestroyViewFilterInput { - """The id of the view filter to destroy.""" - id: UUID! -} - -input CreateViewFilterGroupInput { - id: UUID - parentViewFilterGroupId: UUID - logicalOperator: ViewFilterGroupLogicalOperator = AND - positionInViewFilterGroup: Float - viewId: UUID! -} - -input UpdateViewFilterGroupInput { - id: UUID - parentViewFilterGroupId: UUID - logicalOperator: ViewFilterGroupLogicalOperator = AND - positionInViewFilterGroup: Float - viewId: UUID -} - -input ActivateWorkspaceInput { - displayName: String -} - -input UpdateWorkspaceInput { - subdomain: String - customDomain: String - displayName: String - logo: String - inviteHash: String - isPublicInviteLinkEnabled: Boolean - allowImpersonation: Boolean - isGoogleAuthEnabled: Boolean - isMicrosoftAuthEnabled: Boolean - isPasswordAuthEnabled: Boolean - isGoogleAuthBypassEnabled: Boolean - isMicrosoftAuthBypassEnabled: Boolean - isPasswordAuthBypassEnabled: Boolean - defaultRoleId: UUID - isTwoFactorAuthenticationEnforced: Boolean - trashRetentionDays: Float - eventLogRetentionDays: Float - fastModel: String - smartModel: String - aiAdditionalInstructions: String - editableProfileFields: [String!] - enabledAiModelIds: [String!] - useRecommendedModels: Boolean -} - -input CreateApplicationRegistrationInput { - name: String! - description: String - logoUrl: String - author: String - universalIdentifier: String - oAuthRedirectUris: [String!] - oAuthScopes: [String!] - websiteUrl: String - termsUrl: String -} - -input UpdateApplicationRegistrationInput { - id: String! - update: UpdateApplicationRegistrationPayload! -} - -input UpdateApplicationRegistrationPayload { - name: String - description: String - logoUrl: String - author: String - oAuthRedirectUris: [String!] - oAuthScopes: [String!] - websiteUrl: String - termsUrl: String - isListed: Boolean -} - -input CreateApplicationRegistrationVariableInput { - applicationRegistrationId: String! - key: String! - value: String! - description: String - isSecret: Boolean -} - -input UpdateApplicationRegistrationVariableInput { - id: String! - update: UpdateApplicationRegistrationVariablePayload! -} - -input UpdateApplicationRegistrationVariablePayload { - value: String - description: String -} - -input GetAuthorizationUrlForSSOInput { - identityProviderId: UUID! - workspaceInviteHash: String -} - -input SetupOIDCSsoInput { - name: String! - issuer: String! - clientID: String! - clientSecret: String! -} - -input SetupSAMLSsoInput { - name: String! - issuer: String! - id: UUID! - ssoURL: String! - certificate: String! - fingerprint: String -} - -input DeleteSsoInput { - identityProviderId: UUID! -} - -input EditSsoInput { - id: UUID! - status: SSOIdentityProviderStatus! -} - input UpdateMessageFolderInput { id: UUID! update: UpdateMessageFolderInputUpdates! @@ -4527,6 +4421,113 @@ input UpdateSkillInput { isActive: Boolean } +input GetAuthorizationUrlForSSOInput { + identityProviderId: UUID! + workspaceInviteHash: String +} + +input CreateApplicationRegistrationInput { + name: String! + description: String + logoUrl: String + author: String + universalIdentifier: String + oAuthRedirectUris: [String!] + oAuthScopes: [String!] + websiteUrl: String + termsUrl: String +} + +input UpdateApplicationRegistrationInput { + id: String! + update: UpdateApplicationRegistrationPayload! +} + +input UpdateApplicationRegistrationPayload { + name: String + description: String + logoUrl: String + author: String + oAuthRedirectUris: [String!] + oAuthScopes: [String!] + websiteUrl: String + termsUrl: String + isListed: Boolean +} + +input CreateApplicationRegistrationVariableInput { + applicationRegistrationId: String! + key: String! + value: String! + description: String + isSecret: Boolean +} + +input UpdateApplicationRegistrationVariableInput { + id: String! + update: UpdateApplicationRegistrationVariablePayload! +} + +input UpdateApplicationRegistrationVariablePayload { + value: String + description: String +} + +input ActivateWorkspaceInput { + displayName: String +} + +input UpdateWorkspaceInput { + subdomain: String + customDomain: String + displayName: String + logo: String + inviteHash: String + isPublicInviteLinkEnabled: Boolean + allowImpersonation: Boolean + isGoogleAuthEnabled: Boolean + isMicrosoftAuthEnabled: Boolean + isPasswordAuthEnabled: Boolean + isGoogleAuthBypassEnabled: Boolean + isMicrosoftAuthBypassEnabled: Boolean + isPasswordAuthBypassEnabled: Boolean + defaultRoleId: UUID + isTwoFactorAuthenticationEnforced: Boolean + trashRetentionDays: Float + eventLogRetentionDays: Float + fastModel: String + smartModel: String + aiAdditionalInstructions: String + editableProfileFields: [String!] + enabledAiModelIds: [String!] + useRecommendedModels: Boolean +} + +input SetupOIDCSsoInput { + name: String! + issuer: String! + clientID: String! + clientSecret: String! +} + +input SetupSAMLSsoInput { + name: String! + issuer: String! + id: UUID! + ssoURL: String! + certificate: String! + fingerprint: String +} + +input DeleteSsoInput { + identityProviderId: UUID! +} + +input EditSsoInput { + id: UUID! + status: SSOIdentityProviderStatus! +} + input EmailAccountConnectionParameters { IMAP: ConnectionParameters SMTP: ConnectionParameters @@ -4592,6 +4593,7 @@ enum FileFolder { Dependencies Workflow AppTarball + GeneratedSdkClient } type Subscription { diff --git a/packages/twenty-sdk/src/clients/generated/metadata/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts similarity index 99% rename from packages/twenty-sdk/src/clients/generated/metadata/schema.ts rename to packages/twenty-client-sdk/src/metadata/generated/schema.ts index 3e1c5f2a363..73ad7970dd6 100644 --- a/packages/twenty-sdk/src/clients/generated/metadata/schema.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts @@ -1181,9 +1181,105 @@ export interface SendInvitations { __typename: 'SendInvitations' } -export interface ResendEmailVerificationToken { - success: Scalars['Boolean'] - __typename: 'ResendEmailVerificationToken' +export interface RecordIdentifier { + id: Scalars['UUID'] + labelIdentifier: Scalars['String'] + imageIdentifier?: Scalars['String'] + __typename: 'RecordIdentifier' +} + +export interface NavigationMenuItem { + id: Scalars['UUID'] + userWorkspaceId?: Scalars['UUID'] + targetRecordId?: Scalars['UUID'] + targetObjectMetadataId?: Scalars['UUID'] + viewId?: Scalars['UUID'] + type: NavigationMenuItemType + name?: Scalars['String'] + link?: Scalars['String'] + icon?: Scalars['String'] + color?: Scalars['String'] + folderId?: Scalars['UUID'] + position: Scalars['Float'] + applicationId?: Scalars['UUID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + targetRecordIdentifier?: RecordIdentifier + __typename: 'NavigationMenuItem' +} + +export type NavigationMenuItemType = 'VIEW' | 'FOLDER' | 'LINK' | 'OBJECT' | 'RECORD' + +export interface ObjectRecordEventProperties { + updatedFields?: Scalars['String'][] + before?: Scalars['JSON'] + after?: Scalars['JSON'] + diff?: Scalars['JSON'] + __typename: 'ObjectRecordEventProperties' +} + +export interface MetadataEvent { + type: MetadataEventAction + metadataName: Scalars['String'] + recordId: Scalars['String'] + properties: ObjectRecordEventProperties + updatedCollectionHash?: Scalars['String'] + __typename: 'MetadataEvent' +} + + +/** Metadata Event Action */ +export type MetadataEventAction = 'CREATED' | 'UPDATED' | 'DELETED' + +export interface ObjectRecordEvent { + action: DatabaseEventAction + objectNameSingular: Scalars['String'] + recordId: Scalars['String'] + userId?: Scalars['String'] + workspaceMemberId?: Scalars['String'] + properties: ObjectRecordEventProperties + __typename: 'ObjectRecordEvent' +} + + +/** Database Event Action */ +export type DatabaseEventAction = 'CREATED' | 'UPDATED' | 'DELETED' | 'DESTROYED' | 'RESTORED' | 'UPSERTED' + +export interface ObjectRecordEventWithQueryIds { + queryIds: Scalars['String'][] + objectRecordEvent: ObjectRecordEvent + __typename: 'ObjectRecordEventWithQueryIds' +} + +export interface EventSubscription { + eventStreamId: Scalars['String'] + objectRecordEventsWithQueryIds: ObjectRecordEventWithQueryIds[] + metadataEvents: MetadataEvent[] + __typename: 'EventSubscription' +} + +export interface LogicFunctionExecutionResult { + /** Execution result in JSON format */ + data?: Scalars['JSON'] + /** Execution Logs */ + logs: Scalars['String'] + /** Execution duration in milliseconds */ + duration: Scalars['Float'] + /** Execution status */ + status: LogicFunctionExecutionStatus + /** Execution error in JSON format */ + error?: Scalars['JSON'] + __typename: 'LogicFunctionExecutionResult' +} + + +/** Status of the logic function execution */ +export type LogicFunctionExecutionStatus = 'IDLE' | 'SUCCESS' | 'ERROR' + +export interface BillingTrialPeriod { + duration: Scalars['Float'] + isCreditCardRequired: Scalars['Boolean'] + __typename: 'BillingTrialPeriod' } export interface WorkspaceUrls { @@ -1192,6 +1288,470 @@ export interface WorkspaceUrls { __typename: 'WorkspaceUrls' } +export interface SSOIdentityProvider { + id: Scalars['UUID'] + name: Scalars['String'] + type: IdentityProviderType + status: SSOIdentityProviderStatus + issuer: Scalars['String'] + __typename: 'SSOIdentityProvider' +} + +export type IdentityProviderType = 'OIDC' | 'SAML' + +export type SSOIdentityProviderStatus = 'Active' | 'Inactive' | 'Error' + +export interface AuthProviders { + sso: SSOIdentityProvider[] + google: Scalars['Boolean'] + magicLink: Scalars['Boolean'] + password: Scalars['Boolean'] + microsoft: Scalars['Boolean'] + __typename: 'AuthProviders' +} + +export interface AuthBypassProviders { + google: Scalars['Boolean'] + password: Scalars['Boolean'] + microsoft: Scalars['Boolean'] + __typename: 'AuthBypassProviders' +} + +export interface PublicWorkspaceData { + id: Scalars['UUID'] + authProviders: AuthProviders + authBypassProviders?: AuthBypassProviders + logo?: Scalars['String'] + displayName?: Scalars['String'] + workspaceUrls: WorkspaceUrls + __typename: 'PublicWorkspaceData' +} + +export interface NativeModelCapabilities { + webSearch?: Scalars['Boolean'] + twitterSearch?: Scalars['Boolean'] + __typename: 'NativeModelCapabilities' +} + +export interface ClientAIModelConfig { + modelId: Scalars['String'] + label: Scalars['String'] + modelFamily?: ModelFamily + modelFamilyLabel?: Scalars['String'] + sdkPackage?: Scalars['String'] + inputCostPerMillionTokensInCredits: Scalars['Float'] + outputCostPerMillionTokensInCredits: Scalars['Float'] + nativeCapabilities?: NativeModelCapabilities + isDeprecated?: Scalars['Boolean'] + isRecommended?: Scalars['Boolean'] + providerName?: Scalars['String'] + dataResidency?: Scalars['String'] + __typename: 'ClientAIModelConfig' +} + +export type ModelFamily = 'GPT' | 'CLAUDE' | 'GEMINI' | 'MISTRAL' | 'GROK' + +export interface AdminAIModelConfig { + modelId: Scalars['String'] + label: Scalars['String'] + modelFamily?: ModelFamily + modelFamilyLabel?: Scalars['String'] + sdkPackage?: Scalars['String'] + isAvailable: Scalars['Boolean'] + isAdminEnabled: Scalars['Boolean'] + isDeprecated?: Scalars['Boolean'] + isRecommended?: Scalars['Boolean'] + contextWindowTokens?: Scalars['Float'] + maxOutputTokens?: Scalars['Float'] + inputCostPerMillionTokens?: Scalars['Float'] + outputCostPerMillionTokens?: Scalars['Float'] + providerName?: Scalars['String'] + providerLabel?: Scalars['String'] + name?: Scalars['String'] + dataResidency?: Scalars['String'] + __typename: 'AdminAIModelConfig' +} + +export interface AdminAIModels { + models: AdminAIModelConfig[] + defaultSmartModelId?: Scalars['String'] + defaultFastModelId?: Scalars['String'] + __typename: 'AdminAIModels' +} + +export interface Billing { + isBillingEnabled: Scalars['Boolean'] + billingUrl?: Scalars['String'] + trialPeriods: BillingTrialPeriod[] + __typename: 'Billing' +} + +export interface Support { + supportDriver: SupportDriver + supportFrontChatId?: Scalars['String'] + __typename: 'Support' +} + +export type SupportDriver = 'NONE' | 'FRONT' + +export interface Sentry { + environment?: Scalars['String'] + release?: Scalars['String'] + dsn?: Scalars['String'] + __typename: 'Sentry' +} + +export interface Captcha { + provider?: CaptchaDriverType + siteKey?: Scalars['String'] + __typename: 'Captcha' +} + +export type CaptchaDriverType = 'GOOGLE_RECAPTCHA' | 'TURNSTILE' + +export interface ApiConfig { + mutationMaximumAffectedRecords: Scalars['Float'] + __typename: 'ApiConfig' +} + +export interface PublicFeatureFlagMetadata { + label: Scalars['String'] + description: Scalars['String'] + imagePath?: Scalars['String'] + __typename: 'PublicFeatureFlagMetadata' +} + +export interface PublicFeatureFlag { + key: FeatureFlagKey + metadata: PublicFeatureFlagMetadata + __typename: 'PublicFeatureFlag' +} + +export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_APPLICATION_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_DASHBOARD_V2_ENABLED' | 'IS_ATTACHMENT_MIGRATED' | 'IS_NOTE_TARGET_MIGRATED' | 'IS_TASK_TARGET_MIGRATED' | 'IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_ENABLED' | 'IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_GRAPHQL_QUERY_TIMING_ENABLED' + +export interface ClientConfig { + appVersion?: Scalars['String'] + authProviders: AuthProviders + billing: Billing + aiModels: ClientAIModelConfig[] + signInPrefilled: Scalars['Boolean'] + isMultiWorkspaceEnabled: Scalars['Boolean'] + isEmailVerificationRequired: Scalars['Boolean'] + defaultSubdomain?: Scalars['String'] + frontDomain: Scalars['String'] + analyticsEnabled: Scalars['Boolean'] + support: Support + isAttachmentPreviewEnabled: Scalars['Boolean'] + sentry: Sentry + captcha: Captcha + api: ApiConfig + canManageFeatureFlags: Scalars['Boolean'] + publicFeatureFlags: PublicFeatureFlag[] + isMicrosoftMessagingEnabled: Scalars['Boolean'] + isMicrosoftCalendarEnabled: Scalars['Boolean'] + isGoogleMessagingEnabled: Scalars['Boolean'] + isGoogleCalendarEnabled: Scalars['Boolean'] + isConfigVariablesInDbEnabled: Scalars['Boolean'] + isImapSmtpCaldavEnabled: Scalars['Boolean'] + allowRequestsToTwentyIcons: Scalars['Boolean'] + calendarBookingPageId?: Scalars['String'] + isCloudflareIntegrationEnabled: Scalars['Boolean'] + isClickHouseConfigured: Scalars['Boolean'] + __typename: 'ClientConfig' +} + +export interface ConfigVariable { + name: Scalars['String'] + description: Scalars['String'] + value?: Scalars['JSON'] + isSensitive: Scalars['Boolean'] + source: ConfigSource + isEnvOnly: Scalars['Boolean'] + type: ConfigVariableType + options?: Scalars['JSON'] + __typename: 'ConfigVariable' +} + +export type ConfigSource = 'ENVIRONMENT' | 'DATABASE' | 'DEFAULT' + +export type ConfigVariableType = 'BOOLEAN' | 'NUMBER' | 'ARRAY' | 'STRING' | 'ENUM' | 'JSON' + +export interface ConfigVariablesGroupData { + variables: ConfigVariable[] + name: ConfigVariablesGroup + description: Scalars['String'] + isHiddenOnLoad: Scalars['Boolean'] + __typename: 'ConfigVariablesGroupData' +} + +export type ConfigVariablesGroup = 'SERVER_CONFIG' | 'RATE_LIMITING' | 'STORAGE_CONFIG' | 'GOOGLE_AUTH' | 'MICROSOFT_AUTH' | 'EMAIL_SETTINGS' | 'LOGGING' | 'ADVANCED_SETTINGS' | 'BILLING_CONFIG' | 'CAPTCHA_CONFIG' | 'CLOUDFLARE_CONFIG' | 'LLM' | 'LOGIC_FUNCTION_CONFIG' | 'CODE_INTERPRETER_CONFIG' | 'SSL' | 'SUPPORT_CHAT_CONFIG' | 'ANALYTICS_CONFIG' | 'TOKENS_DURATION' | 'AWS_SES_SETTINGS' + +export interface ConfigVariables { + groups: ConfigVariablesGroupData[] + __typename: 'ConfigVariables' +} + +export interface JobOperationResult { + jobId: Scalars['String'] + success: Scalars['Boolean'] + error?: Scalars['String'] + __typename: 'JobOperationResult' +} + +export interface DeleteJobsResponse { + deletedCount: Scalars['Int'] + results: JobOperationResult[] + __typename: 'DeleteJobsResponse' +} + +export interface QueueJob { + id: Scalars['String'] + name: Scalars['String'] + data?: Scalars['JSON'] + state: JobState + timestamp?: Scalars['Float'] + failedReason?: Scalars['String'] + processedOn?: Scalars['Float'] + finishedOn?: Scalars['Float'] + attemptsMade: Scalars['Float'] + returnValue?: Scalars['JSON'] + logs?: Scalars['String'][] + stackTrace?: Scalars['String'][] + __typename: 'QueueJob' +} + + +/** Job state in the queue */ +export type JobState = 'COMPLETED' | 'FAILED' | 'ACTIVE' | 'WAITING' | 'DELAYED' | 'PRIORITIZED' | 'WAITING_CHILDREN' + +export interface QueueRetentionConfig { + completedMaxAge: Scalars['Float'] + completedMaxCount: Scalars['Float'] + failedMaxAge: Scalars['Float'] + failedMaxCount: Scalars['Float'] + __typename: 'QueueRetentionConfig' +} + +export interface QueueJobsResponse { + jobs: QueueJob[] + count: Scalars['Float'] + totalCount: Scalars['Float'] + hasMore: Scalars['Boolean'] + retentionConfig: QueueRetentionConfig + __typename: 'QueueJobsResponse' +} + +export interface RetryJobsResponse { + retriedCount: Scalars['Int'] + results: JobOperationResult[] + __typename: 'RetryJobsResponse' +} + +export interface SystemHealthService { + id: HealthIndicatorId + label: Scalars['String'] + status: AdminPanelHealthServiceStatus + __typename: 'SystemHealthService' +} + +export type HealthIndicatorId = 'database' | 'redis' | 'worker' | 'connectedAccount' | 'app' + +export type AdminPanelHealthServiceStatus = 'OPERATIONAL' | 'OUTAGE' + +export interface SystemHealth { + services: SystemHealthService[] + __typename: 'SystemHealth' +} + +export interface FeatureFlag { + key: FeatureFlagKey + value: Scalars['Boolean'] + __typename: 'FeatureFlag' +} + +export interface UserInfo { + id: Scalars['UUID'] + email: Scalars['String'] + firstName?: Scalars['String'] + lastName?: Scalars['String'] + __typename: 'UserInfo' +} + +export interface WorkspaceInfo { + id: Scalars['UUID'] + name: Scalars['String'] + allowImpersonation: Scalars['Boolean'] + logo?: Scalars['String'] + totalUsers: Scalars['Float'] + workspaceUrls: WorkspaceUrls + users: UserInfo[] + featureFlags: FeatureFlag[] + __typename: 'WorkspaceInfo' +} + +export interface UserLookup { + user: UserInfo + workspaces: WorkspaceInfo[] + __typename: 'UserLookup' +} + +export interface VersionInfo { + currentVersion?: Scalars['String'] + latestVersion: Scalars['String'] + __typename: 'VersionInfo' +} + +export interface AdminPanelWorkerQueueHealth { + id: Scalars['String'] + queueName: Scalars['String'] + status: AdminPanelHealthServiceStatus + __typename: 'AdminPanelWorkerQueueHealth' +} + +export interface AdminPanelHealthServiceData { + id: HealthIndicatorId + label: Scalars['String'] + description: Scalars['String'] + status: AdminPanelHealthServiceStatus + errorMessage?: Scalars['String'] + details?: Scalars['String'] + queues?: AdminPanelWorkerQueueHealth[] + __typename: 'AdminPanelHealthServiceData' +} + +export interface ModelsDevModelSuggestion { + modelId: Scalars['String'] + name: Scalars['String'] + inputCostPerMillionTokens: Scalars['Float'] + outputCostPerMillionTokens: Scalars['Float'] + cachedInputCostPerMillionTokens?: Scalars['Float'] + cacheCreationCostPerMillionTokens?: Scalars['Float'] + contextWindowTokens: Scalars['Float'] + maxOutputTokens: Scalars['Float'] + modalities: Scalars['String'][] + supportsReasoning: Scalars['Boolean'] + __typename: 'ModelsDevModelSuggestion' +} + +export interface ModelsDevProviderSuggestion { + id: Scalars['String'] + modelCount: Scalars['Float'] + npm: Scalars['String'] + __typename: 'ModelsDevProviderSuggestion' +} + +export interface QueueMetricsDataPoint { + x: Scalars['Float'] + y: Scalars['Float'] + __typename: 'QueueMetricsDataPoint' +} + +export interface QueueMetricsSeries { + id: Scalars['String'] + data: QueueMetricsDataPoint[] + __typename: 'QueueMetricsSeries' +} + +export interface WorkerQueueMetrics { + failed: Scalars['Float'] + completed: Scalars['Float'] + waiting: Scalars['Float'] + active: Scalars['Float'] + delayed: Scalars['Float'] + failureRate: Scalars['Float'] + failedData?: Scalars['Float'][] + completedData?: Scalars['Float'][] + __typename: 'WorkerQueueMetrics' +} + +export interface QueueMetricsData { + queueName: Scalars['String'] + workers: Scalars['Float'] + timeRange: QueueMetricsTimeRange + details?: WorkerQueueMetrics + data: QueueMetricsSeries[] + __typename: 'QueueMetricsData' +} + +export type QueueMetricsTimeRange = 'SevenDays' | 'OneDay' | 'TwelveHours' | 'FourHours' | 'OneHour' + +export interface VersionDistributionEntry { + version: Scalars['String'] + count: Scalars['Int'] + __typename: 'VersionDistributionEntry' +} + +export interface ApplicationRegistrationStats { + activeInstalls: Scalars['Int'] + mostInstalledVersion?: Scalars['String'] + versionDistribution: VersionDistributionEntry[] + __typename: 'ApplicationRegistrationStats' +} + +export interface CreateApplicationRegistration { + applicationRegistration: ApplicationRegistration + clientSecret: Scalars['String'] + __typename: 'CreateApplicationRegistration' +} + +export interface PublicApplicationRegistration { + id: Scalars['UUID'] + name: Scalars['String'] + logoUrl?: Scalars['String'] + websiteUrl?: Scalars['String'] + oAuthScopes: Scalars['String'][] + __typename: 'PublicApplicationRegistration' +} + +export interface RotateClientSecret { + clientSecret: Scalars['String'] + __typename: 'RotateClientSecret' +} + +export interface ResendEmailVerificationToken { + success: Scalars['Boolean'] + __typename: 'ResendEmailVerificationToken' +} + +export interface DeleteSso { + identityProviderId: Scalars['UUID'] + __typename: 'DeleteSso' +} + +export interface EditSso { + id: Scalars['UUID'] + type: IdentityProviderType + issuer: Scalars['String'] + name: Scalars['String'] + status: SSOIdentityProviderStatus + __typename: 'EditSso' +} + +export interface WorkspaceNameAndId { + displayName?: Scalars['String'] + id: Scalars['UUID'] + __typename: 'WorkspaceNameAndId' +} + +export interface FindAvailableSSOIDP { + type: IdentityProviderType + id: Scalars['UUID'] + issuer: Scalars['String'] + name: Scalars['String'] + status: SSOIdentityProviderStatus + workspace: WorkspaceNameAndId + __typename: 'FindAvailableSSOIDP' +} + +export interface SetupSso { + id: Scalars['UUID'] + type: IdentityProviderType + issuer: Scalars['String'] + name: Scalars['String'] + status: SSOIdentityProviderStatus + __typename: 'SetupSso' +} + export interface SSOConnection { type: IdentityProviderType id: Scalars['UUID'] @@ -1201,10 +1761,6 @@ export interface SSOConnection { __typename: 'SSOConnection' } -export type IdentityProviderType = 'OIDC' | 'SAML' - -export type SSOIdentityProviderStatus = 'Active' | 'Inactive' | 'Error' - export interface AvailableWorkspace { id: Scalars['UUID'] displayName?: Scalars['String'] @@ -1256,49 +1812,6 @@ export interface DomainValidRecords { __typename: 'DomainValidRecords' } -export interface FeatureFlag { - key: FeatureFlagKey - value: Scalars['Boolean'] - __typename: 'FeatureFlag' -} - -export type FeatureFlagKey = 'IS_UNIQUE_INDEXES_ENABLED' | 'IS_JSON_FILTER_ENABLED' | 'IS_AI_ENABLED' | 'IS_APPLICATION_ENABLED' | 'IS_MARKETPLACE_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_EDITING_ENABLED' | 'IS_PUBLIC_DOMAIN_ENABLED' | 'IS_EMAILING_DOMAIN_ENABLED' | 'IS_DASHBOARD_V2_ENABLED' | 'IS_ATTACHMENT_MIGRATED' | 'IS_NOTE_TARGET_MIGRATED' | 'IS_TASK_TARGET_MIGRATED' | 'IS_ROW_LEVEL_PERMISSION_PREDICATES_ENABLED' | 'IS_JUNCTION_RELATIONS_ENABLED' | 'IS_COMMAND_MENU_ITEM_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_ENABLED' | 'IS_DATE_TIME_WHOLE_DAY_FILTER_ENABLED' | 'IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED' | 'IS_DRAFT_EMAIL_ENABLED' | 'IS_USAGE_ANALYTICS_ENABLED' | 'IS_RICH_TEXT_V1_MIGRATED' | 'IS_DIRECT_GRAPHQL_EXECUTION_ENABLED' | 'IS_RECORD_PAGE_LAYOUT_GLOBAL_EDITION_ENABLED' | 'IS_CONNECTED_ACCOUNT_MIGRATED' | 'IS_GRAPHQL_QUERY_TIMING_ENABLED' - -export interface SSOIdentityProvider { - id: Scalars['UUID'] - name: Scalars['String'] - type: IdentityProviderType - status: SSOIdentityProviderStatus - issuer: Scalars['String'] - __typename: 'SSOIdentityProvider' -} - -export interface AuthProviders { - sso: SSOIdentityProvider[] - google: Scalars['Boolean'] - magicLink: Scalars['Boolean'] - password: Scalars['Boolean'] - microsoft: Scalars['Boolean'] - __typename: 'AuthProviders' -} - -export interface AuthBypassProviders { - google: Scalars['Boolean'] - password: Scalars['Boolean'] - microsoft: Scalars['Boolean'] - __typename: 'AuthBypassProviders' -} - -export interface PublicWorkspaceData { - id: Scalars['UUID'] - authProviders: AuthProviders - authBypassProviders?: AuthBypassProviders - logo?: Scalars['String'] - displayName?: Scalars['String'] - workspaceUrls: WorkspaceUrls - __typename: 'PublicWorkspaceData' -} - export interface IndexEdge { /** The node containing the Index */ node: Index @@ -1403,39 +1916,6 @@ export interface UpsertRowLevelPermissionPredicatesResult { __typename: 'UpsertRowLevelPermissionPredicatesResult' } -export interface VersionDistributionEntry { - version: Scalars['String'] - count: Scalars['Int'] - __typename: 'VersionDistributionEntry' -} - -export interface ApplicationRegistrationStats { - activeInstalls: Scalars['Int'] - mostInstalledVersion?: Scalars['String'] - versionDistribution: VersionDistributionEntry[] - __typename: 'ApplicationRegistrationStats' -} - -export interface CreateApplicationRegistration { - applicationRegistration: ApplicationRegistration - clientSecret: Scalars['String'] - __typename: 'CreateApplicationRegistration' -} - -export interface PublicApplicationRegistration { - id: Scalars['UUID'] - name: Scalars['String'] - logoUrl?: Scalars['String'] - websiteUrl?: Scalars['String'] - oAuthScopes: Scalars['String'][] - __typename: 'PublicApplicationRegistration' -} - -export interface RotateClientSecret { - clientSecret: Scalars['String'] - __typename: 'RotateClientSecret' -} - export interface Relation { type: RelationType sourceObjectMetadata: Object @@ -1457,45 +1937,6 @@ export interface FieldConnection { __typename: 'FieldConnection' } -export interface DeleteSso { - identityProviderId: Scalars['UUID'] - __typename: 'DeleteSso' -} - -export interface EditSso { - id: Scalars['UUID'] - type: IdentityProviderType - issuer: Scalars['String'] - name: Scalars['String'] - status: SSOIdentityProviderStatus - __typename: 'EditSso' -} - -export interface WorkspaceNameAndId { - displayName?: Scalars['String'] - id: Scalars['UUID'] - __typename: 'WorkspaceNameAndId' -} - -export interface FindAvailableSSOIDP { - type: IdentityProviderType - id: Scalars['UUID'] - issuer: Scalars['String'] - name: Scalars['String'] - status: SSOIdentityProviderStatus - workspace: WorkspaceNameAndId - __typename: 'FindAvailableSSOIDP' -} - -export interface SetupSso { - id: Scalars['UUID'] - type: IdentityProviderType - issuer: Scalars['String'] - name: Scalars['String'] - status: SSOIdentityProviderStatus - __typename: 'SetupSso' -} - export interface DeleteTwoFactorAuthenticationMethod { /** Boolean that confirms query was dispatched */ success: Scalars['Boolean'] @@ -1611,100 +2052,251 @@ export interface WorkspaceInviteHashValid { __typename: 'WorkspaceInviteHashValid' } -export interface RecordIdentifier { - id: Scalars['UUID'] - labelIdentifier: Scalars['String'] - imageIdentifier?: Scalars['String'] - __typename: 'RecordIdentifier' +export interface Impersonate { + loginToken: AuthToken + workspace: WorkspaceUrlsAndId + __typename: 'Impersonate' } -export interface NavigationMenuItem { +export interface DevelopmentApplication { + id: Scalars['String'] + universalIdentifier: Scalars['String'] + __typename: 'DevelopmentApplication' +} + +export interface WorkspaceMigration { + applicationUniversalIdentifier: Scalars['String'] + actions: Scalars['JSON'] + __typename: 'WorkspaceMigration' +} + +export interface ApplicationTokenPair { + applicationAccessToken: AuthToken + applicationRefreshToken: AuthToken + __typename: 'ApplicationTokenPair' +} + +export interface File { id: Scalars['UUID'] - userWorkspaceId?: Scalars['UUID'] - targetRecordId?: Scalars['UUID'] - targetObjectMetadataId?: Scalars['UUID'] - viewId?: Scalars['UUID'] - type: NavigationMenuItemType - name?: Scalars['String'] - link?: Scalars['String'] + path: Scalars['String'] + size: Scalars['Float'] + createdAt: Scalars['DateTime'] + __typename: 'File' +} + +export interface MarketplaceAppField { + name: Scalars['String'] + type: Scalars['String'] + label: Scalars['String'] + description?: Scalars['String'] icon?: Scalars['String'] - color?: Scalars['String'] - folderId?: Scalars['UUID'] - position: Scalars['Float'] - applicationId?: Scalars['UUID'] + objectUniversalIdentifier?: Scalars['String'] + universalIdentifier?: Scalars['String'] + __typename: 'MarketplaceAppField' +} + +export interface MarketplaceAppObject { + universalIdentifier: Scalars['String'] + nameSingular: Scalars['String'] + namePlural: Scalars['String'] + labelSingular: Scalars['String'] + labelPlural: Scalars['String'] + description?: Scalars['String'] + icon?: Scalars['String'] + fields: MarketplaceAppField[] + __typename: 'MarketplaceAppObject' +} + +export interface MarketplaceAppLogicFunction { + name: Scalars['String'] + description?: Scalars['String'] + timeoutSeconds?: Scalars['Int'] + __typename: 'MarketplaceAppLogicFunction' +} + +export interface MarketplaceAppFrontComponent { + name: Scalars['String'] + description?: Scalars['String'] + __typename: 'MarketplaceAppFrontComponent' +} + +export interface MarketplaceAppRoleObjectPermission { + objectUniversalIdentifier: Scalars['String'] + canReadObjectRecords?: Scalars['Boolean'] + canUpdateObjectRecords?: Scalars['Boolean'] + canSoftDeleteObjectRecords?: Scalars['Boolean'] + canDestroyObjectRecords?: Scalars['Boolean'] + __typename: 'MarketplaceAppRoleObjectPermission' +} + +export interface MarketplaceAppRoleFieldPermission { + objectUniversalIdentifier: Scalars['String'] + fieldUniversalIdentifier: Scalars['String'] + canReadFieldValue?: Scalars['Boolean'] + canUpdateFieldValue?: Scalars['Boolean'] + __typename: 'MarketplaceAppRoleFieldPermission' +} + +export interface MarketplaceAppDefaultRole { + id: Scalars['String'] + label: Scalars['String'] + description?: Scalars['String'] + canReadAllObjectRecords: Scalars['Boolean'] + canUpdateAllObjectRecords: Scalars['Boolean'] + canSoftDeleteAllObjectRecords: Scalars['Boolean'] + canDestroyAllObjectRecords: Scalars['Boolean'] + canUpdateAllSettings: Scalars['Boolean'] + canAccessAllTools: Scalars['Boolean'] + objectPermissions: MarketplaceAppRoleObjectPermission[] + fieldPermissions: MarketplaceAppRoleFieldPermission[] + permissionFlags: Scalars['String'][] + __typename: 'MarketplaceAppDefaultRole' +} + +export interface MarketplaceApp { + id: Scalars['String'] + name: Scalars['String'] + description: Scalars['String'] + icon: Scalars['String'] + version: Scalars['String'] + author: Scalars['String'] + category: Scalars['String'] + logo?: Scalars['String'] + screenshots: Scalars['String'][] + aboutDescription: Scalars['String'] + providers: Scalars['String'][] + websiteUrl?: Scalars['String'] + termsUrl?: Scalars['String'] + objects: MarketplaceAppObject[] + fields: MarketplaceAppField[] + logicFunctions: MarketplaceAppLogicFunction[] + frontComponents: MarketplaceAppFrontComponent[] + defaultRole?: MarketplaceAppDefaultRole + sourcePackage?: Scalars['String'] + isFeatured: Scalars['Boolean'] + __typename: 'MarketplaceApp' +} + +export interface PublicDomain { + id: Scalars['UUID'] + domain: Scalars['String'] + isValidated: Scalars['Boolean'] + createdAt: Scalars['DateTime'] + __typename: 'PublicDomain' +} + +export interface VerificationRecord { + type: Scalars['String'] + key: Scalars['String'] + value: Scalars['String'] + priority?: Scalars['Float'] + __typename: 'VerificationRecord' +} + +export interface EmailingDomain { + id: Scalars['UUID'] createdAt: Scalars['DateTime'] updatedAt: Scalars['DateTime'] - targetRecordIdentifier?: RecordIdentifier - __typename: 'NavigationMenuItem' + domain: Scalars['String'] + driver: EmailingDomainDriver + status: EmailingDomainStatus + verificationRecords?: VerificationRecord[] + verifiedAt?: Scalars['DateTime'] + __typename: 'EmailingDomain' } -export type NavigationMenuItemType = 'VIEW' | 'FOLDER' | 'LINK' | 'OBJECT' | 'RECORD' +export type EmailingDomainDriver = 'AWS_SES' -export interface ObjectRecordEventProperties { - updatedFields?: Scalars['String'][] - before?: Scalars['JSON'] - after?: Scalars['JSON'] - diff?: Scalars['JSON'] - __typename: 'ObjectRecordEventProperties' +export type EmailingDomainStatus = 'PENDING' | 'VERIFIED' | 'FAILED' | 'TEMPORARY_FAILURE' + +export interface AutocompleteResult { + text: Scalars['String'] + placeId: Scalars['String'] + __typename: 'AutocompleteResult' } -export interface MetadataEvent { - type: MetadataEventAction - metadataName: Scalars['String'] - recordId: Scalars['String'] - properties: ObjectRecordEventProperties - updatedCollectionHash?: Scalars['String'] - __typename: 'MetadataEvent' +export interface Location { + lat?: Scalars['Float'] + lng?: Scalars['Float'] + __typename: 'Location' } - -/** Metadata Event Action */ -export type MetadataEventAction = 'CREATED' | 'UPDATED' | 'DELETED' - -export interface ObjectRecordEvent { - action: DatabaseEventAction - objectNameSingular: Scalars['String'] - recordId: Scalars['String'] - userId?: Scalars['String'] - workspaceMemberId?: Scalars['String'] - properties: ObjectRecordEventProperties - __typename: 'ObjectRecordEvent' +export interface PlaceDetailsResult { + state?: Scalars['String'] + postcode?: Scalars['String'] + city?: Scalars['String'] + country?: Scalars['String'] + location?: Location + __typename: 'PlaceDetailsResult' } - -/** Database Event Action */ -export type DatabaseEventAction = 'CREATED' | 'UPDATED' | 'DELETED' | 'DESTROYED' | 'RESTORED' | 'UPSERTED' - -export interface ObjectRecordEventWithQueryIds { - queryIds: Scalars['String'][] - objectRecordEvent: ObjectRecordEvent - __typename: 'ObjectRecordEventWithQueryIds' +export interface ConnectionParametersOutput { + host: Scalars['String'] + port: Scalars['Float'] + username?: Scalars['String'] + password: Scalars['String'] + secure?: Scalars['Boolean'] + __typename: 'ConnectionParametersOutput' } -export interface EventSubscription { - eventStreamId: Scalars['String'] - objectRecordEventsWithQueryIds: ObjectRecordEventWithQueryIds[] - metadataEvents: MetadataEvent[] - __typename: 'EventSubscription' +export interface ImapSmtpCaldavConnectionParameters { + IMAP?: ConnectionParametersOutput + SMTP?: ConnectionParametersOutput + CALDAV?: ConnectionParametersOutput + __typename: 'ImapSmtpCaldavConnectionParameters' } -export interface LogicFunctionExecutionResult { - /** Execution result in JSON format */ - data?: Scalars['JSON'] - /** Execution Logs */ - logs: Scalars['String'] - /** Execution duration in milliseconds */ - duration: Scalars['Float'] - /** Execution status */ - status: LogicFunctionExecutionStatus - /** Execution error in JSON format */ - error?: Scalars['JSON'] - __typename: 'LogicFunctionExecutionResult' +export interface ConnectedImapSmtpCaldavAccount { + id: Scalars['UUID'] + handle: Scalars['String'] + provider: Scalars['String'] + accountOwnerId: Scalars['UUID'] + connectionParameters?: ImapSmtpCaldavConnectionParameters + __typename: 'ConnectedImapSmtpCaldavAccount' } +export interface ImapSmtpCaldavConnectionSuccess { + success: Scalars['Boolean'] + connectedAccountId: Scalars['String'] + __typename: 'ImapSmtpCaldavConnectionSuccess' +} -/** Status of the logic function execution */ -export type LogicFunctionExecutionStatus = 'IDLE' | 'SUCCESS' | 'ERROR' +export interface PostgresCredentials { + id: Scalars['UUID'] + user: Scalars['String'] + password: Scalars['String'] + workspaceId: Scalars['UUID'] + __typename: 'PostgresCredentials' +} + +export interface UsageBreakdownItem { + key: Scalars['String'] + label?: Scalars['String'] + creditsUsed: Scalars['Float'] + __typename: 'UsageBreakdownItem' +} + +export interface UsageTimeSeries { + date: Scalars['String'] + creditsUsed: Scalars['Float'] + __typename: 'UsageTimeSeries' +} + +export interface UsageUserDaily { + userWorkspaceId: Scalars['String'] + dailyUsage: UsageTimeSeries[] + __typename: 'UsageUserDaily' +} + +export interface UsageAnalytics { + usageByUser: UsageBreakdownItem[] + usageByOperationType: UsageBreakdownItem[] + timeSeries: UsageTimeSeries[] + periodStart: Scalars['DateTime'] + periodEnd: Scalars['DateTime'] + userDailyUsage?: UsageUserDaily + __typename: 'UsageAnalytics' +} export interface LogicFunctionLogs { /** Execution Logs */ @@ -1712,6 +2304,49 @@ export interface LogicFunctionLogs { __typename: 'LogicFunctionLogs' } +export interface FrontComponent { + id: Scalars['UUID'] + name: Scalars['String'] + description?: Scalars['String'] + sourceComponentPath: Scalars['String'] + builtComponentPath: Scalars['String'] + componentName: Scalars['String'] + builtComponentChecksum: Scalars['String'] + universalIdentifier?: Scalars['UUID'] + applicationId: Scalars['UUID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + isHeadless: Scalars['Boolean'] + usesSdkClient: Scalars['Boolean'] + applicationTokenPair?: ApplicationTokenPair + __typename: 'FrontComponent' +} + +export interface CommandMenuItem { + id: Scalars['UUID'] + workflowVersionId?: Scalars['UUID'] + frontComponentId?: Scalars['UUID'] + frontComponent?: FrontComponent + engineComponentKey: EngineComponentKey + label: Scalars['String'] + icon?: Scalars['String'] + shortLabel?: Scalars['String'] + position: Scalars['Float'] + isPinned: Scalars['Boolean'] + availabilityType: CommandMenuItemAvailabilityType + hotKeys?: Scalars['String'][] + conditionalAvailabilityExpression?: Scalars['String'] + availabilityObjectMetadataId?: Scalars['UUID'] + applicationId?: Scalars['UUID'] + createdAt: Scalars['DateTime'] + updatedAt: Scalars['DateTime'] + __typename: 'CommandMenuItem' +} + +export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'EXPORT_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'GO_TO_WORKFLOWS' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'GO_TO_RUNS' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' + +export type CommandMenuItemAvailabilityType = 'GLOBAL' | 'RECORD_SELECTION' | 'FALLBACK' + export interface ToolIndexEntry { name: Scalars['String'] description: Scalars['String'] @@ -1751,6 +2386,107 @@ export interface AgentMessagePart { __typename: 'AgentMessagePart' } +export interface ChannelSyncSuccess { + success: Scalars['Boolean'] + __typename: 'ChannelSyncSuccess' +} + +export interface BarChartSeries { + key: Scalars['String'] + label: Scalars['String'] + __typename: 'BarChartSeries' +} + +export interface BarChartData { + data: Scalars['JSON'][] + indexBy: Scalars['String'] + keys: Scalars['String'][] + series: BarChartSeries[] + xAxisLabel: Scalars['String'] + yAxisLabel: Scalars['String'] + showLegend: Scalars['Boolean'] + showDataLabels: Scalars['Boolean'] + layout: BarChartLayout + groupMode: BarChartGroupMode + hasTooManyGroups: Scalars['Boolean'] + formattedToRawLookup: Scalars['JSON'] + __typename: 'BarChartData' +} + +export interface LineChartDataPoint { + x: Scalars['String'] + y: Scalars['Float'] + __typename: 'LineChartDataPoint' +} + +export interface LineChartSeries { + id: Scalars['String'] + label: Scalars['String'] + data: LineChartDataPoint[] + __typename: 'LineChartSeries' +} + +export interface LineChartData { + series: LineChartSeries[] + xAxisLabel: Scalars['String'] + yAxisLabel: Scalars['String'] + showLegend: Scalars['Boolean'] + showDataLabels: Scalars['Boolean'] + hasTooManyGroups: Scalars['Boolean'] + formattedToRawLookup: Scalars['JSON'] + __typename: 'LineChartData' +} + +export interface PieChartDataItem { + id: Scalars['String'] + value: Scalars['Float'] + __typename: 'PieChartDataItem' +} + +export interface PieChartData { + data: PieChartDataItem[] + showLegend: Scalars['Boolean'] + showDataLabels: Scalars['Boolean'] + showCenterMetric: Scalars['Boolean'] + hasTooManyGroups: Scalars['Boolean'] + formattedToRawLookup: Scalars['JSON'] + __typename: 'PieChartData' +} + +export interface DuplicatedDashboard { + id: Scalars['UUID'] + title?: Scalars['String'] + pageLayoutId?: Scalars['UUID'] + position: Scalars['Float'] + createdAt: Scalars['String'] + updatedAt: Scalars['String'] + __typename: 'DuplicatedDashboard' +} + +export interface EventLogRecord { + event: Scalars['String'] + timestamp: Scalars['DateTime'] + userId?: Scalars['String'] + properties?: Scalars['JSON'] + recordId?: Scalars['String'] + objectMetadataId?: Scalars['String'] + isCustom?: Scalars['Boolean'] + __typename: 'EventLogRecord' +} + +export interface EventLogPageInfo { + endCursor?: Scalars['String'] + hasNextPage: Scalars['Boolean'] + __typename: 'EventLogPageInfo' +} + +export interface EventLogQueryResult { + records: EventLogRecord[] + totalCount: Scalars['Int'] + pageInfo: EventLogPageInfo + __typename: 'EventLogQueryResult' +} + export interface Skill { id: Scalars['UUID'] name: Scalars['String'] @@ -1766,54 +2502,6 @@ export interface Skill { __typename: 'Skill' } -export interface ApplicationTokenPair { - applicationAccessToken: AuthToken - applicationRefreshToken: AuthToken - __typename: 'ApplicationTokenPair' -} - -export interface FrontComponent { - id: Scalars['UUID'] - name: Scalars['String'] - description?: Scalars['String'] - sourceComponentPath: Scalars['String'] - builtComponentPath: Scalars['String'] - componentName: Scalars['String'] - builtComponentChecksum: Scalars['String'] - universalIdentifier?: Scalars['UUID'] - applicationId: Scalars['UUID'] - createdAt: Scalars['DateTime'] - updatedAt: Scalars['DateTime'] - isHeadless: Scalars['Boolean'] - applicationTokenPair?: ApplicationTokenPair - __typename: 'FrontComponent' -} - -export interface CommandMenuItem { - id: Scalars['UUID'] - workflowVersionId?: Scalars['UUID'] - frontComponentId?: Scalars['UUID'] - frontComponent?: FrontComponent - engineComponentKey: EngineComponentKey - label: Scalars['String'] - icon?: Scalars['String'] - shortLabel?: Scalars['String'] - position: Scalars['Float'] - isPinned: Scalars['Boolean'] - availabilityType: CommandMenuItemAvailabilityType - hotKeys?: Scalars['String'][] - conditionalAvailabilityExpression?: Scalars['String'] - availabilityObjectMetadataId?: Scalars['UUID'] - applicationId?: Scalars['UUID'] - createdAt: Scalars['DateTime'] - updatedAt: Scalars['DateTime'] - __typename: 'CommandMenuItem' -} - -export type EngineComponentKey = 'NAVIGATE_TO_NEXT_RECORD' | 'NAVIGATE_TO_PREVIOUS_RECORD' | 'CREATE_NEW_RECORD' | 'DELETE_SINGLE_RECORD' | 'DELETE_MULTIPLE_RECORDS' | 'RESTORE_SINGLE_RECORD' | 'RESTORE_MULTIPLE_RECORDS' | 'DESTROY_SINGLE_RECORD' | 'DESTROY_MULTIPLE_RECORDS' | 'ADD_TO_FAVORITES' | 'REMOVE_FROM_FAVORITES' | 'EXPORT_NOTE_TO_PDF' | 'EXPORT_FROM_RECORD_INDEX' | 'EXPORT_FROM_RECORD_SHOW' | 'UPDATE_MULTIPLE_RECORDS' | 'MERGE_MULTIPLE_RECORDS' | 'EXPORT_MULTIPLE_RECORDS' | 'IMPORT_RECORDS' | 'EXPORT_VIEW' | 'SEE_DELETED_RECORDS' | 'CREATE_NEW_VIEW' | 'HIDE_DELETED_RECORDS' | 'GO_TO_PEOPLE' | 'GO_TO_COMPANIES' | 'GO_TO_DASHBOARDS' | 'GO_TO_OPPORTUNITIES' | 'GO_TO_SETTINGS' | 'GO_TO_TASKS' | 'GO_TO_NOTES' | 'EDIT_RECORD_PAGE_LAYOUT' | 'EDIT_DASHBOARD_LAYOUT' | 'SAVE_DASHBOARD_LAYOUT' | 'CANCEL_DASHBOARD_LAYOUT' | 'DUPLICATE_DASHBOARD' | 'GO_TO_WORKFLOWS' | 'ACTIVATE_WORKFLOW' | 'DEACTIVATE_WORKFLOW' | 'DISCARD_DRAFT_WORKFLOW' | 'TEST_WORKFLOW' | 'SEE_ACTIVE_VERSION_WORKFLOW' | 'SEE_RUNS_WORKFLOW' | 'SEE_VERSIONS_WORKFLOW' | 'ADD_NODE_WORKFLOW' | 'TIDY_UP_WORKFLOW' | 'DUPLICATE_WORKFLOW' | 'GO_TO_RUNS' | 'SEE_VERSION_WORKFLOW_RUN' | 'SEE_WORKFLOW_WORKFLOW_RUN' | 'STOP_WORKFLOW_RUN' | 'SEE_RUNS_WORKFLOW_VERSION' | 'SEE_WORKFLOW_WORKFLOW_VERSION' | 'USE_AS_DRAFT_WORKFLOW_VERSION' | 'SEE_VERSIONS_WORKFLOW_VERSION' | 'SEARCH_RECORDS' | 'SEARCH_RECORDS_FALLBACK' | 'ASK_AI' | 'VIEW_PREVIOUS_AI_CHATS' | 'TRIGGER_WORKFLOW_VERSION' | 'FRONT_COMPONENT_RENDERER' - -export type CommandMenuItemAvailabilityType = 'GLOBAL' | 'RECORD_SELECTION' | 'FALLBACK' - export interface AgentChatThread { id: Scalars['UUID'] title?: Scalars['String'] @@ -2033,708 +2721,35 @@ export interface Webhook { __typename: 'Webhook' } -export interface BillingTrialPeriod { - duration: Scalars['Float'] - isCreditCardRequired: Scalars['Boolean'] - __typename: 'BillingTrialPeriod' -} - -export interface NativeModelCapabilities { - webSearch?: Scalars['Boolean'] - twitterSearch?: Scalars['Boolean'] - __typename: 'NativeModelCapabilities' -} - -export interface ClientAIModelConfig { - modelId: Scalars['String'] - label: Scalars['String'] - modelFamily?: ModelFamily - modelFamilyLabel?: Scalars['String'] - sdkPackage?: Scalars['String'] - inputCostPerMillionTokensInCredits: Scalars['Float'] - outputCostPerMillionTokensInCredits: Scalars['Float'] - nativeCapabilities?: NativeModelCapabilities - isDeprecated?: Scalars['Boolean'] - isRecommended?: Scalars['Boolean'] - providerName?: Scalars['String'] - dataResidency?: Scalars['String'] - __typename: 'ClientAIModelConfig' -} - -export type ModelFamily = 'GPT' | 'CLAUDE' | 'GEMINI' | 'MISTRAL' | 'GROK' - -export interface AdminAIModelConfig { - modelId: Scalars['String'] - label: Scalars['String'] - modelFamily?: ModelFamily - modelFamilyLabel?: Scalars['String'] - sdkPackage?: Scalars['String'] - isAvailable: Scalars['Boolean'] - isAdminEnabled: Scalars['Boolean'] - isDeprecated?: Scalars['Boolean'] - isRecommended?: Scalars['Boolean'] - contextWindowTokens?: Scalars['Float'] - maxOutputTokens?: Scalars['Float'] - inputCostPerMillionTokens?: Scalars['Float'] - outputCostPerMillionTokens?: Scalars['Float'] - providerName?: Scalars['String'] - providerLabel?: Scalars['String'] - name?: Scalars['String'] - dataResidency?: Scalars['String'] - __typename: 'AdminAIModelConfig' -} - -export interface AdminAIModels { - models: AdminAIModelConfig[] - defaultSmartModelId?: Scalars['String'] - defaultFastModelId?: Scalars['String'] - __typename: 'AdminAIModels' -} - -export interface Billing { - isBillingEnabled: Scalars['Boolean'] - billingUrl?: Scalars['String'] - trialPeriods: BillingTrialPeriod[] - __typename: 'Billing' -} - -export interface Support { - supportDriver: SupportDriver - supportFrontChatId?: Scalars['String'] - __typename: 'Support' -} - -export type SupportDriver = 'NONE' | 'FRONT' - -export interface Sentry { - environment?: Scalars['String'] - release?: Scalars['String'] - dsn?: Scalars['String'] - __typename: 'Sentry' -} - -export interface Captcha { - provider?: CaptchaDriverType - siteKey?: Scalars['String'] - __typename: 'Captcha' -} - -export type CaptchaDriverType = 'GOOGLE_RECAPTCHA' | 'TURNSTILE' - -export interface ApiConfig { - mutationMaximumAffectedRecords: Scalars['Float'] - __typename: 'ApiConfig' -} - -export interface PublicFeatureFlagMetadata { - label: Scalars['String'] - description: Scalars['String'] - imagePath?: Scalars['String'] - __typename: 'PublicFeatureFlagMetadata' -} - -export interface PublicFeatureFlag { - key: FeatureFlagKey - metadata: PublicFeatureFlagMetadata - __typename: 'PublicFeatureFlag' -} - -export interface ClientConfig { - appVersion?: Scalars['String'] - authProviders: AuthProviders - billing: Billing - aiModels: ClientAIModelConfig[] - signInPrefilled: Scalars['Boolean'] - isMultiWorkspaceEnabled: Scalars['Boolean'] - isEmailVerificationRequired: Scalars['Boolean'] - defaultSubdomain?: Scalars['String'] - frontDomain: Scalars['String'] - analyticsEnabled: Scalars['Boolean'] - support: Support - isAttachmentPreviewEnabled: Scalars['Boolean'] - sentry: Sentry - captcha: Captcha - api: ApiConfig - canManageFeatureFlags: Scalars['Boolean'] - publicFeatureFlags: PublicFeatureFlag[] - isMicrosoftMessagingEnabled: Scalars['Boolean'] - isMicrosoftCalendarEnabled: Scalars['Boolean'] - isGoogleMessagingEnabled: Scalars['Boolean'] - isGoogleCalendarEnabled: Scalars['Boolean'] - isConfigVariablesInDbEnabled: Scalars['Boolean'] - isImapSmtpCaldavEnabled: Scalars['Boolean'] - allowRequestsToTwentyIcons: Scalars['Boolean'] - calendarBookingPageId?: Scalars['String'] - isCloudflareIntegrationEnabled: Scalars['Boolean'] - isClickHouseConfigured: Scalars['Boolean'] - __typename: 'ClientConfig' -} - -export interface ConfigVariable { - name: Scalars['String'] - description: Scalars['String'] - value?: Scalars['JSON'] - isSensitive: Scalars['Boolean'] - source: ConfigSource - isEnvOnly: Scalars['Boolean'] - type: ConfigVariableType - options?: Scalars['JSON'] - __typename: 'ConfigVariable' -} - -export type ConfigSource = 'ENVIRONMENT' | 'DATABASE' | 'DEFAULT' - -export type ConfigVariableType = 'BOOLEAN' | 'NUMBER' | 'ARRAY' | 'STRING' | 'ENUM' | 'JSON' - -export interface ConfigVariablesGroupData { - variables: ConfigVariable[] - name: ConfigVariablesGroup - description: Scalars['String'] - isHiddenOnLoad: Scalars['Boolean'] - __typename: 'ConfigVariablesGroupData' -} - -export type ConfigVariablesGroup = 'SERVER_CONFIG' | 'RATE_LIMITING' | 'STORAGE_CONFIG' | 'GOOGLE_AUTH' | 'MICROSOFT_AUTH' | 'EMAIL_SETTINGS' | 'LOGGING' | 'ADVANCED_SETTINGS' | 'BILLING_CONFIG' | 'CAPTCHA_CONFIG' | 'CLOUDFLARE_CONFIG' | 'LLM' | 'LOGIC_FUNCTION_CONFIG' | 'CODE_INTERPRETER_CONFIG' | 'SSL' | 'SUPPORT_CHAT_CONFIG' | 'ANALYTICS_CONFIG' | 'TOKENS_DURATION' | 'AWS_SES_SETTINGS' - -export interface ConfigVariables { - groups: ConfigVariablesGroupData[] - __typename: 'ConfigVariables' -} - -export interface JobOperationResult { - jobId: Scalars['String'] - success: Scalars['Boolean'] - error?: Scalars['String'] - __typename: 'JobOperationResult' -} - -export interface DeleteJobsResponse { - deletedCount: Scalars['Int'] - results: JobOperationResult[] - __typename: 'DeleteJobsResponse' -} - -export interface QueueJob { - id: Scalars['String'] - name: Scalars['String'] - data?: Scalars['JSON'] - state: JobState - timestamp?: Scalars['Float'] - failedReason?: Scalars['String'] - processedOn?: Scalars['Float'] - finishedOn?: Scalars['Float'] - attemptsMade: Scalars['Float'] - returnValue?: Scalars['JSON'] - logs?: Scalars['String'][] - stackTrace?: Scalars['String'][] - __typename: 'QueueJob' -} - - -/** Job state in the queue */ -export type JobState = 'COMPLETED' | 'FAILED' | 'ACTIVE' | 'WAITING' | 'DELAYED' | 'PRIORITIZED' | 'WAITING_CHILDREN' - -export interface QueueRetentionConfig { - completedMaxAge: Scalars['Float'] - completedMaxCount: Scalars['Float'] - failedMaxAge: Scalars['Float'] - failedMaxCount: Scalars['Float'] - __typename: 'QueueRetentionConfig' -} - -export interface QueueJobsResponse { - jobs: QueueJob[] - count: Scalars['Float'] - totalCount: Scalars['Float'] - hasMore: Scalars['Boolean'] - retentionConfig: QueueRetentionConfig - __typename: 'QueueJobsResponse' -} - -export interface RetryJobsResponse { - retriedCount: Scalars['Int'] - results: JobOperationResult[] - __typename: 'RetryJobsResponse' -} - -export interface SystemHealthService { - id: HealthIndicatorId - label: Scalars['String'] - status: AdminPanelHealthServiceStatus - __typename: 'SystemHealthService' -} - -export type HealthIndicatorId = 'database' | 'redis' | 'worker' | 'connectedAccount' | 'app' - -export type AdminPanelHealthServiceStatus = 'OPERATIONAL' | 'OUTAGE' - -export interface SystemHealth { - services: SystemHealthService[] - __typename: 'SystemHealth' -} - -export interface UserInfo { - id: Scalars['UUID'] - email: Scalars['String'] - firstName?: Scalars['String'] - lastName?: Scalars['String'] - __typename: 'UserInfo' -} - -export interface WorkspaceInfo { - id: Scalars['UUID'] - name: Scalars['String'] - allowImpersonation: Scalars['Boolean'] - logo?: Scalars['String'] - totalUsers: Scalars['Float'] - workspaceUrls: WorkspaceUrls - users: UserInfo[] - featureFlags: FeatureFlag[] - __typename: 'WorkspaceInfo' -} - -export interface UserLookup { - user: UserInfo - workspaces: WorkspaceInfo[] - __typename: 'UserLookup' -} - -export interface VersionInfo { - currentVersion?: Scalars['String'] - latestVersion: Scalars['String'] - __typename: 'VersionInfo' -} - -export interface AdminPanelWorkerQueueHealth { - id: Scalars['String'] - queueName: Scalars['String'] - status: AdminPanelHealthServiceStatus - __typename: 'AdminPanelWorkerQueueHealth' -} - -export interface AdminPanelHealthServiceData { - id: HealthIndicatorId - label: Scalars['String'] - description: Scalars['String'] - status: AdminPanelHealthServiceStatus - errorMessage?: Scalars['String'] - details?: Scalars['String'] - queues?: AdminPanelWorkerQueueHealth[] - __typename: 'AdminPanelHealthServiceData' -} - -export interface ModelsDevModelSuggestion { - modelId: Scalars['String'] - name: Scalars['String'] - inputCostPerMillionTokens: Scalars['Float'] - outputCostPerMillionTokens: Scalars['Float'] - cachedInputCostPerMillionTokens?: Scalars['Float'] - cacheCreationCostPerMillionTokens?: Scalars['Float'] - contextWindowTokens: Scalars['Float'] - maxOutputTokens: Scalars['Float'] - modalities: Scalars['String'][] - supportsReasoning: Scalars['Boolean'] - __typename: 'ModelsDevModelSuggestion' -} - -export interface ModelsDevProviderSuggestion { - id: Scalars['String'] - modelCount: Scalars['Float'] - npm: Scalars['String'] - __typename: 'ModelsDevProviderSuggestion' -} - -export interface QueueMetricsDataPoint { - x: Scalars['Float'] - y: Scalars['Float'] - __typename: 'QueueMetricsDataPoint' -} - -export interface QueueMetricsSeries { - id: Scalars['String'] - data: QueueMetricsDataPoint[] - __typename: 'QueueMetricsSeries' -} - -export interface WorkerQueueMetrics { - failed: Scalars['Float'] - completed: Scalars['Float'] - waiting: Scalars['Float'] - active: Scalars['Float'] - delayed: Scalars['Float'] - failureRate: Scalars['Float'] - failedData?: Scalars['Float'][] - completedData?: Scalars['Float'][] - __typename: 'WorkerQueueMetrics' -} - -export interface QueueMetricsData { - queueName: Scalars['String'] - workers: Scalars['Float'] - timeRange: QueueMetricsTimeRange - details?: WorkerQueueMetrics - data: QueueMetricsSeries[] - __typename: 'QueueMetricsData' -} - -export type QueueMetricsTimeRange = 'SevenDays' | 'OneDay' | 'TwelveHours' | 'FourHours' | 'OneHour' - -export interface Impersonate { - loginToken: AuthToken - workspace: WorkspaceUrlsAndId - __typename: 'Impersonate' -} - -export interface DevelopmentApplication { - id: Scalars['String'] - universalIdentifier: Scalars['String'] - __typename: 'DevelopmentApplication' -} - -export interface WorkspaceMigration { - applicationUniversalIdentifier: Scalars['String'] - actions: Scalars['JSON'] - __typename: 'WorkspaceMigration' -} - -export interface File { - id: Scalars['UUID'] - path: Scalars['String'] - size: Scalars['Float'] - createdAt: Scalars['DateTime'] - __typename: 'File' -} - -export interface MarketplaceAppField { - name: Scalars['String'] - type: Scalars['String'] - label: Scalars['String'] - description?: Scalars['String'] - icon?: Scalars['String'] - objectUniversalIdentifier?: Scalars['String'] - universalIdentifier?: Scalars['String'] - __typename: 'MarketplaceAppField' -} - -export interface MarketplaceAppObject { - universalIdentifier: Scalars['String'] - nameSingular: Scalars['String'] - namePlural: Scalars['String'] - labelSingular: Scalars['String'] - labelPlural: Scalars['String'] - description?: Scalars['String'] - icon?: Scalars['String'] - fields: MarketplaceAppField[] - __typename: 'MarketplaceAppObject' -} - -export interface MarketplaceAppLogicFunction { - name: Scalars['String'] - description?: Scalars['String'] - timeoutSeconds?: Scalars['Int'] - __typename: 'MarketplaceAppLogicFunction' -} - -export interface MarketplaceAppFrontComponent { - name: Scalars['String'] - description?: Scalars['String'] - __typename: 'MarketplaceAppFrontComponent' -} - -export interface MarketplaceAppRoleObjectPermission { - objectUniversalIdentifier: Scalars['String'] - canReadObjectRecords?: Scalars['Boolean'] - canUpdateObjectRecords?: Scalars['Boolean'] - canSoftDeleteObjectRecords?: Scalars['Boolean'] - canDestroyObjectRecords?: Scalars['Boolean'] - __typename: 'MarketplaceAppRoleObjectPermission' -} - -export interface MarketplaceAppRoleFieldPermission { - objectUniversalIdentifier: Scalars['String'] - fieldUniversalIdentifier: Scalars['String'] - canReadFieldValue?: Scalars['Boolean'] - canUpdateFieldValue?: Scalars['Boolean'] - __typename: 'MarketplaceAppRoleFieldPermission' -} - -export interface MarketplaceAppDefaultRole { - id: Scalars['String'] - label: Scalars['String'] - description?: Scalars['String'] - canReadAllObjectRecords: Scalars['Boolean'] - canUpdateAllObjectRecords: Scalars['Boolean'] - canSoftDeleteAllObjectRecords: Scalars['Boolean'] - canDestroyAllObjectRecords: Scalars['Boolean'] - canUpdateAllSettings: Scalars['Boolean'] - canAccessAllTools: Scalars['Boolean'] - objectPermissions: MarketplaceAppRoleObjectPermission[] - fieldPermissions: MarketplaceAppRoleFieldPermission[] - permissionFlags: Scalars['String'][] - __typename: 'MarketplaceAppDefaultRole' -} - -export interface MarketplaceApp { - id: Scalars['String'] - name: Scalars['String'] - description: Scalars['String'] - icon: Scalars['String'] - version: Scalars['String'] - author: Scalars['String'] - category: Scalars['String'] - logo?: Scalars['String'] - screenshots: Scalars['String'][] - aboutDescription: Scalars['String'] - providers: Scalars['String'][] - websiteUrl?: Scalars['String'] - termsUrl?: Scalars['String'] - objects: MarketplaceAppObject[] - fields: MarketplaceAppField[] - logicFunctions: MarketplaceAppLogicFunction[] - frontComponents: MarketplaceAppFrontComponent[] - defaultRole?: MarketplaceAppDefaultRole - sourcePackage?: Scalars['String'] - isFeatured: Scalars['Boolean'] - __typename: 'MarketplaceApp' -} - -export interface UsageBreakdownItem { - key: Scalars['String'] - label?: Scalars['String'] - creditsUsed: Scalars['Float'] - __typename: 'UsageBreakdownItem' -} - -export interface UsageTimeSeries { - date: Scalars['String'] - creditsUsed: Scalars['Float'] - __typename: 'UsageTimeSeries' -} - -export interface UsageUserDaily { - userWorkspaceId: Scalars['String'] - dailyUsage: UsageTimeSeries[] - __typename: 'UsageUserDaily' -} - -export interface UsageAnalytics { - usageByUser: UsageBreakdownItem[] - usageByOperationType: UsageBreakdownItem[] - timeSeries: UsageTimeSeries[] - periodStart: Scalars['DateTime'] - periodEnd: Scalars['DateTime'] - userDailyUsage?: UsageUserDaily - __typename: 'UsageAnalytics' -} - -export interface PublicDomain { - id: Scalars['UUID'] - domain: Scalars['String'] - isValidated: Scalars['Boolean'] - createdAt: Scalars['DateTime'] - __typename: 'PublicDomain' -} - -export interface VerificationRecord { - type: Scalars['String'] - key: Scalars['String'] - value: Scalars['String'] - priority?: Scalars['Float'] - __typename: 'VerificationRecord' -} - -export interface EmailingDomain { - id: Scalars['UUID'] - createdAt: Scalars['DateTime'] - updatedAt: Scalars['DateTime'] - domain: Scalars['String'] - driver: EmailingDomainDriver - status: EmailingDomainStatus - verificationRecords?: VerificationRecord[] - verifiedAt?: Scalars['DateTime'] - __typename: 'EmailingDomain' -} - -export type EmailingDomainDriver = 'AWS_SES' - -export type EmailingDomainStatus = 'PENDING' | 'VERIFIED' | 'FAILED' | 'TEMPORARY_FAILURE' - -export interface AutocompleteResult { - text: Scalars['String'] - placeId: Scalars['String'] - __typename: 'AutocompleteResult' -} - -export interface Location { - lat?: Scalars['Float'] - lng?: Scalars['Float'] - __typename: 'Location' -} - -export interface PlaceDetailsResult { - state?: Scalars['String'] - postcode?: Scalars['String'] - city?: Scalars['String'] - country?: Scalars['String'] - location?: Location - __typename: 'PlaceDetailsResult' -} - -export interface ConnectionParametersOutput { - host: Scalars['String'] - port: Scalars['Float'] - username?: Scalars['String'] - password: Scalars['String'] - secure?: Scalars['Boolean'] - __typename: 'ConnectionParametersOutput' -} - -export interface ImapSmtpCaldavConnectionParameters { - IMAP?: ConnectionParametersOutput - SMTP?: ConnectionParametersOutput - CALDAV?: ConnectionParametersOutput - __typename: 'ImapSmtpCaldavConnectionParameters' -} - -export interface ConnectedImapSmtpCaldavAccount { - id: Scalars['UUID'] - handle: Scalars['String'] - provider: Scalars['String'] - accountOwnerId: Scalars['UUID'] - connectionParameters?: ImapSmtpCaldavConnectionParameters - __typename: 'ConnectedImapSmtpCaldavAccount' -} - -export interface ImapSmtpCaldavConnectionSuccess { - success: Scalars['Boolean'] - connectedAccountId: Scalars['String'] - __typename: 'ImapSmtpCaldavConnectionSuccess' -} - -export interface PostgresCredentials { - id: Scalars['UUID'] - user: Scalars['String'] - password: Scalars['String'] - workspaceId: Scalars['UUID'] - __typename: 'PostgresCredentials' -} - -export interface ChannelSyncSuccess { - success: Scalars['Boolean'] - __typename: 'ChannelSyncSuccess' -} - -export interface BarChartSeries { - key: Scalars['String'] - label: Scalars['String'] - __typename: 'BarChartSeries' -} - -export interface BarChartData { - data: Scalars['JSON'][] - indexBy: Scalars['String'] - keys: Scalars['String'][] - series: BarChartSeries[] - xAxisLabel: Scalars['String'] - yAxisLabel: Scalars['String'] - showLegend: Scalars['Boolean'] - showDataLabels: Scalars['Boolean'] - layout: BarChartLayout - groupMode: BarChartGroupMode - hasTooManyGroups: Scalars['Boolean'] - formattedToRawLookup: Scalars['JSON'] - __typename: 'BarChartData' -} - -export interface LineChartDataPoint { - x: Scalars['String'] - y: Scalars['Float'] - __typename: 'LineChartDataPoint' -} - -export interface LineChartSeries { - id: Scalars['String'] - label: Scalars['String'] - data: LineChartDataPoint[] - __typename: 'LineChartSeries' -} - -export interface LineChartData { - series: LineChartSeries[] - xAxisLabel: Scalars['String'] - yAxisLabel: Scalars['String'] - showLegend: Scalars['Boolean'] - showDataLabels: Scalars['Boolean'] - hasTooManyGroups: Scalars['Boolean'] - formattedToRawLookup: Scalars['JSON'] - __typename: 'LineChartData' -} - -export interface PieChartDataItem { - id: Scalars['String'] - value: Scalars['Float'] - __typename: 'PieChartDataItem' -} - -export interface PieChartData { - data: PieChartDataItem[] - showLegend: Scalars['Boolean'] - showDataLabels: Scalars['Boolean'] - showCenterMetric: Scalars['Boolean'] - hasTooManyGroups: Scalars['Boolean'] - formattedToRawLookup: Scalars['JSON'] - __typename: 'PieChartData' -} - -export interface DuplicatedDashboard { - id: Scalars['UUID'] - title?: Scalars['String'] - pageLayoutId?: Scalars['UUID'] - position: Scalars['Float'] - createdAt: Scalars['String'] - updatedAt: Scalars['String'] - __typename: 'DuplicatedDashboard' -} - -export interface EventLogRecord { - event: Scalars['String'] - timestamp: Scalars['DateTime'] - userId?: Scalars['String'] - properties?: Scalars['JSON'] - recordId?: Scalars['String'] - objectMetadataId?: Scalars['String'] - isCustom?: Scalars['Boolean'] - __typename: 'EventLogRecord' -} - -export interface EventLogPageInfo { - endCursor?: Scalars['String'] - hasNextPage: Scalars['Boolean'] - __typename: 'EventLogPageInfo' -} - -export interface EventLogQueryResult { - records: EventLogRecord[] - totalCount: Scalars['Int'] - pageInfo: EventLogPageInfo - __typename: 'EventLogQueryResult' -} - export interface Query { navigationMenuItems: NavigationMenuItem[] navigationMenuItem?: NavigationMenuItem - getPageLayoutWidgets: PageLayoutWidget[] - getPageLayoutWidget: PageLayoutWidget - getPageLayoutTabs: PageLayoutTab[] - getPageLayoutTab: PageLayoutTab - getPageLayouts: PageLayout[] - getPageLayout?: PageLayout + getViewFilterGroups: ViewFilterGroup[] + getViewFilterGroup?: ViewFilterGroup + getViewFilters: ViewFilter[] + getViewFilter?: ViewFilter getViews: View[] getView?: View getViewSorts: ViewSort[] getViewSort?: ViewSort getViewFieldGroups: ViewFieldGroup[] getViewFieldGroup?: ViewFieldGroup + apiKeys: ApiKey[] + apiKey?: ApiKey + enterprisePortalSession?: Scalars['String'] + enterpriseCheckoutSession?: Scalars['String'] + enterpriseSubscriptionStatus?: EnterpriseSubscriptionStatusDTO + billingPortalSession: BillingSession + listPlans: BillingPlan[] + getMeteredProductsUsage: BillingMeteredProductUsage[] + findWorkspaceInvitations: WorkspaceInvitation[] + getApprovedAccessDomains: ApprovedAccessDomain[] + getPageLayoutTabs: PageLayoutTab[] + getPageLayoutTab: PageLayoutTab + getPageLayouts: PageLayout[] + getPageLayout?: PageLayout + getPageLayoutWidgets: PageLayoutWidget[] + getPageLayoutWidget: PageLayoutWidget findOneLogicFunction: LogicFunction findManyLogicFunctions: LogicFunction[] getAvailablePackages: Scalars['JSON'] @@ -2752,42 +2767,13 @@ export interface Query { indexMetadatas: IndexConnection findManyAgents: Agent[] findOneAgent: Agent - billingPortalSession: BillingSession - listPlans: BillingPlan[] - getMeteredProductsUsage: BillingMeteredProductUsage[] - enterprisePortalSession?: Scalars['String'] - enterpriseCheckoutSession?: Scalars['String'] - enterpriseSubscriptionStatus?: EnterpriseSubscriptionStatusDTO getRoles: Role[] - findWorkspaceInvitations: WorkspaceInvitation[] - getApprovedAccessDomains: ApprovedAccessDomain[] - apiKeys: ApiKey[] - apiKey?: ApiKey getToolIndex: ToolIndexEntry[] getToolInputSchema?: Scalars['JSON'] field: Field fields: FieldConnection getViewGroups: ViewGroup[] getViewGroup?: ViewGroup - getViewFilters: ViewFilter[] - getViewFilter?: ViewFilter - getViewFilterGroups: ViewFilterGroup[] - getViewFilterGroup?: ViewFilterGroup - currentUser: User - currentWorkspace: Workspace - getPublicWorkspaceDataByDomain: PublicWorkspaceData - findApplicationRegistrationByClientId?: PublicApplicationRegistration - findApplicationRegistrationByUniversalIdentifier?: ApplicationRegistration - findManyApplicationRegistrations: ApplicationRegistration[] - findOneApplicationRegistration: ApplicationRegistration - findApplicationRegistrationStats: ApplicationRegistrationStats - findApplicationRegistrationVariables: ApplicationRegistrationVariable[] - applicationRegistrationTarballUrl?: Scalars['String'] - checkUserExists: CheckUserExist - checkWorkspaceInviteHashIsValid: WorkspaceInviteHashValid - findWorkspaceFromInviteHash: Workspace - validatePasswordResetToken: ValidatePasswordResetToken - getSSOIdentityProviders: FindAvailableSSOIDP[] myMessageFolders: MessageFolder[] myMessageChannels: MessageChannel[] myConnectedAccounts: ConnectedAccountDTO[] @@ -2807,6 +2793,21 @@ export interface Query { pieChartData: PieChartData lineChartData: LineChartData barChartData: BarChartData + checkUserExists: CheckUserExist + checkWorkspaceInviteHashIsValid: WorkspaceInviteHashValid + findWorkspaceFromInviteHash: Workspace + validatePasswordResetToken: ValidatePasswordResetToken + findApplicationRegistrationByClientId?: PublicApplicationRegistration + findApplicationRegistrationByUniversalIdentifier?: ApplicationRegistration + findManyApplicationRegistrations: ApplicationRegistration[] + findOneApplicationRegistration: ApplicationRegistration + findApplicationRegistrationStats: ApplicationRegistrationStats + findApplicationRegistrationVariables: ApplicationRegistrationVariable[] + applicationRegistrationTarballUrl?: Scalars['String'] + currentUser: User + currentWorkspace: Workspace + getPublicWorkspaceDataByDomain: PublicWorkspaceData + getSSOIdentityProviders: FindAvailableSSOIDP[] getConnectedImapSmtpCaldavAccount: ConnectedImapSmtpCaldavAccount getAutoCompleteAddress: AutocompleteResult[] getAddressDetails: PlaceDetailsResult @@ -2857,18 +2858,14 @@ export interface Mutation { uploadWorkspaceMemberProfilePicture: FileWithSignedUrl uploadFilesFieldFile: FileWithSignedUrl uploadFilesFieldFileByUniversalIdentifier: FileWithSignedUrl - createObjectEvent: Analytics - trackAnalytics: Analytics - createPageLayoutWidget: PageLayoutWidget - updatePageLayoutWidget: PageLayoutWidget - destroyPageLayoutWidget: Scalars['Boolean'] - createPageLayoutTab: PageLayoutTab - updatePageLayoutTab: PageLayoutTab - destroyPageLayoutTab: Scalars['Boolean'] - createPageLayout: PageLayout - updatePageLayout: PageLayout - destroyPageLayout: Scalars['Boolean'] - updatePageLayoutWithTabsAndWidgets: PageLayout + createViewFilterGroup: ViewFilterGroup + updateViewFilterGroup: ViewFilterGroup + deleteViewFilterGroup: Scalars['Boolean'] + destroyViewFilterGroup: Scalars['Boolean'] + createViewFilter: ViewFilter + updateViewFilter: ViewFilter + deleteViewFilter: ViewFilter + destroyViewFilter: ViewFilter createView: View updateView: View deleteView: Scalars['Boolean'] @@ -2883,6 +2880,40 @@ export interface Mutation { deleteViewFieldGroup: ViewFieldGroup destroyViewFieldGroup: ViewFieldGroup upsertFieldsWidget: View + createApiKey: ApiKey + updateApiKey?: ApiKey + revokeApiKey?: ApiKey + assignRoleToApiKey: Scalars['Boolean'] + createObjectEvent: Analytics + trackAnalytics: Analytics + refreshEnterpriseValidityToken: Scalars['Boolean'] + setEnterpriseKey: EnterpriseLicenseInfoDTO + skipSyncEmailOnboardingStep: OnboardingStepSuccess + skipBookOnboardingStep: OnboardingStepSuccess + checkoutSession: BillingSession + switchSubscriptionInterval: BillingUpdate + switchBillingPlan: BillingUpdate + cancelSwitchBillingPlan: BillingUpdate + cancelSwitchBillingInterval: BillingUpdate + setMeteredSubscriptionPrice: BillingUpdate + endSubscriptionTrialPeriod: BillingEndTrialPeriod + cancelSwitchMeteredPrice: BillingUpdate + deleteWorkspaceInvitation: Scalars['String'] + resendWorkspaceInvitation: SendInvitations + sendInvitations: SendInvitations + createApprovedAccessDomain: ApprovedAccessDomain + deleteApprovedAccessDomain: Scalars['Boolean'] + validateApprovedAccessDomain: ApprovedAccessDomain + createPageLayoutTab: PageLayoutTab + updatePageLayoutTab: PageLayoutTab + destroyPageLayoutTab: Scalars['Boolean'] + createPageLayout: PageLayout + updatePageLayout: PageLayout + destroyPageLayout: Scalars['Boolean'] + updatePageLayoutWithTabsAndWidgets: PageLayout + createPageLayoutWidget: PageLayoutWidget + updatePageLayoutWidget: PageLayoutWidget + destroyPageLayoutWidget: Scalars['Boolean'] deleteOneLogicFunction: LogicFunction createOneLogicFunction: LogicFunction executeOneLogicFunction: LogicFunctionExecutionResult @@ -2904,16 +2935,6 @@ export interface Mutation { createOneAgent: Agent updateOneAgent: Agent deleteOneAgent: Agent - checkoutSession: BillingSession - switchSubscriptionInterval: BillingUpdate - switchBillingPlan: BillingUpdate - cancelSwitchBillingPlan: BillingUpdate - cancelSwitchBillingInterval: BillingUpdate - setMeteredSubscriptionPrice: BillingUpdate - endSubscriptionTrialPeriod: BillingEndTrialPeriod - cancelSwitchMeteredPrice: BillingUpdate - refreshEnterpriseValidityToken: Scalars['Boolean'] - setEnterpriseKey: EnterpriseLicenseInfoDTO updateWorkspaceMemberRole: WorkspaceMember createOneRole: Role updateOneRole: Role @@ -2924,18 +2945,6 @@ export interface Mutation { upsertRowLevelPermissionPredicates: UpsertRowLevelPermissionPredicatesResult assignRoleToAgent: Scalars['Boolean'] removeRoleFromAgent: Scalars['Boolean'] - skipSyncEmailOnboardingStep: OnboardingStepSuccess - skipBookOnboardingStep: OnboardingStepSuccess - deleteWorkspaceInvitation: Scalars['String'] - resendWorkspaceInvitation: SendInvitations - sendInvitations: SendInvitations - createApprovedAccessDomain: ApprovedAccessDomain - deleteApprovedAccessDomain: Scalars['Boolean'] - validateApprovedAccessDomain: ApprovedAccessDomain - createApiKey: ApiKey - updateApiKey?: ApiKey - revokeApiKey?: ApiKey - assignRoleToApiKey: Scalars['Boolean'] createOneField: Field updateOneField: Field deleteOneField: Field @@ -2944,55 +2953,6 @@ export interface Mutation { updateViewGroup: ViewGroup deleteViewGroup: ViewGroup destroyViewGroup: ViewGroup - createViewFilter: ViewFilter - updateViewFilter: ViewFilter - deleteViewFilter: ViewFilter - destroyViewFilter: ViewFilter - createViewFilterGroup: ViewFilterGroup - updateViewFilterGroup: ViewFilterGroup - deleteViewFilterGroup: Scalars['Boolean'] - destroyViewFilterGroup: Scalars['Boolean'] - deleteUser: User - deleteUserFromWorkspace: UserWorkspace - updateUserEmail: Scalars['Boolean'] - resendEmailVerificationToken: ResendEmailVerificationToken - activateWorkspace: Workspace - updateWorkspace: Workspace - deleteCurrentWorkspace: Workspace - checkCustomDomainValidRecords?: DomainValidRecords - createApplicationRegistration: CreateApplicationRegistration - updateApplicationRegistration: ApplicationRegistration - deleteApplicationRegistration: Scalars['Boolean'] - rotateApplicationRegistrationClientSecret: RotateClientSecret - createApplicationRegistrationVariable: ApplicationRegistrationVariable - updateApplicationRegistrationVariable: ApplicationRegistrationVariable - deleteApplicationRegistrationVariable: Scalars['Boolean'] - uploadAppTarball: ApplicationRegistration - transferApplicationRegistrationOwnership: ApplicationRegistration - getAuthorizationUrlForSSO: GetAuthorizationUrlForSSO - getLoginTokenFromCredentials: LoginToken - signIn: AvailableWorkspacesAndAccessTokens - verifyEmailAndGetLoginToken: VerifyEmailAndGetLoginToken - verifyEmailAndGetWorkspaceAgnosticToken: AvailableWorkspacesAndAccessTokens - getAuthTokensFromOTP: AuthTokens - signUp: AvailableWorkspacesAndAccessTokens - signUpInWorkspace: SignUp - signUpInNewWorkspace: SignUp - generateTransientToken: TransientToken - getAuthTokensFromLoginToken: AuthTokens - authorizeApp: AuthorizeApp - renewToken: AuthTokens - generateApiKeyToken: ApiKeyToken - emailPasswordResetLink: EmailPasswordResetLink - updatePasswordViaResetToken: InvalidatePassword - initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioning - initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning - deleteTwoFactorAuthenticationMethod: DeleteTwoFactorAuthenticationMethod - verifyTwoFactorAuthenticationMethodForAuthenticatedUser: VerifyTwoFactorAuthenticationMethod - createOIDCIdentityProvider: SetupSso - createSAMLIdentityProvider: SetupSso - deleteSSOIdentityProvider: DeleteSso - editSSOIdentityProvider: EditSso updateMessageFolder: MessageFolder updateMessageFolders: MessageFolder[] updateMessageChannel: MessageChannel @@ -3010,6 +2970,47 @@ export interface Mutation { evaluateAgentTurn: AgentTurnEvaluation runEvaluationInput: AgentTurn duplicateDashboard: DuplicatedDashboard + getAuthorizationUrlForSSO: GetAuthorizationUrlForSSO + getLoginTokenFromCredentials: LoginToken + signIn: AvailableWorkspacesAndAccessTokens + verifyEmailAndGetLoginToken: VerifyEmailAndGetLoginToken + verifyEmailAndGetWorkspaceAgnosticToken: AvailableWorkspacesAndAccessTokens + getAuthTokensFromOTP: AuthTokens + signUp: AvailableWorkspacesAndAccessTokens + signUpInWorkspace: SignUp + signUpInNewWorkspace: SignUp + generateTransientToken: TransientToken + getAuthTokensFromLoginToken: AuthTokens + authorizeApp: AuthorizeApp + renewToken: AuthTokens + generateApiKeyToken: ApiKeyToken + emailPasswordResetLink: EmailPasswordResetLink + updatePasswordViaResetToken: InvalidatePassword + createApplicationRegistration: CreateApplicationRegistration + updateApplicationRegistration: ApplicationRegistration + deleteApplicationRegistration: Scalars['Boolean'] + rotateApplicationRegistrationClientSecret: RotateClientSecret + createApplicationRegistrationVariable: ApplicationRegistrationVariable + updateApplicationRegistrationVariable: ApplicationRegistrationVariable + deleteApplicationRegistrationVariable: Scalars['Boolean'] + uploadAppTarball: ApplicationRegistration + transferApplicationRegistrationOwnership: ApplicationRegistration + initiateOTPProvisioning: InitiateTwoFactorAuthenticationProvisioning + initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning + deleteTwoFactorAuthenticationMethod: DeleteTwoFactorAuthenticationMethod + verifyTwoFactorAuthenticationMethodForAuthenticatedUser: VerifyTwoFactorAuthenticationMethod + deleteUser: User + deleteUserFromWorkspace: UserWorkspace + updateUserEmail: Scalars['Boolean'] + resendEmailVerificationToken: ResendEmailVerificationToken + activateWorkspace: Workspace + updateWorkspace: Workspace + deleteCurrentWorkspace: Workspace + checkCustomDomainValidRecords?: DomainValidRecords + createOIDCIdentityProvider: SetupSso + createSAMLIdentityProvider: SetupSso + deleteSSOIdentityProvider: DeleteSso + editSSOIdentityProvider: EditSso impersonate: Impersonate startChannelSync: ChannelSyncSuccess saveImapSmtpCaldavAccount: ImapSmtpCaldavConnectionSuccess @@ -3057,7 +3058,7 @@ export type AiModelRole = 'FAST' | 'SMART' export type WorkspaceMigrationActionType = 'delete' | 'create' | 'update' -export type FileFolder = 'ProfilePicture' | 'WorkspaceLogo' | 'Attachment' | 'PersonPicture' | 'CorePicture' | 'File' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'AppTarball' +export type FileFolder = 'ProfilePicture' | 'WorkspaceLogo' | 'Attachment' | 'PersonPicture' | 'CorePicture' | 'File' | 'AgentChat' | 'BuiltLogicFunction' | 'BuiltFrontComponent' | 'PublicAsset' | 'Source' | 'FilesField' | 'Dependencies' | 'Workflow' | 'AppTarball' | 'GeneratedSdkClient' export interface Subscription { onEventSubscription?: EventSubscription @@ -4301,483 +4302,6 @@ export interface SendInvitationsGenqlSelection{ __scalar?: boolean | number } -export interface ResendEmailVerificationTokenGenqlSelection{ - success?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface WorkspaceUrlsGenqlSelection{ - customUrl?: boolean | number - subdomainUrl?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface SSOConnectionGenqlSelection{ - type?: boolean | number - id?: boolean | number - issuer?: boolean | number - name?: boolean | number - status?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AvailableWorkspaceGenqlSelection{ - id?: boolean | number - displayName?: boolean | number - loginToken?: boolean | number - personalInviteToken?: boolean | number - inviteHash?: boolean | number - workspaceUrls?: WorkspaceUrlsGenqlSelection - logo?: boolean | number - sso?: SSOConnectionGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AvailableWorkspacesGenqlSelection{ - availableWorkspacesForSignIn?: AvailableWorkspaceGenqlSelection - availableWorkspacesForSignUp?: AvailableWorkspaceGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface DeletedWorkspaceMemberGenqlSelection{ - id?: boolean | number - name?: FullNameGenqlSelection - userEmail?: boolean | number - avatarUrl?: boolean | number - userWorkspaceId?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface BillingEntitlementGenqlSelection{ - key?: boolean | number - value?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface DomainRecordGenqlSelection{ - validationType?: boolean | number - type?: boolean | number - status?: boolean | number - key?: boolean | number - value?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface DomainValidRecordsGenqlSelection{ - id?: boolean | number - domain?: boolean | number - records?: DomainRecordGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface FeatureFlagGenqlSelection{ - key?: boolean | number - value?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface SSOIdentityProviderGenqlSelection{ - id?: boolean | number - name?: boolean | number - type?: boolean | number - status?: boolean | number - issuer?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthProvidersGenqlSelection{ - sso?: SSOIdentityProviderGenqlSelection - google?: boolean | number - magicLink?: boolean | number - password?: boolean | number - microsoft?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthBypassProvidersGenqlSelection{ - google?: boolean | number - password?: boolean | number - microsoft?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface PublicWorkspaceDataGenqlSelection{ - id?: boolean | number - authProviders?: AuthProvidersGenqlSelection - authBypassProviders?: AuthBypassProvidersGenqlSelection - logo?: boolean | number - displayName?: boolean | number - workspaceUrls?: WorkspaceUrlsGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface IndexEdgeGenqlSelection{ - /** The node containing the Index */ - node?: IndexGenqlSelection - /** Cursor for this node. */ - cursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface PageInfoGenqlSelection{ - /** true if paging forward and there are more records. */ - hasNextPage?: boolean | number - /** true if paging backwards and there are more records. */ - hasPreviousPage?: boolean | number - /** The cursor of the first returned record. */ - startCursor?: boolean | number - /** The cursor of the last returned record. */ - endCursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface IndexConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: IndexEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface IndexFieldEdgeGenqlSelection{ - /** The node containing the IndexField */ - node?: IndexFieldGenqlSelection - /** Cursor for this node. */ - cursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface IndexIndexFieldMetadatasConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: IndexFieldEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ObjectEdgeGenqlSelection{ - /** The node containing the Object */ - node?: ObjectGenqlSelection - /** Cursor for this node. */ - cursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface IndexObjectMetadataConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: ObjectEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ObjectRecordCountGenqlSelection{ - objectNamePlural?: boolean | number - totalCount?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ObjectConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: ObjectEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ObjectIndexMetadatasConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: IndexEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface FieldEdgeGenqlSelection{ - /** The node containing the Field */ - node?: FieldGenqlSelection - /** Cursor for this node. */ - cursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ObjectFieldsConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: FieldEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{ - predicates?: RowLevelPermissionPredicateGenqlSelection - predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface VersionDistributionEntryGenqlSelection{ - version?: boolean | number - count?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ApplicationRegistrationStatsGenqlSelection{ - activeInstalls?: boolean | number - mostInstalledVersion?: boolean | number - versionDistribution?: VersionDistributionEntryGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface CreateApplicationRegistrationGenqlSelection{ - applicationRegistration?: ApplicationRegistrationGenqlSelection - clientSecret?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface PublicApplicationRegistrationGenqlSelection{ - id?: boolean | number - name?: boolean | number - logoUrl?: boolean | number - websiteUrl?: boolean | number - oAuthScopes?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface RotateClientSecretGenqlSelection{ - clientSecret?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface RelationGenqlSelection{ - type?: boolean | number - sourceObjectMetadata?: ObjectGenqlSelection - targetObjectMetadata?: ObjectGenqlSelection - sourceFieldMetadata?: FieldGenqlSelection - targetFieldMetadata?: FieldGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface FieldConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: FieldEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface DeleteSsoGenqlSelection{ - identityProviderId?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface EditSsoGenqlSelection{ - id?: boolean | number - type?: boolean | number - issuer?: boolean | number - name?: boolean | number - status?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface WorkspaceNameAndIdGenqlSelection{ - displayName?: boolean | number - id?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface FindAvailableSSOIDPGenqlSelection{ - type?: boolean | number - id?: boolean | number - issuer?: boolean | number - name?: boolean | number - status?: boolean | number - workspace?: WorkspaceNameAndIdGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface SetupSsoGenqlSelection{ - id?: boolean | number - type?: boolean | number - issuer?: boolean | number - name?: boolean | number - status?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface DeleteTwoFactorAuthenticationMethodGenqlSelection{ - /** Boolean that confirms query was dispatched */ - success?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface InitiateTwoFactorAuthenticationProvisioningGenqlSelection{ - uri?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface VerifyTwoFactorAuthenticationMethodGenqlSelection{ - success?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthorizeAppGenqlSelection{ - redirectUrl?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthTokenGenqlSelection{ - token?: boolean | number - expiresAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthTokenPairGenqlSelection{ - accessOrWorkspaceAgnosticToken?: AuthTokenGenqlSelection - refreshToken?: AuthTokenGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AvailableWorkspacesAndAccessTokensGenqlSelection{ - tokens?: AuthTokenPairGenqlSelection - availableWorkspaces?: AvailableWorkspacesGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface EmailPasswordResetLinkGenqlSelection{ - /** Boolean that confirms query was dispatched */ - success?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface GetAuthorizationUrlForSSOGenqlSelection{ - authorizationURL?: boolean | number - type?: boolean | number - id?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface InvalidatePasswordGenqlSelection{ - /** Boolean that confirms query was dispatched */ - success?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface WorkspaceUrlsAndIdGenqlSelection{ - workspaceUrls?: WorkspaceUrlsGenqlSelection - id?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface SignUpGenqlSelection{ - loginToken?: AuthTokenGenqlSelection - workspace?: WorkspaceUrlsAndIdGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface TransientTokenGenqlSelection{ - transientToken?: AuthTokenGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ValidatePasswordResetTokenGenqlSelection{ - id?: boolean | number - email?: boolean | number - hasPassword?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface VerifyEmailAndGetLoginTokenGenqlSelection{ - loginToken?: AuthTokenGenqlSelection - workspaceUrls?: WorkspaceUrlsGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ApiKeyTokenGenqlSelection{ - token?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AuthTokensGenqlSelection{ - tokens?: AuthTokenPairGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface LoginTokenGenqlSelection{ - loginToken?: AuthTokenGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface CheckUserExistGenqlSelection{ - exists?: boolean | number - availableWorkspacesCount?: boolean | number - isEmailVerified?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface WorkspaceInviteHashValidGenqlSelection{ - isValid?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - export interface RecordIdentifierGenqlSelection{ id?: boolean | number labelIdentifier?: boolean | number @@ -4867,327 +4391,6 @@ export interface LogicFunctionExecutionResultGenqlSelection{ __scalar?: boolean | number } -export interface LogicFunctionLogsGenqlSelection{ - /** Execution Logs */ - logs?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ToolIndexEntryGenqlSelection{ - name?: boolean | number - description?: boolean | number - category?: boolean | number - objectName?: boolean | number - inputSchema?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentMessagePartGenqlSelection{ - id?: boolean | number - messageId?: boolean | number - orderIndex?: boolean | number - type?: boolean | number - textContent?: boolean | number - reasoningContent?: boolean | number - toolName?: boolean | number - toolCallId?: boolean | number - toolInput?: boolean | number - toolOutput?: boolean | number - state?: boolean | number - errorMessage?: boolean | number - errorDetails?: boolean | number - sourceUrlSourceId?: boolean | number - sourceUrlUrl?: boolean | number - sourceUrlTitle?: boolean | number - sourceDocumentSourceId?: boolean | number - sourceDocumentMediaType?: boolean | number - sourceDocumentTitle?: boolean | number - sourceDocumentFilename?: boolean | number - fileMediaType?: boolean | number - fileFilename?: boolean | number - fileId?: boolean | number - fileUrl?: boolean | number - providerMetadata?: boolean | number - createdAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface SkillGenqlSelection{ - id?: boolean | number - name?: boolean | number - label?: boolean | number - icon?: boolean | number - description?: boolean | number - content?: boolean | number - isCustom?: boolean | number - isActive?: boolean | number - applicationId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ApplicationTokenPairGenqlSelection{ - applicationAccessToken?: AuthTokenGenqlSelection - applicationRefreshToken?: AuthTokenGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface FrontComponentGenqlSelection{ - id?: boolean | number - name?: boolean | number - description?: boolean | number - sourceComponentPath?: boolean | number - builtComponentPath?: boolean | number - componentName?: boolean | number - builtComponentChecksum?: boolean | number - universalIdentifier?: boolean | number - applicationId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - isHeadless?: boolean | number - applicationTokenPair?: ApplicationTokenPairGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface CommandMenuItemGenqlSelection{ - id?: boolean | number - workflowVersionId?: boolean | number - frontComponentId?: boolean | number - frontComponent?: FrontComponentGenqlSelection - engineComponentKey?: boolean | number - label?: boolean | number - icon?: boolean | number - shortLabel?: boolean | number - position?: boolean | number - isPinned?: boolean | number - availabilityType?: boolean | number - hotKeys?: boolean | number - conditionalAvailabilityExpression?: boolean | number - availabilityObjectMetadataId?: boolean | number - applicationId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentChatThreadGenqlSelection{ - id?: boolean | number - title?: boolean | number - totalInputTokens?: boolean | number - totalOutputTokens?: boolean | number - contextWindowTokens?: boolean | number - conversationSize?: boolean | number - totalInputCredits?: boolean | number - totalOutputCredits?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentMessageGenqlSelection{ - id?: boolean | number - threadId?: boolean | number - turnId?: boolean | number - agentId?: boolean | number - role?: boolean | number - parts?: AgentMessagePartGenqlSelection - createdAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AISystemPromptSectionGenqlSelection{ - title?: boolean | number - content?: boolean | number - estimatedTokenCount?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AISystemPromptPreviewGenqlSelection{ - sections?: AISystemPromptSectionGenqlSelection - estimatedTokenCount?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentChatThreadEdgeGenqlSelection{ - /** The node containing the AgentChatThread */ - node?: AgentChatThreadGenqlSelection - /** Cursor for this node. */ - cursor?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentChatThreadConnectionGenqlSelection{ - /** Paging information */ - pageInfo?: PageInfoGenqlSelection - /** Array of edges. */ - edges?: AgentChatThreadEdgeGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentTurnEvaluationGenqlSelection{ - id?: boolean | number - turnId?: boolean | number - score?: boolean | number - comment?: boolean | number - createdAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface AgentTurnGenqlSelection{ - id?: boolean | number - threadId?: boolean | number - agentId?: boolean | number - evaluations?: AgentTurnEvaluationGenqlSelection - messages?: AgentMessageGenqlSelection - createdAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface CalendarChannelGenqlSelection{ - id?: boolean | number - handle?: boolean | number - syncStatus?: boolean | number - syncStage?: boolean | number - visibility?: boolean | number - isContactAutoCreationEnabled?: boolean | number - contactAutoCreationPolicy?: boolean | number - isSyncEnabled?: boolean | number - syncedAt?: boolean | number - syncStageStartedAt?: boolean | number - throttleFailureCount?: boolean | number - connectedAccountId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface ConnectedAccountDTOGenqlSelection{ - id?: boolean | number - handle?: boolean | number - provider?: boolean | number - lastCredentialsRefreshedAt?: boolean | number - authFailedAt?: boolean | number - handleAliases?: boolean | number - scopes?: boolean | number - lastSignedInAt?: boolean | number - userWorkspaceId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MessageChannelGenqlSelection{ - id?: boolean | number - visibility?: boolean | number - handle?: boolean | number - type?: boolean | number - isContactAutoCreationEnabled?: boolean | number - contactAutoCreationPolicy?: boolean | number - messageFolderImportPolicy?: boolean | number - excludeNonProfessionalEmails?: boolean | number - excludeGroupEmails?: boolean | number - pendingGroupEmailsAction?: boolean | number - isSyncEnabled?: boolean | number - syncedAt?: boolean | number - syncStatus?: boolean | number - syncStage?: boolean | number - syncStageStartedAt?: boolean | number - throttleFailureCount?: boolean | number - throttleRetryAfter?: boolean | number - connectedAccountId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MessageFolderGenqlSelection{ - id?: boolean | number - name?: boolean | number - isSentFolder?: boolean | number - isSynced?: boolean | number - parentFolderId?: boolean | number - externalId?: boolean | number - pendingSyncAction?: boolean | number - messageChannelId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface CollectionHashGenqlSelection{ - collectionName?: boolean | number - hash?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MinimalObjectMetadataGenqlSelection{ - id?: boolean | number - nameSingular?: boolean | number - namePlural?: boolean | number - labelSingular?: boolean | number - labelPlural?: boolean | number - icon?: boolean | number - color?: boolean | number - isCustom?: boolean | number - isActive?: boolean | number - isSystem?: boolean | number - isRemote?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MinimalViewGenqlSelection{ - id?: boolean | number - type?: boolean | number - key?: boolean | number - objectMetadataId?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface MinimalMetadataGenqlSelection{ - objectMetadataItems?: MinimalObjectMetadataGenqlSelection - views?: MinimalViewGenqlSelection - collectionHashes?: CollectionHashGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface WebhookGenqlSelection{ - id?: boolean | number - targetUrl?: boolean | number - operations?: boolean | number - description?: boolean | number - secret?: boolean | number - applicationId?: boolean | number - createdAt?: boolean | number - updatedAt?: boolean | number - deletedAt?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - export interface BillingTrialPeriodGenqlSelection{ duration?: boolean | number isCreditCardRequired?: boolean | number @@ -5195,6 +4398,52 @@ export interface BillingTrialPeriodGenqlSelection{ __scalar?: boolean | number } +export interface WorkspaceUrlsGenqlSelection{ + customUrl?: boolean | number + subdomainUrl?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface SSOIdentityProviderGenqlSelection{ + id?: boolean | number + name?: boolean | number + type?: boolean | number + status?: boolean | number + issuer?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthProvidersGenqlSelection{ + sso?: SSOIdentityProviderGenqlSelection + google?: boolean | number + magicLink?: boolean | number + password?: boolean | number + microsoft?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthBypassProvidersGenqlSelection{ + google?: boolean | number + password?: boolean | number + microsoft?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface PublicWorkspaceDataGenqlSelection{ + id?: boolean | number + authProviders?: AuthProvidersGenqlSelection + authBypassProviders?: AuthBypassProvidersGenqlSelection + logo?: boolean | number + displayName?: boolean | number + workspaceUrls?: WorkspaceUrlsGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + export interface NativeModelCapabilitiesGenqlSelection{ webSearch?: boolean | number twitterSearch?: boolean | number @@ -5432,6 +4681,13 @@ export interface SystemHealthGenqlSelection{ __scalar?: boolean | number } +export interface FeatureFlagGenqlSelection{ + key?: boolean | number + value?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface UserInfoGenqlSelection{ id?: boolean | number email?: boolean | number @@ -5548,6 +4804,430 @@ export interface QueueMetricsDataGenqlSelection{ __scalar?: boolean | number } +export interface VersionDistributionEntryGenqlSelection{ + version?: boolean | number + count?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ApplicationRegistrationStatsGenqlSelection{ + activeInstalls?: boolean | number + mostInstalledVersion?: boolean | number + versionDistribution?: VersionDistributionEntryGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface CreateApplicationRegistrationGenqlSelection{ + applicationRegistration?: ApplicationRegistrationGenqlSelection + clientSecret?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface PublicApplicationRegistrationGenqlSelection{ + id?: boolean | number + name?: boolean | number + logoUrl?: boolean | number + websiteUrl?: boolean | number + oAuthScopes?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface RotateClientSecretGenqlSelection{ + clientSecret?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ResendEmailVerificationTokenGenqlSelection{ + success?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface DeleteSsoGenqlSelection{ + identityProviderId?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface EditSsoGenqlSelection{ + id?: boolean | number + type?: boolean | number + issuer?: boolean | number + name?: boolean | number + status?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface WorkspaceNameAndIdGenqlSelection{ + displayName?: boolean | number + id?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface FindAvailableSSOIDPGenqlSelection{ + type?: boolean | number + id?: boolean | number + issuer?: boolean | number + name?: boolean | number + status?: boolean | number + workspace?: WorkspaceNameAndIdGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface SetupSsoGenqlSelection{ + id?: boolean | number + type?: boolean | number + issuer?: boolean | number + name?: boolean | number + status?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface SSOConnectionGenqlSelection{ + type?: boolean | number + id?: boolean | number + issuer?: boolean | number + name?: boolean | number + status?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AvailableWorkspaceGenqlSelection{ + id?: boolean | number + displayName?: boolean | number + loginToken?: boolean | number + personalInviteToken?: boolean | number + inviteHash?: boolean | number + workspaceUrls?: WorkspaceUrlsGenqlSelection + logo?: boolean | number + sso?: SSOConnectionGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AvailableWorkspacesGenqlSelection{ + availableWorkspacesForSignIn?: AvailableWorkspaceGenqlSelection + availableWorkspacesForSignUp?: AvailableWorkspaceGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface DeletedWorkspaceMemberGenqlSelection{ + id?: boolean | number + name?: FullNameGenqlSelection + userEmail?: boolean | number + avatarUrl?: boolean | number + userWorkspaceId?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface BillingEntitlementGenqlSelection{ + key?: boolean | number + value?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface DomainRecordGenqlSelection{ + validationType?: boolean | number + type?: boolean | number + status?: boolean | number + key?: boolean | number + value?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface DomainValidRecordsGenqlSelection{ + id?: boolean | number + domain?: boolean | number + records?: DomainRecordGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface IndexEdgeGenqlSelection{ + /** The node containing the Index */ + node?: IndexGenqlSelection + /** Cursor for this node. */ + cursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface PageInfoGenqlSelection{ + /** true if paging forward and there are more records. */ + hasNextPage?: boolean | number + /** true if paging backwards and there are more records. */ + hasPreviousPage?: boolean | number + /** The cursor of the first returned record. */ + startCursor?: boolean | number + /** The cursor of the last returned record. */ + endCursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface IndexConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: IndexEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface IndexFieldEdgeGenqlSelection{ + /** The node containing the IndexField */ + node?: IndexFieldGenqlSelection + /** Cursor for this node. */ + cursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface IndexIndexFieldMetadatasConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: IndexFieldEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ObjectEdgeGenqlSelection{ + /** The node containing the Object */ + node?: ObjectGenqlSelection + /** Cursor for this node. */ + cursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface IndexObjectMetadataConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: ObjectEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ObjectRecordCountGenqlSelection{ + objectNamePlural?: boolean | number + totalCount?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ObjectConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: ObjectEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ObjectIndexMetadatasConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: IndexEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface FieldEdgeGenqlSelection{ + /** The node containing the Field */ + node?: FieldGenqlSelection + /** Cursor for this node. */ + cursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ObjectFieldsConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: FieldEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UpsertRowLevelPermissionPredicatesResultGenqlSelection{ + predicates?: RowLevelPermissionPredicateGenqlSelection + predicateGroups?: RowLevelPermissionPredicateGroupGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface RelationGenqlSelection{ + type?: boolean | number + sourceObjectMetadata?: ObjectGenqlSelection + targetObjectMetadata?: ObjectGenqlSelection + sourceFieldMetadata?: FieldGenqlSelection + targetFieldMetadata?: FieldGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface FieldConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: FieldEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface DeleteTwoFactorAuthenticationMethodGenqlSelection{ + /** Boolean that confirms query was dispatched */ + success?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface InitiateTwoFactorAuthenticationProvisioningGenqlSelection{ + uri?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface VerifyTwoFactorAuthenticationMethodGenqlSelection{ + success?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthorizeAppGenqlSelection{ + redirectUrl?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthTokenGenqlSelection{ + token?: boolean | number + expiresAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthTokenPairGenqlSelection{ + accessOrWorkspaceAgnosticToken?: AuthTokenGenqlSelection + refreshToken?: AuthTokenGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AvailableWorkspacesAndAccessTokensGenqlSelection{ + tokens?: AuthTokenPairGenqlSelection + availableWorkspaces?: AvailableWorkspacesGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface EmailPasswordResetLinkGenqlSelection{ + /** Boolean that confirms query was dispatched */ + success?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface GetAuthorizationUrlForSSOGenqlSelection{ + authorizationURL?: boolean | number + type?: boolean | number + id?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface InvalidatePasswordGenqlSelection{ + /** Boolean that confirms query was dispatched */ + success?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface WorkspaceUrlsAndIdGenqlSelection{ + workspaceUrls?: WorkspaceUrlsGenqlSelection + id?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface SignUpGenqlSelection{ + loginToken?: AuthTokenGenqlSelection + workspace?: WorkspaceUrlsAndIdGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface TransientTokenGenqlSelection{ + transientToken?: AuthTokenGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ValidatePasswordResetTokenGenqlSelection{ + id?: boolean | number + email?: boolean | number + hasPassword?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface VerifyEmailAndGetLoginTokenGenqlSelection{ + loginToken?: AuthTokenGenqlSelection + workspaceUrls?: WorkspaceUrlsGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ApiKeyTokenGenqlSelection{ + token?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AuthTokensGenqlSelection{ + tokens?: AuthTokenPairGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface LoginTokenGenqlSelection{ + loginToken?: AuthTokenGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface CheckUserExistGenqlSelection{ + exists?: boolean | number + availableWorkspacesCount?: boolean | number + isEmailVerified?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface WorkspaceInviteHashValidGenqlSelection{ + isValid?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface ImpersonateGenqlSelection{ loginToken?: AuthTokenGenqlSelection workspace?: WorkspaceUrlsAndIdGenqlSelection @@ -5569,6 +5249,13 @@ export interface WorkspaceMigrationGenqlSelection{ __scalar?: boolean | number } +export interface ApplicationTokenPairGenqlSelection{ + applicationAccessToken?: AuthTokenGenqlSelection + applicationRefreshToken?: AuthTokenGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + export interface FileGenqlSelection{ id?: boolean | number path?: boolean | number @@ -5679,39 +5366,6 @@ export interface MarketplaceAppGenqlSelection{ __scalar?: boolean | number } -export interface UsageBreakdownItemGenqlSelection{ - key?: boolean | number - label?: boolean | number - creditsUsed?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageTimeSeriesGenqlSelection{ - date?: boolean | number - creditsUsed?: boolean | number - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageUserDailyGenqlSelection{ - userWorkspaceId?: boolean | number - dailyUsage?: UsageTimeSeriesGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - -export interface UsageAnalyticsGenqlSelection{ - usageByUser?: UsageBreakdownItemGenqlSelection - usageByOperationType?: UsageBreakdownItemGenqlSelection - timeSeries?: UsageTimeSeriesGenqlSelection - periodStart?: boolean | number - periodEnd?: boolean | number - userDailyUsage?: UsageUserDailyGenqlSelection - __typename?: boolean | number - __scalar?: boolean | number -} - export interface PublicDomainGenqlSelection{ id?: boolean | number domain?: boolean | number @@ -5811,6 +5465,128 @@ export interface PostgresCredentialsGenqlSelection{ __scalar?: boolean | number } +export interface UsageBreakdownItemGenqlSelection{ + key?: boolean | number + label?: boolean | number + creditsUsed?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UsageTimeSeriesGenqlSelection{ + date?: boolean | number + creditsUsed?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UsageUserDailyGenqlSelection{ + userWorkspaceId?: boolean | number + dailyUsage?: UsageTimeSeriesGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface UsageAnalyticsGenqlSelection{ + usageByUser?: UsageBreakdownItemGenqlSelection + usageByOperationType?: UsageBreakdownItemGenqlSelection + timeSeries?: UsageTimeSeriesGenqlSelection + periodStart?: boolean | number + periodEnd?: boolean | number + userDailyUsage?: UsageUserDailyGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface LogicFunctionLogsGenqlSelection{ + /** Execution Logs */ + logs?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface FrontComponentGenqlSelection{ + id?: boolean | number + name?: boolean | number + description?: boolean | number + sourceComponentPath?: boolean | number + builtComponentPath?: boolean | number + componentName?: boolean | number + builtComponentChecksum?: boolean | number + universalIdentifier?: boolean | number + applicationId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + isHeadless?: boolean | number + usesSdkClient?: boolean | number + applicationTokenPair?: ApplicationTokenPairGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface CommandMenuItemGenqlSelection{ + id?: boolean | number + workflowVersionId?: boolean | number + frontComponentId?: boolean | number + frontComponent?: FrontComponentGenqlSelection + engineComponentKey?: boolean | number + label?: boolean | number + icon?: boolean | number + shortLabel?: boolean | number + position?: boolean | number + isPinned?: boolean | number + availabilityType?: boolean | number + hotKeys?: boolean | number + conditionalAvailabilityExpression?: boolean | number + availabilityObjectMetadataId?: boolean | number + applicationId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ToolIndexEntryGenqlSelection{ + name?: boolean | number + description?: boolean | number + category?: boolean | number + objectName?: boolean | number + inputSchema?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentMessagePartGenqlSelection{ + id?: boolean | number + messageId?: boolean | number + orderIndex?: boolean | number + type?: boolean | number + textContent?: boolean | number + reasoningContent?: boolean | number + toolName?: boolean | number + toolCallId?: boolean | number + toolInput?: boolean | number + toolOutput?: boolean | number + state?: boolean | number + errorMessage?: boolean | number + errorDetails?: boolean | number + sourceUrlSourceId?: boolean | number + sourceUrlUrl?: boolean | number + sourceUrlTitle?: boolean | number + sourceDocumentSourceId?: boolean | number + sourceDocumentMediaType?: boolean | number + sourceDocumentTitle?: boolean | number + sourceDocumentFilename?: boolean | number + fileMediaType?: boolean | number + fileFilename?: boolean | number + fileId?: boolean | number + fileUrl?: boolean | number + providerMetadata?: boolean | number + createdAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface ChannelSyncSuccessGenqlSelection{ success?: boolean | number __typename?: boolean | number @@ -5924,21 +5700,261 @@ export interface EventLogQueryResultGenqlSelection{ __scalar?: boolean | number } +export interface SkillGenqlSelection{ + id?: boolean | number + name?: boolean | number + label?: boolean | number + icon?: boolean | number + description?: boolean | number + content?: boolean | number + isCustom?: boolean | number + isActive?: boolean | number + applicationId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentChatThreadGenqlSelection{ + id?: boolean | number + title?: boolean | number + totalInputTokens?: boolean | number + totalOutputTokens?: boolean | number + contextWindowTokens?: boolean | number + conversationSize?: boolean | number + totalInputCredits?: boolean | number + totalOutputCredits?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentMessageGenqlSelection{ + id?: boolean | number + threadId?: boolean | number + turnId?: boolean | number + agentId?: boolean | number + role?: boolean | number + parts?: AgentMessagePartGenqlSelection + createdAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AISystemPromptSectionGenqlSelection{ + title?: boolean | number + content?: boolean | number + estimatedTokenCount?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AISystemPromptPreviewGenqlSelection{ + sections?: AISystemPromptSectionGenqlSelection + estimatedTokenCount?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentChatThreadEdgeGenqlSelection{ + /** The node containing the AgentChatThread */ + node?: AgentChatThreadGenqlSelection + /** Cursor for this node. */ + cursor?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentChatThreadConnectionGenqlSelection{ + /** Paging information */ + pageInfo?: PageInfoGenqlSelection + /** Array of edges. */ + edges?: AgentChatThreadEdgeGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentTurnEvaluationGenqlSelection{ + id?: boolean | number + turnId?: boolean | number + score?: boolean | number + comment?: boolean | number + createdAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface AgentTurnGenqlSelection{ + id?: boolean | number + threadId?: boolean | number + agentId?: boolean | number + evaluations?: AgentTurnEvaluationGenqlSelection + messages?: AgentMessageGenqlSelection + createdAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface CalendarChannelGenqlSelection{ + id?: boolean | number + handle?: boolean | number + syncStatus?: boolean | number + syncStage?: boolean | number + visibility?: boolean | number + isContactAutoCreationEnabled?: boolean | number + contactAutoCreationPolicy?: boolean | number + isSyncEnabled?: boolean | number + syncedAt?: boolean | number + syncStageStartedAt?: boolean | number + throttleFailureCount?: boolean | number + connectedAccountId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface ConnectedAccountDTOGenqlSelection{ + id?: boolean | number + handle?: boolean | number + provider?: boolean | number + lastCredentialsRefreshedAt?: boolean | number + authFailedAt?: boolean | number + handleAliases?: boolean | number + scopes?: boolean | number + lastSignedInAt?: boolean | number + userWorkspaceId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MessageChannelGenqlSelection{ + id?: boolean | number + visibility?: boolean | number + handle?: boolean | number + type?: boolean | number + isContactAutoCreationEnabled?: boolean | number + contactAutoCreationPolicy?: boolean | number + messageFolderImportPolicy?: boolean | number + excludeNonProfessionalEmails?: boolean | number + excludeGroupEmails?: boolean | number + pendingGroupEmailsAction?: boolean | number + isSyncEnabled?: boolean | number + syncedAt?: boolean | number + syncStatus?: boolean | number + syncStage?: boolean | number + syncStageStartedAt?: boolean | number + throttleFailureCount?: boolean | number + throttleRetryAfter?: boolean | number + connectedAccountId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MessageFolderGenqlSelection{ + id?: boolean | number + name?: boolean | number + isSentFolder?: boolean | number + isSynced?: boolean | number + parentFolderId?: boolean | number + externalId?: boolean | number + pendingSyncAction?: boolean | number + messageChannelId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface CollectionHashGenqlSelection{ + collectionName?: boolean | number + hash?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MinimalObjectMetadataGenqlSelection{ + id?: boolean | number + nameSingular?: boolean | number + namePlural?: boolean | number + labelSingular?: boolean | number + labelPlural?: boolean | number + icon?: boolean | number + color?: boolean | number + isCustom?: boolean | number + isActive?: boolean | number + isSystem?: boolean | number + isRemote?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MinimalViewGenqlSelection{ + id?: boolean | number + type?: boolean | number + key?: boolean | number + objectMetadataId?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface MinimalMetadataGenqlSelection{ + objectMetadataItems?: MinimalObjectMetadataGenqlSelection + views?: MinimalViewGenqlSelection + collectionHashes?: CollectionHashGenqlSelection + __typename?: boolean | number + __scalar?: boolean | number +} + +export interface WebhookGenqlSelection{ + id?: boolean | number + targetUrl?: boolean | number + operations?: boolean | number + description?: boolean | number + secret?: boolean | number + applicationId?: boolean | number + createdAt?: boolean | number + updatedAt?: boolean | number + deletedAt?: boolean | number + __typename?: boolean | number + __scalar?: boolean | number +} + export interface QueryGenqlSelection{ navigationMenuItems?: NavigationMenuItemGenqlSelection navigationMenuItem?: (NavigationMenuItemGenqlSelection & { __args: {id: Scalars['UUID']} }) - getPageLayoutWidgets?: (PageLayoutWidgetGenqlSelection & { __args: {pageLayoutTabId: Scalars['String']} }) - getPageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String']} }) - getPageLayoutTabs?: (PageLayoutTabGenqlSelection & { __args: {pageLayoutId: Scalars['String']} }) - getPageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {id: Scalars['String']} }) - getPageLayouts?: (PageLayoutGenqlSelection & { __args?: {objectMetadataId?: (Scalars['String'] | null), pageLayoutType?: (PageLayoutType | null)} }) - getPageLayout?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String']} }) + getViewFilterGroups?: (ViewFilterGroupGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) + getViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {id: Scalars['String']} }) + getViewFilters?: (ViewFilterGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) + getViewFilter?: (ViewFilterGenqlSelection & { __args: {id: Scalars['String']} }) getViews?: (ViewGenqlSelection & { __args?: {objectMetadataId?: (Scalars['String'] | null), viewTypes?: (ViewType[] | null)} }) getView?: (ViewGenqlSelection & { __args: {id: Scalars['String']} }) getViewSorts?: (ViewSortGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) getViewSort?: (ViewSortGenqlSelection & { __args: {id: Scalars['String']} }) getViewFieldGroups?: (ViewFieldGroupGenqlSelection & { __args: {viewId: Scalars['String']} }) getViewFieldGroup?: (ViewFieldGroupGenqlSelection & { __args: {id: Scalars['String']} }) + apiKeys?: ApiKeyGenqlSelection + apiKey?: (ApiKeyGenqlSelection & { __args: {input: GetApiKeyInput} }) + enterprisePortalSession?: { __args: {returnUrlPath?: (Scalars['String'] | null)} } | boolean | number + enterpriseCheckoutSession?: { __args: {billingInterval?: (Scalars['String'] | null)} } | boolean | number + enterpriseSubscriptionStatus?: EnterpriseSubscriptionStatusDTOGenqlSelection + billingPortalSession?: (BillingSessionGenqlSelection & { __args?: {returnUrlPath?: (Scalars['String'] | null)} }) + listPlans?: BillingPlanGenqlSelection + getMeteredProductsUsage?: BillingMeteredProductUsageGenqlSelection + findWorkspaceInvitations?: WorkspaceInvitationGenqlSelection + getApprovedAccessDomains?: ApprovedAccessDomainGenqlSelection + getPageLayoutTabs?: (PageLayoutTabGenqlSelection & { __args: {pageLayoutId: Scalars['String']} }) + getPageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {id: Scalars['String']} }) + getPageLayouts?: (PageLayoutGenqlSelection & { __args?: {objectMetadataId?: (Scalars['String'] | null), pageLayoutType?: (PageLayoutType | null)} }) + getPageLayout?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String']} }) + getPageLayoutWidgets?: (PageLayoutWidgetGenqlSelection & { __args: {pageLayoutTabId: Scalars['String']} }) + getPageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String']} }) findOneLogicFunction?: (LogicFunctionGenqlSelection & { __args: {input: LogicFunctionIdInput} }) findManyLogicFunctions?: LogicFunctionGenqlSelection getAvailablePackages?: { __args: {input: LogicFunctionIdInput} } @@ -5968,17 +5984,7 @@ export interface QueryGenqlSelection{ filter: IndexFilter} }) findManyAgents?: AgentGenqlSelection findOneAgent?: (AgentGenqlSelection & { __args: {input: AgentIdInput} }) - billingPortalSession?: (BillingSessionGenqlSelection & { __args?: {returnUrlPath?: (Scalars['String'] | null)} }) - listPlans?: BillingPlanGenqlSelection - getMeteredProductsUsage?: BillingMeteredProductUsageGenqlSelection - enterprisePortalSession?: { __args: {returnUrlPath?: (Scalars['String'] | null)} } | boolean | number - enterpriseCheckoutSession?: { __args: {billingInterval?: (Scalars['String'] | null)} } | boolean | number - enterpriseSubscriptionStatus?: EnterpriseSubscriptionStatusDTOGenqlSelection getRoles?: RoleGenqlSelection - findWorkspaceInvitations?: WorkspaceInvitationGenqlSelection - getApprovedAccessDomains?: ApprovedAccessDomainGenqlSelection - apiKeys?: ApiKeyGenqlSelection - apiKey?: (ApiKeyGenqlSelection & { __args: {input: GetApiKeyInput} }) getToolIndex?: ToolIndexEntryGenqlSelection getToolInputSchema?: { __args: {toolName: Scalars['String']} } field?: (FieldGenqlSelection & { __args: { @@ -5991,25 +5997,6 @@ export interface QueryGenqlSelection{ filter: FieldFilter} }) getViewGroups?: (ViewGroupGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) getViewGroup?: (ViewGroupGenqlSelection & { __args: {id: Scalars['String']} }) - getViewFilters?: (ViewFilterGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) - getViewFilter?: (ViewFilterGenqlSelection & { __args: {id: Scalars['String']} }) - getViewFilterGroups?: (ViewFilterGroupGenqlSelection & { __args?: {viewId?: (Scalars['String'] | null)} }) - getViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {id: Scalars['String']} }) - currentUser?: UserGenqlSelection - currentWorkspace?: WorkspaceGenqlSelection - getPublicWorkspaceDataByDomain?: (PublicWorkspaceDataGenqlSelection & { __args?: {origin?: (Scalars['String'] | null)} }) - findApplicationRegistrationByClientId?: (PublicApplicationRegistrationGenqlSelection & { __args: {clientId: Scalars['String']} }) - findApplicationRegistrationByUniversalIdentifier?: (ApplicationRegistrationGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) - findManyApplicationRegistrations?: ApplicationRegistrationGenqlSelection - findOneApplicationRegistration?: (ApplicationRegistrationGenqlSelection & { __args: {id: Scalars['String']} }) - findApplicationRegistrationStats?: (ApplicationRegistrationStatsGenqlSelection & { __args: {id: Scalars['String']} }) - findApplicationRegistrationVariables?: (ApplicationRegistrationVariableGenqlSelection & { __args: {applicationRegistrationId: Scalars['String']} }) - applicationRegistrationTarballUrl?: { __args: {id: Scalars['String']} } - checkUserExists?: (CheckUserExistGenqlSelection & { __args: {email: Scalars['String'], captchaToken?: (Scalars['String'] | null)} }) - checkWorkspaceInviteHashIsValid?: (WorkspaceInviteHashValidGenqlSelection & { __args: {inviteHash: Scalars['String']} }) - findWorkspaceFromInviteHash?: (WorkspaceGenqlSelection & { __args: {inviteHash: Scalars['String']} }) - validatePasswordResetToken?: (ValidatePasswordResetTokenGenqlSelection & { __args: {passwordResetToken: Scalars['String']} }) - getSSOIdentityProviders?: FindAvailableSSOIDPGenqlSelection myMessageFolders?: (MessageFolderGenqlSelection & { __args?: {messageChannelId?: (Scalars['UUID'] | null)} }) myMessageChannels?: (MessageChannelGenqlSelection & { __args?: {connectedAccountId?: (Scalars['UUID'] | null)} }) myConnectedAccounts?: ConnectedAccountDTOGenqlSelection @@ -6035,6 +6022,21 @@ export interface QueryGenqlSelection{ pieChartData?: (PieChartDataGenqlSelection & { __args: {input: PieChartDataInput} }) lineChartData?: (LineChartDataGenqlSelection & { __args: {input: LineChartDataInput} }) barChartData?: (BarChartDataGenqlSelection & { __args: {input: BarChartDataInput} }) + checkUserExists?: (CheckUserExistGenqlSelection & { __args: {email: Scalars['String'], captchaToken?: (Scalars['String'] | null)} }) + checkWorkspaceInviteHashIsValid?: (WorkspaceInviteHashValidGenqlSelection & { __args: {inviteHash: Scalars['String']} }) + findWorkspaceFromInviteHash?: (WorkspaceGenqlSelection & { __args: {inviteHash: Scalars['String']} }) + validatePasswordResetToken?: (ValidatePasswordResetTokenGenqlSelection & { __args: {passwordResetToken: Scalars['String']} }) + findApplicationRegistrationByClientId?: (PublicApplicationRegistrationGenqlSelection & { __args: {clientId: Scalars['String']} }) + findApplicationRegistrationByUniversalIdentifier?: (ApplicationRegistrationGenqlSelection & { __args: {universalIdentifier: Scalars['String']} }) + findManyApplicationRegistrations?: ApplicationRegistrationGenqlSelection + findOneApplicationRegistration?: (ApplicationRegistrationGenqlSelection & { __args: {id: Scalars['String']} }) + findApplicationRegistrationStats?: (ApplicationRegistrationStatsGenqlSelection & { __args: {id: Scalars['String']} }) + findApplicationRegistrationVariables?: (ApplicationRegistrationVariableGenqlSelection & { __args: {applicationRegistrationId: Scalars['String']} }) + applicationRegistrationTarballUrl?: { __args: {id: Scalars['String']} } + currentUser?: UserGenqlSelection + currentWorkspace?: WorkspaceGenqlSelection + getPublicWorkspaceDataByDomain?: (PublicWorkspaceDataGenqlSelection & { __args?: {origin?: (Scalars['String'] | null)} }) + getSSOIdentityProviders?: FindAvailableSSOIDPGenqlSelection getConnectedImapSmtpCaldavAccount?: (ConnectedImapSmtpCaldavAccountGenqlSelection & { __args: {id: Scalars['UUID']} }) getAutoCompleteAddress?: (AutocompleteResultGenqlSelection & { __args: {address: Scalars['String'], token: Scalars['String'], country?: (Scalars['String'] | null), isFieldCity?: (Scalars['Boolean'] | null)} }) getAddressDetails?: (PlaceDetailsResultGenqlSelection & { __args: {placeId: Scalars['String'], token: Scalars['String']} }) @@ -6062,6 +6064,8 @@ export interface QueryGenqlSelection{ __scalar?: boolean | number } +export interface GetApiKeyInput {id: Scalars['UUID']} + export interface LogicFunctionIdInput { /** The id of the function. */ id: Scalars['ID']} @@ -6070,8 +6074,6 @@ export interface AgentIdInput { /** The id of the agent. */ id: Scalars['UUID']} -export interface GetApiKeyInput {id: Scalars['UUID']} - export interface AgentChatThreadFilter {and?: (AgentChatThreadFilter[] | null),or?: (AgentChatThreadFilter[] | null),id?: (UUIDFilterComparison | null),updatedAt?: (DateFieldComparison | null)} export interface DateFieldComparison {is?: (Scalars['Boolean'] | null),isNot?: (Scalars['Boolean'] | null),eq?: (Scalars['DateTime'] | null),neq?: (Scalars['DateTime'] | null),gt?: (Scalars['DateTime'] | null),gte?: (Scalars['DateTime'] | null),lt?: (Scalars['DateTime'] | null),lte?: (Scalars['DateTime'] | null),in?: (Scalars['DateTime'][] | null),notIn?: (Scalars['DateTime'][] | null),between?: (DateFieldComparisonBetween | null),notBetween?: (DateFieldComparisonBetween | null)} @@ -6106,18 +6108,14 @@ export interface MutationGenqlSelection{ uploadWorkspaceMemberProfilePicture?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload']} }) uploadFilesFieldFile?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload'], fieldMetadataId: Scalars['String']} }) uploadFilesFieldFileByUniversalIdentifier?: (FileWithSignedUrlGenqlSelection & { __args: {file: Scalars['Upload'], fieldMetadataUniversalIdentifier: Scalars['String']} }) - createObjectEvent?: (AnalyticsGenqlSelection & { __args: {event: Scalars['String'], recordId: Scalars['UUID'], objectMetadataId: Scalars['UUID'], properties?: (Scalars['JSON'] | null)} }) - trackAnalytics?: (AnalyticsGenqlSelection & { __args: {type: AnalyticsType, name?: (Scalars['String'] | null), event?: (Scalars['String'] | null), properties?: (Scalars['JSON'] | null)} }) - createPageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {input: CreatePageLayoutWidgetInput} }) - updatePageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWidgetInput} }) - destroyPageLayoutWidget?: { __args: {id: Scalars['String']} } - createPageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {input: CreatePageLayoutTabInput} }) - updatePageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutTabInput} }) - destroyPageLayoutTab?: { __args: {id: Scalars['String']} } - createPageLayout?: (PageLayoutGenqlSelection & { __args: {input: CreatePageLayoutInput} }) - updatePageLayout?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutInput} }) - destroyPageLayout?: { __args: {id: Scalars['String']} } - updatePageLayoutWithTabsAndWidgets?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWithTabsInput} }) + createViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {input: CreateViewFilterGroupInput} }) + updateViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {id: Scalars['String'], input: UpdateViewFilterGroupInput} }) + deleteViewFilterGroup?: { __args: {id: Scalars['String']} } + destroyViewFilterGroup?: { __args: {id: Scalars['String']} } + createViewFilter?: (ViewFilterGenqlSelection & { __args: {input: CreateViewFilterInput} }) + updateViewFilter?: (ViewFilterGenqlSelection & { __args: {input: UpdateViewFilterInput} }) + deleteViewFilter?: (ViewFilterGenqlSelection & { __args: {input: DeleteViewFilterInput} }) + destroyViewFilter?: (ViewFilterGenqlSelection & { __args: {input: DestroyViewFilterInput} }) createView?: (ViewGenqlSelection & { __args: {input: CreateViewInput} }) updateView?: (ViewGenqlSelection & { __args: {id: Scalars['String'], input: UpdateViewInput} }) deleteView?: { __args: {id: Scalars['String']} } @@ -6132,6 +6130,40 @@ export interface MutationGenqlSelection{ deleteViewFieldGroup?: (ViewFieldGroupGenqlSelection & { __args: {input: DeleteViewFieldGroupInput} }) destroyViewFieldGroup?: (ViewFieldGroupGenqlSelection & { __args: {input: DestroyViewFieldGroupInput} }) upsertFieldsWidget?: (ViewGenqlSelection & { __args: {input: UpsertFieldsWidgetInput} }) + createApiKey?: (ApiKeyGenqlSelection & { __args: {input: CreateApiKeyInput} }) + updateApiKey?: (ApiKeyGenqlSelection & { __args: {input: UpdateApiKeyInput} }) + revokeApiKey?: (ApiKeyGenqlSelection & { __args: {input: RevokeApiKeyInput} }) + assignRoleToApiKey?: { __args: {apiKeyId: Scalars['UUID'], roleId: Scalars['UUID']} } + createObjectEvent?: (AnalyticsGenqlSelection & { __args: {event: Scalars['String'], recordId: Scalars['UUID'], objectMetadataId: Scalars['UUID'], properties?: (Scalars['JSON'] | null)} }) + trackAnalytics?: (AnalyticsGenqlSelection & { __args: {type: AnalyticsType, name?: (Scalars['String'] | null), event?: (Scalars['String'] | null), properties?: (Scalars['JSON'] | null)} }) + refreshEnterpriseValidityToken?: boolean | number + setEnterpriseKey?: (EnterpriseLicenseInfoDTOGenqlSelection & { __args: {enterpriseKey: Scalars['String']} }) + skipSyncEmailOnboardingStep?: OnboardingStepSuccessGenqlSelection + skipBookOnboardingStep?: OnboardingStepSuccessGenqlSelection + checkoutSession?: (BillingSessionGenqlSelection & { __args: {recurringInterval: SubscriptionInterval, plan: BillingPlanKey, requirePaymentMethod: Scalars['Boolean'], successUrlPath?: (Scalars['String'] | null)} }) + switchSubscriptionInterval?: BillingUpdateGenqlSelection + switchBillingPlan?: BillingUpdateGenqlSelection + cancelSwitchBillingPlan?: BillingUpdateGenqlSelection + cancelSwitchBillingInterval?: BillingUpdateGenqlSelection + setMeteredSubscriptionPrice?: (BillingUpdateGenqlSelection & { __args: {priceId: Scalars['String']} }) + endSubscriptionTrialPeriod?: BillingEndTrialPeriodGenqlSelection + cancelSwitchMeteredPrice?: BillingUpdateGenqlSelection + deleteWorkspaceInvitation?: { __args: {appTokenId: Scalars['String']} } + resendWorkspaceInvitation?: (SendInvitationsGenqlSelection & { __args: {appTokenId: Scalars['String']} }) + sendInvitations?: (SendInvitationsGenqlSelection & { __args: {emails: Scalars['String'][], roleId?: (Scalars['UUID'] | null)} }) + createApprovedAccessDomain?: (ApprovedAccessDomainGenqlSelection & { __args: {input: CreateApprovedAccessDomainInput} }) + deleteApprovedAccessDomain?: { __args: {input: DeleteApprovedAccessDomainInput} } + validateApprovedAccessDomain?: (ApprovedAccessDomainGenqlSelection & { __args: {input: ValidateApprovedAccessDomainInput} }) + createPageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {input: CreatePageLayoutTabInput} }) + updatePageLayoutTab?: (PageLayoutTabGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutTabInput} }) + destroyPageLayoutTab?: { __args: {id: Scalars['String']} } + createPageLayout?: (PageLayoutGenqlSelection & { __args: {input: CreatePageLayoutInput} }) + updatePageLayout?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutInput} }) + destroyPageLayout?: { __args: {id: Scalars['String']} } + updatePageLayoutWithTabsAndWidgets?: (PageLayoutGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWithTabsInput} }) + createPageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {input: CreatePageLayoutWidgetInput} }) + updatePageLayoutWidget?: (PageLayoutWidgetGenqlSelection & { __args: {id: Scalars['String'], input: UpdatePageLayoutWidgetInput} }) + destroyPageLayoutWidget?: { __args: {id: Scalars['String']} } deleteOneLogicFunction?: (LogicFunctionGenqlSelection & { __args: {input: LogicFunctionIdInput} }) createOneLogicFunction?: (LogicFunctionGenqlSelection & { __args: {input: CreateLogicFunctionFromSourceInput} }) executeOneLogicFunction?: (LogicFunctionExecutionResultGenqlSelection & { __args: {input: ExecuteOneLogicFunctionInput} }) @@ -6153,16 +6185,6 @@ export interface MutationGenqlSelection{ createOneAgent?: (AgentGenqlSelection & { __args: {input: CreateAgentInput} }) updateOneAgent?: (AgentGenqlSelection & { __args: {input: UpdateAgentInput} }) deleteOneAgent?: (AgentGenqlSelection & { __args: {input: AgentIdInput} }) - checkoutSession?: (BillingSessionGenqlSelection & { __args: {recurringInterval: SubscriptionInterval, plan: BillingPlanKey, requirePaymentMethod: Scalars['Boolean'], successUrlPath?: (Scalars['String'] | null)} }) - switchSubscriptionInterval?: BillingUpdateGenqlSelection - switchBillingPlan?: BillingUpdateGenqlSelection - cancelSwitchBillingPlan?: BillingUpdateGenqlSelection - cancelSwitchBillingInterval?: BillingUpdateGenqlSelection - setMeteredSubscriptionPrice?: (BillingUpdateGenqlSelection & { __args: {priceId: Scalars['String']} }) - endSubscriptionTrialPeriod?: BillingEndTrialPeriodGenqlSelection - cancelSwitchMeteredPrice?: BillingUpdateGenqlSelection - refreshEnterpriseValidityToken?: boolean | number - setEnterpriseKey?: (EnterpriseLicenseInfoDTOGenqlSelection & { __args: {enterpriseKey: Scalars['String']} }) updateWorkspaceMemberRole?: (WorkspaceMemberGenqlSelection & { __args: {workspaceMemberId: Scalars['UUID'], roleId: Scalars['UUID']} }) createOneRole?: (RoleGenqlSelection & { __args: {createRoleInput: CreateRoleInput} }) updateOneRole?: (RoleGenqlSelection & { __args: {updateRoleInput: UpdateRoleInput} }) @@ -6173,18 +6195,6 @@ export interface MutationGenqlSelection{ upsertRowLevelPermissionPredicates?: (UpsertRowLevelPermissionPredicatesResultGenqlSelection & { __args: {input: UpsertRowLevelPermissionPredicatesInput} }) assignRoleToAgent?: { __args: {agentId: Scalars['UUID'], roleId: Scalars['UUID']} } removeRoleFromAgent?: { __args: {agentId: Scalars['UUID']} } - skipSyncEmailOnboardingStep?: OnboardingStepSuccessGenqlSelection - skipBookOnboardingStep?: OnboardingStepSuccessGenqlSelection - deleteWorkspaceInvitation?: { __args: {appTokenId: Scalars['String']} } - resendWorkspaceInvitation?: (SendInvitationsGenqlSelection & { __args: {appTokenId: Scalars['String']} }) - sendInvitations?: (SendInvitationsGenqlSelection & { __args: {emails: Scalars['String'][], roleId?: (Scalars['UUID'] | null)} }) - createApprovedAccessDomain?: (ApprovedAccessDomainGenqlSelection & { __args: {input: CreateApprovedAccessDomainInput} }) - deleteApprovedAccessDomain?: { __args: {input: DeleteApprovedAccessDomainInput} } - validateApprovedAccessDomain?: (ApprovedAccessDomainGenqlSelection & { __args: {input: ValidateApprovedAccessDomainInput} }) - createApiKey?: (ApiKeyGenqlSelection & { __args: {input: CreateApiKeyInput} }) - updateApiKey?: (ApiKeyGenqlSelection & { __args: {input: UpdateApiKeyInput} }) - revokeApiKey?: (ApiKeyGenqlSelection & { __args: {input: RevokeApiKeyInput} }) - assignRoleToApiKey?: { __args: {apiKeyId: Scalars['UUID'], roleId: Scalars['UUID']} } createOneField?: (FieldGenqlSelection & { __args: {input: CreateOneFieldMetadataInput} }) updateOneField?: (FieldGenqlSelection & { __args: {input: UpdateOneFieldMetadataInput} }) deleteOneField?: (FieldGenqlSelection & { __args: {input: DeleteOneFieldInput} }) @@ -6193,55 +6203,6 @@ export interface MutationGenqlSelection{ updateViewGroup?: (ViewGroupGenqlSelection & { __args: {input: UpdateViewGroupInput} }) deleteViewGroup?: (ViewGroupGenqlSelection & { __args: {input: DeleteViewGroupInput} }) destroyViewGroup?: (ViewGroupGenqlSelection & { __args: {input: DestroyViewGroupInput} }) - createViewFilter?: (ViewFilterGenqlSelection & { __args: {input: CreateViewFilterInput} }) - updateViewFilter?: (ViewFilterGenqlSelection & { __args: {input: UpdateViewFilterInput} }) - deleteViewFilter?: (ViewFilterGenqlSelection & { __args: {input: DeleteViewFilterInput} }) - destroyViewFilter?: (ViewFilterGenqlSelection & { __args: {input: DestroyViewFilterInput} }) - createViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {input: CreateViewFilterGroupInput} }) - updateViewFilterGroup?: (ViewFilterGroupGenqlSelection & { __args: {id: Scalars['String'], input: UpdateViewFilterGroupInput} }) - deleteViewFilterGroup?: { __args: {id: Scalars['String']} } - destroyViewFilterGroup?: { __args: {id: Scalars['String']} } - deleteUser?: UserGenqlSelection - deleteUserFromWorkspace?: (UserWorkspaceGenqlSelection & { __args: {workspaceMemberIdToDelete: Scalars['String']} }) - updateUserEmail?: { __args: {newEmail: Scalars['String'], verifyEmailRedirectPath?: (Scalars['String'] | null)} } - resendEmailVerificationToken?: (ResendEmailVerificationTokenGenqlSelection & { __args: {email: Scalars['String'], origin: Scalars['String']} }) - activateWorkspace?: (WorkspaceGenqlSelection & { __args: {data: ActivateWorkspaceInput} }) - updateWorkspace?: (WorkspaceGenqlSelection & { __args: {data: UpdateWorkspaceInput} }) - deleteCurrentWorkspace?: WorkspaceGenqlSelection - checkCustomDomainValidRecords?: DomainValidRecordsGenqlSelection - createApplicationRegistration?: (CreateApplicationRegistrationGenqlSelection & { __args: {input: CreateApplicationRegistrationInput} }) - updateApplicationRegistration?: (ApplicationRegistrationGenqlSelection & { __args: {input: UpdateApplicationRegistrationInput} }) - deleteApplicationRegistration?: { __args: {id: Scalars['String']} } - rotateApplicationRegistrationClientSecret?: (RotateClientSecretGenqlSelection & { __args: {id: Scalars['String']} }) - createApplicationRegistrationVariable?: (ApplicationRegistrationVariableGenqlSelection & { __args: {input: CreateApplicationRegistrationVariableInput} }) - updateApplicationRegistrationVariable?: (ApplicationRegistrationVariableGenqlSelection & { __args: {input: UpdateApplicationRegistrationVariableInput} }) - deleteApplicationRegistrationVariable?: { __args: {id: Scalars['String']} } - uploadAppTarball?: (ApplicationRegistrationGenqlSelection & { __args: {file: Scalars['Upload'], universalIdentifier?: (Scalars['String'] | null)} }) - transferApplicationRegistrationOwnership?: (ApplicationRegistrationGenqlSelection & { __args: {applicationRegistrationId: Scalars['String'], targetWorkspaceSubdomain: Scalars['String']} }) - getAuthorizationUrlForSSO?: (GetAuthorizationUrlForSSOGenqlSelection & { __args: {input: GetAuthorizationUrlForSSOInput} }) - getLoginTokenFromCredentials?: (LoginTokenGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null), origin: Scalars['String']} }) - signIn?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) - verifyEmailAndGetLoginToken?: (VerifyEmailAndGetLoginTokenGenqlSelection & { __args: {emailVerificationToken: Scalars['String'], email: Scalars['String'], captchaToken?: (Scalars['String'] | null), origin: Scalars['String']} }) - verifyEmailAndGetWorkspaceAgnosticToken?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {emailVerificationToken: Scalars['String'], email: Scalars['String'], captchaToken?: (Scalars['String'] | null)} }) - getAuthTokensFromOTP?: (AuthTokensGenqlSelection & { __args: {otp: Scalars['String'], loginToken: Scalars['String'], captchaToken?: (Scalars['String'] | null), origin: Scalars['String']} }) - signUp?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) - signUpInWorkspace?: (SignUpGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], workspaceId?: (Scalars['UUID'] | null), workspaceInviteHash?: (Scalars['String'] | null), workspacePersonalInviteToken?: (Scalars['String'] | null), captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) - signUpInNewWorkspace?: SignUpGenqlSelection - generateTransientToken?: TransientTokenGenqlSelection - getAuthTokensFromLoginToken?: (AuthTokensGenqlSelection & { __args: {loginToken: Scalars['String'], origin: Scalars['String']} }) - authorizeApp?: (AuthorizeAppGenqlSelection & { __args: {clientId: Scalars['String'], codeChallenge?: (Scalars['String'] | null), redirectUrl: Scalars['String'], state?: (Scalars['String'] | null), scope?: (Scalars['String'] | null)} }) - renewToken?: (AuthTokensGenqlSelection & { __args: {appToken: Scalars['String']} }) - generateApiKeyToken?: (ApiKeyTokenGenqlSelection & { __args: {apiKeyId: Scalars['UUID'], expiresAt: Scalars['String']} }) - emailPasswordResetLink?: (EmailPasswordResetLinkGenqlSelection & { __args: {email: Scalars['String'], workspaceId?: (Scalars['UUID'] | null)} }) - updatePasswordViaResetToken?: (InvalidatePasswordGenqlSelection & { __args: {passwordResetToken: Scalars['String'], newPassword: Scalars['String']} }) - initiateOTPProvisioning?: (InitiateTwoFactorAuthenticationProvisioningGenqlSelection & { __args: {loginToken: Scalars['String'], origin: Scalars['String']} }) - initiateOTPProvisioningForAuthenticatedUser?: InitiateTwoFactorAuthenticationProvisioningGenqlSelection - deleteTwoFactorAuthenticationMethod?: (DeleteTwoFactorAuthenticationMethodGenqlSelection & { __args: {twoFactorAuthenticationMethodId: Scalars['UUID']} }) - verifyTwoFactorAuthenticationMethodForAuthenticatedUser?: (VerifyTwoFactorAuthenticationMethodGenqlSelection & { __args: {otp: Scalars['String']} }) - createOIDCIdentityProvider?: (SetupSsoGenqlSelection & { __args: {input: SetupOIDCSsoInput} }) - createSAMLIdentityProvider?: (SetupSsoGenqlSelection & { __args: {input: SetupSAMLSsoInput} }) - deleteSSOIdentityProvider?: (DeleteSsoGenqlSelection & { __args: {input: DeleteSsoInput} }) - editSSOIdentityProvider?: (EditSsoGenqlSelection & { __args: {input: EditSsoInput} }) updateMessageFolder?: (MessageFolderGenqlSelection & { __args: {input: UpdateMessageFolderInput} }) updateMessageFolders?: (MessageFolderGenqlSelection & { __args: {input: UpdateMessageFoldersInput} }) updateMessageChannel?: (MessageChannelGenqlSelection & { __args: {input: UpdateMessageChannelInput} }) @@ -6259,6 +6220,47 @@ export interface MutationGenqlSelection{ evaluateAgentTurn?: (AgentTurnEvaluationGenqlSelection & { __args: {turnId: Scalars['UUID']} }) runEvaluationInput?: (AgentTurnGenqlSelection & { __args: {agentId: Scalars['UUID'], input: Scalars['String']} }) duplicateDashboard?: (DuplicatedDashboardGenqlSelection & { __args: {id: Scalars['UUID']} }) + getAuthorizationUrlForSSO?: (GetAuthorizationUrlForSSOGenqlSelection & { __args: {input: GetAuthorizationUrlForSSOInput} }) + getLoginTokenFromCredentials?: (LoginTokenGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null), origin: Scalars['String']} }) + signIn?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) + verifyEmailAndGetLoginToken?: (VerifyEmailAndGetLoginTokenGenqlSelection & { __args: {emailVerificationToken: Scalars['String'], email: Scalars['String'], captchaToken?: (Scalars['String'] | null), origin: Scalars['String']} }) + verifyEmailAndGetWorkspaceAgnosticToken?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {emailVerificationToken: Scalars['String'], email: Scalars['String'], captchaToken?: (Scalars['String'] | null)} }) + getAuthTokensFromOTP?: (AuthTokensGenqlSelection & { __args: {otp: Scalars['String'], loginToken: Scalars['String'], captchaToken?: (Scalars['String'] | null), origin: Scalars['String']} }) + signUp?: (AvailableWorkspacesAndAccessTokensGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) + signUpInWorkspace?: (SignUpGenqlSelection & { __args: {email: Scalars['String'], password: Scalars['String'], workspaceId?: (Scalars['UUID'] | null), workspaceInviteHash?: (Scalars['String'] | null), workspacePersonalInviteToken?: (Scalars['String'] | null), captchaToken?: (Scalars['String'] | null), locale?: (Scalars['String'] | null), verifyEmailRedirectPath?: (Scalars['String'] | null)} }) + signUpInNewWorkspace?: SignUpGenqlSelection + generateTransientToken?: TransientTokenGenqlSelection + getAuthTokensFromLoginToken?: (AuthTokensGenqlSelection & { __args: {loginToken: Scalars['String'], origin: Scalars['String']} }) + authorizeApp?: (AuthorizeAppGenqlSelection & { __args: {clientId: Scalars['String'], codeChallenge?: (Scalars['String'] | null), redirectUrl: Scalars['String'], state?: (Scalars['String'] | null), scope?: (Scalars['String'] | null)} }) + renewToken?: (AuthTokensGenqlSelection & { __args: {appToken: Scalars['String']} }) + generateApiKeyToken?: (ApiKeyTokenGenqlSelection & { __args: {apiKeyId: Scalars['UUID'], expiresAt: Scalars['String']} }) + emailPasswordResetLink?: (EmailPasswordResetLinkGenqlSelection & { __args: {email: Scalars['String'], workspaceId?: (Scalars['UUID'] | null)} }) + updatePasswordViaResetToken?: (InvalidatePasswordGenqlSelection & { __args: {passwordResetToken: Scalars['String'], newPassword: Scalars['String']} }) + createApplicationRegistration?: (CreateApplicationRegistrationGenqlSelection & { __args: {input: CreateApplicationRegistrationInput} }) + updateApplicationRegistration?: (ApplicationRegistrationGenqlSelection & { __args: {input: UpdateApplicationRegistrationInput} }) + deleteApplicationRegistration?: { __args: {id: Scalars['String']} } + rotateApplicationRegistrationClientSecret?: (RotateClientSecretGenqlSelection & { __args: {id: Scalars['String']} }) + createApplicationRegistrationVariable?: (ApplicationRegistrationVariableGenqlSelection & { __args: {input: CreateApplicationRegistrationVariableInput} }) + updateApplicationRegistrationVariable?: (ApplicationRegistrationVariableGenqlSelection & { __args: {input: UpdateApplicationRegistrationVariableInput} }) + deleteApplicationRegistrationVariable?: { __args: {id: Scalars['String']} } + uploadAppTarball?: (ApplicationRegistrationGenqlSelection & { __args: {file: Scalars['Upload'], universalIdentifier?: (Scalars['String'] | null)} }) + transferApplicationRegistrationOwnership?: (ApplicationRegistrationGenqlSelection & { __args: {applicationRegistrationId: Scalars['String'], targetWorkspaceSubdomain: Scalars['String']} }) + initiateOTPProvisioning?: (InitiateTwoFactorAuthenticationProvisioningGenqlSelection & { __args: {loginToken: Scalars['String'], origin: Scalars['String']} }) + initiateOTPProvisioningForAuthenticatedUser?: InitiateTwoFactorAuthenticationProvisioningGenqlSelection + deleteTwoFactorAuthenticationMethod?: (DeleteTwoFactorAuthenticationMethodGenqlSelection & { __args: {twoFactorAuthenticationMethodId: Scalars['UUID']} }) + verifyTwoFactorAuthenticationMethodForAuthenticatedUser?: (VerifyTwoFactorAuthenticationMethodGenqlSelection & { __args: {otp: Scalars['String']} }) + deleteUser?: UserGenqlSelection + deleteUserFromWorkspace?: (UserWorkspaceGenqlSelection & { __args: {workspaceMemberIdToDelete: Scalars['String']} }) + updateUserEmail?: { __args: {newEmail: Scalars['String'], verifyEmailRedirectPath?: (Scalars['String'] | null)} } + resendEmailVerificationToken?: (ResendEmailVerificationTokenGenqlSelection & { __args: {email: Scalars['String'], origin: Scalars['String']} }) + activateWorkspace?: (WorkspaceGenqlSelection & { __args: {data: ActivateWorkspaceInput} }) + updateWorkspace?: (WorkspaceGenqlSelection & { __args: {data: UpdateWorkspaceInput} }) + deleteCurrentWorkspace?: WorkspaceGenqlSelection + checkCustomDomainValidRecords?: DomainValidRecordsGenqlSelection + createOIDCIdentityProvider?: (SetupSsoGenqlSelection & { __args: {input: SetupOIDCSsoInput} }) + createSAMLIdentityProvider?: (SetupSsoGenqlSelection & { __args: {input: SetupSAMLSsoInput} }) + deleteSSOIdentityProvider?: (DeleteSsoGenqlSelection & { __args: {input: DeleteSsoInput} }) + editSSOIdentityProvider?: (EditSsoGenqlSelection & { __args: {input: EditSsoInput} }) impersonate?: (ImpersonateGenqlSelection & { __args: {userId: Scalars['UUID'], workspaceId: Scalars['UUID']} }) startChannelSync?: (ChannelSyncSuccessGenqlSelection & { __args: {connectedAccountId: Scalars['UUID']} }) saveImapSmtpCaldavAccount?: (ImapSmtpCaldavConnectionSuccessGenqlSelection & { __args: {accountOwnerId: Scalars['UUID'], handle: Scalars['String'], connectionParameters: EmailAccountConnectionParameters, id?: (Scalars['UUID'] | null)} }) @@ -6315,25 +6317,27 @@ update: UpdateNavigationMenuItemInput} export interface UpdateNavigationMenuItemInput {folderId?: (Scalars['UUID'] | null),position?: (Scalars['Float'] | null),name?: (Scalars['String'] | null),link?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),color?: (Scalars['String'] | null)} -export interface CreatePageLayoutWidgetInput {pageLayoutTabId: Scalars['UUID'],title: Scalars['String'],type: WidgetType,objectMetadataId?: (Scalars['UUID'] | null),gridPosition: GridPositionInput,position?: (Scalars['JSON'] | null),configuration: Scalars['JSON']} +export interface CreateViewFilterGroupInput {id?: (Scalars['UUID'] | null),parentViewFilterGroupId?: (Scalars['UUID'] | null),logicalOperator?: (ViewFilterGroupLogicalOperator | null),positionInViewFilterGroup?: (Scalars['Float'] | null),viewId: Scalars['UUID']} -export interface GridPositionInput {row: Scalars['Float'],column: Scalars['Float'],rowSpan: Scalars['Float'],columnSpan: Scalars['Float']} +export interface UpdateViewFilterGroupInput {id?: (Scalars['UUID'] | null),parentViewFilterGroupId?: (Scalars['UUID'] | null),logicalOperator?: (ViewFilterGroupLogicalOperator | null),positionInViewFilterGroup?: (Scalars['Float'] | null),viewId?: (Scalars['UUID'] | null)} -export interface UpdatePageLayoutWidgetInput {title?: (Scalars['String'] | null),type?: (WidgetType | null),objectMetadataId?: (Scalars['UUID'] | null),gridPosition?: (GridPositionInput | null),position?: (Scalars['JSON'] | null),configuration?: (Scalars['JSON'] | null),conditionalDisplay?: (Scalars['JSON'] | null)} +export interface CreateViewFilterInput {id?: (Scalars['UUID'] | null),fieldMetadataId: Scalars['UUID'],operand?: (ViewFilterOperand | null),value: Scalars['JSON'],viewFilterGroupId?: (Scalars['UUID'] | null),positionInViewFilterGroup?: (Scalars['Float'] | null),subFieldName?: (Scalars['String'] | null),viewId: Scalars['UUID']} -export interface CreatePageLayoutTabInput {title: Scalars['String'],position?: (Scalars['Float'] | null),pageLayoutId: Scalars['UUID'],layoutMode?: (PageLayoutTabLayoutMode | null)} +export interface UpdateViewFilterInput { +/** The id of the view filter to update */ +id: Scalars['UUID'], +/** The view filter to update */ +update: UpdateViewFilterInputUpdates} -export interface UpdatePageLayoutTabInput {title?: (Scalars['String'] | null),position?: (Scalars['Float'] | null),icon?: (Scalars['String'] | null),layoutMode?: (PageLayoutTabLayoutMode | null)} +export interface UpdateViewFilterInputUpdates {fieldMetadataId?: (Scalars['UUID'] | null),operand?: (ViewFilterOperand | null),value?: (Scalars['JSON'] | null),viewFilterGroupId?: (Scalars['UUID'] | null),positionInViewFilterGroup?: (Scalars['Float'] | null),subFieldName?: (Scalars['String'] | null)} -export interface CreatePageLayoutInput {name: Scalars['String'],type?: (PageLayoutType | null),objectMetadataId?: (Scalars['UUID'] | null)} +export interface DeleteViewFilterInput { +/** The id of the view filter to delete. */ +id: Scalars['UUID']} -export interface UpdatePageLayoutInput {name?: (Scalars['String'] | null),type?: (PageLayoutType | null),objectMetadataId?: (Scalars['UUID'] | null)} - -export interface UpdatePageLayoutWithTabsInput {name: Scalars['String'],type: PageLayoutType,objectMetadataId?: (Scalars['UUID'] | null),tabs: UpdatePageLayoutTabWithWidgetsInput[]} - -export interface UpdatePageLayoutTabWithWidgetsInput {id: Scalars['UUID'],title: Scalars['String'],position: Scalars['Float'],icon?: (Scalars['String'] | null),layoutMode?: (PageLayoutTabLayoutMode | null),widgets: UpdatePageLayoutWidgetWithIdInput[]} - -export interface UpdatePageLayoutWidgetWithIdInput {id: Scalars['UUID'],pageLayoutTabId: Scalars['UUID'],title: Scalars['String'],type: WidgetType,objectMetadataId?: (Scalars['UUID'] | null),gridPosition: GridPositionInput,position?: (Scalars['JSON'] | null),configuration?: (Scalars['JSON'] | null),conditionalDisplay?: (Scalars['JSON'] | null)} +export interface DestroyViewFilterInput { +/** The id of the view filter to destroy. */ +id: Scalars['UUID']} export interface CreateViewInput {id?: (Scalars['UUID'] | null),name: Scalars['String'],objectMetadataId: Scalars['UUID'],type?: (ViewType | null),key?: (ViewKey | null),icon: Scalars['String'],position?: (Scalars['Float'] | null),isCompact?: (Scalars['Boolean'] | null),shouldHideEmptyGroups?: (Scalars['Boolean'] | null),openRecordIn?: (ViewOpenRecordIn | null),kanbanAggregateOperation?: (AggregateOperations | null),kanbanAggregateOperationFieldMetadataId?: (Scalars['UUID'] | null),anyFieldFilterValue?: (Scalars['String'] | null),calendarLayout?: (ViewCalendarLayout | null),calendarFieldMetadataId?: (Scalars['UUID'] | null),mainGroupByFieldMetadataId?: (Scalars['UUID'] | null),visibility?: (ViewVisibility | null)} @@ -6389,6 +6393,38 @@ export interface UpsertFieldsWidgetFieldInput { /** The id of the view field */ viewFieldId: Scalars['UUID'],isVisible: Scalars['Boolean'],position: Scalars['Float']} +export interface CreateApiKeyInput {name: Scalars['String'],expiresAt: Scalars['String'],revokedAt?: (Scalars['String'] | null),roleId: Scalars['UUID']} + +export interface UpdateApiKeyInput {id: Scalars['UUID'],name?: (Scalars['String'] | null),expiresAt?: (Scalars['String'] | null),revokedAt?: (Scalars['String'] | null)} + +export interface RevokeApiKeyInput {id: Scalars['UUID']} + +export interface CreateApprovedAccessDomainInput {domain: Scalars['String'],email: Scalars['String']} + +export interface DeleteApprovedAccessDomainInput {id: Scalars['UUID']} + +export interface ValidateApprovedAccessDomainInput {validationToken: Scalars['String'],approvedAccessDomainId: Scalars['UUID']} + +export interface CreatePageLayoutTabInput {title: Scalars['String'],position?: (Scalars['Float'] | null),pageLayoutId: Scalars['UUID'],layoutMode?: (PageLayoutTabLayoutMode | null)} + +export interface UpdatePageLayoutTabInput {title?: (Scalars['String'] | null),position?: (Scalars['Float'] | null),icon?: (Scalars['String'] | null),layoutMode?: (PageLayoutTabLayoutMode | null)} + +export interface CreatePageLayoutInput {name: Scalars['String'],type?: (PageLayoutType | null),objectMetadataId?: (Scalars['UUID'] | null)} + +export interface UpdatePageLayoutInput {name?: (Scalars['String'] | null),type?: (PageLayoutType | null),objectMetadataId?: (Scalars['UUID'] | null)} + +export interface UpdatePageLayoutWithTabsInput {name: Scalars['String'],type: PageLayoutType,objectMetadataId?: (Scalars['UUID'] | null),tabs: UpdatePageLayoutTabWithWidgetsInput[]} + +export interface UpdatePageLayoutTabWithWidgetsInput {id: Scalars['UUID'],title: Scalars['String'],position: Scalars['Float'],icon?: (Scalars['String'] | null),layoutMode?: (PageLayoutTabLayoutMode | null),widgets: UpdatePageLayoutWidgetWithIdInput[]} + +export interface UpdatePageLayoutWidgetWithIdInput {id: Scalars['UUID'],pageLayoutTabId: Scalars['UUID'],title: Scalars['String'],type: WidgetType,objectMetadataId?: (Scalars['UUID'] | null),gridPosition: GridPositionInput,position?: (Scalars['JSON'] | null),configuration?: (Scalars['JSON'] | null),conditionalDisplay?: (Scalars['JSON'] | null)} + +export interface GridPositionInput {row: Scalars['Float'],column: Scalars['Float'],rowSpan: Scalars['Float'],columnSpan: Scalars['Float']} + +export interface CreatePageLayoutWidgetInput {pageLayoutTabId: Scalars['UUID'],title: Scalars['String'],type: WidgetType,objectMetadataId?: (Scalars['UUID'] | null),gridPosition: GridPositionInput,position?: (Scalars['JSON'] | null),configuration: Scalars['JSON']} + +export interface UpdatePageLayoutWidgetInput {title?: (Scalars['String'] | null),type?: (WidgetType | null),objectMetadataId?: (Scalars['UUID'] | null),gridPosition?: (GridPositionInput | null),position?: (Scalars['JSON'] | null),configuration?: (Scalars['JSON'] | null),conditionalDisplay?: (Scalars['JSON'] | null)} + export interface CreateLogicFunctionFromSourceInput {id?: (Scalars['UUID'] | null),universalIdentifier?: (Scalars['UUID'] | null),name: Scalars['String'],description?: (Scalars['String'] | null),timeoutSeconds?: (Scalars['Float'] | null),toolInputSchema?: (Scalars['JSON'] | null),isTool?: (Scalars['Boolean'] | null),source?: (Scalars['JSON'] | null),cronTriggerSettings?: (Scalars['JSON'] | null),databaseEventTriggerSettings?: (Scalars['JSON'] | null),httpRouteTriggerSettings?: (Scalars['JSON'] | null)} export interface ExecuteOneLogicFunctionInput { @@ -6481,18 +6517,6 @@ export interface RowLevelPermissionPredicateInput {id?: (Scalars['UUID'] | null) export interface RowLevelPermissionPredicateGroupInput {id?: (Scalars['UUID'] | null),objectMetadataId: Scalars['UUID'],parentRowLevelPermissionPredicateGroupId?: (Scalars['UUID'] | null),logicalOperator: RowLevelPermissionPredicateGroupLogicalOperator,positionInRowLevelPermissionPredicateGroup?: (Scalars['Float'] | null)} -export interface CreateApprovedAccessDomainInput {domain: Scalars['String'],email: Scalars['String']} - -export interface DeleteApprovedAccessDomainInput {id: Scalars['UUID']} - -export interface ValidateApprovedAccessDomainInput {validationToken: Scalars['String'],approvedAccessDomainId: Scalars['UUID']} - -export interface CreateApiKeyInput {name: Scalars['String'],expiresAt: Scalars['String'],revokedAt?: (Scalars['String'] | null),roleId: Scalars['UUID']} - -export interface UpdateApiKeyInput {id: Scalars['UUID'],name?: (Scalars['String'] | null),expiresAt?: (Scalars['String'] | null),revokedAt?: (Scalars['String'] | null)} - -export interface RevokeApiKeyInput {id: Scalars['UUID']} - export interface CreateOneFieldMetadataInput { /** The record to create */ field: CreateFieldInput} @@ -6529,54 +6553,6 @@ export interface DestroyViewGroupInput { /** The id of the view group to destroy. */ id: Scalars['UUID']} -export interface CreateViewFilterInput {id?: (Scalars['UUID'] | null),fieldMetadataId: Scalars['UUID'],operand?: (ViewFilterOperand | null),value: Scalars['JSON'],viewFilterGroupId?: (Scalars['UUID'] | null),positionInViewFilterGroup?: (Scalars['Float'] | null),subFieldName?: (Scalars['String'] | null),viewId: Scalars['UUID']} - -export interface UpdateViewFilterInput { -/** The id of the view filter to update */ -id: Scalars['UUID'], -/** The view filter to update */ -update: UpdateViewFilterInputUpdates} - -export interface UpdateViewFilterInputUpdates {fieldMetadataId?: (Scalars['UUID'] | null),operand?: (ViewFilterOperand | null),value?: (Scalars['JSON'] | null),viewFilterGroupId?: (Scalars['UUID'] | null),positionInViewFilterGroup?: (Scalars['Float'] | null),subFieldName?: (Scalars['String'] | null)} - -export interface DeleteViewFilterInput { -/** The id of the view filter to delete. */ -id: Scalars['UUID']} - -export interface DestroyViewFilterInput { -/** The id of the view filter to destroy. */ -id: Scalars['UUID']} - -export interface CreateViewFilterGroupInput {id?: (Scalars['UUID'] | null),parentViewFilterGroupId?: (Scalars['UUID'] | null),logicalOperator?: (ViewFilterGroupLogicalOperator | null),positionInViewFilterGroup?: (Scalars['Float'] | null),viewId: Scalars['UUID']} - -export interface UpdateViewFilterGroupInput {id?: (Scalars['UUID'] | null),parentViewFilterGroupId?: (Scalars['UUID'] | null),logicalOperator?: (ViewFilterGroupLogicalOperator | null),positionInViewFilterGroup?: (Scalars['Float'] | null),viewId?: (Scalars['UUID'] | null)} - -export interface ActivateWorkspaceInput {displayName?: (Scalars['String'] | null)} - -export interface UpdateWorkspaceInput {subdomain?: (Scalars['String'] | null),customDomain?: (Scalars['String'] | null),displayName?: (Scalars['String'] | null),logo?: (Scalars['String'] | null),inviteHash?: (Scalars['String'] | null),isPublicInviteLinkEnabled?: (Scalars['Boolean'] | null),allowImpersonation?: (Scalars['Boolean'] | null),isGoogleAuthEnabled?: (Scalars['Boolean'] | null),isMicrosoftAuthEnabled?: (Scalars['Boolean'] | null),isPasswordAuthEnabled?: (Scalars['Boolean'] | null),isGoogleAuthBypassEnabled?: (Scalars['Boolean'] | null),isMicrosoftAuthBypassEnabled?: (Scalars['Boolean'] | null),isPasswordAuthBypassEnabled?: (Scalars['Boolean'] | null),defaultRoleId?: (Scalars['UUID'] | null),isTwoFactorAuthenticationEnforced?: (Scalars['Boolean'] | null),trashRetentionDays?: (Scalars['Float'] | null),eventLogRetentionDays?: (Scalars['Float'] | null),fastModel?: (Scalars['String'] | null),smartModel?: (Scalars['String'] | null),aiAdditionalInstructions?: (Scalars['String'] | null),editableProfileFields?: (Scalars['String'][] | null),enabledAiModelIds?: (Scalars['String'][] | null),useRecommendedModels?: (Scalars['Boolean'] | null)} - -export interface CreateApplicationRegistrationInput {name: Scalars['String'],description?: (Scalars['String'] | null),logoUrl?: (Scalars['String'] | null),author?: (Scalars['String'] | null),universalIdentifier?: (Scalars['String'] | null),oAuthRedirectUris?: (Scalars['String'][] | null),oAuthScopes?: (Scalars['String'][] | null),websiteUrl?: (Scalars['String'] | null),termsUrl?: (Scalars['String'] | null)} - -export interface UpdateApplicationRegistrationInput {id: Scalars['String'],update: UpdateApplicationRegistrationPayload} - -export interface UpdateApplicationRegistrationPayload {name?: (Scalars['String'] | null),description?: (Scalars['String'] | null),logoUrl?: (Scalars['String'] | null),author?: (Scalars['String'] | null),oAuthRedirectUris?: (Scalars['String'][] | null),oAuthScopes?: (Scalars['String'][] | null),websiteUrl?: (Scalars['String'] | null),termsUrl?: (Scalars['String'] | null),isListed?: (Scalars['Boolean'] | null)} - -export interface CreateApplicationRegistrationVariableInput {applicationRegistrationId: Scalars['String'],key: Scalars['String'],value: Scalars['String'],description?: (Scalars['String'] | null),isSecret?: (Scalars['Boolean'] | null)} - -export interface UpdateApplicationRegistrationVariableInput {id: Scalars['String'],update: UpdateApplicationRegistrationVariablePayload} - -export interface UpdateApplicationRegistrationVariablePayload {value?: (Scalars['String'] | null),description?: (Scalars['String'] | null)} - -export interface GetAuthorizationUrlForSSOInput {identityProviderId: Scalars['UUID'],workspaceInviteHash?: (Scalars['String'] | null)} - -export interface SetupOIDCSsoInput {name: Scalars['String'],issuer: Scalars['String'],clientID: Scalars['String'],clientSecret: Scalars['String']} - -export interface SetupSAMLSsoInput {name: Scalars['String'],issuer: Scalars['String'],id: Scalars['UUID'],ssoURL: Scalars['String'],certificate: Scalars['String'],fingerprint?: (Scalars['String'] | null)} - -export interface DeleteSsoInput {identityProviderId: Scalars['UUID']} - -export interface EditSsoInput {id: Scalars['UUID'],status: SSOIdentityProviderStatus} - export interface UpdateMessageFolderInput {id: Scalars['UUID'],update: UpdateMessageFolderInputUpdates} export interface UpdateMessageFolderInputUpdates {isSynced?: (Scalars['Boolean'] | null)} @@ -6605,6 +6581,32 @@ export interface CreateSkillInput {id?: (Scalars['UUID'] | null),name: Scalars[' export interface UpdateSkillInput {id: Scalars['UUID'],name?: (Scalars['String'] | null),label?: (Scalars['String'] | null),icon?: (Scalars['String'] | null),description?: (Scalars['String'] | null),content?: (Scalars['String'] | null),isActive?: (Scalars['Boolean'] | null)} +export interface GetAuthorizationUrlForSSOInput {identityProviderId: Scalars['UUID'],workspaceInviteHash?: (Scalars['String'] | null)} + +export interface CreateApplicationRegistrationInput {name: Scalars['String'],description?: (Scalars['String'] | null),logoUrl?: (Scalars['String'] | null),author?: (Scalars['String'] | null),universalIdentifier?: (Scalars['String'] | null),oAuthRedirectUris?: (Scalars['String'][] | null),oAuthScopes?: (Scalars['String'][] | null),websiteUrl?: (Scalars['String'] | null),termsUrl?: (Scalars['String'] | null)} + +export interface UpdateApplicationRegistrationInput {id: Scalars['String'],update: UpdateApplicationRegistrationPayload} + +export interface UpdateApplicationRegistrationPayload {name?: (Scalars['String'] | null),description?: (Scalars['String'] | null),logoUrl?: (Scalars['String'] | null),author?: (Scalars['String'] | null),oAuthRedirectUris?: (Scalars['String'][] | null),oAuthScopes?: (Scalars['String'][] | null),websiteUrl?: (Scalars['String'] | null),termsUrl?: (Scalars['String'] | null),isListed?: (Scalars['Boolean'] | null)} + +export interface CreateApplicationRegistrationVariableInput {applicationRegistrationId: Scalars['String'],key: Scalars['String'],value: Scalars['String'],description?: (Scalars['String'] | null),isSecret?: (Scalars['Boolean'] | null)} + +export interface UpdateApplicationRegistrationVariableInput {id: Scalars['String'],update: UpdateApplicationRegistrationVariablePayload} + +export interface UpdateApplicationRegistrationVariablePayload {value?: (Scalars['String'] | null),description?: (Scalars['String'] | null)} + +export interface ActivateWorkspaceInput {displayName?: (Scalars['String'] | null)} + +export interface UpdateWorkspaceInput {subdomain?: (Scalars['String'] | null),customDomain?: (Scalars['String'] | null),displayName?: (Scalars['String'] | null),logo?: (Scalars['String'] | null),inviteHash?: (Scalars['String'] | null),isPublicInviteLinkEnabled?: (Scalars['Boolean'] | null),allowImpersonation?: (Scalars['Boolean'] | null),isGoogleAuthEnabled?: (Scalars['Boolean'] | null),isMicrosoftAuthEnabled?: (Scalars['Boolean'] | null),isPasswordAuthEnabled?: (Scalars['Boolean'] | null),isGoogleAuthBypassEnabled?: (Scalars['Boolean'] | null),isMicrosoftAuthBypassEnabled?: (Scalars['Boolean'] | null),isPasswordAuthBypassEnabled?: (Scalars['Boolean'] | null),defaultRoleId?: (Scalars['UUID'] | null),isTwoFactorAuthenticationEnforced?: (Scalars['Boolean'] | null),trashRetentionDays?: (Scalars['Float'] | null),eventLogRetentionDays?: (Scalars['Float'] | null),fastModel?: (Scalars['String'] | null),smartModel?: (Scalars['String'] | null),aiAdditionalInstructions?: (Scalars['String'] | null),editableProfileFields?: (Scalars['String'][] | null),enabledAiModelIds?: (Scalars['String'][] | null),useRecommendedModels?: (Scalars['Boolean'] | null)} + +export interface SetupOIDCSsoInput {name: Scalars['String'],issuer: Scalars['String'],clientID: Scalars['String'],clientSecret: Scalars['String']} + +export interface SetupSAMLSsoInput {name: Scalars['String'],issuer: Scalars['String'],id: Scalars['UUID'],ssoURL: Scalars['String'],certificate: Scalars['String'],fingerprint?: (Scalars['String'] | null)} + +export interface DeleteSsoInput {identityProviderId: Scalars['UUID']} + +export interface EditSsoInput {id: Scalars['UUID'],status: SSOIdentityProviderStatus} + export interface EmailAccountConnectionParameters {IMAP?: (ConnectionParameters | null),SMTP?: (ConnectionParameters | null),CALDAV?: (ConnectionParameters | null)} export interface ConnectionParameters {host: Scalars['String'],port: Scalars['Float'],username?: (Scalars['String'] | null),password: Scalars['String'],secure?: (Scalars['Boolean'] | null)} @@ -7375,478 +7377,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null - const ResendEmailVerificationToken_possibleTypes: string[] = ['ResendEmailVerificationToken'] - export const isResendEmailVerificationToken = (obj?: { __typename?: any } | null): obj is ResendEmailVerificationToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isResendEmailVerificationToken"') - return ResendEmailVerificationToken_possibleTypes.includes(obj.__typename) - } - - - - const WorkspaceUrls_possibleTypes: string[] = ['WorkspaceUrls'] - export const isWorkspaceUrls = (obj?: { __typename?: any } | null): obj is WorkspaceUrls => { - if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceUrls"') - return WorkspaceUrls_possibleTypes.includes(obj.__typename) - } - - - - const SSOConnection_possibleTypes: string[] = ['SSOConnection'] - export const isSSOConnection = (obj?: { __typename?: any } | null): obj is SSOConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isSSOConnection"') - return SSOConnection_possibleTypes.includes(obj.__typename) - } - - - - const AvailableWorkspace_possibleTypes: string[] = ['AvailableWorkspace'] - export const isAvailableWorkspace = (obj?: { __typename?: any } | null): obj is AvailableWorkspace => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspace"') - return AvailableWorkspace_possibleTypes.includes(obj.__typename) - } - - - - const AvailableWorkspaces_possibleTypes: string[] = ['AvailableWorkspaces'] - export const isAvailableWorkspaces = (obj?: { __typename?: any } | null): obj is AvailableWorkspaces => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspaces"') - return AvailableWorkspaces_possibleTypes.includes(obj.__typename) - } - - - - const DeletedWorkspaceMember_possibleTypes: string[] = ['DeletedWorkspaceMember'] - export const isDeletedWorkspaceMember = (obj?: { __typename?: any } | null): obj is DeletedWorkspaceMember => { - if (!obj?.__typename) throw new Error('__typename is missing in "isDeletedWorkspaceMember"') - return DeletedWorkspaceMember_possibleTypes.includes(obj.__typename) - } - - - - const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement'] - export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => { - if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"') - return BillingEntitlement_possibleTypes.includes(obj.__typename) - } - - - - const DomainRecord_possibleTypes: string[] = ['DomainRecord'] - export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => { - if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"') - return DomainRecord_possibleTypes.includes(obj.__typename) - } - - - - const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords'] - export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => { - if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"') - return DomainValidRecords_possibleTypes.includes(obj.__typename) - } - - - - const FeatureFlag_possibleTypes: string[] = ['FeatureFlag'] - export const isFeatureFlag = (obj?: { __typename?: any } | null): obj is FeatureFlag => { - if (!obj?.__typename) throw new Error('__typename is missing in "isFeatureFlag"') - return FeatureFlag_possibleTypes.includes(obj.__typename) - } - - - - const SSOIdentityProvider_possibleTypes: string[] = ['SSOIdentityProvider'] - export const isSSOIdentityProvider = (obj?: { __typename?: any } | null): obj is SSOIdentityProvider => { - if (!obj?.__typename) throw new Error('__typename is missing in "isSSOIdentityProvider"') - return SSOIdentityProvider_possibleTypes.includes(obj.__typename) - } - - - - const AuthProviders_possibleTypes: string[] = ['AuthProviders'] - export const isAuthProviders = (obj?: { __typename?: any } | null): obj is AuthProviders => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthProviders"') - return AuthProviders_possibleTypes.includes(obj.__typename) - } - - - - const AuthBypassProviders_possibleTypes: string[] = ['AuthBypassProviders'] - export const isAuthBypassProviders = (obj?: { __typename?: any } | null): obj is AuthBypassProviders => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthBypassProviders"') - return AuthBypassProviders_possibleTypes.includes(obj.__typename) - } - - - - const PublicWorkspaceData_possibleTypes: string[] = ['PublicWorkspaceData'] - export const isPublicWorkspaceData = (obj?: { __typename?: any } | null): obj is PublicWorkspaceData => { - if (!obj?.__typename) throw new Error('__typename is missing in "isPublicWorkspaceData"') - return PublicWorkspaceData_possibleTypes.includes(obj.__typename) - } - - - - const IndexEdge_possibleTypes: string[] = ['IndexEdge'] - export const isIndexEdge = (obj?: { __typename?: any } | null): obj is IndexEdge => { - if (!obj?.__typename) throw new Error('__typename is missing in "isIndexEdge"') - return IndexEdge_possibleTypes.includes(obj.__typename) - } - - - - const PageInfo_possibleTypes: string[] = ['PageInfo'] - export const isPageInfo = (obj?: { __typename?: any } | null): obj is PageInfo => { - if (!obj?.__typename) throw new Error('__typename is missing in "isPageInfo"') - return PageInfo_possibleTypes.includes(obj.__typename) - } - - - - const IndexConnection_possibleTypes: string[] = ['IndexConnection'] - export const isIndexConnection = (obj?: { __typename?: any } | null): obj is IndexConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isIndexConnection"') - return IndexConnection_possibleTypes.includes(obj.__typename) - } - - - - const IndexFieldEdge_possibleTypes: string[] = ['IndexFieldEdge'] - export const isIndexFieldEdge = (obj?: { __typename?: any } | null): obj is IndexFieldEdge => { - if (!obj?.__typename) throw new Error('__typename is missing in "isIndexFieldEdge"') - return IndexFieldEdge_possibleTypes.includes(obj.__typename) - } - - - - const IndexIndexFieldMetadatasConnection_possibleTypes: string[] = ['IndexIndexFieldMetadatasConnection'] - export const isIndexIndexFieldMetadatasConnection = (obj?: { __typename?: any } | null): obj is IndexIndexFieldMetadatasConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isIndexIndexFieldMetadatasConnection"') - return IndexIndexFieldMetadatasConnection_possibleTypes.includes(obj.__typename) - } - - - - const ObjectEdge_possibleTypes: string[] = ['ObjectEdge'] - export const isObjectEdge = (obj?: { __typename?: any } | null): obj is ObjectEdge => { - if (!obj?.__typename) throw new Error('__typename is missing in "isObjectEdge"') - return ObjectEdge_possibleTypes.includes(obj.__typename) - } - - - - const IndexObjectMetadataConnection_possibleTypes: string[] = ['IndexObjectMetadataConnection'] - export const isIndexObjectMetadataConnection = (obj?: { __typename?: any } | null): obj is IndexObjectMetadataConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isIndexObjectMetadataConnection"') - return IndexObjectMetadataConnection_possibleTypes.includes(obj.__typename) - } - - - - const ObjectRecordCount_possibleTypes: string[] = ['ObjectRecordCount'] - export const isObjectRecordCount = (obj?: { __typename?: any } | null): obj is ObjectRecordCount => { - if (!obj?.__typename) throw new Error('__typename is missing in "isObjectRecordCount"') - return ObjectRecordCount_possibleTypes.includes(obj.__typename) - } - - - - const ObjectConnection_possibleTypes: string[] = ['ObjectConnection'] - export const isObjectConnection = (obj?: { __typename?: any } | null): obj is ObjectConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isObjectConnection"') - return ObjectConnection_possibleTypes.includes(obj.__typename) - } - - - - const ObjectIndexMetadatasConnection_possibleTypes: string[] = ['ObjectIndexMetadatasConnection'] - export const isObjectIndexMetadatasConnection = (obj?: { __typename?: any } | null): obj is ObjectIndexMetadatasConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isObjectIndexMetadatasConnection"') - return ObjectIndexMetadatasConnection_possibleTypes.includes(obj.__typename) - } - - - - const FieldEdge_possibleTypes: string[] = ['FieldEdge'] - export const isFieldEdge = (obj?: { __typename?: any } | null): obj is FieldEdge => { - if (!obj?.__typename) throw new Error('__typename is missing in "isFieldEdge"') - return FieldEdge_possibleTypes.includes(obj.__typename) - } - - - - const ObjectFieldsConnection_possibleTypes: string[] = ['ObjectFieldsConnection'] - export const isObjectFieldsConnection = (obj?: { __typename?: any } | null): obj is ObjectFieldsConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isObjectFieldsConnection"') - return ObjectFieldsConnection_possibleTypes.includes(obj.__typename) - } - - - - const UpsertRowLevelPermissionPredicatesResult_possibleTypes: string[] = ['UpsertRowLevelPermissionPredicatesResult'] - export const isUpsertRowLevelPermissionPredicatesResult = (obj?: { __typename?: any } | null): obj is UpsertRowLevelPermissionPredicatesResult => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUpsertRowLevelPermissionPredicatesResult"') - return UpsertRowLevelPermissionPredicatesResult_possibleTypes.includes(obj.__typename) - } - - - - const VersionDistributionEntry_possibleTypes: string[] = ['VersionDistributionEntry'] - export const isVersionDistributionEntry = (obj?: { __typename?: any } | null): obj is VersionDistributionEntry => { - if (!obj?.__typename) throw new Error('__typename is missing in "isVersionDistributionEntry"') - return VersionDistributionEntry_possibleTypes.includes(obj.__typename) - } - - - - const ApplicationRegistrationStats_possibleTypes: string[] = ['ApplicationRegistrationStats'] - export const isApplicationRegistrationStats = (obj?: { __typename?: any } | null): obj is ApplicationRegistrationStats => { - if (!obj?.__typename) throw new Error('__typename is missing in "isApplicationRegistrationStats"') - return ApplicationRegistrationStats_possibleTypes.includes(obj.__typename) - } - - - - const CreateApplicationRegistration_possibleTypes: string[] = ['CreateApplicationRegistration'] - export const isCreateApplicationRegistration = (obj?: { __typename?: any } | null): obj is CreateApplicationRegistration => { - if (!obj?.__typename) throw new Error('__typename is missing in "isCreateApplicationRegistration"') - return CreateApplicationRegistration_possibleTypes.includes(obj.__typename) - } - - - - const PublicApplicationRegistration_possibleTypes: string[] = ['PublicApplicationRegistration'] - export const isPublicApplicationRegistration = (obj?: { __typename?: any } | null): obj is PublicApplicationRegistration => { - if (!obj?.__typename) throw new Error('__typename is missing in "isPublicApplicationRegistration"') - return PublicApplicationRegistration_possibleTypes.includes(obj.__typename) - } - - - - const RotateClientSecret_possibleTypes: string[] = ['RotateClientSecret'] - export const isRotateClientSecret = (obj?: { __typename?: any } | null): obj is RotateClientSecret => { - if (!obj?.__typename) throw new Error('__typename is missing in "isRotateClientSecret"') - return RotateClientSecret_possibleTypes.includes(obj.__typename) - } - - - - const Relation_possibleTypes: string[] = ['Relation'] - export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => { - if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"') - return Relation_possibleTypes.includes(obj.__typename) - } - - - - const FieldConnection_possibleTypes: string[] = ['FieldConnection'] - export const isFieldConnection = (obj?: { __typename?: any } | null): obj is FieldConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConnection"') - return FieldConnection_possibleTypes.includes(obj.__typename) - } - - - - const DeleteSso_possibleTypes: string[] = ['DeleteSso'] - export const isDeleteSso = (obj?: { __typename?: any } | null): obj is DeleteSso => { - if (!obj?.__typename) throw new Error('__typename is missing in "isDeleteSso"') - return DeleteSso_possibleTypes.includes(obj.__typename) - } - - - - const EditSso_possibleTypes: string[] = ['EditSso'] - export const isEditSso = (obj?: { __typename?: any } | null): obj is EditSso => { - if (!obj?.__typename) throw new Error('__typename is missing in "isEditSso"') - return EditSso_possibleTypes.includes(obj.__typename) - } - - - - const WorkspaceNameAndId_possibleTypes: string[] = ['WorkspaceNameAndId'] - export const isWorkspaceNameAndId = (obj?: { __typename?: any } | null): obj is WorkspaceNameAndId => { - if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceNameAndId"') - return WorkspaceNameAndId_possibleTypes.includes(obj.__typename) - } - - - - const FindAvailableSSOIDP_possibleTypes: string[] = ['FindAvailableSSOIDP'] - export const isFindAvailableSSOIDP = (obj?: { __typename?: any } | null): obj is FindAvailableSSOIDP => { - if (!obj?.__typename) throw new Error('__typename is missing in "isFindAvailableSSOIDP"') - return FindAvailableSSOIDP_possibleTypes.includes(obj.__typename) - } - - - - const SetupSso_possibleTypes: string[] = ['SetupSso'] - export const isSetupSso = (obj?: { __typename?: any } | null): obj is SetupSso => { - if (!obj?.__typename) throw new Error('__typename is missing in "isSetupSso"') - return SetupSso_possibleTypes.includes(obj.__typename) - } - - - - const DeleteTwoFactorAuthenticationMethod_possibleTypes: string[] = ['DeleteTwoFactorAuthenticationMethod'] - export const isDeleteTwoFactorAuthenticationMethod = (obj?: { __typename?: any } | null): obj is DeleteTwoFactorAuthenticationMethod => { - if (!obj?.__typename) throw new Error('__typename is missing in "isDeleteTwoFactorAuthenticationMethod"') - return DeleteTwoFactorAuthenticationMethod_possibleTypes.includes(obj.__typename) - } - - - - const InitiateTwoFactorAuthenticationProvisioning_possibleTypes: string[] = ['InitiateTwoFactorAuthenticationProvisioning'] - export const isInitiateTwoFactorAuthenticationProvisioning = (obj?: { __typename?: any } | null): obj is InitiateTwoFactorAuthenticationProvisioning => { - if (!obj?.__typename) throw new Error('__typename is missing in "isInitiateTwoFactorAuthenticationProvisioning"') - return InitiateTwoFactorAuthenticationProvisioning_possibleTypes.includes(obj.__typename) - } - - - - const VerifyTwoFactorAuthenticationMethod_possibleTypes: string[] = ['VerifyTwoFactorAuthenticationMethod'] - export const isVerifyTwoFactorAuthenticationMethod = (obj?: { __typename?: any } | null): obj is VerifyTwoFactorAuthenticationMethod => { - if (!obj?.__typename) throw new Error('__typename is missing in "isVerifyTwoFactorAuthenticationMethod"') - return VerifyTwoFactorAuthenticationMethod_possibleTypes.includes(obj.__typename) - } - - - - const AuthorizeApp_possibleTypes: string[] = ['AuthorizeApp'] - export const isAuthorizeApp = (obj?: { __typename?: any } | null): obj is AuthorizeApp => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthorizeApp"') - return AuthorizeApp_possibleTypes.includes(obj.__typename) - } - - - - const AuthToken_possibleTypes: string[] = ['AuthToken'] - export const isAuthToken = (obj?: { __typename?: any } | null): obj is AuthToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthToken"') - return AuthToken_possibleTypes.includes(obj.__typename) - } - - - - const AuthTokenPair_possibleTypes: string[] = ['AuthTokenPair'] - export const isAuthTokenPair = (obj?: { __typename?: any } | null): obj is AuthTokenPair => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthTokenPair"') - return AuthTokenPair_possibleTypes.includes(obj.__typename) - } - - - - const AvailableWorkspacesAndAccessTokens_possibleTypes: string[] = ['AvailableWorkspacesAndAccessTokens'] - export const isAvailableWorkspacesAndAccessTokens = (obj?: { __typename?: any } | null): obj is AvailableWorkspacesAndAccessTokens => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspacesAndAccessTokens"') - return AvailableWorkspacesAndAccessTokens_possibleTypes.includes(obj.__typename) - } - - - - const EmailPasswordResetLink_possibleTypes: string[] = ['EmailPasswordResetLink'] - export const isEmailPasswordResetLink = (obj?: { __typename?: any } | null): obj is EmailPasswordResetLink => { - if (!obj?.__typename) throw new Error('__typename is missing in "isEmailPasswordResetLink"') - return EmailPasswordResetLink_possibleTypes.includes(obj.__typename) - } - - - - const GetAuthorizationUrlForSSO_possibleTypes: string[] = ['GetAuthorizationUrlForSSO'] - export const isGetAuthorizationUrlForSSO = (obj?: { __typename?: any } | null): obj is GetAuthorizationUrlForSSO => { - if (!obj?.__typename) throw new Error('__typename is missing in "isGetAuthorizationUrlForSSO"') - return GetAuthorizationUrlForSSO_possibleTypes.includes(obj.__typename) - } - - - - const InvalidatePassword_possibleTypes: string[] = ['InvalidatePassword'] - export const isInvalidatePassword = (obj?: { __typename?: any } | null): obj is InvalidatePassword => { - if (!obj?.__typename) throw new Error('__typename is missing in "isInvalidatePassword"') - return InvalidatePassword_possibleTypes.includes(obj.__typename) - } - - - - const WorkspaceUrlsAndId_possibleTypes: string[] = ['WorkspaceUrlsAndId'] - export const isWorkspaceUrlsAndId = (obj?: { __typename?: any } | null): obj is WorkspaceUrlsAndId => { - if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceUrlsAndId"') - return WorkspaceUrlsAndId_possibleTypes.includes(obj.__typename) - } - - - - const SignUp_possibleTypes: string[] = ['SignUp'] - export const isSignUp = (obj?: { __typename?: any } | null): obj is SignUp => { - if (!obj?.__typename) throw new Error('__typename is missing in "isSignUp"') - return SignUp_possibleTypes.includes(obj.__typename) - } - - - - const TransientToken_possibleTypes: string[] = ['TransientToken'] - export const isTransientToken = (obj?: { __typename?: any } | null): obj is TransientToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isTransientToken"') - return TransientToken_possibleTypes.includes(obj.__typename) - } - - - - const ValidatePasswordResetToken_possibleTypes: string[] = ['ValidatePasswordResetToken'] - export const isValidatePasswordResetToken = (obj?: { __typename?: any } | null): obj is ValidatePasswordResetToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isValidatePasswordResetToken"') - return ValidatePasswordResetToken_possibleTypes.includes(obj.__typename) - } - - - - const VerifyEmailAndGetLoginToken_possibleTypes: string[] = ['VerifyEmailAndGetLoginToken'] - export const isVerifyEmailAndGetLoginToken = (obj?: { __typename?: any } | null): obj is VerifyEmailAndGetLoginToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isVerifyEmailAndGetLoginToken"') - return VerifyEmailAndGetLoginToken_possibleTypes.includes(obj.__typename) - } - - - - const ApiKeyToken_possibleTypes: string[] = ['ApiKeyToken'] - export const isApiKeyToken = (obj?: { __typename?: any } | null): obj is ApiKeyToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isApiKeyToken"') - return ApiKeyToken_possibleTypes.includes(obj.__typename) - } - - - - const AuthTokens_possibleTypes: string[] = ['AuthTokens'] - export const isAuthTokens = (obj?: { __typename?: any } | null): obj is AuthTokens => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAuthTokens"') - return AuthTokens_possibleTypes.includes(obj.__typename) - } - - - - const LoginToken_possibleTypes: string[] = ['LoginToken'] - export const isLoginToken = (obj?: { __typename?: any } | null): obj is LoginToken => { - if (!obj?.__typename) throw new Error('__typename is missing in "isLoginToken"') - return LoginToken_possibleTypes.includes(obj.__typename) - } - - - - const CheckUserExist_possibleTypes: string[] = ['CheckUserExist'] - export const isCheckUserExist = (obj?: { __typename?: any } | null): obj is CheckUserExist => { - if (!obj?.__typename) throw new Error('__typename is missing in "isCheckUserExist"') - return CheckUserExist_possibleTypes.includes(obj.__typename) - } - - - - const WorkspaceInviteHashValid_possibleTypes: string[] = ['WorkspaceInviteHashValid'] - export const isWorkspaceInviteHashValid = (obj?: { __typename?: any } | null): obj is WorkspaceInviteHashValid => { - if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceInviteHashValid"') - return WorkspaceInviteHashValid_possibleTypes.includes(obj.__typename) - } - - - const RecordIdentifier_possibleTypes: string[] = ['RecordIdentifier'] export const isRecordIdentifier = (obj?: { __typename?: any } | null): obj is RecordIdentifier => { if (!obj?.__typename) throw new Error('__typename is missing in "isRecordIdentifier"') @@ -7911,198 +7441,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null - const LogicFunctionLogs_possibleTypes: string[] = ['LogicFunctionLogs'] - export const isLogicFunctionLogs = (obj?: { __typename?: any } | null): obj is LogicFunctionLogs => { - if (!obj?.__typename) throw new Error('__typename is missing in "isLogicFunctionLogs"') - return LogicFunctionLogs_possibleTypes.includes(obj.__typename) - } - - - - const ToolIndexEntry_possibleTypes: string[] = ['ToolIndexEntry'] - export const isToolIndexEntry = (obj?: { __typename?: any } | null): obj is ToolIndexEntry => { - if (!obj?.__typename) throw new Error('__typename is missing in "isToolIndexEntry"') - return ToolIndexEntry_possibleTypes.includes(obj.__typename) - } - - - - const AgentMessagePart_possibleTypes: string[] = ['AgentMessagePart'] - export const isAgentMessagePart = (obj?: { __typename?: any } | null): obj is AgentMessagePart => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentMessagePart"') - return AgentMessagePart_possibleTypes.includes(obj.__typename) - } - - - - const Skill_possibleTypes: string[] = ['Skill'] - export const isSkill = (obj?: { __typename?: any } | null): obj is Skill => { - if (!obj?.__typename) throw new Error('__typename is missing in "isSkill"') - return Skill_possibleTypes.includes(obj.__typename) - } - - - - const ApplicationTokenPair_possibleTypes: string[] = ['ApplicationTokenPair'] - export const isApplicationTokenPair = (obj?: { __typename?: any } | null): obj is ApplicationTokenPair => { - if (!obj?.__typename) throw new Error('__typename is missing in "isApplicationTokenPair"') - return ApplicationTokenPair_possibleTypes.includes(obj.__typename) - } - - - - const FrontComponent_possibleTypes: string[] = ['FrontComponent'] - export const isFrontComponent = (obj?: { __typename?: any } | null): obj is FrontComponent => { - if (!obj?.__typename) throw new Error('__typename is missing in "isFrontComponent"') - return FrontComponent_possibleTypes.includes(obj.__typename) - } - - - - const CommandMenuItem_possibleTypes: string[] = ['CommandMenuItem'] - export const isCommandMenuItem = (obj?: { __typename?: any } | null): obj is CommandMenuItem => { - if (!obj?.__typename) throw new Error('__typename is missing in "isCommandMenuItem"') - return CommandMenuItem_possibleTypes.includes(obj.__typename) - } - - - - const AgentChatThread_possibleTypes: string[] = ['AgentChatThread'] - export const isAgentChatThread = (obj?: { __typename?: any } | null): obj is AgentChatThread => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThread"') - return AgentChatThread_possibleTypes.includes(obj.__typename) - } - - - - const AgentMessage_possibleTypes: string[] = ['AgentMessage'] - export const isAgentMessage = (obj?: { __typename?: any } | null): obj is AgentMessage => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentMessage"') - return AgentMessage_possibleTypes.includes(obj.__typename) - } - - - - const AISystemPromptSection_possibleTypes: string[] = ['AISystemPromptSection'] - export const isAISystemPromptSection = (obj?: { __typename?: any } | null): obj is AISystemPromptSection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptSection"') - return AISystemPromptSection_possibleTypes.includes(obj.__typename) - } - - - - const AISystemPromptPreview_possibleTypes: string[] = ['AISystemPromptPreview'] - export const isAISystemPromptPreview = (obj?: { __typename?: any } | null): obj is AISystemPromptPreview => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptPreview"') - return AISystemPromptPreview_possibleTypes.includes(obj.__typename) - } - - - - const AgentChatThreadEdge_possibleTypes: string[] = ['AgentChatThreadEdge'] - export const isAgentChatThreadEdge = (obj?: { __typename?: any } | null): obj is AgentChatThreadEdge => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThreadEdge"') - return AgentChatThreadEdge_possibleTypes.includes(obj.__typename) - } - - - - const AgentChatThreadConnection_possibleTypes: string[] = ['AgentChatThreadConnection'] - export const isAgentChatThreadConnection = (obj?: { __typename?: any } | null): obj is AgentChatThreadConnection => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThreadConnection"') - return AgentChatThreadConnection_possibleTypes.includes(obj.__typename) - } - - - - const AgentTurnEvaluation_possibleTypes: string[] = ['AgentTurnEvaluation'] - export const isAgentTurnEvaluation = (obj?: { __typename?: any } | null): obj is AgentTurnEvaluation => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentTurnEvaluation"') - return AgentTurnEvaluation_possibleTypes.includes(obj.__typename) - } - - - - const AgentTurn_possibleTypes: string[] = ['AgentTurn'] - export const isAgentTurn = (obj?: { __typename?: any } | null): obj is AgentTurn => { - if (!obj?.__typename) throw new Error('__typename is missing in "isAgentTurn"') - return AgentTurn_possibleTypes.includes(obj.__typename) - } - - - - const CalendarChannel_possibleTypes: string[] = ['CalendarChannel'] - export const isCalendarChannel = (obj?: { __typename?: any } | null): obj is CalendarChannel => { - if (!obj?.__typename) throw new Error('__typename is missing in "isCalendarChannel"') - return CalendarChannel_possibleTypes.includes(obj.__typename) - } - - - - const ConnectedAccountDTO_possibleTypes: string[] = ['ConnectedAccountDTO'] - export const isConnectedAccountDTO = (obj?: { __typename?: any } | null): obj is ConnectedAccountDTO => { - if (!obj?.__typename) throw new Error('__typename is missing in "isConnectedAccountDTO"') - return ConnectedAccountDTO_possibleTypes.includes(obj.__typename) - } - - - - const MessageChannel_possibleTypes: string[] = ['MessageChannel'] - export const isMessageChannel = (obj?: { __typename?: any } | null): obj is MessageChannel => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMessageChannel"') - return MessageChannel_possibleTypes.includes(obj.__typename) - } - - - - const MessageFolder_possibleTypes: string[] = ['MessageFolder'] - export const isMessageFolder = (obj?: { __typename?: any } | null): obj is MessageFolder => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMessageFolder"') - return MessageFolder_possibleTypes.includes(obj.__typename) - } - - - - const CollectionHash_possibleTypes: string[] = ['CollectionHash'] - export const isCollectionHash = (obj?: { __typename?: any } | null): obj is CollectionHash => { - if (!obj?.__typename) throw new Error('__typename is missing in "isCollectionHash"') - return CollectionHash_possibleTypes.includes(obj.__typename) - } - - - - const MinimalObjectMetadata_possibleTypes: string[] = ['MinimalObjectMetadata'] - export const isMinimalObjectMetadata = (obj?: { __typename?: any } | null): obj is MinimalObjectMetadata => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalObjectMetadata"') - return MinimalObjectMetadata_possibleTypes.includes(obj.__typename) - } - - - - const MinimalView_possibleTypes: string[] = ['MinimalView'] - export const isMinimalView = (obj?: { __typename?: any } | null): obj is MinimalView => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalView"') - return MinimalView_possibleTypes.includes(obj.__typename) - } - - - - const MinimalMetadata_possibleTypes: string[] = ['MinimalMetadata'] - export const isMinimalMetadata = (obj?: { __typename?: any } | null): obj is MinimalMetadata => { - if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalMetadata"') - return MinimalMetadata_possibleTypes.includes(obj.__typename) - } - - - - const Webhook_possibleTypes: string[] = ['Webhook'] - export const isWebhook = (obj?: { __typename?: any } | null): obj is Webhook => { - if (!obj?.__typename) throw new Error('__typename is missing in "isWebhook"') - return Webhook_possibleTypes.includes(obj.__typename) - } - - - const BillingTrialPeriod_possibleTypes: string[] = ['BillingTrialPeriod'] export const isBillingTrialPeriod = (obj?: { __typename?: any } | null): obj is BillingTrialPeriod => { if (!obj?.__typename) throw new Error('__typename is missing in "isBillingTrialPeriod"') @@ -8111,6 +7449,46 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const WorkspaceUrls_possibleTypes: string[] = ['WorkspaceUrls'] + export const isWorkspaceUrls = (obj?: { __typename?: any } | null): obj is WorkspaceUrls => { + if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceUrls"') + return WorkspaceUrls_possibleTypes.includes(obj.__typename) + } + + + + const SSOIdentityProvider_possibleTypes: string[] = ['SSOIdentityProvider'] + export const isSSOIdentityProvider = (obj?: { __typename?: any } | null): obj is SSOIdentityProvider => { + if (!obj?.__typename) throw new Error('__typename is missing in "isSSOIdentityProvider"') + return SSOIdentityProvider_possibleTypes.includes(obj.__typename) + } + + + + const AuthProviders_possibleTypes: string[] = ['AuthProviders'] + export const isAuthProviders = (obj?: { __typename?: any } | null): obj is AuthProviders => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthProviders"') + return AuthProviders_possibleTypes.includes(obj.__typename) + } + + + + const AuthBypassProviders_possibleTypes: string[] = ['AuthBypassProviders'] + export const isAuthBypassProviders = (obj?: { __typename?: any } | null): obj is AuthBypassProviders => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthBypassProviders"') + return AuthBypassProviders_possibleTypes.includes(obj.__typename) + } + + + + const PublicWorkspaceData_possibleTypes: string[] = ['PublicWorkspaceData'] + export const isPublicWorkspaceData = (obj?: { __typename?: any } | null): obj is PublicWorkspaceData => { + if (!obj?.__typename) throw new Error('__typename is missing in "isPublicWorkspaceData"') + return PublicWorkspaceData_possibleTypes.includes(obj.__typename) + } + + + const NativeModelCapabilities_possibleTypes: string[] = ['NativeModelCapabilities'] export const isNativeModelCapabilities = (obj?: { __typename?: any } | null): obj is NativeModelCapabilities => { if (!obj?.__typename) throw new Error('__typename is missing in "isNativeModelCapabilities"') @@ -8295,6 +7673,14 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const FeatureFlag_possibleTypes: string[] = ['FeatureFlag'] + export const isFeatureFlag = (obj?: { __typename?: any } | null): obj is FeatureFlag => { + if (!obj?.__typename) throw new Error('__typename is missing in "isFeatureFlag"') + return FeatureFlag_possibleTypes.includes(obj.__typename) + } + + + const UserInfo_possibleTypes: string[] = ['UserInfo'] export const isUserInfo = (obj?: { __typename?: any } | null): obj is UserInfo => { if (!obj?.__typename) throw new Error('__typename is missing in "isUserInfo"') @@ -8391,6 +7777,430 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const VersionDistributionEntry_possibleTypes: string[] = ['VersionDistributionEntry'] + export const isVersionDistributionEntry = (obj?: { __typename?: any } | null): obj is VersionDistributionEntry => { + if (!obj?.__typename) throw new Error('__typename is missing in "isVersionDistributionEntry"') + return VersionDistributionEntry_possibleTypes.includes(obj.__typename) + } + + + + const ApplicationRegistrationStats_possibleTypes: string[] = ['ApplicationRegistrationStats'] + export const isApplicationRegistrationStats = (obj?: { __typename?: any } | null): obj is ApplicationRegistrationStats => { + if (!obj?.__typename) throw new Error('__typename is missing in "isApplicationRegistrationStats"') + return ApplicationRegistrationStats_possibleTypes.includes(obj.__typename) + } + + + + const CreateApplicationRegistration_possibleTypes: string[] = ['CreateApplicationRegistration'] + export const isCreateApplicationRegistration = (obj?: { __typename?: any } | null): obj is CreateApplicationRegistration => { + if (!obj?.__typename) throw new Error('__typename is missing in "isCreateApplicationRegistration"') + return CreateApplicationRegistration_possibleTypes.includes(obj.__typename) + } + + + + const PublicApplicationRegistration_possibleTypes: string[] = ['PublicApplicationRegistration'] + export const isPublicApplicationRegistration = (obj?: { __typename?: any } | null): obj is PublicApplicationRegistration => { + if (!obj?.__typename) throw new Error('__typename is missing in "isPublicApplicationRegistration"') + return PublicApplicationRegistration_possibleTypes.includes(obj.__typename) + } + + + + const RotateClientSecret_possibleTypes: string[] = ['RotateClientSecret'] + export const isRotateClientSecret = (obj?: { __typename?: any } | null): obj is RotateClientSecret => { + if (!obj?.__typename) throw new Error('__typename is missing in "isRotateClientSecret"') + return RotateClientSecret_possibleTypes.includes(obj.__typename) + } + + + + const ResendEmailVerificationToken_possibleTypes: string[] = ['ResendEmailVerificationToken'] + export const isResendEmailVerificationToken = (obj?: { __typename?: any } | null): obj is ResendEmailVerificationToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isResendEmailVerificationToken"') + return ResendEmailVerificationToken_possibleTypes.includes(obj.__typename) + } + + + + const DeleteSso_possibleTypes: string[] = ['DeleteSso'] + export const isDeleteSso = (obj?: { __typename?: any } | null): obj is DeleteSso => { + if (!obj?.__typename) throw new Error('__typename is missing in "isDeleteSso"') + return DeleteSso_possibleTypes.includes(obj.__typename) + } + + + + const EditSso_possibleTypes: string[] = ['EditSso'] + export const isEditSso = (obj?: { __typename?: any } | null): obj is EditSso => { + if (!obj?.__typename) throw new Error('__typename is missing in "isEditSso"') + return EditSso_possibleTypes.includes(obj.__typename) + } + + + + const WorkspaceNameAndId_possibleTypes: string[] = ['WorkspaceNameAndId'] + export const isWorkspaceNameAndId = (obj?: { __typename?: any } | null): obj is WorkspaceNameAndId => { + if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceNameAndId"') + return WorkspaceNameAndId_possibleTypes.includes(obj.__typename) + } + + + + const FindAvailableSSOIDP_possibleTypes: string[] = ['FindAvailableSSOIDP'] + export const isFindAvailableSSOIDP = (obj?: { __typename?: any } | null): obj is FindAvailableSSOIDP => { + if (!obj?.__typename) throw new Error('__typename is missing in "isFindAvailableSSOIDP"') + return FindAvailableSSOIDP_possibleTypes.includes(obj.__typename) + } + + + + const SetupSso_possibleTypes: string[] = ['SetupSso'] + export const isSetupSso = (obj?: { __typename?: any } | null): obj is SetupSso => { + if (!obj?.__typename) throw new Error('__typename is missing in "isSetupSso"') + return SetupSso_possibleTypes.includes(obj.__typename) + } + + + + const SSOConnection_possibleTypes: string[] = ['SSOConnection'] + export const isSSOConnection = (obj?: { __typename?: any } | null): obj is SSOConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isSSOConnection"') + return SSOConnection_possibleTypes.includes(obj.__typename) + } + + + + const AvailableWorkspace_possibleTypes: string[] = ['AvailableWorkspace'] + export const isAvailableWorkspace = (obj?: { __typename?: any } | null): obj is AvailableWorkspace => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspace"') + return AvailableWorkspace_possibleTypes.includes(obj.__typename) + } + + + + const AvailableWorkspaces_possibleTypes: string[] = ['AvailableWorkspaces'] + export const isAvailableWorkspaces = (obj?: { __typename?: any } | null): obj is AvailableWorkspaces => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspaces"') + return AvailableWorkspaces_possibleTypes.includes(obj.__typename) + } + + + + const DeletedWorkspaceMember_possibleTypes: string[] = ['DeletedWorkspaceMember'] + export const isDeletedWorkspaceMember = (obj?: { __typename?: any } | null): obj is DeletedWorkspaceMember => { + if (!obj?.__typename) throw new Error('__typename is missing in "isDeletedWorkspaceMember"') + return DeletedWorkspaceMember_possibleTypes.includes(obj.__typename) + } + + + + const BillingEntitlement_possibleTypes: string[] = ['BillingEntitlement'] + export const isBillingEntitlement = (obj?: { __typename?: any } | null): obj is BillingEntitlement => { + if (!obj?.__typename) throw new Error('__typename is missing in "isBillingEntitlement"') + return BillingEntitlement_possibleTypes.includes(obj.__typename) + } + + + + const DomainRecord_possibleTypes: string[] = ['DomainRecord'] + export const isDomainRecord = (obj?: { __typename?: any } | null): obj is DomainRecord => { + if (!obj?.__typename) throw new Error('__typename is missing in "isDomainRecord"') + return DomainRecord_possibleTypes.includes(obj.__typename) + } + + + + const DomainValidRecords_possibleTypes: string[] = ['DomainValidRecords'] + export const isDomainValidRecords = (obj?: { __typename?: any } | null): obj is DomainValidRecords => { + if (!obj?.__typename) throw new Error('__typename is missing in "isDomainValidRecords"') + return DomainValidRecords_possibleTypes.includes(obj.__typename) + } + + + + const IndexEdge_possibleTypes: string[] = ['IndexEdge'] + export const isIndexEdge = (obj?: { __typename?: any } | null): obj is IndexEdge => { + if (!obj?.__typename) throw new Error('__typename is missing in "isIndexEdge"') + return IndexEdge_possibleTypes.includes(obj.__typename) + } + + + + const PageInfo_possibleTypes: string[] = ['PageInfo'] + export const isPageInfo = (obj?: { __typename?: any } | null): obj is PageInfo => { + if (!obj?.__typename) throw new Error('__typename is missing in "isPageInfo"') + return PageInfo_possibleTypes.includes(obj.__typename) + } + + + + const IndexConnection_possibleTypes: string[] = ['IndexConnection'] + export const isIndexConnection = (obj?: { __typename?: any } | null): obj is IndexConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isIndexConnection"') + return IndexConnection_possibleTypes.includes(obj.__typename) + } + + + + const IndexFieldEdge_possibleTypes: string[] = ['IndexFieldEdge'] + export const isIndexFieldEdge = (obj?: { __typename?: any } | null): obj is IndexFieldEdge => { + if (!obj?.__typename) throw new Error('__typename is missing in "isIndexFieldEdge"') + return IndexFieldEdge_possibleTypes.includes(obj.__typename) + } + + + + const IndexIndexFieldMetadatasConnection_possibleTypes: string[] = ['IndexIndexFieldMetadatasConnection'] + export const isIndexIndexFieldMetadatasConnection = (obj?: { __typename?: any } | null): obj is IndexIndexFieldMetadatasConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isIndexIndexFieldMetadatasConnection"') + return IndexIndexFieldMetadatasConnection_possibleTypes.includes(obj.__typename) + } + + + + const ObjectEdge_possibleTypes: string[] = ['ObjectEdge'] + export const isObjectEdge = (obj?: { __typename?: any } | null): obj is ObjectEdge => { + if (!obj?.__typename) throw new Error('__typename is missing in "isObjectEdge"') + return ObjectEdge_possibleTypes.includes(obj.__typename) + } + + + + const IndexObjectMetadataConnection_possibleTypes: string[] = ['IndexObjectMetadataConnection'] + export const isIndexObjectMetadataConnection = (obj?: { __typename?: any } | null): obj is IndexObjectMetadataConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isIndexObjectMetadataConnection"') + return IndexObjectMetadataConnection_possibleTypes.includes(obj.__typename) + } + + + + const ObjectRecordCount_possibleTypes: string[] = ['ObjectRecordCount'] + export const isObjectRecordCount = (obj?: { __typename?: any } | null): obj is ObjectRecordCount => { + if (!obj?.__typename) throw new Error('__typename is missing in "isObjectRecordCount"') + return ObjectRecordCount_possibleTypes.includes(obj.__typename) + } + + + + const ObjectConnection_possibleTypes: string[] = ['ObjectConnection'] + export const isObjectConnection = (obj?: { __typename?: any } | null): obj is ObjectConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isObjectConnection"') + return ObjectConnection_possibleTypes.includes(obj.__typename) + } + + + + const ObjectIndexMetadatasConnection_possibleTypes: string[] = ['ObjectIndexMetadatasConnection'] + export const isObjectIndexMetadatasConnection = (obj?: { __typename?: any } | null): obj is ObjectIndexMetadatasConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isObjectIndexMetadatasConnection"') + return ObjectIndexMetadatasConnection_possibleTypes.includes(obj.__typename) + } + + + + const FieldEdge_possibleTypes: string[] = ['FieldEdge'] + export const isFieldEdge = (obj?: { __typename?: any } | null): obj is FieldEdge => { + if (!obj?.__typename) throw new Error('__typename is missing in "isFieldEdge"') + return FieldEdge_possibleTypes.includes(obj.__typename) + } + + + + const ObjectFieldsConnection_possibleTypes: string[] = ['ObjectFieldsConnection'] + export const isObjectFieldsConnection = (obj?: { __typename?: any } | null): obj is ObjectFieldsConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isObjectFieldsConnection"') + return ObjectFieldsConnection_possibleTypes.includes(obj.__typename) + } + + + + const UpsertRowLevelPermissionPredicatesResult_possibleTypes: string[] = ['UpsertRowLevelPermissionPredicatesResult'] + export const isUpsertRowLevelPermissionPredicatesResult = (obj?: { __typename?: any } | null): obj is UpsertRowLevelPermissionPredicatesResult => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUpsertRowLevelPermissionPredicatesResult"') + return UpsertRowLevelPermissionPredicatesResult_possibleTypes.includes(obj.__typename) + } + + + + const Relation_possibleTypes: string[] = ['Relation'] + export const isRelation = (obj?: { __typename?: any } | null): obj is Relation => { + if (!obj?.__typename) throw new Error('__typename is missing in "isRelation"') + return Relation_possibleTypes.includes(obj.__typename) + } + + + + const FieldConnection_possibleTypes: string[] = ['FieldConnection'] + export const isFieldConnection = (obj?: { __typename?: any } | null): obj is FieldConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isFieldConnection"') + return FieldConnection_possibleTypes.includes(obj.__typename) + } + + + + const DeleteTwoFactorAuthenticationMethod_possibleTypes: string[] = ['DeleteTwoFactorAuthenticationMethod'] + export const isDeleteTwoFactorAuthenticationMethod = (obj?: { __typename?: any } | null): obj is DeleteTwoFactorAuthenticationMethod => { + if (!obj?.__typename) throw new Error('__typename is missing in "isDeleteTwoFactorAuthenticationMethod"') + return DeleteTwoFactorAuthenticationMethod_possibleTypes.includes(obj.__typename) + } + + + + const InitiateTwoFactorAuthenticationProvisioning_possibleTypes: string[] = ['InitiateTwoFactorAuthenticationProvisioning'] + export const isInitiateTwoFactorAuthenticationProvisioning = (obj?: { __typename?: any } | null): obj is InitiateTwoFactorAuthenticationProvisioning => { + if (!obj?.__typename) throw new Error('__typename is missing in "isInitiateTwoFactorAuthenticationProvisioning"') + return InitiateTwoFactorAuthenticationProvisioning_possibleTypes.includes(obj.__typename) + } + + + + const VerifyTwoFactorAuthenticationMethod_possibleTypes: string[] = ['VerifyTwoFactorAuthenticationMethod'] + export const isVerifyTwoFactorAuthenticationMethod = (obj?: { __typename?: any } | null): obj is VerifyTwoFactorAuthenticationMethod => { + if (!obj?.__typename) throw new Error('__typename is missing in "isVerifyTwoFactorAuthenticationMethod"') + return VerifyTwoFactorAuthenticationMethod_possibleTypes.includes(obj.__typename) + } + + + + const AuthorizeApp_possibleTypes: string[] = ['AuthorizeApp'] + export const isAuthorizeApp = (obj?: { __typename?: any } | null): obj is AuthorizeApp => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthorizeApp"') + return AuthorizeApp_possibleTypes.includes(obj.__typename) + } + + + + const AuthToken_possibleTypes: string[] = ['AuthToken'] + export const isAuthToken = (obj?: { __typename?: any } | null): obj is AuthToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthToken"') + return AuthToken_possibleTypes.includes(obj.__typename) + } + + + + const AuthTokenPair_possibleTypes: string[] = ['AuthTokenPair'] + export const isAuthTokenPair = (obj?: { __typename?: any } | null): obj is AuthTokenPair => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthTokenPair"') + return AuthTokenPair_possibleTypes.includes(obj.__typename) + } + + + + const AvailableWorkspacesAndAccessTokens_possibleTypes: string[] = ['AvailableWorkspacesAndAccessTokens'] + export const isAvailableWorkspacesAndAccessTokens = (obj?: { __typename?: any } | null): obj is AvailableWorkspacesAndAccessTokens => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAvailableWorkspacesAndAccessTokens"') + return AvailableWorkspacesAndAccessTokens_possibleTypes.includes(obj.__typename) + } + + + + const EmailPasswordResetLink_possibleTypes: string[] = ['EmailPasswordResetLink'] + export const isEmailPasswordResetLink = (obj?: { __typename?: any } | null): obj is EmailPasswordResetLink => { + if (!obj?.__typename) throw new Error('__typename is missing in "isEmailPasswordResetLink"') + return EmailPasswordResetLink_possibleTypes.includes(obj.__typename) + } + + + + const GetAuthorizationUrlForSSO_possibleTypes: string[] = ['GetAuthorizationUrlForSSO'] + export const isGetAuthorizationUrlForSSO = (obj?: { __typename?: any } | null): obj is GetAuthorizationUrlForSSO => { + if (!obj?.__typename) throw new Error('__typename is missing in "isGetAuthorizationUrlForSSO"') + return GetAuthorizationUrlForSSO_possibleTypes.includes(obj.__typename) + } + + + + const InvalidatePassword_possibleTypes: string[] = ['InvalidatePassword'] + export const isInvalidatePassword = (obj?: { __typename?: any } | null): obj is InvalidatePassword => { + if (!obj?.__typename) throw new Error('__typename is missing in "isInvalidatePassword"') + return InvalidatePassword_possibleTypes.includes(obj.__typename) + } + + + + const WorkspaceUrlsAndId_possibleTypes: string[] = ['WorkspaceUrlsAndId'] + export const isWorkspaceUrlsAndId = (obj?: { __typename?: any } | null): obj is WorkspaceUrlsAndId => { + if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceUrlsAndId"') + return WorkspaceUrlsAndId_possibleTypes.includes(obj.__typename) + } + + + + const SignUp_possibleTypes: string[] = ['SignUp'] + export const isSignUp = (obj?: { __typename?: any } | null): obj is SignUp => { + if (!obj?.__typename) throw new Error('__typename is missing in "isSignUp"') + return SignUp_possibleTypes.includes(obj.__typename) + } + + + + const TransientToken_possibleTypes: string[] = ['TransientToken'] + export const isTransientToken = (obj?: { __typename?: any } | null): obj is TransientToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isTransientToken"') + return TransientToken_possibleTypes.includes(obj.__typename) + } + + + + const ValidatePasswordResetToken_possibleTypes: string[] = ['ValidatePasswordResetToken'] + export const isValidatePasswordResetToken = (obj?: { __typename?: any } | null): obj is ValidatePasswordResetToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isValidatePasswordResetToken"') + return ValidatePasswordResetToken_possibleTypes.includes(obj.__typename) + } + + + + const VerifyEmailAndGetLoginToken_possibleTypes: string[] = ['VerifyEmailAndGetLoginToken'] + export const isVerifyEmailAndGetLoginToken = (obj?: { __typename?: any } | null): obj is VerifyEmailAndGetLoginToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isVerifyEmailAndGetLoginToken"') + return VerifyEmailAndGetLoginToken_possibleTypes.includes(obj.__typename) + } + + + + const ApiKeyToken_possibleTypes: string[] = ['ApiKeyToken'] + export const isApiKeyToken = (obj?: { __typename?: any } | null): obj is ApiKeyToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isApiKeyToken"') + return ApiKeyToken_possibleTypes.includes(obj.__typename) + } + + + + const AuthTokens_possibleTypes: string[] = ['AuthTokens'] + export const isAuthTokens = (obj?: { __typename?: any } | null): obj is AuthTokens => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAuthTokens"') + return AuthTokens_possibleTypes.includes(obj.__typename) + } + + + + const LoginToken_possibleTypes: string[] = ['LoginToken'] + export const isLoginToken = (obj?: { __typename?: any } | null): obj is LoginToken => { + if (!obj?.__typename) throw new Error('__typename is missing in "isLoginToken"') + return LoginToken_possibleTypes.includes(obj.__typename) + } + + + + const CheckUserExist_possibleTypes: string[] = ['CheckUserExist'] + export const isCheckUserExist = (obj?: { __typename?: any } | null): obj is CheckUserExist => { + if (!obj?.__typename) throw new Error('__typename is missing in "isCheckUserExist"') + return CheckUserExist_possibleTypes.includes(obj.__typename) + } + + + + const WorkspaceInviteHashValid_possibleTypes: string[] = ['WorkspaceInviteHashValid'] + export const isWorkspaceInviteHashValid = (obj?: { __typename?: any } | null): obj is WorkspaceInviteHashValid => { + if (!obj?.__typename) throw new Error('__typename is missing in "isWorkspaceInviteHashValid"') + return WorkspaceInviteHashValid_possibleTypes.includes(obj.__typename) + } + + + const Impersonate_possibleTypes: string[] = ['Impersonate'] export const isImpersonate = (obj?: { __typename?: any } | null): obj is Impersonate => { if (!obj?.__typename) throw new Error('__typename is missing in "isImpersonate"') @@ -8415,6 +8225,14 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const ApplicationTokenPair_possibleTypes: string[] = ['ApplicationTokenPair'] + export const isApplicationTokenPair = (obj?: { __typename?: any } | null): obj is ApplicationTokenPair => { + if (!obj?.__typename) throw new Error('__typename is missing in "isApplicationTokenPair"') + return ApplicationTokenPair_possibleTypes.includes(obj.__typename) + } + + + const File_possibleTypes: string[] = ['File'] export const isFile = (obj?: { __typename?: any } | null): obj is File => { if (!obj?.__typename) throw new Error('__typename is missing in "isFile"') @@ -8487,38 +8305,6 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null - const UsageBreakdownItem_possibleTypes: string[] = ['UsageBreakdownItem'] - export const isUsageBreakdownItem = (obj?: { __typename?: any } | null): obj is UsageBreakdownItem => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageBreakdownItem"') - return UsageBreakdownItem_possibleTypes.includes(obj.__typename) - } - - - - const UsageTimeSeries_possibleTypes: string[] = ['UsageTimeSeries'] - export const isUsageTimeSeries = (obj?: { __typename?: any } | null): obj is UsageTimeSeries => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageTimeSeries"') - return UsageTimeSeries_possibleTypes.includes(obj.__typename) - } - - - - const UsageUserDaily_possibleTypes: string[] = ['UsageUserDaily'] - export const isUsageUserDaily = (obj?: { __typename?: any } | null): obj is UsageUserDaily => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageUserDaily"') - return UsageUserDaily_possibleTypes.includes(obj.__typename) - } - - - - const UsageAnalytics_possibleTypes: string[] = ['UsageAnalytics'] - export const isUsageAnalytics = (obj?: { __typename?: any } | null): obj is UsageAnalytics => { - if (!obj?.__typename) throw new Error('__typename is missing in "isUsageAnalytics"') - return UsageAnalytics_possibleTypes.includes(obj.__typename) - } - - - const PublicDomain_possibleTypes: string[] = ['PublicDomain'] export const isPublicDomain = (obj?: { __typename?: any } | null): obj is PublicDomain => { if (!obj?.__typename) throw new Error('__typename is missing in "isPublicDomain"') @@ -8607,6 +8393,78 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const UsageBreakdownItem_possibleTypes: string[] = ['UsageBreakdownItem'] + export const isUsageBreakdownItem = (obj?: { __typename?: any } | null): obj is UsageBreakdownItem => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageBreakdownItem"') + return UsageBreakdownItem_possibleTypes.includes(obj.__typename) + } + + + + const UsageTimeSeries_possibleTypes: string[] = ['UsageTimeSeries'] + export const isUsageTimeSeries = (obj?: { __typename?: any } | null): obj is UsageTimeSeries => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageTimeSeries"') + return UsageTimeSeries_possibleTypes.includes(obj.__typename) + } + + + + const UsageUserDaily_possibleTypes: string[] = ['UsageUserDaily'] + export const isUsageUserDaily = (obj?: { __typename?: any } | null): obj is UsageUserDaily => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageUserDaily"') + return UsageUserDaily_possibleTypes.includes(obj.__typename) + } + + + + const UsageAnalytics_possibleTypes: string[] = ['UsageAnalytics'] + export const isUsageAnalytics = (obj?: { __typename?: any } | null): obj is UsageAnalytics => { + if (!obj?.__typename) throw new Error('__typename is missing in "isUsageAnalytics"') + return UsageAnalytics_possibleTypes.includes(obj.__typename) + } + + + + const LogicFunctionLogs_possibleTypes: string[] = ['LogicFunctionLogs'] + export const isLogicFunctionLogs = (obj?: { __typename?: any } | null): obj is LogicFunctionLogs => { + if (!obj?.__typename) throw new Error('__typename is missing in "isLogicFunctionLogs"') + return LogicFunctionLogs_possibleTypes.includes(obj.__typename) + } + + + + const FrontComponent_possibleTypes: string[] = ['FrontComponent'] + export const isFrontComponent = (obj?: { __typename?: any } | null): obj is FrontComponent => { + if (!obj?.__typename) throw new Error('__typename is missing in "isFrontComponent"') + return FrontComponent_possibleTypes.includes(obj.__typename) + } + + + + const CommandMenuItem_possibleTypes: string[] = ['CommandMenuItem'] + export const isCommandMenuItem = (obj?: { __typename?: any } | null): obj is CommandMenuItem => { + if (!obj?.__typename) throw new Error('__typename is missing in "isCommandMenuItem"') + return CommandMenuItem_possibleTypes.includes(obj.__typename) + } + + + + const ToolIndexEntry_possibleTypes: string[] = ['ToolIndexEntry'] + export const isToolIndexEntry = (obj?: { __typename?: any } | null): obj is ToolIndexEntry => { + if (!obj?.__typename) throw new Error('__typename is missing in "isToolIndexEntry"') + return ToolIndexEntry_possibleTypes.includes(obj.__typename) + } + + + + const AgentMessagePart_possibleTypes: string[] = ['AgentMessagePart'] + export const isAgentMessagePart = (obj?: { __typename?: any } | null): obj is AgentMessagePart => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentMessagePart"') + return AgentMessagePart_possibleTypes.includes(obj.__typename) + } + + + const ChannelSyncSuccess_possibleTypes: string[] = ['ChannelSyncSuccess'] export const isChannelSyncSuccess = (obj?: { __typename?: any } | null): obj is ChannelSyncSuccess => { if (!obj?.__typename) throw new Error('__typename is missing in "isChannelSyncSuccess"') @@ -8703,6 +8561,150 @@ export interface LogicFunctionLogsInput {applicationId?: (Scalars['UUID'] | null + const Skill_possibleTypes: string[] = ['Skill'] + export const isSkill = (obj?: { __typename?: any } | null): obj is Skill => { + if (!obj?.__typename) throw new Error('__typename is missing in "isSkill"') + return Skill_possibleTypes.includes(obj.__typename) + } + + + + const AgentChatThread_possibleTypes: string[] = ['AgentChatThread'] + export const isAgentChatThread = (obj?: { __typename?: any } | null): obj is AgentChatThread => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThread"') + return AgentChatThread_possibleTypes.includes(obj.__typename) + } + + + + const AgentMessage_possibleTypes: string[] = ['AgentMessage'] + export const isAgentMessage = (obj?: { __typename?: any } | null): obj is AgentMessage => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentMessage"') + return AgentMessage_possibleTypes.includes(obj.__typename) + } + + + + const AISystemPromptSection_possibleTypes: string[] = ['AISystemPromptSection'] + export const isAISystemPromptSection = (obj?: { __typename?: any } | null): obj is AISystemPromptSection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptSection"') + return AISystemPromptSection_possibleTypes.includes(obj.__typename) + } + + + + const AISystemPromptPreview_possibleTypes: string[] = ['AISystemPromptPreview'] + export const isAISystemPromptPreview = (obj?: { __typename?: any } | null): obj is AISystemPromptPreview => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAISystemPromptPreview"') + return AISystemPromptPreview_possibleTypes.includes(obj.__typename) + } + + + + const AgentChatThreadEdge_possibleTypes: string[] = ['AgentChatThreadEdge'] + export const isAgentChatThreadEdge = (obj?: { __typename?: any } | null): obj is AgentChatThreadEdge => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThreadEdge"') + return AgentChatThreadEdge_possibleTypes.includes(obj.__typename) + } + + + + const AgentChatThreadConnection_possibleTypes: string[] = ['AgentChatThreadConnection'] + export const isAgentChatThreadConnection = (obj?: { __typename?: any } | null): obj is AgentChatThreadConnection => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentChatThreadConnection"') + return AgentChatThreadConnection_possibleTypes.includes(obj.__typename) + } + + + + const AgentTurnEvaluation_possibleTypes: string[] = ['AgentTurnEvaluation'] + export const isAgentTurnEvaluation = (obj?: { __typename?: any } | null): obj is AgentTurnEvaluation => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentTurnEvaluation"') + return AgentTurnEvaluation_possibleTypes.includes(obj.__typename) + } + + + + const AgentTurn_possibleTypes: string[] = ['AgentTurn'] + export const isAgentTurn = (obj?: { __typename?: any } | null): obj is AgentTurn => { + if (!obj?.__typename) throw new Error('__typename is missing in "isAgentTurn"') + return AgentTurn_possibleTypes.includes(obj.__typename) + } + + + + const CalendarChannel_possibleTypes: string[] = ['CalendarChannel'] + export const isCalendarChannel = (obj?: { __typename?: any } | null): obj is CalendarChannel => { + if (!obj?.__typename) throw new Error('__typename is missing in "isCalendarChannel"') + return CalendarChannel_possibleTypes.includes(obj.__typename) + } + + + + const ConnectedAccountDTO_possibleTypes: string[] = ['ConnectedAccountDTO'] + export const isConnectedAccountDTO = (obj?: { __typename?: any } | null): obj is ConnectedAccountDTO => { + if (!obj?.__typename) throw new Error('__typename is missing in "isConnectedAccountDTO"') + return ConnectedAccountDTO_possibleTypes.includes(obj.__typename) + } + + + + const MessageChannel_possibleTypes: string[] = ['MessageChannel'] + export const isMessageChannel = (obj?: { __typename?: any } | null): obj is MessageChannel => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMessageChannel"') + return MessageChannel_possibleTypes.includes(obj.__typename) + } + + + + const MessageFolder_possibleTypes: string[] = ['MessageFolder'] + export const isMessageFolder = (obj?: { __typename?: any } | null): obj is MessageFolder => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMessageFolder"') + return MessageFolder_possibleTypes.includes(obj.__typename) + } + + + + const CollectionHash_possibleTypes: string[] = ['CollectionHash'] + export const isCollectionHash = (obj?: { __typename?: any } | null): obj is CollectionHash => { + if (!obj?.__typename) throw new Error('__typename is missing in "isCollectionHash"') + return CollectionHash_possibleTypes.includes(obj.__typename) + } + + + + const MinimalObjectMetadata_possibleTypes: string[] = ['MinimalObjectMetadata'] + export const isMinimalObjectMetadata = (obj?: { __typename?: any } | null): obj is MinimalObjectMetadata => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalObjectMetadata"') + return MinimalObjectMetadata_possibleTypes.includes(obj.__typename) + } + + + + const MinimalView_possibleTypes: string[] = ['MinimalView'] + export const isMinimalView = (obj?: { __typename?: any } | null): obj is MinimalView => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalView"') + return MinimalView_possibleTypes.includes(obj.__typename) + } + + + + const MinimalMetadata_possibleTypes: string[] = ['MinimalMetadata'] + export const isMinimalMetadata = (obj?: { __typename?: any } | null): obj is MinimalMetadata => { + if (!obj?.__typename) throw new Error('__typename is missing in "isMinimalMetadata"') + return MinimalMetadata_possibleTypes.includes(obj.__typename) + } + + + + const Webhook_possibleTypes: string[] = ['Webhook'] + export const isWebhook = (obj?: { __typename?: any } | null): obj is Webhook => { + if (!obj?.__typename) throw new Error('__typename is missing in "isWebhook"') + return Webhook_possibleTypes.includes(obj.__typename) + } + + + const Query_possibleTypes: string[] = ['Query'] export const isQuery = (obj?: { __typename?: any } | null): obj is Query => { if (!obj?.__typename) throw new Error('__typename is missing in "isQuery"') @@ -9063,6 +9065,35 @@ export const enumSubscriptionStatus = { Unpaid: 'Unpaid' as const } +export const enumNavigationMenuItemType = { + VIEW: 'VIEW' as const, + FOLDER: 'FOLDER' as const, + LINK: 'LINK' as const, + OBJECT: 'OBJECT' as const, + RECORD: 'RECORD' as const +} + +export const enumMetadataEventAction = { + CREATED: 'CREATED' as const, + UPDATED: 'UPDATED' as const, + DELETED: 'DELETED' as const +} + +export const enumDatabaseEventAction = { + CREATED: 'CREATED' as const, + UPDATED: 'UPDATED' as const, + DELETED: 'DELETED' as const, + DESTROYED: 'DESTROYED' as const, + RESTORED: 'RESTORED' as const, + UPSERTED: 'UPSERTED' as const +} + +export const enumLogicFunctionExecutionStatus = { + IDLE: 'IDLE' as const, + SUCCESS: 'SUCCESS' as const, + ERROR: 'ERROR' as const +} + export const enumIdentityProviderType = { OIDC: 'OIDC' as const, SAML: 'SAML' as const @@ -9074,11 +9105,22 @@ export const enumSsoIdentityProviderStatus = { Error: 'Error' as const } -export const enumBillingEntitlementKey = { - SSO: 'SSO' as const, - CUSTOM_DOMAIN: 'CUSTOM_DOMAIN' as const, - RLS: 'RLS' as const, - AUDIT_LOGS: 'AUDIT_LOGS' as const +export const enumModelFamily = { + GPT: 'GPT' as const, + CLAUDE: 'CLAUDE' as const, + GEMINI: 'GEMINI' as const, + MISTRAL: 'MISTRAL' as const, + GROK: 'GROK' as const +} + +export const enumSupportDriver = { + NONE: 'NONE' as const, + FRONT: 'FRONT' as const +} + +export const enumCaptchaDriverType = { + GOOGLE_RECAPTCHA: 'GOOGLE_RECAPTCHA' as const, + TURNSTILE: 'TURNSTILE' as const } export const enumFeatureFlagKey = { @@ -9109,38 +9151,95 @@ export const enumFeatureFlagKey = { IS_GRAPHQL_QUERY_TIMING_ENABLED: 'IS_GRAPHQL_QUERY_TIMING_ENABLED' as const } +export const enumConfigSource = { + ENVIRONMENT: 'ENVIRONMENT' as const, + DATABASE: 'DATABASE' as const, + DEFAULT: 'DEFAULT' as const +} + +export const enumConfigVariableType = { + BOOLEAN: 'BOOLEAN' as const, + NUMBER: 'NUMBER' as const, + ARRAY: 'ARRAY' as const, + STRING: 'STRING' as const, + ENUM: 'ENUM' as const, + JSON: 'JSON' as const +} + +export const enumConfigVariablesGroup = { + SERVER_CONFIG: 'SERVER_CONFIG' as const, + RATE_LIMITING: 'RATE_LIMITING' as const, + STORAGE_CONFIG: 'STORAGE_CONFIG' as const, + GOOGLE_AUTH: 'GOOGLE_AUTH' as const, + MICROSOFT_AUTH: 'MICROSOFT_AUTH' as const, + EMAIL_SETTINGS: 'EMAIL_SETTINGS' as const, + LOGGING: 'LOGGING' as const, + ADVANCED_SETTINGS: 'ADVANCED_SETTINGS' as const, + BILLING_CONFIG: 'BILLING_CONFIG' as const, + CAPTCHA_CONFIG: 'CAPTCHA_CONFIG' as const, + CLOUDFLARE_CONFIG: 'CLOUDFLARE_CONFIG' as const, + LLM: 'LLM' as const, + LOGIC_FUNCTION_CONFIG: 'LOGIC_FUNCTION_CONFIG' as const, + CODE_INTERPRETER_CONFIG: 'CODE_INTERPRETER_CONFIG' as const, + SSL: 'SSL' as const, + SUPPORT_CHAT_CONFIG: 'SUPPORT_CHAT_CONFIG' as const, + ANALYTICS_CONFIG: 'ANALYTICS_CONFIG' as const, + TOKENS_DURATION: 'TOKENS_DURATION' as const, + AWS_SES_SETTINGS: 'AWS_SES_SETTINGS' as const +} + +export const enumJobState = { + COMPLETED: 'COMPLETED' as const, + FAILED: 'FAILED' as const, + ACTIVE: 'ACTIVE' as const, + WAITING: 'WAITING' as const, + DELAYED: 'DELAYED' as const, + PRIORITIZED: 'PRIORITIZED' as const, + WAITING_CHILDREN: 'WAITING_CHILDREN' as const +} + +export const enumHealthIndicatorId = { + database: 'database' as const, + redis: 'redis' as const, + worker: 'worker' as const, + connectedAccount: 'connectedAccount' as const, + app: 'app' as const +} + +export const enumAdminPanelHealthServiceStatus = { + OPERATIONAL: 'OPERATIONAL' as const, + OUTAGE: 'OUTAGE' as const +} + +export const enumQueueMetricsTimeRange = { + SevenDays: 'SevenDays' as const, + OneDay: 'OneDay' as const, + TwelveHours: 'TwelveHours' as const, + FourHours: 'FourHours' as const, + OneHour: 'OneHour' as const +} + +export const enumBillingEntitlementKey = { + SSO: 'SSO' as const, + CUSTOM_DOMAIN: 'CUSTOM_DOMAIN' as const, + RLS: 'RLS' as const, + AUDIT_LOGS: 'AUDIT_LOGS' as const +} + export const enumRelationType = { ONE_TO_MANY: 'ONE_TO_MANY' as const, MANY_TO_ONE: 'MANY_TO_ONE' as const } -export const enumNavigationMenuItemType = { - VIEW: 'VIEW' as const, - FOLDER: 'FOLDER' as const, - LINK: 'LINK' as const, - OBJECT: 'OBJECT' as const, - RECORD: 'RECORD' as const +export const enumEmailingDomainDriver = { + AWS_SES: 'AWS_SES' as const } -export const enumMetadataEventAction = { - CREATED: 'CREATED' as const, - UPDATED: 'UPDATED' as const, - DELETED: 'DELETED' as const -} - -export const enumDatabaseEventAction = { - CREATED: 'CREATED' as const, - UPDATED: 'UPDATED' as const, - DELETED: 'DELETED' as const, - DESTROYED: 'DESTROYED' as const, - RESTORED: 'RESTORED' as const, - UPSERTED: 'UPSERTED' as const -} - -export const enumLogicFunctionExecutionStatus = { - IDLE: 'IDLE' as const, - SUCCESS: 'SUCCESS' as const, - ERROR: 'ERROR' as const +export const enumEmailingDomainStatus = { + PENDING: 'PENDING' as const, + VERIFIED: 'VERIFIED' as const, + FAILED: 'FAILED' as const, + TEMPORARY_FAILURE: 'TEMPORARY_FAILURE' as const } export const enumEngineComponentKey = { @@ -9323,103 +9422,6 @@ export const enumAllMetadataName = { webhook: 'webhook' as const } -export const enumModelFamily = { - GPT: 'GPT' as const, - CLAUDE: 'CLAUDE' as const, - GEMINI: 'GEMINI' as const, - MISTRAL: 'MISTRAL' as const, - GROK: 'GROK' as const -} - -export const enumSupportDriver = { - NONE: 'NONE' as const, - FRONT: 'FRONT' as const -} - -export const enumCaptchaDriverType = { - GOOGLE_RECAPTCHA: 'GOOGLE_RECAPTCHA' as const, - TURNSTILE: 'TURNSTILE' as const -} - -export const enumConfigSource = { - ENVIRONMENT: 'ENVIRONMENT' as const, - DATABASE: 'DATABASE' as const, - DEFAULT: 'DEFAULT' as const -} - -export const enumConfigVariableType = { - BOOLEAN: 'BOOLEAN' as const, - NUMBER: 'NUMBER' as const, - ARRAY: 'ARRAY' as const, - STRING: 'STRING' as const, - ENUM: 'ENUM' as const, - JSON: 'JSON' as const -} - -export const enumConfigVariablesGroup = { - SERVER_CONFIG: 'SERVER_CONFIG' as const, - RATE_LIMITING: 'RATE_LIMITING' as const, - STORAGE_CONFIG: 'STORAGE_CONFIG' as const, - GOOGLE_AUTH: 'GOOGLE_AUTH' as const, - MICROSOFT_AUTH: 'MICROSOFT_AUTH' as const, - EMAIL_SETTINGS: 'EMAIL_SETTINGS' as const, - LOGGING: 'LOGGING' as const, - ADVANCED_SETTINGS: 'ADVANCED_SETTINGS' as const, - BILLING_CONFIG: 'BILLING_CONFIG' as const, - CAPTCHA_CONFIG: 'CAPTCHA_CONFIG' as const, - CLOUDFLARE_CONFIG: 'CLOUDFLARE_CONFIG' as const, - LLM: 'LLM' as const, - LOGIC_FUNCTION_CONFIG: 'LOGIC_FUNCTION_CONFIG' as const, - CODE_INTERPRETER_CONFIG: 'CODE_INTERPRETER_CONFIG' as const, - SSL: 'SSL' as const, - SUPPORT_CHAT_CONFIG: 'SUPPORT_CHAT_CONFIG' as const, - ANALYTICS_CONFIG: 'ANALYTICS_CONFIG' as const, - TOKENS_DURATION: 'TOKENS_DURATION' as const, - AWS_SES_SETTINGS: 'AWS_SES_SETTINGS' as const -} - -export const enumJobState = { - COMPLETED: 'COMPLETED' as const, - FAILED: 'FAILED' as const, - ACTIVE: 'ACTIVE' as const, - WAITING: 'WAITING' as const, - DELAYED: 'DELAYED' as const, - PRIORITIZED: 'PRIORITIZED' as const, - WAITING_CHILDREN: 'WAITING_CHILDREN' as const -} - -export const enumHealthIndicatorId = { - database: 'database' as const, - redis: 'redis' as const, - worker: 'worker' as const, - connectedAccount: 'connectedAccount' as const, - app: 'app' as const -} - -export const enumAdminPanelHealthServiceStatus = { - OPERATIONAL: 'OPERATIONAL' as const, - OUTAGE: 'OUTAGE' as const -} - -export const enumQueueMetricsTimeRange = { - SevenDays: 'SevenDays' as const, - OneDay: 'OneDay' as const, - TwelveHours: 'TwelveHours' as const, - FourHours: 'FourHours' as const, - OneHour: 'OneHour' as const -} - -export const enumEmailingDomainDriver = { - AWS_SES: 'AWS_SES' as const -} - -export const enumEmailingDomainStatus = { - PENDING: 'PENDING' as const, - VERIFIED: 'VERIFIED' as const, - FAILED: 'FAILED' as const, - TEMPORARY_FAILURE: 'TEMPORARY_FAILURE' as const -} - export const enumAgentChatThreadSortFields = { id: 'id' as const, updatedAt: 'updatedAt' as const @@ -9473,5 +9475,6 @@ export const enumFileFolder = { FilesField: 'FilesField' as const, Dependencies: 'Dependencies' as const, Workflow: 'Workflow' as const, - AppTarball: 'AppTarball' as const + AppTarball: 'AppTarball' as const, + GeneratedSdkClient: 'GeneratedSdkClient' as const } diff --git a/packages/twenty-sdk/src/clients/generated/metadata/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts similarity index 97% rename from packages/twenty-sdk/src/clients/generated/metadata/types.ts rename to packages/twenty-client-sdk/src/metadata/generated/types.ts index 0f44e721b68..5b8d32848c4 100644 --- a/packages/twenty-sdk/src/clients/generated/metadata/types.ts +++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts @@ -44,49 +44,49 @@ export default { 121, 123, 131, - 147, - 148, - 153, - 157, + 146, + 149, + 151, + 155, + 159, + 160, + 166, + 171, + 174, + 178, 181, + 182, + 184, + 189, + 194, + 195, 210, - 213, - 215, - 219, 227, - 228, - 238, - 239, - 240, - 241, 244, - 245, - 246, - 247, - 248, - 249, - 250, - 252, - 254, - 262, - 267, - 270, - 276, - 277, - 279, - 284, - 289, - 290, - 304, - 324, + 282, + 283, + 299, + 300, 325, - 348, + 326, + 327, + 328, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 339, + 341, + 349, 355, 356, 357, 359, 372, - 373, + 398, 482, 487, 488 @@ -793,10 +793,10 @@ export default { 3 ], "relation": [ - 180 + 243 ], "morphRelations": [ - 180 + 243 ], "object": [ 46 @@ -855,7 +855,7 @@ export default { 36 ], "objectMetadata": [ - 168, + 236, { "paging": [ 39, @@ -868,7 +868,7 @@ export default { } ], "indexFieldMetadatas": [ - 166, + 234, { "paging": [ 39, @@ -1113,7 +1113,7 @@ export default { 37 ], "fields": [ - 173, + 241, { "paging": [ 39, @@ -1126,7 +1126,7 @@ export default { } ], "indexMetadatas": [ - 171, + 239, { "paging": [ 39, @@ -1698,7 +1698,7 @@ export default { 49 ], "featureFlags": [ - 156 + 197 ], "billingSubscriptions": [ 130 @@ -1707,7 +1707,7 @@ export default { 130 ], "billingEntitlements": [ - 152 + 226 ], "hasValidEnterpriseKey": [ 6 @@ -1719,7 +1719,7 @@ export default { 6 ], "workspaceUrls": [ - 145 + 157 ], "workspaceCustomApplicationId": [ 1 @@ -1811,7 +1811,7 @@ export default { 20 ], "deletedWorkspaceMembers": [ - 151 + 225 ], "hasPassword": [ 6 @@ -1823,7 +1823,7 @@ export default { 17 ], "availableWorkspaces": [ - 150 + 224 ], "__typename": [ 1 @@ -2989,8 +2989,187 @@ export default { 1 ] }, - "ResendEmailVerificationToken": { - "success": [ + "RecordIdentifier": { + "id": [ + 3 + ], + "labelIdentifier": [ + 1 + ], + "imageIdentifier": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "NavigationMenuItem": { + "id": [ + 3 + ], + "userWorkspaceId": [ + 3 + ], + "targetRecordId": [ + 3 + ], + "targetObjectMetadataId": [ + 3 + ], + "viewId": [ + 3 + ], + "type": [ + 146 + ], + "name": [ + 1 + ], + "link": [ + 1 + ], + "icon": [ + 1 + ], + "color": [ + 1 + ], + "folderId": [ + 3 + ], + "position": [ + 11 + ], + "applicationId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "targetRecordIdentifier": [ + 144 + ], + "__typename": [ + 1 + ] + }, + "NavigationMenuItemType": {}, + "ObjectRecordEventProperties": { + "updatedFields": [ + 1 + ], + "before": [ + 15 + ], + "after": [ + 15 + ], + "diff": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "MetadataEvent": { + "type": [ + 149 + ], + "metadataName": [ + 1 + ], + "recordId": [ + 1 + ], + "properties": [ + 147 + ], + "updatedCollectionHash": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "MetadataEventAction": {}, + "ObjectRecordEvent": { + "action": [ + 151 + ], + "objectNameSingular": [ + 1 + ], + "recordId": [ + 1 + ], + "userId": [ + 1 + ], + "workspaceMemberId": [ + 1 + ], + "properties": [ + 147 + ], + "__typename": [ + 1 + ] + }, + "DatabaseEventAction": {}, + "ObjectRecordEventWithQueryIds": { + "queryIds": [ + 1 + ], + "objectRecordEvent": [ + 150 + ], + "__typename": [ + 1 + ] + }, + "EventSubscription": { + "eventStreamId": [ + 1 + ], + "objectRecordEventsWithQueryIds": [ + 152 + ], + "metadataEvents": [ + 148 + ], + "__typename": [ + 1 + ] + }, + "LogicFunctionExecutionResult": { + "data": [ + 15 + ], + "logs": [ + 1 + ], + "duration": [ + 11 + ], + "status": [ + 155 + ], + "error": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "LogicFunctionExecutionStatus": {}, + "BillingTrialPeriod": { + "duration": [ + 11 + ], + "isCreditCardRequired": [ 6 ], "__typename": [ @@ -3008,146 +3187,6 @@ export default { 1 ] }, - "SSOConnection": { - "type": [ - 147 - ], - "id": [ - 3 - ], - "issuer": [ - 1 - ], - "name": [ - 1 - ], - "status": [ - 148 - ], - "__typename": [ - 1 - ] - }, - "IdentityProviderType": {}, - "SSOIdentityProviderStatus": {}, - "AvailableWorkspace": { - "id": [ - 3 - ], - "displayName": [ - 1 - ], - "loginToken": [ - 1 - ], - "personalInviteToken": [ - 1 - ], - "inviteHash": [ - 1 - ], - "workspaceUrls": [ - 145 - ], - "logo": [ - 1 - ], - "sso": [ - 146 - ], - "__typename": [ - 1 - ] - }, - "AvailableWorkspaces": { - "availableWorkspacesForSignIn": [ - 149 - ], - "availableWorkspacesForSignUp": [ - 149 - ], - "__typename": [ - 1 - ] - }, - "DeletedWorkspaceMember": { - "id": [ - 3 - ], - "name": [ - 19 - ], - "userEmail": [ - 1 - ], - "avatarUrl": [ - 1 - ], - "userWorkspaceId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "BillingEntitlement": { - "key": [ - 153 - ], - "value": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "BillingEntitlementKey": {}, - "DomainRecord": { - "validationType": [ - 1 - ], - "type": [ - 1 - ], - "status": [ - 1 - ], - "key": [ - 1 - ], - "value": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "DomainValidRecords": { - "id": [ - 3 - ], - "domain": [ - 1 - ], - "records": [ - 154 - ], - "__typename": [ - 1 - ] - }, - "FeatureFlag": { - "key": [ - 157 - ], - "value": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "FeatureFlagKey": {}, "SSOIdentityProvider": { "id": [ 3 @@ -3156,10 +3195,10 @@ export default { 1 ], "type": [ - 147 + 159 ], "status": [ - 148 + 160 ], "issuer": [ 1 @@ -3168,6 +3207,8 @@ export default { 1 ] }, + "IdentityProviderType": {}, + "SSOIdentityProviderStatus": {}, "AuthProviders": { "sso": [ 158 @@ -3207,10 +3248,10 @@ export default { 3 ], "authProviders": [ - 159 + 161 ], "authBypassProviders": [ - 160 + 162 ], "logo": [ 1 @@ -3219,161 +3260,743 @@ export default { 1 ], "workspaceUrls": [ - 145 + 157 ], "__typename": [ 1 ] }, - "IndexEdge": { - "node": [ - 37 - ], - "cursor": [ - 40 - ], - "__typename": [ - 1 - ] - }, - "PageInfo": { - "hasNextPage": [ + "NativeModelCapabilities": { + "webSearch": [ 6 ], - "hasPreviousPage": [ + "twitterSearch": [ 6 ], - "startCursor": [ - 40 + "__typename": [ + 1 + ] + }, + "ClientAIModelConfig": { + "modelId": [ + 1 ], - "endCursor": [ - 40 + "label": [ + 1 + ], + "modelFamily": [ + 166 + ], + "modelFamilyLabel": [ + 1 + ], + "sdkPackage": [ + 1 + ], + "inputCostPerMillionTokensInCredits": [ + 11 + ], + "outputCostPerMillionTokensInCredits": [ + 11 + ], + "nativeCapabilities": [ + 164 + ], + "isDeprecated": [ + 6 + ], + "isRecommended": [ + 6 + ], + "providerName": [ + 1 + ], + "dataResidency": [ + 1 ], "__typename": [ 1 ] }, - "IndexConnection": { - "pageInfo": [ - 163 + "ModelFamily": {}, + "AdminAIModelConfig": { + "modelId": [ + 1 ], - "edges": [ - 162 + "label": [ + 1 + ], + "modelFamily": [ + 166 + ], + "modelFamilyLabel": [ + 1 + ], + "sdkPackage": [ + 1 + ], + "isAvailable": [ + 6 + ], + "isAdminEnabled": [ + 6 + ], + "isDeprecated": [ + 6 + ], + "isRecommended": [ + 6 + ], + "contextWindowTokens": [ + 11 + ], + "maxOutputTokens": [ + 11 + ], + "inputCostPerMillionTokens": [ + 11 + ], + "outputCostPerMillionTokens": [ + 11 + ], + "providerName": [ + 1 + ], + "providerLabel": [ + 1 + ], + "name": [ + 1 + ], + "dataResidency": [ + 1 ], "__typename": [ 1 ] }, - "IndexFieldEdge": { - "node": [ - 36 + "AdminAIModels": { + "models": [ + 167 ], - "cursor": [ - 40 + "defaultSmartModelId": [ + 1 + ], + "defaultFastModelId": [ + 1 ], "__typename": [ 1 ] }, - "IndexIndexFieldMetadatasConnection": { - "pageInfo": [ - 163 + "Billing": { + "isBillingEnabled": [ + 6 ], - "edges": [ + "billingUrl": [ + 1 + ], + "trialPeriods": [ + 156 + ], + "__typename": [ + 1 + ] + }, + "Support": { + "supportDriver": [ + 171 + ], + "supportFrontChatId": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "SupportDriver": {}, + "Sentry": { + "environment": [ + 1 + ], + "release": [ + 1 + ], + "dsn": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "Captcha": { + "provider": [ + 174 + ], + "siteKey": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "CaptchaDriverType": {}, + "ApiConfig": { + "mutationMaximumAffectedRecords": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "PublicFeatureFlagMetadata": { + "label": [ + 1 + ], + "description": [ + 1 + ], + "imagePath": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "PublicFeatureFlag": { + "key": [ + 178 + ], + "metadata": [ + 176 + ], + "__typename": [ + 1 + ] + }, + "FeatureFlagKey": {}, + "ClientConfig": { + "appVersion": [ + 1 + ], + "authProviders": [ + 161 + ], + "billing": [ + 169 + ], + "aiModels": [ 165 ], - "__typename": [ - 1 - ] - }, - "ObjectEdge": { - "node": [ - 46 + "signInPrefilled": [ + 6 ], - "cursor": [ - 40 + "isMultiWorkspaceEnabled": [ + 6 ], - "__typename": [ - 1 - ] - }, - "IndexObjectMetadataConnection": { - "pageInfo": [ - 163 + "isEmailVerificationRequired": [ + 6 ], - "edges": [ - 167 - ], - "__typename": [ - 1 - ] - }, - "ObjectRecordCount": { - "objectNamePlural": [ + "defaultSubdomain": [ 1 ], - "totalCount": [ - 21 - ], - "__typename": [ + "frontDomain": [ 1 - ] - }, - "ObjectConnection": { - "pageInfo": [ - 163 ], - "edges": [ - 167 + "analyticsEnabled": [ + 6 ], - "__typename": [ - 1 - ] - }, - "ObjectIndexMetadatasConnection": { - "pageInfo": [ - 163 + "support": [ + 170 ], - "edges": [ - 162 + "isAttachmentPreviewEnabled": [ + 6 ], - "__typename": [ - 1 - ] - }, - "FieldEdge": { - "node": [ - 34 - ], - "cursor": [ - 40 - ], - "__typename": [ - 1 - ] - }, - "ObjectFieldsConnection": { - "pageInfo": [ - 163 - ], - "edges": [ + "sentry": [ 172 ], - "__typename": [ - 1 - ] - }, - "UpsertRowLevelPermissionPredicatesResult": { - "predicates": [ - 13 + "captcha": [ + 173 ], - "predicateGroups": [ - 10 + "api": [ + 175 + ], + "canManageFeatureFlags": [ + 6 + ], + "publicFeatureFlags": [ + 177 + ], + "isMicrosoftMessagingEnabled": [ + 6 + ], + "isMicrosoftCalendarEnabled": [ + 6 + ], + "isGoogleMessagingEnabled": [ + 6 + ], + "isGoogleCalendarEnabled": [ + 6 + ], + "isConfigVariablesInDbEnabled": [ + 6 + ], + "isImapSmtpCaldavEnabled": [ + 6 + ], + "allowRequestsToTwentyIcons": [ + 6 + ], + "calendarBookingPageId": [ + 1 + ], + "isCloudflareIntegrationEnabled": [ + 6 + ], + "isClickHouseConfigured": [ + 6 ], "__typename": [ 1 ] }, + "ConfigVariable": { + "name": [ + 1 + ], + "description": [ + 1 + ], + "value": [ + 15 + ], + "isSensitive": [ + 6 + ], + "source": [ + 181 + ], + "isEnvOnly": [ + 6 + ], + "type": [ + 182 + ], + "options": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "ConfigSource": {}, + "ConfigVariableType": {}, + "ConfigVariablesGroupData": { + "variables": [ + 180 + ], + "name": [ + 184 + ], + "description": [ + 1 + ], + "isHiddenOnLoad": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "ConfigVariablesGroup": {}, + "ConfigVariables": { + "groups": [ + 183 + ], + "__typename": [ + 1 + ] + }, + "JobOperationResult": { + "jobId": [ + 1 + ], + "success": [ + 6 + ], + "error": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "DeleteJobsResponse": { + "deletedCount": [ + 21 + ], + "results": [ + 186 + ], + "__typename": [ + 1 + ] + }, + "QueueJob": { + "id": [ + 1 + ], + "name": [ + 1 + ], + "data": [ + 15 + ], + "state": [ + 189 + ], + "timestamp": [ + 11 + ], + "failedReason": [ + 1 + ], + "processedOn": [ + 11 + ], + "finishedOn": [ + 11 + ], + "attemptsMade": [ + 11 + ], + "returnValue": [ + 15 + ], + "logs": [ + 1 + ], + "stackTrace": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "JobState": {}, + "QueueRetentionConfig": { + "completedMaxAge": [ + 11 + ], + "completedMaxCount": [ + 11 + ], + "failedMaxAge": [ + 11 + ], + "failedMaxCount": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "QueueJobsResponse": { + "jobs": [ + 188 + ], + "count": [ + 11 + ], + "totalCount": [ + 11 + ], + "hasMore": [ + 6 + ], + "retentionConfig": [ + 190 + ], + "__typename": [ + 1 + ] + }, + "RetryJobsResponse": { + "retriedCount": [ + 21 + ], + "results": [ + 186 + ], + "__typename": [ + 1 + ] + }, + "SystemHealthService": { + "id": [ + 194 + ], + "label": [ + 1 + ], + "status": [ + 195 + ], + "__typename": [ + 1 + ] + }, + "HealthIndicatorId": {}, + "AdminPanelHealthServiceStatus": {}, + "SystemHealth": { + "services": [ + 193 + ], + "__typename": [ + 1 + ] + }, + "FeatureFlag": { + "key": [ + 178 + ], + "value": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "UserInfo": { + "id": [ + 3 + ], + "email": [ + 1 + ], + "firstName": [ + 1 + ], + "lastName": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceInfo": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "allowImpersonation": [ + 6 + ], + "logo": [ + 1 + ], + "totalUsers": [ + 11 + ], + "workspaceUrls": [ + 157 + ], + "users": [ + 198 + ], + "featureFlags": [ + 197 + ], + "__typename": [ + 1 + ] + }, + "UserLookup": { + "user": [ + 198 + ], + "workspaces": [ + 199 + ], + "__typename": [ + 1 + ] + }, + "VersionInfo": { + "currentVersion": [ + 1 + ], + "latestVersion": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "AdminPanelWorkerQueueHealth": { + "id": [ + 1 + ], + "queueName": [ + 1 + ], + "status": [ + 195 + ], + "__typename": [ + 1 + ] + }, + "AdminPanelHealthServiceData": { + "id": [ + 194 + ], + "label": [ + 1 + ], + "description": [ + 1 + ], + "status": [ + 195 + ], + "errorMessage": [ + 1 + ], + "details": [ + 1 + ], + "queues": [ + 202 + ], + "__typename": [ + 1 + ] + }, + "ModelsDevModelSuggestion": { + "modelId": [ + 1 + ], + "name": [ + 1 + ], + "inputCostPerMillionTokens": [ + 11 + ], + "outputCostPerMillionTokens": [ + 11 + ], + "cachedInputCostPerMillionTokens": [ + 11 + ], + "cacheCreationCostPerMillionTokens": [ + 11 + ], + "contextWindowTokens": [ + 11 + ], + "maxOutputTokens": [ + 11 + ], + "modalities": [ + 1 + ], + "supportsReasoning": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "ModelsDevProviderSuggestion": { + "id": [ + 1 + ], + "modelCount": [ + 11 + ], + "npm": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "QueueMetricsDataPoint": { + "x": [ + 11 + ], + "y": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "QueueMetricsSeries": { + "id": [ + 1 + ], + "data": [ + 206 + ], + "__typename": [ + 1 + ] + }, + "WorkerQueueMetrics": { + "failed": [ + 11 + ], + "completed": [ + 11 + ], + "waiting": [ + 11 + ], + "active": [ + 11 + ], + "delayed": [ + 11 + ], + "failureRate": [ + 11 + ], + "failedData": [ + 11 + ], + "completedData": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "QueueMetricsData": { + "queueName": [ + 1 + ], + "workers": [ + 11 + ], + "timeRange": [ + 210 + ], + "details": [ + 208 + ], + "data": [ + 207 + ], + "__typename": [ + 1 + ] + }, + "QueueMetricsTimeRange": {}, "VersionDistributionEntry": { "version": [ 1 @@ -3393,7 +4016,7 @@ export default { 1 ], "versionDistribution": [ - 175 + 211 ], "__typename": [ 1 @@ -3438,9 +4061,374 @@ export default { 1 ] }, + "ResendEmailVerificationToken": { + "success": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "DeleteSso": { + "identityProviderId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "EditSso": { + "id": [ + 3 + ], + "type": [ + 159 + ], + "issuer": [ + 1 + ], + "name": [ + 1 + ], + "status": [ + 160 + ], + "__typename": [ + 1 + ] + }, + "WorkspaceNameAndId": { + "displayName": [ + 1 + ], + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "FindAvailableSSOIDP": { + "type": [ + 159 + ], + "id": [ + 3 + ], + "issuer": [ + 1 + ], + "name": [ + 1 + ], + "status": [ + 160 + ], + "workspace": [ + 219 + ], + "__typename": [ + 1 + ] + }, + "SetupSso": { + "id": [ + 3 + ], + "type": [ + 159 + ], + "issuer": [ + 1 + ], + "name": [ + 1 + ], + "status": [ + 160 + ], + "__typename": [ + 1 + ] + }, + "SSOConnection": { + "type": [ + 159 + ], + "id": [ + 3 + ], + "issuer": [ + 1 + ], + "name": [ + 1 + ], + "status": [ + 160 + ], + "__typename": [ + 1 + ] + }, + "AvailableWorkspace": { + "id": [ + 3 + ], + "displayName": [ + 1 + ], + "loginToken": [ + 1 + ], + "personalInviteToken": [ + 1 + ], + "inviteHash": [ + 1 + ], + "workspaceUrls": [ + 157 + ], + "logo": [ + 1 + ], + "sso": [ + 222 + ], + "__typename": [ + 1 + ] + }, + "AvailableWorkspaces": { + "availableWorkspacesForSignIn": [ + 223 + ], + "availableWorkspacesForSignUp": [ + 223 + ], + "__typename": [ + 1 + ] + }, + "DeletedWorkspaceMember": { + "id": [ + 3 + ], + "name": [ + 19 + ], + "userEmail": [ + 1 + ], + "avatarUrl": [ + 1 + ], + "userWorkspaceId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "BillingEntitlement": { + "key": [ + 227 + ], + "value": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "BillingEntitlementKey": {}, + "DomainRecord": { + "validationType": [ + 1 + ], + "type": [ + 1 + ], + "status": [ + 1 + ], + "key": [ + 1 + ], + "value": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "DomainValidRecords": { + "id": [ + 3 + ], + "domain": [ + 1 + ], + "records": [ + 228 + ], + "__typename": [ + 1 + ] + }, + "IndexEdge": { + "node": [ + 37 + ], + "cursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "PageInfo": { + "hasNextPage": [ + 6 + ], + "hasPreviousPage": [ + 6 + ], + "startCursor": [ + 40 + ], + "endCursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "IndexConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 230 + ], + "__typename": [ + 1 + ] + }, + "IndexFieldEdge": { + "node": [ + 36 + ], + "cursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "IndexIndexFieldMetadatasConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 233 + ], + "__typename": [ + 1 + ] + }, + "ObjectEdge": { + "node": [ + 46 + ], + "cursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "IndexObjectMetadataConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 235 + ], + "__typename": [ + 1 + ] + }, + "ObjectRecordCount": { + "objectNamePlural": [ + 1 + ], + "totalCount": [ + 21 + ], + "__typename": [ + 1 + ] + }, + "ObjectConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 235 + ], + "__typename": [ + 1 + ] + }, + "ObjectIndexMetadatasConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 230 + ], + "__typename": [ + 1 + ] + }, + "FieldEdge": { + "node": [ + 34 + ], + "cursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "ObjectFieldsConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 240 + ], + "__typename": [ + 1 + ] + }, + "UpsertRowLevelPermissionPredicatesResult": { + "predicates": [ + 13 + ], + "predicateGroups": [ + 10 + ], + "__typename": [ + 1 + ] + }, "Relation": { "type": [ - 181 + 244 ], "sourceObjectMetadata": [ 46 @@ -3461,92 +4449,10 @@ export default { "RelationType": {}, "FieldConnection": { "pageInfo": [ - 163 + 231 ], "edges": [ - 172 - ], - "__typename": [ - 1 - ] - }, - "DeleteSso": { - "identityProviderId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "EditSso": { - "id": [ - 3 - ], - "type": [ - 147 - ], - "issuer": [ - 1 - ], - "name": [ - 1 - ], - "status": [ - 148 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceNameAndId": { - "displayName": [ - 1 - ], - "id": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "FindAvailableSSOIDP": { - "type": [ - 147 - ], - "id": [ - 3 - ], - "issuer": [ - 1 - ], - "name": [ - 1 - ], - "status": [ - 148 - ], - "workspace": [ - 185 - ], - "__typename": [ - 1 - ] - }, - "SetupSso": { - "id": [ - 3 - ], - "type": [ - 147 - ], - "issuer": [ - 1 - ], - "name": [ - 1 - ], - "status": [ - 148 + 240 ], "__typename": [ 1 @@ -3597,10 +4503,10 @@ export default { }, "AuthTokenPair": { "accessOrWorkspaceAgnosticToken": [ - 192 + 250 ], "refreshToken": [ - 192 + 250 ], "__typename": [ 1 @@ -3608,10 +4514,10 @@ export default { }, "AvailableWorkspacesAndAccessTokens": { "tokens": [ - 193 + 251 ], "availableWorkspaces": [ - 150 + 224 ], "__typename": [ 1 @@ -3649,7 +4555,7 @@ export default { }, "WorkspaceUrlsAndId": { "workspaceUrls": [ - 145 + 157 ], "id": [ 3 @@ -3660,10 +4566,10 @@ export default { }, "SignUp": { "loginToken": [ - 192 + 250 ], "workspace": [ - 198 + 256 ], "__typename": [ 1 @@ -3671,7 +4577,7 @@ export default { }, "TransientToken": { "transientToken": [ - 192 + 250 ], "__typename": [ 1 @@ -3693,10 +4599,10 @@ export default { }, "VerifyEmailAndGetLoginToken": { "loginToken": [ - 192 + 250 ], "workspaceUrls": [ - 145 + 157 ], "__typename": [ 1 @@ -3712,7 +4618,7 @@ export default { }, "AuthTokens": { "tokens": [ - 193 + 251 ], "__typename": [ 1 @@ -3720,7 +4626,7 @@ export default { }, "LoginToken": { "loginToken": [ - 192 + 250 ], "__typename": [ 1 @@ -3748,57 +4654,571 @@ export default { 1 ] }, - "RecordIdentifier": { - "id": [ - 3 + "Impersonate": { + "loginToken": [ + 250 ], - "labelIdentifier": [ + "workspace": [ + 256 + ], + "__typename": [ + 1 + ] + }, + "DevelopmentApplication": { + "id": [ 1 ], - "imageIdentifier": [ + "universalIdentifier": [ 1 ], "__typename": [ 1 ] }, - "NavigationMenuItem": { + "WorkspaceMigration": { + "applicationUniversalIdentifier": [ + 1 + ], + "actions": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "ApplicationTokenPair": { + "applicationAccessToken": [ + 250 + ], + "applicationRefreshToken": [ + 250 + ], + "__typename": [ + 1 + ] + }, + "File": { "id": [ 3 ], - "userWorkspaceId": [ - 3 + "path": [ + 1 ], - "targetRecordId": [ - 3 + "size": [ + 11 ], - "targetObjectMetadataId": [ - 3 - ], - "viewId": [ - 3 - ], - "type": [ - 210 + "createdAt": [ + 4 ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppField": { "name": [ 1 ], - "link": [ + "type": [ + 1 + ], + "label": [ + 1 + ], + "description": [ 1 ], "icon": [ 1 ], - "color": [ + "objectUniversalIdentifier": [ 1 ], - "folderId": [ + "universalIdentifier": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppObject": { + "universalIdentifier": [ + 1 + ], + "nameSingular": [ + 1 + ], + "namePlural": [ + 1 + ], + "labelSingular": [ + 1 + ], + "labelPlural": [ + 1 + ], + "description": [ + 1 + ], + "icon": [ + 1 + ], + "fields": [ + 271 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppLogicFunction": { + "name": [ + 1 + ], + "description": [ + 1 + ], + "timeoutSeconds": [ + 21 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppFrontComponent": { + "name": [ + 1 + ], + "description": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppRoleObjectPermission": { + "objectUniversalIdentifier": [ + 1 + ], + "canReadObjectRecords": [ + 6 + ], + "canUpdateObjectRecords": [ + 6 + ], + "canSoftDeleteObjectRecords": [ + 6 + ], + "canDestroyObjectRecords": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppRoleFieldPermission": { + "objectUniversalIdentifier": [ + 1 + ], + "fieldUniversalIdentifier": [ + 1 + ], + "canReadFieldValue": [ + 6 + ], + "canUpdateFieldValue": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceAppDefaultRole": { + "id": [ + 1 + ], + "label": [ + 1 + ], + "description": [ + 1 + ], + "canReadAllObjectRecords": [ + 6 + ], + "canUpdateAllObjectRecords": [ + 6 + ], + "canSoftDeleteAllObjectRecords": [ + 6 + ], + "canDestroyAllObjectRecords": [ + 6 + ], + "canUpdateAllSettings": [ + 6 + ], + "canAccessAllTools": [ + 6 + ], + "objectPermissions": [ + 275 + ], + "fieldPermissions": [ + 276 + ], + "permissionFlags": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "MarketplaceApp": { + "id": [ + 1 + ], + "name": [ + 1 + ], + "description": [ + 1 + ], + "icon": [ + 1 + ], + "version": [ + 1 + ], + "author": [ + 1 + ], + "category": [ + 1 + ], + "logo": [ + 1 + ], + "screenshots": [ + 1 + ], + "aboutDescription": [ + 1 + ], + "providers": [ + 1 + ], + "websiteUrl": [ + 1 + ], + "termsUrl": [ + 1 + ], + "objects": [ + 272 + ], + "fields": [ + 271 + ], + "logicFunctions": [ + 273 + ], + "frontComponents": [ + 274 + ], + "defaultRole": [ + 277 + ], + "sourcePackage": [ + 1 + ], + "isFeatured": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "PublicDomain": { + "id": [ 3 ], - "position": [ + "domain": [ + 1 + ], + "isValidated": [ + 6 + ], + "createdAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "VerificationRecord": { + "type": [ + 1 + ], + "key": [ + 1 + ], + "value": [ + 1 + ], + "priority": [ 11 ], + "__typename": [ + 1 + ] + }, + "EmailingDomain": { + "id": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "domain": [ + 1 + ], + "driver": [ + 282 + ], + "status": [ + 283 + ], + "verificationRecords": [ + 280 + ], + "verifiedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "EmailingDomainDriver": {}, + "EmailingDomainStatus": {}, + "AutocompleteResult": { + "text": [ + 1 + ], + "placeId": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "Location": { + "lat": [ + 11 + ], + "lng": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "PlaceDetailsResult": { + "state": [ + 1 + ], + "postcode": [ + 1 + ], + "city": [ + 1 + ], + "country": [ + 1 + ], + "location": [ + 285 + ], + "__typename": [ + 1 + ] + }, + "ConnectionParametersOutput": { + "host": [ + 1 + ], + "port": [ + 11 + ], + "username": [ + 1 + ], + "password": [ + 1 + ], + "secure": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "ImapSmtpCaldavConnectionParameters": { + "IMAP": [ + 287 + ], + "SMTP": [ + 287 + ], + "CALDAV": [ + 287 + ], + "__typename": [ + 1 + ] + }, + "ConnectedImapSmtpCaldavAccount": { + "id": [ + 3 + ], + "handle": [ + 1 + ], + "provider": [ + 1 + ], + "accountOwnerId": [ + 3 + ], + "connectionParameters": [ + 288 + ], + "__typename": [ + 1 + ] + }, + "ImapSmtpCaldavConnectionSuccess": { + "success": [ + 6 + ], + "connectedAccountId": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "PostgresCredentials": { + "id": [ + 3 + ], + "user": [ + 1 + ], + "password": [ + 1 + ], + "workspaceId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "UsageBreakdownItem": { + "key": [ + 1 + ], + "label": [ + 1 + ], + "creditsUsed": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "UsageTimeSeries": { + "date": [ + 1 + ], + "creditsUsed": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "UsageUserDaily": { + "userWorkspaceId": [ + 1 + ], + "dailyUsage": [ + 293 + ], + "__typename": [ + 1 + ] + }, + "UsageAnalytics": { + "usageByUser": [ + 292 + ], + "usageByOperationType": [ + 292 + ], + "timeSeries": [ + 293 + ], + "periodStart": [ + 4 + ], + "periodEnd": [ + 4 + ], + "userDailyUsage": [ + 294 + ], + "__typename": [ + 1 + ] + }, + "LogicFunctionLogs": { + "logs": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "FrontComponent": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "description": [ + 1 + ], + "sourceComponentPath": [ + 1 + ], + "builtComponentPath": [ + 1 + ], + "componentName": [ + 1 + ], + "builtComponentChecksum": [ + 1 + ], + "universalIdentifier": [ + 3 + ], "applicationId": [ 3 ], @@ -3808,130 +5228,77 @@ export default { "updatedAt": [ 4 ], - "targetRecordIdentifier": [ - 208 + "isHeadless": [ + 6 + ], + "usesSdkClient": [ + 6 + ], + "applicationTokenPair": [ + 269 ], "__typename": [ 1 ] }, - "NavigationMenuItemType": {}, - "ObjectRecordEventProperties": { - "updatedFields": [ + "CommandMenuItem": { + "id": [ + 3 + ], + "workflowVersionId": [ + 3 + ], + "frontComponentId": [ + 3 + ], + "frontComponent": [ + 297 + ], + "engineComponentKey": [ + 299 + ], + "label": [ 1 ], - "before": [ - 15 - ], - "after": [ - 15 - ], - "diff": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "MetadataEvent": { - "type": [ - 213 - ], - "metadataName": [ + "icon": [ 1 ], - "recordId": [ + "shortLabel": [ 1 ], - "properties": [ - 211 - ], - "updatedCollectionHash": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "MetadataEventAction": {}, - "ObjectRecordEvent": { - "action": [ - 215 - ], - "objectNameSingular": [ - 1 - ], - "recordId": [ - 1 - ], - "userId": [ - 1 - ], - "workspaceMemberId": [ - 1 - ], - "properties": [ - 211 - ], - "__typename": [ - 1 - ] - }, - "DatabaseEventAction": {}, - "ObjectRecordEventWithQueryIds": { - "queryIds": [ - 1 - ], - "objectRecordEvent": [ - 214 - ], - "__typename": [ - 1 - ] - }, - "EventSubscription": { - "eventStreamId": [ - 1 - ], - "objectRecordEventsWithQueryIds": [ - 216 - ], - "metadataEvents": [ - 212 - ], - "__typename": [ - 1 - ] - }, - "LogicFunctionExecutionResult": { - "data": [ - 15 - ], - "logs": [ - 1 - ], - "duration": [ + "position": [ 11 ], - "status": [ - 219 + "isPinned": [ + 6 ], - "error": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "LogicFunctionExecutionStatus": {}, - "LogicFunctionLogs": { - "logs": [ - 1 + "availabilityType": [ + 300 + ], + "hotKeys": [ + 1 + ], + "conditionalAvailabilityExpression": [ + 1 + ], + "availabilityObjectMetadataId": [ + 3 + ], + "applicationId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 ], "__typename": [ 1 ] }, + "EngineComponentKey": {}, + "CommandMenuItemAvailabilityType": {}, "ToolIndexEntry": { "name": [ 1 @@ -4035,1869 +5402,6 @@ export default { 1 ] }, - "Skill": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "label": [ - 1 - ], - "icon": [ - 1 - ], - "description": [ - 1 - ], - "content": [ - 1 - ], - "isCustom": [ - 6 - ], - "isActive": [ - 6 - ], - "applicationId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "ApplicationTokenPair": { - "applicationAccessToken": [ - 192 - ], - "applicationRefreshToken": [ - 192 - ], - "__typename": [ - 1 - ] - }, - "FrontComponent": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "description": [ - 1 - ], - "sourceComponentPath": [ - 1 - ], - "builtComponentPath": [ - 1 - ], - "componentName": [ - 1 - ], - "builtComponentChecksum": [ - 1 - ], - "universalIdentifier": [ - 3 - ], - "applicationId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "isHeadless": [ - 6 - ], - "applicationTokenPair": [ - 224 - ], - "__typename": [ - 1 - ] - }, - "CommandMenuItem": { - "id": [ - 3 - ], - "workflowVersionId": [ - 3 - ], - "frontComponentId": [ - 3 - ], - "frontComponent": [ - 225 - ], - "engineComponentKey": [ - 227 - ], - "label": [ - 1 - ], - "icon": [ - 1 - ], - "shortLabel": [ - 1 - ], - "position": [ - 11 - ], - "isPinned": [ - 6 - ], - "availabilityType": [ - 228 - ], - "hotKeys": [ - 1 - ], - "conditionalAvailabilityExpression": [ - 1 - ], - "availabilityObjectMetadataId": [ - 3 - ], - "applicationId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "EngineComponentKey": {}, - "CommandMenuItemAvailabilityType": {}, - "AgentChatThread": { - "id": [ - 3 - ], - "title": [ - 1 - ], - "totalInputTokens": [ - 21 - ], - "totalOutputTokens": [ - 21 - ], - "contextWindowTokens": [ - 21 - ], - "conversationSize": [ - 21 - ], - "totalInputCredits": [ - 11 - ], - "totalOutputCredits": [ - 11 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "AgentMessage": { - "id": [ - 3 - ], - "threadId": [ - 3 - ], - "turnId": [ - 3 - ], - "agentId": [ - 3 - ], - "role": [ - 1 - ], - "parts": [ - 222 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "AISystemPromptSection": { - "title": [ - 1 - ], - "content": [ - 1 - ], - "estimatedTokenCount": [ - 21 - ], - "__typename": [ - 1 - ] - }, - "AISystemPromptPreview": { - "sections": [ - 231 - ], - "estimatedTokenCount": [ - 21 - ], - "__typename": [ - 1 - ] - }, - "AgentChatThreadEdge": { - "node": [ - 229 - ], - "cursor": [ - 40 - ], - "__typename": [ - 1 - ] - }, - "AgentChatThreadConnection": { - "pageInfo": [ - 163 - ], - "edges": [ - 233 - ], - "__typename": [ - 1 - ] - }, - "AgentTurnEvaluation": { - "id": [ - 3 - ], - "turnId": [ - 3 - ], - "score": [ - 21 - ], - "comment": [ - 1 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "AgentTurn": { - "id": [ - 3 - ], - "threadId": [ - 3 - ], - "agentId": [ - 3 - ], - "evaluations": [ - 235 - ], - "messages": [ - 230 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "CalendarChannel": { - "id": [ - 3 - ], - "handle": [ - 1 - ], - "syncStatus": [ - 238 - ], - "syncStage": [ - 239 - ], - "visibility": [ - 240 - ], - "isContactAutoCreationEnabled": [ - 6 - ], - "contactAutoCreationPolicy": [ - 241 - ], - "isSyncEnabled": [ - 6 - ], - "syncedAt": [ - 4 - ], - "syncStageStartedAt": [ - 4 - ], - "throttleFailureCount": [ - 11 - ], - "connectedAccountId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "CalendarChannelSyncStatus": {}, - "CalendarChannelSyncStage": {}, - "CalendarChannelVisibility": {}, - "CalendarChannelContactAutoCreationPolicy": {}, - "ConnectedAccountDTO": { - "id": [ - 3 - ], - "handle": [ - 1 - ], - "provider": [ - 1 - ], - "lastCredentialsRefreshedAt": [ - 4 - ], - "authFailedAt": [ - 4 - ], - "handleAliases": [ - 1 - ], - "scopes": [ - 1 - ], - "lastSignedInAt": [ - 4 - ], - "userWorkspaceId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "MessageChannel": { - "id": [ - 3 - ], - "visibility": [ - 244 - ], - "handle": [ - 1 - ], - "type": [ - 245 - ], - "isContactAutoCreationEnabled": [ - 6 - ], - "contactAutoCreationPolicy": [ - 246 - ], - "messageFolderImportPolicy": [ - 247 - ], - "excludeNonProfessionalEmails": [ - 6 - ], - "excludeGroupEmails": [ - 6 - ], - "pendingGroupEmailsAction": [ - 248 - ], - "isSyncEnabled": [ - 6 - ], - "syncedAt": [ - 4 - ], - "syncStatus": [ - 249 - ], - "syncStage": [ - 250 - ], - "syncStageStartedAt": [ - 4 - ], - "throttleFailureCount": [ - 11 - ], - "throttleRetryAfter": [ - 4 - ], - "connectedAccountId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "MessageChannelVisibility": {}, - "MessageChannelType": {}, - "MessageChannelContactAutoCreationPolicy": {}, - "MessageFolderImportPolicy": {}, - "MessageChannelPendingGroupEmailsAction": {}, - "MessageChannelSyncStatus": {}, - "MessageChannelSyncStage": {}, - "MessageFolder": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "isSentFolder": [ - 6 - ], - "isSynced": [ - 6 - ], - "parentFolderId": [ - 3 - ], - "externalId": [ - 1 - ], - "pendingSyncAction": [ - 252 - ], - "messageChannelId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "MessageFolderPendingSyncAction": {}, - "CollectionHash": { - "collectionName": [ - 254 - ], - "hash": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "AllMetadataName": {}, - "MinimalObjectMetadata": { - "id": [ - 3 - ], - "nameSingular": [ - 1 - ], - "namePlural": [ - 1 - ], - "labelSingular": [ - 1 - ], - "labelPlural": [ - 1 - ], - "icon": [ - 1 - ], - "color": [ - 1 - ], - "isCustom": [ - 6 - ], - "isActive": [ - 6 - ], - "isSystem": [ - 6 - ], - "isRemote": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "MinimalView": { - "id": [ - 3 - ], - "type": [ - 61 - ], - "key": [ - 62 - ], - "objectMetadataId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "MinimalMetadata": { - "objectMetadataItems": [ - 255 - ], - "views": [ - 256 - ], - "collectionHashes": [ - 253 - ], - "__typename": [ - 1 - ] - }, - "Webhook": { - "id": [ - 3 - ], - "targetUrl": [ - 1 - ], - "operations": [ - 1 - ], - "description": [ - 1 - ], - "secret": [ - 1 - ], - "applicationId": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "deletedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "BillingTrialPeriod": { - "duration": [ - 11 - ], - "isCreditCardRequired": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "NativeModelCapabilities": { - "webSearch": [ - 6 - ], - "twitterSearch": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "ClientAIModelConfig": { - "modelId": [ - 1 - ], - "label": [ - 1 - ], - "modelFamily": [ - 262 - ], - "modelFamilyLabel": [ - 1 - ], - "sdkPackage": [ - 1 - ], - "inputCostPerMillionTokensInCredits": [ - 11 - ], - "outputCostPerMillionTokensInCredits": [ - 11 - ], - "nativeCapabilities": [ - 260 - ], - "isDeprecated": [ - 6 - ], - "isRecommended": [ - 6 - ], - "providerName": [ - 1 - ], - "dataResidency": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "ModelFamily": {}, - "AdminAIModelConfig": { - "modelId": [ - 1 - ], - "label": [ - 1 - ], - "modelFamily": [ - 262 - ], - "modelFamilyLabel": [ - 1 - ], - "sdkPackage": [ - 1 - ], - "isAvailable": [ - 6 - ], - "isAdminEnabled": [ - 6 - ], - "isDeprecated": [ - 6 - ], - "isRecommended": [ - 6 - ], - "contextWindowTokens": [ - 11 - ], - "maxOutputTokens": [ - 11 - ], - "inputCostPerMillionTokens": [ - 11 - ], - "outputCostPerMillionTokens": [ - 11 - ], - "providerName": [ - 1 - ], - "providerLabel": [ - 1 - ], - "name": [ - 1 - ], - "dataResidency": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "AdminAIModels": { - "models": [ - 263 - ], - "defaultSmartModelId": [ - 1 - ], - "defaultFastModelId": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "Billing": { - "isBillingEnabled": [ - 6 - ], - "billingUrl": [ - 1 - ], - "trialPeriods": [ - 259 - ], - "__typename": [ - 1 - ] - }, - "Support": { - "supportDriver": [ - 267 - ], - "supportFrontChatId": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "SupportDriver": {}, - "Sentry": { - "environment": [ - 1 - ], - "release": [ - 1 - ], - "dsn": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "Captcha": { - "provider": [ - 270 - ], - "siteKey": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "CaptchaDriverType": {}, - "ApiConfig": { - "mutationMaximumAffectedRecords": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "PublicFeatureFlagMetadata": { - "label": [ - 1 - ], - "description": [ - 1 - ], - "imagePath": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "PublicFeatureFlag": { - "key": [ - 157 - ], - "metadata": [ - 272 - ], - "__typename": [ - 1 - ] - }, - "ClientConfig": { - "appVersion": [ - 1 - ], - "authProviders": [ - 159 - ], - "billing": [ - 265 - ], - "aiModels": [ - 261 - ], - "signInPrefilled": [ - 6 - ], - "isMultiWorkspaceEnabled": [ - 6 - ], - "isEmailVerificationRequired": [ - 6 - ], - "defaultSubdomain": [ - 1 - ], - "frontDomain": [ - 1 - ], - "analyticsEnabled": [ - 6 - ], - "support": [ - 266 - ], - "isAttachmentPreviewEnabled": [ - 6 - ], - "sentry": [ - 268 - ], - "captcha": [ - 269 - ], - "api": [ - 271 - ], - "canManageFeatureFlags": [ - 6 - ], - "publicFeatureFlags": [ - 273 - ], - "isMicrosoftMessagingEnabled": [ - 6 - ], - "isMicrosoftCalendarEnabled": [ - 6 - ], - "isGoogleMessagingEnabled": [ - 6 - ], - "isGoogleCalendarEnabled": [ - 6 - ], - "isConfigVariablesInDbEnabled": [ - 6 - ], - "isImapSmtpCaldavEnabled": [ - 6 - ], - "allowRequestsToTwentyIcons": [ - 6 - ], - "calendarBookingPageId": [ - 1 - ], - "isCloudflareIntegrationEnabled": [ - 6 - ], - "isClickHouseConfigured": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "ConfigVariable": { - "name": [ - 1 - ], - "description": [ - 1 - ], - "value": [ - 15 - ], - "isSensitive": [ - 6 - ], - "source": [ - 276 - ], - "isEnvOnly": [ - 6 - ], - "type": [ - 277 - ], - "options": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "ConfigSource": {}, - "ConfigVariableType": {}, - "ConfigVariablesGroupData": { - "variables": [ - 275 - ], - "name": [ - 279 - ], - "description": [ - 1 - ], - "isHiddenOnLoad": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "ConfigVariablesGroup": {}, - "ConfigVariables": { - "groups": [ - 278 - ], - "__typename": [ - 1 - ] - }, - "JobOperationResult": { - "jobId": [ - 1 - ], - "success": [ - 6 - ], - "error": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "DeleteJobsResponse": { - "deletedCount": [ - 21 - ], - "results": [ - 281 - ], - "__typename": [ - 1 - ] - }, - "QueueJob": { - "id": [ - 1 - ], - "name": [ - 1 - ], - "data": [ - 15 - ], - "state": [ - 284 - ], - "timestamp": [ - 11 - ], - "failedReason": [ - 1 - ], - "processedOn": [ - 11 - ], - "finishedOn": [ - 11 - ], - "attemptsMade": [ - 11 - ], - "returnValue": [ - 15 - ], - "logs": [ - 1 - ], - "stackTrace": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "JobState": {}, - "QueueRetentionConfig": { - "completedMaxAge": [ - 11 - ], - "completedMaxCount": [ - 11 - ], - "failedMaxAge": [ - 11 - ], - "failedMaxCount": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "QueueJobsResponse": { - "jobs": [ - 283 - ], - "count": [ - 11 - ], - "totalCount": [ - 11 - ], - "hasMore": [ - 6 - ], - "retentionConfig": [ - 285 - ], - "__typename": [ - 1 - ] - }, - "RetryJobsResponse": { - "retriedCount": [ - 21 - ], - "results": [ - 281 - ], - "__typename": [ - 1 - ] - }, - "SystemHealthService": { - "id": [ - 289 - ], - "label": [ - 1 - ], - "status": [ - 290 - ], - "__typename": [ - 1 - ] - }, - "HealthIndicatorId": {}, - "AdminPanelHealthServiceStatus": {}, - "SystemHealth": { - "services": [ - 288 - ], - "__typename": [ - 1 - ] - }, - "UserInfo": { - "id": [ - 3 - ], - "email": [ - 1 - ], - "firstName": [ - 1 - ], - "lastName": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceInfo": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "allowImpersonation": [ - 6 - ], - "logo": [ - 1 - ], - "totalUsers": [ - 11 - ], - "workspaceUrls": [ - 145 - ], - "users": [ - 292 - ], - "featureFlags": [ - 156 - ], - "__typename": [ - 1 - ] - }, - "UserLookup": { - "user": [ - 292 - ], - "workspaces": [ - 293 - ], - "__typename": [ - 1 - ] - }, - "VersionInfo": { - "currentVersion": [ - 1 - ], - "latestVersion": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "AdminPanelWorkerQueueHealth": { - "id": [ - 1 - ], - "queueName": [ - 1 - ], - "status": [ - 290 - ], - "__typename": [ - 1 - ] - }, - "AdminPanelHealthServiceData": { - "id": [ - 289 - ], - "label": [ - 1 - ], - "description": [ - 1 - ], - "status": [ - 290 - ], - "errorMessage": [ - 1 - ], - "details": [ - 1 - ], - "queues": [ - 296 - ], - "__typename": [ - 1 - ] - }, - "ModelsDevModelSuggestion": { - "modelId": [ - 1 - ], - "name": [ - 1 - ], - "inputCostPerMillionTokens": [ - 11 - ], - "outputCostPerMillionTokens": [ - 11 - ], - "cachedInputCostPerMillionTokens": [ - 11 - ], - "cacheCreationCostPerMillionTokens": [ - 11 - ], - "contextWindowTokens": [ - 11 - ], - "maxOutputTokens": [ - 11 - ], - "modalities": [ - 1 - ], - "supportsReasoning": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "ModelsDevProviderSuggestion": { - "id": [ - 1 - ], - "modelCount": [ - 11 - ], - "npm": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "QueueMetricsDataPoint": { - "x": [ - 11 - ], - "y": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "QueueMetricsSeries": { - "id": [ - 1 - ], - "data": [ - 300 - ], - "__typename": [ - 1 - ] - }, - "WorkerQueueMetrics": { - "failed": [ - 11 - ], - "completed": [ - 11 - ], - "waiting": [ - 11 - ], - "active": [ - 11 - ], - "delayed": [ - 11 - ], - "failureRate": [ - 11 - ], - "failedData": [ - 11 - ], - "completedData": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "QueueMetricsData": { - "queueName": [ - 1 - ], - "workers": [ - 11 - ], - "timeRange": [ - 304 - ], - "details": [ - 302 - ], - "data": [ - 301 - ], - "__typename": [ - 1 - ] - }, - "QueueMetricsTimeRange": {}, - "Impersonate": { - "loginToken": [ - 192 - ], - "workspace": [ - 198 - ], - "__typename": [ - 1 - ] - }, - "DevelopmentApplication": { - "id": [ - 1 - ], - "universalIdentifier": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "WorkspaceMigration": { - "applicationUniversalIdentifier": [ - 1 - ], - "actions": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "File": { - "id": [ - 3 - ], - "path": [ - 1 - ], - "size": [ - 11 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppField": { - "name": [ - 1 - ], - "type": [ - 1 - ], - "label": [ - 1 - ], - "description": [ - 1 - ], - "icon": [ - 1 - ], - "objectUniversalIdentifier": [ - 1 - ], - "universalIdentifier": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppObject": { - "universalIdentifier": [ - 1 - ], - "nameSingular": [ - 1 - ], - "namePlural": [ - 1 - ], - "labelSingular": [ - 1 - ], - "labelPlural": [ - 1 - ], - "description": [ - 1 - ], - "icon": [ - 1 - ], - "fields": [ - 309 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppLogicFunction": { - "name": [ - 1 - ], - "description": [ - 1 - ], - "timeoutSeconds": [ - 21 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppFrontComponent": { - "name": [ - 1 - ], - "description": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppRoleObjectPermission": { - "objectUniversalIdentifier": [ - 1 - ], - "canReadObjectRecords": [ - 6 - ], - "canUpdateObjectRecords": [ - 6 - ], - "canSoftDeleteObjectRecords": [ - 6 - ], - "canDestroyObjectRecords": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppRoleFieldPermission": { - "objectUniversalIdentifier": [ - 1 - ], - "fieldUniversalIdentifier": [ - 1 - ], - "canReadFieldValue": [ - 6 - ], - "canUpdateFieldValue": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceAppDefaultRole": { - "id": [ - 1 - ], - "label": [ - 1 - ], - "description": [ - 1 - ], - "canReadAllObjectRecords": [ - 6 - ], - "canUpdateAllObjectRecords": [ - 6 - ], - "canSoftDeleteAllObjectRecords": [ - 6 - ], - "canDestroyAllObjectRecords": [ - 6 - ], - "canUpdateAllSettings": [ - 6 - ], - "canAccessAllTools": [ - 6 - ], - "objectPermissions": [ - 313 - ], - "fieldPermissions": [ - 314 - ], - "permissionFlags": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "MarketplaceApp": { - "id": [ - 1 - ], - "name": [ - 1 - ], - "description": [ - 1 - ], - "icon": [ - 1 - ], - "version": [ - 1 - ], - "author": [ - 1 - ], - "category": [ - 1 - ], - "logo": [ - 1 - ], - "screenshots": [ - 1 - ], - "aboutDescription": [ - 1 - ], - "providers": [ - 1 - ], - "websiteUrl": [ - 1 - ], - "termsUrl": [ - 1 - ], - "objects": [ - 310 - ], - "fields": [ - 309 - ], - "logicFunctions": [ - 311 - ], - "frontComponents": [ - 312 - ], - "defaultRole": [ - 315 - ], - "sourcePackage": [ - 1 - ], - "isFeatured": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "UsageBreakdownItem": { - "key": [ - 1 - ], - "label": [ - 1 - ], - "creditsUsed": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "UsageTimeSeries": { - "date": [ - 1 - ], - "creditsUsed": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "UsageUserDaily": { - "userWorkspaceId": [ - 1 - ], - "dailyUsage": [ - 318 - ], - "__typename": [ - 1 - ] - }, - "UsageAnalytics": { - "usageByUser": [ - 317 - ], - "usageByOperationType": [ - 317 - ], - "timeSeries": [ - 318 - ], - "periodStart": [ - 4 - ], - "periodEnd": [ - 4 - ], - "userDailyUsage": [ - 319 - ], - "__typename": [ - 1 - ] - }, - "PublicDomain": { - "id": [ - 3 - ], - "domain": [ - 1 - ], - "isValidated": [ - 6 - ], - "createdAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "VerificationRecord": { - "type": [ - 1 - ], - "key": [ - 1 - ], - "value": [ - 1 - ], - "priority": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "EmailingDomain": { - "id": [ - 3 - ], - "createdAt": [ - 4 - ], - "updatedAt": [ - 4 - ], - "domain": [ - 1 - ], - "driver": [ - 324 - ], - "status": [ - 325 - ], - "verificationRecords": [ - 322 - ], - "verifiedAt": [ - 4 - ], - "__typename": [ - 1 - ] - }, - "EmailingDomainDriver": {}, - "EmailingDomainStatus": {}, - "AutocompleteResult": { - "text": [ - 1 - ], - "placeId": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "Location": { - "lat": [ - 11 - ], - "lng": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "PlaceDetailsResult": { - "state": [ - 1 - ], - "postcode": [ - 1 - ], - "city": [ - 1 - ], - "country": [ - 1 - ], - "location": [ - 327 - ], - "__typename": [ - 1 - ] - }, - "ConnectionParametersOutput": { - "host": [ - 1 - ], - "port": [ - 11 - ], - "username": [ - 1 - ], - "password": [ - 1 - ], - "secure": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "ImapSmtpCaldavConnectionParameters": { - "IMAP": [ - 329 - ], - "SMTP": [ - 329 - ], - "CALDAV": [ - 329 - ], - "__typename": [ - 1 - ] - }, - "ConnectedImapSmtpCaldavAccount": { - "id": [ - 3 - ], - "handle": [ - 1 - ], - "provider": [ - 1 - ], - "accountOwnerId": [ - 3 - ], - "connectionParameters": [ - 330 - ], - "__typename": [ - 1 - ] - }, - "ImapSmtpCaldavConnectionSuccess": { - "success": [ - 6 - ], - "connectedAccountId": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "PostgresCredentials": { - "id": [ - 3 - ], - "user": [ - 1 - ], - "password": [ - 1 - ], - "workspaceId": [ - 3 - ], - "__typename": [ - 1 - ] - }, "ChannelSyncSuccess": { "success": [ 6 @@ -5928,7 +5432,7 @@ export default { 1 ], "series": [ - 335 + 304 ], "xAxisLabel": [ 1 @@ -5977,7 +5481,7 @@ export default { 1 ], "data": [ - 337 + 306 ], "__typename": [ 1 @@ -5985,7 +5489,7 @@ export default { }, "LineChartData": { "series": [ - 338 + 307 ], "xAxisLabel": [ 1 @@ -6022,7 +5526,7 @@ export default { }, "PieChartData": { "data": [ - 340 + 309 ], "showLegend": [ 6 @@ -6105,13 +5609,512 @@ export default { }, "EventLogQueryResult": { "records": [ - 343 + 312 ], "totalCount": [ 21 ], "pageInfo": [ - 344 + 313 + ], + "__typename": [ + 1 + ] + }, + "Skill": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "label": [ + 1 + ], + "icon": [ + 1 + ], + "description": [ + 1 + ], + "content": [ + 1 + ], + "isCustom": [ + 6 + ], + "isActive": [ + 6 + ], + "applicationId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "AgentChatThread": { + "id": [ + 3 + ], + "title": [ + 1 + ], + "totalInputTokens": [ + 21 + ], + "totalOutputTokens": [ + 21 + ], + "contextWindowTokens": [ + 21 + ], + "conversationSize": [ + 21 + ], + "totalInputCredits": [ + 11 + ], + "totalOutputCredits": [ + 11 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "AgentMessage": { + "id": [ + 3 + ], + "threadId": [ + 3 + ], + "turnId": [ + 3 + ], + "agentId": [ + 3 + ], + "role": [ + 1 + ], + "parts": [ + 302 + ], + "createdAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "AISystemPromptSection": { + "title": [ + 1 + ], + "content": [ + 1 + ], + "estimatedTokenCount": [ + 21 + ], + "__typename": [ + 1 + ] + }, + "AISystemPromptPreview": { + "sections": [ + 318 + ], + "estimatedTokenCount": [ + 21 + ], + "__typename": [ + 1 + ] + }, + "AgentChatThreadEdge": { + "node": [ + 316 + ], + "cursor": [ + 40 + ], + "__typename": [ + 1 + ] + }, + "AgentChatThreadConnection": { + "pageInfo": [ + 231 + ], + "edges": [ + 320 + ], + "__typename": [ + 1 + ] + }, + "AgentTurnEvaluation": { + "id": [ + 3 + ], + "turnId": [ + 3 + ], + "score": [ + 21 + ], + "comment": [ + 1 + ], + "createdAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "AgentTurn": { + "id": [ + 3 + ], + "threadId": [ + 3 + ], + "agentId": [ + 3 + ], + "evaluations": [ + 322 + ], + "messages": [ + 317 + ], + "createdAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "CalendarChannel": { + "id": [ + 3 + ], + "handle": [ + 1 + ], + "syncStatus": [ + 325 + ], + "syncStage": [ + 326 + ], + "visibility": [ + 327 + ], + "isContactAutoCreationEnabled": [ + 6 + ], + "contactAutoCreationPolicy": [ + 328 + ], + "isSyncEnabled": [ + 6 + ], + "syncedAt": [ + 4 + ], + "syncStageStartedAt": [ + 4 + ], + "throttleFailureCount": [ + 11 + ], + "connectedAccountId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "CalendarChannelSyncStatus": {}, + "CalendarChannelSyncStage": {}, + "CalendarChannelVisibility": {}, + "CalendarChannelContactAutoCreationPolicy": {}, + "ConnectedAccountDTO": { + "id": [ + 3 + ], + "handle": [ + 1 + ], + "provider": [ + 1 + ], + "lastCredentialsRefreshedAt": [ + 4 + ], + "authFailedAt": [ + 4 + ], + "handleAliases": [ + 1 + ], + "scopes": [ + 1 + ], + "lastSignedInAt": [ + 4 + ], + "userWorkspaceId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "MessageChannel": { + "id": [ + 3 + ], + "visibility": [ + 331 + ], + "handle": [ + 1 + ], + "type": [ + 332 + ], + "isContactAutoCreationEnabled": [ + 6 + ], + "contactAutoCreationPolicy": [ + 333 + ], + "messageFolderImportPolicy": [ + 334 + ], + "excludeNonProfessionalEmails": [ + 6 + ], + "excludeGroupEmails": [ + 6 + ], + "pendingGroupEmailsAction": [ + 335 + ], + "isSyncEnabled": [ + 6 + ], + "syncedAt": [ + 4 + ], + "syncStatus": [ + 336 + ], + "syncStage": [ + 337 + ], + "syncStageStartedAt": [ + 4 + ], + "throttleFailureCount": [ + 11 + ], + "throttleRetryAfter": [ + 4 + ], + "connectedAccountId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "MessageChannelVisibility": {}, + "MessageChannelType": {}, + "MessageChannelContactAutoCreationPolicy": {}, + "MessageFolderImportPolicy": {}, + "MessageChannelPendingGroupEmailsAction": {}, + "MessageChannelSyncStatus": {}, + "MessageChannelSyncStage": {}, + "MessageFolder": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "isSentFolder": [ + 6 + ], + "isSynced": [ + 6 + ], + "parentFolderId": [ + 3 + ], + "externalId": [ + 1 + ], + "pendingSyncAction": [ + 339 + ], + "messageChannelId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "__typename": [ + 1 + ] + }, + "MessageFolderPendingSyncAction": {}, + "CollectionHash": { + "collectionName": [ + 341 + ], + "hash": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "AllMetadataName": {}, + "MinimalObjectMetadata": { + "id": [ + 3 + ], + "nameSingular": [ + 1 + ], + "namePlural": [ + 1 + ], + "labelSingular": [ + 1 + ], + "labelPlural": [ + 1 + ], + "icon": [ + 1 + ], + "color": [ + 1 + ], + "isCustom": [ + 6 + ], + "isActive": [ + 6 + ], + "isSystem": [ + 6 + ], + "isRemote": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "MinimalView": { + "id": [ + 3 + ], + "type": [ + 61 + ], + "key": [ + 62 + ], + "objectMetadataId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "MinimalMetadata": { + "objectMetadataItems": [ + 342 + ], + "views": [ + 343 + ], + "collectionHashes": [ + 340 + ], + "__typename": [ + 1 + ] + }, + "Webhook": { + "id": [ + 3 + ], + "targetUrl": [ + 1 + ], + "operations": [ + 1 + ], + "description": [ + 1 + ], + "secret": [ + 1 + ], + "applicationId": [ + 3 + ], + "createdAt": [ + 4 + ], + "updatedAt": [ + 4 + ], + "deletedAt": [ + 4 ], "__typename": [ 1 @@ -6119,10 +6122,10 @@ export default { }, "Query": { "navigationMenuItems": [ - 209 + 145 ], "navigationMenuItem": [ - 209, + 145, { "id": [ 3, @@ -6130,55 +6133,33 @@ export default { ] } ], - "getPageLayoutWidgets": [ - 75, + "getViewFilterGroups": [ + 52, { - "pageLayoutTabId": [ - 1, - "String!" - ] - } - ], - "getPageLayoutWidget": [ - 75, - { - "id": [ - 1, - "String!" - ] - } - ], - "getPageLayoutTabs": [ - 112, - { - "pageLayoutId": [ - 1, - "String!" - ] - } - ], - "getPageLayoutTab": [ - 112, - { - "id": [ - 1, - "String!" - ] - } - ], - "getPageLayouts": [ - 113, - { - "objectMetadataId": [ + "viewId": [ 1 - ], - "pageLayoutType": [ - 114 ] } ], - "getPageLayout": [ - 113, + "getViewFilterGroup": [ + 52, + { + "id": [ + 1, + "String!" + ] + } + ], + "getViewFilters": [ + 54, + { + "viewId": [ + 1 + ] + } + ], + "getViewFilter": [ + 54, { "id": [ 1, @@ -6242,11 +6223,118 @@ export default { ] } ], + "apiKeys": [ + 2 + ], + "apiKey": [ + 2, + { + "input": [ + 347, + "GetApiKeyInput!" + ] + } + ], + "enterprisePortalSession": [ + 1, + { + "returnUrlPath": [ + 1 + ] + } + ], + "enterpriseCheckoutSession": [ + 1, + { + "billingInterval": [ + 1 + ] + } + ], + "enterpriseSubscriptionStatus": [ + 138 + ], + "billingPortalSession": [ + 135, + { + "returnUrlPath": [ + 1 + ] + } + ], + "listPlans": [ + 134 + ], + "getMeteredProductsUsage": [ + 133 + ], + "findWorkspaceInvitations": [ + 142 + ], + "getApprovedAccessDomains": [ + 140 + ], + "getPageLayoutTabs": [ + 112, + { + "pageLayoutId": [ + 1, + "String!" + ] + } + ], + "getPageLayoutTab": [ + 112, + { + "id": [ + 1, + "String!" + ] + } + ], + "getPageLayouts": [ + 113, + { + "objectMetadataId": [ + 1 + ], + "pageLayoutType": [ + 114 + ] + } + ], + "getPageLayout": [ + 113, + { + "id": [ + 1, + "String!" + ] + } + ], + "getPageLayoutWidgets": [ + 75, + { + "pageLayoutTabId": [ + 1, + "String!" + ] + } + ], + "getPageLayoutWidget": [ + 75, + { + "id": [ + 1, + "String!" + ] + } + ], "findOneLogicFunction": [ 32, { "input": [ - 347, + 348, "LogicFunctionIdInput!" ] } @@ -6258,7 +6346,7 @@ export default { 15, { "input": [ - 347, + 348, "LogicFunctionIdInput!" ] } @@ -6267,16 +6355,16 @@ export default { 1, { "input": [ - 347, + 348, "LogicFunctionIdInput!" ] } ], "commandMenuItems": [ - 226 + 298 ], "commandMenuItem": [ - 226, + 298, { "id": [ 3, @@ -6285,10 +6373,10 @@ export default { } ], "frontComponents": [ - 225 + 297 ], "frontComponent": [ - 225, + 297, { "id": [ 3, @@ -6297,7 +6385,7 @@ export default { } ], "objectRecordCounts": [ - 169 + 237 ], "object": [ 46, @@ -6309,7 +6397,7 @@ export default { } ], "objects": [ - 170, + 238, { "paging": [ 39, @@ -6349,7 +6437,7 @@ export default { } ], "indexMetadatas": [ - 164, + 232, { "paging": [ 39, @@ -6368,67 +6456,16 @@ export default { 25, { "input": [ - 349, + 350, "AgentIdInput!" ] } ], - "billingPortalSession": [ - 135, - { - "returnUrlPath": [ - 1 - ] - } - ], - "listPlans": [ - 134 - ], - "getMeteredProductsUsage": [ - 133 - ], - "enterprisePortalSession": [ - 1, - { - "returnUrlPath": [ - 1 - ] - } - ], - "enterpriseCheckoutSession": [ - 1, - { - "billingInterval": [ - 1 - ] - } - ], - "enterpriseSubscriptionStatus": [ - 138 - ], "getRoles": [ 29 ], - "findWorkspaceInvitations": [ - 142 - ], - "getApprovedAccessDomains": [ - 140 - ], - "apiKeys": [ - 2 - ], - "apiKey": [ - 2, - { - "input": [ - 350, - "GetApiKeyInput!" - ] - } - ], "getToolIndex": [ - 221 + 301 ], "getToolInputSchema": [ 15, @@ -6449,7 +6486,7 @@ export default { } ], "fields": [ - 182, + 245, { "paging": [ 39, @@ -6478,56 +6515,187 @@ export default { ] } ], - "getViewFilters": [ - 54, + "myMessageFolders": [ + 338, { - "viewId": [ + "messageChannelId": [ + 3 + ] + } + ], + "myMessageChannels": [ + 330, + { + "connectedAccountId": [ + 3 + ] + } + ], + "myConnectedAccounts": [ + 329 + ], + "connectedAccounts": [ + 329 + ], + "myCalendarChannels": [ + 324, + { + "connectedAccountId": [ + 3 + ] + } + ], + "webhooks": [ + 345 + ], + "webhook": [ + 345, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "minimalMetadata": [ + 344 + ], + "chatThread": [ + 316, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "chatMessages": [ + 317, + { + "threadId": [ + 3, + "UUID!" + ] + } + ], + "getAISystemPromptPreview": [ + 319 + ], + "skills": [ + 315 + ], + "skill": [ + 315, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "chatThreads": [ + 321, + { + "paging": [ + 39, + "CursorPaging!" + ], + "filter": [ + 351, + "AgentChatThreadFilter!" + ], + "sorting": [ + 354, + "[AgentChatThreadSort!]!" + ] + } + ], + "agentTurns": [ + 323, + { + "agentId": [ + 3, + "UUID!" + ] + } + ], + "eventLogs": [ + 314, + { + "input": [ + 358, + "EventLogQueryInput!" + ] + } + ], + "pieChartData": [ + 310, + { + "input": [ + 362, + "PieChartDataInput!" + ] + } + ], + "lineChartData": [ + 308, + { + "input": [ + 363, + "LineChartDataInput!" + ] + } + ], + "barChartData": [ + 305, + { + "input": [ + 364, + "BarChartDataInput!" + ] + } + ], + "checkUserExists": [ + 264, + { + "email": [ + 1, + "String!" + ], + "captchaToken": [ 1 ] } ], - "getViewFilter": [ - 54, + "checkWorkspaceInviteHashIsValid": [ + 265, { - "id": [ + "inviteHash": [ 1, "String!" ] } ], - "getViewFilterGroups": [ - 52, + "findWorkspaceFromInviteHash": [ + 66, { - "viewId": [ - 1 - ] - } - ], - "getViewFilterGroup": [ - 52, - { - "id": [ + "inviteHash": [ 1, "String!" ] } ], - "currentUser": [ - 69 - ], - "currentWorkspace": [ - 66 - ], - "getPublicWorkspaceDataByDomain": [ - 161, + "validatePasswordResetToken": [ + 259, { - "origin": [ - 1 + "passwordResetToken": [ + 1, + "String!" ] } ], "findApplicationRegistrationByClientId": [ - 178, + 214, { "clientId": [ 1, @@ -6557,7 +6725,7 @@ export default { } ], "findApplicationRegistrationStats": [ - 176, + 212, { "id": [ 1, @@ -6583,190 +6751,25 @@ export default { ] } ], - "checkUserExists": [ - 206, + "currentUser": [ + 69 + ], + "currentWorkspace": [ + 66 + ], + "getPublicWorkspaceDataByDomain": [ + 163, { - "email": [ - 1, - "String!" - ], - "captchaToken": [ + "origin": [ 1 ] } ], - "checkWorkspaceInviteHashIsValid": [ - 207, - { - "inviteHash": [ - 1, - "String!" - ] - } - ], - "findWorkspaceFromInviteHash": [ - 66, - { - "inviteHash": [ - 1, - "String!" - ] - } - ], - "validatePasswordResetToken": [ - 201, - { - "passwordResetToken": [ - 1, - "String!" - ] - } - ], "getSSOIdentityProviders": [ - 186 - ], - "myMessageFolders": [ - 251, - { - "messageChannelId": [ - 3 - ] - } - ], - "myMessageChannels": [ - 243, - { - "connectedAccountId": [ - 3 - ] - } - ], - "myConnectedAccounts": [ - 242 - ], - "connectedAccounts": [ - 242 - ], - "myCalendarChannels": [ - 237, - { - "connectedAccountId": [ - 3 - ] - } - ], - "webhooks": [ - 258 - ], - "webhook": [ - 258, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "minimalMetadata": [ - 257 - ], - "chatThread": [ - 229, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "chatMessages": [ - 230, - { - "threadId": [ - 3, - "UUID!" - ] - } - ], - "getAISystemPromptPreview": [ - 232 - ], - "skills": [ - 223 - ], - "skill": [ - 223, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "chatThreads": [ - 234, - { - "paging": [ - 39, - "CursorPaging!" - ], - "filter": [ - 351, - "AgentChatThreadFilter!" - ], - "sorting": [ - 354, - "[AgentChatThreadSort!]!" - ] - } - ], - "agentTurns": [ - 236, - { - "agentId": [ - 3, - "UUID!" - ] - } - ], - "eventLogs": [ - 345, - { - "input": [ - 358, - "EventLogQueryInput!" - ] - } - ], - "pieChartData": [ - 341, - { - "input": [ - 362, - "PieChartDataInput!" - ] - } - ], - "lineChartData": [ - 339, - { - "input": [ - 363, - "LineChartDataInput!" - ] - } - ], - "barChartData": [ - 336, - { - "input": [ - 364, - "BarChartDataInput!" - ] - } + 220 ], "getConnectedImapSmtpCaldavAccount": [ - 331, + 289, { "id": [ 3, @@ -6775,7 +6778,7 @@ export default { } ], "getAutoCompleteAddress": [ - 326, + 284, { "address": [ 1, @@ -6794,7 +6797,7 @@ export default { } ], "getAddressDetails": [ - 328, + 286, { "placeId": [ 1, @@ -6807,40 +6810,40 @@ export default { } ], "getConfigVariablesGrouped": [ - 280 + 185 ], "getSystemHealthStatus": [ - 291 + 196 ], "getIndicatorHealthStatus": [ - 297, + 203, { "indicatorId": [ - 289, + 194, "HealthIndicatorId!" ] } ], "getQueueMetrics": [ - 303, + 209, { "queueName": [ 1, "String!" ], "timeRange": [ - 304 + 210 ] } ], "versionInfo": [ - 295 + 201 ], "getAdminAiModels": [ - 264 + 168 ], "getDatabaseConfigVariable": [ - 275, + 180, { "key": [ 1, @@ -6849,14 +6852,14 @@ export default { } ], "getQueueJobs": [ - 286, + 191, { "queueName": [ 1, "String!" ], "state": [ - 284, + 189, "JobState!" ], "limit": [ @@ -6874,10 +6877,10 @@ export default { 15 ], "getModelsDevProviders": [ - 299 + 205 ], "getModelsDevSuggestions": [ - 298, + 204, { "providerType": [ 1, @@ -6886,19 +6889,19 @@ export default { } ], "getPostgresCredentials": [ - 333 + 291 ], "findManyPublicDomains": [ - 321 + 279 ], "getEmailingDomains": [ - 323 + 281 ], "findManyMarketplaceApps": [ - 316 + 278 ], "findOneMarketplaceApp": [ - 316, + 278, { "universalIdentifier": [ 1, @@ -6921,7 +6924,7 @@ export default { } ], "getUsageAnalytics": [ - 320, + 295, { "input": [ 365 @@ -6932,16 +6935,7 @@ export default { 1 ] }, - "LogicFunctionIdInput": { - "id": [ - 348 - ], - "__typename": [ - 1 - ] - }, - "ID": {}, - "AgentIdInput": { + "GetApiKeyInput": { "id": [ 3 ], @@ -6949,7 +6943,16 @@ export default { 1 ] }, - "GetApiKeyInput": { + "LogicFunctionIdInput": { + "id": [ + 349 + ], + "__typename": [ + 1 + ] + }, + "ID": {}, + "AgentIdInput": { "id": [ 3 ], @@ -7159,7 +7162,7 @@ export default { } ], "createNavigationMenuItem": [ - 209, + 145, { "input": [ 369, @@ -7168,7 +7171,7 @@ export default { } ], "updateNavigationMenuItem": [ - 209, + 145, { "input": [ 370, @@ -7177,7 +7180,7 @@ export default { } ], "deleteNavigationMenuItem": [ - 209, + 145, { "id": [ 3, @@ -7247,147 +7250,79 @@ export default { ] } ], - "createObjectEvent": [ - 115, + "createViewFilterGroup": [ + 52, { - "event": [ + "input": [ + 373, + "CreateViewFilterGroupInput!" + ] + } + ], + "updateViewFilterGroup": [ + 52, + { + "id": [ 1, "String!" ], - "recordId": [ - 3, - "UUID!" - ], - "objectMetadataId": [ - 3, - "UUID!" - ], - "properties": [ - 15 - ] - } - ], - "trackAnalytics": [ - 115, - { - "type": [ - 373, - "AnalyticsType!" - ], - "name": [ - 1 - ], - "event": [ - 1 - ], - "properties": [ - 15 - ] - } - ], - "createPageLayoutWidget": [ - 75, - { "input": [ 374, - "CreatePageLayoutWidgetInput!" + "UpdateViewFilterGroupInput!" ] } ], - "updatePageLayoutWidget": [ - 75, + "deleteViewFilterGroup": [ + 6, { "id": [ 1, "String!" - ], + ] + } + ], + "destroyViewFilterGroup": [ + 6, + { + "id": [ + 1, + "String!" + ] + } + ], + "createViewFilter": [ + 54, + { + "input": [ + 375, + "CreateViewFilterInput!" + ] + } + ], + "updateViewFilter": [ + 54, + { "input": [ 376, - "UpdatePageLayoutWidgetInput!" + "UpdateViewFilterInput!" ] } ], - "destroyPageLayoutWidget": [ - 6, + "deleteViewFilter": [ + 54, { - "id": [ - 1, - "String!" - ] - } - ], - "createPageLayoutTab": [ - 112, - { - "input": [ - 377, - "CreatePageLayoutTabInput!" - ] - } - ], - "updatePageLayoutTab": [ - 112, - { - "id": [ - 1, - "String!" - ], "input": [ 378, - "UpdatePageLayoutTabInput!" + "DeleteViewFilterInput!" ] } ], - "destroyPageLayoutTab": [ - 6, - { - "id": [ - 1, - "String!" - ] - } - ], - "createPageLayout": [ - 113, + "destroyViewFilter": [ + 54, { "input": [ 379, - "CreatePageLayoutInput!" - ] - } - ], - "updatePageLayout": [ - 113, - { - "id": [ - 1, - "String!" - ], - "input": [ - 380, - "UpdatePageLayoutInput!" - ] - } - ], - "destroyPageLayout": [ - 6, - { - "id": [ - 1, - "String!" - ] - } - ], - "updatePageLayoutWithTabsAndWidgets": [ - 113, - { - "id": [ - 1, - "String!" - ], - "input": [ - 381, - "UpdatePageLayoutWithTabsInput!" + "DestroyViewFilterInput!" ] } ], @@ -7395,7 +7330,7 @@ export default { 60, { "input": [ - 384, + 380, "CreateViewInput!" ] } @@ -7408,7 +7343,7 @@ export default { "String!" ], "input": [ - 385, + 381, "UpdateViewInput!" ] } @@ -7435,7 +7370,7 @@ export default { 57, { "input": [ - 386, + 382, "CreateViewSortInput!" ] } @@ -7444,7 +7379,7 @@ export default { 57, { "input": [ - 387, + 383, "UpdateViewSortInput!" ] } @@ -7453,7 +7388,7 @@ export default { 6, { "input": [ - 389, + 385, "DeleteViewSortInput!" ] } @@ -7462,7 +7397,7 @@ export default { 6, { "input": [ - 390, + 386, "DestroyViewSortInput!" ] } @@ -7471,7 +7406,7 @@ export default { 59, { "input": [ - 391, + 387, "UpdateViewFieldGroupInput!" ] } @@ -7480,7 +7415,7 @@ export default { 59, { "input": [ - 393, + 389, "CreateViewFieldGroupInput!" ] } @@ -7489,7 +7424,7 @@ export default { 59, { "inputs": [ - 393, + 389, "[CreateViewFieldGroupInput!]!" ] } @@ -7498,7 +7433,7 @@ export default { 59, { "input": [ - 394, + 390, "DeleteViewFieldGroupInput!" ] } @@ -7507,7 +7442,7 @@ export default { 59, { "input": [ - 395, + 391, "DestroyViewFieldGroupInput!" ] } @@ -7516,199 +7451,106 @@ export default { 60, { "input": [ - 396, + 392, "UpsertFieldsWidgetInput!" ] } ], - "deleteOneLogicFunction": [ - 32, + "createApiKey": [ + 2, { "input": [ - 347, - "LogicFunctionIdInput!" + 395, + "CreateApiKeyInput!" ] } ], - "createOneLogicFunction": [ - 32, + "updateApiKey": [ + 2, { "input": [ - 399, - "CreateLogicFunctionFromSourceInput!" + 396, + "UpdateApiKeyInput!" ] } ], - "executeOneLogicFunction": [ - 218, + "revokeApiKey": [ + 2, { "input": [ - 400, - "ExecuteOneLogicFunctionInput!" + 397, + "RevokeApiKeyInput!" ] } ], - "updateOneLogicFunction": [ + "assignRoleToApiKey": [ 6, { - "input": [ - 401, - "UpdateLogicFunctionFromSourceInput!" - ] - } - ], - "createCommandMenuItem": [ - 226, - { - "input": [ - 403, - "CreateCommandMenuItemInput!" - ] - } - ], - "updateCommandMenuItem": [ - 226, - { - "input": [ - 404, - "UpdateCommandMenuItemInput!" - ] - } - ], - "deleteCommandMenuItem": [ - 226, - { - "id": [ + "apiKeyId": [ + 3, + "UUID!" + ], + "roleId": [ 3, "UUID!" ] } ], - "createFrontComponent": [ - 225, + "createObjectEvent": [ + 115, { - "input": [ - 405, - "CreateFrontComponentInput!" - ] - } - ], - "updateFrontComponent": [ - 225, - { - "input": [ - 406, - "UpdateFrontComponentInput!" - ] - } - ], - "deleteFrontComponent": [ - 225, - { - "id": [ + "event": [ + 1, + "String!" + ], + "recordId": [ 3, "UUID!" + ], + "objectMetadataId": [ + 3, + "UUID!" + ], + "properties": [ + 15 ] } ], - "createOneObject": [ - 46, + "trackAnalytics": [ + 115, { - "input": [ - 408, - "CreateOneObjectInput!" + "type": [ + 398, + "AnalyticsType!" + ], + "name": [ + 1 + ], + "event": [ + 1 + ], + "properties": [ + 15 ] } ], - "deleteOneObject": [ - 46, + "refreshEnterpriseValidityToken": [ + 6 + ], + "setEnterpriseKey": [ + 137, { - "input": [ - 410, - "DeleteOneObjectInput!" + "enterpriseKey": [ + 1, + "String!" ] } ], - "updateOneObject": [ - 46, - { - "input": [ - 411, - "UpdateOneObjectInput!" - ] - } + "skipSyncEmailOnboardingStep": [ + 139 ], - "updateViewField": [ - 50, - { - "input": [ - 413, - "UpdateViewFieldInput!" - ] - } - ], - "createViewField": [ - 50, - { - "input": [ - 415, - "CreateViewFieldInput!" - ] - } - ], - "createManyViewFields": [ - 50, - { - "inputs": [ - 415, - "[CreateViewFieldInput!]!" - ] - } - ], - "deleteViewField": [ - 50, - { - "input": [ - 416, - "DeleteViewFieldInput!" - ] - } - ], - "destroyViewField": [ - 50, - { - "input": [ - 417, - "DestroyViewFieldInput!" - ] - } - ], - "createOneAgent": [ - 25, - { - "input": [ - 418, - "CreateAgentInput!" - ] - } - ], - "updateOneAgent": [ - 25, - { - "input": [ - 419, - "UpdateAgentInput!" - ] - } - ], - "deleteOneAgent": [ - 25, - { - "input": [ - 349, - "AgentIdInput!" - ] - } + "skipBookOnboardingStep": [ + 139 ], "checkoutSession": [ 135, @@ -7757,122 +7599,6 @@ export default { "cancelSwitchMeteredPrice": [ 136 ], - "refreshEnterpriseValidityToken": [ - 6 - ], - "setEnterpriseKey": [ - 137, - { - "enterpriseKey": [ - 1, - "String!" - ] - } - ], - "updateWorkspaceMemberRole": [ - 20, - { - "workspaceMemberId": [ - 3, - "UUID!" - ], - "roleId": [ - 3, - "UUID!" - ] - } - ], - "createOneRole": [ - 29, - { - "createRoleInput": [ - 420, - "CreateRoleInput!" - ] - } - ], - "updateOneRole": [ - 29, - { - "updateRoleInput": [ - 421, - "UpdateRoleInput!" - ] - } - ], - "deleteOneRole": [ - 1, - { - "roleId": [ - 3, - "UUID!" - ] - } - ], - "upsertObjectPermissions": [ - 16, - { - "upsertObjectPermissionsInput": [ - 423, - "UpsertObjectPermissionsInput!" - ] - } - ], - "upsertPermissionFlags": [ - 27, - { - "upsertPermissionFlagsInput": [ - 425, - "UpsertPermissionFlagsInput!" - ] - } - ], - "upsertFieldPermissions": [ - 26, - { - "upsertFieldPermissionsInput": [ - 426, - "UpsertFieldPermissionsInput!" - ] - } - ], - "upsertRowLevelPermissionPredicates": [ - 174, - { - "input": [ - 428, - "UpsertRowLevelPermissionPredicatesInput!" - ] - } - ], - "assignRoleToAgent": [ - 6, - { - "agentId": [ - 3, - "UUID!" - ], - "roleId": [ - 3, - "UUID!" - ] - } - ], - "removeRoleFromAgent": [ - 6, - { - "agentId": [ - 3, - "UUID!" - ] - } - ], - "skipSyncEmailOnboardingStep": [ - 139 - ], - "skipBookOnboardingStep": [ - 139 - ], "deleteWorkspaceInvitation": [ 1, { @@ -7907,7 +7633,7 @@ export default { 140, { "input": [ - 431, + 399, "CreateApprovedAccessDomainInput!" ] } @@ -7916,7 +7642,7 @@ export default { 6, { "input": [ - 432, + 400, "DeleteApprovedAccessDomainInput!" ] } @@ -7925,42 +7651,310 @@ export default { 140, { "input": [ - 433, + 401, "ValidateApprovedAccessDomainInput!" ] } ], - "createApiKey": [ - 2, + "createPageLayoutTab": [ + 112, { "input": [ - 434, - "CreateApiKeyInput!" + 402, + "CreatePageLayoutTabInput!" ] } ], - "updateApiKey": [ - 2, + "updatePageLayoutTab": [ + 112, { + "id": [ + 1, + "String!" + ], "input": [ - 435, - "UpdateApiKeyInput!" + 403, + "UpdatePageLayoutTabInput!" ] } ], - "revokeApiKey": [ - 2, - { - "input": [ - 436, - "RevokeApiKeyInput!" - ] - } - ], - "assignRoleToApiKey": [ + "destroyPageLayoutTab": [ 6, { - "apiKeyId": [ + "id": [ + 1, + "String!" + ] + } + ], + "createPageLayout": [ + 113, + { + "input": [ + 404, + "CreatePageLayoutInput!" + ] + } + ], + "updatePageLayout": [ + 113, + { + "id": [ + 1, + "String!" + ], + "input": [ + 405, + "UpdatePageLayoutInput!" + ] + } + ], + "destroyPageLayout": [ + 6, + { + "id": [ + 1, + "String!" + ] + } + ], + "updatePageLayoutWithTabsAndWidgets": [ + 113, + { + "id": [ + 1, + "String!" + ], + "input": [ + 406, + "UpdatePageLayoutWithTabsInput!" + ] + } + ], + "createPageLayoutWidget": [ + 75, + { + "input": [ + 410, + "CreatePageLayoutWidgetInput!" + ] + } + ], + "updatePageLayoutWidget": [ + 75, + { + "id": [ + 1, + "String!" + ], + "input": [ + 411, + "UpdatePageLayoutWidgetInput!" + ] + } + ], + "destroyPageLayoutWidget": [ + 6, + { + "id": [ + 1, + "String!" + ] + } + ], + "deleteOneLogicFunction": [ + 32, + { + "input": [ + 348, + "LogicFunctionIdInput!" + ] + } + ], + "createOneLogicFunction": [ + 32, + { + "input": [ + 412, + "CreateLogicFunctionFromSourceInput!" + ] + } + ], + "executeOneLogicFunction": [ + 154, + { + "input": [ + 413, + "ExecuteOneLogicFunctionInput!" + ] + } + ], + "updateOneLogicFunction": [ + 6, + { + "input": [ + 414, + "UpdateLogicFunctionFromSourceInput!" + ] + } + ], + "createCommandMenuItem": [ + 298, + { + "input": [ + 416, + "CreateCommandMenuItemInput!" + ] + } + ], + "updateCommandMenuItem": [ + 298, + { + "input": [ + 417, + "UpdateCommandMenuItemInput!" + ] + } + ], + "deleteCommandMenuItem": [ + 298, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "createFrontComponent": [ + 297, + { + "input": [ + 418, + "CreateFrontComponentInput!" + ] + } + ], + "updateFrontComponent": [ + 297, + { + "input": [ + 419, + "UpdateFrontComponentInput!" + ] + } + ], + "deleteFrontComponent": [ + 297, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "createOneObject": [ + 46, + { + "input": [ + 421, + "CreateOneObjectInput!" + ] + } + ], + "deleteOneObject": [ + 46, + { + "input": [ + 423, + "DeleteOneObjectInput!" + ] + } + ], + "updateOneObject": [ + 46, + { + "input": [ + 424, + "UpdateOneObjectInput!" + ] + } + ], + "updateViewField": [ + 50, + { + "input": [ + 426, + "UpdateViewFieldInput!" + ] + } + ], + "createViewField": [ + 50, + { + "input": [ + 428, + "CreateViewFieldInput!" + ] + } + ], + "createManyViewFields": [ + 50, + { + "inputs": [ + 428, + "[CreateViewFieldInput!]!" + ] + } + ], + "deleteViewField": [ + 50, + { + "input": [ + 429, + "DeleteViewFieldInput!" + ] + } + ], + "destroyViewField": [ + 50, + { + "input": [ + 430, + "DestroyViewFieldInput!" + ] + } + ], + "createOneAgent": [ + 25, + { + "input": [ + 431, + "CreateAgentInput!" + ] + } + ], + "updateOneAgent": [ + 25, + { + "input": [ + 432, + "UpdateAgentInput!" + ] + } + ], + "deleteOneAgent": [ + 25, + { + "input": [ + 350, + "AgentIdInput!" + ] + } + ], + "updateWorkspaceMemberRole": [ + 20, + { + "workspaceMemberId": [ 3, "UUID!" ], @@ -7970,11 +7964,96 @@ export default { ] } ], + "createOneRole": [ + 29, + { + "createRoleInput": [ + 433, + "CreateRoleInput!" + ] + } + ], + "updateOneRole": [ + 29, + { + "updateRoleInput": [ + 434, + "UpdateRoleInput!" + ] + } + ], + "deleteOneRole": [ + 1, + { + "roleId": [ + 3, + "UUID!" + ] + } + ], + "upsertObjectPermissions": [ + 16, + { + "upsertObjectPermissionsInput": [ + 436, + "UpsertObjectPermissionsInput!" + ] + } + ], + "upsertPermissionFlags": [ + 27, + { + "upsertPermissionFlagsInput": [ + 438, + "UpsertPermissionFlagsInput!" + ] + } + ], + "upsertFieldPermissions": [ + 26, + { + "upsertFieldPermissionsInput": [ + 439, + "UpsertFieldPermissionsInput!" + ] + } + ], + "upsertRowLevelPermissionPredicates": [ + 242, + { + "input": [ + 441, + "UpsertRowLevelPermissionPredicatesInput!" + ] + } + ], + "assignRoleToAgent": [ + 6, + { + "agentId": [ + 3, + "UUID!" + ], + "roleId": [ + 3, + "UUID!" + ] + } + ], + "removeRoleFromAgent": [ + 6, + { + "agentId": [ + 3, + "UUID!" + ] + } + ], "createOneField": [ 34, { "input": [ - 437, + 444, "CreateOneFieldMetadataInput!" ] } @@ -7983,7 +8062,7 @@ export default { 34, { "input": [ - 439, + 446, "UpdateOneFieldMetadataInput!" ] } @@ -7992,7 +8071,7 @@ export default { 34, { "input": [ - 441, + 448, "DeleteOneFieldInput!" ] } @@ -8001,7 +8080,7 @@ export default { 56, { "input": [ - 442, + 449, "CreateViewGroupInput!" ] } @@ -8010,7 +8089,7 @@ export default { 56, { "inputs": [ - 442, + 449, "[CreateViewGroupInput!]!" ] } @@ -8019,7 +8098,7 @@ export default { 56, { "input": [ - 443, + 450, "UpdateViewGroupInput!" ] } @@ -8028,7 +8107,7 @@ export default { 56, { "input": [ - 445, + 452, "DeleteViewGroupInput!" ] } @@ -8037,153 +8116,421 @@ export default { 56, { "input": [ - 446, + 453, "DestroyViewGroupInput!" ] } ], - "createViewFilter": [ - 54, + "updateMessageFolder": [ + 338, { "input": [ - 447, - "CreateViewFilterInput!" + 454, + "UpdateMessageFolderInput!" ] } ], - "updateViewFilter": [ - 54, + "updateMessageFolders": [ + 338, { "input": [ - 448, - "UpdateViewFilterInput!" + 456, + "UpdateMessageFoldersInput!" ] } ], - "deleteViewFilter": [ - 54, + "updateMessageChannel": [ + 330, { "input": [ - 450, - "DeleteViewFilterInput!" + 457, + "UpdateMessageChannelInput!" ] } ], - "destroyViewFilter": [ - 54, - { - "input": [ - 451, - "DestroyViewFilterInput!" - ] - } - ], - "createViewFilterGroup": [ - 52, - { - "input": [ - 452, - "CreateViewFilterGroupInput!" - ] - } - ], - "updateViewFilterGroup": [ - 52, + "deleteConnectedAccount": [ + 329, { "id": [ + 3, + "UUID!" + ] + } + ], + "updateCalendarChannel": [ + 324, + { + "input": [ + 459, + "UpdateCalendarChannelInput!" + ] + } + ], + "createWebhook": [ + 345, + { + "input": [ + 461, + "CreateWebhookInput!" + ] + } + ], + "updateWebhook": [ + 345, + { + "input": [ + 462, + "UpdateWebhookInput!" + ] + } + ], + "deleteWebhook": [ + 345, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "createChatThread": [ + 316 + ], + "createSkill": [ + 315, + { + "input": [ + 464, + "CreateSkillInput!" + ] + } + ], + "updateSkill": [ + 315, + { + "input": [ + 465, + "UpdateSkillInput!" + ] + } + ], + "deleteSkill": [ + 315, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "activateSkill": [ + 315, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "deactivateSkill": [ + 315, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "evaluateAgentTurn": [ + 322, + { + "turnId": [ + 3, + "UUID!" + ] + } + ], + "runEvaluationInput": [ + 323, + { + "agentId": [ + 3, + "UUID!" + ], + "input": [ + 1, + "String!" + ] + } + ], + "duplicateDashboard": [ + 311, + { + "id": [ + 3, + "UUID!" + ] + } + ], + "getAuthorizationUrlForSSO": [ + 254, + { + "input": [ + 466, + "GetAuthorizationUrlForSSOInput!" + ] + } + ], + "getLoginTokenFromCredentials": [ + 263, + { + "email": [ 1, "String!" ], - "input": [ - 453, - "UpdateViewFilterGroupInput!" - ] - } - ], - "deleteViewFilterGroup": [ - 6, - { - "id": [ + "password": [ + 1, + "String!" + ], + "captchaToken": [ + 1 + ], + "locale": [ + 1 + ], + "verifyEmailRedirectPath": [ + 1 + ], + "origin": [ 1, "String!" ] } ], - "destroyViewFilterGroup": [ - 6, + "signIn": [ + 252, { - "id": [ + "email": [ 1, "String!" - ] - } - ], - "deleteUser": [ - 69 - ], - "deleteUserFromWorkspace": [ - 17, - { - "workspaceMemberIdToDelete": [ - 1, - "String!" - ] - } - ], - "updateUserEmail": [ - 6, - { - "newEmail": [ + ], + "password": [ 1, "String!" ], + "captchaToken": [ + 1 + ], + "locale": [ + 1 + ], "verifyEmailRedirectPath": [ 1 ] } ], - "resendEmailVerificationToken": [ - 144, + "verifyEmailAndGetLoginToken": [ + 260, + { + "emailVerificationToken": [ + 1, + "String!" + ], + "email": [ + 1, + "String!" + ], + "captchaToken": [ + 1 + ], + "origin": [ + 1, + "String!" + ] + } + ], + "verifyEmailAndGetWorkspaceAgnosticToken": [ + 252, + { + "emailVerificationToken": [ + 1, + "String!" + ], + "email": [ + 1, + "String!" + ], + "captchaToken": [ + 1 + ] + } + ], + "getAuthTokensFromOTP": [ + 262, + { + "otp": [ + 1, + "String!" + ], + "loginToken": [ + 1, + "String!" + ], + "captchaToken": [ + 1 + ], + "origin": [ + 1, + "String!" + ] + } + ], + "signUp": [ + 252, { "email": [ 1, "String!" ], + "password": [ + 1, + "String!" + ], + "captchaToken": [ + 1 + ], + "locale": [ + 1 + ], + "verifyEmailRedirectPath": [ + 1 + ] + } + ], + "signUpInWorkspace": [ + 257, + { + "email": [ + 1, + "String!" + ], + "password": [ + 1, + "String!" + ], + "workspaceId": [ + 3 + ], + "workspaceInviteHash": [ + 1 + ], + "workspacePersonalInviteToken": [ + 1 + ], + "captchaToken": [ + 1 + ], + "locale": [ + 1 + ], + "verifyEmailRedirectPath": [ + 1 + ] + } + ], + "signUpInNewWorkspace": [ + 257 + ], + "generateTransientToken": [ + 258 + ], + "getAuthTokensFromLoginToken": [ + 262, + { + "loginToken": [ + 1, + "String!" + ], "origin": [ 1, "String!" ] } ], - "activateWorkspace": [ - 66, + "authorizeApp": [ + 249, { - "data": [ - 454, - "ActivateWorkspaceInput!" + "clientId": [ + 1, + "String!" + ], + "codeChallenge": [ + 1 + ], + "redirectUrl": [ + 1, + "String!" + ], + "state": [ + 1 + ], + "scope": [ + 1 ] } ], - "updateWorkspace": [ - 66, + "renewToken": [ + 262, { - "data": [ - 455, - "UpdateWorkspaceInput!" + "appToken": [ + 1, + "String!" ] } ], - "deleteCurrentWorkspace": [ - 66 + "generateApiKeyToken": [ + 261, + { + "apiKeyId": [ + 3, + "UUID!" + ], + "expiresAt": [ + 1, + "String!" + ] + } ], - "checkCustomDomainValidRecords": [ - 155 + "emailPasswordResetLink": [ + 253, + { + "email": [ + 1, + "String!" + ], + "workspaceId": [ + 3 + ] + } + ], + "updatePasswordViaResetToken": [ + 255, + { + "passwordResetToken": [ + 1, + "String!" + ], + "newPassword": [ + 1, + "String!" + ] + } ], "createApplicationRegistration": [ - 177, + 213, { "input": [ - 456, + 467, "CreateApplicationRegistrationInput!" ] } @@ -8192,7 +8539,7 @@ export default { 7, { "input": [ - 457, + 468, "UpdateApplicationRegistrationInput!" ] } @@ -8207,7 +8554,7 @@ export default { } ], "rotateApplicationRegistrationClientSecret": [ - 179, + 215, { "id": [ 1, @@ -8219,7 +8566,7 @@ export default { 5, { "input": [ - 459, + 470, "CreateApplicationRegistrationVariableInput!" ] } @@ -8228,7 +8575,7 @@ export default { 5, { "input": [ - 460, + 471, "UpdateApplicationRegistrationVariableInput!" ] } @@ -8267,262 +8614,8 @@ export default { ] } ], - "getAuthorizationUrlForSSO": [ - 196, - { - "input": [ - 462, - "GetAuthorizationUrlForSSOInput!" - ] - } - ], - "getLoginTokenFromCredentials": [ - 205, - { - "email": [ - 1, - "String!" - ], - "password": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ], - "locale": [ - 1 - ], - "verifyEmailRedirectPath": [ - 1 - ], - "origin": [ - 1, - "String!" - ] - } - ], - "signIn": [ - 194, - { - "email": [ - 1, - "String!" - ], - "password": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ], - "locale": [ - 1 - ], - "verifyEmailRedirectPath": [ - 1 - ] - } - ], - "verifyEmailAndGetLoginToken": [ - 202, - { - "emailVerificationToken": [ - 1, - "String!" - ], - "email": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ], - "origin": [ - 1, - "String!" - ] - } - ], - "verifyEmailAndGetWorkspaceAgnosticToken": [ - 194, - { - "emailVerificationToken": [ - 1, - "String!" - ], - "email": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ] - } - ], - "getAuthTokensFromOTP": [ - 204, - { - "otp": [ - 1, - "String!" - ], - "loginToken": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ], - "origin": [ - 1, - "String!" - ] - } - ], - "signUp": [ - 194, - { - "email": [ - 1, - "String!" - ], - "password": [ - 1, - "String!" - ], - "captchaToken": [ - 1 - ], - "locale": [ - 1 - ], - "verifyEmailRedirectPath": [ - 1 - ] - } - ], - "signUpInWorkspace": [ - 199, - { - "email": [ - 1, - "String!" - ], - "password": [ - 1, - "String!" - ], - "workspaceId": [ - 3 - ], - "workspaceInviteHash": [ - 1 - ], - "workspacePersonalInviteToken": [ - 1 - ], - "captchaToken": [ - 1 - ], - "locale": [ - 1 - ], - "verifyEmailRedirectPath": [ - 1 - ] - } - ], - "signUpInNewWorkspace": [ - 199 - ], - "generateTransientToken": [ - 200 - ], - "getAuthTokensFromLoginToken": [ - 204, - { - "loginToken": [ - 1, - "String!" - ], - "origin": [ - 1, - "String!" - ] - } - ], - "authorizeApp": [ - 191, - { - "clientId": [ - 1, - "String!" - ], - "codeChallenge": [ - 1 - ], - "redirectUrl": [ - 1, - "String!" - ], - "state": [ - 1 - ], - "scope": [ - 1 - ] - } - ], - "renewToken": [ - 204, - { - "appToken": [ - 1, - "String!" - ] - } - ], - "generateApiKeyToken": [ - 203, - { - "apiKeyId": [ - 3, - "UUID!" - ], - "expiresAt": [ - 1, - "String!" - ] - } - ], - "emailPasswordResetLink": [ - 195, - { - "email": [ - 1, - "String!" - ], - "workspaceId": [ - 3 - ] - } - ], - "updatePasswordViaResetToken": [ - 197, - { - "passwordResetToken": [ - 1, - "String!" - ], - "newPassword": [ - 1, - "String!" - ] - } - ], "initiateOTPProvisioning": [ - 189, + 247, { "loginToken": [ 1, @@ -8535,10 +8628,10 @@ export default { } ], "initiateOTPProvisioningForAuthenticatedUser": [ - 189 + 247 ], "deleteTwoFactorAuthenticationMethod": [ - 188, + 246, { "twoFactorAuthenticationMethodId": [ 3, @@ -8547,7 +8640,7 @@ export default { } ], "verifyTwoFactorAuthenticationMethodForAuthenticatedUser": [ - 190, + 248, { "otp": [ 1, @@ -8555,195 +8648,105 @@ export default { ] } ], - "createOIDCIdentityProvider": [ - 187, - { - "input": [ - 463, - "SetupOIDCSsoInput!" - ] - } + "deleteUser": [ + 69 ], - "createSAMLIdentityProvider": [ - 187, + "deleteUserFromWorkspace": [ + 17, { - "input": [ - 464, - "SetupSAMLSsoInput!" - ] - } - ], - "deleteSSOIdentityProvider": [ - 183, - { - "input": [ - 465, - "DeleteSsoInput!" - ] - } - ], - "editSSOIdentityProvider": [ - 184, - { - "input": [ - 466, - "EditSsoInput!" - ] - } - ], - "updateMessageFolder": [ - 251, - { - "input": [ - 467, - "UpdateMessageFolderInput!" - ] - } - ], - "updateMessageFolders": [ - 251, - { - "input": [ - 469, - "UpdateMessageFoldersInput!" - ] - } - ], - "updateMessageChannel": [ - 243, - { - "input": [ - 470, - "UpdateMessageChannelInput!" - ] - } - ], - "deleteConnectedAccount": [ - 242, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "updateCalendarChannel": [ - 237, - { - "input": [ - 472, - "UpdateCalendarChannelInput!" - ] - } - ], - "createWebhook": [ - 258, - { - "input": [ - 474, - "CreateWebhookInput!" - ] - } - ], - "updateWebhook": [ - 258, - { - "input": [ - 475, - "UpdateWebhookInput!" - ] - } - ], - "deleteWebhook": [ - 258, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "createChatThread": [ - 229 - ], - "createSkill": [ - 223, - { - "input": [ - 477, - "CreateSkillInput!" - ] - } - ], - "updateSkill": [ - 223, - { - "input": [ - 478, - "UpdateSkillInput!" - ] - } - ], - "deleteSkill": [ - 223, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "activateSkill": [ - 223, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "deactivateSkill": [ - 223, - { - "id": [ - 3, - "UUID!" - ] - } - ], - "evaluateAgentTurn": [ - 235, - { - "turnId": [ - 3, - "UUID!" - ] - } - ], - "runEvaluationInput": [ - 236, - { - "agentId": [ - 3, - "UUID!" - ], - "input": [ + "workspaceMemberIdToDelete": [ 1, "String!" ] } ], - "duplicateDashboard": [ - 342, + "updateUserEmail": [ + 6, { - "id": [ - 3, - "UUID!" + "newEmail": [ + 1, + "String!" + ], + "verifyEmailRedirectPath": [ + 1 + ] + } + ], + "resendEmailVerificationToken": [ + 216, + { + "email": [ + 1, + "String!" + ], + "origin": [ + 1, + "String!" + ] + } + ], + "activateWorkspace": [ + 66, + { + "data": [ + 473, + "ActivateWorkspaceInput!" + ] + } + ], + "updateWorkspace": [ + 66, + { + "data": [ + 474, + "UpdateWorkspaceInput!" + ] + } + ], + "deleteCurrentWorkspace": [ + 66 + ], + "checkCustomDomainValidRecords": [ + 229 + ], + "createOIDCIdentityProvider": [ + 221, + { + "input": [ + 475, + "SetupOIDCSsoInput!" + ] + } + ], + "createSAMLIdentityProvider": [ + 221, + { + "input": [ + 476, + "SetupSAMLSsoInput!" + ] + } + ], + "deleteSSOIdentityProvider": [ + 217, + { + "input": [ + 477, + "DeleteSsoInput!" + ] + } + ], + "editSSOIdentityProvider": [ + 218, + { + "input": [ + 478, + "EditSsoInput!" ] } ], "impersonate": [ - 305, + 266, { "userId": [ 3, @@ -8756,7 +8759,7 @@ export default { } ], "startChannelSync": [ - 334, + 303, { "connectedAccountId": [ 3, @@ -8765,7 +8768,7 @@ export default { } ], "saveImapSmtpCaldavAccount": [ - 332, + 290, { "accountOwnerId": [ 3, @@ -8785,7 +8788,7 @@ export default { } ], "updateLabPublicFeatureFlag": [ - 156, + 197, { "input": [ 481, @@ -8794,7 +8797,7 @@ export default { } ], "userLookupAdminPanel": [ - 294, + 200, { "userIdentifier": [ 1, @@ -8894,7 +8897,7 @@ export default { } ], "retryJobs": [ - 287, + 192, { "queueName": [ 1, @@ -8907,7 +8910,7 @@ export default { } ], "deleteJobs": [ - 282, + 187, { "queueName": [ 1, @@ -8968,13 +8971,13 @@ export default { } ], "enablePostgresProxy": [ - 333 + 291 ], "disablePostgresProxy": [ - 333 + 291 ], "createPublicDomain": [ - 321, + 279, { "domain": [ 1, @@ -8992,7 +8995,7 @@ export default { } ], "checkPublicDomainValidRecords": [ - 155, + 229, { "domain": [ 1, @@ -9001,14 +9004,14 @@ export default { } ], "createEmailingDomain": [ - 323, + 281, { "domain": [ 1, "String!" ], "driver": [ - 324, + 282, "EmailingDomainDriver!" ] } @@ -9023,7 +9026,7 @@ export default { } ], "verifyEmailingDomain": [ - 323, + 281, { "id": [ 1, @@ -9100,7 +9103,7 @@ export default { } ], "createDevelopmentApplication": [ - 306, + 267, { "universalIdentifier": [ 1, @@ -9113,7 +9116,7 @@ export default { } ], "generateApplicationToken": [ - 224, + 269, { "applicationId": [ 3, @@ -9122,7 +9125,7 @@ export default { } ], "syncApplication": [ - 307, + 268, { "manifest": [ 15, @@ -9131,7 +9134,7 @@ export default { } ], "uploadApplicationFile": [ - 308, + 270, { "file": [ 372, @@ -9165,7 +9168,7 @@ export default { } ], "renewApplicationToken": [ - 224, + 269, { "applicationRefreshToken": [ 1, @@ -9219,7 +9222,7 @@ export default { 3 ], "type": [ - 210 + 146 ], "name": [ 1 @@ -9278,205 +9281,120 @@ export default { ] }, "Upload": {}, - "AnalyticsType": {}, - "CreatePageLayoutWidgetInput": { - "pageLayoutTabId": [ - 3 - ], - "title": [ - 1 - ], - "type": [ - 76 - ], - "objectMetadataId": [ - 3 - ], - "gridPosition": [ - 375 - ], - "position": [ - 15 - ], - "configuration": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "GridPositionInput": { - "row": [ - 11 - ], - "column": [ - 11 - ], - "rowSpan": [ - 11 - ], - "columnSpan": [ - 11 - ], - "__typename": [ - 1 - ] - }, - "UpdatePageLayoutWidgetInput": { - "title": [ - 1 - ], - "type": [ - 76 - ], - "objectMetadataId": [ - 3 - ], - "gridPosition": [ - 375 - ], - "position": [ - 15 - ], - "configuration": [ - 15 - ], - "conditionalDisplay": [ - 15 - ], - "__typename": [ - 1 - ] - }, - "CreatePageLayoutTabInput": { - "title": [ - 1 - ], - "position": [ - 11 - ], - "pageLayoutId": [ - 3 - ], - "layoutMode": [ - 79 - ], - "__typename": [ - 1 - ] - }, - "UpdatePageLayoutTabInput": { - "title": [ - 1 - ], - "position": [ - 11 - ], - "icon": [ - 1 - ], - "layoutMode": [ - 79 - ], - "__typename": [ - 1 - ] - }, - "CreatePageLayoutInput": { - "name": [ - 1 - ], - "type": [ - 114 - ], - "objectMetadataId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "UpdatePageLayoutInput": { - "name": [ - 1 - ], - "type": [ - 114 - ], - "objectMetadataId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "UpdatePageLayoutWithTabsInput": { - "name": [ - 1 - ], - "type": [ - 114 - ], - "objectMetadataId": [ - 3 - ], - "tabs": [ - 382 - ], - "__typename": [ - 1 - ] - }, - "UpdatePageLayoutTabWithWidgetsInput": { + "CreateViewFilterGroupInput": { "id": [ 3 ], - "title": [ - 1 + "parentViewFilterGroupId": [ + 3 ], - "position": [ + "logicalOperator": [ + 53 + ], + "positionInViewFilterGroup": [ 11 ], - "icon": [ - 1 - ], - "layoutMode": [ - 79 - ], - "widgets": [ - 383 + "viewId": [ + 3 ], "__typename": [ 1 ] }, - "UpdatePageLayoutWidgetWithIdInput": { + "UpdateViewFilterGroupInput": { "id": [ 3 ], - "pageLayoutTabId": [ + "parentViewFilterGroupId": [ 3 ], - "title": [ + "logicalOperator": [ + 53 + ], + "positionInViewFilterGroup": [ + 11 + ], + "viewId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "CreateViewFilterInput": { + "id": [ + 3 + ], + "fieldMetadataId": [ + 3 + ], + "operand": [ + 55 + ], + "value": [ + 15 + ], + "viewFilterGroupId": [ + 3 + ], + "positionInViewFilterGroup": [ + 11 + ], + "subFieldName": [ 1 ], - "type": [ - 76 - ], - "objectMetadataId": [ + "viewId": [ 3 ], - "gridPosition": [ - 375 + "__typename": [ + 1 + ] + }, + "UpdateViewFilterInput": { + "id": [ + 3 ], - "position": [ + "update": [ + 377 + ], + "__typename": [ + 1 + ] + }, + "UpdateViewFilterInputUpdates": { + "fieldMetadataId": [ + 3 + ], + "operand": [ + 55 + ], + "value": [ 15 ], - "configuration": [ - 15 + "viewFilterGroupId": [ + 3 ], - "conditionalDisplay": [ - 15 + "positionInViewFilterGroup": [ + 11 + ], + "subFieldName": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "DeleteViewFilterInput": { + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "DestroyViewFilterInput": { + "id": [ + 3 ], "__typename": [ 1 @@ -9610,7 +9528,7 @@ export default { 3 ], "update": [ - 388 + 384 ], "__typename": [ 1 @@ -9645,7 +9563,7 @@ export default { 3 ], "update": [ - 392 + 388 ], "__typename": [ 1 @@ -9709,10 +9627,10 @@ export default { 3 ], "groups": [ - 397 + 393 ], "fields": [ - 398 + 394 ], "__typename": [ 1 @@ -9732,7 +9650,7 @@ export default { 6 ], "fields": [ - 398 + 394 ], "__typename": [ 1 @@ -9752,6 +9670,282 @@ export default { 1 ] }, + "CreateApiKeyInput": { + "name": [ + 1 + ], + "expiresAt": [ + 1 + ], + "revokedAt": [ + 1 + ], + "roleId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "UpdateApiKeyInput": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "expiresAt": [ + 1 + ], + "revokedAt": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "RevokeApiKeyInput": { + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "AnalyticsType": {}, + "CreateApprovedAccessDomainInput": { + "domain": [ + 1 + ], + "email": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "DeleteApprovedAccessDomainInput": { + "id": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "ValidateApprovedAccessDomainInput": { + "validationToken": [ + 1 + ], + "approvedAccessDomainId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "CreatePageLayoutTabInput": { + "title": [ + 1 + ], + "position": [ + 11 + ], + "pageLayoutId": [ + 3 + ], + "layoutMode": [ + 79 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutTabInput": { + "title": [ + 1 + ], + "position": [ + 11 + ], + "icon": [ + 1 + ], + "layoutMode": [ + 79 + ], + "__typename": [ + 1 + ] + }, + "CreatePageLayoutInput": { + "name": [ + 1 + ], + "type": [ + 114 + ], + "objectMetadataId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutInput": { + "name": [ + 1 + ], + "type": [ + 114 + ], + "objectMetadataId": [ + 3 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutWithTabsInput": { + "name": [ + 1 + ], + "type": [ + 114 + ], + "objectMetadataId": [ + 3 + ], + "tabs": [ + 407 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutTabWithWidgetsInput": { + "id": [ + 3 + ], + "title": [ + 1 + ], + "position": [ + 11 + ], + "icon": [ + 1 + ], + "layoutMode": [ + 79 + ], + "widgets": [ + 408 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutWidgetWithIdInput": { + "id": [ + 3 + ], + "pageLayoutTabId": [ + 3 + ], + "title": [ + 1 + ], + "type": [ + 76 + ], + "objectMetadataId": [ + 3 + ], + "gridPosition": [ + 409 + ], + "position": [ + 15 + ], + "configuration": [ + 15 + ], + "conditionalDisplay": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "GridPositionInput": { + "row": [ + 11 + ], + "column": [ + 11 + ], + "rowSpan": [ + 11 + ], + "columnSpan": [ + 11 + ], + "__typename": [ + 1 + ] + }, + "CreatePageLayoutWidgetInput": { + "pageLayoutTabId": [ + 3 + ], + "title": [ + 1 + ], + "type": [ + 76 + ], + "objectMetadataId": [ + 3 + ], + "gridPosition": [ + 409 + ], + "position": [ + 15 + ], + "configuration": [ + 15 + ], + "__typename": [ + 1 + ] + }, + "UpdatePageLayoutWidgetInput": { + "title": [ + 1 + ], + "type": [ + 76 + ], + "objectMetadataId": [ + 3 + ], + "gridPosition": [ + 409 + ], + "position": [ + 15 + ], + "configuration": [ + 15 + ], + "conditionalDisplay": [ + 15 + ], + "__typename": [ + 1 + ] + }, "CreateLogicFunctionFromSourceInput": { "id": [ 3 @@ -9806,7 +10000,7 @@ export default { 3 ], "update": [ - 402 + 415 ], "__typename": [ 1 @@ -9858,7 +10052,7 @@ export default { 3 ], "engineComponentKey": [ - 227 + 299 ], "label": [ 1 @@ -9876,7 +10070,7 @@ export default { 6 ], "availabilityType": [ - 228 + 300 ], "hotKeys": [ 1 @@ -9911,13 +10105,13 @@ export default { 6 ], "availabilityType": [ - 228 + 300 ], "availabilityObjectMetadataId": [ 3 ], "engineComponentKey": [ - 227 + 299 ], "hotKeys": [ 1 @@ -9957,7 +10151,7 @@ export default { 3 ], "update": [ - 407 + 420 ], "__typename": [ 1 @@ -9976,7 +10170,7 @@ export default { }, "CreateOneObjectInput": { "object": [ - 409 + 422 ], "__typename": [ 1 @@ -10036,7 +10230,7 @@ export default { }, "UpdateOneObjectInput": { "update": [ - 412 + 425 ], "id": [ 3 @@ -10091,7 +10285,7 @@ export default { 3 ], "update": [ - 414 + 427 ], "__typename": [ 1 @@ -10281,7 +10475,7 @@ export default { }, "UpdateRoleInput": { "update": [ - 422 + 435 ], "id": [ 3 @@ -10336,7 +10530,7 @@ export default { 3 ], "objectPermissions": [ - 424 + 437 ], "__typename": [ 1 @@ -10378,7 +10572,7 @@ export default { 3 ], "fieldPermissions": [ - 427 + 440 ], "__typename": [ 1 @@ -10409,10 +10603,10 @@ export default { 3 ], "predicates": [ - 429 + 442 ], "predicateGroups": [ - 430 + 443 ], "__typename": [ 1 @@ -10470,81 +10664,9 @@ export default { 1 ] }, - "CreateApprovedAccessDomainInput": { - "domain": [ - 1 - ], - "email": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "DeleteApprovedAccessDomainInput": { - "id": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "ValidateApprovedAccessDomainInput": { - "validationToken": [ - 1 - ], - "approvedAccessDomainId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "CreateApiKeyInput": { - "name": [ - 1 - ], - "expiresAt": [ - 1 - ], - "revokedAt": [ - 1 - ], - "roleId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "UpdateApiKeyInput": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "expiresAt": [ - 1 - ], - "revokedAt": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "RevokeApiKeyInput": { - "id": [ - 3 - ], - "__typename": [ - 1 - ] - }, "CreateOneFieldMetadataInput": { "field": [ - 438 + 445 ], "__typename": [ 1 @@ -10617,7 +10739,7 @@ export default { 3 ], "update": [ - 440 + 447 ], "__typename": [ 1 @@ -10706,7 +10828,7 @@ export default { 3 ], "update": [ - 444 + 451 ], "__typename": [ 1 @@ -10745,120 +10867,321 @@ export default { 1 ] }, - "CreateViewFilterInput": { - "id": [ - 3 - ], - "fieldMetadataId": [ - 3 - ], - "operand": [ - 55 - ], - "value": [ - 15 - ], - "viewFilterGroupId": [ - 3 - ], - "positionInViewFilterGroup": [ - 11 - ], - "subFieldName": [ - 1 - ], - "viewId": [ - 3 - ], - "__typename": [ - 1 - ] - }, - "UpdateViewFilterInput": { + "UpdateMessageFolderInput": { "id": [ 3 ], "update": [ - 449 + 455 ], "__typename": [ 1 ] }, - "UpdateViewFilterInputUpdates": { - "fieldMetadataId": [ + "UpdateMessageFolderInputUpdates": { + "isSynced": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "UpdateMessageFoldersInput": { + "ids": [ 3 ], - "operand": [ - 55 + "update": [ + 455 + ], + "__typename": [ + 1 + ] + }, + "UpdateMessageChannelInput": { + "id": [ + 3 + ], + "update": [ + 458 + ], + "__typename": [ + 1 + ] + }, + "UpdateMessageChannelInputUpdates": { + "visibility": [ + 331 + ], + "isContactAutoCreationEnabled": [ + 6 + ], + "contactAutoCreationPolicy": [ + 333 + ], + "messageFolderImportPolicy": [ + 334 + ], + "isSyncEnabled": [ + 6 + ], + "excludeNonProfessionalEmails": [ + 6 + ], + "excludeGroupEmails": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "UpdateCalendarChannelInput": { + "id": [ + 3 + ], + "update": [ + 460 + ], + "__typename": [ + 1 + ] + }, + "UpdateCalendarChannelInputUpdates": { + "visibility": [ + 327 + ], + "isContactAutoCreationEnabled": [ + 6 + ], + "contactAutoCreationPolicy": [ + 328 + ], + "isSyncEnabled": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "CreateWebhookInput": { + "id": [ + 3 + ], + "targetUrl": [ + 1 + ], + "operations": [ + 1 + ], + "description": [ + 1 + ], + "secret": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "UpdateWebhookInput": { + "id": [ + 3 + ], + "update": [ + 463 + ], + "__typename": [ + 1 + ] + }, + "UpdateWebhookInputUpdates": { + "targetUrl": [ + 1 + ], + "operations": [ + 1 + ], + "description": [ + 1 + ], + "secret": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "CreateSkillInput": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "label": [ + 1 + ], + "icon": [ + 1 + ], + "description": [ + 1 + ], + "content": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "UpdateSkillInput": { + "id": [ + 3 + ], + "name": [ + 1 + ], + "label": [ + 1 + ], + "icon": [ + 1 + ], + "description": [ + 1 + ], + "content": [ + 1 + ], + "isActive": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "GetAuthorizationUrlForSSOInput": { + "identityProviderId": [ + 3 + ], + "workspaceInviteHash": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "CreateApplicationRegistrationInput": { + "name": [ + 1 + ], + "description": [ + 1 + ], + "logoUrl": [ + 1 + ], + "author": [ + 1 + ], + "universalIdentifier": [ + 1 + ], + "oAuthRedirectUris": [ + 1 + ], + "oAuthScopes": [ + 1 + ], + "websiteUrl": [ + 1 + ], + "termsUrl": [ + 1 + ], + "__typename": [ + 1 + ] + }, + "UpdateApplicationRegistrationInput": { + "id": [ + 1 + ], + "update": [ + 469 + ], + "__typename": [ + 1 + ] + }, + "UpdateApplicationRegistrationPayload": { + "name": [ + 1 + ], + "description": [ + 1 + ], + "logoUrl": [ + 1 + ], + "author": [ + 1 + ], + "oAuthRedirectUris": [ + 1 + ], + "oAuthScopes": [ + 1 + ], + "websiteUrl": [ + 1 + ], + "termsUrl": [ + 1 + ], + "isListed": [ + 6 + ], + "__typename": [ + 1 + ] + }, + "CreateApplicationRegistrationVariableInput": { + "applicationRegistrationId": [ + 1 + ], + "key": [ + 1 ], "value": [ - 15 - ], - "viewFilterGroupId": [ - 3 - ], - "positionInViewFilterGroup": [ - 11 - ], - "subFieldName": [ 1 ], + "description": [ + 1 + ], + "isSecret": [ + 6 + ], "__typename": [ 1 ] }, - "DeleteViewFilterInput": { + "UpdateApplicationRegistrationVariableInput": { "id": [ - 3 + 1 + ], + "update": [ + 472 ], "__typename": [ 1 ] }, - "DestroyViewFilterInput": { - "id": [ - 3 - ], - "__typename": [ + "UpdateApplicationRegistrationVariablePayload": { + "value": [ 1 - ] - }, - "CreateViewFilterGroupInput": { - "id": [ - 3 ], - "parentViewFilterGroupId": [ - 3 - ], - "logicalOperator": [ - 53 - ], - "positionInViewFilterGroup": [ - 11 - ], - "viewId": [ - 3 - ], - "__typename": [ + "description": [ 1 - ] - }, - "UpdateViewFilterGroupInput": { - "id": [ - 3 - ], - "parentViewFilterGroupId": [ - 3 - ], - "logicalOperator": [ - 53 - ], - "positionInViewFilterGroup": [ - 11 - ], - "viewId": [ - 3 ], "__typename": [ 1 @@ -10946,134 +11269,6 @@ export default { 1 ] }, - "CreateApplicationRegistrationInput": { - "name": [ - 1 - ], - "description": [ - 1 - ], - "logoUrl": [ - 1 - ], - "author": [ - 1 - ], - "universalIdentifier": [ - 1 - ], - "oAuthRedirectUris": [ - 1 - ], - "oAuthScopes": [ - 1 - ], - "websiteUrl": [ - 1 - ], - "termsUrl": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "UpdateApplicationRegistrationInput": { - "id": [ - 1 - ], - "update": [ - 458 - ], - "__typename": [ - 1 - ] - }, - "UpdateApplicationRegistrationPayload": { - "name": [ - 1 - ], - "description": [ - 1 - ], - "logoUrl": [ - 1 - ], - "author": [ - 1 - ], - "oAuthRedirectUris": [ - 1 - ], - "oAuthScopes": [ - 1 - ], - "websiteUrl": [ - 1 - ], - "termsUrl": [ - 1 - ], - "isListed": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "CreateApplicationRegistrationVariableInput": { - "applicationRegistrationId": [ - 1 - ], - "key": [ - 1 - ], - "value": [ - 1 - ], - "description": [ - 1 - ], - "isSecret": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "UpdateApplicationRegistrationVariableInput": { - "id": [ - 1 - ], - "update": [ - 461 - ], - "__typename": [ - 1 - ] - }, - "UpdateApplicationRegistrationVariablePayload": { - "value": [ - 1 - ], - "description": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "GetAuthorizationUrlForSSOInput": { - "identityProviderId": [ - 3 - ], - "workspaceInviteHash": [ - 1 - ], - "__typename": [ - 1 - ] - }, "SetupOIDCSsoInput": { "name": [ 1 @@ -11127,199 +11322,7 @@ export default { 3 ], "status": [ - 148 - ], - "__typename": [ - 1 - ] - }, - "UpdateMessageFolderInput": { - "id": [ - 3 - ], - "update": [ - 468 - ], - "__typename": [ - 1 - ] - }, - "UpdateMessageFolderInputUpdates": { - "isSynced": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "UpdateMessageFoldersInput": { - "ids": [ - 3 - ], - "update": [ - 468 - ], - "__typename": [ - 1 - ] - }, - "UpdateMessageChannelInput": { - "id": [ - 3 - ], - "update": [ - 471 - ], - "__typename": [ - 1 - ] - }, - "UpdateMessageChannelInputUpdates": { - "visibility": [ - 244 - ], - "isContactAutoCreationEnabled": [ - 6 - ], - "contactAutoCreationPolicy": [ - 246 - ], - "messageFolderImportPolicy": [ - 247 - ], - "isSyncEnabled": [ - 6 - ], - "excludeNonProfessionalEmails": [ - 6 - ], - "excludeGroupEmails": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "UpdateCalendarChannelInput": { - "id": [ - 3 - ], - "update": [ - 473 - ], - "__typename": [ - 1 - ] - }, - "UpdateCalendarChannelInputUpdates": { - "visibility": [ - 240 - ], - "isContactAutoCreationEnabled": [ - 6 - ], - "contactAutoCreationPolicy": [ - 241 - ], - "isSyncEnabled": [ - 6 - ], - "__typename": [ - 1 - ] - }, - "CreateWebhookInput": { - "id": [ - 3 - ], - "targetUrl": [ - 1 - ], - "operations": [ - 1 - ], - "description": [ - 1 - ], - "secret": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "UpdateWebhookInput": { - "id": [ - 3 - ], - "update": [ - 476 - ], - "__typename": [ - 1 - ] - }, - "UpdateWebhookInputUpdates": { - "targetUrl": [ - 1 - ], - "operations": [ - 1 - ], - "description": [ - 1 - ], - "secret": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "CreateSkillInput": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "label": [ - 1 - ], - "icon": [ - 1 - ], - "description": [ - 1 - ], - "content": [ - 1 - ], - "__typename": [ - 1 - ] - }, - "UpdateSkillInput": { - "id": [ - 3 - ], - "name": [ - 1 - ], - "label": [ - 1 - ], - "icon": [ - 1 - ], - "description": [ - 1 - ], - "content": [ - 1 - ], - "isActive": [ - 6 + 160 ], "__typename": [ 1 @@ -11400,7 +11403,7 @@ export default { 487 ], "metadataName": [ - 254 + 341 ], "universalIdentifier": [ 1 @@ -11413,7 +11416,7 @@ export default { "FileFolder": {}, "Subscription": { "onEventSubscription": [ - 217, + 153, { "eventStreamId": [ 1, @@ -11422,7 +11425,7 @@ export default { } ], "logicFunctionLogs": [ - 220, + 296, { "input": [ 490, diff --git a/packages/twenty-client-sdk/src/metadata/index.ts b/packages/twenty-client-sdk/src/metadata/index.ts new file mode 100644 index 00000000000..72f8057c93f --- /dev/null +++ b/packages/twenty-client-sdk/src/metadata/index.ts @@ -0,0 +1,2 @@ +export { MetadataApiClient } from './generated/index'; +export * as MetadataSchema from './generated/schema'; diff --git a/packages/twenty-client-sdk/tsconfig.json b/packages/twenty-client-sdk/tsconfig.json new file mode 100644 index 00000000000..43709b3de84 --- /dev/null +++ b/packages/twenty-client-sdk/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "allowJs": false, + "esModuleInterop": false, + "allowSyntheticDefaultImports": true, + "strictNullChecks": true, + "alwaysStrict": true, + "noImplicitAny": true, + "strictBindCallApply": false, + "noEmit": true, + "types": ["node"], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": ["src/**/*.ts", "vite.config.ts"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/twenty-client-sdk/tsconfig.lib.json b/packages/twenty-client-sdk/tsconfig.lib.json new file mode 100644 index 00000000000..4a9ce13e93e --- /dev/null +++ b/packages/twenty-client-sdk/tsconfig.lib.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "declaration": false, + "sourceMap": true + }, + "include": ["src"], + "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"] +} diff --git a/packages/twenty-client-sdk/vite.config.ts b/packages/twenty-client-sdk/vite.config.ts new file mode 100644 index 00000000000..e4be0bb6a6d --- /dev/null +++ b/packages/twenty-client-sdk/vite.config.ts @@ -0,0 +1,78 @@ +import path from 'path'; +import { defineConfig } from 'vite'; +import tsconfigPaths from 'vite-tsconfig-paths'; +import packageJson from './package.json'; + +const entries = [ + 'src/core/index.ts', + 'src/metadata/index.ts', + 'src/generate/index.ts', +]; + +const entryFileNames = (chunk: any, extension: 'cjs' | 'mjs') => { + if (!chunk.isEntry) { + throw new Error( + `Should never occur, encountered a non entry chunk ${chunk.facadeModuleId}`, + ); + } + + const splitFaceModuleId = chunk.facadeModuleId?.split('/'); + if (splitFaceModuleId === undefined) { + throw new Error( + `Should never occur, splitFaceModuleId is undefined ${chunk.facadeModuleId}`, + ); + } + + const moduleDirectory = splitFaceModuleId[splitFaceModuleId?.length - 2]; + if (moduleDirectory === 'src') { + return `${chunk.name}.${extension}`; + } + return `${moduleDirectory}.${extension}`; +}; + +export default defineConfig(() => { + return { + root: __dirname, + cacheDir: '../../node_modules/.vite/packages/twenty-client-sdk', + resolve: { + alias: { + '@/': path.resolve(__dirname, 'src') + '/', + }, + }, + plugins: [ + tsconfigPaths({ + root: __dirname, + }), + ], + build: { + emptyOutDir: false, + outDir: 'dist', + lib: { entry: entries, name: 'twenty-client-sdk' }, + rollupOptions: { + external: [ + ...Object.keys((packageJson as any).dependencies || {}), + ...Object.keys((packageJson as any).devDependencies || {}).filter( + (dep: string) => dep !== 'twenty-shared', + ), + 'node:fs/promises', + 'node:fs', + 'node:path', + ], + output: [ + { + format: 'es', + entryFileNames: (chunk) => entryFileNames(chunk, 'mjs'), + }, + { + format: 'cjs', + interop: 'auto', + esModule: true, + exports: 'named', + entryFileNames: (chunk) => entryFileNames(chunk, 'cjs'), + }, + ], + }, + }, + logLevel: 'warn', + }; +}); diff --git a/packages/twenty-client-sdk/vitest.config.ts b/packages/twenty-client-sdk/vitest.config.ts new file mode 100644 index 00000000000..8555cf2620e --- /dev/null +++ b/packages/twenty-client-sdk/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + name: 'twenty-client-sdk', + environment: 'node', + include: [ + 'src/**/__tests__/**/*.{test,spec}.{ts,tsx}', + 'src/**/*.{test,spec}.{ts,tsx}', + ], + exclude: ['**/node_modules/**', '**/.git/**'], + globals: true, + }, +}); diff --git a/packages/twenty-docs/developers/extend/capabilities/apps.mdx b/packages/twenty-docs/developers/extend/capabilities/apps.mdx index 1e3e1f9a088..f027d9e6a75 100644 --- a/packages/twenty-docs/developers/extend/capabilities/apps.mdx +++ b/packages/twenty-docs/developers/extend/capabilities/apps.mdx @@ -546,7 +546,7 @@ Each function file uses `defineLogicFunction()` to export a configuration with a // src/app/createPostCard.logic-function.ts import { defineLogicFunction } from 'twenty-sdk'; import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk'; -import { CoreApiClient, type Person } from 'twenty-sdk/clients'; +import { CoreApiClient, type Person } from 'twenty-client-sdk/core'; const handler = async (params: RoutePayload) => { const client = new CoreApiClient(); @@ -784,7 +784,7 @@ To mark a logic function as a tool, set `isTool: true` and provide a `toolInputS ```typescript // src/logic-functions/enrich-company.logic-function.ts import { defineLogicFunction } from 'twenty-sdk'; -import { CoreApiClient } from 'twenty-sdk/clients'; +import { CoreApiClient } from 'twenty-client-sdk/core'; const handler = async (params: { companyName: string; domain?: string }) => { const client = new CoreApiClient(); @@ -1200,8 +1200,8 @@ Two typed clients are auto-generated by `yarn twenty dev` and stored in `node_mo - **`MetadataApiClient`** — queries the `/metadata` endpoint for workspace configuration and file uploads ```typescript -import { CoreApiClient } from 'twenty-sdk/clients'; -import { MetadataApiClient } from 'twenty-sdk/clients'; +import { CoreApiClient } from 'twenty-client-sdk/core'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; const client = new CoreApiClient(); const { me } = await client.query({ me: { id: true, displayName: true } }); @@ -1229,7 +1229,7 @@ Notes: The `MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields on your workspace objects. Because standard GraphQL clients do not support multipart file uploads natively, the client provides this dedicated method that implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec) under the hood. ```typescript -import { MetadataApiClient } from 'twenty-sdk/clients'; +import { MetadataApiClient } from 'twenty-client-sdk/metadata'; import * as fs from 'fs'; const metadataClient = new MetadataApiClient(); diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts index 6474817584e..9d217b7ebff 100644 --- a/packages/twenty-front/src/generated-metadata/graphql.ts +++ b/packages/twenty-front/src/generated-metadata/graphql.ts @@ -1873,6 +1873,7 @@ export enum FileFolder { Dependencies = 'Dependencies', File = 'File', FilesField = 'FilesField', + GeneratedSdkClient = 'GeneratedSdkClient', PersonPicture = 'PersonPicture', ProfilePicture = 'ProfilePicture', PublicAsset = 'PublicAsset', @@ -1920,6 +1921,7 @@ export type FrontComponent = { sourceComponentPath: Scalars['String']; universalIdentifier?: Maybe; updatedAt: Scalars['DateTime']; + usesSdkClient: Scalars['Boolean']; }; export type FrontComponentConfiguration = { @@ -6640,7 +6642,7 @@ export type FindOneFrontComponentQueryVariables = Exact<{ }>; -export type FindOneFrontComponentQuery = { __typename?: 'Query', frontComponent?: { __typename?: 'FrontComponent', id: string, name: string, applicationId: string, builtComponentChecksum: string, isHeadless: boolean, applicationTokenPair?: { __typename?: 'ApplicationTokenPair', applicationAccessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, applicationRefreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } | null } | null }; +export type FindOneFrontComponentQuery = { __typename?: 'Query', frontComponent?: { __typename?: 'FrontComponent', id: string, name: string, applicationId: string, builtComponentChecksum: string, isHeadless: boolean, usesSdkClient: boolean, applicationTokenPair?: { __typename?: 'ApplicationTokenPair', applicationAccessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, applicationRefreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } | null } | null }; export type LogicFunctionFieldsFragment = { __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, cronTriggerSettings?: any | null, databaseEventTriggerSettings?: any | null, httpRouteTriggerSettings?: any | null, applicationId?: string | null, createdAt: string, updatedAt: string }; @@ -8170,7 +8172,7 @@ export const UploadFilesFieldFileDocument = {"kind":"Document","definitions":[{" export const UploadWorkflowFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UploadWorkflowFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Upload"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"uploadWorkflowFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"path"}},{"kind":"Field","name":{"kind":"Name","value":"size"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}}]}}]} as unknown as DocumentNode; export const RenewApplicationTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"RenewApplicationToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"applicationRefreshToken"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"renewApplicationToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"applicationRefreshToken"},"value":{"kind":"Variable","name":{"kind":"Name","value":"applicationRefreshToken"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"applicationAccessToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"applicationRefreshToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]}}]} as unknown as DocumentNode; export const FindManyFrontComponentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyFrontComponents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"frontComponents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}}]}}]}}]} as unknown as DocumentNode; -export const FindOneFrontComponentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneFrontComponent"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"frontComponent"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"builtComponentChecksum"}},{"kind":"Field","name":{"kind":"Name","value":"isHeadless"}},{"kind":"Field","name":{"kind":"Name","value":"applicationTokenPair"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"applicationAccessToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"applicationRefreshToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; +export const FindOneFrontComponentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindOneFrontComponent"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"id"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"frontComponent"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"id"},"value":{"kind":"Variable","name":{"kind":"Name","value":"id"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"builtComponentChecksum"}},{"kind":"Field","name":{"kind":"Name","value":"isHeadless"}},{"kind":"Field","name":{"kind":"Name","value":"usesSdkClient"}},{"kind":"Field","name":{"kind":"Name","value":"applicationTokenPair"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"applicationAccessToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}},{"kind":"Field","name":{"kind":"Name","value":"applicationRefreshToken"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"token"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]}}]}}]} as unknown as DocumentNode; export const CreateOneLogicFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOneLogicFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateLogicFunctionFromSourceInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createOneLogicFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LogicFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LogicFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"timeoutSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"sourceHandlerPath"}},{"kind":"Field","name":{"kind":"Name","value":"handlerName"}},{"kind":"Field","name":{"kind":"Name","value":"toolInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"isTool"}},{"kind":"Field","name":{"kind":"Name","value":"cronTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"databaseEventTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"httpRouteTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode; export const DeleteOneLogicFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteOneLogicFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunctionIdInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteOneLogicFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"LogicFunctionFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"LogicFunctionFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LogicFunction"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"runtime"}},{"kind":"Field","name":{"kind":"Name","value":"timeoutSeconds"}},{"kind":"Field","name":{"kind":"Name","value":"sourceHandlerPath"}},{"kind":"Field","name":{"kind":"Name","value":"handlerName"}},{"kind":"Field","name":{"kind":"Name","value":"toolInputSchema"}},{"kind":"Field","name":{"kind":"Name","value":"isTool"}},{"kind":"Field","name":{"kind":"Name","value":"cronTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"databaseEventTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"httpRouteTriggerSettings"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode; export const ExecuteOneLogicFunctionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"ExecuteOneLogicFunction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"input"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ExecuteOneLogicFunctionInput"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"executeOneLogicFunction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"input"},"value":{"kind":"Variable","name":{"kind":"Name","value":"input"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}},{"kind":"Field","name":{"kind":"Name","value":"logs"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"error"}}]}}]}}]} as unknown as DocumentNode; diff --git a/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx b/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx index 483ccbe3a5c..c8db3d6aa2b 100644 --- a/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx +++ b/packages/twenty-front/src/modules/front-components/components/FrontComponentRenderer.tsx @@ -1,4 +1,5 @@ import { FrontComponentRendererProvider } from '@/front-components/components/FrontComponentRendererProvider'; +import { FrontComponentRendererWithSdkClient } from '@/front-components/components/FrontComponentRendererWithSdkClient'; import { useFrontComponentExecutionContext } from '@/front-components/hooks/useFrontComponentExecutionContext'; import { useOnFrontComponentUpdated } from '@/front-components/hooks/useOnFrontComponentUpdated'; import { frontComponentApplicationTokenPairComponentState } from '@/front-components/states/frontComponentApplicationTokenPairComponentState'; @@ -73,11 +74,6 @@ export const FrontComponentRenderer = ({ frontComponentId, }); - const componentUrl = getFrontComponentUrl({ - frontComponentId, - checksum: data?.frontComponent?.builtComponentChecksum, - }); - const applicationTokenPair = data?.frontComponent?.applicationTokenPair ?? null; @@ -89,14 +85,39 @@ export const FrontComponentRenderer = ({ return null; } + const componentUrl = getFrontComponentUrl({ + frontComponentId, + checksum: data.frontComponent.builtComponentChecksum, + }); + + const usesSdkClient = data.frontComponent.usesSdkClient; + + const accessToken = applicationTokenPair.applicationAccessToken.token; + + if (usesSdkClient) { + return ( + + + + ); + } + return ( void; +}; + +export const FrontComponentRendererWithSdkClient = ({ + colorScheme, + componentUrl, + applicationAccessToken, + applicationId, + executionContext, + frontComponentHostCommunicationApi, + onError, +}: FrontComponentRendererWithSdkClientProps) => { + const sdkClientState = useAtomValue( + sdkClientFamilyState.atomFamily(applicationId), + ); + + return ( + <> + + {sdkClientState.status === 'loaded' && ( + + )} + + ); +}; diff --git a/packages/twenty-front/src/modules/front-components/components/SdkClientBlobUrlsEffect.tsx b/packages/twenty-front/src/modules/front-components/components/SdkClientBlobUrlsEffect.tsx new file mode 100644 index 00000000000..161ed2e4000 --- /dev/null +++ b/packages/twenty-front/src/modules/front-components/components/SdkClientBlobUrlsEffect.tsx @@ -0,0 +1,49 @@ +import { useStore } from 'jotai'; +import { useEffect } from 'react'; + +import { sdkClientFamilyState } from '@/front-components/states/sdkClientFamilyState'; +import { fetchSdkClientBlobUrls } from '@/front-components/utils/fetchSdkClientBlobUrls'; + +export const SdkClientBlobUrlsEffect = ({ + applicationId, + accessToken, + onError, +}: { + applicationId: string; + accessToken: string; + onError?: (error: Error) => void; +}) => { + const store = useStore(); + + useEffect(() => { + const atom = sdkClientFamilyState.atomFamily(applicationId); + const { status } = store.get(atom); + + if (status === 'loading' || status === 'loaded') { + return; + } + + store.set(atom, { status: 'loading' }); + + const fetchBlobUrls = async () => { + try { + const blobUrls = await fetchSdkClientBlobUrls( + applicationId, + accessToken, + ); + + store.set(atom, { status: 'loaded', blobUrls }); + } catch (error: unknown) { + const normalizedError = + error instanceof Error ? error : new Error(String(error)); + + store.set(atom, { status: 'error', error: normalizedError }); + onError?.(normalizedError); + } + }; + + fetchBlobUrls(); + }, [applicationId, accessToken, store, onError]); + + return null; +}; diff --git a/packages/twenty-front/src/modules/front-components/graphql/queries/findOneFrontComponent.ts b/packages/twenty-front/src/modules/front-components/graphql/queries/findOneFrontComponent.ts index 99d530bc887..f13be24c1c7 100644 --- a/packages/twenty-front/src/modules/front-components/graphql/queries/findOneFrontComponent.ts +++ b/packages/twenty-front/src/modules/front-components/graphql/queries/findOneFrontComponent.ts @@ -8,6 +8,7 @@ export const FIND_ONE_FRONT_COMPONENT = gql` applicationId builtComponentChecksum isHeadless + usesSdkClient applicationTokenPair { applicationAccessToken { token diff --git a/packages/twenty-front/src/modules/front-components/states/sdkClientFamilyState.ts b/packages/twenty-front/src/modules/front-components/states/sdkClientFamilyState.ts new file mode 100644 index 00000000000..43347bf6c9b --- /dev/null +++ b/packages/twenty-front/src/modules/front-components/states/sdkClientFamilyState.ts @@ -0,0 +1,20 @@ +import { createAtomFamilyState } from '@/ui/utilities/state/jotai/utils/createAtomFamilyState'; + +export type SdkClientBlobUrls = { + core: string; + metadata: string; +}; + +export type SdkClientState = + | { status: 'idle' } + | { status: 'loading' } + | { status: 'loaded'; blobUrls: SdkClientBlobUrls } + | { status: 'error'; error: Error }; + +export const sdkClientFamilyState = createAtomFamilyState< + SdkClientState, + string +>({ + key: 'sdkClientFamilyState', + defaultValue: { status: 'idle' }, +}); diff --git a/packages/twenty-front/src/modules/front-components/utils/fetchSdkClientBlobUrls.ts b/packages/twenty-front/src/modules/front-components/utils/fetchSdkClientBlobUrls.ts new file mode 100644 index 00000000000..48d2c89b376 --- /dev/null +++ b/packages/twenty-front/src/modules/front-components/utils/fetchSdkClientBlobUrls.ts @@ -0,0 +1,55 @@ +import { type SdkClientBlobUrls } from '@/front-components/states/sdkClientFamilyState'; +import { getSdkClientUrls } from '@/front-components/utils/getSdkClientUrls'; + +const fetchAndCreateBlobUrl = async ( + url: string, + token: string, +): Promise => { + const response = await fetch(url, { + headers: { Authorization: `Bearer ${token}` }, + }); + + if (!response.ok) { + throw new Error( + `Failed to fetch SDK module from ${url}: ${response.status}`, + ); + } + + const source = await response.text(); + const blob = new Blob([source], { type: 'application/javascript' }); + + return URL.createObjectURL(blob); +}; + +export const fetchSdkClientBlobUrls = async ( + applicationId: string, + accessToken: string, +): Promise => { + const urls = getSdkClientUrls(applicationId); + + const [coreResult, metadataResult] = await Promise.allSettled([ + fetchAndCreateBlobUrl(urls.core, accessToken), + fetchAndCreateBlobUrl(urls.metadata, accessToken), + ]); + + if ( + coreResult.status === 'fulfilled' && + metadataResult.status === 'fulfilled' + ) { + return { core: coreResult.value, metadata: metadataResult.value }; + } + + if (coreResult.status === 'fulfilled') { + URL.revokeObjectURL(coreResult.value); + } + + if (metadataResult.status === 'fulfilled') { + URL.revokeObjectURL(metadataResult.value); + } + + throw coreResult.status === 'rejected' + ? coreResult.reason + : metadataResult.status === 'rejected' + ? metadataResult.reason + : new Error('Unexpected SDK client fetch failure'); +}; diff --git a/packages/twenty-front/src/modules/front-components/utils/getSdkClientUrls.ts b/packages/twenty-front/src/modules/front-components/utils/getSdkClientUrls.ts new file mode 100644 index 00000000000..68c7c87c8bb --- /dev/null +++ b/packages/twenty-front/src/modules/front-components/utils/getSdkClientUrls.ts @@ -0,0 +1,6 @@ +import { REST_API_BASE_URL } from '@/apollo/constant/rest-api-base-url'; + +export const getSdkClientUrls = (applicationId: string) => ({ + core: `${REST_API_BASE_URL}/sdk-client/${applicationId}/core`, + metadata: `${REST_API_BASE_URL}/sdk-client/${applicationId}/metadata`, +}); diff --git a/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts b/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts index 7845e09889a..819df2e5d4a 100644 --- a/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts +++ b/packages/twenty-front/src/modules/users/hooks/useLoadCurrentUser.ts @@ -56,7 +56,7 @@ export const useLoadCurrentUser = () => { const user = currentUserResult.data?.currentUser; - if (!user) { + if (!isDefined(user)) { throw new Error('No current user result'); } diff --git a/packages/twenty-sdk/.oxlintrc.json b/packages/twenty-sdk/.oxlintrc.json index e21abc5dbe5..a1d10264b45 100644 --- a/packages/twenty-sdk/.oxlintrc.json +++ b/packages/twenty-sdk/.oxlintrc.json @@ -4,7 +4,7 @@ "categories": { "correctness": "off" }, - "ignorePatterns": ["node_modules", "dist", "src/clients/generated"], + "ignorePatterns": ["node_modules", "dist"], "rules": { "func-style": ["error", "declaration", { "allowArrowFunctions": true }], "no-console": "off", diff --git a/packages/twenty-sdk/.prettierignore b/packages/twenty-sdk/.prettierignore index 2b4b03aed84..e3d13709bb2 100644 --- a/packages/twenty-sdk/.prettierignore +++ b/packages/twenty-sdk/.prettierignore @@ -1,4 +1,3 @@ dist storybook-static coverage -src/clients/generated diff --git a/packages/twenty-sdk/package.json b/packages/twenty-sdk/package.json index 23c2f558f8c..de2a85c614e 100644 --- a/packages/twenty-sdk/package.json +++ b/packages/twenty-sdk/package.json @@ -48,11 +48,6 @@ "types": "./dist/build/index.d.ts", "import": "./dist/build.mjs", "require": "./dist/build.cjs" - }, - "./clients": { - "types": "./dist/clients/index.d.ts", - "import": "./dist/clients.mjs", - "require": "./dist/clients.cjs" } }, "license": "AGPL-3.0", @@ -101,6 +96,7 @@ "storybook": "^10.2.13", "ts-morph": "^25.0.0", "tsx": "^4.7.0", + "twenty-client-sdk": "workspace:*", "twenty-shared": "workspace:*", "twenty-ui": "workspace:*", "vite-plugin-dts": "^4.5.4", @@ -120,9 +116,6 @@ ], "front-component-renderer": [ "dist/front-component-renderer/index.d.ts" - ], - "clients": [ - "dist/clients/index.d.ts" ] } } diff --git a/packages/twenty-sdk/project.json b/packages/twenty-sdk/project.json index 43183fc883c..65d758cc052 100644 --- a/packages/twenty-sdk/project.json +++ b/packages/twenty-sdk/project.json @@ -96,16 +96,6 @@ "command": "npx vite build -c vite.config.sdk.ts" } }, - "generate-metadata-client": { - "executor": "nx:run-commands", - "cache": false, - "dependsOn": ["^build"], - "outputs": ["{projectRoot}/src/clients/generated/metadata"], - "options": { - "cwd": "packages/twenty-sdk", - "command": "tsx -r tsconfig-paths/register scripts/generate-metadata-client.ts" - } - }, "generate-remote-dom-elements": { "executor": "nx:run-commands", "cache": true, diff --git a/packages/twenty-sdk/scripts/generate-metadata-client.ts b/packages/twenty-sdk/scripts/generate-metadata-client.ts deleted file mode 100644 index 1578720d209..00000000000 --- a/packages/twenty-sdk/scripts/generate-metadata-client.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { readFile } from 'node:fs/promises'; -import path from 'path'; - -import { CLIENTS_GENERATED_DIR } from '@/cli/constants/clients-dir'; -import { ClientService } from '@/cli/utilities/client/client-service'; - -const TEMPLATE_PATH = path.resolve( - __dirname, - '..', - 'src', - 'cli', - 'utilities', - 'client', - 'twenty-client-template.ts', -); - -const main = async () => { - const outputPath = path.resolve( - __dirname, - '..', - CLIENTS_GENERATED_DIR, - 'metadata', - ); - - const serverUrl = process.env.TWENTY_API_URL ?? 'http://localhost:3000'; - const clientWrapperTemplateSource = await readFile(TEMPLATE_PATH, 'utf-8'); - - const clientService = new ClientService({ - clientWrapperTemplateSource, - serverUrl, - skipAuth: true, - }); - - await clientService.generateMetadataClient({ outputPath }); - - console.log(`Metadata client generated at ${outputPath}`); -}; - -main().catch((error) => { - console.error('Failed to generate metadata client:', error); - process.exit(1); -}); diff --git a/packages/twenty-sdk/src/cli/__tests__/apps/function-execute-app/__e2e__/function-execute.e2e-spec.ts b/packages/twenty-sdk/src/cli/__tests__/apps/function-execute-app/__e2e__/function-execute.e2e-spec.ts index 5fc63005d53..72ff189f48f 100644 --- a/packages/twenty-sdk/src/cli/__tests__/apps/function-execute-app/__e2e__/function-execute.e2e-spec.ts +++ b/packages/twenty-sdk/src/cli/__tests__/apps/function-execute-app/__e2e__/function-execute.e2e-spec.ts @@ -1,6 +1,8 @@ import { vi } from 'vitest'; import { appBuild } from '@/cli/operations/build'; +import { appDeploy } from '@/cli/operations/deploy'; +import { appInstall } from '@/cli/operations/install'; import { appUninstall } from '@/cli/operations/uninstall'; import { functionExecute } from '@/cli/operations/execute'; import { FUNCTION_EXECUTE_APP_PATH } from '@/cli/__tests__/apps/fixture-paths'; @@ -11,7 +13,7 @@ const APP_PATH = FUNCTION_EXECUTE_APP_PATH; describe('functionExecute E2E', () => { beforeAll(async () => { - const buildResult = await appBuild({ appPath: APP_PATH }); + const buildResult = await appBuild({ appPath: APP_PATH, tarball: true }); if (!buildResult.success) { throw new Error( @@ -19,6 +21,24 @@ describe('functionExecute E2E', () => { ); } + const deployResult = await appDeploy({ + tarballPath: buildResult.data.tarballPath!, + }); + + if (!deployResult.success) { + throw new Error( + `appDeploy failed: ${deployResult.error.code} – ${deployResult.error.message}`, + ); + } + + const installResult = await appInstall({ appPath: APP_PATH }); + + if (!installResult.success) { + throw new Error( + `appInstall failed: ${installResult.error.code} – ${installResult.error.message}`, + ); + } + await vi.waitFor( async () => { const result = await functionExecute({ diff --git a/packages/twenty-sdk/src/cli/__tests__/apps/minimal-app/__integration__/app-dev/expected-manifest.ts b/packages/twenty-sdk/src/cli/__tests__/apps/minimal-app/__integration__/app-dev/expected-manifest.ts index a6d3f6b00a9..c16414e6507 100644 --- a/packages/twenty-sdk/src/cli/__tests__/apps/minimal-app/__integration__/app-dev/expected-manifest.ts +++ b/packages/twenty-sdk/src/cli/__tests__/apps/minimal-app/__integration__/app-dev/expected-manifest.ts @@ -15,7 +15,6 @@ export const EXPECTED_MANIFEST: Manifest = { defaultRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002', packageJsonChecksum: '[checksum]', yarnLockChecksum: '[checksum]', - apiClientChecksum: null, }, skills: [], agents: [], @@ -345,6 +344,7 @@ export const EXPECTED_MANIFEST: Manifest = { builtComponentPath: 'my.front-component.mjs', builtComponentChecksum: '[checksum]', isHeadless: false, + usesSdkClient: false, }, ], views: [], diff --git a/packages/twenty-sdk/src/cli/__tests__/apps/postcard-app/__integration__/app-dev/expected-manifest.ts b/packages/twenty-sdk/src/cli/__tests__/apps/postcard-app/__integration__/app-dev/expected-manifest.ts index 980510242fc..fae5ba28c6b 100644 --- a/packages/twenty-sdk/src/cli/__tests__/apps/postcard-app/__integration__/app-dev/expected-manifest.ts +++ b/packages/twenty-sdk/src/cli/__tests__/apps/postcard-app/__integration__/app-dev/expected-manifest.ts @@ -49,7 +49,6 @@ export const EXPECTED_MANIFEST: Manifest = { universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7', yarnLockChecksum: 'd41d8cd98f00b204e9800998ecf8427e', packageJsonChecksum: '2851d0e2c3621a57e1fd103a245b6fde', - apiClientChecksum: null, }, frontComponents: [ { @@ -61,6 +60,7 @@ export const EXPECTED_MANIFEST: Manifest = { sourceComponentPath: 'src/root.front-component.tsx', universalIdentifier: 'a0a1a2a3-a4a5-4000-8000-000000000001', isHeadless: false, + usesSdkClient: false, }, { builtComponentPath: 'src/components/card.front-component.mjs', @@ -71,6 +71,7 @@ export const EXPECTED_MANIFEST: Manifest = { sourceComponentPath: 'src/components/card.front-component.tsx', universalIdentifier: '88c15ae2-5f87-4a6b-b48f-1974bbe62eb7', isHeadless: false, + usesSdkClient: false, }, { builtComponentPath: 'src/components/greeting.front-component.mjs', @@ -81,6 +82,7 @@ export const EXPECTED_MANIFEST: Manifest = { sourceComponentPath: 'src/components/greeting.front-component.tsx', universalIdentifier: '370ae182-743f-4ecb-b625-7ac48e21f0e5', isHeadless: false, + usesSdkClient: false, }, { builtComponentPath: 'src/components/test.front-component.mjs', @@ -91,6 +93,7 @@ export const EXPECTED_MANIFEST: Manifest = { sourceComponentPath: 'src/components/test.front-component.tsx', universalIdentifier: 'f1234567-abcd-4000-8000-000000000001', isHeadless: false, + usesSdkClient: false, }, ], @@ -269,7 +272,7 @@ export const EXPECTED_MANIFEST: Manifest = { }, ], type: FieldType.SELECT, - universalIdentifier: '8b9c0d1e-2f3a-4b5c-6d7e-8f9a0b1c2d3e', + universalIdentifier: 'b602dbd9-e511-49ce-b6d3-b697218dc69c', }, { objectUniversalIdentifier: '54b589ca-eeed-4950-a176-358418b85c05', @@ -277,7 +280,7 @@ export const EXPECTED_MANIFEST: Manifest = { label: 'Priority', name: 'priority', type: FieldType.NUMBER, - universalIdentifier: '7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d', + universalIdentifier: '7b57bd63-5a4c-46ca-9d52-42c8f02d1df6', }, { label: 'Recipient', @@ -1266,8 +1269,8 @@ export const EXPECTED_MANIFEST: Manifest = { }, { icon: 'IconHome', - label: 'Address', - name: 'address', + label: 'Mailing Address', + name: 'mailingAddress', type: FieldType.ADDRESS, universalIdentifier: 'd3a2b3c4-5e6f-4a7b-8c9d-0e1f2a3b4c5d', }, diff --git a/packages/twenty-sdk/src/cli/__tests__/integration/utils/normalize-manifest.util.ts b/packages/twenty-sdk/src/cli/__tests__/integration/utils/normalize-manifest.util.ts index 1d54ae1bd32..e2bf4b98eae 100644 --- a/packages/twenty-sdk/src/cli/__tests__/integration/utils/normalize-manifest.util.ts +++ b/packages/twenty-sdk/src/cli/__tests__/integration/utils/normalize-manifest.util.ts @@ -17,9 +17,6 @@ export const normalizeManifestForComparison = ( packageJsonChecksum: manifest.application.packageJsonChecksum ? '[checksum]' : null, - apiClientChecksum: manifest.application.apiClientChecksum - ? '[checksum]' - : null, }, objects: sortById( manifest.objects.map((object) => ({ diff --git a/packages/twenty-sdk/src/cli/commands/app-command.ts b/packages/twenty-sdk/src/cli/commands/app-command.ts index c6566955732..67ec637c1cb 100644 --- a/packages/twenty-sdk/src/cli/commands/app-command.ts +++ b/packages/twenty-sdk/src/cli/commands/app-command.ts @@ -3,6 +3,7 @@ import chalk from 'chalk'; import type { Command } from 'commander'; import { AppBuildCommand } from './build'; import { AppDevCommand } from './dev'; +import { AppInstallCommand } from './install'; import { AppPublishCommand } from './publish'; import { AppTypecheckCommand } from './typecheck'; import { AppUninstallCommand } from './uninstall'; @@ -17,6 +18,7 @@ import { SyncableEntity } from 'twenty-shared/application'; export const registerCommands = (program: Command): void => { const buildCommand = new AppBuildCommand(); const devCommand = new AppDevCommand(); + const installCommand = new AppInstallCommand(); const publishCommand = new AppPublishCommand(); const typecheckCommand = new AppTypecheckCommand(); const uninstallCommand = new AppUninstallCommand(); @@ -45,9 +47,20 @@ export const registerCommands = (program: Command): void => { }); }); + program + .command('install [appPath]') + .description('Install a deployed application on the connected server') + .option('-r, --remote ', 'Install on a specific remote') + .action(async (appPath, options) => { + await installCommand.execute({ + appPath: formatPath(appPath), + remote: options.remote, + }); + }); + program .command('deploy [appPath]') - .description('Build and deploy to a Twenty server') + .description('Build and upload application to a Twenty server') .option('-r, --remote ', 'Deploy to a specific remote') .action(async (appPath, options) => { await deployCommand.execute({ diff --git a/packages/twenty-sdk/src/cli/commands/deploy.ts b/packages/twenty-sdk/src/cli/commands/deploy.ts index d77cb709e0a..b1290ecf6d9 100644 --- a/packages/twenty-sdk/src/cli/commands/deploy.ts +++ b/packages/twenty-sdk/src/cli/commands/deploy.ts @@ -1,7 +1,7 @@ +import { appBuild } from '@/cli/operations/build'; import { appDeploy } from '@/cli/operations/deploy'; import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/utilities/config/current-execution-directory'; import { checkSdkVersionCompatibility } from '@/cli/utilities/version/check-sdk-version-compatibility'; -import { ConfigService } from '@/cli/utilities/config/config-service'; import chalk from 'chalk'; export type DeployCommandOptions = { @@ -15,34 +15,26 @@ export class DeployCommand { await checkSdkVersionCompatibility(appPath); - const configService = new ConfigService(); - let serverUrl: string; - let token: string | undefined; - - if (options.remote) { - const remoteConfig = await configService.getConfigForRemote( - options.remote, - ); - - serverUrl = remoteConfig.apiUrl; - token = remoteConfig.accessToken ?? remoteConfig.apiKey; - } else { - const config = await configService.getConfig(); - - serverUrl = config.apiUrl; - token = config.accessToken ?? config.apiKey; - } - - const remoteName = options.remote ?? ConfigService.getActiveRemote(); - - console.log(chalk.blue(`Deploying to ${remoteName} (${serverUrl})...`)); + console.log(chalk.blue('Deploying application...')); console.log(chalk.gray(`App path: ${appPath}\n`)); - const result = await appDeploy({ + const onProgress = (message: string) => console.log(chalk.gray(message)); + + const buildResult = await appBuild({ appPath, - serverUrl, - token, - onProgress: (message) => console.log(chalk.gray(message)), + tarball: true, + onProgress, + }); + + if (!buildResult.success) { + console.error(chalk.red(buildResult.error.message)); + process.exit(1); + } + + const result = await appDeploy({ + tarballPath: buildResult.data.tarballPath!, + remote: options.remote, + onProgress, }); if (!result.success) { diff --git a/packages/twenty-sdk/src/cli/commands/install.ts b/packages/twenty-sdk/src/cli/commands/install.ts new file mode 100644 index 00000000000..359f3349bb4 --- /dev/null +++ b/packages/twenty-sdk/src/cli/commands/install.ts @@ -0,0 +1,32 @@ +import { appInstall } from '@/cli/operations/install'; +import { CURRENT_EXECUTION_DIRECTORY } from '@/cli/utilities/config/current-execution-directory'; +import { checkSdkVersionCompatibility } from '@/cli/utilities/version/check-sdk-version-compatibility'; +import chalk from 'chalk'; + +export type AppInstallCommandOptions = { + appPath?: string; + remote?: string; +}; + +export class AppInstallCommand { + async execute(options: AppInstallCommandOptions): Promise { + const appPath = options.appPath ?? CURRENT_EXECUTION_DIRECTORY; + + await checkSdkVersionCompatibility(appPath); + + console.log(chalk.blue('Installing application...')); + console.log(chalk.gray(`App path: ${appPath}\n`)); + + const result = await appInstall({ + appPath, + remote: options.remote, + }); + + if (!result.success) { + console.error(chalk.red(result.error.message)); + process.exit(1); + } + + console.log(chalk.green('✓ Application installed')); + } +} diff --git a/packages/twenty-sdk/src/cli/constants/clients-dir.ts b/packages/twenty-sdk/src/cli/constants/clients-dir.ts deleted file mode 100644 index d4d6498217c..00000000000 --- a/packages/twenty-sdk/src/cli/constants/clients-dir.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const CLIENTS_SOURCE_DIR = 'src/clients'; -export const CLIENTS_GENERATED_DIR = `${CLIENTS_SOURCE_DIR}/generated`; diff --git a/packages/twenty-sdk/src/cli/operations/build.ts b/packages/twenty-sdk/src/cli/operations/build.ts index bd11992d8be..99f3ef6ad1e 100644 --- a/packages/twenty-sdk/src/cli/operations/build.ts +++ b/packages/twenty-sdk/src/cli/operations/build.ts @@ -2,10 +2,10 @@ import { execSync } from 'child_process'; import path from 'path'; import { buildApplication } from '@/cli/utilities/build/common/build-application'; -import { synchronizeBuiltApplication } from '@/cli/utilities/build/common/synchronize-built-application'; import { runTypecheck } from '@/cli/utilities/build/common/typecheck-plugin'; import { buildAndValidateManifest } from '@/cli/utilities/build/manifest/build-and-validate-manifest'; -import { ClientService } from '@/cli/utilities/client/client-service'; +import { manifestUpdateChecksums } from '@/cli/utilities/build/manifest/manifest-update-checksums'; +import { writeManifestToOutput } from '@/cli/utilities/build/manifest/manifest-writer'; import { runSafe } from '@/cli/utilities/run-safe'; import { APP_ERROR_CODES, type CommandResult } from '@/cli/types'; @@ -48,30 +48,12 @@ const innerAppBuild = async ( onProgress?.('Building application files...'); - const firstBuildResult = await buildApplication({ + const buildResult = await buildApplication({ appPath, manifest, filePaths, }); - onProgress?.('Syncing application schema...'); - - const firstSyncResult = await synchronizeBuiltApplication({ - appPath, - manifest, - builtFileInfos: firstBuildResult.builtFileInfos, - }); - - if (!firstSyncResult.success) { - return firstSyncResult; - } - - onProgress?.('Generating API client...'); - - const clientService = new ClientService(); - - await clientService.generateCoreClient({ appPath }); - onProgress?.('Running typecheck...'); const typecheckErrors = await runTypecheck(appPath); @@ -91,31 +73,18 @@ const innerAppBuild = async ( }; } - onProgress?.('Rebuilding with generated client...'); - - const finalBuildResult = await buildApplication({ - appPath, + const updatedManifest = manifestUpdateChecksums({ manifest, - filePaths, + builtFileInfos: buildResult.builtFileInfos, }); - onProgress?.('Syncing built files...'); - - const finalSyncResult = await synchronizeBuiltApplication({ - appPath, - manifest, - builtFileInfos: finalBuildResult.builtFileInfos, - }); - - if (!finalSyncResult.success) { - return finalSyncResult; - } + await writeManifestToOutput(appPath, updatedManifest); const outputDir = path.join(appPath, '.twenty', 'output'); const result: AppBuildResult = { outputDir, - fileCount: finalBuildResult.builtFileInfos.size, + fileCount: buildResult.builtFileInfos.size, }; if (options.tarball) { diff --git a/packages/twenty-sdk/src/cli/operations/deploy.ts b/packages/twenty-sdk/src/cli/operations/deploy.ts index cf90846c862..5f4c157e0d4 100644 --- a/packages/twenty-sdk/src/cli/operations/deploy.ts +++ b/packages/twenty-sdk/src/cli/operations/deploy.ts @@ -1,13 +1,14 @@ import fs from 'fs'; import { ApiService } from '@/cli/utilities/api/api-service'; +import { ConfigService } from '@/cli/utilities/config/config-service'; import { runSafe } from '@/cli/utilities/run-safe'; -import { appBuild } from './build'; import { APP_ERROR_CODES, type CommandResult } from '@/cli/types'; export type AppDeployOptions = { - appPath: string; - serverUrl: string; + tarballPath: string; + remote?: string; + serverUrl?: string; token?: string; onProgress?: (message: string) => void; }; @@ -19,25 +20,19 @@ export type AppDeployResult = { const innerAppDeploy = async ( options: AppDeployOptions, ): Promise> => { - const { appPath, serverUrl, token, onProgress } = options; + const { tarballPath, onProgress } = options; - const buildResult = await appBuild({ - appPath, - tarball: true, - onProgress, - }); - - if (!buildResult.success) { - return buildResult; + if (options.remote) { + ConfigService.setActiveRemote(options.remote); } - onProgress?.(`Uploading ${buildResult.data.tarballPath}...`); + onProgress?.(`Uploading ${tarballPath}...`); - const tarballBuffer = fs.readFileSync(buildResult.data.tarballPath!); + const tarballBuffer = fs.readFileSync(tarballPath); const apiService = new ApiService({ - serverUrl, - token, + serverUrl: options.serverUrl, + token: options.token, }); const uploadResult = await apiService.uploadAppTarball({ tarballBuffer }); @@ -52,22 +47,6 @@ const innerAppDeploy = async ( }; } - onProgress?.('Installing application...'); - - const installResult = await apiService.installTarballApp({ - universalIdentifier: uploadResult.data.universalIdentifier, - }); - - if (!installResult.success) { - return { - success: false, - error: { - code: APP_ERROR_CODES.DEPLOY_FAILED, - message: `Install failed: ${installResult.error}`, - }, - }; - } - return { success: true, data: { diff --git a/packages/twenty-sdk/src/cli/operations/index.ts b/packages/twenty-sdk/src/cli/operations/index.ts index 5c29dd5bbc4..ef33566f7d8 100644 --- a/packages/twenty-sdk/src/cli/operations/index.ts +++ b/packages/twenty-sdk/src/cli/operations/index.ts @@ -11,6 +11,8 @@ export { appBuild } from './build'; export type { AppBuildOptions, AppBuildResult } from './build'; export { appDeploy } from './deploy'; export type { AppDeployOptions, AppDeployResult } from './deploy'; +export { appInstall } from './install'; +export type { AppInstallOptions } from './install'; export { appPublish } from './publish'; export type { AppPublishOptions, AppPublishResult } from './publish'; export { appUninstall } from './uninstall'; diff --git a/packages/twenty-sdk/src/cli/operations/install.ts b/packages/twenty-sdk/src/cli/operations/install.ts new file mode 100644 index 00000000000..91994bb8ea4 --- /dev/null +++ b/packages/twenty-sdk/src/cli/operations/install.ts @@ -0,0 +1,57 @@ +import { ApiService } from '@/cli/utilities/api/api-service'; +import { readManifestFromFile } from '@/cli/utilities/build/manifest/manifest-reader'; +import { ConfigService } from '@/cli/utilities/config/config-service'; +import { runSafe } from '@/cli/utilities/run-safe'; +import { APP_ERROR_CODES, type CommandResult } from '@/cli/types'; + +export type AppInstallOptions = { + appPath: string; + remote?: string; +}; + +const innerAppInstall = async ( + options: AppInstallOptions, +): Promise => { + if (options.remote) { + ConfigService.setActiveRemote(options.remote); + } + + const apiService = new ApiService(); + const manifest = await readManifestFromFile(options.appPath); + + if (!manifest) { + return { + success: false, + error: { + code: APP_ERROR_CODES.MANIFEST_NOT_FOUND, + message: 'Manifest not found. Run `build` or `dev` first.', + }, + }; + } + + const result = await apiService.installTarballApp({ + universalIdentifier: manifest.application.universalIdentifier, + }); + + if (!result.success) { + const errorMessage = + result.error instanceof Error + ? result.error.message + : String(result.error ?? 'Unknown error'); + + return { + success: false, + error: { + code: APP_ERROR_CODES.INSTALL_FAILED, + message: errorMessage, + }, + }; + } + + return { success: true, data: undefined }; +}; + +export const appInstall = ( + options: AppInstallOptions, +): Promise => + runSafe(() => innerAppInstall(options), APP_ERROR_CODES.INSTALL_FAILED); diff --git a/packages/twenty-sdk/src/cli/types.ts b/packages/twenty-sdk/src/cli/types.ts index ebbb0952687..4e2515cf025 100644 --- a/packages/twenty-sdk/src/cli/types.ts +++ b/packages/twenty-sdk/src/cli/types.ts @@ -20,6 +20,7 @@ export const APP_ERROR_CODES = { MANIFEST_BUILD_FAILED: 'MANIFEST_BUILD_FAILED', BUILD_FAILED: 'BUILD_FAILED', PUBLISH_FAILED: 'PUBLISH_FAILED', + INSTALL_FAILED: 'INSTALL_FAILED', UNINSTALL_FAILED: 'UNINSTALL_FAILED', SYNC_FAILED: 'SYNC_FAILED', TYPECHECK_FAILED: 'TYPECHECK_FAILED', diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/build-application.ts b/packages/twenty-sdk/src/cli/utilities/build/common/build-application.ts index fcc5b258032..5b453c6d99e 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/build-application.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/build-application.ts @@ -9,10 +9,7 @@ import { import { FileFolder } from 'twenty-shared/types'; import { esbuildOneShotBuild } from '@/cli/utilities/build/common/esbuild-one-shot-build'; -import { - LOGIC_FUNCTION_EXTERNAL_MODULES, - createSdkClientsResolverPlugin, -} from '@/cli/utilities/build/common/esbuild-watcher'; +import { LOGIC_FUNCTION_EXTERNAL_MODULES } from '@/cli/utilities/build/common/esbuild-watcher'; import { getBaseFrontComponentBuildOptions } from '@/cli/utilities/build/common/front-component-build/utils/get-base-front-component-build-options'; import { getFrontComponentBuildPlugins } from '@/cli/utilities/build/common/front-component-build/utils/get-front-component-build-plugins'; import { type OnFileBuiltCallback } from '@/cli/utilities/build/common/restartable-watcher-interface'; @@ -36,6 +33,7 @@ export type BuiltFileInfo = { builtPath: string; sourcePath: string; fileFolder: FileFolder; + usesSdkClient?: boolean; }; export type AppBuildResult = { @@ -58,6 +56,7 @@ export const buildApplication = async ( builtPath: event.builtPath, sourcePath: event.sourcePath, fileFolder: event.fileFolder, + usesSdkClient: event.usesSdkClient, }); }; @@ -80,7 +79,6 @@ export const buildApplication = async ( metafile: true, logLevel: 'silent', banner: NODE_ESM_CJS_BANNER, - plugins: [createSdkClientsResolverPlugin(options.appPath)], }, onFileBuilt: collectFileBuilt, }); @@ -93,10 +91,11 @@ export const buildApplication = async ( ...getBaseFrontComponentBuildOptions(), outdir: join(options.appPath, OUTPUT_DIR), tsconfig: join(options.appPath, 'tsconfig.json'), - plugins: [ - createSdkClientsResolverPlugin(options.appPath), - ...getFrontComponentBuildPlugins(), - ], + jsx: 'automatic', + sourcemap: true, + metafile: true, + logLevel: 'silent', + plugins: [...getFrontComponentBuildPlugins()], }, onFileBuilt: collectFileBuilt, }); diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-result-processor.ts b/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-result-processor.ts index bf20dfcdd54..447ca5a3782 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-result-processor.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-result-processor.ts @@ -5,6 +5,8 @@ import path from 'path'; import { type OnFileBuiltCallback } from '@/cli/utilities/build/common/restartable-watcher-interface'; import { type FileFolder } from 'twenty-shared/types'; +const SDK_CLIENT_IMPORT_PREFIX = 'twenty-client-sdk'; + export type ProcessEsbuildResultParams = { result: esbuild.BuildResult; appPath: string; @@ -42,12 +44,21 @@ export const processEsbuildResult = async ({ lastChecksums.set(relativeBuiltPath, checksum); + const outputMeta = result.metafile?.outputs?.[outputFile]; + const usesSdkClient = + outputMeta?.imports?.some( + (imp) => + imp.external === true && + imp.path.startsWith(SDK_CLIENT_IMPORT_PREFIX), + ) ?? false; + if (onFileBuilt) { await onFileBuilt({ fileFolder, builtPath: relativeBuiltPath, sourcePath: relativeSourcePath, checksum, + usesSdkClient, }); } } diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-watcher.ts b/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-watcher.ts index fc75c17eebc..32831c8d3f4 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-watcher.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/esbuild-watcher.ts @@ -1,4 +1,3 @@ -import { CLIENTS_SOURCE_DIR } from '@/cli/constants/clients-dir'; import { cleanupRemovedFiles } from '@/cli/utilities/build/common/cleanup-removed-files'; import { processEsbuildResult } from '@/cli/utilities/build/common/esbuild-result-processor'; import { FRONT_COMPONENT_EXTERNAL_MODULES } from '@/cli/utilities/build/common/front-component-build/constants/front-component-external-modules'; @@ -16,6 +15,8 @@ import { NODE_ESM_CJS_BANNER, OUTPUT_DIR } from 'twenty-shared/application'; import { FileFolder } from 'twenty-shared/types'; export const LOGIC_FUNCTION_EXTERNAL_MODULES: string[] = [ + 'twenty-client-sdk/core', + 'twenty-client-sdk/metadata', 'path', 'fs', 'crypto', @@ -186,25 +187,6 @@ export class EsbuildWatcher implements RestartableWatcher { } } -// Resolves twenty-sdk/clients to the source barrel so esbuild -// bundles it instead of treating it as external (via twenty-sdk/*) -export const createSdkClientsResolverPlugin = ( - appPath: string, -): esbuild.Plugin => ({ - name: 'sdk-clients-resolver', - setup: (build) => { - build.onResolve({ filter: /^twenty-sdk\/clients/ }, () => ({ - path: path.join( - appPath, - 'node_modules', - 'twenty-sdk', - CLIENTS_SOURCE_DIR, - 'index.ts', - ), - })); - }, -}); - export type EsbuildWatcherFactoryOptions = RestartableWatcherOptions & { shouldSkipTypecheck: () => boolean; }; @@ -220,7 +202,6 @@ export const createLogicFunctionsWatcher = ( platform: 'node', extraPlugins: [ createTypecheckPlugin(options.appPath, options.shouldSkipTypecheck), - createSdkClientsResolverPlugin(options.appPath), ], banner: NODE_ESM_CJS_BANNER, }, @@ -237,7 +218,6 @@ export const createFrontComponentsWatcher = ( jsx: 'automatic', extraPlugins: [ createTypecheckPlugin(options.appPath, options.shouldSkipTypecheck), - createSdkClientsResolverPlugin(options.appPath), ...getFrontComponentBuildPlugins(), ], }, diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/constants/front-component-external-modules.ts b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/constants/front-component-external-modules.ts index 75d6ef324c6..b98a52b75b4 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/constants/front-component-external-modules.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/front-component-build/constants/front-component-external-modules.ts @@ -1 +1,4 @@ -export const FRONT_COMPONENT_EXTERNAL_MODULES: string[] = []; +export const FRONT_COMPONENT_EXTERNAL_MODULES: string[] = [ + 'twenty-client-sdk/core', + 'twenty-client-sdk/metadata', +]; diff --git a/packages/twenty-sdk/src/cli/utilities/build/common/restartable-watcher-interface.ts b/packages/twenty-sdk/src/cli/utilities/build/common/restartable-watcher-interface.ts index 5e6485cae99..0d8fe7bc770 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/common/restartable-watcher-interface.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/common/restartable-watcher-interface.ts @@ -13,6 +13,7 @@ export type OnFileBuiltCallback = (options: { builtPath: string; sourcePath: string; checksum: string; + usesSdkClient?: boolean; }) => void | Promise; export type OnBuildErrorCallback = ( diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/__tests__/manifest-validate.spec.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/__tests__/manifest-validate.spec.ts index 7a8b132d685..8112b02d8cb 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/manifest/__tests__/manifest-validate.spec.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/__tests__/manifest-validate.spec.ts @@ -13,7 +13,6 @@ const validApplication: ApplicationManifest = { defaultRoleUniversalIdentifier: '68bb56f3-8300-4cb5-8cc3-8da9ee66f1b2', packageJsonChecksum: '98592af7-4be9-4655-b5c4-9bef307a996c', yarnLockChecksum: '580ee05f-15fe-4146-bac2-6c382483c94e', - apiClientChecksum: null, }; const validField: FieldManifest = { diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts index 7c468135b54..6b6b17dd5dd 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-build.ts @@ -115,7 +115,6 @@ export const buildManifest = async ( ...extract.config, yarnLockChecksum: null, packageJsonChecksum: null, - apiClientChecksum: null, }; errors.push(...extract.errors); applicationFilePaths.push(relativePath); diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-extract-config-from-file.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-extract-config-from-file.ts index 4c0b51470a1..cab6c866b38 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-extract-config-from-file.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-extract-config-from-file.ts @@ -8,7 +8,11 @@ import os from 'os'; import path from 'path'; import { isDefined, isPlainObject } from 'twenty-shared/utils'; -const MANIFEST_MOCK_MODULES = ['twenty-sdk/ui', 'twenty-sdk/clients']; +const MANIFEST_MOCK_MODULES = [ + 'twenty-sdk/ui', + 'twenty-client-sdk/core', + 'twenty-client-sdk/metadata', +]; const manifestMockPlugin: esbuild.Plugin = { name: 'manifest-mock', diff --git a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-update-checksums.ts b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-update-checksums.ts index 47c915409c1..4fc96b91b2c 100644 --- a/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-update-checksums.ts +++ b/packages/twenty-sdk/src/cli/utilities/build/manifest/manifest-update-checksums.ts @@ -1,10 +1,5 @@ -import crypto from 'crypto'; import { relative } from 'path'; -import { - type Manifest, - OUTPUT_DIR, - API_CLIENT_DIR, -} from 'twenty-shared/application'; +import { type Manifest, OUTPUT_DIR } from 'twenty-shared/application'; import { FileFolder } from 'twenty-shared/types'; import type { EntityFilePaths } from '@/cli/utilities/build/manifest/manifest-extract-config'; @@ -19,7 +14,12 @@ export type UpdateManifestChecksumParams = { manifest: Manifest; builtFileInfos: Map< string, - { checksum: string; builtPath: string; fileFolder: FileFolder } + { + checksum: string; + builtPath: string; + fileFolder: FileFolder; + usesSdkClient?: boolean; + } >; }; @@ -73,11 +73,17 @@ export const manifestUpdateChecksums = ({ if (componentIndex === -1) { continue; } + const builtFileInfo = builtFileInfos.get(builtPath); + result = { ...result, frontComponents: frontComponents.map((component, index) => index === componentIndex - ? { ...component, builtComponentChecksum: checksum } + ? { + ...component, + builtComponentChecksum: checksum, + usesSdkClient: builtFileInfo?.usesSdkClient ?? false, + } : component, ), }; @@ -94,29 +100,5 @@ export const manifestUpdateChecksums = ({ } } - const apiClientChecksums: string[] = []; - - for (const [builtPath, { fileFolder }] of builtFileInfos.entries()) { - const rootBuiltPath = relative(OUTPUT_DIR, builtPath); - - if ( - fileFolder === FileFolder.Dependencies && - rootBuiltPath.startsWith(`${API_CLIENT_DIR}/`) - ) { - const entry = builtFileInfos.get(builtPath); - - if (entry) { - apiClientChecksums.push(entry.checksum); - } - } - } - - if (apiClientChecksums.length > 0) { - result.application.apiClientChecksum = crypto - .createHash('md5') - .update(apiClientChecksums.sort().join('')) - .digest('hex'); - } - return result; }; diff --git a/packages/twenty-sdk/src/cli/utilities/client/client-service.ts b/packages/twenty-sdk/src/cli/utilities/client/client-service.ts index faf44ca3ecc..eb826a0329a 100644 --- a/packages/twenty-sdk/src/cli/utilities/client/client-service.ts +++ b/packages/twenty-sdk/src/cli/utilities/client/client-service.ts @@ -1,88 +1,16 @@ -import { appendFile } from 'node:fs/promises'; import { join } from 'path'; -import { CLIENTS_GENERATED_DIR } from '@/cli/constants/clients-dir'; import { ApiService } from '@/cli/utilities/api/api-service'; -import twentyClientTemplateSource from '@/cli/utilities/client/twenty-client-template.ts?raw'; -import { - emptyDir, - ensureDir, - move, - remove, -} from '@/cli/utilities/file/fs-utils'; -import { generate } from '@genql/cli'; -import { DEFAULT_API_URL_NAME } from 'twenty-shared/application'; - -type ClientWrapperOptions = { - apiClientName: string; - defaultUrl: string; - includeUploadFile: boolean; -}; - -const COMMON_SCALAR_TYPES = { - DateTime: 'string', - JSON: 'Record', - UUID: 'string', -}; - -const STRIPPED_TYPES_START = '// __STRIPPED_DURING_INJECTION_START__'; -const STRIPPED_TYPES_END = '// __STRIPPED_DURING_INJECTION_END__'; -const UPLOAD_FILE_START = '// __UPLOAD_FILE_START__'; -const UPLOAD_FILE_END = '// __UPLOAD_FILE_END__'; - -const buildClientWrapperSource = ( - templateSource: string, - options: ClientWrapperOptions, -): string => { - let source = templateSource; - - source = source.replace( - new RegExp( - `${escapeRegExp(STRIPPED_TYPES_START)}[\\s\\S]*?${escapeRegExp(STRIPPED_TYPES_END)}\\n?`, - ), - '', - ); - - source = source.replace("'__TWENTY_DEFAULT_URL__'", options.defaultUrl); - - source = source.replace(/TwentyGeneratedClient/g, options.apiClientName); - - if (!options.includeUploadFile) { - source = source.replace( - new RegExp( - `\\s*${escapeRegExp(UPLOAD_FILE_START)}[\\s\\S]*?${escapeRegExp(UPLOAD_FILE_END)}\\n?`, - ), - '\n', - ); - } else { - source = source.replace( - new RegExp(`\\s*${escapeRegExp(UPLOAD_FILE_START)}\\n`), - '\n', - ); - source = source.replace( - new RegExp(`\\s*${escapeRegExp(UPLOAD_FILE_END)}\\n`), - '\n', - ); - } - - return `\n// ${options.apiClientName} (auto-injected by twenty-sdk)\n${source}`; -}; - -const escapeRegExp = (value: string): string => - value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +import { replaceCoreClient } from 'twenty-client-sdk/generate'; export class ClientService { private apiService: ApiService; - private clientWrapperTemplateSource: string; constructor(options?: { - clientWrapperTemplateSource?: string; serverUrl?: string; token?: string; skipAuth?: boolean; }) { - this.clientWrapperTemplateSource = - options?.clientWrapperTemplateSource ?? twentyClientTemplateSource; this.apiService = new ApiService({ disableInterceptors: true, serverUrl: options?.serverUrl, @@ -98,15 +26,6 @@ export class ClientService { appPath: string; authToken?: string; }): Promise { - const generatedDir = join( - appPath, - 'node_modules', - 'twenty-sdk', - CLIENTS_GENERATED_DIR, - ); - const coreOutputPath = join(generatedDir, 'core'); - const tempPath = `${coreOutputPath}.tmp`; - const coreSchemaResponse = await this.apiService.getSchema({ authToken }); if (!coreSchemaResponse.success) { @@ -115,66 +34,9 @@ export class ClientService { ); } - await ensureDir(tempPath); - await emptyDir(tempPath); - - await generate({ + await replaceCoreClient({ + packageRoot: join(appPath, 'node_modules', 'twenty-client-sdk'), schema: coreSchemaResponse.data, - output: tempPath, - scalarTypes: COMMON_SCALAR_TYPES, }); - - await this.injectClientWrapper(tempPath, { - apiClientName: 'CoreApiClient', - defaultUrl: `\`\${process.env.${DEFAULT_API_URL_NAME}}/graphql\``, - includeUploadFile: true, - }); - - await remove(coreOutputPath); - await move(tempPath, coreOutputPath); - } - - async generateMetadataClient({ - outputPath, - }: { - outputPath: string; - }): Promise { - const metadataSchemaResponse = await this.apiService.getMetadataSchema(); - - if (!metadataSchemaResponse.success) { - throw new Error( - `Failed to introspect metadata schema: ${JSON.stringify(metadataSchemaResponse.error)}`, - ); - } - - await ensureDir(outputPath); - await emptyDir(outputPath); - - await generate({ - schema: metadataSchemaResponse.data, - output: outputPath, - scalarTypes: { - ...COMMON_SCALAR_TYPES, - Upload: 'File', - }, - }); - - await this.injectClientWrapper(outputPath, { - apiClientName: 'MetadataApiClient', - defaultUrl: `\`\${process.env.${DEFAULT_API_URL_NAME}}/metadata\``, - includeUploadFile: true, - }); - } - - private async injectClientWrapper( - output: string, - options: ClientWrapperOptions, - ): Promise { - const clientContent = buildClientWrapperSource( - this.clientWrapperTemplateSource, - options, - ); - - await appendFile(join(output, 'index.ts'), clientContent); } } diff --git a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator-state.ts b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator-state.ts index c4a36200b3f..c9aa00d195a 100644 --- a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator-state.ts +++ b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator-state.ts @@ -54,6 +54,7 @@ export type OrchestratorStateBuiltFileInfo = { builtPath: string; sourcePath: string; fileFolder: FileFolder; + usesSdkClient?: boolean; }; export type OrchestratorStatePipeline = { diff --git a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator.ts b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator.ts index c3bc220a344..dd600edf958 100644 --- a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator.ts +++ b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/dev-mode-orchestrator.ts @@ -196,10 +196,6 @@ export class DevModeOrchestrator { }); this.skipTypecheck = false; - - await this.uploadFilesStep.copyAndUploadApiClientFiles( - this.state.appPath, - ); } } diff --git a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/start-watchers-orchestrator-step.ts b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/start-watchers-orchestrator-step.ts index 38f17424209..42fcf2f2e3e 100644 --- a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/start-watchers-orchestrator-step.ts +++ b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/start-watchers-orchestrator-step.ts @@ -19,6 +19,7 @@ export type FileBuiltEvent = { builtPath: string; sourcePath: string; checksum: string; + usesSdkClient?: boolean; }; export type StartWatchersOrchestratorStepOutput = { @@ -142,6 +143,7 @@ export class StartWatchersOrchestratorStep { builtPath: event.builtPath, sourcePath: event.sourcePath, fileFolder: event.fileFolder, + usesSdkClient: event.usesSdkClient, }); this.onFileBuilt(event); diff --git a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/upload-files-orchestrator-step.ts b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/upload-files-orchestrator-step.ts index c91d33170d5..b5ee8a5315e 100644 --- a/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/upload-files-orchestrator-step.ts +++ b/packages/twenty-sdk/src/cli/utilities/dev/orchestrator/steps/upload-files-orchestrator-step.ts @@ -3,15 +3,7 @@ import { type OrchestratorStateBuiltFileInfo, } from '@/cli/utilities/dev/orchestrator/dev-mode-orchestrator-state'; import { FileUploader } from '@/cli/utilities/file/file-uploader'; -import { copy, ensureDir, pathExists } from '@/cli/utilities/file/fs-utils'; -import crypto from 'crypto'; -import { readFile } from 'node:fs/promises'; -import { join } from 'path'; -import { CLIENTS_GENERATED_DIR } from '@/cli/constants/clients-dir'; -import { OUTPUT_DIR, API_CLIENT_DIR } from 'twenty-shared/application'; -import { FileFolder } from 'twenty-shared/types'; - -const API_CLIENT_FILES = ['core/types.ts', 'core/schema.ts']; +import { type FileFolder } from 'twenty-shared/types'; export type UploadFilesOrchestratorStepOutput = { fileUploader: FileUploader | null; @@ -119,48 +111,6 @@ export class UploadFilesOrchestratorStep { this.notify(); } - async copyAndUploadApiClientFiles(appPath: string): Promise { - const generatedDir = join( - appPath, - 'node_modules', - 'twenty-sdk', - CLIENTS_GENERATED_DIR, - ); - - if (!(await pathExists(generatedDir))) { - return; - } - - const outputDir = join(appPath, OUTPUT_DIR, API_CLIENT_DIR); - - await ensureDir(outputDir); - - for (const fileName of API_CLIENT_FILES) { - const absoluteSourcePath = join(generatedDir, fileName); - - if (!(await pathExists(absoluteSourcePath))) { - continue; - } - - await copy(absoluteSourcePath, join(outputDir, fileName)); - - const content = await readFile(absoluteSourcePath); - const checksum = crypto.createHash('md5').update(content).digest('hex'); - - const builtPath = join(OUTPUT_DIR, API_CLIENT_DIR, fileName); - const sourcePath = join(API_CLIENT_DIR, fileName); - - this.state.steps.uploadFiles.output.builtFileInfos.set(builtPath, { - checksum, - builtPath, - sourcePath, - fileFolder: FileFolder.Dependencies, - }); - - this.uploadFile(builtPath, sourcePath, FileFolder.Dependencies); - } - } - private uploadPendingFiles(): void { for (const [ builtPath, diff --git a/packages/twenty-sdk/src/clients/generated/core/index.ts b/packages/twenty-sdk/src/clients/generated/core/index.ts deleted file mode 100644 index aa9460a41d8..00000000000 --- a/packages/twenty-sdk/src/clients/generated/core/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Stub — overwritten by `twenty build` or `twenty dev` -export class CoreApiClient {} diff --git a/packages/twenty-sdk/src/clients/index.ts b/packages/twenty-sdk/src/clients/index.ts deleted file mode 100644 index d35a443e188..00000000000 --- a/packages/twenty-sdk/src/clients/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { CoreApiClient } from './generated/core/index'; -export * as CoreSchema from './generated/core/schema'; -export { MetadataApiClient } from './generated/metadata/index'; -export * as MetadataSchema from './generated/metadata/schema'; diff --git a/packages/twenty-sdk/src/front-component-renderer/host/components/FrontComponentRenderer.tsx b/packages/twenty-sdk/src/front-component-renderer/host/components/FrontComponentRenderer.tsx index b2ad4dfa2dd..4d3fdf3f9ac 100644 --- a/packages/twenty-sdk/src/front-component-renderer/host/components/FrontComponentRenderer.tsx +++ b/packages/twenty-sdk/src/front-component-renderer/host/components/FrontComponentRenderer.tsx @@ -2,6 +2,7 @@ import { FrontComponentErrorEffect } from '@/front-component-renderer/remote/com import { FrontComponentHostCommunicationApiEffect } from '@/front-component-renderer/remote/components/FrontComponentHostCommunicationApiEffect'; import { FrontComponentUpdateContextEffect } from '@/front-component-renderer/remote/components/FrontComponentUpdateContextEffect'; import { type FrontComponentHostCommunicationApi } from '@/front-component-renderer/types/FrontComponentHostCommunicationApi'; +import { type SdkClientUrls } from '@/front-component-renderer/types/HostToWorkerRenderContext'; import { type WorkerExports } from '@/front-component-renderer/types/WorkerExports'; import { type FrontComponentExecutionContext } from '@/sdk/front-component-api'; import { type ThreadWebWorker } from '@quilted/threads'; @@ -20,6 +21,7 @@ type FrontComponentContentProps = { componentUrl: string; applicationAccessToken?: string; apiUrl?: string; + sdkClientUrls?: SdkClientUrls; executionContext: FrontComponentExecutionContext; frontComponentHostCommunicationApi: FrontComponentHostCommunicationApi; onError: (error?: Error) => void; @@ -30,6 +32,7 @@ export const FrontComponentRenderer = ({ componentUrl, applicationAccessToken, apiUrl, + sdkClientUrls, executionContext, frontComponentHostCommunicationApi, onError, @@ -50,6 +53,7 @@ export const FrontComponentRenderer = ({ componentUrl={componentUrl} applicationAccessToken={applicationAccessToken} apiUrl={apiUrl} + sdkClientUrls={sdkClientUrls} frontComponentId={executionContext.frontComponentId} frontComponentHostCommunicationApi={frontComponentHostCommunicationApi} setReceiver={setReceiver} @@ -65,6 +69,7 @@ export const FrontComponentRenderer = ({ setThread, applicationAccessToken, apiUrl, + sdkClientUrls, executionContext.frontComponentId, ]); diff --git a/packages/twenty-sdk/src/front-component-renderer/index.ts b/packages/twenty-sdk/src/front-component-renderer/index.ts index 0988d1fec53..bcb63f44e03 100644 --- a/packages/twenty-sdk/src/front-component-renderer/index.ts +++ b/packages/twenty-sdk/src/front-component-renderer/index.ts @@ -126,6 +126,9 @@ export type { export { createRemoteWorker } from './remote/worker/utils/createRemoteWorker'; export type { FrontComponentExecutionContext } from '../sdk/front-component-api'; export type { FrontComponentHostCommunicationApi } from './types/FrontComponentHostCommunicationApi'; -export type { HostToWorkerRenderContext } from './types/HostToWorkerRenderContext'; +export type { + HostToWorkerRenderContext, + SdkClientUrls, +} from './types/HostToWorkerRenderContext'; export type { PropertySchema } from './types/PropertySchema'; export type { WorkerExports } from './types/WorkerExports'; diff --git a/packages/twenty-sdk/src/front-component-renderer/remote/components/FrontComponentWorkerEffect.tsx b/packages/twenty-sdk/src/front-component-renderer/remote/components/FrontComponentWorkerEffect.tsx index 7a01f635ba1..22dde492379 100644 --- a/packages/twenty-sdk/src/front-component-renderer/remote/components/FrontComponentWorkerEffect.tsx +++ b/packages/twenty-sdk/src/front-component-renderer/remote/components/FrontComponentWorkerEffect.tsx @@ -4,6 +4,7 @@ import { useEffect, useRef } from 'react'; import { type ConfirmationModalCaller } from 'twenty-shared/types'; import { type CommandConfirmationModalResult } from '../../../sdk/front-component-api/globals/frontComponentHostCommunicationApi'; import { type FrontComponentHostCommunicationApi } from '../../types/FrontComponentHostCommunicationApi'; +import { type SdkClientUrls } from '../../types/HostToWorkerRenderContext'; import { type WorkerExports } from '../../types/WorkerExports'; import { createRemoteWorker } from '../worker/utils/createRemoteWorker'; @@ -20,6 +21,7 @@ type FrontComponentWorkerEffectProps = { componentUrl: string; applicationAccessToken?: string; apiUrl?: string; + sdkClientUrls?: SdkClientUrls; frontComponentId: string; frontComponentHostCommunicationApi: FrontComponentHostCommunicationApi; setReceiver: React.Dispatch>; @@ -36,6 +38,7 @@ export const FrontComponentWorkerEffect = ({ componentUrl, applicationAccessToken, apiUrl, + sdkClientUrls, frontComponentId, frontComponentHostCommunicationApi, setReceiver, @@ -105,6 +108,7 @@ export const FrontComponentWorkerEffect = ({ componentUrl, applicationAccessToken, apiUrl, + sdkClientUrls, }) .catch((error: Error) => { setError(error); @@ -126,6 +130,7 @@ export const FrontComponentWorkerEffect = ({ componentUrl, applicationAccessToken, apiUrl, + sdkClientUrls, frontComponentId, setError, setReceiver, diff --git a/packages/twenty-sdk/src/front-component-renderer/remote/worker/remote-worker.ts b/packages/twenty-sdk/src/front-component-renderer/remote/worker/remote-worker.ts index e8251a84c41..9ac233e3e77 100644 --- a/packages/twenty-sdk/src/front-component-renderer/remote/worker/remote-worker.ts +++ b/packages/twenty-sdk/src/front-component-renderer/remote/worker/remote-worker.ts @@ -37,6 +37,49 @@ exposeGlobals({ __HTML_TAG_TO_CUSTOM_ELEMENT_TAG__: HTML_TAG_TO_CUSTOM_ELEMENT_TAG, }); +const fetchComponentSource = async ( + url: string, + headers?: Record, +): Promise => { + const response = await fetch(url, { headers }); + + if (!response.ok) { + throw new Error( + `Failed to fetch ${url}: ${response.status} ${response.statusText}`, + ); + } + + return response.text(); +}; + +const SDK_IMPORT_SPECIFIERS = [ + 'twenty-client-sdk/core', + 'twenty-client-sdk/metadata', +] as const; + +// Rewrites bare SDK import specifiers to the blob URLs provided by the host. +const rewriteSdkImports = ( + source: string, + sdkClientUrls: { core: string; metadata: string }, +): string => { + const specifierToBlobUrl: Record = { + 'twenty-client-sdk/core': sdkClientUrls.core, + 'twenty-client-sdk/metadata': sdkClientUrls.metadata, + }; + + let rewritten = source; + + for (const [specifier, blobUrl] of Object.entries(specifierToBlobUrl)) { + rewritten = rewritten + .split(`"${specifier}"`) + .join(`"${blobUrl}"`) + .split(`'${specifier}'`) + .join(`'${blobUrl}'`); + } + + return rewritten; +}; + const render: WorkerExports['render'] = async ( connection: RemoteConnection, renderContext: HostToWorkerRenderContext, @@ -61,25 +104,30 @@ const render: WorkerExports['render'] = async ( }); } - const response = await fetch(renderContext.componentUrl, { - headers: isDefined(renderContext.applicationAccessToken) - ? { Authorization: `Bearer ${renderContext.applicationAccessToken}` } - : undefined, - }); + const authHeaders = isDefined(renderContext.applicationAccessToken) + ? { Authorization: `Bearer ${renderContext.applicationAccessToken}` } + : undefined; - if (!response.ok) { - throw new Error( - `Failed to fetch front component from ${renderContext.componentUrl}: ${response.status} ${response.statusText}`, + const componentSource = await fetchComponentSource( + renderContext.componentUrl, + authHeaders, + ); + + const hasSdkImports = + isDefined(renderContext.sdkClientUrls) && + SDK_IMPORT_SPECIFIERS.some((specifier) => + componentSource.includes(specifier), ); - } - const responseText = await response.text(); + const finalSource = hasSdkImports + ? rewriteSdkImports(componentSource, renderContext.sdkClientUrls!) + : componentSource; - const blob = new Blob([responseText], { + const componentBlob = new Blob([finalSource], { type: 'application/javascript', }); - const importUrl = URL.createObjectURL(blob); + const importUrl = URL.createObjectURL(componentBlob); try { /* @vite-ignore */ diff --git a/packages/twenty-sdk/src/front-component-renderer/types/HostToWorkerRenderContext.ts b/packages/twenty-sdk/src/front-component-renderer/types/HostToWorkerRenderContext.ts index a56aeb5305a..dc4eb9bb9b2 100644 --- a/packages/twenty-sdk/src/front-component-renderer/types/HostToWorkerRenderContext.ts +++ b/packages/twenty-sdk/src/front-component-renderer/types/HostToWorkerRenderContext.ts @@ -1,5 +1,11 @@ +export type SdkClientUrls = { + core: string; + metadata: string; +}; + export type HostToWorkerRenderContext = { componentUrl: string; applicationAccessToken?: string; apiUrl?: string; + sdkClientUrls?: SdkClientUrls; }; diff --git a/packages/twenty-sdk/src/sdk/application/application-config.ts b/packages/twenty-sdk/src/sdk/application/application-config.ts index 7d80263e6f6..5725b9ed9d9 100644 --- a/packages/twenty-sdk/src/sdk/application/application-config.ts +++ b/packages/twenty-sdk/src/sdk/application/application-config.ts @@ -4,7 +4,6 @@ export type ApplicationConfig = Omit< ApplicationManifest, | 'packageJsonChecksum' | 'yarnLockChecksum' - | 'apiClientChecksum' | 'postInstallLogicFunctionUniversalIdentifier' | 'preInstallLogicFunctionUniversalIdentifier' >; diff --git a/packages/twenty-sdk/src/sdk/front-component-config.ts b/packages/twenty-sdk/src/sdk/front-component-config.ts index 38d9dc193ae..5c59c97da4b 100644 --- a/packages/twenty-sdk/src/sdk/front-component-config.ts +++ b/packages/twenty-sdk/src/sdk/front-component-config.ts @@ -18,6 +18,7 @@ export type FrontComponentConfig = Omit< | 'builtComponentPath' | 'builtComponentChecksum' | 'componentName' + | 'usesSdkClient' | 'command' > & { component: FrontComponentType; diff --git a/packages/twenty-sdk/vite.config.node.ts b/packages/twenty-sdk/vite.config.node.ts index e5455c7c4f1..52b92c3980e 100644 --- a/packages/twenty-sdk/vite.config.node.ts +++ b/packages/twenty-sdk/vite.config.node.ts @@ -28,7 +28,6 @@ export default defineConfig(() => { cli: 'src/cli/cli.ts', operations: 'src/cli/operations/index.ts', build: 'src/build/index.ts', - clients: 'src/clients/index.ts', }, name: 'twenty-sdk', }, diff --git a/packages/twenty-server/package.json b/packages/twenty-server/package.json index 1ef579a236e..57eaa14c38b 100644 --- a/packages/twenty-server/package.json +++ b/packages/twenty-server/package.json @@ -227,6 +227,7 @@ "@types/unzipper": "^0", "@yarnpkg/types": "^4.0.0", "rimraf": "^5.0.5", + "twenty-client-sdk": "workspace:*", "twenty-emails": "workspace:*", "twenty-shared": "workspace:*" }, diff --git a/packages/twenty-server/project.json b/packages/twenty-server/project.json index edb65f0bffe..86f4c44fc31 100644 --- a/packages/twenty-server/project.json +++ b/packages/twenty-server/project.json @@ -10,7 +10,11 @@ "options": { "cwd": "packages/twenty-server", "parallel": false, - "commands": ["rimraf dist", "nest build --path ./tsconfig.build.json"] + "commands": [ + "rimraf dist", + "nest build --path ./tsconfig.build.json", + "mkdir -p dist/assets/twenty-client-sdk && cp ../twenty-client-sdk/package.json dist/assets/twenty-client-sdk/ && cp -r ../twenty-client-sdk/dist dist/assets/twenty-client-sdk/dist" + ] }, "dependsOn": ["^build"] }, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command.ts new file mode 100644 index 00000000000..e88572e5cc5 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command.ts @@ -0,0 +1,67 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { Command } from 'nest-commander'; +import { Repository } from 'typeorm'; + +import { ActiveOrSuspendedWorkspacesMigrationCommandRunner } from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; +import { RunOnWorkspaceArgs } from 'src/database/commands/command-runners/workspaces-migration.command-runner'; +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; +import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager'; + +@Command({ + name: 'upgrade:1-20:generate-application-sdk-clients', + description: + 'Generate SDK client archives for all existing applications so drivers do not crash with ARCHIVE_NOT_FOUND', +}) +export class GenerateApplicationSdkClientsCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { + constructor( + @InjectRepository(WorkspaceEntity) + protected readonly workspaceRepository: Repository, + protected readonly twentyORMGlobalManager: GlobalWorkspaceOrmManager, + protected readonly dataSourceService: DataSourceService, + @InjectRepository(ApplicationEntity) + private readonly applicationRepository: Repository, + private readonly sdkClientGenerationService: SdkClientGenerationService, + ) { + super(workspaceRepository, twentyORMGlobalManager, dataSourceService); + } + + override async runOnWorkspace({ + workspaceId, + options, + }: RunOnWorkspaceArgs): Promise { + const dryRun = options.dryRun ?? false; + + const applications = await this.applicationRepository.find({ + where: { workspaceId }, + }); + + this.logger.log( + `Found ${applications.length} application(s) in workspace ${workspaceId}`, + ); + + for (const application of applications) { + if (dryRun) { + this.logger.log( + `[DRY RUN] Would generate SDK client for application ${application.universalIdentifier} (${application.id})`, + ); + continue; + } + + try { + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: application.id, + applicationUniversalIdentifier: application.universalIdentifier, + }); + } catch (error) { + this.logger.error( + `Failed to generate SDK client for application ${application.universalIdentifier} (${application.id}): ${error instanceof Error ? error.message : String(error)}`, + ); + } + } + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts index 49b9196f423..9c0f371770e 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/1-20/1-20-upgrade-version-command.module.ts @@ -7,6 +7,7 @@ import { BackfillNavigationMenuItemTypeCommand } from 'src/database/commands/upg import { BackfillPageLayoutsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-page-layouts.command'; import { BackfillSelectFieldOptionIdsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-backfill-select-field-option-ids.command'; import { DeleteOrphanNavigationMenuItemsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-delete-orphan-navigation-menu-items.command'; +import { GenerateApplicationSdkClientsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command'; import { IdentifyObjectPermissionMetadataCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-identify-object-permission-metadata.command'; import { IdentifyPermissionFlagMetadataCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-identify-permission-flag-metadata.command'; import { MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigrationCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-make-object-permission-universal-identifier-and-application-id-not-nullable-migration.command'; @@ -16,8 +17,10 @@ import { MigrateRichTextToTextCommand } from 'src/database/commands/upgrade-vers import { SeedCliApplicationRegistrationCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command'; import { UpdateStandardIndexViewNamesCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command'; import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; +import { SdkClientModule } from 'src/engine/core-modules/sdk-client/sdk-client.module'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity'; @@ -37,6 +40,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo imports: [ TypeOrmModule.forFeature([ WorkspaceEntity, + ApplicationEntity, ConnectedAccountEntity, MessageChannelEntity, CalendarChannelEntity, @@ -53,6 +57,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo ApplicationRegistrationModule, WorkspaceMigrationModule, FeatureFlagModule, + SdkClientModule, WorkflowCommonModule, ], providers: [ @@ -66,6 +71,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo BackfillPageLayoutsCommand, BackfillSelectFieldOptionIdsCommand, DeleteOrphanNavigationMenuItemsCommand, + GenerateApplicationSdkClientsCommand, SeedCliApplicationRegistrationCommand, MigrateRichTextToTextCommand, MigrateMessagingInfrastructureToMetadataCommand, @@ -82,6 +88,7 @@ import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-commo BackfillPageLayoutsCommand, BackfillSelectFieldOptionIdsCommand, DeleteOrphanNavigationMenuItemsCommand, + GenerateApplicationSdkClientsCommand, SeedCliApplicationRegistrationCommand, MigrateRichTextToTextCommand, MigrateMessagingInfrastructureToMetadataCommand, diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts index 0db41b1ad6d..bf59c80ffee 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts @@ -45,6 +45,7 @@ import { MakeObjectPermissionUniversalIdentifierAndApplicationIdNotNullableMigra import { MakePermissionFlagUniversalIdentifierAndApplicationIdNotNullableMigrationCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-make-permission-flag-universal-identifier-and-application-id-not-nullable-migration.command'; import { MigrateMessagingInfrastructureToMetadataCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-migrate-messaging-infrastructure-to-metadata.command'; import { MigrateRichTextToTextCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-migrate-rich-text-to-text.command'; +import { GenerateApplicationSdkClientsCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-generate-application-sdk-clients.command'; import { SeedCliApplicationRegistrationCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-seed-cli-application-registration.command'; import { UpdateStandardIndexViewNamesCommand } from 'src/database/commands/upgrade-version-command/1-20/1-20-update-standard-index-view-names.command'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; @@ -105,6 +106,7 @@ export class UpgradeCommand extends UpgradeCommandRunner { protected readonly backfillCommandMenuItemsCommand: BackfillCommandMenuItemsCommand, protected readonly deleteOrphanNavigationMenuItemsCommand: DeleteOrphanNavigationMenuItemsCommand, protected readonly backfillPageLayoutsCommand: BackfillPageLayoutsCommand, + protected readonly generateApplicationSdkClientsCommand: GenerateApplicationSdkClientsCommand, protected readonly seedCliApplicationRegistrationCommand: SeedCliApplicationRegistrationCommand, protected readonly migrateRichTextToTextCommand: MigrateRichTextToTextCommand, protected readonly migrateMessagingInfrastructureToMetadataCommand: MigrateMessagingInfrastructureToMetadataCommand, @@ -174,6 +176,7 @@ export class UpgradeCommand extends UpgradeCommandRunner { this.backfillFieldWidgetsCommand, this.backfillSelectFieldOptionIdsCommand, this.updateStandardIndexViewNamesCommand, + this.generateApplicationSdkClientsCommand, ]; this.allCommands = { diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1773000000000-add-is-sdk-layer-stale-to-application.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1773000000000-add-is-sdk-layer-stale-to-application.ts new file mode 100644 index 00000000000..28536dcfff6 --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1773000000000-add-is-sdk-layer-stale-to-application.ts @@ -0,0 +1,19 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class AddIsSdkLayerStaleToApplication1773000000000 + implements MigrationInterface +{ + name = 'AddIsSdkLayerStaleToApplication1773000000000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."application" ADD "isSdkLayerStale" boolean NOT NULL DEFAULT false`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."application" DROP COLUMN "isSdkLayerStale"`, + ); + } +} diff --git a/packages/twenty-server/src/database/typeorm/core/migrations/common/1773100000000-add-uses-sdk-client-to-front-component.ts b/packages/twenty-server/src/database/typeorm/core/migrations/common/1773100000000-add-uses-sdk-client-to-front-component.ts new file mode 100644 index 00000000000..8fc5463823b --- /dev/null +++ b/packages/twenty-server/src/database/typeorm/core/migrations/common/1773100000000-add-uses-sdk-client-to-front-component.ts @@ -0,0 +1,19 @@ +import { type MigrationInterface, type QueryRunner } from 'typeorm'; + +export class AddUsesSdkClientToFrontComponent1773100000000 + implements MigrationInterface +{ + name = 'AddUsesSdkClientToFrontComponent1773100000000'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."frontComponent" ADD "usesSdkClient" boolean NOT NULL DEFAULT false`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "core"."frontComponent" DROP COLUMN "usesSdkClient"`, + ); + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts index fe05df7aa95..0c2e477729e 100644 --- a/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/core-graphql-api.module.ts @@ -4,7 +4,7 @@ import { ScalarsExplorerService } from 'src/engine/api/graphql/services/scalars- import { WorkspaceResolverBuilderModule } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module'; import { WorkspaceSchemaBuilderModule } from 'src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; -import { MetadataEngineModule } from 'src/engine/metadata-modules/metadata-engine.module'; +import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module'; @@ -12,7 +12,7 @@ import { WorkspaceSchemaFactory } from './workspace-schema.factory'; @Module({ imports: [ - MetadataEngineModule, + DataSourceModule, WorkspaceSchemaBuilderModule, WorkspaceResolverBuilderModule, WorkspaceCacheStorageModule, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts index c09ea57e670..9328b9f7c4e 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/utils/workspace-query-runner-graphql-api-exception-handler.util.ts @@ -23,6 +23,10 @@ import { twentyORMGraphqlApiExceptionHandler } from 'src/engine/twenty-orm/utils import { WorkflowQueryValidationException } from 'src/modules/workflow/common/exceptions/workflow-query-validation.exception'; import { workflowQueryValidationGraphqlApiExceptionHandler } from 'src/modules/workflow/common/utils/workflow-query-validation-graphql-api-exception-handler.util'; +export interface QueryFailedErrorWithCode extends QueryFailedError { + code: string; +} + export const workspaceQueryRunnerGraphqlApiExceptionHandler = ( error: Error | QueryFailedError, ) => { diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts index ef27ca7370a..0fd8100ca5b 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-query-runner/workspace-query-runner.module.ts @@ -4,7 +4,6 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { TelemetryListener } from 'src/engine/api/graphql/workspace-query-runner/listeners/telemetry.listener'; import { WorkspaceQueryHookModule } from 'src/engine/api/graphql/workspace-query-runner/workspace-query-hook/workspace-query-hook.module'; import { AuditModule } from 'src/engine/core-modules/audit/audit.module'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity'; import { FileModule } from 'src/engine/core-modules/file/file.module'; import { RecordPositionModule } from 'src/engine/core-modules/record-position/record-position.module'; @@ -17,7 +16,6 @@ import { EntityEventsToDbListener } from './listeners/entity-events-to-db.listen @Module({ imports: [ - AuthModule, WorkspaceDataSourceModule, WorkspaceQueryHookModule, TypeOrmModule.forFeature([FeatureFlagEntity]), diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/exceptions/workspace-graphql-schema.exception.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/exceptions/workspace-graphql-schema.exception.ts new file mode 100644 index 00000000000..3cfaae4e1d5 --- /dev/null +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/exceptions/workspace-graphql-schema.exception.ts @@ -0,0 +1,36 @@ +import { type MessageDescriptor } from '@lingui/core'; +import { assertUnreachable } from 'twenty-shared/utils'; + +import { STANDARD_ERROR_MESSAGE } from 'src/engine/api/common/common-query-runners/errors/standard-error-message.constant'; +import { CustomException } from 'src/utils/custom-exception'; + +export enum WorkspaceGraphQLSchemaExceptionCode { + QUERY_TYPE_NOT_FOUND = 'QUERY_TYPE_NOT_FOUND', + MUTATION_TYPE_NOT_FOUND = 'MUTATION_TYPE_NOT_FOUND', +} + +const getWorkspaceGraphQLSchemaExceptionUserFriendlyMessage = ( + code: WorkspaceGraphQLSchemaExceptionCode, +) => { + switch (code) { + case WorkspaceGraphQLSchemaExceptionCode.QUERY_TYPE_NOT_FOUND: + case WorkspaceGraphQLSchemaExceptionCode.MUTATION_TYPE_NOT_FOUND: + return STANDARD_ERROR_MESSAGE; + default: + assertUnreachable(code); + } +}; + +export class WorkspaceGraphQLSchemaException extends CustomException { + constructor( + message: string, + code: WorkspaceGraphQLSchemaExceptionCode, + { userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {}, + ) { + super(message, code, { + userFriendlyMessage: + userFriendlyMessage ?? + getWorkspaceGraphQLSchemaExceptionUserFriendlyMessage(code), + }); + } +} diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts index 595014f998d..63278c73fa1 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator.ts @@ -6,20 +6,13 @@ import { } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; -import { CompositeFieldMetadataGqlEnumTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/enum-types/composite-field-metadata-gql-enum-type.generator'; -import { EnumFieldMetadataGqlEnumTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/enum-types/enum-field-metadata-gql-enum-type.generator'; -import { CompositeFieldMetadataGqlInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/composite-field-metadata-gql-input-type.generator'; -import { GroupByDateGranularityInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/group-by-input/group-by-date-granularity-gql-input-type.generator'; -import { ObjectMetadataGqlInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/object-metadata-gql-input-type.generator'; -import { RelationConnectGqlInputTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/relation-connect-gql-input-type.generator'; -import { CompositeFieldMetadataGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/composite-field-metadata-gql-object-type.generator'; -import { ConnectionGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/connection-gql-object-type.generator'; -import { EdgeGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/edge-gql-object-type.generator'; -import { GroupByConnectionGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/group-by-connection-gql-object-type.generator'; -import { ObjectMetadataGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-gql-object-type.generator'; -import { ObjectMetadataWithRelationsGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator'; -import { MutationTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/mutation-type.generator'; -import { QueryTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator'; +import { WorkspaceResolverBuilderService } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service'; +import { + type TypeGenerators, + instantiateTypeGenerators, +} from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage'; import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type'; import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util'; import { FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type'; @@ -30,54 +23,54 @@ export class GqlTypeGenerator { private readonly logger = new Logger(GqlTypeGenerator.name); constructor( - private readonly objectMetadataGqlObjectTypeGenerator: ObjectMetadataGqlObjectTypeGenerator, - private readonly objectMetadataGqlInputTypeGenerator: ObjectMetadataGqlInputTypeGenerator, - private readonly compositeFieldMetadataGqlObjectTypeGenerator: CompositeFieldMetadataGqlObjectTypeGenerator, - private readonly enumFieldMetadataGqlEnumTypeGenerator: EnumFieldMetadataGqlEnumTypeGenerator, - private readonly compositeFieldMetadataGqlEnumTypeGenerator: CompositeFieldMetadataGqlEnumTypeGenerator, - private readonly compositeFieldMetadataGqlInputTypeGenerator: CompositeFieldMetadataGqlInputTypeGenerator, - private readonly edgeGqlObjectTypeGenerator: EdgeGqlObjectTypeGenerator, - private readonly connectionGqlObjectTypeGenerator: ConnectionGqlObjectTypeGenerator, - private readonly groupByConnectionGqlObjectTypeGenerator: GroupByConnectionGqlObjectTypeGenerator, - private readonly objectMetadataWithRelationsGqlObjectTypeGenerator: ObjectMetadataWithRelationsGqlObjectTypeGenerator, - private readonly relationConnectGqlInputTypeGenerator: RelationConnectGqlInputTypeGenerator, - private readonly groupByDateGranularityInputTypeGenerator: GroupByDateGranularityInputTypeGenerator, - private readonly queryTypeGenerator: QueryTypeGenerator, - private readonly mutationTypeGenerator: MutationTypeGenerator, + private readonly typeMapperService: TypeMapperService, + private readonly workspaceResolverBuilderService: WorkspaceResolverBuilderService, ) {} - async buildAndStore(context: SchemaGenerationContext) { + async buildAndStore( + context: SchemaGenerationContext, + ): Promise { + const gqlTypesStorage = new GqlTypesStorage(); + const generators = instantiateTypeGenerators( + gqlTypesStorage, + this.typeMapperService, + this.workspaceResolverBuilderService, + ); + const compositeTypeCollection = [...compositeTypeDefinitions.values()]; - this.buildAndStoreCompositeFieldMetadataGqlTypes(compositeTypeCollection); - this.buildAndStoreDateFieldMetadataGroupByGqlTypes(); - this.buildAndStoreObjectMetadataGqlTypes(context); - await this.queryTypeGenerator.buildAndStore(context); - this.mutationTypeGenerator.buildAndStore(context); + this.buildAndStoreCompositeFieldMetadataGqlTypes( + compositeTypeCollection, + generators, + ); + generators.groupByDateGranularityInputTypeGenerator.buildAndStore(); + this.buildAndStoreObjectMetadataGqlTypes(context, generators); + await generators.queryTypeGenerator.buildAndStore(context); + generators.mutationTypeGenerator.buildAndStore(context); + + return gqlTypesStorage; } private buildAndStoreCompositeFieldMetadataGqlTypes( compositeTypes: CompositeType[], + generators: TypeGenerators, ) { for (const compositeType of compositeTypes) { - this.compositeFieldMetadataGqlEnumTypeGenerator.buildAndStore( + generators.compositeFieldMetadataGqlEnumTypeGenerator.buildAndStore( compositeType, ); - this.compositeFieldMetadataGqlObjectTypeGenerator.buildAndStore( + generators.compositeFieldMetadataGqlObjectTypeGenerator.buildAndStore( compositeType, ); - this.compositeFieldMetadataGqlInputTypeGenerator.buildAndStore( + generators.compositeFieldMetadataGqlInputTypeGenerator.buildAndStore( compositeType, ); } } - private buildAndStoreDateFieldMetadataGroupByGqlTypes() { - this.groupByDateGranularityInputTypeGenerator.buildAndStore(); - } - private buildAndStoreObjectMetadataGqlTypes( context: SchemaGenerationContext, + generators: TypeGenerators, ) { const { flatObjectMetadataMaps, flatFieldMetadataMaps } = context; const objectMetadataCollection = Object.values( @@ -96,35 +89,35 @@ export class GqlTypeGenerator { flatFieldMetadataMaps, ); - this.enumFieldMetadataGqlEnumTypeGenerator.buildAndStore( + generators.enumFieldMetadataGqlEnumTypeGenerator.buildAndStore( flatObjectMetadata, fields, ); - this.objectMetadataGqlObjectTypeGenerator.buildAndStore( + generators.objectMetadataGqlObjectTypeGenerator.buildAndStore( flatObjectMetadata, fields, ); - this.edgeGqlObjectTypeGenerator.buildAndStore(flatObjectMetadata); - this.connectionGqlObjectTypeGenerator.buildAndStore( + generators.edgeGqlObjectTypeGenerator.buildAndStore(flatObjectMetadata); + generators.connectionGqlObjectTypeGenerator.buildAndStore( flatObjectMetadata, fields, ); - this.groupByConnectionGqlObjectTypeGenerator.buildAndStore( + generators.groupByConnectionGqlObjectTypeGenerator.buildAndStore( flatObjectMetadata, ); - this.relationConnectGqlInputTypeGenerator.buildAndStore( + generators.relationConnectGqlInputTypeGenerator.buildAndStore( flatObjectMetadata, fields, context, ); - this.objectMetadataGqlInputTypeGenerator.buildAndStore( + generators.objectMetadataGqlInputTypeGenerator.buildAndStore( flatObjectMetadata, fields, context, ); if (this.objectContainsRelationOrMorphField(fields)) { - this.objectMetadataWithRelationsGqlObjectTypeGenerator.buildAndStore( + generators.objectMetadataWithRelationsGqlObjectTypeGenerator.buildAndStore( flatObjectMetadata, fields, context, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/create-input/composite-field-metadata-create-gql-input-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/create-input/composite-field-metadata-create-gql-input-type.generator.ts index dd2b410c8bd..b9e706d3c2b 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/create-input/composite-field-metadata-create-gql-input-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/create-input/composite-field-metadata-create-gql-input-type.generator.ts @@ -1,6 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { + GraphQLEnumType, GraphQLInputFieldConfigMap, GraphQLInputObjectType, isObjectType, @@ -71,7 +72,7 @@ export class CompositeFieldMetadataCreateGqlInputTypeGenerator { const typeOptions = computeCompositeFieldTypeOptions(property); const type = isEnumFieldMetadataType(property.type) - ? this.gqlTypesStorage.getGqlTypeByKey(key) + ? this.gqlTypesStorage.getGqlTypeByKey(key) : this.typeMapperService.mapToPreBuiltGraphQLInputType({ fieldMetadataType: property.type, typeOptions, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/update-input/composite-field-metadata-update-gql-input-type.generator.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/update-input/composite-field-metadata-update-gql-input-type.generator.ts index d86800e2022..4c81da49412 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/update-input/composite-field-metadata-update-gql-input-type.generator.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/input-types/update-input/composite-field-metadata-update-gql-input-type.generator.ts @@ -1,6 +1,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { + GraphQLEnumType, GraphQLInputFieldConfigMap, GraphQLInputObjectType, isObjectType, @@ -72,7 +73,7 @@ export class CompositeFieldMetadataUpdateGqlInputTypeGenerator { const typeOptions = computeCompositeFieldTypeOptions(property); const type = isEnumFieldMetadataType(property.type) - ? this.gqlTypesStorage.getGqlTypeByKey(key) + ? this.gqlTypesStorage.getGqlTypeByKey(key) : this.typeMapperService.mapToPreBuiltGraphQLInputType({ fieldMetadataType: property.type, typeOptions, diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators.ts index 63103311566..b78e7399d1a 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators.ts @@ -1,3 +1,4 @@ +import { WorkspaceResolverBuilderService } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.service'; import { ArgsTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/args-type/args-type.generator'; import { CompositeFieldMetadataGqlEnumTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/enum-types/composite-field-metadata-gql-enum-type.generator'; import { EnumFieldMetadataGqlEnumTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/enum-types/enum-field-metadata-gql-enum-type.generator'; @@ -26,42 +27,152 @@ import { GroupByConnectionGqlObjectTypeGenerator } from 'src/engine/api/graphql/ import { ObjectMetadataGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-gql-object-type.generator'; import { ObjectMetadataWithRelationsGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/object-metadata-with-relations-gql-object-type.generator'; import { RelationFieldMetadataGqlObjectTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/object-types/relation-field-metadata-gql-object-type.generator'; -import { OrphanedTypesGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/orphaned-types.generator'; import { MutationTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/mutation-type.generator'; import { QueryTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator'; import { RootTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/root-type.generator'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; +import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage'; -export const workspaceSchemaBuilderTypeGenerators = [ - CompositeFieldMetadataGqlEnumTypeGenerator, - EnumFieldMetadataGqlEnumTypeGenerator, - CompositeFieldMetadataGqlInputTypeGenerator, - CompositeFieldMetadataCreateGqlInputTypeGenerator, - CompositeFieldMetadataUpdateGqlInputTypeGenerator, - CompositeFieldMetadataFilterGqlInputTypeGenerator, - CompositeFieldMetadataOrderByGqlInputTypeGenerator, - CompositeFieldMetadataGroupByGqlInputTypeGenerator, - RelationFieldMetadataGqlInputTypeGenerator, - RelationFieldMetadataGqlObjectTypeGenerator, - ObjectMetadataGqlInputTypeGenerator, - ObjectMetadataCreateGqlInputTypeGenerator, - ObjectMetadataUpdateGqlInputTypeGenerator, - ObjectMetadataFilterGqlInputTypeGenerator, - ObjectMetadataOrderByGqlInputTypeGenerator, - ObjectMetadataGroupByGqlInputTypeGenerator, - ObjectMetadataOrderByWithGroupByGqlInputTypeGenerator, - ObjectMetadataOrderByBaseGenerator, - GroupByDateGranularityInputTypeGenerator, - CompositeFieldMetadataGqlObjectTypeGenerator, - ObjectMetadataGqlObjectTypeGenerator, - RelationConnectGqlInputTypeGenerator, - ConnectionGqlObjectTypeGenerator, - EdgeGqlObjectTypeGenerator, - GroupByConnectionGqlObjectTypeGenerator, - ObjectMetadataWithRelationsGqlObjectTypeGenerator, - AggregationObjectTypeGenerator, - ArgsTypeGenerator, - RootTypeGenerator, - QueryTypeGenerator, - MutationTypeGenerator, - OrphanedTypesGenerator, -]; +export const instantiateTypeGenerators = ( + gqlTypesStorage: GqlTypesStorage, + typeMapperService: TypeMapperService, + workspaceResolverBuilderService: WorkspaceResolverBuilderService, +) => { + const argsTypeGenerator = new ArgsTypeGenerator(gqlTypesStorage); + + const relationFieldMetadataGqlObjectTypeGenerator = + new RelationFieldMetadataGqlObjectTypeGenerator(typeMapperService); + + const relationFieldMetadataGqlInputTypeGenerator = + new RelationFieldMetadataGqlInputTypeGenerator( + typeMapperService, + gqlTypesStorage, + ); + + const compositeFieldMetadataCreateGqlInputTypeGenerator = + new CompositeFieldMetadataCreateGqlInputTypeGenerator( + gqlTypesStorage, + typeMapperService, + ); + const compositeFieldMetadataUpdateGqlInputTypeGenerator = + new CompositeFieldMetadataUpdateGqlInputTypeGenerator( + gqlTypesStorage, + typeMapperService, + ); + const compositeFieldMetadataFilterGqlInputTypeGenerator = + new CompositeFieldMetadataFilterGqlInputTypeGenerator( + gqlTypesStorage, + typeMapperService, + ); + const compositeFieldMetadataOrderByGqlInputTypeGenerator = + new CompositeFieldMetadataOrderByGqlInputTypeGenerator( + gqlTypesStorage, + typeMapperService, + ); + const compositeFieldMetadataGroupByGqlInputTypeGenerator = + new CompositeFieldMetadataGroupByGqlInputTypeGenerator( + gqlTypesStorage, + typeMapperService, + ); + + const objectMetadataOrderByBaseGenerator = + new ObjectMetadataOrderByBaseGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + typeMapperService, + ); + + const rootTypeGenerator = new RootTypeGenerator( + gqlTypesStorage, + argsTypeGenerator, + workspaceResolverBuilderService, + ); + + return { + enumFieldMetadataGqlEnumTypeGenerator: + new EnumFieldMetadataGqlEnumTypeGenerator(gqlTypesStorage), + compositeFieldMetadataGqlEnumTypeGenerator: + new CompositeFieldMetadataGqlEnumTypeGenerator(gqlTypesStorage), + compositeFieldMetadataGqlObjectTypeGenerator: + new CompositeFieldMetadataGqlObjectTypeGenerator( + gqlTypesStorage, + typeMapperService, + ), + compositeFieldMetadataGqlInputTypeGenerator: + new CompositeFieldMetadataGqlInputTypeGenerator( + compositeFieldMetadataCreateGqlInputTypeGenerator, + compositeFieldMetadataUpdateGqlInputTypeGenerator, + compositeFieldMetadataFilterGqlInputTypeGenerator, + compositeFieldMetadataOrderByGqlInputTypeGenerator, + compositeFieldMetadataGroupByGqlInputTypeGenerator, + ), + objectMetadataGqlObjectTypeGenerator: + new ObjectMetadataGqlObjectTypeGenerator( + relationFieldMetadataGqlObjectTypeGenerator, + gqlTypesStorage, + typeMapperService, + ), + objectMetadataGqlInputTypeGenerator: + new ObjectMetadataGqlInputTypeGenerator( + new ObjectMetadataCreateGqlInputTypeGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + typeMapperService, + ), + new ObjectMetadataUpdateGqlInputTypeGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + typeMapperService, + ), + new ObjectMetadataFilterGqlInputTypeGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + typeMapperService, + ), + new ObjectMetadataOrderByGqlInputTypeGenerator( + gqlTypesStorage, + objectMetadataOrderByBaseGenerator, + ), + new ObjectMetadataOrderByWithGroupByGqlInputTypeGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + objectMetadataOrderByBaseGenerator, + typeMapperService, + ), + new ObjectMetadataGroupByGqlInputTypeGenerator( + gqlTypesStorage, + relationFieldMetadataGqlInputTypeGenerator, + typeMapperService, + ), + ), + edgeGqlObjectTypeGenerator: new EdgeGqlObjectTypeGenerator(gqlTypesStorage), + connectionGqlObjectTypeGenerator: new ConnectionGqlObjectTypeGenerator( + new AggregationObjectTypeGenerator(), + gqlTypesStorage, + ), + groupByConnectionGqlObjectTypeGenerator: + new GroupByConnectionGqlObjectTypeGenerator(gqlTypesStorage), + objectMetadataWithRelationsGqlObjectTypeGenerator: + new ObjectMetadataWithRelationsGqlObjectTypeGenerator( + argsTypeGenerator, + gqlTypesStorage, + ), + relationConnectGqlInputTypeGenerator: + new RelationConnectGqlInputTypeGenerator( + typeMapperService, + gqlTypesStorage, + ), + groupByDateGranularityInputTypeGenerator: + new GroupByDateGranularityInputTypeGenerator(gqlTypesStorage), + queryTypeGenerator: new QueryTypeGenerator( + rootTypeGenerator, + gqlTypesStorage, + ), + mutationTypeGenerator: new MutationTypeGenerator( + rootTypeGenerator, + gqlTypesStorage, + ), + }; +}; + +export type TypeGenerators = ReturnType; diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage.ts index 92e0483e194..b3b3538e849 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage.ts @@ -1,36 +1,19 @@ -import { Injectable, Scope } from '@nestjs/common'; +import { type GraphQLNamedType } from 'graphql'; -import { - type GraphQLEnumType, - type GraphQLInputObjectType, - type GraphQLObjectType, -} from 'graphql'; - -// Must be scoped on REQUEST level, because we need to recreate it for each workspaces -// TODO: Implement properly durable by workspace -@Injectable({ scope: Scope.REQUEST, durable: true }) export class GqlTypesStorage { - private readonly gqlTypes = new Map< - string, - GraphQLEnumType | GraphQLInputObjectType | GraphQLObjectType - >(); + private readonly gqlTypes = new Map(); - addGqlType( - key: string, - type: GraphQLEnumType | GraphQLInputObjectType | GraphQLObjectType, - ) { + addGqlType(key: string, type: GraphQLNamedType) { this.gqlTypes.set(key, type); } - getGqlTypeByKey( + getGqlTypeByKey( key: string, - ): GraphQLEnumType | GraphQLInputObjectType | GraphQLObjectType | undefined { - return this.gqlTypes.get(key); + ): T | undefined { + return this.gqlTypes.get(key) as T | undefined; } - getAllGqlTypesExcept( - keysToExclude: string[], - ): (GraphQLEnumType | GraphQLInputObjectType | GraphQLObjectType)[] { + getAllGqlTypesExcept(keysToExclude: string[]): GraphQLNamedType[] { return Array.from(this.gqlTypes.entries()) .filter(([key]) => !keysToExclude.includes(key)) .map(([, value]) => value); diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts index bc2c62503a7..9863df2f5a8 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory.ts @@ -1,34 +1,53 @@ import { Injectable } from '@nestjs/common'; -import { GraphQLSchema } from 'graphql'; +import { GraphQLObjectType, GraphQLSchema } from 'graphql'; +import { isDefined } from 'twenty-shared/utils'; +import { GqlOperation } from 'src/engine/api/graphql/workspace-schema-builder/enums/gql-operation.enum'; +import { + WorkspaceGraphQLSchemaException, + WorkspaceGraphQLSchemaExceptionCode, +} from 'src/engine/api/graphql/workspace-schema-builder/exceptions/workspace-graphql-schema.exception'; import { GqlTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator'; -import { OrphanedTypesGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/orphaned-types.generator'; -import { MutationTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/mutation-type.generator'; -import { QueryTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/root-types/query-type.generator'; import { type SchemaGenerationContext } from 'src/engine/api/graphql/workspace-schema-builder/types/schema-generation-context.type'; @Injectable() export class WorkspaceGraphQLSchemaGenerator { - constructor( - private readonly gqlTypeGenerator: GqlTypeGenerator, - private readonly queryTypeGenerator: QueryTypeGenerator, - private readonly mutationTypeGenerator: MutationTypeGenerator, - private readonly orphanedTypesGenerator: OrphanedTypesGenerator, - ) {} + constructor(private readonly gqlTypeGenerator: GqlTypeGenerator) {} async generateSchema( context: SchemaGenerationContext, ): Promise { - await this.gqlTypeGenerator.buildAndStore(context); + const gqlTypesStorage = await this.gqlTypeGenerator.buildAndStore(context); - // Assemble schema - const schema = new GraphQLSchema({ - query: this.queryTypeGenerator.fetchQueryType(), - mutation: this.mutationTypeGenerator.fetchMutationType(), - types: this.orphanedTypesGenerator.fetchOrphanedTypes(), + const queryType = gqlTypesStorage.getGqlTypeByKey( + GqlOperation.Query, + ); + const mutationType = gqlTypesStorage.getGqlTypeByKey( + GqlOperation.Mutation, + ); + + if (!isDefined(queryType)) { + throw new WorkspaceGraphQLSchemaException( + 'Query type not found in GqlTypesStorage', + WorkspaceGraphQLSchemaExceptionCode.QUERY_TYPE_NOT_FOUND, + ); + } + + if (!isDefined(mutationType)) { + throw new WorkspaceGraphQLSchemaException( + 'Mutation type not found in GqlTypesStorage', + WorkspaceGraphQLSchemaExceptionCode.MUTATION_TYPE_NOT_FOUND, + ); + } + + return new GraphQLSchema({ + query: queryType, + mutation: mutationType, + types: gqlTypesStorage.getAllGqlTypesExcept([ + GqlOperation.Query, + GqlOperation.Mutation, + ]), }); - - return schema; } } diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts index f1c1860a028..321abc0e3bd 100644 --- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts +++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/workspace-schema-builder.module.ts @@ -2,23 +2,13 @@ import { Module } from '@nestjs/common'; import { WorkspaceResolverBuilderModule } from 'src/engine/api/graphql/workspace-resolver-builder/workspace-resolver-builder.module'; import { GqlTypeGenerator } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/gql-type.generator'; -import { workspaceSchemaBuilderTypeGenerators } from 'src/engine/api/graphql/workspace-schema-builder/graphql-type-generators/type-generators'; -import { GqlTypesStorage } from 'src/engine/api/graphql/workspace-schema-builder/storages/gql-types.storage'; +import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service'; import { WorkspaceGraphQLSchemaGenerator } from 'src/engine/api/graphql/workspace-schema-builder/workspace-graphql-schema.factory'; -import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; -import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; -import { TypeMapperService } from './services/type-mapper.service'; @Module({ - imports: [ - ObjectMetadataModule, - WorkspaceResolverBuilderModule, - FeatureFlagModule, - ], + imports: [WorkspaceResolverBuilderModule], providers: [ - GqlTypesStorage, TypeMapperService, - ...workspaceSchemaBuilderTypeGenerators, GqlTypeGenerator, WorkspaceGraphQLSchemaGenerator, ], diff --git a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts index af98b288fe8..948a5dc18de 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.module.ts @@ -7,6 +7,7 @@ import { ApplicationDevelopmentResolver } from 'src/engine/core-modules/applicat import { TokenModule } from 'src/engine/core-modules/auth/token/token.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; +import { SdkClientModule } from 'src/engine/core-modules/sdk-client/sdk-client.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-graphql-api-exception.interceptor'; @@ -16,6 +17,7 @@ import { WorkspaceMigrationGraphqlApiExceptionInterceptor } from 'src/engine/wor ApplicationManifestModule, ApplicationRegistrationModule, FeatureFlagModule, + SdkClientModule, TokenModule, FileStorageModule, PermissionsModule, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts index 948a4fa66e4..753e742f5f5 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-development/application-development.resolver.ts @@ -8,32 +8,34 @@ import { Args, Mutation } from '@nestjs/graphql'; import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'; import { PermissionFlagType } from 'twenty-shared/constants'; -import { FileFolder, FeatureFlagKey } from 'twenty-shared/types'; +import { FeatureFlagKey, FileFolder } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; import type { FileUpload } from 'graphql-upload/processRequest.mjs'; -import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service'; -import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service'; import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator'; -import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; -import { - ApplicationException, - ApplicationExceptionCode, -} from 'src/engine/core-modules/application/application.exception'; -import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum'; -import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; -import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { ApplicationInput } from 'src/engine/core-modules/application/application-development/dtos/application.input'; import { CreateDevelopmentApplicationInput } from 'src/engine/core-modules/application/application-development/dtos/create-development-application.input'; import { DevelopmentApplicationDTO } from 'src/engine/core-modules/application/application-development/dtos/development-application.dto'; import { GenerateApplicationTokenInput } from 'src/engine/core-modules/application/application-development/dtos/generate-application-token.input'; import { UploadApplicationFileInput } from 'src/engine/core-modules/application/application-development/dtos/upload-application-file.input'; import { WorkspaceMigrationDTO } from 'src/engine/core-modules/application/application-development/dtos/workspace-migration.dto'; +import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter'; +import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; import { ApplicationTokenPairDTO } from 'src/engine/core-modules/application/application-oauth/dtos/application-token-pair.dto'; +import { ApplicationRegistrationVariableService } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.service'; +import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service'; +import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum'; +import { + ApplicationException, + ApplicationExceptionCode, +} from 'src/engine/core-modules/application/application.exception'; +import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { ApplicationTokenService } from 'src/engine/core-modules/auth/token/services/application-token.service'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; import { FileDTO } from 'src/engine/core-modules/file/dtos/file.dto'; import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe'; +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AuthUser } from 'src/engine/decorators/auth/auth-user.decorator'; import { AuthUserWorkspaceId } from 'src/engine/decorators/auth/auth-user-workspace-id.decorator'; @@ -66,6 +68,7 @@ export class ApplicationDevelopmentResolver { private readonly applicationRegistrationService: ApplicationRegistrationService, private readonly applicationRegistrationVariableService: ApplicationRegistrationVariableService, private readonly fileStorageService: FileStorageService, + private readonly sdkClientGenerationService: SdkClientGenerationService, ) {} @Mutation(() => DevelopmentApplicationDTO) @@ -133,13 +136,38 @@ export class ApplicationDevelopmentResolver { workspaceId, ); - const workspaceMigration = + const application = await this.applicationService.findByUniversalIdentifier( + { + universalIdentifier: manifest.application.universalIdentifier, + workspaceId, + }, + ); + + if (!isDefined(application)) { + throw new ApplicationException( + `Application "${manifest.application.universalIdentifier}" not found in workspace "${workspaceId}". Run createDevelopmentApplication first.`, + ApplicationExceptionCode.APPLICATION_NOT_FOUND, + ); + } + + const isFirstSync = !isDefined(application.version); + + const { workspaceMigration, hasSchemaMetadataChanged } = await this.applicationSyncService.synchronizeFromManifest({ workspaceId, manifest, applicationRegistrationId, }); + if (isFirstSync || hasSchemaMetadataChanged) { + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: application.id, + applicationUniversalIdentifier: + manifest.application.universalIdentifier, + }); + } + await this.syncRegistrationMetadata( applicationRegistrationId, manifest, diff --git a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts index f0a797e538f..47fd91d54f1 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.module.ts @@ -10,6 +10,7 @@ import { ApplicationPackageModule } from 'src/engine/core-modules/application/ap import { ApplicationInstallResolver } from 'src/engine/core-modules/application/application-install/application-install.resolver'; import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; +import { SdkClientModule } from 'src/engine/core-modules/sdk-client/sdk-client.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; @Module({ @@ -20,6 +21,7 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi ApplicationPackageModule, CacheLockModule, FeatureFlagModule, + SdkClientModule, PermissionsModule, FileStorageModule, ], diff --git a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.service.ts index acbfcbd8eb5..0d151de4897 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-install/application-install.service.ts @@ -24,7 +24,7 @@ import { import { ApplicationSyncService } from 'src/engine/core-modules/application/application-manifest/application-sync.service'; import { CacheLockService } from 'src/engine/core-modules/cache-lock/cache-lock.service'; import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; - +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; @Injectable() export class ApplicationInstallService { private readonly logger = new Logger(ApplicationInstallService.name); @@ -37,6 +37,7 @@ export class ApplicationInstallService { private readonly applicationSyncService: ApplicationSyncService, private readonly fileStorageService: FileStorageService, private readonly cacheLockService: CacheLockService, + private readonly sdkClientGenerationService: SdkClientGenerationService, ) {} async installApplication(params: { @@ -108,7 +109,7 @@ export class ApplicationInstallService { const universalIdentifier = appRegistration.universalIdentifier; - await this.ensureApplicationExists({ + const { application, wasCreated } = await this.ensureApplicationExists({ universalIdentifier, name: resolvedPackage.manifest.application.displayName, workspaceId: params.workspaceId, @@ -123,11 +124,20 @@ export class ApplicationInstallService { params.workspaceId, ); - await this.applicationSyncService.synchronizeFromManifest({ - workspaceId: params.workspaceId, - manifest: resolvedPackage.manifest, - applicationRegistrationId: appRegistration.id, - }); + const { hasSchemaMetadataChanged } = + await this.applicationSyncService.synchronizeFromManifest({ + workspaceId: params.workspaceId, + manifest: resolvedPackage.manifest, + applicationRegistrationId: appRegistration.id, + }); + + if (wasCreated || hasSchemaMetadataChanged) { + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId: params.workspaceId, + applicationId: application.id, + applicationUniversalIdentifier: universalIdentifier, + }); + } this.logger.log( `Successfully installed app ${universalIdentifier} v${resolvedPackage.packageJson.version ?? 'unknown'}`, @@ -232,17 +242,17 @@ export class ApplicationInstallService { workspaceId: string; applicationRegistrationId: string; sourceType: ApplicationRegistrationSourceType; - }): Promise { + }): Promise<{ application: ApplicationEntity; wasCreated: boolean }> { const existing = await this.applicationService.findByUniversalIdentifier({ universalIdentifier: params.universalIdentifier, workspaceId: params.workspaceId, }); if (isDefined(existing)) { - return existing; + return { application: existing, wasCreated: false }; } - return this.applicationService.create({ + const application = await this.applicationService.create({ universalIdentifier: params.universalIdentifier, name: params.name, sourcePath: params.universalIdentifier, @@ -250,5 +260,7 @@ export class ApplicationInstallService { applicationRegistrationId: params.applicationRegistrationId, workspaceId: params.workspaceId, }); + + return { application, wasCreated: true }; } } diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest-migration.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest-migration.service.ts index ccf689855e1..7d10513a19c 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest-migration.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-manifest-migration.service.ts @@ -47,7 +47,10 @@ export class ApplicationManifestMigrationService { manifest: Manifest; workspaceId: string; ownerFlatApplication: FlatApplication; - }): Promise { + }): Promise<{ + workspaceMigration: WorkspaceMigration; + hasSchemaMetadataChanged: boolean; + }> { const now = new Date().toISOString(); const { twentyStandardFlatApplication } = @@ -122,7 +125,10 @@ export class ApplicationManifestMigrationService { ownerFlatApplication, }); - return validateAndBuildResult.workspaceMigration; + return { + workspaceMigration: validateAndBuildResult.workspaceMigration, + hasSchemaMetadataChanged: validateAndBuildResult.hasSchemaMetadataChanged, + }; } /** diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-sync.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-sync.service.ts index c8c64c529fe..83c62af5ec1 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-sync.service.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/application-sync.service.ts @@ -47,7 +47,10 @@ export class ApplicationSyncService { workspaceId: string; manifest: Manifest; applicationRegistrationId?: string; - }): Promise { + }): Promise<{ + workspaceMigration: WorkspaceMigration; + hasSchemaMetadataChanged: boolean; + }> { const application = await this.syncApplication({ workspaceId, manifest, @@ -56,7 +59,7 @@ export class ApplicationSyncService { const ownerFlatApplication: FlatApplication = application; - const workspaceMigration = + const syncResult = await this.applicationManifestMigrationService.syncMetadataFromManifest({ manifest, workspaceId, @@ -65,7 +68,7 @@ export class ApplicationSyncService { this.logger.log('Application sync from manifest completed'); - return workspaceMigration; + return syncResult; } private async syncApplication({ diff --git a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-front-component-manifest-to-universal-flat-front-component.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-front-component-manifest-to-universal-flat-front-component.util.ts index b848d922dcf..be476be591e 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-front-component-manifest-to-universal-flat-front-component.util.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application-manifest/converters/from-front-component-manifest-to-universal-flat-front-component.util.ts @@ -21,6 +21,7 @@ export const fromFrontComponentManifestToUniversalFlatFrontComponent = ({ componentName: frontComponentManifest.componentName, builtComponentChecksum: frontComponentManifest.builtComponentChecksum, isHeadless: frontComponentManifest.isHeadless ?? false, + usesSdkClient: frontComponentManifest.usesSdkClient ?? false, createdAt: now, updatedAt: now, }; diff --git a/packages/twenty-server/src/engine/core-modules/application/application.entity.ts b/packages/twenty-server/src/engine/core-modules/application/application.entity.ts index a9cf4036723..fd0e60ce814 100644 --- a/packages/twenty-server/src/engine/core-modules/application/application.entity.ts +++ b/packages/twenty-server/src/engine/core-modules/application/application.entity.ts @@ -97,6 +97,9 @@ export class ApplicationEntity extends WorkspaceRelatedEntity { @Column({ nullable: false, type: 'boolean', default: true }) canBeUninstalled: boolean; + @Column({ nullable: false, type: 'boolean', default: false }) + isSdkLayerStale: boolean; + @Column({ nullable: true, type: 'uuid' }) applicationRegistrationId: string | null; diff --git a/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts index bd908e00d05..310892fff81 100644 --- a/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts +++ b/packages/twenty-server/src/engine/core-modules/auth/auth.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { TypeORMModule } from 'src/database/typeorm/typeorm.module'; import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity'; import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module'; import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; @@ -58,18 +57,13 @@ import { UserEntity } from 'src/engine/core-modules/user/user.entity'; import { UserModule } from 'src/engine/core-modules/user/user.module'; import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; -import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.module'; -import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { CalendarChannelDataAccessModule } from 'src/engine/metadata-modules/calendar-channel/data-access/calendar-channel-data-access.module'; import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity'; import { ConnectedAccountDataAccessModule } from 'src/engine/metadata-modules/connected-account/data-access/connected-account-data-access.module'; import { MessageChannelDataAccessModule } from 'src/engine/metadata-modules/message-channel/data-access/message-channel-data-access.module'; import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; -import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module'; import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; -import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; -import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module'; import { CalendarChannelSyncStatusService } from 'src/modules/calendar/common/services/calendar-channel-sync-status.service'; import { ConnectedAccountModule } from 'src/modules/connected-account/connected-account.module'; import { MessagingCommonModule } from 'src/modules/messaging/common/messaging-common.module'; @@ -83,12 +77,9 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; @Module({ imports: [ JwtModule, - DataSourceModule, WorkspaceDomainsModule, TokenModule, UserModule, - WorkspaceManagerModule, - TypeORMModule, TypeOrmModule.forFeature([ WorkspaceEntity, UserEntity, @@ -104,9 +95,7 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; ConnectedAccountEntity, ]), UserWorkspaceModule, - WorkspaceModule, OnboardingModule, - WorkspaceDataSourceModule, ConnectedAccountModule, MessagingCommonModule, MessagingFolderSyncManagerModule, @@ -120,7 +109,6 @@ import { JwtAuthStrategy } from './strategies/jwt.auth.strategy'; GuardRedirectModule, MetricsModule, PermissionsModule, - UserRoleModule, TwoFactorAuthenticationModule, ApiKeyModule, AuditModule, diff --git a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts index 49b5dcd90c7..272cc24b6d0 100644 --- a/packages/twenty-server/src/engine/core-modules/core-engine.module.ts +++ b/packages/twenty-server/src/engine/core-modules/core-engine.module.ts @@ -7,19 +7,17 @@ import { ActorModule } from 'src/engine/core-modules/actor/actor.module'; import { AdminPanelModule } from 'src/engine/core-modules/admin-panel/admin-panel.module'; import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module'; import { AppTokenModule } from 'src/engine/core-modules/app-token/app-token.module'; -import { ApplicationOAuthModule } from 'src/engine/core-modules/application/application-oauth/application-oauth.module'; -import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; import { ApplicationDevelopmentModule } from 'src/engine/core-modules/application/application-development/application-development.module'; import { ApplicationInstallModule } from 'src/engine/core-modules/application/application-install/application-install.module'; +import { MarketplaceModule } from 'src/engine/core-modules/application/application-marketplace/marketplace.module'; +import { ApplicationOAuthModule } from 'src/engine/core-modules/application/application-oauth/application-oauth.module'; +import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; import { ApplicationUpgradeModule } from 'src/engine/core-modules/application/application-upgrade/application-upgrade.module'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; -import { MarketplaceModule } from 'src/engine/core-modules/application/application-marketplace/marketplace.module'; -import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module'; import { ApprovedAccessDomainModule } from 'src/engine/core-modules/approved-access-domain/approved-access-domain.module'; import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { BillingWebhookModule } from 'src/engine/core-modules/billing-webhook/billing-webhook.module'; import { BillingModule } from 'src/engine/core-modules/billing/billing.module'; -import { UsageModule } from 'src/engine/core-modules/usage/usage.module'; import { CacheStorageModule } from 'src/engine/core-modules/cache-storage/cache-storage.module'; import { TimelineCalendarEventModule } from 'src/engine/core-modules/calendar/timeline-calendar-event.module'; import { CaptchaModule } from 'src/engine/core-modules/captcha/captcha.module'; @@ -28,6 +26,7 @@ import { CodeInterpreterModule } from 'src/engine/core-modules/code-interpreter/ import { DnsManagerModule } from 'src/engine/core-modules/dns-manager/dns-manager.module'; import { EmailModule } from 'src/engine/core-modules/email/email.module'; import { EmailingDomainModule } from 'src/engine/core-modules/emailing-domain/emailing-domain.module'; +import { EnvironmentModule } from 'src/engine/core-modules/environment/environment.module'; import { ExceptionHandlerModule } from 'src/engine/core-modules/exception-handler/exception-handler.module'; import { exceptionHandlerModuleFactory } from 'src/engine/core-modules/exception-handler/exception-handler.module-factory'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; @@ -39,6 +38,7 @@ import { ImpersonationModule } from 'src/engine/core-modules/impersonation/imper import { LabModule } from 'src/engine/core-modules/lab/lab.module'; import { LoggerModule } from 'src/engine/core-modules/logger/logger.module'; import { loggerModuleFactory } from 'src/engine/core-modules/logger/logger.module-factory'; +import { LogicFunctionModule } from 'src/engine/core-modules/logic-function/logic-function.module'; import { MessageQueueModule } from 'src/engine/core-modules/message-queue/message-queue.module'; import { messageQueueModuleFactory } from 'src/engine/core-modules/message-queue/message-queue.module-factory'; import { TimelineMessagingModule } from 'src/engine/core-modules/messaging/timeline-messaging.module'; @@ -50,11 +50,11 @@ import { PublicDomainModule } from 'src/engine/core-modules/public-domain/public import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module'; import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service'; import { SearchModule } from 'src/engine/core-modules/search/search.module'; -import { LogicFunctionModule } from 'src/engine/core-modules/logic-function/logic-function.module'; import { WorkspaceSSOModule } from 'src/engine/core-modules/sso/sso.module'; import { TelemetryModule } from 'src/engine/core-modules/telemetry/telemetry.module'; import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; +import { UsageModule } from 'src/engine/core-modules/usage/usage.module'; import { UserModule } from 'src/engine/core-modules/user/user.module'; import { WorkflowApiModule } from 'src/engine/core-modules/workflow/workflow-api.module'; import { WorkspaceInvitationModule } from 'src/engine/core-modules/workspace-invitation/workspace-invitation.module'; diff --git a/packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts b/packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts index 2d33d05c0f5..1369fc2b044 100644 --- a/packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts +++ b/packages/twenty-server/src/engine/core-modules/file/interfaces/file-folder.interface.ts @@ -57,6 +57,9 @@ export const fileFolderConfigs: Record = { [FileFolder.AppTarball]: { ignoreExpirationToken: false, }, + [FileFolder.GeneratedSdkClient]: { + ignoreExpirationToken: false, + }, }; export type AllowedFolders = KebabCase; diff --git a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/lambda.driver.ts b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/lambda.driver.ts index eda4a48f609..5b75757c8ae 100644 --- a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/lambda.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/lambda.driver.ts @@ -6,6 +6,7 @@ import { CreateFunctionCommand, type CreateFunctionCommandInput, DeleteFunctionCommand, + DeleteLayerVersionCommand, GetFunctionCommand, InvokeCommand, type InvokeCommandInput, @@ -24,9 +25,9 @@ import { AssumeRoleCommand, STSClient } from '@aws-sdk/client-sts'; import { isDefined } from 'twenty-shared/utils'; import { + type LogicFunctionDriver, type LogicFunctionExecuteParams, type LogicFunctionExecuteResult, - type LogicFunctionDriver, type LogicFunctionTranspileParams, type LogicFunctionTranspileResult, } from 'src/engine/core-modules/logic-function/logic-function-drivers/interfaces/logic-function-driver.interface'; @@ -40,6 +41,9 @@ import { copyExecutor } from 'src/engine/core-modules/logic-function/logic-funct import { copyYarnInstall } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/copy-yarn-install'; import { createZipFile } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/create-zip-file'; import { TemporaryDirManager } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/temporary-dir-manager'; +import { type LogicFunctionResourceService } from 'src/engine/core-modules/logic-function/logic-function-resource/logic-function-resource.service'; +import { type SdkClientArchiveService } from 'src/engine/core-modules/sdk-client/sdk-client-archive.service'; +import { callWithTimeout } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/call-with-timeout'; import { LogicFunctionExecutionStatus } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-execution-result.dto'; import { LogicFunctionRuntime } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; import { @@ -47,8 +51,6 @@ import { LogicFunctionExceptionCode, } from 'src/engine/metadata-modules/logic-function/logic-function.exception'; import { type FlatLogicFunction } from 'src/engine/metadata-modules/logic-function/types/flat-logic-function.type'; -import { type LogicFunctionResourceService } from 'src/engine/core-modules/logic-function/logic-function-resource/logic-function-resource.service'; -import { callWithTimeout } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/call-with-timeout'; const UPDATE_FUNCTION_DURATION_TIMEOUT_IN_SECONDS = 60; const CREDENTIALS_DURATION_IN_SECONDS = 60 * 60; // 1h @@ -105,6 +107,7 @@ export type BuilderLambdaResult = { export interface LambdaDriverOptions extends LambdaClientConfig { logicFunctionResourceService: LogicFunctionResourceService; + sdkClientArchiveService: SdkClientArchiveService; region: string; lambdaRole: string; subhostingRole?: string; @@ -120,11 +123,13 @@ export class LambdaDriver implements LogicFunctionDriver { private credentialsExpiry: Date | null = null; private readonly options: LambdaDriverOptions; private readonly logicFunctionResourceService: LogicFunctionResourceService; + private readonly sdkClientArchiveService: SdkClientArchiveService; constructor(options: LambdaDriverOptions) { this.options = options; this.lambdaClient = undefined; this.logicFunctionResourceService = options.logicFunctionResourceService; + this.sdkClientArchiveService = options.sdkClientArchiveService; } private areAssumeRoleCredentialsExpired(): boolean { @@ -223,8 +228,20 @@ export class LambdaDriver implements LogicFunctionDriver { ); } - private getLayerName(flatApplication: FlatApplication) { - return flatApplication.yarnLockChecksum ?? 'default'; + private getDepsLayerName(flatApplication: FlatApplication): string { + const checksum = flatApplication.yarnLockChecksum ?? 'default'; + + return `deps-${checksum}`; + } + + private getSdkLayerName({ + workspaceId, + applicationUniversalIdentifier, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + }): string { + return `sdk-${workspaceId}-${applicationUniversalIdentifier}`; } private yarnInstallFunctionName: string | undefined; @@ -538,6 +555,33 @@ export class LambdaDriver implements LogicFunctionDriver { return listLayerResult.LayerVersions?.[0]?.LayerVersionArn; } + private async publishLayer({ + layerName, + zipBuffer, + }: { + layerName: string; + zipBuffer: Buffer; + }): Promise { + const result = await ( + await this.getLambdaClient() + ).send( + new PublishLayerVersionCommand({ + LayerName: layerName, + Content: { ZipFile: zipBuffer }, + CompatibleRuntimes: [ + LogicFunctionRuntime.NODE18, + LogicFunctionRuntime.NODE22, + ], + }), + ); + + if (!isDefined(result.LayerVersionArn)) { + throw new Error('New layer version ARN is undefined'); + } + + return result.LayerVersionArn; + } + private async getDependencyContents( flatApplication: FlatApplication, applicationUniversalIdentifier: string, @@ -570,7 +614,7 @@ export class LambdaDriver implements LogicFunctionDriver { flatApplication: FlatApplication; applicationUniversalIdentifier: string; }): Promise { - const layerName = this.getLayerName(flatApplication); + const layerName = this.getDepsLayerName(flatApplication); const existingArn = await this.getExistingLayerArn(layerName); @@ -625,7 +669,7 @@ export class LambdaDriver implements LogicFunctionDriver { flatApplication: FlatApplication; applicationUniversalIdentifier: string; }): Promise { - const layerName = this.getLayerName(flatApplication); + const layerName = this.getDepsLayerName(flatApplication); const existingArn = await this.getExistingLayerArn(layerName); @@ -649,6 +693,89 @@ export class LambdaDriver implements LogicFunctionDriver { return newArn; } + private async ensureSdkLayer({ + flatApplication, + applicationUniversalIdentifier, + }: { + flatApplication: FlatApplication; + applicationUniversalIdentifier: string; + }): Promise { + const layerName = this.getSdkLayerName({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + }); + + if (!flatApplication.isSdkLayerStale) { + const existingArn = await this.getExistingLayerArn(layerName); + + if (isDefined(existingArn)) { + return existingArn; + } + } + + await this.deleteAllLayerVersions({ + lambdaClient: await this.getLambdaClient(), + layerName, + }); + + const sdkArchiveBuffer = + await this.sdkClientArchiveService.downloadArchiveBuffer({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + }); + + const zipBuffer = await this.reprefixZipEntries({ + sourceBuffer: sdkArchiveBuffer, + prefix: 'nodejs/node_modules/twenty-client-sdk', + }); + + const arn = await this.publishLayer({ layerName, zipBuffer }); + + await this.sdkClientArchiveService.markSdkLayerFresh({ + applicationId: flatApplication.id, + workspaceId: flatApplication.workspaceId, + }); + + return arn; + } + + // Re-wraps zip entries under a new prefix path without extracting to disk. + private async reprefixZipEntries({ + sourceBuffer, + prefix, + }: { + sourceBuffer: Buffer; + prefix: string; + }): Promise { + const { default: unzipper } = await import('unzipper'); + const archiver = (await import('archiver')).default; + + const directory = await unzipper.Open.buffer(sourceBuffer); + const archive = archiver('zip', { zlib: { level: 9 } }); + + const chunks: Buffer[] = []; + + archive.on('data', (chunk: Buffer) => chunks.push(chunk)); + + for (const entry of directory.files) { + if (entry.type === 'Directory') { + continue; + } + + archive.append(entry.stream(), { + name: `${prefix}/${entry.path}`, + }); + } + + await new Promise((resolve, reject) => { + archive.on('end', resolve); + archive.on('error', reject); + archive.finalize(); + }); + + return Buffer.concat(chunks); + } + private async getLambdaExecutor(flatLogicFunction: FlatLogicFunction) { try { const getFunctionCommand: GetFunctionCommand = new GetFunctionCommand({ @@ -675,10 +802,50 @@ export class LambdaDriver implements LogicFunctionDriver { } } - private async isAlreadyBuilt( - flatLogicFunction: FlatLogicFunction, - flatApplication: FlatApplication, - ) { + private async deleteAllLayerVersions({ + lambdaClient, + layerName, + }: { + lambdaClient: Lambda; + layerName: string; + }): Promise { + let marker: string | undefined; + + do { + const listResult = await lambdaClient.send( + new ListLayerVersionsCommand({ + LayerName: layerName, + MaxItems: 50, + Marker: marker, + }), + ); + + const versions = listResult.LayerVersions ?? []; + + await Promise.all( + versions.map((version) => + lambdaClient.send( + new DeleteLayerVersionCommand({ + LayerName: layerName, + VersionNumber: version.Version, + }), + ), + ), + ); + + marker = listResult.NextMarker; + } while (isDefined(marker)); + } + + private async isAlreadyBuilt({ + flatLogicFunction, + flatApplication, + applicationUniversalIdentifier, + }: { + flatLogicFunction: FlatLogicFunction; + flatApplication: FlatApplication; + applicationUniversalIdentifier: string; + }) { const lambdaExecutor = await this.getLambdaExecutor(flatLogicFunction); if (!isDefined(lambdaExecutor)) { @@ -687,15 +854,23 @@ export class LambdaDriver implements LogicFunctionDriver { const layers = lambdaExecutor.Configuration?.Layers; - if (!isDefined(layers) || layers.length !== 1) { + if (!isDefined(layers) || layers.length !== 2) { await this.delete(flatLogicFunction); return false; } - const layerName = this.getLayerName(flatApplication); + const depsLayerName = this.getDepsLayerName(flatApplication); + const sdkLayerName = this.getSdkLayerName({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + }); - if (layers[0].Arn?.includes(layerName)) { + const hasExpectedLayers = + layers.some((layer) => layer.Arn?.includes(depsLayerName)) && + layers.some((layer) => layer.Arn?.includes(sdkLayerName)); + + if (hasExpectedLayers) { return true; } @@ -713,11 +888,25 @@ export class LambdaDriver implements LogicFunctionDriver { flatApplication: FlatApplication; applicationUniversalIdentifier: string; }) { - if (await this.isAlreadyBuilt(flatLogicFunction, flatApplication)) { + if ( + !flatApplication.isSdkLayerStale && + (await this.isAlreadyBuilt({ + flatLogicFunction, + flatApplication, + applicationUniversalIdentifier, + })) + ) { return; } - const layerArn = await this.getLayerArn({ + await this.delete(flatLogicFunction); + + const depsLayerArn = await this.getLayerArn({ + flatApplication, + applicationUniversalIdentifier, + }); + + const sdkLayerArn = await this.ensureSdkLayer({ flatApplication, applicationUniversalIdentifier, }); @@ -727,27 +916,31 @@ export class LambdaDriver implements LogicFunctionDriver { const { sourceTemporaryDir, lambdaZipPath } = await temporaryDirManager.init(); - await copyExecutor(sourceTemporaryDir); + try { + await copyExecutor(sourceTemporaryDir); - await createZipFile(sourceTemporaryDir, lambdaZipPath); + await createZipFile(sourceTemporaryDir, lambdaZipPath); - const params: CreateFunctionCommandInput = { - Code: { - ZipFile: await fs.readFile(lambdaZipPath), - }, - FunctionName: flatLogicFunction.id, - Layers: [layerArn], - Handler: 'index.handler', - Role: this.options.lambdaRole, - Runtime: flatLogicFunction.runtime, - Timeout: 900, // timeout is handled by the logic function service - }; + // SDK layer listed last so it overwrites the stub twenty-client-sdk + // from the deps layer (later layers take precedence in /opt merge). + const params: CreateFunctionCommandInput = { + Code: { + ZipFile: await fs.readFile(lambdaZipPath), + }, + FunctionName: flatLogicFunction.id, + Layers: [depsLayerArn, sdkLayerArn], + Handler: 'index.handler', + Role: this.options.lambdaRole, + Runtime: flatLogicFunction.runtime, + Timeout: 900, + }; - const command = new CreateFunctionCommand(params); + const command = new CreateFunctionCommand(params); - await (await this.getLambdaClient()).send(command); - - await temporaryDirManager.clean(); + await (await this.getLambdaClient()).send(command); + } finally { + await temporaryDirManager.clean(); + } } private extractLogs(logString: string): string { diff --git a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/local.driver.ts b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/local.driver.ts index 6521564dacc..72aacd97cd9 100644 --- a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/local.driver.ts +++ b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/drivers/local.driver.ts @@ -21,23 +21,41 @@ import { HANDLER_NAME_REGEX } from 'src/engine/metadata-modules/logic-function/c import { LogicFunctionExecutionStatus } from 'src/engine/metadata-modules/logic-function/dtos/logic-function-execution-result.dto'; import { copyYarnEngineAndBuildDependencies } from 'src/engine/core-modules/application/application-package/utils/copy-yarn-engine-and-build-dependencies'; import type { LogicFunctionResourceService } from 'src/engine/core-modules/logic-function/logic-function-resource/logic-function-resource.service'; +import type { SdkClientArchiveService } from 'src/engine/core-modules/sdk-client/sdk-client-archive.service'; export interface LocalDriverOptions { logicFunctionResourceService: LogicFunctionResourceService; + sdkClientArchiveService: SdkClientArchiveService; } export class LocalDriver implements LogicFunctionDriver { private readonly logicFunctionResourceService: LogicFunctionResourceService; + private readonly sdkClientArchiveService: SdkClientArchiveService; constructor(options: LocalDriverOptions) { this.logicFunctionResourceService = options.logicFunctionResourceService; + this.sdkClientArchiveService = options.sdkClientArchiveService; } - private getInMemoryLayerFolderPath = (flatApplication: FlatApplication) => { + private getDepsLayerPath(flatApplication: FlatApplication): string { const checksum = flatApplication.yarnLockChecksum ?? 'default'; - return join(LOGIC_FUNCTION_EXECUTOR_TMPDIR_FOLDER, checksum); - }; + return join(LOGIC_FUNCTION_EXECUTOR_TMPDIR_FOLDER, 'deps', checksum); + } + + private getSdkLayerPath({ + workspaceId, + applicationUniversalIdentifier, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + }): string { + return join( + LOGIC_FUNCTION_EXECUTOR_TMPDIR_FOLDER, + 'sdk', + `${workspaceId}-${applicationUniversalIdentifier}`, + ); + } private async createLayerIfNotExist({ flatApplication, @@ -45,20 +63,64 @@ export class LocalDriver implements LogicFunctionDriver { }: { flatApplication: FlatApplication; applicationUniversalIdentifier: string; - }) { - const inMemoryLayerFolderPath = - this.getInMemoryLayerFolderPath(flatApplication); + }): Promise { + const depsLayerPath = this.getDepsLayerPath(flatApplication); try { - await fs.access(inMemoryLayerFolderPath); + await fs.access(depsLayerPath); + + return; } catch { - await this.logicFunctionResourceService.copyDependenciesInMemory({ - applicationUniversalIdentifier, - workspaceId: flatApplication.workspaceId, - inMemoryFolderPath: inMemoryLayerFolderPath, - }); - await copyYarnEngineAndBuildDependencies(inMemoryLayerFolderPath); + // Layer doesn't exist yet } + + await this.logicFunctionResourceService.copyDependenciesInMemory({ + applicationUniversalIdentifier, + workspaceId: flatApplication.workspaceId, + inMemoryFolderPath: depsLayerPath, + }); + await copyYarnEngineAndBuildDependencies(depsLayerPath); + } + + private async ensureSdkLayer({ + flatApplication, + applicationUniversalIdentifier, + }: { + flatApplication: FlatApplication; + applicationUniversalIdentifier: string; + }): Promise { + const sdkLayerPath = this.getSdkLayerPath({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + }); + + const layerExists = await fs + .access(sdkLayerPath) + .then(() => true) + .catch(() => false); + + if (layerExists && !flatApplication.isSdkLayerStale) { + return; + } + + await fs.rm(sdkLayerPath, { recursive: true, force: true }); + + const sdkPackagePath = join( + sdkLayerPath, + 'node_modules', + 'twenty-client-sdk', + ); + + await this.sdkClientArchiveService.downloadAndExtractToPackage({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + targetPackagePath: sdkPackagePath, + }); + + await this.sdkClientArchiveService.markSdkLayerFresh({ + applicationId: flatApplication.id, + workspaceId: flatApplication.workspaceId, + }); } async transpile({ @@ -110,6 +172,59 @@ export class LocalDriver implements LogicFunctionDriver { flatApplication, applicationUniversalIdentifier, }); + await this.ensureSdkLayer({ + flatApplication, + applicationUniversalIdentifier, + }); + } + + // Symlinks everything from the deps layer except twenty-client-sdk, + // which comes from the SDK layer (workspace-specific generated client). + private async assembleNodeModules({ + sourceTemporaryDir, + flatApplication, + applicationUniversalIdentifier, + }: { + sourceTemporaryDir: string; + flatApplication: FlatApplication; + applicationUniversalIdentifier: string; + }): Promise { + const depsNodeModules = join( + this.getDepsLayerPath(flatApplication), + 'node_modules', + ); + const sdkNodeModules = join( + this.getSdkLayerPath({ + workspaceId: flatApplication.workspaceId, + applicationUniversalIdentifier, + }), + 'node_modules', + ); + const execNodeModules = join(sourceTemporaryDir, 'node_modules'); + + await fs.mkdir(execNodeModules, { recursive: true }); + + const entries = await fs.readdir(depsNodeModules, { + withFileTypes: true, + }); + + const symlinkPromises = entries + .filter((entry) => entry.name !== 'twenty-client-sdk') + .map((entry) => + fs.symlink( + join(depsNodeModules, entry.name), + join(execNodeModules, entry.name), + entry.isDirectory() ? 'dir' : 'file', + ), + ); + + await Promise.all(symlinkPromises); + + await fs.symlink( + join(sdkNodeModules, 'twenty-client-sdk'), + join(execNodeModules, 'twenty-client-sdk'), + 'dir', + ); } async execute({ @@ -124,6 +239,10 @@ export class LocalDriver implements LogicFunctionDriver { flatApplication, applicationUniversalIdentifier, }); + await this.ensureSdkLayer({ + flatApplication, + applicationUniversalIdentifier, + }); const startTime = Date.now(); @@ -140,20 +259,11 @@ export class LocalDriver implements LogicFunctionDriver { inMemoryDestinationPath: sourceTemporaryDir, }); - try { - await fs.symlink( - join( - this.getInMemoryLayerFolderPath(flatApplication), - 'node_modules', - ), - join(sourceTemporaryDir, 'node_modules'), - 'dir', - ); - } catch (err) { - if (err.code !== 'EEXIST') { - throw err; - } - } + await this.assembleNodeModules({ + sourceTemporaryDir, + flatApplication, + applicationUniversalIdentifier, + }); let logs = ''; @@ -169,7 +279,7 @@ export class LocalDriver implements LogicFunctionDriver { (_key, value) => { if (typeof value === 'object' && value !== null) { if (seen.has(value)) { - return '[Circular]'; // Handle circular references + return '[Circular]'; } seen.add(value); } @@ -374,7 +484,6 @@ export class LocalDriver implements LogicFunctionDriver { if (settled) return; settled = true; if (code === 0) { - // Fallback path if no IPC (shouldn't happen with our stdio) resolve({ ok: true, stdout, stderr }); } else { resolve({ @@ -398,7 +507,6 @@ export class LocalDriver implements LogicFunctionDriver { }); }, timeoutMs); - // Kick it off child.send?.({ type: 'run', payload }); child.on('close', () => clearTimeout(t)); diff --git a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/logic-function-driver.factory.ts b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/logic-function-driver.factory.ts index ce997519b89..32c5cb3e98d 100644 --- a/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/logic-function-driver.factory.ts +++ b/packages/twenty-server/src/engine/core-modules/logic-function/logic-function-drivers/logic-function-driver.factory.ts @@ -11,6 +11,7 @@ import { DisabledDriver } from 'src/engine/core-modules/logic-function/logic-fun import { LambdaDriver } from 'src/engine/core-modules/logic-function/logic-function-drivers/drivers/lambda.driver'; import { LocalDriver } from 'src/engine/core-modules/logic-function/logic-function-drivers/drivers/local.driver'; import { LogicFunctionResourceService } from 'src/engine/core-modules/logic-function/logic-function-resource/logic-function-resource.service'; +import { SdkClientArchiveService } from 'src/engine/core-modules/sdk-client/sdk-client-archive.service'; import { DriverFactoryBase } from 'src/engine/core-modules/twenty-config/dynamic-factory.base'; import { ConfigVariablesGroup } from 'src/engine/core-modules/twenty-config/enums/config-variables-group.enum'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; @@ -20,6 +21,7 @@ export class LogicFunctionDriverFactory extends DriverFactoryBase { + switch (code) { + case SdkClientExceptionCode.ARCHIVE_NOT_FOUND: + return msg`SDK client archive not found. The SDK client may not have been generated for this application.`; + case SdkClientExceptionCode.ARCHIVE_EXTRACTION_FAILED: + return msg`Failed to extract SDK client archive.`; + case SdkClientExceptionCode.FILE_NOT_FOUND_IN_ARCHIVE: + return msg`File not found in SDK client archive.`; + case SdkClientExceptionCode.GENERATION_FAILED: + return msg`Failed to generate SDK client.`; + default: + assertUnreachable(code); + } +}; + +export class SdkClientException extends CustomException { + constructor( + message: string, + code: SdkClientExceptionCode, + { userFriendlyMessage }: { userFriendlyMessage?: MessageDescriptor } = {}, + ) { + super(message, code, { + userFriendlyMessage: + userFriendlyMessage ?? getSdkClientExceptionUserFriendlyMessage(code), + }); + } +} diff --git a/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-archive.service.ts b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-archive.service.ts new file mode 100644 index 00000000000..657c255732d --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-archive.service.ts @@ -0,0 +1,166 @@ +import { Injectable } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; + +import { createWriteStream } from 'fs'; +import * as fs from 'fs/promises'; +import { join } from 'path'; +import { type Readable } from 'stream'; +import { pipeline } from 'stream/promises'; + +import { FileFolder } from 'twenty-shared/types'; +import { Repository } from 'typeorm'; + +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; +import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; +import { + FileStorageException, + FileStorageExceptionCode, +} from 'src/engine/core-modules/file-storage/interfaces/file-storage-exception'; +import { TemporaryDirManager } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/temporary-dir-manager'; +import { type SdkModuleName } from 'src/engine/core-modules/sdk-client/constants/allowed-sdk-modules'; +import { + SdkClientException, + SdkClientExceptionCode, +} from 'src/engine/core-modules/sdk-client/exceptions/sdk-client.exception'; +import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; +import { streamToBuffer } from 'src/utils/stream-to-buffer'; + +const SDK_CLIENT_ARCHIVE_NAME = 'twenty-client-sdk.zip'; + +@Injectable() +export class SdkClientArchiveService { + constructor( + private readonly fileStorageService: FileStorageService, + @InjectRepository(ApplicationEntity) + private readonly applicationRepository: Repository, + private readonly workspaceCacheService: WorkspaceCacheService, + ) {} + + async downloadAndExtractToPackage({ + workspaceId, + applicationUniversalIdentifier, + targetPackagePath, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + targetPackagePath: string; + }): Promise { + const temporaryDirManager = new TemporaryDirManager(); + + try { + const { sourceTemporaryDir } = await temporaryDirManager.init(); + const archivePath = join(sourceTemporaryDir, SDK_CLIENT_ARCHIVE_NAME); + + const archiveStream = await this.readArchiveStream({ + workspaceId, + applicationUniversalIdentifier, + }); + + await pipeline(archiveStream, createWriteStream(archivePath)); + + await fs.rm(targetPackagePath, { recursive: true, force: true }); + await fs.mkdir(targetPackagePath, { recursive: true }); + + const { default: unzipper } = await import('unzipper'); + const directory = await unzipper.Open.file(archivePath); + + await directory.extract({ path: targetPackagePath }); + } finally { + await temporaryDirManager.clean(); + } + } + + async downloadArchiveBuffer({ + workspaceId, + applicationUniversalIdentifier, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + }): Promise { + const archiveStream = await this.readArchiveStream({ + workspaceId, + applicationUniversalIdentifier, + }); + + return streamToBuffer(archiveStream); + } + + async getClientModuleFromArchive({ + workspaceId, + applicationUniversalIdentifier, + moduleName, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + moduleName: SdkModuleName; + }): Promise { + const filePath = `dist/${moduleName}.mjs`; + + const archiveBuffer = await this.downloadArchiveBuffer({ + workspaceId, + applicationUniversalIdentifier, + }); + + const { default: unzipper } = await import('unzipper'); + const directory = await unzipper.Open.buffer(archiveBuffer); + + const entry = directory.files.find( + (file) => file.path === filePath || file.path === `./${filePath}`, + ); + + if (!entry) { + throw new SdkClientException( + `Module "${moduleName}" not found in SDK client archive for application "${applicationUniversalIdentifier}" in workspace "${workspaceId}"`, + SdkClientExceptionCode.FILE_NOT_FOUND_IN_ARCHIVE, + ); + } + + return entry.buffer(); + } + + async markSdkLayerFresh({ + applicationId, + workspaceId, + }: { + applicationId: string; + workspaceId: string; + }): Promise { + await this.applicationRepository.update( + { id: applicationId, workspaceId }, + { isSdkLayerStale: false }, + ); + + await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [ + 'flatApplicationMaps', + ]); + } + + private async readArchiveStream({ + workspaceId, + applicationUniversalIdentifier, + }: { + workspaceId: string; + applicationUniversalIdentifier: string; + }): Promise { + try { + return await this.fileStorageService.readFile({ + workspaceId, + applicationUniversalIdentifier, + fileFolder: FileFolder.GeneratedSdkClient, + resourcePath: SDK_CLIENT_ARCHIVE_NAME, + }); + } catch (error) { + if ( + error instanceof FileStorageException && + error.code === FileStorageExceptionCode.FILE_NOT_FOUND + ) { + throw new SdkClientException( + `SDK client archive "${SDK_CLIENT_ARCHIVE_NAME}" not found for application "${applicationUniversalIdentifier}" in workspace "${workspaceId}".`, + SdkClientExceptionCode.ARCHIVE_NOT_FOUND, + ); + } + + throw error; + } + } +} diff --git a/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-generation.service.ts b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-generation.service.ts new file mode 100644 index 00000000000..0392df0e774 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client-generation.service.ts @@ -0,0 +1,131 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { InjectRepository } from '@nestjs/typeorm'; + +import * as fs from 'fs/promises'; +import { printSchema } from 'graphql'; +import path, { join } from 'path'; + +import { replaceCoreClient } from 'twenty-client-sdk/generate'; +import { FileFolder } from 'twenty-shared/types'; +import { Repository } from 'typeorm'; + +import { WorkspaceSchemaFactory } from 'src/engine/api/graphql/workspace-schema.factory'; +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; +import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service'; +import { createZipFile } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/create-zip-file'; +import { TemporaryDirManager } from 'src/engine/core-modules/logic-function/logic-function-drivers/utils/temporary-dir-manager'; +import { SDK_CLIENT_PACKAGE_DIRNAME } from 'src/engine/core-modules/sdk-client/constants/sdk-client-package-dirname'; +import { + SdkClientException, + SdkClientExceptionCode, +} from 'src/engine/core-modules/sdk-client/exceptions/sdk-client.exception'; +import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; +import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; + +const SDK_CLIENT_ARCHIVE_NAME = 'twenty-client-sdk.zip'; + +@Injectable() +export class SdkClientGenerationService { + private readonly logger = new Logger(SdkClientGenerationService.name); + + constructor( + private readonly fileStorageService: FileStorageService, + @InjectRepository(ApplicationEntity) + private readonly applicationRepository: Repository, + private readonly workspaceCacheService: WorkspaceCacheService, + private readonly workspaceSchemaFactory: WorkspaceSchemaFactory, + ) {} + + async generateSdkClientForApplication({ + workspaceId, + applicationId, + applicationUniversalIdentifier, + }: { + workspaceId: string; + applicationId: string; + applicationUniversalIdentifier: string; + }): Promise { + const graphqlSchema = await this.workspaceSchemaFactory.createGraphQLSchema( + { id: workspaceId } as WorkspaceEntity, + applicationId, + ); + + await this.generateAndStore({ + workspaceId, + applicationId, + applicationUniversalIdentifier, + schema: printSchema(graphqlSchema), + }); + + this.logger.log( + `Generated SDK client for application ${applicationUniversalIdentifier}`, + ); + } + + private async generateAndStore({ + workspaceId, + applicationId, + applicationUniversalIdentifier, + schema, + }: { + workspaceId: string; + applicationId: string; + applicationUniversalIdentifier: string; + schema: string; + }): Promise { + const temporaryDirManager = new TemporaryDirManager(); + + try { + const { sourceTemporaryDir } = await temporaryDirManager.init(); + + const tempPackageRoot = join(sourceTemporaryDir, 'twenty-client-sdk'); + + await fs.cp(SDK_CLIENT_PACKAGE_DIRNAME, tempPackageRoot, { + recursive: true, + filter: (source) => { + const relativePath = path.relative( + SDK_CLIENT_PACKAGE_DIRNAME, + source, + ); + + return ( + !relativePath.includes('node_modules') && + !relativePath.startsWith('src') + ); + }, + }); + + await replaceCoreClient({ packageRoot: tempPackageRoot, schema }); + + const archivePath = join(sourceTemporaryDir, SDK_CLIENT_ARCHIVE_NAME); + + await createZipFile(tempPackageRoot, archivePath); + + await this.fileStorageService.writeFile({ + workspaceId, + applicationUniversalIdentifier, + fileFolder: FileFolder.GeneratedSdkClient, + resourcePath: SDK_CLIENT_ARCHIVE_NAME, + sourceFile: await fs.readFile(archivePath), + mimeType: 'application/zip', + settings: { isTemporaryFile: false, toDelete: false }, + }); + + await this.applicationRepository.update( + { id: applicationId, workspaceId }, + { isSdkLayerStale: true }, + ); + + await this.workspaceCacheService.invalidateAndRecompute(workspaceId, [ + 'flatApplicationMaps', + ]); + } catch (error) { + throw new SdkClientException( + `Failed to generate SDK client for application "${applicationUniversalIdentifier}" in workspace "${workspaceId}": ${error instanceof Error ? error.message : String(error)}`, + SdkClientExceptionCode.GENERATION_FAILED, + ); + } finally { + await temporaryDirManager.clean(); + } + } +} diff --git a/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client.module.ts b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client.module.ts new file mode 100644 index 00000000000..cf36aac3d17 --- /dev/null +++ b/packages/twenty-server/src/engine/core-modules/sdk-client/sdk-client.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { CoreGraphQLApiModule } from 'src/engine/api/graphql/core-graphql-api.module'; + +import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; +import { SdkClientController } from 'src/engine/core-modules/sdk-client/controllers/sdk-client.controller'; +import { SdkClientArchiveService } from 'src/engine/core-modules/sdk-client/sdk-client-archive.service'; +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; +import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([ApplicationEntity]), + WorkspaceCacheModule, + CoreGraphQLApiModule, + ], + controllers: [SdkClientController], + providers: [SdkClientGenerationService, SdkClientArchiveService], + exports: [SdkClientGenerationService, SdkClientArchiveService], +}) +export class SdkClientModule {} diff --git a/packages/twenty-server/src/engine/metadata-modules/calendar-channel/calendar-channel-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/calendar-channel/calendar-channel-metadata.module.ts index 47b3ac895f1..a940bad53cb 100644 --- a/packages/twenty-server/src/engine/metadata-modules/calendar-channel/calendar-channel-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/calendar-channel/calendar-channel-metadata.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { CalendarChannelMetadataService } from 'src/engine/metadata-modules/calendar-channel/calendar-channel-metadata.service'; import { CalendarChannelEntity } from 'src/engine/metadata-modules/calendar-channel/entities/calendar-channel.entity'; @@ -13,7 +12,6 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi @Module({ imports: [ TypeOrmModule.forFeature([CalendarChannelEntity]), - AuthModule, PermissionsModule, FeatureFlagModule, ConnectedAccountMetadataModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts index fe9b24db36b..05eb27d8d58 100644 --- a/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/command-menu-item/command-menu-item.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@nestjs/common'; import { isDefined } from 'twenty-shared/utils'; -import { type QueryRunner } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { @@ -88,7 +87,6 @@ export class CommandMenuItemService { async create( input: CreateCommandMenuItemInput, workspaceId: string, - queryRunner?: QueryRunner, ): Promise { const { flatObjectMetadataMaps, flatFrontComponentMaps } = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps( @@ -126,7 +124,6 @@ export class CommandMenuItemService { isSystemBuild: false, applicationUniversalIdentifier: workspaceCustomFlatApplication.universalIdentifier, - queryRunner, }, ); @@ -156,7 +153,6 @@ export class CommandMenuItemService { async update( input: UpdateCommandMenuItemInput, workspaceId: string, - queryRunner?: QueryRunner, ): Promise { const { workspaceCustomFlatApplication } = await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( @@ -195,7 +191,6 @@ export class CommandMenuItemService { isSystemBuild: false, applicationUniversalIdentifier: workspaceCustomFlatApplication.universalIdentifier, - queryRunner, }, ); @@ -222,11 +217,7 @@ export class CommandMenuItemService { ); } - async delete( - id: string, - workspaceId: string, - queryRunner?: QueryRunner, - ): Promise { + async delete(id: string, workspaceId: string): Promise { const { workspaceCustomFlatApplication } = await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( { workspaceId }, @@ -260,7 +251,6 @@ export class CommandMenuItemService { isSystemBuild: false, applicationUniversalIdentifier: workspaceCustomFlatApplication.universalIdentifier, - queryRunner, }, ); diff --git a/packages/twenty-server/src/engine/metadata-modules/connected-account/connected-account-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/connected-account/connected-account-metadata.module.ts index 724a7959672..626d80173d4 100644 --- a/packages/twenty-server/src/engine/metadata-modules/connected-account/connected-account-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/connected-account/connected-account-metadata.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { ConnectedAccountMetadataService } from 'src/engine/metadata-modules/connected-account/connected-account-metadata.service'; import { ConnectedAccountEntity } from 'src/engine/metadata-modules/connected-account/entities/connected-account.entity'; @@ -12,7 +11,6 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi @Module({ imports: [ TypeOrmModule.forFeature([ConnectedAccountEntity]), - AuthModule, PermissionsModule, FeatureFlagModule, ], diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/__tests__/__snapshots__/all-universal-flat-entity-properties-to-compare-and-stringify.constant.spec.ts.snap b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/__tests__/__snapshots__/all-universal-flat-entity-properties-to-compare-and-stringify.constant.spec.ts.snap index da709e742a4..cb91d8d9799 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/__tests__/__snapshots__/all-universal-flat-entity-properties-to-compare-and-stringify.constant.spec.ts.snap +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/__tests__/__snapshots__/all-universal-flat-entity-properties-to-compare-and-stringify.constant.spec.ts.snap @@ -67,6 +67,7 @@ exports[`ALL_UNIVERSAL_FLAT_ENTITY_PROPERTIES_TO_COMPARE_AND_STRINGIFY should ma "builtComponentPath", "componentName", "isHeadless", + "usesSdkClient", ], "propertiesToStringify": [], }, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts index 061aa367ee8..494014d56e6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-entity/constant/all-entity-properties-configuration-by-metadata-name.constant.ts @@ -1405,6 +1405,11 @@ export const ALL_ENTITY_PROPERTIES_CONFIGURATION_BY_METADATA_NAME = { toStringify: false, universalProperty: undefined, }, + usesSdkClient: { + toCompare: true, + toStringify: false, + universalProperty: undefined, + }, createdAt: { toCompare: false, toStringify: false, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts index aeabdc4c42c..310f771f077 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/__tests__/morph-relation-from-create-field-input-to-flat-field-metadatas-to-create.spec.ts @@ -43,6 +43,7 @@ const MOCK_FLAT_APPLICATION: FlatApplication = { createdAt: new Date(), updatedAt: new Date(), deletedAt: null, + isSdkLayerStale: true, }; const flatObjectMetadataMaps = [ diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts index 47089756a3d..46051c13004 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/__tests__/generate-morph-or-relation-flat-field-metadata-pair.spec.ts @@ -38,6 +38,7 @@ const MOCK_FLAT_APPLICATION: FlatApplication = { createdAt: new Date(), updatedAt: new Date(), deletedAt: null, + isSdkLayerStale: true, }; type GenerateMorphOrRelationFlatFieldMetadataPairTestInput = Parameters< diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-create-front-component-input-to-flat-front-component-to-create.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-create-front-component-input-to-flat-front-component-to-create.util.ts index 5e9d2669ad5..b2061bea394 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-create-front-component-input-to-flat-front-component-to-create.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-create-front-component-input-to-flat-front-component-to-create.util.ts @@ -34,6 +34,7 @@ export const fromCreateFrontComponentInputToFlatFrontComponentToCreate = ({ componentName: createFrontComponentInput.componentName, builtComponentChecksum: createFrontComponentInput.builtComponentChecksum, isHeadless: false, + usesSdkClient: false, workspaceId, createdAt: now, updatedAt: now, diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-flat-front-component-to-front-component-dto.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-flat-front-component-to-front-component-dto.util.ts index 0d4f1e1dfce..1c7d3d8dcbf 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-flat-front-component-to-front-component-dto.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-flat-front-component-to-front-component-dto.util.ts @@ -21,6 +21,7 @@ export const fromFlatFrontComponentToFrontComponentDto = ( workspaceId: flatFrontComponent.workspaceId, applicationId: flatFrontComponent.applicationId, isHeadless: flatFrontComponent.isHeadless, + usesSdkClient: flatFrontComponent.usesSdkClient, createdAt: new Date(flatFrontComponent.createdAt), updatedAt: new Date(flatFrontComponent.updatedAt), }); diff --git a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-front-component-entity-to-flat-front-component.util.ts b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-front-component-entity-to-flat-front-component.util.ts index 04ae15c704d..bd49aaaeae6 100644 --- a/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-front-component-entity-to-flat-front-component.util.ts +++ b/packages/twenty-server/src/engine/metadata-modules/flat-front-component/utils/from-front-component-entity-to-flat-front-component.util.ts @@ -32,6 +32,7 @@ export const fromFrontComponentEntityToFlatFrontComponent = ({ componentName: frontComponentEntity.componentName, builtComponentChecksum: frontComponentEntity.builtComponentChecksum, isHeadless: frontComponentEntity.isHeadless, + usesSdkClient: frontComponentEntity.usesSdkClient, workspaceId: frontComponentEntity.workspaceId, universalIdentifier: frontComponentEntity.universalIdentifier, applicationId: frontComponentEntity.applicationId, diff --git a/packages/twenty-server/src/engine/metadata-modules/front-component/dtos/front-component.dto.ts b/packages/twenty-server/src/engine/metadata-modules/front-component/dtos/front-component.dto.ts index a9a28e9da20..5b2377aea6c 100644 --- a/packages/twenty-server/src/engine/metadata-modules/front-component/dtos/front-component.dto.ts +++ b/packages/twenty-server/src/engine/metadata-modules/front-component/dtos/front-component.dto.ts @@ -68,6 +68,10 @@ export class FrontComponentDTO { @Field() isHeadless: boolean; + @IsBoolean() + @Field() + usesSdkClient: boolean; + @Field(() => ApplicationTokenPairDTO, { nullable: true }) applicationTokenPair?: ApplicationTokenPairDTO; } diff --git a/packages/twenty-server/src/engine/metadata-modules/front-component/entities/front-component.entity.ts b/packages/twenty-server/src/engine/metadata-modules/front-component/entities/front-component.entity.ts index fb2ce1a1e42..9385e63198a 100644 --- a/packages/twenty-server/src/engine/metadata-modules/front-component/entities/front-component.entity.ts +++ b/packages/twenty-server/src/engine/metadata-modules/front-component/entities/front-component.entity.ts @@ -37,6 +37,9 @@ export class FrontComponentEntity @Column({ default: false }) isHeadless: boolean; + @Column({ default: false }) + usesSdkClient: boolean; + @CreateDateColumn({ type: 'timestamptz' }) createdAt: Date; diff --git a/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts b/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts index 36fdd6c4e9e..9961ae33abc 100644 --- a/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts +++ b/packages/twenty-server/src/engine/metadata-modules/front-component/front-component.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@nestjs/common'; -import { type Readable } from 'stream'; +import { Readable } from 'stream'; import { FileFolder } from 'twenty-shared/types'; import { isDefined } from 'twenty-shared/utils'; diff --git a/packages/twenty-server/src/engine/metadata-modules/message-channel/message-channel-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/message-channel/message-channel-metadata.module.ts index 2b58d14c8d7..59129a0ca70 100644 --- a/packages/twenty-server/src/engine/metadata-modules/message-channel/message-channel-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/message-channel/message-channel-metadata.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { ConnectedAccountMetadataModule } from 'src/engine/metadata-modules/connected-account/connected-account-metadata.module'; import { MessageChannelEntity } from 'src/engine/metadata-modules/message-channel/entities/message-channel.entity'; @@ -15,7 +14,6 @@ import { MessagingImportManagerModule } from 'src/modules/messaging/message-impo @Module({ imports: [ TypeOrmModule.forFeature([MessageChannelEntity]), - AuthModule, PermissionsModule, FeatureFlagModule, ConnectedAccountMetadataModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/message-folder/message-folder-metadata.module.ts b/packages/twenty-server/src/engine/metadata-modules/message-folder/message-folder-metadata.module.ts index 46369ac9c03..784281b9bb0 100644 --- a/packages/twenty-server/src/engine/metadata-modules/message-folder/message-folder-metadata.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/message-folder/message-folder-metadata.module.ts @@ -1,7 +1,6 @@ import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; import { ConnectedAccountMetadataModule } from 'src/engine/metadata-modules/connected-account/connected-account-metadata.module'; import { MessageChannelMetadataModule } from 'src/engine/metadata-modules/message-channel/message-channel-metadata.module'; @@ -14,7 +13,6 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi @Module({ imports: [ TypeOrmModule.forFeature([MessageFolderEntity]), - AuthModule, PermissionsModule, FeatureFlagModule, ConnectedAccountMetadataModule, diff --git a/packages/twenty-server/src/engine/metadata-modules/webhook/webhook.module.ts b/packages/twenty-server/src/engine/metadata-modules/webhook/webhook.module.ts index d5f180da968..99d5f2f1892 100644 --- a/packages/twenty-server/src/engine/metadata-modules/webhook/webhook.module.ts +++ b/packages/twenty-server/src/engine/metadata-modules/webhook/webhook.module.ts @@ -3,7 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; -import { AuthModule } from 'src/engine/core-modules/auth/auth.module'; +import { TokenModule } from 'src/engine/core-modules/auth/token/token.module'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; import { FlatWebhookModule } from 'src/engine/metadata-modules/flat-webhook/flat-webhook.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; @@ -23,7 +23,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace WorkspaceMigrationModule, WorkspaceCacheStorageModule, ApplicationModule, - AuthModule, + TokenModule, PermissionsModule, FlatWebhookModule, ], diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/dev-seeder.module.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/dev-seeder.module.ts index 817d3468edf..e1001bb1b35 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/dev-seeder.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/dev-seeder.module.ts @@ -6,6 +6,7 @@ import { ApiKeyModule } from 'src/engine/core-modules/api-key/api-key.module'; import { ApplicationRegistrationModule } from 'src/engine/core-modules/application/application-registration/application-registration.module'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; +import { SdkClientModule } from 'src/engine/core-modules/sdk-client/sdk-client.module'; import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; @@ -50,6 +51,7 @@ import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace WorkspaceCacheModule, WorkspaceMigrationModule, TwentyStandardApplicationModule, + SdkClientModule, ], exports: [DevSeederService], providers: [ diff --git a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/services/dev-seeder.service.ts b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/services/dev-seeder.service.ts index 6f85022bd5f..59fe7f9794c 100644 --- a/packages/twenty-server/src/engine/workspace-manager/dev-seeder/services/dev-seeder.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/dev-seeder/services/dev-seeder.service.ts @@ -1,12 +1,13 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { InjectDataSource } from '@nestjs/typeorm'; import { ALL_METADATA_NAME } from 'twenty-shared/metadata'; -import { DataSource } from 'typeorm'; import { FeatureFlagKey } from 'twenty-shared/types'; +import { DataSource } from 'typeorm'; import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; @@ -27,6 +28,8 @@ import { TwentyStandardApplicationService } from 'src/engine/workspace-manager/t @Injectable() export class DevSeederService { + private readonly logger = new Logger(DevSeederService.name); + constructor( private readonly workspaceCacheStorageService: WorkspaceCacheStorageService, private readonly twentyConfigService: TwentyConfigService, @@ -39,6 +42,7 @@ export class DevSeederService { private readonly applicationService: ApplicationService, private readonly applicationRegistrationService: ApplicationRegistrationService, private readonly workspaceCacheService: WorkspaceCacheService, + private readonly sdkClientGenerationService: SdkClientGenerationService, @InjectDataSource() private readonly coreDataSource: DataSource, ) {} @@ -90,12 +94,26 @@ export class DevSeederService { }, ); + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: twentyStandardFlatApplication.id, + applicationUniversalIdentifier: + twentyStandardFlatApplication.universalIdentifier, + }); + await this.devSeederMetadataService.seed({ dataSourceMetadata, workspaceId, light, }); + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: workspaceCustomFlatApplication.id, + applicationUniversalIdentifier: + workspaceCustomFlatApplication.universalIdentifier, + }); + await this.devSeederMetadataService.seedRelations({ workspaceId, light, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts index 595133b3059..2eba9f24ad8 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.module.ts @@ -3,18 +3,19 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { ApplicationModule } from 'src/engine/core-modules/application/application.module'; import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module'; +import { SdkClientModule } from 'src/engine/core-modules/sdk-client/sdk-client.module'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { AiAgentModule } from 'src/engine/metadata-modules/ai/ai-agent/ai-agent.module'; import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-source.module'; import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module'; +import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity'; import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity'; import { RoleModule } from 'src/engine/metadata-modules/role/role.module'; -import { LogicFunctionEntity } from 'src/engine/metadata-modules/logic-function/logic-function.entity'; import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module'; import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; import { DevSeederModule } from 'src/engine/workspace-manager/dev-seeder/dev-seeder.module'; @@ -39,6 +40,7 @@ import { WorkspaceManagerService } from './workspace-manager.service'; RoleModule, UserRoleModule, ApplicationModule, + SdkClientModule, TypeOrmModule.forFeature([ FieldMetadataEntity, RoleTargetEntity, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts index 19d102407a9..23bd6c23c69 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-manager.service.ts @@ -5,6 +5,7 @@ import { Repository } from 'typeorm'; import { ApplicationService } from 'src/engine/core-modules/application/application.service'; import { FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type'; +import { SdkClientGenerationService } from 'src/engine/core-modules/sdk-client/sdk-client-generation.service'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity'; import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service'; @@ -32,6 +33,7 @@ export class WorkspaceManagerService { @InjectRepository(RoleEntity) private readonly roleRepository: Repository, private readonly applicationService: ApplicationService, + private readonly sdkClientGenerationService: SdkClientGenerationService, ) {} public async init({ @@ -77,13 +79,27 @@ export class WorkspaceManagerService { `Metadata creation took ${dataSourceMetadataCreationEnd - dataSourceMetadataCreationStart}ms`, ); - const { workspaceCustomFlatApplication } = + const { workspaceCustomFlatApplication, twentyStandardFlatApplication } = await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow( { workspaceId, }, ); + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: twentyStandardFlatApplication.id, + applicationUniversalIdentifier: + twentyStandardFlatApplication.universalIdentifier, + }); + + await this.sdkClientGenerationService.generateSdkClientForApplication({ + workspaceId, + applicationId: workspaceCustomFlatApplication.id, + applicationUniversalIdentifier: + workspaceCustomFlatApplication.universalIdentifier, + }); + await this.setupDefaultRoles({ workspaceId, userId, diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service.ts index ec151af84e9..ea258c054d5 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service.ts @@ -5,11 +5,9 @@ import { WorkspaceMigrationV2ExceptionCode, } from 'twenty-shared/metadata'; import { isDefined } from 'twenty-shared/utils'; -import { type QueryRunner } from 'typeorm'; import { FlatApplicationCacheMaps } from 'src/engine/core-modules/application/types/flat-application-cache-maps.type'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; -import { MetadataEventEmitter } from 'src/engine/subscriptions/metadata-event/metadata-event-emitter'; import { ALL_MANY_TO_ONE_METADATA_RELATIONS } from 'src/engine/metadata-modules/flat-entity/constant/all-many-to-one-metadata-relations.constant'; import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant'; import { @@ -23,6 +21,7 @@ import { MetadataUniversalFlatEntity } from 'src/engine/metadata-modules/flat-en import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util'; import { getMetadataRelatedMetadataNamesForValidation } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-related-metadata-names-for-validation.util'; import { getSubFlatEntityMapsByApplicationIdsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-by-application-ids-or-throw.util'; +import { MetadataEventEmitter } from 'src/engine/subscriptions/metadata-event/metadata-event-emitter'; import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service'; import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications'; import { WorkspaceMigrationV2Exception } from 'src/engine/workspace-manager/workspace-migration.exception'; @@ -359,17 +358,14 @@ export class WorkspaceMigrationValidateBuildAndRunService { public async validateBuildAndRunWorkspaceMigrationFromTo( args: WorkspaceMigrationOrchestratorBuildArgs & { idByUniversalIdentifierByMetadataName?: IdByUniversalIdentifierByMetadataName; - queryRunner?: QueryRunner; }, ): Promise< | WorkspaceMigrationOrchestratorFailedResult - | WorkspaceMigrationOrchestratorSuccessfulResult + | (WorkspaceMigrationOrchestratorSuccessfulResult & { + hasSchemaMetadataChanged: boolean; + }) > { - const { - idByUniversalIdentifierByMetadataName, - queryRunner: externalQueryRunner, - ...buildArgs - } = args; + const { idByUniversalIdentifierByMetadataName, ...buildArgs } = args; const validateAndBuildResult = await this.workspaceMigrationBuildOrchestratorService @@ -397,24 +393,29 @@ export class WorkspaceMigrationValidateBuildAndRunService { }) : validateAndBuildResult.workspaceMigration; - if (workspaceMigration.actions.length > 0) { - const { metadataEvents } = await this.workspaceMigrationRunnerService.run( - { - workspaceId: args.workspaceId, - workspaceMigration, - queryRunner: externalQueryRunner, - }, - ); - - this.metadataEventEmitter.emitMetadataEvents({ - metadataEvents, - workspaceId: args.workspaceId, - }); + if (workspaceMigration.actions.length === 0) { + return { + status: 'success', + workspaceMigration, + hasSchemaMetadataChanged: false, + }; } + const { hasSchemaMetadataChanged, metadataEvents } = + await this.workspaceMigrationRunnerService.run({ + workspaceId: args.workspaceId, + workspaceMigration, + }); + + this.metadataEventEmitter.emitMetadataEvents({ + metadataEvents: metadataEvents, + workspaceId: args.workspaceId, + }); + return { status: 'success', workspaceMigration, + hasSchemaMetadataChanged, }; } @@ -423,10 +424,7 @@ export class WorkspaceMigrationValidateBuildAndRunService { workspaceId, isSystemBuild = false, applicationUniversalIdentifier, - queryRunner, - }: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs & { - queryRunner?: QueryRunner; - }): Promise< + }: ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs): Promise< | WorkspaceMigrationOrchestratorFailedResult | WorkspaceMigrationOrchestratorSuccessfulResult > { @@ -453,7 +451,6 @@ export class WorkspaceMigrationValidateBuildAndRunService { dependencyAllFlatEntityMaps, additionalCacheDataMaps, idByUniversalIdentifierByMetadataName, - queryRunner, }); } } diff --git a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service.ts b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service.ts index 1b03e34f64a..510d1079ce2 100644 --- a/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service.ts +++ b/packages/twenty-server/src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service.ts @@ -3,7 +3,7 @@ import { InjectDataSource } from '@nestjs/typeorm'; import { type AllMetadataName } from 'twenty-shared/metadata'; import { isDefined } from 'twenty-shared/utils'; -import { DataSource, type QueryRunner } from 'typeorm'; +import { DataSource } from 'typeorm'; import { LoggerService } from 'src/engine/core-modules/logger/logger.service'; import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service'; @@ -154,21 +154,18 @@ export class WorkspaceMigrationRunnerService { run = async ({ workspaceMigration: { actions, applicationUniversalIdentifier }, workspaceId, - queryRunner: externalQueryRunner, }: { workspaceMigration: WorkspaceMigration; workspaceId: string; - queryRunner?: QueryRunner; }): Promise<{ allFlatEntityMaps: AllFlatEntityMaps; metadataEvents: MetadataEvent[]; + hasSchemaMetadataChanged: boolean; }> => { this.logger.time('Runner', 'Total execution'); this.logger.time('Runner', 'Initial cache retrieval'); - const queryRunner = - externalQueryRunner ?? this.coreDataSource.createQueryRunner(); - const isTransactionAlreadyActive = queryRunner.isTransactionActive; + const queryRunner = this.coreDataSource.createQueryRunner(); const actionMetadataNames = [ ...new Set(actions.flatMap((action) => action.metadataName)), @@ -219,10 +216,8 @@ export class WorkspaceMigrationRunnerService { this.logger.time('Runner', 'Transaction execution'); - if (!isTransactionAlreadyActive) { - await queryRunner.connect(); - await queryRunner.startTransaction(); - } + await queryRunner.connect(); + await queryRunner.startTransaction(); try { const allMetadataEvents: MetadataEvent[] = []; @@ -250,9 +245,7 @@ export class WorkspaceMigrationRunnerService { allMetadataEvents.push(...metadataEvents); } - if (!isTransactionAlreadyActive) { - await queryRunner.commitTransaction(); - } + await queryRunner.commitTransaction(); this.logger.timeEnd('Runner', 'Transaction execution'); @@ -261,18 +254,24 @@ export class WorkspaceMigrationRunnerService { workspaceId, }); + const hasSchemaMetadataChanged = + allFlatEntityMapsKeys.includes('flatObjectMetadataMaps') || + allFlatEntityMapsKeys.includes('flatFieldMetadataMaps'); + this.logger.timeEnd('Runner', 'Total execution'); - return { allFlatEntityMaps, metadataEvents: allMetadataEvents }; + return { + allFlatEntityMaps, + metadataEvents: allMetadataEvents, + hasSchemaMetadataChanged, + }; } catch (error) { - if (!isTransactionAlreadyActive && queryRunner.isTransactionActive) { - await queryRunner.rollbackTransaction().catch((rollbackError) => - // oxlint-disable-next-line no-console - console.trace( - `Failed to rollback transaction: ${rollbackError.message}`, - ), - ); - } + await queryRunner.rollbackTransaction().catch((rollbackError) => + // oxlint-disable-next-line no-console + console.trace( + `Failed to rollback transaction: ${rollbackError.message}`, + ), + ); const invertedActions = [...actions].reverse(); @@ -299,9 +298,7 @@ export class WorkspaceMigrationRunnerService { code: WorkspaceMigrationRunnerExceptionCode.INTERNAL_SERVER_ERROR, }); } finally { - if (!isTransactionAlreadyActive) { - await queryRunner.release(); - } + await queryRunner.release(); } }; } diff --git a/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-query-hook.module.ts b/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-query-hook.module.ts index 2bfb8d5c8a1..84165259e12 100644 --- a/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-query-hook.module.ts +++ b/packages/twenty-server/src/modules/workspace-member/query-hooks/workspace-member-query-hook.module.ts @@ -5,7 +5,6 @@ import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature- import { OnboardingModule } from 'src/engine/core-modules/onboarding/onboarding.module'; import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity'; import { UserWorkspaceModule } from 'src/engine/core-modules/user-workspace/user-workspace.module'; -import { UserModule } from 'src/engine/core-modules/user/user.module'; import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module'; import { WorkspaceMemberCreateManyPreQueryHook } from 'src/modules/workspace-member/query-hooks/workspace-member-create-many.pre-query.hook'; import { WorkspaceMemberCreateOnePreQueryHook } from 'src/modules/workspace-member/query-hooks/workspace-member-create-one.pre-query.hook'; @@ -41,7 +40,6 @@ import { WorkspaceMemberUpdateOnePreQueryHook } from 'src/modules/workspace-memb PermissionsModule, UserWorkspaceModule, TypeOrmModule.forFeature([UserWorkspaceEntity]), - UserModule, ], }) export class WorkspaceMemberQueryHookModule {} diff --git a/packages/twenty-server/test/integration/metadata/suites/application/app-distribution.integration-spec.ts b/packages/twenty-server/test/integration/metadata/suites/application/app-distribution.integration-spec.ts index 50b49fdf45d..f3972e67076 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/app-distribution.integration-spec.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/app-distribution.integration-spec.ts @@ -57,7 +57,6 @@ const createValidManifest = (universalIdentifier: string) => applicationVariables: {}, packageJsonChecksum: null, yarnLockChecksum: null, - apiClientChecksum: null, }, roles: [], skills: [], diff --git a/packages/twenty-server/test/integration/metadata/suites/application/utils/build-base-manifest.util.ts b/packages/twenty-server/test/integration/metadata/suites/application/utils/build-base-manifest.util.ts index f971ca79786..eb1b8a2ff95 100644 --- a/packages/twenty-server/test/integration/metadata/suites/application/utils/build-base-manifest.util.ts +++ b/packages/twenty-server/test/integration/metadata/suites/application/utils/build-base-manifest.util.ts @@ -18,7 +18,6 @@ export const buildBaseManifest = ({ applicationVariables: {}, packageJsonChecksum: null, yarnLockChecksum: null, - apiClientChecksum: null, }, roles: [ { diff --git a/packages/twenty-shared/src/application/applicationType.ts b/packages/twenty-shared/src/application/applicationType.ts index 49e8e4d5c2c..e30946bf604 100644 --- a/packages/twenty-shared/src/application/applicationType.ts +++ b/packages/twenty-shared/src/application/applicationType.ts @@ -22,5 +22,4 @@ export type ApplicationManifest = SyncableEntityOptions & { settingsCustomTabFrontComponentUniversalIdentifier?: string; packageJsonChecksum: string | null; yarnLockChecksum: string | null; - apiClientChecksum: string | null; }; diff --git a/packages/twenty-shared/src/application/constants/ApiClientDirectory.ts b/packages/twenty-shared/src/application/constants/ApiClientDirectory.ts deleted file mode 100644 index 4282f67dd70..00000000000 --- a/packages/twenty-shared/src/application/constants/ApiClientDirectory.ts +++ /dev/null @@ -1 +0,0 @@ -export const API_CLIENT_DIR = 'api-client'; diff --git a/packages/twenty-shared/src/application/frontComponentManifestType.ts b/packages/twenty-shared/src/application/frontComponentManifestType.ts index 2a8093ab8dd..6cb75ca3571 100644 --- a/packages/twenty-shared/src/application/frontComponentManifestType.ts +++ b/packages/twenty-shared/src/application/frontComponentManifestType.ts @@ -25,5 +25,6 @@ export type FrontComponentManifest = { builtComponentChecksum: string; componentName: string; isHeadless?: boolean; + usesSdkClient?: boolean; command?: FrontComponentCommandManifest; }; diff --git a/packages/twenty-shared/src/application/index.ts b/packages/twenty-shared/src/application/index.ts index 77837884484..e8f2c026db0 100644 --- a/packages/twenty-shared/src/application/index.ts +++ b/packages/twenty-shared/src/application/index.ts @@ -11,7 +11,6 @@ export type { AgentManifest } from './agentManifestType'; export type { ApplicationManifest } from './applicationType'; export type { ApplicationVariables } from './applicationVariablesType'; export type { AssetManifest } from './assetManifestType'; -export { API_CLIENT_DIR } from './constants/ApiClientDirectory'; export { ASSETS_DIR } from './constants/AssetDirectory'; export { DEFAULT_API_KEY_NAME } from './constants/DefaultApiKeyName'; export { DEFAULT_API_URL_NAME } from './constants/DefaultApiUrlName'; diff --git a/packages/twenty-shared/src/types/FileFolder.ts b/packages/twenty-shared/src/types/FileFolder.ts index ef78ba5215a..361e259028c 100644 --- a/packages/twenty-shared/src/types/FileFolder.ts +++ b/packages/twenty-shared/src/types/FileFolder.ts @@ -14,4 +14,5 @@ export enum FileFolder { Dependencies = 'dependencies', Workflow = 'workflow', AppTarball = 'app-tarball', + GeneratedSdkClient = 'generated-sdk-client', } diff --git a/yarn.lock b/yarn.lock index 51303411b37..65d3c71377f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56428,6 +56428,23 @@ __metadata: languageName: unknown linkType: soft +"twenty-client-sdk@workspace:*, twenty-client-sdk@workspace:packages/twenty-client-sdk": + version: 0.0.0-use.local + resolution: "twenty-client-sdk@workspace:packages/twenty-client-sdk" + dependencies: + "@genql/cli": "npm:^3.0.3" + "@genql/runtime": "npm:^2.10.0" + esbuild: "npm:^0.25.0" + graphql: "npm:^16.8.1" + twenty-shared: "workspace:*" + typescript: "npm:^5.9.2" + vite: "npm:^7.0.0" + vite-plugin-dts: "npm:^4.5.4" + vite-tsconfig-paths: "npm:^4.2.1" + vitest: "npm:^4.0.18" + languageName: unknown + linkType: soft + "twenty-docs@workspace:packages/twenty-docs": version: 0.0.0-use.local resolution: "twenty-docs@workspace:packages/twenty-docs" @@ -56630,6 +56647,7 @@ __metadata: tinyglobby: "npm:^0.2.15" ts-morph: "npm:^25.0.0" tsx: "npm:^4.7.0" + twenty-client-sdk: "workspace:*" twenty-shared: "workspace:*" twenty-ui: "workspace:*" typescript: "npm:^5.9.2" @@ -56851,6 +56869,7 @@ __metadata: tsconfig-paths: "npm:^4.2.0" tsdav: "npm:^2.1.5" tslib: "npm:2.8.1" + twenty-client-sdk: "workspace:*" twenty-emails: "workspace:*" twenty-shared: "workspace:*" type-fest: "npm:4.10.1"