Cleanup
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
import gql from 'graphql-tag';
|
||||
|
||||
export const INSTALL_APPLICATION = gql`
|
||||
mutation InstallApplication($appRegistrationId: String!, $version: String) {
|
||||
installApplication(appRegistrationId: $appRegistrationId, version: $version)
|
||||
}
|
||||
`;
|
||||
@@ -1,11 +0,0 @@
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
export const UPLOAD_APP_TARBALL = gql`
|
||||
mutation UploadAppTarball($file: Upload!, $universalIdentifier: String) {
|
||||
uploadAppTarball(file: $file, universalIdentifier: $universalIdentifier) {
|
||||
id
|
||||
universalIdentifier
|
||||
name
|
||||
}
|
||||
}
|
||||
`;
|
||||
@@ -1,61 +0,0 @@
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useMutation } from '@apollo/client';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { useState } from 'react';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { UPLOAD_APP_TARBALL } from '~/modules/marketplace/graphql/mutations/uploadAppTarball';
|
||||
|
||||
type UploadResult =
|
||||
| {
|
||||
success: true;
|
||||
registrationId: string;
|
||||
universalIdentifier: string;
|
||||
}
|
||||
| {
|
||||
success: false;
|
||||
};
|
||||
|
||||
export const useUploadAppTarball = () => {
|
||||
const [uploadAppTarball] = useMutation(UPLOAD_APP_TARBALL);
|
||||
const { enqueueErrorSnackBar } = useSnackBar();
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
const upload = async (file: File): Promise<UploadResult> => {
|
||||
setIsUploading(true);
|
||||
|
||||
try {
|
||||
const result = await uploadAppTarball({
|
||||
variables: { file },
|
||||
});
|
||||
|
||||
const registration = result.data?.uploadAppTarball;
|
||||
|
||||
if (
|
||||
!isDefined(registration?.id) ||
|
||||
!isDefined(registration?.universalIdentifier)
|
||||
) {
|
||||
enqueueErrorSnackBar({ message: t`Upload failed.` });
|
||||
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
registrationId: registration.id,
|
||||
universalIdentifier: registration.universalIdentifier,
|
||||
};
|
||||
} catch (error) {
|
||||
const graphqlMessage = error instanceof Error ? error.message : undefined;
|
||||
|
||||
enqueueErrorSnackBar({
|
||||
message: graphqlMessage ?? t`Failed to upload tarball.`,
|
||||
});
|
||||
|
||||
return { success: false };
|
||||
} finally {
|
||||
setIsUploading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return { upload, isUploading };
|
||||
};
|
||||
+6
-1
@@ -9,6 +9,7 @@ import { ApplicationManifestModule } from 'src/engine/core-modules/application/a
|
||||
import { ApplicationPackageModule } from 'src/engine/core-modules/application/application-package/application-package.module';
|
||||
import { ApplicationInstallResolver } from 'src/engine/core-modules/application/application-install/application-install.resolver';
|
||||
import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service';
|
||||
import { ApplicationQueryResolver } from 'src/engine/core-modules/application/application-install/application-query.resolver';
|
||||
import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
|
||||
@@ -23,7 +24,11 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi
|
||||
PermissionsModule,
|
||||
FileStorageModule,
|
||||
],
|
||||
providers: [ApplicationInstallResolver, ApplicationInstallService],
|
||||
providers: [
|
||||
ApplicationInstallResolver,
|
||||
ApplicationQueryResolver,
|
||||
ApplicationInstallService,
|
||||
],
|
||||
exports: [ApplicationInstallService],
|
||||
})
|
||||
export class ApplicationInstallModule {}
|
||||
|
||||
+1
-31
@@ -1,15 +1,12 @@
|
||||
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
|
||||
import { Args, Mutation, Query } from '@nestjs/graphql';
|
||||
import { Args, Mutation } from '@nestjs/graphql';
|
||||
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
import { FeatureFlagKey } from 'twenty-shared/types';
|
||||
|
||||
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { ApplicationInstallService } from 'src/engine/core-modules/application/application-install/application-install.service';
|
||||
import { ApplicationDTO } from 'src/engine/core-modules/application/dtos/application.dto';
|
||||
import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter';
|
||||
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
|
||||
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@@ -27,36 +24,9 @@ import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard)
|
||||
export class ApplicationInstallResolver {
|
||||
constructor(
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly applicationInstallService: ApplicationInstallService,
|
||||
) {}
|
||||
|
||||
@Query(() => [ApplicationDTO])
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
|
||||
async findManyApplications(
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
) {
|
||||
return this.applicationService.findManyApplications(workspaceId);
|
||||
}
|
||||
|
||||
@Query(() => ApplicationDTO)
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
|
||||
async findOneApplication(
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Args('id', { type: () => UUIDScalarType, nullable: true }) id?: string,
|
||||
@Args('universalIdentifier', {
|
||||
type: () => UUIDScalarType,
|
||||
nullable: true,
|
||||
})
|
||||
universalIdentifier?: string,
|
||||
) {
|
||||
return await this.applicationService.findOneApplicationOrThrow({
|
||||
id,
|
||||
universalIdentifier,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
|
||||
@Mutation(() => Boolean)
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
|
||||
@RequireFeatureFlag(FeatureFlagKey.IS_APPLICATION_ENABLED)
|
||||
|
||||
+39
-40
@@ -110,30 +110,15 @@ export class ApplicationInstallService {
|
||||
'manifest.json',
|
||||
);
|
||||
|
||||
const universalIdentifier = appRegistration.universalIdentifier;
|
||||
|
||||
await this.ensureApplicationExists({
|
||||
universalIdentifier,
|
||||
name: manifest.application.displayName,
|
||||
workspaceId: params.workspaceId,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
sourceType: appRegistration.sourceType,
|
||||
});
|
||||
|
||||
await this.writeFilesToStorage(
|
||||
params.extractedDir,
|
||||
universalIdentifier,
|
||||
params.workspaceId,
|
||||
);
|
||||
|
||||
await this.applicationSyncService.synchronizeFromManifest({
|
||||
workspaceId: params.workspaceId,
|
||||
await this.syncFromExtractedDirectory({
|
||||
appRegistration,
|
||||
extractedDir: params.extractedDir,
|
||||
manifest,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
workspaceId: params.workspaceId,
|
||||
});
|
||||
|
||||
this.logger.log(
|
||||
`Successfully installed app ${universalIdentifier} from local directory`,
|
||||
`Successfully installed app ${appRegistration.universalIdentifier} from local directory`,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -154,30 +139,15 @@ export class ApplicationInstallService {
|
||||
return true;
|
||||
}
|
||||
|
||||
const universalIdentifier = appRegistration.universalIdentifier;
|
||||
|
||||
await this.ensureApplicationExists({
|
||||
universalIdentifier,
|
||||
name: resolvedPackage.manifest.application.displayName,
|
||||
workspaceId: params.workspaceId,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
sourceType: appRegistration.sourceType,
|
||||
});
|
||||
|
||||
await this.writeFilesToStorage(
|
||||
resolvedPackage.extractedDir,
|
||||
universalIdentifier,
|
||||
params.workspaceId,
|
||||
);
|
||||
|
||||
await this.applicationSyncService.synchronizeFromManifest({
|
||||
workspaceId: params.workspaceId,
|
||||
await this.syncFromExtractedDirectory({
|
||||
appRegistration,
|
||||
extractedDir: resolvedPackage.extractedDir,
|
||||
manifest: resolvedPackage.manifest,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
workspaceId: params.workspaceId,
|
||||
});
|
||||
|
||||
this.logger.log(
|
||||
`Successfully installed app ${universalIdentifier} v${resolvedPackage.packageJson.version ?? 'unknown'}`,
|
||||
`Successfully installed app ${appRegistration.universalIdentifier} v${resolvedPackage.packageJson.version ?? 'unknown'}`,
|
||||
);
|
||||
|
||||
return true;
|
||||
@@ -196,6 +166,35 @@ export class ApplicationInstallService {
|
||||
}
|
||||
}
|
||||
|
||||
private async syncFromExtractedDirectory(params: {
|
||||
appRegistration: ApplicationRegistrationEntity;
|
||||
extractedDir: string;
|
||||
manifest: Manifest;
|
||||
workspaceId: string;
|
||||
}): Promise<void> {
|
||||
const { appRegistration, extractedDir, manifest, workspaceId } = params;
|
||||
|
||||
await this.ensureApplicationExists({
|
||||
universalIdentifier: appRegistration.universalIdentifier,
|
||||
name: manifest.application.displayName,
|
||||
workspaceId,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
sourceType: appRegistration.sourceType,
|
||||
});
|
||||
|
||||
await this.writeFilesToStorage(
|
||||
extractedDir,
|
||||
appRegistration.universalIdentifier,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.applicationSyncService.synchronizeFromManifest({
|
||||
workspaceId,
|
||||
manifest,
|
||||
applicationRegistrationId: appRegistration.id,
|
||||
});
|
||||
}
|
||||
|
||||
private async writeFilesToStorage(
|
||||
extractedDir: string,
|
||||
applicationUniversalIdentifier: string,
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { UseFilters, UseGuards, UsePipes } from '@nestjs/common';
|
||||
import { Args, Query } from '@nestjs/graphql';
|
||||
|
||||
import { PermissionFlagType } from 'twenty-shared/constants';
|
||||
|
||||
import { MetadataResolver } from 'src/engine/api/graphql/graphql-config/decorators/metadata-resolver.decorator';
|
||||
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
|
||||
import { ApplicationExceptionFilter } from 'src/engine/core-modules/application/application-exception-filter';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { ApplicationDTO } from 'src/engine/core-modules/application/dtos/application.dto';
|
||||
import { AuthGraphqlApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-graphql-api-exception.filter';
|
||||
import { ResolverValidationPipe } from 'src/engine/core-modules/graphql/pipes/resolver-validation.pipe';
|
||||
import { type WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { FeatureFlagGuard } from 'src/engine/guards/feature-flag.guard';
|
||||
import { SettingsPermissionGuard } from 'src/engine/guards/settings-permission.guard';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
|
||||
@UsePipes(ResolverValidationPipe)
|
||||
@MetadataResolver()
|
||||
@UseFilters(ApplicationExceptionFilter, AuthGraphqlApiExceptionFilter)
|
||||
@UseGuards(WorkspaceAuthGuard, FeatureFlagGuard)
|
||||
export class ApplicationQueryResolver {
|
||||
constructor(private readonly applicationService: ApplicationService) {}
|
||||
|
||||
@Query(() => [ApplicationDTO])
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
|
||||
async findManyApplications(
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
) {
|
||||
return this.applicationService.findManyApplications(workspaceId);
|
||||
}
|
||||
|
||||
@Query(() => ApplicationDTO)
|
||||
@UseGuards(SettingsPermissionGuard(PermissionFlagType.APPLICATIONS))
|
||||
async findOneApplication(
|
||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||
@Args('id', { type: () => UUIDScalarType, nullable: true }) id?: string,
|
||||
@Args('universalIdentifier', {
|
||||
type: () => UUIDScalarType,
|
||||
nullable: true,
|
||||
})
|
||||
universalIdentifier?: string,
|
||||
) {
|
||||
return await this.applicationService.findOneApplicationOrThrow({
|
||||
id,
|
||||
universalIdentifier,
|
||||
workspaceId,
|
||||
});
|
||||
}
|
||||
}
|
||||
+5
@@ -246,6 +246,11 @@ export class MarketplaceAppDTO {
|
||||
@Field()
|
||||
aboutDescription: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@Field({ nullable: true })
|
||||
readme?: string;
|
||||
|
||||
@IsArray()
|
||||
@Field(() => [String])
|
||||
providers: string[];
|
||||
|
||||
+51
-3
@@ -1,9 +1,13 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { ApplicationNpmRegistrationService } from 'src/engine/core-modules/application/application-registration/application-npm-registration.service';
|
||||
import { ApplicationRegistrationService } from 'src/engine/core-modules/application/application-registration/application-registration.service';
|
||||
import { ApplicationRegistrationSourceType } from 'src/engine/core-modules/application/application-registration/enums/application-registration-source-type.enum';
|
||||
import { MARKETPLACE_CATALOG_INDEX } from 'src/engine/core-modules/application/application-marketplace/constants/marketplace-catalog-index.constant';
|
||||
import { type MarketplaceDisplayData } from 'src/engine/core-modules/application/application-marketplace/types/marketplace-display-data.type';
|
||||
import { type NpmPackument } from 'src/engine/core-modules/application/application-marketplace/types/npm-packument.type';
|
||||
import { MarketplaceService } from 'src/engine/core-modules/application/application-marketplace/marketplace.service';
|
||||
|
||||
@Injectable()
|
||||
@@ -63,6 +67,8 @@ export class MarketplaceCatalogSyncService {
|
||||
}
|
||||
|
||||
try {
|
||||
const packageName = app.sourcePackage ?? app.name;
|
||||
|
||||
let isProvenanceVerified = false;
|
||||
let provenanceRepositoryUrl: string | null = null;
|
||||
let provenanceVerifiedAt: Date | null = null;
|
||||
@@ -70,7 +76,7 @@ export class MarketplaceCatalogSyncService {
|
||||
if (app.version) {
|
||||
const provenance =
|
||||
await this.applicationNpmRegistrationService.fetchProvenanceMetadata(
|
||||
app.sourcePackage ?? app.name,
|
||||
packageName,
|
||||
app.version,
|
||||
);
|
||||
|
||||
@@ -81,19 +87,26 @@ export class MarketplaceCatalogSyncService {
|
||||
}
|
||||
}
|
||||
|
||||
const packument =
|
||||
await this.marketplaceService.fetchPackument(packageName);
|
||||
|
||||
const displayData = isDefined(packument)
|
||||
? this.buildDisplayDataFromPackument(packument)
|
||||
: null;
|
||||
|
||||
await this.applicationRegistrationService.upsertFromCatalog({
|
||||
universalIdentifier: app.id,
|
||||
name: app.name,
|
||||
description: app.description,
|
||||
author: app.author,
|
||||
sourceType: ApplicationRegistrationSourceType.NPM,
|
||||
sourcePackage: app.sourcePackage ?? app.name,
|
||||
sourcePackage: packageName,
|
||||
logoUrl: null,
|
||||
websiteUrl: app.websiteUrl ?? null,
|
||||
termsUrl: null,
|
||||
latestAvailableVersion: app.version ?? null,
|
||||
isFeatured: false,
|
||||
marketplaceDisplayData: null,
|
||||
marketplaceDisplayData: displayData,
|
||||
ownerWorkspaceId: null,
|
||||
isProvenanceVerified,
|
||||
provenanceRepositoryUrl,
|
||||
@@ -106,4 +119,39 @@ export class MarketplaceCatalogSyncService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private buildDisplayDataFromPackument(
|
||||
packument: NpmPackument,
|
||||
): MarketplaceDisplayData {
|
||||
const repositoryUrl = this.extractRepositoryUrl(packument.repository);
|
||||
|
||||
return {
|
||||
readme:
|
||||
isDefined(packument.readme) &&
|
||||
packument.readme !== 'ERROR: No README data found!'
|
||||
? packument.readme
|
||||
: undefined,
|
||||
aboutDescription: packument.description,
|
||||
providers: isDefined(repositoryUrl) ? [repositoryUrl] : [],
|
||||
};
|
||||
}
|
||||
|
||||
private extractRepositoryUrl(
|
||||
repository?: { type?: string; url?: string } | string,
|
||||
): string | null {
|
||||
if (!isDefined(repository)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const url =
|
||||
typeof repository === 'string' ? repository : repository.url ?? null;
|
||||
|
||||
if (!isDefined(url)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return url
|
||||
.replace(/^git\+/, '')
|
||||
.replace(/\.git$/, '');
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -105,6 +105,7 @@ export class MarketplaceQueryService {
|
||||
screenshots: displayData?.screenshots ?? [],
|
||||
aboutDescription:
|
||||
displayData?.aboutDescription ?? registration.description ?? '',
|
||||
readme: displayData?.readme,
|
||||
providers: displayData?.providers ?? [],
|
||||
websiteUrl: registration.websiteUrl ?? undefined,
|
||||
termsUrl: registration.termsUrl ?? undefined,
|
||||
|
||||
+26
@@ -5,6 +5,7 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { MarketplaceAppDTO } from 'src/engine/core-modules/application/application-marketplace/dtos/marketplace-app.dto';
|
||||
import { type NpmPackument } from 'src/engine/core-modules/application/application-marketplace/types/npm-packument.type';
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
|
||||
const npmSearchResultSchema = z.object({
|
||||
@@ -28,6 +29,31 @@ export class MarketplaceService {
|
||||
|
||||
constructor(private readonly twentyConfigService: TwentyConfigService) {}
|
||||
|
||||
async fetchPackument(packageName: string): Promise<NpmPackument | null> {
|
||||
const registryUrl = this.twentyConfigService.get('APP_REGISTRY_URL');
|
||||
|
||||
try {
|
||||
const { data } = await axios.get<NpmPackument>(
|
||||
`${registryUrl}/${encodeURIComponent(packageName)}`,
|
||||
{
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'User-Agent': 'Twenty-Marketplace',
|
||||
},
|
||||
timeout: 10_000,
|
||||
},
|
||||
);
|
||||
|
||||
return data;
|
||||
} catch (error) {
|
||||
this.logger.warn(
|
||||
`Failed to fetch packument for ${packageName}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async fetchAppsFromNpmRegistry(): Promise<MarketplaceAppDTO[]> {
|
||||
const registryUrl = this.twentyConfigService.get('APP_REGISTRY_URL');
|
||||
|
||||
|
||||
+1
@@ -8,6 +8,7 @@ export type MarketplaceDisplayData = {
|
||||
logo?: string;
|
||||
screenshots?: string[];
|
||||
aboutDescription?: string;
|
||||
readme?: string;
|
||||
providers?: string[];
|
||||
objects?: MarketplaceDisplayObject[];
|
||||
fields?: MarketplaceDisplayField[];
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// Subset of the npm registry packument response (GET /{packageName}).
|
||||
// Only the fields we actually use are typed; the full response is much larger.
|
||||
export type NpmPackument = {
|
||||
name: string;
|
||||
description?: string;
|
||||
readme?: string;
|
||||
license?: string;
|
||||
repository?: { type?: string; url?: string } | string;
|
||||
homepage?: string;
|
||||
};
|
||||
-7
@@ -65,13 +65,6 @@ export class ApplicationPackageFetcherService implements OnModuleInit {
|
||||
}
|
||||
}
|
||||
|
||||
async resolveNpmPackage(
|
||||
packageName: string,
|
||||
targetVersion?: string,
|
||||
): Promise<ResolvedPackage> {
|
||||
return this.resolveFromNpm(packageName, targetVersion);
|
||||
}
|
||||
|
||||
async resolvePackage(
|
||||
appRegistration: ApplicationRegistrationEntity,
|
||||
options?: { targetVersion?: string },
|
||||
|
||||
-23
@@ -71,21 +71,6 @@ export class ApplicationRegistrationService {
|
||||
return registration;
|
||||
}
|
||||
|
||||
async findOneByIdGlobal(id: string): Promise<ApplicationRegistrationEntity> {
|
||||
const registration = await this.applicationRegistrationRepository.findOne({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
if (!registration) {
|
||||
throw new ApplicationRegistrationException(
|
||||
`Application registration with id ${id} not found`,
|
||||
ApplicationRegistrationExceptionCode.APPLICATION_REGISTRATION_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return registration;
|
||||
}
|
||||
|
||||
// Global lookup — used by OAuth flow (no workspace scoping)
|
||||
async findOneByClientId(
|
||||
clientId: string,
|
||||
@@ -339,14 +324,6 @@ export class ApplicationRegistrationService {
|
||||
await this.applicationRegistrationRepository.save(registration);
|
||||
}
|
||||
|
||||
async findManyBySourceType(
|
||||
sourceType: ApplicationRegistrationSourceType,
|
||||
): Promise<ApplicationRegistrationEntity[]> {
|
||||
return this.applicationRegistrationRepository.find({
|
||||
where: { sourceType },
|
||||
});
|
||||
}
|
||||
|
||||
async findManyNpm(): Promise<ApplicationRegistrationEntity[]> {
|
||||
return this.applicationRegistrationRepository.find({
|
||||
where: { sourceType: ApplicationRegistrationSourceType.NPM },
|
||||
|
||||
@@ -4,8 +4,6 @@ import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceFlatApplicationMapCacheService } from 'src/engine/core-modules/application/workspace-flat-application-map-cache.service';
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { TwentyConfigModule } from 'src/engine/core-modules/twenty-config/twenty-config.module';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
@@ -15,8 +13,6 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
|
||||
TypeOrmModule.forFeature([ApplicationEntity, WorkspaceEntity]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
WorkspaceCacheModule,
|
||||
TwentyConfigModule,
|
||||
FeatureFlagModule,
|
||||
],
|
||||
exports: [ApplicationService, WorkspaceFlatApplicationMapCacheService],
|
||||
providers: [ApplicationService, WorkspaceFlatApplicationMapCacheService],
|
||||
|
||||
@@ -30,24 +30,6 @@ export class ApplicationService {
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
) {}
|
||||
|
||||
async findApplicationRoleId(
|
||||
applicationId: string,
|
||||
workspaceId: string,
|
||||
): Promise<string> {
|
||||
const application = await this.applicationRepository.findOne({
|
||||
where: { id: applicationId, workspaceId },
|
||||
});
|
||||
|
||||
if (!isDefined(application) || !isDefined(application.defaultRoleId)) {
|
||||
throw new ApplicationException(
|
||||
`Could not find application ${applicationId}`,
|
||||
ApplicationExceptionCode.APPLICATION_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return application.defaultRoleId;
|
||||
}
|
||||
|
||||
async findWorkspaceTwentyStandardAndCustomApplicationOrThrow({
|
||||
workspace: workspaceInput,
|
||||
workspaceId,
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
import { type AllMetadataName } from 'twenty-shared/metadata';
|
||||
|
||||
export const APPLICATION_MANIFEST_METADATA_NAMES = [
|
||||
'objectMetadata',
|
||||
'fieldMetadata',
|
||||
'logicFunction',
|
||||
'frontComponent',
|
||||
'role',
|
||||
'skill',
|
||||
'view',
|
||||
'viewField',
|
||||
'viewFieldGroup',
|
||||
'viewFilter',
|
||||
'viewFilterGroup',
|
||||
'viewGroup',
|
||||
'navigationMenuItem',
|
||||
'pageLayout',
|
||||
'pageLayoutTab',
|
||||
'pageLayoutWidget',
|
||||
'commandMenuItem',
|
||||
] as const satisfies AllMetadataName[];
|
||||
|
||||
export type ApplicationManifestMetadataName =
|
||||
(typeof APPLICATION_MANIFEST_METADATA_NAMES)[number];
|
||||
Reference in New Issue
Block a user