diff --git a/packages/twenty-apps/examples/document-generator/src/application-config.ts b/packages/twenty-apps/examples/document-generator/src/application-config.ts
index 15f734cf7c..1f30b09ff5 100644
--- a/packages/twenty-apps/examples/document-generator/src/application-config.ts
+++ b/packages/twenty-apps/examples/document-generator/src/application-config.ts
@@ -12,8 +12,8 @@ export default defineApplication({
universalIdentifier: APPLICATION_UNIVERSAL_IDENTIFIER,
displayName: APP_DISPLAY_NAME,
description: APP_DESCRIPTION,
- logoUrl: 'public/document-generator.svg',
- screenshots: [
+ logo: 'public/document-generator.svg',
+ galleryImages: [
'public/gallery/01-template-editor.png',
'public/gallery/02-command-menu.png',
'public/gallery/03-documents.png',
diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
index 7cecd8b9fd..4156f06ce4 100644
--- a/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
+++ b/packages/twenty-client-sdk/src/metadata/generated/schema.graphql
@@ -2253,7 +2253,8 @@ type MarketplaceAppDetail {
termsUrl: String
emailSupport: String
issueReportUrl: String
- screenshots: [String!]!
+ screenshots: [String!]! @deprecated(reason: "Use galleryImages instead")
+ galleryImages: [String!]!
defaultRoleUniversalIdentifier: String
roles: [MarketplaceAppRole!]
manifest: JSON @deprecated(reason: "Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead")
diff --git a/packages/twenty-client-sdk/src/metadata/generated/schema.ts b/packages/twenty-client-sdk/src/metadata/generated/schema.ts
index 86081d4fbb..f5f3755cc5 100644
--- a/packages/twenty-client-sdk/src/metadata/generated/schema.ts
+++ b/packages/twenty-client-sdk/src/metadata/generated/schema.ts
@@ -1912,7 +1912,9 @@ export interface MarketplaceAppDetail {
termsUrl?: Scalars['String']
emailSupport?: Scalars['String']
issueReportUrl?: Scalars['String']
+ /** @deprecated Use galleryImages instead */
screenshots: Scalars['String'][]
+ galleryImages: Scalars['String'][]
defaultRoleUniversalIdentifier?: Scalars['String']
roles?: MarketplaceAppRole[]
/** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */
@@ -5062,7 +5064,9 @@ export interface MarketplaceAppDetailGenqlSelection{
termsUrl?: boolean | number
emailSupport?: boolean | number
issueReportUrl?: boolean | number
+ /** @deprecated Use galleryImages instead */
screenshots?: boolean | number
+ galleryImages?: boolean | number
defaultRoleUniversalIdentifier?: boolean | number
roles?: MarketplaceAppRoleGenqlSelection
/** @deprecated Use the explicit MarketplaceAppDetail fields (description, author, roles, ...) instead */
diff --git a/packages/twenty-client-sdk/src/metadata/generated/types.ts b/packages/twenty-client-sdk/src/metadata/generated/types.ts
index b1688e9490..09e516f4dc 100644
--- a/packages/twenty-client-sdk/src/metadata/generated/types.ts
+++ b/packages/twenty-client-sdk/src/metadata/generated/types.ts
@@ -4452,6 +4452,9 @@ export default {
"screenshots": [
1
],
+ "galleryImages": [
+ 1
+ ],
"defaultRoleUniversalIdentifier": [
1
],
diff --git a/packages/twenty-docs/developers/extend/apps/config/application.mdx b/packages/twenty-docs/developers/extend/apps/config/application.mdx
index 2de6729d2e..07e0d37fc9 100644
--- a/packages/twenty-docs/developers/extend/apps/config/application.mdx
+++ b/packages/twenty-docs/developers/extend/apps/config/application.mdx
@@ -108,10 +108,14 @@ If you plan to [publish your app](/developers/extend/apps/operations/publishing)
|-------|-------------|
| `author` | Author or company name |
| `category` | App category for marketplace filtering |
-| `logoUrl` | Path to your app logo (e.g., `public/logo.png`) |
-| `screenshots` | Array of screenshot paths (e.g., `public/screenshot-1.png`) |
+| `logo` | Path to your app logo bundled in `public/` (e.g., `public/logo.png`) |
+| `galleryImages` | Array of gallery image paths bundled in `public/` (e.g., `public/screenshot-1.png`) |
| `aboutDescription` | Longer markdown description for the "About" tab. If omitted, the marketplace uses the package's `README.md` from npm |
| `websiteUrl` | Link to your website |
| `termsUrl` | Link to terms of service |
| `emailSupport` | Support email address |
| `issueReportUrl` | Link to issue tracker |
+
+
+`logoUrl` and `screenshots` are deprecated aliases of `logo` and `galleryImages`. External absolute URLs (`http://` or `https://`) are not supported for these fields: they are dropped with a warning at build time. Bundle the images in your app's `public/` folder instead.
+
diff --git a/packages/twenty-docs/developers/extend/apps/config/public-assets.mdx b/packages/twenty-docs/developers/extend/apps/config/public-assets.mdx
index 8350077407..b8c8bd8cfe 100644
--- a/packages/twenty-docs/developers/extend/apps/config/public-assets.mdx
+++ b/packages/twenty-docs/developers/extend/apps/config/public-assets.mdx
@@ -11,7 +11,7 @@ Files placed in `public/` are:
- **Publicly accessible** — once synced to the server, assets are served at a public URL. No authentication is needed to access them.
- **Available in front components** — use asset URLs to display images, icons, or any media inside your React components.
- **Available in logic functions** — reference asset URLs in emails, API responses, or any server-side logic.
-- **Used for marketplace metadata** — the `logoUrl` and `screenshots` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published.
+- **Used for marketplace metadata** — the `logo` and `galleryImages` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published. External absolute URLs are ignored for these fields — bundle the images in `public/` instead.
- **Auto-synced in dev mode** — when you add, update, or delete a file in `public/`, it is synced to the server automatically. No restart needed.
- **Included in builds** — `yarn twenty dev:build` bundles all public assets into the distribution output.
diff --git a/packages/twenty-docs/developers/extend/apps/operations/publishing.mdx b/packages/twenty-docs/developers/extend/apps/operations/publishing.mdx
index bdad1a0415..130e59fd20 100644
--- a/packages/twenty-docs/developers/extend/apps/operations/publishing.mdx
+++ b/packages/twenty-docs/developers/extend/apps/operations/publishing.mdx
@@ -180,15 +180,15 @@ Publishing to npm makes your app discoverable in the Twenty marketplace. Any Twe
### Marketplace metadata
-The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
+The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logo` and `galleryImages` to reference images from the `public/` folder:
```ts src/application-config.ts
export default defineApplication({
universalIdentifier: '...',
displayName: 'My App',
description: 'A great app',
- logoUrl: 'public/logo.png',
- screenshots: [
+ logo: 'public/logo.png',
+ galleryImages: [
'public/screenshot-1.png',
'public/screenshot-2.png',
],
@@ -197,12 +197,12 @@ export default defineApplication({
See the [defineApplication accordion](/developers/extend/apps/config/application#marketplace-metadata) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
-#### Recommended screenshot dimensions
+#### Recommended gallery image dimensions
-The marketplace renders `screenshots` in a fixed `8:5` container (for example, `1600×1000 px`).
+The marketplace renders `galleryImages` in a fixed `8:5` container (for example, `1600×1000 px`).
-Screenshots of any aspect ratio are displayed in full and are never cropped, but anything significantly taller or narrower than `8:5` will show empty bands on the sides.
+Gallery images of any aspect ratio are displayed in full and are never cropped, but anything significantly taller or narrower than `8:5` will show empty bands on the sides.
### Publish
diff --git a/packages/twenty-docs/developers/extend/apps/tutorials/document-generator/publishing.mdx b/packages/twenty-docs/developers/extend/apps/tutorials/document-generator/publishing.mdx
index 570f45ec4f..cc3e181fb4 100644
--- a/packages/twenty-docs/developers/extend/apps/tutorials/document-generator/publishing.mdx
+++ b/packages/twenty-docs/developers/extend/apps/tutorials/document-generator/publishing.mdx
@@ -10,7 +10,7 @@ Your app works. The last step is to describe it for the marketplace and publish.
The [application config](/developers/extend/apps/config/application) carries the
identity that shows up in the marketplace: author, category, logo, and support
-links. Put a logo in `public/` and reference it with `logoUrl`.
+links. Put a logo in `public/` and reference it with `logo`.
```ts filename="src/application-config.ts"
import { defineApplication } from 'twenty-sdk/define';
@@ -20,7 +20,7 @@ export default defineApplication({
displayName: 'Document Generator',
description:
'Create reusable document templates and generate personalized documents from your CRM records.',
- logoUrl: 'public/document-generator.svg',
+ logo: 'public/document-generator.svg',
author: 'Twenty',
category: 'Productivity',
websiteUrl: 'https://docs.twenty.com/developers/extend/apps',
@@ -44,13 +44,13 @@ Also add the `twenty-app` keyword to `package.json` so the app is discoverable:
## Add gallery screenshots
A marketplace listing sells itself with screenshots. Drop a few PNGs in
-`public/gallery/` and reference them with `screenshots` — they render as a gallery
-on the listing page.
+`public/gallery/` and reference them with `galleryImages` — they render as a
+gallery on the listing page, in array order.
```ts filename="src/application-config.ts"
export default defineApplication({
// ...identity from above
- screenshots: [
+ galleryImages: [
'public/gallery/01-generated-document.png',
'public/gallery/02-command-menu.png',
'public/gallery/03-template-editor.png',
diff --git a/packages/twenty-front/src/generated-metadata/graphql.ts b/packages/twenty-front/src/generated-metadata/graphql.ts
index 549a1a4ddf..b0c28b7c74 100644
--- a/packages/twenty-front/src/generated-metadata/graphql.ts
+++ b/packages/twenty-front/src/generated-metadata/graphql.ts
@@ -2316,6 +2316,7 @@ export type MarketplaceAppDetail = {
defaultRoleUniversalIdentifier?: Maybe;
description?: Maybe;
emailSupport?: Maybe;
+ galleryImages: Array;
id: Scalars['String']['output'];
isListed: Scalars['Boolean']['output'];
isVetted: Scalars['Boolean']['output'];
@@ -2326,6 +2327,7 @@ export type MarketplaceAppDetail = {
manifest?: Maybe;
name: Scalars['String']['output'];
roles?: Maybe>;
+ /** @deprecated Use galleryImages instead */
screenshots: Array;
sourcePackage?: Maybe;
sourceType: ApplicationRegistrationSourceType;
@@ -7245,7 +7247,7 @@ export type GetLogicFunctionSourceCodeQueryVariables = Exact<{
export type GetLogicFunctionSourceCodeQuery = { __typename?: 'Query', getLogicFunctionSourceCode?: string | null };
-export type MarketplaceAppDetailFieldsFragment = { __typename?: 'MarketplaceAppDetail', id: string, universalIdentifier: string, name: string, sourceType: ApplicationRegistrationSourceType, sourcePackage?: string | null, latestAvailableVersion?: string | null, isListed: boolean, isVetted: boolean, description?: string | null, author?: string | null, category?: string | null, logo?: string | null, websiteUrl?: string | null, aboutDescription?: string | null, termsUrl?: string | null, emailSupport?: string | null, issueReportUrl?: string | null, screenshots: Array, defaultRoleUniversalIdentifier?: string | null, roles?: Array<{ __typename?: 'MarketplaceAppRole', universalIdentifier: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings?: boolean | null, canAccessAllTools?: boolean | null, canReadAllObjectRecords?: boolean | null, canUpdateAllObjectRecords?: boolean | null, canSoftDeleteAllObjectRecords?: boolean | null, canDestroyAllObjectRecords?: boolean | null, permissionFlagUniversalIdentifiers?: Array | null, objectPermissions?: Array<{ __typename?: 'MarketplaceAppRoleObjectPermission', universalIdentifier: string, objectUniversalIdentifier: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null }> | null, fieldPermissions?: Array<{ __typename?: 'MarketplaceAppRoleFieldPermission', universalIdentifier: string, objectUniversalIdentifier: string, fieldUniversalIdentifier: string, canReadFieldValue?: boolean | null, canUpdateFieldValue?: boolean | null }> | null }> | null };
+export type MarketplaceAppDetailFieldsFragment = { __typename?: 'MarketplaceAppDetail', id: string, universalIdentifier: string, name: string, sourceType: ApplicationRegistrationSourceType, sourcePackage?: string | null, latestAvailableVersion?: string | null, isListed: boolean, isVetted: boolean, description?: string | null, author?: string | null, category?: string | null, logo?: string | null, websiteUrl?: string | null, aboutDescription?: string | null, termsUrl?: string | null, emailSupport?: string | null, issueReportUrl?: string | null, galleryImages: Array, defaultRoleUniversalIdentifier?: string | null, roles?: Array<{ __typename?: 'MarketplaceAppRole', universalIdentifier: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings?: boolean | null, canAccessAllTools?: boolean | null, canReadAllObjectRecords?: boolean | null, canUpdateAllObjectRecords?: boolean | null, canSoftDeleteAllObjectRecords?: boolean | null, canDestroyAllObjectRecords?: boolean | null, permissionFlagUniversalIdentifiers?: Array | null, objectPermissions?: Array<{ __typename?: 'MarketplaceAppRoleObjectPermission', universalIdentifier: string, objectUniversalIdentifier: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null }> | null, fieldPermissions?: Array<{ __typename?: 'MarketplaceAppRoleFieldPermission', universalIdentifier: string, objectUniversalIdentifier: string, fieldUniversalIdentifier: string, canReadFieldValue?: boolean | null, canUpdateFieldValue?: boolean | null }> | null }> | null };
export type MarketplaceAppFieldsFragment = { __typename?: 'MarketplaceApp', id: string, name: string, description: string, author: string, category: string, logo?: string | null, sourcePackage?: string | null, isVetted: boolean };
@@ -7276,7 +7278,7 @@ export type FindMarketplaceAppDetailQueryVariables = Exact<{
}>;
-export type FindMarketplaceAppDetailQuery = { __typename?: 'Query', findMarketplaceAppDetail: { __typename?: 'MarketplaceAppDetail', id: string, universalIdentifier: string, name: string, sourceType: ApplicationRegistrationSourceType, sourcePackage?: string | null, latestAvailableVersion?: string | null, isListed: boolean, isVetted: boolean, description?: string | null, author?: string | null, category?: string | null, logo?: string | null, websiteUrl?: string | null, aboutDescription?: string | null, termsUrl?: string | null, emailSupport?: string | null, issueReportUrl?: string | null, screenshots: Array, defaultRoleUniversalIdentifier?: string | null, roles?: Array<{ __typename?: 'MarketplaceAppRole', universalIdentifier: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings?: boolean | null, canAccessAllTools?: boolean | null, canReadAllObjectRecords?: boolean | null, canUpdateAllObjectRecords?: boolean | null, canSoftDeleteAllObjectRecords?: boolean | null, canDestroyAllObjectRecords?: boolean | null, permissionFlagUniversalIdentifiers?: Array | null, objectPermissions?: Array<{ __typename?: 'MarketplaceAppRoleObjectPermission', universalIdentifier: string, objectUniversalIdentifier: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null }> | null, fieldPermissions?: Array<{ __typename?: 'MarketplaceAppRoleFieldPermission', universalIdentifier: string, objectUniversalIdentifier: string, fieldUniversalIdentifier: string, canReadFieldValue?: boolean | null, canUpdateFieldValue?: boolean | null }> | null }> | null } };
+export type FindMarketplaceAppDetailQuery = { __typename?: 'Query', findMarketplaceAppDetail: { __typename?: 'MarketplaceAppDetail', id: string, universalIdentifier: string, name: string, sourceType: ApplicationRegistrationSourceType, sourcePackage?: string | null, latestAvailableVersion?: string | null, isListed: boolean, isVetted: boolean, description?: string | null, author?: string | null, category?: string | null, logo?: string | null, websiteUrl?: string | null, aboutDescription?: string | null, termsUrl?: string | null, emailSupport?: string | null, issueReportUrl?: string | null, galleryImages: Array, defaultRoleUniversalIdentifier?: string | null, roles?: Array<{ __typename?: 'MarketplaceAppRole', universalIdentifier: string, label: string, description?: string | null, icon?: string | null, canUpdateAllSettings?: boolean | null, canAccessAllTools?: boolean | null, canReadAllObjectRecords?: boolean | null, canUpdateAllObjectRecords?: boolean | null, canSoftDeleteAllObjectRecords?: boolean | null, canDestroyAllObjectRecords?: boolean | null, permissionFlagUniversalIdentifiers?: Array | null, objectPermissions?: Array<{ __typename?: 'MarketplaceAppRoleObjectPermission', universalIdentifier: string, objectUniversalIdentifier: string, canReadObjectRecords?: boolean | null, canUpdateObjectRecords?: boolean | null, canSoftDeleteObjectRecords?: boolean | null, canDestroyObjectRecords?: boolean | null }> | null, fieldPermissions?: Array<{ __typename?: 'MarketplaceAppRoleFieldPermission', universalIdentifier: string, objectUniversalIdentifier: string, fieldUniversalIdentifier: string, canReadFieldValue?: boolean | null, canUpdateFieldValue?: boolean | null }> | null }> | null } };
export type FindMarketplaceAppManifestQueryVariables = Exact<{
universalIdentifier: Scalars['String']['input'];
@@ -8826,7 +8828,7 @@ export const CommandMenuItemFieldsFragmentDoc = {"kind":"Document","definitions"
export const PageLayoutWidgetFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutWidgetFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidget"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"deletedAt"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalAvailabilityExpression"}},{"kind":"Field","name":{"kind":"Name","value":"gridPosition"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}}]}},{"kind":"Field","name":{"kind":"Name","value":"position"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetGridPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetVerticalListPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetCanvasPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"configuration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BarChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"groupMode"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LineChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"isStacked"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PieChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"groupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"groupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"dateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"orderBy"}},{"kind":"Field","name":{"kind":"Name","value":"manualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"showCenterMetric"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"hideEmptyCategory"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AggregateChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"numberFormat"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"prefix"}},{"kind":"Field","name":{"kind":"Name","value":"suffix"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}},{"kind":"Field","name":{"kind":"Name","value":"ratioAggregateConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"optionValue"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"IframeConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StandaloneRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"body"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"blocknote"}},{"kind":"Field","name":{"kind":"Name","value":"markdown"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CalendarConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailThreadConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"fieldDisplayMode"}},{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"newFieldDefaultVisibility"}},{"kind":"Field","name":{"kind":"Name","value":"shouldAllowUserToSeeHiddenFields"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FilesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TasksConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TimelineConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ViewConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RecordTableConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowRunConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowVersionConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FrontComponentConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"frontComponentId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutTabId"}}]}}]} as unknown as DocumentNode;
export const PageLayoutTabFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutTabFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutTab"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"widgets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PageLayoutWidgetFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutWidgetFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidget"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"deletedAt"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalAvailabilityExpression"}},{"kind":"Field","name":{"kind":"Name","value":"gridPosition"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}}]}},{"kind":"Field","name":{"kind":"Name","value":"position"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetGridPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetVerticalListPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetCanvasPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"configuration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BarChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"groupMode"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LineChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"isStacked"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PieChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"groupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"groupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"dateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"orderBy"}},{"kind":"Field","name":{"kind":"Name","value":"manualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"showCenterMetric"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"hideEmptyCategory"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AggregateChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"numberFormat"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"prefix"}},{"kind":"Field","name":{"kind":"Name","value":"suffix"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}},{"kind":"Field","name":{"kind":"Name","value":"ratioAggregateConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"optionValue"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"IframeConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StandaloneRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"body"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"blocknote"}},{"kind":"Field","name":{"kind":"Name","value":"markdown"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CalendarConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailThreadConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"fieldDisplayMode"}},{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"newFieldDefaultVisibility"}},{"kind":"Field","name":{"kind":"Name","value":"shouldAllowUserToSeeHiddenFields"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FilesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TasksConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TimelineConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ViewConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RecordTableConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowRunConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowVersionConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FrontComponentConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"frontComponentId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutTabId"}}]}}]} as unknown as DocumentNode;
export const PageLayoutFragmentFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayout"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"defaultTabToFocusOnMobileAndSidePanelId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"tabs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PageLayoutTabFragment"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutWidgetFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidget"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"objectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"deletedAt"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"conditionalAvailabilityExpression"}},{"kind":"Field","name":{"kind":"Name","value":"gridPosition"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}}]}},{"kind":"Field","name":{"kind":"Name","value":"position"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetGridPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"row"}},{"kind":"Field","name":{"kind":"Name","value":"column"}},{"kind":"Field","name":{"kind":"Name","value":"rowSpan"}},{"kind":"Field","name":{"kind":"Name","value":"columnSpan"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetVerticalListPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"index"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutWidgetCanvasPosition"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"configuration"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"BarChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"groupMode"}},{"kind":"Field","name":{"kind":"Name","value":"layout"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"LineChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"primaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisGroupByDateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisOrderBy"}},{"kind":"Field","name":{"kind":"Name","value":"secondaryAxisManualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"omitNullValues"}},{"kind":"Field","name":{"kind":"Name","value":"axisNameDisplay"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMin"}},{"kind":"Field","name":{"kind":"Name","value":"rangeMax"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"isStacked"}},{"kind":"Field","name":{"kind":"Name","value":"isCumulative"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PieChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"groupByFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"groupBySubFieldName"}},{"kind":"Field","name":{"kind":"Name","value":"dateGranularity"}},{"kind":"Field","name":{"kind":"Name","value":"orderBy"}},{"kind":"Field","name":{"kind":"Name","value":"manualSortOrder"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"showCenterMetric"}},{"kind":"Field","name":{"kind":"Name","value":"displayLegend"}},{"kind":"Field","name":{"kind":"Name","value":"hideEmptyCategory"}},{"kind":"Field","name":{"kind":"Name","value":"splitMultiValueFields"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"AggregateChartConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateFieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"aggregateOperation"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"displayDataLabel"}},{"kind":"Field","name":{"kind":"Name","value":"numberFormat"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"filter"}},{"kind":"Field","name":{"kind":"Name","value":"prefix"}},{"kind":"Field","name":{"kind":"Name","value":"suffix"}},{"kind":"Field","name":{"kind":"Name","value":"timezone"}},{"kind":"Field","name":{"kind":"Name","value":"firstDayOfTheWeek"}},{"kind":"Field","name":{"kind":"Name","value":"ratioAggregateConfig"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"optionValue"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"IframeConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"url"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"StandaloneRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"body"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"blocknote"}},{"kind":"Field","name":{"kind":"Name","value":"markdown"}}]}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"CalendarConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"EmailThreadConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"fieldDisplayMode"}},{"kind":"Field","name":{"kind":"Name","value":"fieldMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldRichTextConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FieldsConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"newFieldDefaultVisibility"}},{"kind":"Field","name":{"kind":"Name","value":"shouldAllowUserToSeeHiddenFields"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FilesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NotesConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TasksConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"TimelineConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"ViewConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"RecordTableConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowRunConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"WorkflowVersionConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}}]}},{"kind":"InlineFragment","typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"FrontComponentConfiguration"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"configurationType"}},{"kind":"Field","name":{"kind":"Name","value":"frontComponentId"}}]}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutTabId"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"PageLayoutTabFragment"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"PageLayoutTab"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"title"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"layoutMode"}},{"kind":"Field","name":{"kind":"Name","value":"widgets"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"PageLayoutWidgetFragment"}}]}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"isActive"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}}]} as unknown as DocumentNode;
-export const MarketplaceAppDetailFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppDetailFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceAppDetail"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sourceType"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"latestAvailableVersion"}},{"kind":"Field","name":{"kind":"Name","value":"isListed"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"aboutDescription"}},{"kind":"Field","name":{"kind":"Name","value":"termsUrl"}},{"kind":"Field","name":{"kind":"Name","value":"emailSupport"}},{"kind":"Field","name":{"kind":"Name","value":"issueReportUrl"}},{"kind":"Field","name":{"kind":"Name","value":"screenshots"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRoleUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"permissionFlagUniversalIdentifiers"}},{"kind":"Field","name":{"kind":"Name","value":"objectPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyObjectRecords"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fieldPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"fieldUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadFieldValue"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateFieldValue"}}]}}]}}]}}]} as unknown as DocumentNode;
+export const MarketplaceAppDetailFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppDetailFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceAppDetail"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sourceType"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"latestAvailableVersion"}},{"kind":"Field","name":{"kind":"Name","value":"isListed"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"aboutDescription"}},{"kind":"Field","name":{"kind":"Name","value":"termsUrl"}},{"kind":"Field","name":{"kind":"Name","value":"emailSupport"}},{"kind":"Field","name":{"kind":"Name","value":"issueReportUrl"}},{"kind":"Field","name":{"kind":"Name","value":"galleryImages"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRoleUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"permissionFlagUniversalIdentifiers"}},{"kind":"Field","name":{"kind":"Name","value":"objectPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyObjectRecords"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fieldPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"fieldUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadFieldValue"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateFieldValue"}}]}}]}}]}}]} as unknown as DocumentNode;
export const MarketplaceAppFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceApp"}},"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":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}}]}}]} as unknown as DocumentNode;
export const NavigationMenuItemFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordId"}},{"kind":"Field","name":{"kind":"Name","value":"targetObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"folderId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"link"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"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 NavigationMenuItemQueryFieldsFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemQueryFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavigationMenuItemFields"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordIdentifier"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifier"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordId"}},{"kind":"Field","name":{"kind":"Name","value":"targetObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"folderId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"link"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"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;
@@ -8959,7 +8961,7 @@ export const GetLogicFunctionSourceCodeDocument = {"kind":"Document","definition
export const InstallApplicationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"InstallApplication"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"installApplication"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}}]}}]}}]} as unknown as DocumentNode;
export const UpgradeApplicationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpgradeApplication"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"appRegistrationId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetVersion"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"upgradeApplication"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"appRegistrationId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"appRegistrationId"}}},{"kind":"Argument","name":{"kind":"Name","value":"targetVersion"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetVersion"}}}]}]}}]} as unknown as DocumentNode;
export const FindManyMarketplaceAppsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindManyMarketplaceApps"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifiers"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findManyMarketplaceApps"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifiers"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifiers"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"MarketplaceAppFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceApp"}},"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":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}}]}}]} as unknown as DocumentNode;
-export const FindMarketplaceAppDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindMarketplaceAppDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findMarketplaceAppDetail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"MarketplaceAppDetailFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppDetailFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceAppDetail"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sourceType"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"latestAvailableVersion"}},{"kind":"Field","name":{"kind":"Name","value":"isListed"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"aboutDescription"}},{"kind":"Field","name":{"kind":"Name","value":"termsUrl"}},{"kind":"Field","name":{"kind":"Name","value":"emailSupport"}},{"kind":"Field","name":{"kind":"Name","value":"issueReportUrl"}},{"kind":"Field","name":{"kind":"Name","value":"screenshots"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRoleUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"permissionFlagUniversalIdentifiers"}},{"kind":"Field","name":{"kind":"Name","value":"objectPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyObjectRecords"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fieldPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"fieldUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadFieldValue"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateFieldValue"}}]}}]}}]}}]} as unknown as DocumentNode;
+export const FindMarketplaceAppDetailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindMarketplaceAppDetail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findMarketplaceAppDetail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"MarketplaceAppDetailFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"MarketplaceAppDetailFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"MarketplaceAppDetail"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"sourceType"}},{"kind":"Field","name":{"kind":"Name","value":"sourcePackage"}},{"kind":"Field","name":{"kind":"Name","value":"latestAvailableVersion"}},{"kind":"Field","name":{"kind":"Name","value":"isListed"}},{"kind":"Field","name":{"kind":"Name","value":"isVetted"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"author"}},{"kind":"Field","name":{"kind":"Name","value":"category"}},{"kind":"Field","name":{"kind":"Name","value":"logo"}},{"kind":"Field","name":{"kind":"Name","value":"websiteUrl"}},{"kind":"Field","name":{"kind":"Name","value":"aboutDescription"}},{"kind":"Field","name":{"kind":"Name","value":"termsUrl"}},{"kind":"Field","name":{"kind":"Name","value":"emailSupport"}},{"kind":"Field","name":{"kind":"Name","value":"issueReportUrl"}},{"kind":"Field","name":{"kind":"Name","value":"galleryImages"}},{"kind":"Field","name":{"kind":"Name","value":"defaultRoleUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"roles"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"label"}},{"kind":"Field","name":{"kind":"Name","value":"description"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllSettings"}},{"kind":"Field","name":{"kind":"Name","value":"canAccessAllTools"}},{"kind":"Field","name":{"kind":"Name","value":"canReadAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyAllObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"permissionFlagUniversalIdentifiers"}},{"kind":"Field","name":{"kind":"Name","value":"objectPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canSoftDeleteObjectRecords"}},{"kind":"Field","name":{"kind":"Name","value":"canDestroyObjectRecords"}}]}},{"kind":"Field","name":{"kind":"Name","value":"fieldPermissions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"universalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"objectUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"fieldUniversalIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"canReadFieldValue"}},{"kind":"Field","name":{"kind":"Name","value":"canUpdateFieldValue"}}]}}]}}]}}]} as unknown as DocumentNode;
export const FindMarketplaceAppManifestDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"FindMarketplaceAppManifest"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"findMarketplaceAppDetail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"universalIdentifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"universalIdentifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"manifest"}}]}}]}}]} as unknown as DocumentNode;
export const CreateManyNavigationMenuItemsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateManyNavigationMenuItems"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"inputs"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"CreateNavigationMenuItemInput"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"createManyNavigationMenuItems"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"inputs"},"value":{"kind":"Variable","name":{"kind":"Name","value":"inputs"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavigationMenuItemQueryFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordId"}},{"kind":"Field","name":{"kind":"Name","value":"targetObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"folderId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"link"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemQueryFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavigationMenuItemFields"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordIdentifier"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifier"}}]}}]}}]} as unknown as DocumentNode;
export const DeleteManyNavigationMenuItemsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteManyNavigationMenuItems"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ids"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"UUID"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"deleteManyNavigationMenuItems"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ids"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ids"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavigationMenuItemQueryFields"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"type"}},{"kind":"Field","name":{"kind":"Name","value":"userWorkspaceId"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordId"}},{"kind":"Field","name":{"kind":"Name","value":"targetObjectMetadataId"}},{"kind":"Field","name":{"kind":"Name","value":"viewId"}},{"kind":"Field","name":{"kind":"Name","value":"folderId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"link"}},{"kind":"Field","name":{"kind":"Name","value":"icon"}},{"kind":"Field","name":{"kind":"Name","value":"color"}},{"kind":"Field","name":{"kind":"Name","value":"pageLayoutId"}},{"kind":"Field","name":{"kind":"Name","value":"position"}},{"kind":"Field","name":{"kind":"Name","value":"applicationId"}},{"kind":"Field","name":{"kind":"Name","value":"createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"updatedAt"}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"NavigationMenuItemQueryFields"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"NavigationMenuItem"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"NavigationMenuItemFields"}},{"kind":"Field","name":{"kind":"Name","value":"targetRecordIdentifier"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"id"}},{"kind":"Field","name":{"kind":"Name","value":"labelIdentifier"}},{"kind":"Field","name":{"kind":"Name","value":"imageIdentifier"}}]}}]}}]} as unknown as DocumentNode;
diff --git a/packages/twenty-front/src/modules/marketplace/graphql/fragments/marketplaceAppDetailFragment.ts b/packages/twenty-front/src/modules/marketplace/graphql/fragments/marketplaceAppDetailFragment.ts
index fd2e802f21..414ace6095 100644
--- a/packages/twenty-front/src/modules/marketplace/graphql/fragments/marketplaceAppDetailFragment.ts
+++ b/packages/twenty-front/src/modules/marketplace/graphql/fragments/marketplaceAppDetailFragment.ts
@@ -19,7 +19,7 @@ export const MARKETPLACE_APP_DETAIL_FRAGMENT = gql`
termsUrl
emailSupport
issueReportUrl
- screenshots
+ galleryImages
defaultRoleUniversalIdentifier
roles {
universalIdentifier
diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx
index 03f01b5d4c..afcc4891bf 100644
--- a/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx
+++ b/packages/twenty-front/src/pages/settings/applications/SettingsApplicationDetails.tsx
@@ -100,7 +100,7 @@ export const SettingsApplicationDetails = () => {
const description = detail?.description ?? resolvedDescription;
const getScreenshots = () => {
- if (detail?.screenshots?.length) return detail.screenshots;
+ if (detail?.galleryImages?.length) return detail.galleryImages;
if (isStandardApplication) return STANDARD_APPLICATION_ILLUSTRATIONS;
if (isCustomApplication) return CUSTOM_APPLICATION_ILLUSTRATIONS;
return undefined;
diff --git a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
index 6e6966ac1a..6b657b2c8f 100644
--- a/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
+++ b/packages/twenty-front/src/pages/settings/applications/SettingsAvailableApplicationDetails.tsx
@@ -221,7 +221,7 @@ export const SettingsAvailableApplicationDetails = () => {
displayName={displayName}
description={description}
aboutDescription={detail.aboutDescription ?? undefined}
- screenshots={detail.screenshots}
+ screenshots={detail.galleryImages}
author={detail.author ?? 'Unknown'}
category={detail.category ?? undefined}
contentEntries={contentEntries}
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 3fce9a28ba..02687cc108 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
@@ -12,6 +12,7 @@ export const EXPECTED_MANIFEST: Manifest = {
universalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000001',
displayName: 'Root App',
description: 'An app with all entities at root level',
+ galleryImages: [],
defaultRoleUniversalIdentifier: 'e1e2e3e4-e5e6-4000-8000-000000000002',
packageJsonChecksum: '[checksum]',
yarnLockChecksum: '[checksum]',
diff --git a/packages/twenty-sdk/src/cli/__tests__/apps/rich-app/__integration__/app-dev/expected-manifest.ts b/packages/twenty-sdk/src/cli/__tests__/apps/rich-app/__integration__/app-dev/expected-manifest.ts
index 61a7333b15..1ad0594ebf 100644
--- a/packages/twenty-sdk/src/cli/__tests__/apps/rich-app/__integration__/app-dev/expected-manifest.ts
+++ b/packages/twenty-sdk/src/cli/__tests__/apps/rich-app/__integration__/app-dev/expected-manifest.ts
@@ -229,6 +229,7 @@ export const EXPECTED_MANIFEST: Manifest = {
},
description: 'A simple rich app',
displayName: 'Rich App',
+ galleryImages: [],
defaultRoleUniversalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
universalIdentifier: '4ec0391d-18d5-411c-b2f3-266ddc1c3ef7',
yarnLockChecksum: 'd41d8cd98f00b204e9800998ecf8427e',
diff --git a/packages/twenty-sdk/src/cli/utilities/build/cover/__tests__/apply-generated-cover.test.ts b/packages/twenty-sdk/src/cli/utilities/build/cover/__tests__/apply-generated-cover.test.ts
index 199dbdbf5f..d0e6f5ee5d 100644
--- a/packages/twenty-sdk/src/cli/utilities/build/cover/__tests__/apply-generated-cover.test.ts
+++ b/packages/twenty-sdk/src/cli/utilities/build/cover/__tests__/apply-generated-cover.test.ts
@@ -41,14 +41,14 @@ describe('applyGeneratedCover', () => {
await writeFile(join(appPath, relativePath), Buffer.from('logo'));
};
- it('generates a cover when a local logo exists and no screenshots are set', async () => {
+ it('generates a cover when a local logo exists and no gallery images are set', async () => {
await writeLogo('public/logo.png');
- const manifest = buildManifest({ logoUrl: 'public/logo.png' });
+ const manifest = buildManifest({ logo: 'public/logo.png' });
const result = await applyGeneratedCover({ appPath, manifest });
expect(mockedGenerateCoverImage).toHaveBeenCalledTimes(1);
- expect(result.manifest.application.screenshots).toEqual([
+ expect(result.manifest.application.galleryImages).toEqual([
GENERATED_COVER_PATH,
]);
expect(
@@ -68,28 +68,28 @@ describe('applyGeneratedCover', () => {
expect(mockedGenerateCoverImage).not.toHaveBeenCalled();
expect(result.generatedAssets).toEqual([]);
- expect(result.manifest.application.screenshots).toBeUndefined();
+ expect(result.manifest.application.galleryImages).toBeUndefined();
});
- it('does nothing when screenshots are already provided', async () => {
+ it('does nothing when gallery images are already provided', async () => {
await writeLogo('public/logo.png');
const manifest = buildManifest({
- logoUrl: 'public/logo.png',
- screenshots: ['public/shot.png'],
+ logo: 'public/logo.png',
+ galleryImages: ['public/shot.png'],
});
const result = await applyGeneratedCover({ appPath, manifest });
expect(mockedGenerateCoverImage).not.toHaveBeenCalled();
expect(result.generatedAssets).toEqual([]);
- expect(result.manifest.application.screenshots).toEqual([
+ expect(result.manifest.application.galleryImages).toEqual([
'public/shot.png',
]);
});
it('does nothing when the logo is an absolute url', async () => {
const manifest = buildManifest({
- logoUrl: 'https://example.com/logo.png',
+ logo: 'https://example.com/logo.png',
});
const result = await applyGeneratedCover({ appPath, manifest });
@@ -99,7 +99,7 @@ describe('applyGeneratedCover', () => {
});
it('does nothing when the logo file is missing', async () => {
- const manifest = buildManifest({ logoUrl: 'public/missing.png' });
+ const manifest = buildManifest({ logo: 'public/missing.png' });
const result = await applyGeneratedCover({ appPath, manifest });
diff --git a/packages/twenty-sdk/src/cli/utilities/build/cover/apply-generated-cover.ts b/packages/twenty-sdk/src/cli/utilities/build/cover/apply-generated-cover.ts
index 3bc206f8a1..daa5dc68eb 100644
--- a/packages/twenty-sdk/src/cli/utilities/build/cover/apply-generated-cover.ts
+++ b/packages/twenty-sdk/src/cli/utilities/build/cover/apply-generated-cover.ts
@@ -18,23 +18,23 @@ export const applyGeneratedCover = async ({
appPath: string;
manifest: Manifest;
}): Promise<{ manifest: Manifest; generatedAssets: GeneratedAsset[] }> => {
- const { logoUrl, screenshots } = manifest.application;
+ const { logo, galleryImages } = manifest.application;
- if (!isDefined(logoUrl) || isAbsoluteUrl(logoUrl)) {
+ if (!isDefined(logo) || isAbsoluteUrl(logo)) {
return { manifest, generatedAssets: [] };
}
- if ((screenshots ?? []).length > 0) {
+ if ((galleryImages ?? []).length > 0) {
return { manifest, generatedAssets: [] };
}
- const logoPath = join(appPath, logoUrl);
+ const logoAbsolutePath = join(appPath, logo);
- if (!(await pathExists(logoPath))) {
+ if (!(await pathExists(logoAbsolutePath))) {
return { manifest, generatedAssets: [] };
}
- const logoBuffer = await readFile(logoPath);
+ const logoBuffer = await readFile(logoAbsolutePath);
const coverBuffer = await generateCoverImage({ logoBuffer });
const coverAsset: AssetManifest = {
@@ -56,7 +56,7 @@ export const applyGeneratedCover = async ({
...manifest,
application: {
...manifest.application,
- screenshots: [GENERATED_COVER_PATH],
+ galleryImages: [GENERATED_COVER_PATH],
},
publicAssets,
},
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 14b93ebdfc..ebda0130cd 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
@@ -571,21 +571,31 @@ export const buildManifest = async (
const application: ApplicationManifest | undefined =
applicationConfig && resolvedDefaultRoleUniversalIdentifier
- ? {
- ...applicationConfig,
- defaultRoleUniversalIdentifier:
- resolvedDefaultRoleUniversalIdentifier,
- aboutDescription: readmeContent,
- yarnLockChecksum: null,
- packageJsonChecksum: null,
- requiredServerVersionRange: getEngineVersionRange(appPath),
- ...(postInstallLogicFunctions.length >= 1
- ? { postInstallLogicFunction: postInstallLogicFunctions[0] }
- : {}),
- ...(preInstallLogicFunctions.length >= 1
- ? { preInstallLogicFunction: preInstallLogicFunctions[0] }
- : {}),
- }
+ ? (() => {
+ const {
+ logoUrl: _logoUrl,
+ screenshots: _screenshots,
+ ...applicationConfigRest
+ } = applicationConfig;
+
+ return {
+ ...applicationConfigRest,
+ logo: applicationConfig.logo,
+ galleryImages: applicationConfig.galleryImages ?? [],
+ defaultRoleUniversalIdentifier:
+ resolvedDefaultRoleUniversalIdentifier,
+ aboutDescription: readmeContent,
+ yarnLockChecksum: null,
+ packageJsonChecksum: null,
+ requiredServerVersionRange: getEngineVersionRange(appPath),
+ ...(postInstallLogicFunctions.length >= 1
+ ? { postInstallLogicFunction: postInstallLogicFunctions[0] }
+ : {}),
+ ...(preInstallLogicFunctions.length >= 1
+ ? { preInstallLogicFunction: preInstallLogicFunctions[0] }
+ : {}),
+ };
+ })()
: undefined;
const byId = (a: T, b: T) =>
diff --git a/packages/twenty-sdk/src/sdk/define/application/__tests__/define-app.spec.ts b/packages/twenty-sdk/src/sdk/define/application/__tests__/define-app.spec.ts
index 99e4c9a2b3..cc0797c30e 100644
--- a/packages/twenty-sdk/src/sdk/define/application/__tests__/define-app.spec.ts
+++ b/packages/twenty-sdk/src/sdk/define/application/__tests__/define-app.spec.ts
@@ -12,7 +12,11 @@ describe('defineApplication', () => {
const result = defineApplication(config);
expect(result.success).toBe(true);
- expect(result.config).toEqual(config);
+ expect(result.config).toEqual({
+ ...config,
+ logo: undefined,
+ galleryImages: [],
+ });
expect(result.errors).toEqual([]);
});
@@ -34,7 +38,11 @@ describe('defineApplication', () => {
const result = defineApplication(config);
expect(result.success).toBe(true);
- expect(result.config).toEqual(config);
+ expect(result.config).toEqual({
+ ...config,
+ logo: undefined,
+ galleryImages: [],
+ });
expect(result.config?.applicationVariables).toBeDefined();
expect(result.config?.defaultRoleUniversalIdentifier).toBe(
'68bb56f3-8300-4cb5-8cc3-8da9ee66f1b2',
diff --git a/packages/twenty-sdk/src/sdk/define/application/define-application.ts b/packages/twenty-sdk/src/sdk/define/application/define-application.ts
index bdb2941505..d4f928c932 100644
--- a/packages/twenty-sdk/src/sdk/define/application/define-application.ts
+++ b/packages/twenty-sdk/src/sdk/define/application/define-application.ts
@@ -7,6 +7,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
import { isNonEmptyArray } from 'twenty-shared/utils';
import { type ApplicationConfig } from '@/sdk/define/application/application-config';
+import { normalizeApplicationAssets } from '@/sdk/define/application/utils/normalize-application-assets';
import { type DefineEntity } from '@/sdk/define/common/types/define-entity.type';
import { createValidationResult } from '@/sdk/define/common/utils/create-validation-result';
@@ -52,8 +53,16 @@ export const defineApplication: DefineEntity = (config) => {
);
}
+ const assetNormalization = normalizeApplicationAssets(config);
+
+ warnings.push(...assetNormalization.warnings);
+
return createValidationResult({
- config,
+ config: {
+ ...config,
+ logo: assetNormalization.logo,
+ galleryImages: assetNormalization.galleryImages,
+ },
errors,
warnings,
});
diff --git a/packages/twenty-sdk/src/sdk/define/application/utils/__tests__/normalize-application-assets.test.ts b/packages/twenty-sdk/src/sdk/define/application/utils/__tests__/normalize-application-assets.test.ts
new file mode 100644
index 0000000000..189d0e2cde
--- /dev/null
+++ b/packages/twenty-sdk/src/sdk/define/application/utils/__tests__/normalize-application-assets.test.ts
@@ -0,0 +1,98 @@
+import { describe, expect, it } from 'vitest';
+
+import { normalizeApplicationAssets } from '@/sdk/define/application/utils/normalize-application-assets';
+import { type ApplicationConfig } from '@/sdk/define/application/application-config';
+
+const buildConfig = (config: Record): ApplicationConfig =>
+ config as unknown as ApplicationConfig;
+
+describe('normalizeApplicationAssets', () => {
+ it('keeps a bundled logo', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({ logo: 'public/logo.png' }),
+ );
+
+ expect(result.logo).toBe('public/logo.png');
+ expect(result.warnings).toEqual([]);
+ });
+
+ it('warns and ignores an absolute logo', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({ logo: 'https://example.com/logo.png' }),
+ );
+
+ expect(result.logo).toBeUndefined();
+ expect(result.warnings).toHaveLength(1);
+ expect(result.warnings[0]).toContain('external URL');
+ });
+
+ it('migrates a deprecated relative logoUrl with a warning', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({ logoUrl: 'public/logo.png' }),
+ );
+
+ expect(result.logo).toBe('public/logo.png');
+ expect(result.warnings[0]).toContain('`logoUrl` is deprecated');
+ });
+
+ it('warns and ignores an absolute logoUrl', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({ logoUrl: 'https://example.com/logo.png' }),
+ );
+
+ expect(result.logo).toBeUndefined();
+ expect(result.warnings[0]).toContain('external URL');
+ });
+
+ it('prefers logo over a deprecated logoUrl', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({
+ logo: 'public/logo.png',
+ logoUrl: 'public/old.png',
+ }),
+ );
+
+ expect(result.logo).toBe('public/logo.png');
+ expect(result.warnings).toEqual([]);
+ });
+
+ it('keeps galleryImages as-is', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({
+ galleryImages: ['public/a.png', 'public/b.png'],
+ }),
+ );
+
+ expect(result.galleryImages).toEqual(['public/a.png', 'public/b.png']);
+ expect(result.warnings).toEqual([]);
+ });
+
+ it('migrates deprecated screenshots to galleryImages with a warning', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({ screenshots: ['public/a.png', 'public/b.png'] }),
+ );
+
+ expect(result.galleryImages).toEqual(['public/a.png', 'public/b.png']);
+ expect(result.warnings[0]).toContain('`screenshots` is deprecated');
+ });
+
+ it('warns and drops absolute urls from gallery images', () => {
+ const result = normalizeApplicationAssets(
+ buildConfig({
+ galleryImages: ['public/a.png', 'https://example.com/b.png'],
+ }),
+ );
+
+ expect(result.galleryImages).toEqual(['public/a.png']);
+ expect(result.warnings).toHaveLength(1);
+ expect(result.warnings[0]).toContain('external URL');
+ });
+
+ it('returns an empty gallery when nothing is provided', () => {
+ const result = normalizeApplicationAssets(buildConfig({}));
+
+ expect(result.logo).toBeUndefined();
+ expect(result.galleryImages).toEqual([]);
+ expect(result.warnings).toEqual([]);
+ });
+});
diff --git a/packages/twenty-sdk/src/sdk/define/application/utils/normalize-application-assets.ts b/packages/twenty-sdk/src/sdk/define/application/utils/normalize-application-assets.ts
new file mode 100644
index 0000000000..23fd7a8a00
--- /dev/null
+++ b/packages/twenty-sdk/src/sdk/define/application/utils/normalize-application-assets.ts
@@ -0,0 +1,62 @@
+import { type ApplicationConfig } from '@/sdk/define/application/application-config';
+
+const isAbsoluteUrl = (value: string): boolean =>
+ value.startsWith('http://') || value.startsWith('https://');
+
+export const normalizeApplicationAssets = (
+ application: ApplicationConfig,
+): {
+ logo?: string;
+ galleryImages: string[];
+ warnings: string[];
+} => {
+ const warnings: string[] = [];
+
+ let logo = application.logo;
+
+ if (logo && isAbsoluteUrl(logo)) {
+ warnings.push(
+ `Application logo "${logo}" is an external URL. External asset URLs are no longer supported and are ignored. Bundle the image in your public/ folder instead.`,
+ );
+ logo = undefined;
+ }
+
+ if (!logo && application.logoUrl) {
+ if (isAbsoluteUrl(application.logoUrl)) {
+ warnings.push(
+ `Application logoUrl "${application.logoUrl}" is an external URL. External asset URLs are no longer supported and are ignored. Bundle the image in your public/ folder and reference it via logo.`,
+ );
+ } else {
+ warnings.push(
+ '`logoUrl` is deprecated. Use `logo` to reference an image bundled in your public/ folder.',
+ );
+ logo = application.logoUrl;
+ }
+ }
+
+ const usesDeprecatedScreenshots =
+ !application.galleryImages && (application.screenshots?.length ?? 0) > 0;
+
+ if (usesDeprecatedScreenshots) {
+ warnings.push(
+ '`screenshots` is deprecated. Use `galleryImages` referencing images bundled in your public/ folder.',
+ );
+ }
+
+ const rawGalleryImages =
+ application.galleryImages ?? application.screenshots ?? [];
+
+ const galleryImages = rawGalleryImages.filter((galleryImage) => {
+ if (isAbsoluteUrl(galleryImage)) {
+ warnings.push(
+ `Gallery image "${galleryImage}" is an external URL. External asset URLs are no longer supported and are ignored.`,
+ );
+
+ return false;
+ }
+
+ return true;
+ });
+
+ return { logo, galleryImages, warnings };
+};
diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783615890055-add-gallery-images-to-application-registration.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783615890055-add-gallery-images-to-application-registration.ts
new file mode 100644
index 0000000000..c4353f61fb
--- /dev/null
+++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-fast-1783615890055-add-gallery-images-to-application-registration.ts
@@ -0,0 +1,21 @@
+import { type QueryRunner } from 'typeorm';
+
+import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
+import { type FastInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/fast-instance-command.interface';
+
+@RegisteredInstanceCommand('2.20.0', 1783615890055)
+export class AddGalleryImagesToApplicationRegistrationFastInstanceCommand
+ implements FastInstanceCommand
+{
+ public async up(queryRunner: QueryRunner): Promise {
+ await queryRunner.query(
+ 'ALTER TABLE "core"."applicationRegistration" ADD COLUMN IF NOT EXISTS "galleryImages" jsonb',
+ );
+ }
+
+ public async down(queryRunner: QueryRunner): Promise {
+ await queryRunner.query(
+ 'ALTER TABLE "core"."applicationRegistration" DROP COLUMN IF EXISTS "galleryImages"',
+ );
+ }
+}
diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-slow-1783615890056-backfill-gallery-images-on-application-registration.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-slow-1783615890056-backfill-gallery-images-on-application-registration.ts
new file mode 100644
index 0000000000..152d042a60
--- /dev/null
+++ b/packages/twenty-server/src/database/commands/upgrade-version-command/2-20/2-20-instance-command-slow-1783615890056-backfill-gallery-images-on-application-registration.ts
@@ -0,0 +1,33 @@
+import { type DataSource, type QueryRunner } from 'typeorm';
+
+import { RegisteredInstanceCommand } from 'src/engine/core-modules/upgrade/decorators/registered-instance-command.decorator';
+import { type SlowInstanceCommand } from 'src/engine/core-modules/upgrade/interfaces/slow-instance-command.interface';
+
+@RegisteredInstanceCommand('2.20.0', 1783615890056, { type: 'slow' })
+export class BackfillGalleryImagesOnApplicationRegistrationSlowInstanceCommand
+ implements SlowInstanceCommand
+{
+ async runDataMigration(dataSource: DataSource): Promise {
+ await dataSource.query(
+ `UPDATE "core"."applicationRegistration" AS "registration"
+ SET "galleryImages" = "screenshotEntries"."galleryImages"
+ FROM (
+ SELECT
+ "id",
+ jsonb_agg(
+ jsonb_build_object('path', "screenshot", 'fileId', NULL)
+ ORDER BY "ordinality"
+ ) AS "galleryImages"
+ FROM "core"."applicationRegistration",
+ unnest("screenshots") WITH ORDINALITY AS "unnested"("screenshot", "ordinality")
+ GROUP BY "id"
+ ) AS "screenshotEntries"
+ WHERE "registration"."id" = "screenshotEntries"."id"
+ AND "registration"."galleryImages" IS NULL`,
+ );
+ }
+
+ public async up(_queryRunner: QueryRunner): Promise {}
+
+ public async down(_queryRunner: QueryRunner): Promise {}
+}
diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts
index d4ee164e97..b17594410d 100644
--- a/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts
+++ b/packages/twenty-server/src/database/commands/upgrade-version-command/instance-commands.constant.ts
@@ -105,6 +105,8 @@ import { BackfillNameFieldIsSystemSideEffectSlowInstanceCommand } from './2-20/2
import { RenameIsFeaturedToIsVettedOnApplicationRegistrationFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783527064000-rename-is-featured-to-is-vetted-on-application-registration';
import { AddIsSystemSideEffectToSearchFieldMetadataFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783580127637-add-is-system-side-effect-to-search-field-metadata';
import { CreateWorkflowCoreTableFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783603454479-create-workflow-core-table';
+import { AddGalleryImagesToApplicationRegistrationFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783615890055-add-gallery-images-to-application-registration';
+import { BackfillGalleryImagesOnApplicationRegistrationSlowInstanceCommand } from './2-20/2-20-instance-command-slow-1783615890056-backfill-gallery-images-on-application-registration';
import { AddWorkflowVersionSyncableColumnsFastInstanceCommand } from './2-20/2-20-instance-command-fast-1783603454480-add-workflow-version-syncable-columns';
export const INSTANCE_COMMANDS = [
@@ -213,5 +215,7 @@ export const INSTANCE_COMMANDS = [
RenameIsFeaturedToIsVettedOnApplicationRegistrationFastInstanceCommand,
AddIsSystemSideEffectToSearchFieldMetadataFastInstanceCommand,
CreateWorkflowCoreTableFastInstanceCommand,
+ AddGalleryImagesToApplicationRegistrationFastInstanceCommand,
+ BackfillGalleryImagesOnApplicationRegistrationSlowInstanceCommand,
AddWorkflowVersionSyncableColumnsFastInstanceCommand,
];
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 8e64131b41..40459b7780 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
@@ -14,6 +14,7 @@ import {
ApplicationException,
ApplicationExceptionCode,
} from 'src/engine/core-modules/application/application.exception';
+import { isImageFilePath } from 'src/engine/core-modules/application/application-registration/utils/is-image-file-path.util';
import { ApplicationRegistrationEntity } from 'src/engine/core-modules/application/application-registration/application-registration.entity';
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';
@@ -559,17 +560,25 @@ export class ApplicationInstallService {
applicationUniversalIdentifier: string;
workspaceId: string;
}): Promise {
- const logoUrl = manifest.application.logoUrl;
+ const logo = manifest.application.logo ?? manifest.application.logoUrl;
if (
- !isDefined(logoUrl) ||
- logoUrl.startsWith('http://') ||
- logoUrl.startsWith('https://')
+ !isDefined(logo) ||
+ logo.startsWith('http://') ||
+ logo.startsWith('https://')
) {
return null;
}
- const absolutePath = this.resolveWithinDirOrThrow(extractedDir, logoUrl);
+ if (!isImageFilePath(logo)) {
+ this.logger.warn(
+ `Logo "${logo}" is not a supported image type; skipping logo import for ${applicationUniversalIdentifier}`,
+ );
+
+ return null;
+ }
+
+ const absolutePath = this.resolveWithinDirOrThrow(extractedDir, logo);
let content: Buffer;
@@ -577,7 +586,7 @@ export class ApplicationInstallService {
content = await fs.readFile(absolutePath);
} catch {
this.logger.warn(
- `Logo "${logoUrl}" declared in manifest but not found in package for ${applicationUniversalIdentifier}; skipping logo import`,
+ `Logo "${logo}" declared in manifest but not found in package for ${applicationUniversalIdentifier}; skipping logo import`,
);
return null;
@@ -588,7 +597,7 @@ export class ApplicationInstallService {
fileFolder: FileFolder.PublicAsset,
applicationUniversalIdentifier,
workspaceId,
- resourcePath: logoUrl,
+ resourcePath: logo,
settings: { isTemporaryFile: false, toDelete: false },
});
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto.ts
index a2dd0eac43..cb2829b8d8 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/dtos/marketplace-app-detail.dto.ts
@@ -90,9 +90,14 @@ export class MarketplaceAppDetailDTO {
@Field({ nullable: true })
issueReportUrl?: string;
- @Field(() => [String])
+ @Field(() => [String], {
+ deprecationReason: 'Use galleryImages instead',
+ })
screenshots: string[];
+ @Field(() => [String])
+ galleryImages: string[];
+
@IsOptional()
@IsString()
@Field({ nullable: true })
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace-query.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace-query.service.ts
index 0af47344e8..0f68cc816e 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace-query.service.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/marketplace-query.service.ts
@@ -13,6 +13,7 @@ import {
ApplicationRegistrationException,
ApplicationRegistrationExceptionCode,
} from 'src/engine/core-modules/application/application-registration/application-registration.exception';
+import { toGalleryImagePaths } from 'src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util';
import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service';
@Injectable()
@@ -81,6 +82,14 @@ export class MarketplaceQueryService {
private toMarketplaceAppDetailDTO(
registration: ApplicationRegistrationEntity,
): MarketplaceAppDetailDTO {
+ // TODO: simplify in a follow-up PR to read galleryImages only, once the
+ // deprecated screenshots column and manifest fallback are backfilled away.
+ const galleryImagePaths = isNonEmptyArray(registration.galleryImages)
+ ? registration.galleryImages.map((galleryImage) => galleryImage.path)
+ : isNonEmptyArray(registration.screenshots)
+ ? registration.screenshots
+ : toGalleryImagePaths(registration.manifest?.application);
+
return {
id: registration.id,
universalIdentifier: registration.universalIdentifier,
@@ -123,9 +132,8 @@ export class MarketplaceQueryService {
registration.issueReportUrl ??
registration.manifest?.application?.issueReportUrl ??
undefined,
- screenshots: isNonEmptyArray(registration.screenshots)
- ? registration.screenshots
- : (registration.manifest?.application?.screenshots ?? []),
+ screenshots: galleryImagePaths,
+ galleryImages: galleryImagePaths,
defaultRoleUniversalIdentifier:
registration.manifest?.application?.defaultRoleUniversalIdentifier,
roles: registration.manifest?.roles?.map((role) =>
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/__tests__/resolve-manifest-asset-urls.util.spec.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/__tests__/resolve-manifest-asset-urls.util.spec.ts
index e7f09945fd..9f5952e1ae 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/__tests__/resolve-manifest-asset-urls.util.spec.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/__tests__/resolve-manifest-asset-urls.util.spec.ts
@@ -131,6 +131,47 @@ describe('resolveManifestAssetUrls', () => {
expect(result.application.screenshots).toEqual([]);
});
+ it('should resolve a relative logo', () => {
+ const manifest = buildMinimalManifest({ logo: 'logo.png' });
+
+ const result = resolveManifestAssetUrls(manifest, urlBuilder);
+
+ expect(result.application.logo).toBe(
+ 'https://cdn.example.com/pkg/logo.png',
+ );
+ });
+
+ it('should not modify an absolute logo', () => {
+ const manifest = buildMinimalManifest({
+ logo: 'https://example.com/logo.png',
+ });
+
+ const result = resolveManifestAssetUrls(manifest, urlBuilder);
+
+ expect(result.application.logo).toBe('https://example.com/logo.png');
+ });
+
+ it('should resolve galleryImages paths and leave absolute ones untouched', () => {
+ const manifest = buildMinimalManifest({
+ galleryImages: ['a.png', 'https://example.com/b.png'],
+ });
+
+ const result = resolveManifestAssetUrls(manifest, urlBuilder);
+
+ expect(result.application.galleryImages).toEqual([
+ 'https://cdn.example.com/pkg/a.png',
+ 'https://example.com/b.png',
+ ]);
+ });
+
+ it('should handle undefined galleryImages', () => {
+ const manifest = buildMinimalManifest();
+
+ const result = resolveManifestAssetUrls(manifest, urlBuilder);
+
+ expect(result.application.galleryImages).toEqual([]);
+ });
+
it('should preserve all other manifest properties', () => {
const manifest = buildMinimalManifest({
logoUrl: 'logo.png',
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util.ts
index a9cf6a9759..7433841736 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-marketplace/utils/resolve-manifest-asset-urls.util.ts
@@ -17,7 +17,11 @@ export const resolveManifestAssetUrls = (
logoUrl: manifest.application.logoUrl
? resolveUrl(manifest.application.logoUrl)
: undefined,
+ logo: manifest.application.logo
+ ? resolveUrl(manifest.application.logo)
+ : undefined,
screenshots: (manifest.application.screenshots ?? []).map(resolveUrl),
+ galleryImages: (manifest.application.galleryImages ?? []).map(resolveUrl),
},
};
};
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.entity.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.entity.ts
index e029145dec..3ff754e696 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.entity.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.entity.ts
@@ -20,6 +20,7 @@ import {
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { type Manifest } from 'twenty-shared/application';
import { ApplicationRegistrationVariableEntity } from 'src/engine/core-modules/application/application-registration-variable/application-registration-variable.entity';
+import { type ApplicationRegistrationGalleryImage } from 'src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type';
import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum';
import { FileEntity } from 'src/engine/core-modules/file/entities/file.entity';
import { WasIntroducedInUpgrade } from 'src/engine/core-modules/upgrade/decorators/was-introduced-in-upgrade.decorator';
@@ -214,7 +215,12 @@ export class ApplicationRegistrationEntity {
@Field(() => String, { nullable: true })
get logoUrl(): string | null {
- return this.logo ?? this.manifest?.application?.logoUrl ?? null;
+ return (
+ this.logo ??
+ this.manifest?.application?.logo ??
+ this.manifest?.application?.logoUrl ??
+ null
+ );
}
@OneToMany(
@@ -224,6 +230,13 @@ export class ApplicationRegistrationEntity {
)
variables: Relation;
+ @Column({ type: 'jsonb', nullable: true })
+ @WasIntroducedInUpgrade({
+ upgradeCommandName:
+ '2.20.0_AddGalleryImagesToApplicationRegistrationFastInstanceCommand_1783615890055',
+ })
+ galleryImages: ApplicationRegistrationGalleryImage[] | null;
+
@Field()
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.service.ts
index 702787e699..4536eb656a 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.service.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-registration.service.ts
@@ -65,6 +65,7 @@ const APPLICATION_REGISTRATION_WITHOUT_MANIFEST_SELECT: (keyof ApplicationRegist
'emailSupport',
'issueReportUrl',
'screenshots',
+ 'galleryImages',
'createdAt',
'updatedAt',
];
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-tarball.service.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-tarball.service.ts
index 2187bd3857..fb2125558e 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-registration/application-tarball.service.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/application-tarball.service.ts
@@ -3,10 +3,10 @@ import { InjectRepository } from '@nestjs/typeorm';
import { promises as fs } from 'fs';
import { tmpdir } from 'os';
-import { join } from 'path';
+import { isAbsolute, join, relative, resolve } from 'path';
import semver from 'semver';
-import { FileFolder } from 'twenty-shared/types';
+import { FileFolder, ServerFileFolder } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { Repository } from 'typeorm';
import { type QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
@@ -24,9 +24,14 @@ import {
ApplicationRegistrationExceptionCode,
} from 'src/engine/core-modules/application/application-registration/application-registration.exception';
import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum';
+import { type ApplicationRegistrationGalleryImage } from 'src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type';
import { fromManifestApplicationToDisplayFields } from 'src/engine/core-modules/application/application-registration/utils/from-manifest-application-to-display-fields.util';
+import { isImageFilePath } from 'src/engine/core-modules/application/application-registration/utils/is-image-file-path.util';
+import { toGalleryImagePaths } from 'src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util';
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
import { FileStorageService } from 'src/engine/core-modules/file-storage/services/file-storage.service';
+import { ServerFileStorageService } from 'src/engine/core-modules/file-storage/services/server-file-storage.service';
+import { prepareFileForStorageOrThrow } from 'src/engine/core-modules/file-storage/utils/prepare-file-for-storage-or-throw.util';
import type { ApplicationManifest } from 'twenty-shared/application';
@Injectable()
@@ -37,6 +42,7 @@ export class ApplicationTarballService {
@InjectRepository(ApplicationRegistrationEntity)
private readonly appRegistrationRepository: Repository,
private readonly fileStorageService: FileStorageService,
+ private readonly serverFileStorageService: ServerFileStorageService,
private readonly applicationService: ApplicationService,
private readonly applicationRegistrationVariableService: ApplicationRegistrationVariableService,
private readonly applicationVersionValidationService: ApplicationVersionValidationService,
@@ -202,6 +208,12 @@ export class ApplicationTarballService {
ownerWorkspaceId: params.ownerWorkspaceId,
} as QueryDeepPartialEntity);
+ await this.storeGalleryImageFiles({
+ applicationRegistrationId: appRegistration.id,
+ manifestApplication: manifest.application,
+ contentDir,
+ });
+
if (manifest.application?.serverVariables) {
await this.applicationRegistrationVariableService.syncVariableSchemas(
appRegistration.id,
@@ -220,4 +232,92 @@ export class ApplicationTarballService {
await fs.rm(tempDir, { recursive: true, force: true });
}
}
+
+ private async storeGalleryImageFiles({
+ applicationRegistrationId,
+ manifestApplication,
+ contentDir,
+ }: {
+ applicationRegistrationId: string;
+ manifestApplication: ApplicationManifest | undefined;
+ contentDir: string;
+ }): Promise {
+ const galleryImages: ApplicationRegistrationGalleryImage[] = [];
+
+ for (const path of toGalleryImagePaths(manifestApplication)) {
+ const fileId = await this.storeGalleryImageFile({
+ applicationRegistrationId,
+ contentDir,
+ path,
+ });
+
+ if (isDefined(fileId)) {
+ galleryImages.push({ path, fileId });
+ }
+ }
+
+ await this.appRegistrationRepository.update(applicationRegistrationId, {
+ galleryImages,
+ } as QueryDeepPartialEntity);
+ }
+
+ private async storeGalleryImageFile({
+ applicationRegistrationId,
+ contentDir,
+ path,
+ }: {
+ applicationRegistrationId: string;
+ contentDir: string;
+ path: string;
+ }): Promise {
+ if (
+ path.startsWith('http://') ||
+ path.startsWith('https://') ||
+ !isImageFilePath(path)
+ ) {
+ return null;
+ }
+
+ const absolutePath = resolve(contentDir, path);
+ const relativeToContentDir = relative(contentDir, absolutePath);
+
+ if (
+ relativeToContentDir === '..' ||
+ relativeToContentDir.startsWith('../') ||
+ isAbsolute(relativeToContentDir)
+ ) {
+ this.logger.warn(
+ `Gallery image "${path}" escapes the package directory; skipping`,
+ );
+
+ return null;
+ }
+
+ try {
+ const contents = await fs.readFile(absolutePath);
+
+ const { sourceFile, mimeType } = await prepareFileForStorageOrThrow({
+ sourceFile: contents,
+ resourcePath: path,
+ });
+
+ const savedFile = await this.serverFileStorageService.writeServerFile({
+ fileFolder: ServerFileFolder.ApplicationRegistration,
+ applicationRegistrationId,
+ resourcePath: path,
+ contents: Buffer.isBuffer(sourceFile)
+ ? sourceFile
+ : Buffer.from(sourceFile),
+ mimeType,
+ });
+
+ return savedFile.id;
+ } catch (error) {
+ this.logger.warn(
+ `Failed to store gallery image "${path}" for registration ${applicationRegistrationId}: ${error.message}`,
+ );
+
+ return null;
+ }
+ }
}
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type.ts
new file mode 100644
index 0000000000..b0e697ed6c
--- /dev/null
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type.ts
@@ -0,0 +1,4 @@
+export type ApplicationRegistrationGalleryImage = {
+ path: string;
+ fileId: string | null;
+};
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/__tests__/is-image-file-path.util.spec.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/__tests__/is-image-file-path.util.spec.ts
new file mode 100644
index 0000000000..90d75f2cc7
--- /dev/null
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/__tests__/is-image-file-path.util.spec.ts
@@ -0,0 +1,26 @@
+import { isImageFilePath } from 'src/engine/core-modules/application/application-registration/utils/is-image-file-path.util';
+
+describe('isImageFilePath', () => {
+ it.each([
+ 'public/logo.png',
+ 'public/shot.JPG',
+ 'a/b/c.jpeg',
+ 'image.webp',
+ 'anim.gif',
+ 'icon.svg',
+ 'photo.avif',
+ ])('returns true for image path %s', (filePath) => {
+ expect(isImageFilePath(filePath)).toBe(true);
+ });
+
+ it.each([
+ 'public/data.json',
+ 'public/styles.css',
+ 'script.mjs',
+ 'README',
+ 'archive.tar.gz',
+ 'noextension',
+ ])('returns false for non-image path %s', (filePath) => {
+ expect(isImageFilePath(filePath)).toBe(false);
+ });
+});
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/from-manifest-application-to-display-fields.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/from-manifest-application-to-display-fields.util.ts
index 31ff997b3d..5702660f9a 100644
--- a/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/from-manifest-application-to-display-fields.util.ts
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/from-manifest-application-to-display-fields.util.ts
@@ -1,9 +1,12 @@
import { type ApplicationManifest } from 'twenty-shared/application';
+import { type ApplicationRegistrationGalleryImage } from 'src/engine/core-modules/application/application-registration/types/application-registration-gallery-image.type';
+import { toGalleryImagePaths } from 'src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util';
+
export const fromManifestApplicationToDisplayFields = (
application: ApplicationManifest | undefined,
) => ({
- logo: application?.logoUrl ?? null,
+ logo: application?.logo ?? application?.logoUrl ?? null,
description: application?.description ?? null,
author: application?.author ?? null,
category: application?.category ?? null,
@@ -12,5 +15,7 @@ export const fromManifestApplicationToDisplayFields = (
termsUrl: application?.termsUrl ?? null,
emailSupport: application?.emailSupport ?? null,
issueReportUrl: application?.issueReportUrl ?? null,
- screenshots: application?.screenshots ?? [],
+ galleryImages: toGalleryImagePaths(application).map(
+ (path): ApplicationRegistrationGalleryImage => ({ path, fileId: null }),
+ ),
});
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/is-image-file-path.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/is-image-file-path.util.ts
new file mode 100644
index 0000000000..06d023a51e
--- /dev/null
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/is-image-file-path.util.ts
@@ -0,0 +1,21 @@
+const ALLOWED_IMAGE_EXTENSIONS = new Set([
+ '.png',
+ '.jpg',
+ '.jpeg',
+ '.webp',
+ '.gif',
+ '.svg',
+ '.avif',
+]);
+
+export const isImageFilePath = (filePath: string): boolean => {
+ const lastDotIndex = filePath.lastIndexOf('.');
+
+ if (lastDotIndex === -1) {
+ return false;
+ }
+
+ return ALLOWED_IMAGE_EXTENSIONS.has(
+ filePath.slice(lastDotIndex).toLowerCase(),
+ );
+};
diff --git a/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util.ts b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util.ts
new file mode 100644
index 0000000000..646a7ac343
--- /dev/null
+++ b/packages/twenty-server/src/engine/core-modules/application/application-registration/utils/to-gallery-image-paths.util.ts
@@ -0,0 +1,13 @@
+import { type ApplicationManifest } from 'twenty-shared/application';
+
+export const toGalleryImagePaths = (
+ application: ApplicationManifest | undefined,
+): string[] => {
+ const galleryImages = application?.galleryImages;
+
+ if (galleryImages && galleryImages.length > 0) {
+ return galleryImages;
+ }
+
+ return application?.screenshots ?? [];
+};
diff --git a/packages/twenty-shared/src/application/applicationType.ts b/packages/twenty-shared/src/application/applicationType.ts
index 40a9c83e80..e81a04c843 100644
--- a/packages/twenty-shared/src/application/applicationType.ts
+++ b/packages/twenty-shared/src/application/applicationType.ts
@@ -13,8 +13,16 @@ export type ApplicationManifest = SyncableEntityOptions & {
serverVariables?: ServerVariables;
author?: string;
category?: ApplicationCategory;
+ /**
+ * @deprecated Use `logo` instead.
+ */
logoUrl?: string;
+ logo?: string;
+ /**
+ * @deprecated Use `galleryImages` instead.
+ */
screenshots?: string[];
+ galleryImages?: string[];
aboutDescription?: string;
websiteUrl?: string;
termsUrl?: string;