Skip to content

Commit

Permalink
chore: lint class member order
Browse files Browse the repository at this point in the history
  • Loading branch information
Nicolas Moreau committed Jan 6, 2025
1 parent d65e089 commit ca5d4fc
Show file tree
Hide file tree
Showing 26 changed files with 476 additions and 429 deletions.
18 changes: 16 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module.exports = {
sourceType: 'module',
project: ['./tsconfig.eslint.json'],
},
plugins: ['@typescript-eslint', 'prettier', 'jest', 'jest-formatting'],
plugins: ['@typescript-eslint', 'prettier', 'jest', 'jest-formatting', 'sort-class-members'],
rules: {
/**********/
/** Style */
Expand Down Expand Up @@ -48,7 +48,21 @@ module.exports = {
alphabetize: { order: 'asc', caseInsensitive: true },
},
],

"sort-class-members/sort-class-members": [
2,
{
"order": [
"[static-properties]",
"[static-methods]",
"[properties]",
"constructor",
"[conventional-private-properties]",
"[methods]",
"[conventional-private-methods]"
],
"accessorPairPositioning": "getThenSet"
}
],
/***********************************/
/* Stricter rules than airbnb-base */
/***********************************/
Expand Down
1 change: 1 addition & 0 deletions packages/_example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"db:seed": "ts-node scripts/db-seed.ts"
},
"devDependencies": {
"eslint-plugin-sort-class-members": "^1.21.0",
"ts-node": "^10.9.2"
}
}
10 changes: 5 additions & 5 deletions packages/agent/src/framework-mounter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ export default class FrameworkMounter {
private readonly prefix: string;
private readonly logger: Logger;

/** Compute the prefix that the main router should be mounted at in the client's application */
private get completeMountPrefix(): string {
return path.posix.join('/', this.prefix, 'forest');
}

constructor(prefix: string, logger: Logger) {
this.prefix = prefix;
this.logger = logger;
}

/** Compute the prefix that the main router should be mounted at in the client's application */
private get completeMountPrefix(): string {
return path.posix.join('/', this.prefix, 'forest');
}

protected async mount(router: Router): Promise<void> {
for (const task of this.onFirstStart) await task(); // eslint-disable-line no-await-in-loop

Expand Down
8 changes: 4 additions & 4 deletions packages/agent/src/routes/access/api-chart-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ import CollectionRoute from '../collection-route';
export default class CollectionApiChartRoute extends CollectionRoute {
private chartName: string;

get chartUrlSlug(): string {
return this.escapeUrlSlug(this.chartName);
}

constructor(
services: ForestAdminHttpDriverServices,
options: AgentOptionsWithDefaults,
Expand All @@ -28,6 +24,10 @@ export default class CollectionApiChartRoute extends CollectionRoute {
this.chartName = chartName;
}

get chartUrlSlug(): string {
return this.escapeUrlSlug(this.chartName);
}

setupRoutes(router: Router): void {
// Mount both GET and POST, respectively for smart and api charts.
const suffix = `/_charts/${this.collectionUrlSlug}/${this.chartUrlSlug}`;
Expand Down
8 changes: 4 additions & 4 deletions packages/agent/src/routes/access/api-chart-datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ export default class DataSourceApiChartRoute extends BaseRoute {
private dataSource: DataSource;
private chartName: string;

get chartUrlSlug(): string {
return this.escapeUrlSlug(this.chartName);
}

constructor(
services: ForestAdminHttpDriverServices,
options: AgentOptionsWithDefaults,
Expand All @@ -31,6 +27,10 @@ export default class DataSourceApiChartRoute extends BaseRoute {
this.chartName = chartName;
}

get chartUrlSlug(): string {
return this.escapeUrlSlug(this.chartName);
}

setupRoutes(router: Router): void {
// Mount both GET and POST, respectively for smart and api charts.
const suffix = `/_charts/${this.chartUrlSlug}`;
Expand Down
3 changes: 1 addition & 2 deletions packages/agent/src/routes/base-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ export default abstract class BaseRoute {
protected readonly services: ForestAdminHttpDriverServices;
protected readonly options: AgentOptionsWithDefaults;

abstract get type(): RouteType;

constructor(services: ForestAdminHttpDriverServices, options: AgentOptionsWithDefaults) {
this.services = services;
this.options = options;
}
abstract get type(): RouteType;

async bootstrap(): Promise<void> {
// Do nothing by default
Expand Down
16 changes: 8 additions & 8 deletions packages/agent/src/routes/collection-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ export default abstract class CollectionRoute extends BaseRoute {
private readonly collectionName: string;
protected readonly dataSource: DataSource;

protected get collection(): Collection {
return this.dataSource.getCollection(this.collectionName);
}

protected get collectionUrlSlug(): string {
return this.escapeUrlSlug(this.collectionName);
}

constructor(
services: ForestAdminHttpDriverServices,
options: AgentOptionsWithDefaults,
Expand All @@ -28,4 +20,12 @@ export default abstract class CollectionRoute extends BaseRoute {
this.collectionName = collectionName;
this.dataSource = dataSource;
}

protected get collection(): Collection {
return this.dataSource.getCollection(this.collectionName);
}

protected get collectionUrlSlug(): string {
return this.escapeUrlSlug(this.collectionName);
}
}
188 changes: 94 additions & 94 deletions packages/agent/src/routes/modification/action/action-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,100 @@ type CanPerformCustomActionParams = {
};

export default class ActionAuthorizationService {
private static async canPerformConditionalCustomAction(
caller: Caller,
collection: Collection,
requestFilter: Filter,
condition?: unknown,
) {
if (condition) {
const [requestRecordsCount, matchingRecordsCount] = await Promise.all([
ActionAuthorizationService.aggregateCountConditionIntersection(
caller,
collection,
requestFilter,
),
ActionAuthorizationService.aggregateCountConditionIntersection(
caller,
collection,
requestFilter,
condition,
),
]);

// If all records condition the condition everything is ok
// Otherwise when some records don't match the condition then the user
// is not allow to perform the conditional action
return matchingRecordsCount === requestRecordsCount;
}

return true;
}

private static async aggregateCountConditionIntersection(
caller: Caller,
collection: Collection,
requestFilter: Filter,
condition?: unknown,
) {
try {
// Override request filter with condition if any
const conditionalFilter = requestFilter.override({
conditionTree: condition
? ConditionTreeFactory.intersect(
ConditionTreeParser.fromPlainObject(collection, condition),
requestFilter.conditionTree,
)
: requestFilter.conditionTree,
});

const rows = await collection.aggregate(
caller,
conditionalFilter,
new Aggregation({
operation: 'Count',
}),
);

return (rows?.[0]?.value as number) ?? 0;
} catch (error) {
throw new InvalidActionConditionError();
}
}

/**
* Given a map it groups keys based on their hash values
*/
private static transformToRolesIdsGroupByConditions<T>(
actionConditionsByRoleId: Map<number, T>,
): {
roleIds: number[];
condition: T;
}[] {
const rolesIdsGroupByConditions = Array.from(
actionConditionsByRoleId,
([roleId, condition]) => {
return {
roleId,
condition,
conditionHash: hashObject(condition as Record<string, unknown>, { respectType: false }),
};
},
).reduce((acc, current) => {
const { roleId, condition, conditionHash } = current;

if (acc.has(conditionHash)) {
acc.get(conditionHash).roleIds.push(roleId);
} else {
acc.set(conditionHash, { roleIds: [roleId], condition });
}

return acc;
}, new Map<string, { roleIds: number[]; condition: T }>());

return Array.from(rolesIdsGroupByConditions.values());
}

constructor(private readonly forestAdminClient: ForestAdminClient) {}

public async assertCanTriggerCustomAction({
Expand Down Expand Up @@ -274,98 +368,4 @@ export default class ActionAuthorizationService {
roleIdsAllowedToApproveWithoutConditions,
);
}

private static async canPerformConditionalCustomAction(
caller: Caller,
collection: Collection,
requestFilter: Filter,
condition?: unknown,
) {
if (condition) {
const [requestRecordsCount, matchingRecordsCount] = await Promise.all([
ActionAuthorizationService.aggregateCountConditionIntersection(
caller,
collection,
requestFilter,
),
ActionAuthorizationService.aggregateCountConditionIntersection(
caller,
collection,
requestFilter,
condition,
),
]);

// If all records condition the condition everything is ok
// Otherwise when some records don't match the condition then the user
// is not allow to perform the conditional action
return matchingRecordsCount === requestRecordsCount;
}

return true;
}

private static async aggregateCountConditionIntersection(
caller: Caller,
collection: Collection,
requestFilter: Filter,
condition?: unknown,
) {
try {
// Override request filter with condition if any
const conditionalFilter = requestFilter.override({
conditionTree: condition
? ConditionTreeFactory.intersect(
ConditionTreeParser.fromPlainObject(collection, condition),
requestFilter.conditionTree,
)
: requestFilter.conditionTree,
});

const rows = await collection.aggregate(
caller,
conditionalFilter,
new Aggregation({
operation: 'Count',
}),
);

return (rows?.[0]?.value as number) ?? 0;
} catch (error) {
throw new InvalidActionConditionError();
}
}

/**
* Given a map it groups keys based on their hash values
*/
private static transformToRolesIdsGroupByConditions<T>(
actionConditionsByRoleId: Map<number, T>,
): {
roleIds: number[];
condition: T;
}[] {
const rolesIdsGroupByConditions = Array.from(
actionConditionsByRoleId,
([roleId, condition]) => {
return {
roleId,
condition,
conditionHash: hashObject(condition as Record<string, unknown>, { respectType: false }),
};
},
).reduce((acc, current) => {
const { roleId, condition, conditionHash } = current;

if (acc.has(conditionHash)) {
acc.get(conditionHash).roleIds.push(roleId);
} else {
acc.set(conditionHash, { roleIds: [roleId], condition });
}

return acc;
}, new Map<string, { roleIds: number[]; condition: T }>());

return Array.from(rolesIdsGroupByConditions.values());
}
}
22 changes: 11 additions & 11 deletions packages/agent/src/routes/relation-route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import { AgentOptionsWithDefaults } from '../types';
export default abstract class RelationRoute extends CollectionRoute {
protected readonly relationName: string;

constructor(
services: ForestAdminHttpDriverServices,
options: AgentOptionsWithDefaults,
dataSource: DataSource,
collectionName: string,
relationName: string,
) {
super(services, options, dataSource, collectionName);
this.relationName = relationName;
}

protected get foreignCollection(): Collection {
const schema = SchemaUtils.getRelation(
this.collection.schema,
Expand All @@ -20,15 +31,4 @@ export default abstract class RelationRoute extends CollectionRoute {
protected get relationUrlSlug(): string {
return this.escapeUrlSlug(this.relationName);
}

constructor(
services: ForestAdminHttpDriverServices,
options: AgentOptionsWithDefaults,
dataSource: DataSource,
collectionName: string,
relationName: string,
) {
super(services, options, dataSource, collectionName);
this.relationName = relationName;
}
}
Loading

0 comments on commit ca5d4fc

Please sign in to comment.