Fix CI: lint, formatting, test, CodeQL, and generated types ordering
- Sort CSS properties alphabetically in StyledPublishMethodLabel - Fix prettier formatting in app-register.ts and server test/service files - Update test assertion for twenty-app- prefix normalization - Remove unused ApplicationExceptionCode import in test - Use replaceAll instead of replace for URL encoding (CodeQL) - Correct alphabetical ordering in generated GraphQL types Made-with: Cursor
This commit is contained in:
@@ -99,7 +99,7 @@ describe('copyBaseApplicationProject', () => {
|
||||
expect(await fs.pathExists(packageJsonPath)).toBe(true);
|
||||
|
||||
const packageJson = await fs.readJson(packageJsonPath);
|
||||
expect(packageJson.name).toBe('my-test-app');
|
||||
expect(packageJson.name).toBe('twenty-app-my-test-app');
|
||||
expect(packageJson.version).toBe('0.1.0');
|
||||
expect(packageJson.devDependencies['twenty-sdk']).toBe(
|
||||
createTwentyAppPackageJson.version,
|
||||
|
||||
@@ -2458,6 +2458,7 @@ export type Mutation = {
|
||||
initiateOTPProvisioningForAuthenticatedUser: InitiateTwoFactorAuthenticationProvisioning;
|
||||
installApplication: Scalars['Boolean'];
|
||||
installMarketplaceApp: Scalars['Boolean'];
|
||||
registerNpmPackage: ApplicationRegistration;
|
||||
removeQueryFromEventStream: Scalars['Boolean'];
|
||||
removeRoleFromAgent: Scalars['Boolean'];
|
||||
renewApplicationToken: ApplicationTokenPair;
|
||||
@@ -2537,7 +2538,6 @@ export type Mutation = {
|
||||
verifyEmailAndGetLoginToken: VerifyEmailAndGetLoginToken;
|
||||
verifyEmailAndGetWorkspaceAgnosticToken: AvailableWorkspacesAndAccessTokens;
|
||||
verifyEmailingDomain: EmailingDomain;
|
||||
registerNpmPackage: ApplicationRegistration;
|
||||
verifyTwoFactorAuthenticationMethodForAuthenticatedUser: VerifyTwoFactorAuthenticationMethod;
|
||||
};
|
||||
|
||||
@@ -3058,6 +3058,11 @@ export type MutationInstallMarketplaceAppArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationRegisterNpmPackageArgs = {
|
||||
packageName: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationRemoveQueryFromEventStreamArgs = {
|
||||
input: RemoveQueryFromEventStreamInput;
|
||||
};
|
||||
@@ -3481,11 +3486,6 @@ export type MutationVerifyEmailingDomainArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationRegisterNpmPackageArgs = {
|
||||
packageName: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationVerifyTwoFactorAuthenticationMethodForAuthenticatedUserArgs = {
|
||||
otp: Scalars['String'];
|
||||
};
|
||||
|
||||
+1
-1
@@ -28,8 +28,8 @@ const StyledButtonContainer = styled.div`
|
||||
`;
|
||||
|
||||
const StyledPublishMethodLabel = styled.div`
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
color: ${themeCssVariables.font.color.light};
|
||||
font-size: ${themeCssVariables.font.size.sm};
|
||||
margin-bottom: ${themeCssVariables.spacing[2]};
|
||||
margin-top: ${themeCssVariables.spacing[4]};
|
||||
`;
|
||||
|
||||
@@ -31,20 +31,14 @@ export class AppRegisterCommand {
|
||||
|
||||
console.log(chalk.green('Package registered successfully!'));
|
||||
console.log(chalk.gray(` Name: ${result.data.name}`));
|
||||
console.log(
|
||||
chalk.gray(` ID: ${result.data.universalIdentifier}`),
|
||||
);
|
||||
console.log(chalk.gray(` ID: ${result.data.universalIdentifier}`));
|
||||
|
||||
if (result.data.isProvenanceVerified) {
|
||||
console.log(
|
||||
chalk.green(' Provenance: Verified'),
|
||||
);
|
||||
console.log(chalk.green(' Provenance: Verified'));
|
||||
|
||||
if (result.data.provenanceRepositoryUrl) {
|
||||
console.log(
|
||||
chalk.gray(
|
||||
` Repository: ${result.data.provenanceRepositoryUrl}`,
|
||||
),
|
||||
chalk.gray(` Repository: ${result.data.provenanceRepositoryUrl}`),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
||||
+7
-8
@@ -1,12 +1,11 @@
|
||||
import {
|
||||
ApplicationException,
|
||||
ApplicationExceptionCode,
|
||||
} from 'src/engine/core-modules/application/application.exception';
|
||||
import { ApplicationException } from 'src/engine/core-modules/application/application.exception';
|
||||
import { assertValidNpmPackageName } from 'src/engine/core-modules/application/application-package/utils/assert-valid-npm-package-name.util';
|
||||
|
||||
describe('assertValidNpmPackageName', () => {
|
||||
it('should accept valid twenty-app- prefixed names', () => {
|
||||
expect(() => assertValidNpmPackageName('twenty-app-my-cool-app')).not.toThrow();
|
||||
expect(() =>
|
||||
assertValidNpmPackageName('twenty-app-my-cool-app'),
|
||||
).not.toThrow();
|
||||
expect(() => assertValidNpmPackageName('twenty-app-hello')).not.toThrow();
|
||||
});
|
||||
|
||||
@@ -23,9 +22,9 @@ describe('assertValidNpmPackageName', () => {
|
||||
});
|
||||
|
||||
it('should reject scoped packages without twenty-app- prefix', () => {
|
||||
expect(() =>
|
||||
assertValidNpmPackageName('@myorg/my-cool-app'),
|
||||
).toThrow(ApplicationException);
|
||||
expect(() => assertValidNpmPackageName('@myorg/my-cool-app')).toThrow(
|
||||
ApplicationException,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject invalid npm package names', () => {
|
||||
|
||||
+5
-18
@@ -10,9 +10,7 @@ import { ApplicationRegistrationService } from 'src/engine/core-modules/applicat
|
||||
import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service';
|
||||
import { type UserEntity } from 'src/engine/core-modules/user/user.entity';
|
||||
|
||||
const createMockUser = (
|
||||
overrides: Partial<UserEntity> = {},
|
||||
): UserEntity =>
|
||||
const createMockUser = (overrides: Partial<UserEntity> = {}): UserEntity =>
|
||||
({
|
||||
id: 'user-123',
|
||||
email: '[email protected]',
|
||||
@@ -59,9 +57,7 @@ describe('ApplicationNpmRegistrationService', () => {
|
||||
}).compile();
|
||||
|
||||
service = module.get(ApplicationNpmRegistrationService);
|
||||
applicationRegistrationService = module.get(
|
||||
ApplicationRegistrationService,
|
||||
);
|
||||
applicationRegistrationService = module.get(ApplicationRegistrationService);
|
||||
applicationPackageFetcherService = module.get(
|
||||
ApplicationPackageFetcherService,
|
||||
);
|
||||
@@ -101,11 +97,7 @@ describe('ApplicationNpmRegistrationService', () => {
|
||||
});
|
||||
|
||||
await expect(
|
||||
service.registerNpmPackage(
|
||||
'twenty-app-test',
|
||||
user,
|
||||
'workspace-1',
|
||||
),
|
||||
service.registerNpmPackage('twenty-app-test', user, 'workspace-1'),
|
||||
).rejects.toThrow(ApplicationRegistrationException);
|
||||
});
|
||||
|
||||
@@ -203,19 +195,14 @@ describe('ApplicationNpmRegistrationService', () => {
|
||||
{} as any,
|
||||
);
|
||||
|
||||
await service.registerNpmPackage(
|
||||
'twenty-app-test',
|
||||
user,
|
||||
'workspace-1',
|
||||
);
|
||||
await service.registerNpmPackage('twenty-app-test', user, 'workspace-1');
|
||||
|
||||
expect(
|
||||
applicationRegistrationService.upsertFromNpmRegistration,
|
||||
).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
isProvenanceVerified: true,
|
||||
provenanceRepositoryUrl:
|
||||
'https://github.com/user/twenty-app-test',
|
||||
provenanceRepositoryUrl: 'https://github.com/user/twenty-app-test',
|
||||
provenanceVerifiedAt: expect.any(Date),
|
||||
}),
|
||||
);
|
||||
|
||||
+6
-15
@@ -17,10 +17,7 @@ type NpmPackument = {
|
||||
name: string;
|
||||
'dist-tags': Record<string, string>;
|
||||
maintainers: Array<{ name: string; email: string }>;
|
||||
versions: Record<
|
||||
string,
|
||||
{ dist?: { tarball?: string; integrity?: string } }
|
||||
>;
|
||||
versions: Record<string, { dist?: { tarball?: string; integrity?: string } }>;
|
||||
};
|
||||
|
||||
export type ProvenanceMetadata = {
|
||||
@@ -30,9 +27,7 @@ export type ProvenanceMetadata = {
|
||||
|
||||
@Injectable()
|
||||
export class ApplicationNpmRegistrationService {
|
||||
private readonly logger = new Logger(
|
||||
ApplicationNpmRegistrationService.name,
|
||||
);
|
||||
private readonly logger = new Logger(ApplicationNpmRegistrationService.name);
|
||||
|
||||
constructor(
|
||||
private readonly twentyConfigService: TwentyConfigService,
|
||||
@@ -55,7 +50,7 @@ export class ApplicationNpmRegistrationService {
|
||||
}
|
||||
|
||||
const { data } = await axios.get<NpmPackument>(
|
||||
`${registryUrl}/${encodeURIComponent(packageName).replace('%40', '@')}`,
|
||||
`${registryUrl}/${encodeURIComponent(packageName).replaceAll('%40', '@')}`,
|
||||
{ headers, timeout: 15_000 },
|
||||
);
|
||||
|
||||
@@ -142,10 +137,8 @@ export class ApplicationNpmRegistrationService {
|
||||
ownerWorkspaceId: workspaceId,
|
||||
createdByUserId: user.id,
|
||||
latestAvailableVersion: latestVersion ?? null,
|
||||
isProvenanceVerified:
|
||||
provenanceMetadata?.hasProvenance ?? false,
|
||||
provenanceRepositoryUrl:
|
||||
provenanceMetadata?.repositoryUrl ?? null,
|
||||
isProvenanceVerified: provenanceMetadata?.hasProvenance ?? false,
|
||||
provenanceRepositoryUrl: provenanceMetadata?.repositoryUrl ?? null,
|
||||
provenanceVerifiedAt: provenanceMetadata?.hasProvenance
|
||||
? new Date()
|
||||
: null,
|
||||
@@ -176,9 +169,7 @@ export class ApplicationNpmRegistrationService {
|
||||
}
|
||||
|
||||
for (const attestation of data.attestations) {
|
||||
if (
|
||||
attestation.predicateType !== 'https://slsa.dev/provenance/v1'
|
||||
) {
|
||||
if (attestation.predicateType !== 'https://slsa.dev/provenance/v1') {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user