Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 🔥 [EXL-71] support policy creation onboarding page #361

Merged
merged 4 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .depcheckrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"@commitlint/cli",
"@types/node",
"stylelint",
"@prisma/client",
"is-docker"
"is-docker",
"@prisma/client"
]
}
4 changes: 3 additions & 1 deletion .npmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
save-exact=true
stream=true
strict-peer-dependencies=false
strict-peer-dependencies=false
public-hoist-pattern[]=prisma
public-hoist-pattern[]=@prisma/client
8 changes: 8 additions & 0 deletions apps/backend/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@ module.exports = {

'node/no-sync': 'error',
},
overrides: [
{
files: ['./src/data/**/*.ts'],
rules: {
'max-lines': 'off',
},
},
],
};
10 changes: 10 additions & 0 deletions apps/backend/src/data/depcheck-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { ILibraryData } from '../interfaces/libraries-data';

export const depcheckData: ILibraryData = {
name: 'Depcheck',
author: 'Djordje Lukic, Junle Li',
description: 'Check your npm module for unused dependencies.',
types: ['Linters'],
categories: ['Dependencies'],
language: 'JavaScript',
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { LibraryCategory } from '../models/library-category';
import { LibraryType } from '../models/library-type';
import type { ILibraryData } from '../interfaces/libraries-data';

export const eslintData = {
export const eslintData: ILibraryData = {
name: 'ESLint',
author: 'Nicholas C. Zakas',
description: 'Find and fix problems in your JavaScript code.',
type: [LibraryType.Linters],
category: [LibraryCategory.Code],
types: ['Linters'],
categories: ['Code'],
language: 'JavaScript',
rules: {
'Array Callback Return': {
description: 'Enforce `return` statements in callbacks of array methods',
Expand Down
10 changes: 10 additions & 0 deletions apps/backend/src/data/inflint-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import type { ILibraryData } from '../interfaces/libraries-data';

export const inflintData: ILibraryData = {
name: 'Inflint',
author: 'Tal Rofe',
description: 'Inflint is a tool which scans and verifies file name conventions.',
types: ['Linters'],
categories: ['File System'],
language: 'Agnostic',
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { ILbirariesData } from '../interfaces/libraries';
import type { ILibraryData } from '../interfaces/libraries-data';
import { depcheckData } from './depcheck-data';
import { eslintData } from './eslint-data';
import { inflintData } from './inflint-data';
import { prettierData } from './prettier-data';
import { stylelintData } from './stylelint-data';

export const librariesData: ILbirariesData = {
eslint: eslintData,
stylelint: stylelintData,
depcheck: depcheckData,
prettier: prettierData,
inflint: inflintData,
};
export const librariesData: ILibraryData[] = [
depcheckData,
eslintData,
inflintData,
prettierData,
stylelintData,
];
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { LibraryCategory } from '../models/library-category';
import { LibraryType } from '../models/library-type';
import type { ILibraryData } from '../interfaces/libraries-data';

export const prettierData = {
export const prettierData: ILibraryData = {
name: 'Prettier',
author: 'prettier.io',
description: 'Prettier is an opinionated code formatter.',
type: [LibraryType.Formatters],
category: [LibraryCategory.Code],
types: ['Formatters'],
categories: ['Code'],
rules: {
'Print Width': {
description: 'Specify the line length that the printer will wrap on.',
Expand Down Expand Up @@ -100,4 +99,5 @@ export const prettierData = {
configApi: 'singleAttributePerLine',
},
},
language: 'Agnostic',
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { LibraryCategory } from '../models/library-category';
import { LibraryType } from '../models/library-type';
import type { ILibraryData } from '../interfaces/libraries-data';

export const stylelintData = {
export const stylelintData: ILibraryData = {
name: 'Stylelint',
author: 'stylelint.io',
description:
'A mighty, modern linter that helps you avoid errors and enforce conventions in your styles.',
type: [LibraryType.Linters],
category: [LibraryCategory.Code, LibraryCategory.Styles],
types: ['Linters'],
categories: ['Code', 'Styles'],
language: 'CSSHTML',
rules: {
'Color No Invalid Hex': {
description: 'Disallow invalid hex colors.',
Expand Down
24 changes: 24 additions & 0 deletions apps/backend/src/interfaces/libraries-data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { PolicyLibrary } from '@prisma/client';

interface ILibraryRule {
readonly description: string;
readonly configApi: string;
readonly hasAutoFix?: boolean;
readonly category?: string;
}

export type IType = 'Linters' | 'Formatters';

export type ICategory = 'Code' | 'File System' | 'Styles' | 'Dependencies';

export type ILanguage = 'JavaScript' | 'CSSHTML' | 'Agnostic';

export interface ILibraryData {
readonly name: PolicyLibrary;
readonly author: string;
readonly description: string;
readonly types: IType[];
readonly categories: ICategory[];
readonly language: ILanguage;
readonly rules?: Record<string, ILibraryRule>;
}
80 changes: 19 additions & 61 deletions apps/backend/src/modules/database/inline-policy.service.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
import { Injectable } from '@nestjs/common';
import type { PolicyLibrary, Prisma } from '@prisma/client';
import type { PolicyLibrary } from '@prisma/client';

import { PrismaService } from './prisma.service';

@Injectable()
export class DBInlinePolicyService {
constructor(private prisma: PrismaService) {}

public async createInlinePolicy(groupId: string, label: string, library: PolicyLibrary) {
const createdInlinePolicy = await this.prisma.inlinePolicy.create({
data: { groupId, label, library },
select: { id: true },
});

return createdInlinePolicy.id;
}

public async deleteInlinePolicy(inlinePolicyId: string) {
await this.prisma.inlinePolicy.delete({ where: { id: inlinePolicyId } });
}

public async updateConfiguration(inlinePolicyId: string, configuration: Record<string, unknown>) {
await this.prisma.inlinePolicy.update({
where: { id: inlinePolicyId },
data: { configuration: configuration as Prisma.JsonObject },
public async createInlinePolicy(
groupId: string,
label: string,
description: string | null,
library: PolicyLibrary,
) {
await this.prisma.inlinePolicy.create({
data: { groupId, label, description, library },
});
}

Expand All @@ -35,54 +26,21 @@ export class DBInlinePolicyService {
return inlinePolicyDB !== null;
}

public async addRule(inlinePolicyId: string, rule: Record<string, unknown>) {
const inlinePolicyDB = await this.prisma.inlinePolicy.findUniqueOrThrow({
where: { id: inlinePolicyId },
select: { rules: true },
public async isLabelAvailable(userId: string, label: string) {
const record = await this.prisma.inlinePolicy.findFirst({
where: { label, group: { userId } },
});

let newInlinePolicyRules: Prisma.JsonObject;

if (!inlinePolicyDB.rules) {
newInlinePolicyRules = rule as Prisma.JsonObject;
} else {
newInlinePolicyRules = {
...(inlinePolicyDB.rules as Prisma.JsonObject),
...rule,
} as Prisma.JsonObject;
}

await this.prisma.inlinePolicy.update({
where: { id: inlinePolicyId },
data: { rules: newInlinePolicyRules },
});
return record === null;
}

public async removeRule(inlinePolicyId: string, ruleName: string) {
const inlinePolicyDB = await this.prisma.inlinePolicy.findUniqueOrThrow({
where: { id: inlinePolicyId },
select: { rules: true },
});

if (!inlinePolicyDB.rules) {
return;
}

const rulesWithoutRule = {
...(inlinePolicyDB.rules as Prisma.JsonObject),
[ruleName]: undefined,
};

await this.prisma.inlinePolicy.update({
where: { id: inlinePolicyId },
data: { rules: rulesWithoutRule },
});
public getUserGroupLibraries(groupId: string) {
return this.prisma.inlinePolicy.findMany({ where: { groupId }, select: { library: true } });
}

public getConfiguration(inlinePolicyId: string) {
return this.prisma.inlinePolicy.findFirst({
where: { id: inlinePolicyId },
select: { configuration: true },
});
public async groupHasLibrary(groupId: string, library: PolicyLibrary) {
const record = await this.prisma.inlinePolicy.findFirst({ where: { groupId, library } });

return record !== null;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ApiResponseProperty } from '@nestjs/swagger';
import { PolicyLibrary } from '@prisma/client';

import type { IGroupInlinePolicies, IGroupInlinePolicy } from '../interfaces/group-policies';
import { ILanguage } from '@/interfaces/libraries-data';

import type { IGroupInlinePolicies, IGroupInlinePolicy } from '../interfaces/group-policies';
import type { IUserGroupGetAll, IUserGroupInlinePolicy } from '../interfaces/user-group';

class UserGroupInlinePolicyGetAll implements IUserGroupInlinePolicy {
Expand Down Expand Up @@ -71,7 +72,7 @@ class GroupInlinePolicy implements IGroupInlinePolicy {
type: String,
example: 'JavaScript',
})
public language!: string;
public language!: ILanguage;
}

export class CreateGroupResponse {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { Group, InlinePolicy } from '@prisma/client';

import type { ILanguage } from '@/interfaces/libraries-data';

export type IGroupInlinePolicy = Pick<InlinePolicy, 'id' | 'label' | 'library'> & {
readonly language: string;
readonly language: ILanguage;
};

export interface IGroupInlinePolicies extends Pick<Group, 'description'> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { QueryHandler, type IQueryHandler } from '@nestjs/cqrs';

import { DBGroupService } from '@/modules/database/group.service';
import { librariesData } from '@/data/libraries-data';

import { GetInlinePoliciesContract } from '../contracts/get-inline-policies.contract';
import { libariesLanguages } from '../../data/libraries';

@QueryHandler(GetInlinePoliciesContract)
export class GetInlinePoliciesHandler implements IQueryHandler<GetInlinePoliciesContract> {
Expand All @@ -17,10 +17,16 @@ export class GetInlinePoliciesHandler implements IQueryHandler<GetInlinePolicies
isPageANumber ? parseInt(contract.page!) : 1,
);

data.inlinePolicies = data.inlinePolicies.map((inlinePolicy) => ({
...inlinePolicy,
language: libariesLanguages[inlinePolicy.library],
}));
data.inlinePolicies = data.inlinePolicies.map((inlinePolicy) => {
const matchingLibraryData = librariesData.find(
(libraryData) => libraryData.name === inlinePolicy.library,
)!;

return {
...inlinePolicy,
language: matchingLibraryData.language,
};
});

return data;
}
Expand Down
Loading