mirror of
https://github.com/logto-io/logto.git
synced 2025-02-17 22:04:19 -05:00
refactor(core): remove SchemaActions
class
This commit is contained in:
parent
98b2eed6ec
commit
d64461c30e
7 changed files with 96 additions and 121 deletions
|
@ -5,7 +5,7 @@ import { number } from 'zod';
|
||||||
import RequestError from '#src/errors/RequestError/index.js';
|
import RequestError from '#src/errors/RequestError/index.js';
|
||||||
import { buildLink } from '#src/utils/pagination.js';
|
import { buildLink } from '#src/utils/pagination.js';
|
||||||
|
|
||||||
export type Pagination = {
|
type Pagination = {
|
||||||
offset: number;
|
offset: number;
|
||||||
limit: number;
|
limit: number;
|
||||||
totalCount?: number;
|
totalCount?: number;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { z } from 'zod';
|
||||||
import RequestError from '#src/errors/RequestError/index.js';
|
import RequestError from '#src/errors/RequestError/index.js';
|
||||||
import koaGuard from '#src/middleware/koa-guard.js';
|
import koaGuard from '#src/middleware/koa-guard.js';
|
||||||
import koaPagination from '#src/middleware/koa-pagination.js';
|
import koaPagination from '#src/middleware/koa-pagination.js';
|
||||||
import SchemaRouter, { SchemaActions } from '#src/utils/SchemaRouter.js';
|
import SchemaRouter from '#src/utils/SchemaRouter.js';
|
||||||
|
|
||||||
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ export default function organizationRoutes<T extends AuthedRouter>(...args: Rout
|
||||||
queries: { organizations, users },
|
queries: { organizations, users },
|
||||||
},
|
},
|
||||||
] = args;
|
] = args;
|
||||||
const router = new SchemaRouter(Organizations, new SchemaActions(organizations), {
|
const router = new SchemaRouter(Organizations, organizations, {
|
||||||
errorHandler,
|
errorHandler,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { type CreateOrganizationRole, OrganizationRoles } from '@logto/schemas';
|
import { type CreateOrganizationRole, OrganizationRoles } from '@logto/schemas';
|
||||||
|
import { generateStandardId } from '@logto/shared';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import koaGuard from '#src/middleware/koa-guard.js';
|
import koaGuard from '#src/middleware/koa-guard.js';
|
||||||
import SchemaRouter, { SchemaActions } from '#src/utils/SchemaRouter.js';
|
import SchemaRouter from '#src/utils/SchemaRouter.js';
|
||||||
|
|
||||||
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
||||||
|
|
||||||
|
@ -21,8 +22,7 @@ export default function organizationRoleRoutes<T extends AuthedRouter>(
|
||||||
},
|
},
|
||||||
]: RouterInitArgs<T>
|
]: RouterInitArgs<T>
|
||||||
) {
|
) {
|
||||||
const actions = new SchemaActions(roles);
|
const router = new SchemaRouter(OrganizationRoles, roles, {
|
||||||
const router = new SchemaRouter(OrganizationRoles, actions, {
|
|
||||||
disabled: { post: true },
|
disabled: { post: true },
|
||||||
errorHandler,
|
errorHandler,
|
||||||
});
|
});
|
||||||
|
@ -50,7 +50,7 @@ export default function organizationRoleRoutes<T extends AuthedRouter>(
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const { organizationScopeIds: scopeIds, ...data } = ctx.guard.body;
|
const { organizationScopeIds: scopeIds, ...data } = ctx.guard.body;
|
||||||
const role = await actions.post(data);
|
const role = await roles.insert({ id: generateStandardId(), ...data });
|
||||||
|
|
||||||
if (scopeIds.length > 0) {
|
if (scopeIds.length > 0) {
|
||||||
await rolesScopes.insert(...scopeIds.map<[string, string]>((id) => [role.id, id]));
|
await rolesScopes.insert(...scopeIds.map<[string, string]>((id) => [role.id, id]));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { OrganizationScopes } from '@logto/schemas';
|
import { OrganizationScopes } from '@logto/schemas';
|
||||||
|
|
||||||
import SchemaRouter, { SchemaActions } from '#src/utils/SchemaRouter.js';
|
import SchemaRouter from '#src/utils/SchemaRouter.js';
|
||||||
|
|
||||||
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
import { type AuthedRouter, type RouterInitArgs } from '../types.js';
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ export default function organizationScopeRoutes<T extends AuthedRouter>(
|
||||||
},
|
},
|
||||||
]: RouterInitArgs<T>
|
]: RouterInitArgs<T>
|
||||||
) {
|
) {
|
||||||
const router = new SchemaRouter(OrganizationScopes, new SchemaActions(scopes), { errorHandler });
|
const router = new SchemaRouter(OrganizationScopes, scopes, { errorHandler });
|
||||||
|
|
||||||
originalRouter.use(router.routes());
|
originalRouter.use(router.routes());
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ import { buildUpdateWhereWithPool } from '#src/database/update-where.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query class that contains all the necessary CRUD queries for a schema. It is
|
* Query class that contains all the necessary CRUD queries for a schema. It is
|
||||||
* designed to be used with SchemaActions for a SchemaRouter. You can also extend
|
* designed to be used with a SchemaRouter. You can also extend this class to add
|
||||||
* this class to add more queries.
|
* more queries.
|
||||||
*/
|
*/
|
||||||
export default class SchemaQueries<
|
export default class SchemaQueries<
|
||||||
Key extends string,
|
Key extends string,
|
||||||
|
@ -55,7 +55,7 @@ export default class SchemaQueries<
|
||||||
return this.#findById(id);
|
return this.#findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async insert(data: OmitAutoSetFields<CreateSchema>): Promise<Readonly<Schema>> {
|
async insert(data: CreateSchema): Promise<Readonly<Schema>> {
|
||||||
return this.#insert(data);
|
return this.#insert(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { z } from 'zod';
|
||||||
import RequestError from '#src/errors/RequestError/index.js';
|
import RequestError from '#src/errors/RequestError/index.js';
|
||||||
|
|
||||||
import SchemaQueries from './SchemaQueries.js';
|
import SchemaQueries from './SchemaQueries.js';
|
||||||
import SchemaRouter, { type SchemaActions } from './SchemaRouter.js';
|
import SchemaRouter from './SchemaRouter.js';
|
||||||
import { createRequester, createTestPool } from './test-utils.js';
|
import { createRequester, createTestPool } from './test-utils.js';
|
||||||
|
|
||||||
const { jest } = import.meta;
|
const { jest } = import.meta;
|
||||||
|
@ -36,21 +36,26 @@ describe('SchemaRouter', () => {
|
||||||
{ id: '1', name: 'test' },
|
{ id: '1', name: 'test' },
|
||||||
{ id: '2', name: 'test2' },
|
{ id: '2', name: 'test2' },
|
||||||
] as const satisfies readonly Schema[];
|
] as const satisfies readonly Schema[];
|
||||||
const actions: SchemaActions<'name', CreateSchema, Schema> = {
|
const queries = new SchemaQueries(createTestPool(undefined, { id: '1' }), schema);
|
||||||
queries: new SchemaQueries(createTestPool(), schema),
|
|
||||||
get: jest.fn().mockResolvedValue([entities.length, entities]),
|
jest.spyOn(queries, 'findTotalNumber').mockResolvedValue(entities.length);
|
||||||
getById: jest.fn(async (id) => {
|
jest.spyOn(queries, 'findAll').mockResolvedValue(entities);
|
||||||
|
jest.spyOn(queries, 'findById').mockImplementation(async (id) => {
|
||||||
const entity = entities.find((entity) => entity.id === id);
|
const entity = entities.find((entity) => entity.id === id);
|
||||||
if (!entity) {
|
if (!entity) {
|
||||||
throw new RequestError({ code: 'entity.not_found', status: 404 });
|
throw new RequestError({ code: 'entity.not_found', status: 404 });
|
||||||
}
|
}
|
||||||
return entity;
|
return entity;
|
||||||
}),
|
});
|
||||||
post: jest.fn(async () => ({ id: 'new', name: 'test_new' })),
|
jest.spyOn(queries, 'insert').mockResolvedValue({ id: 'new', name: 'test_new' });
|
||||||
patchById: jest.fn(async (id, data) => ({ id, name: 'name_patch_default', ...data })),
|
jest.spyOn(queries, 'updateById').mockImplementation(async (id, data) => ({
|
||||||
deleteById: jest.fn(),
|
id,
|
||||||
};
|
name: 'name_patch_default',
|
||||||
const schemaRouter = new SchemaRouter(schema, actions);
|
...data,
|
||||||
|
}));
|
||||||
|
jest.spyOn(queries, 'deleteById');
|
||||||
|
|
||||||
|
const schemaRouter = new SchemaRouter(schema, queries);
|
||||||
const request = createRequester({ authedRoutes: (router) => router.use(schemaRouter.routes()) });
|
const request = createRequester({ authedRoutes: (router) => router.use(schemaRouter.routes()) });
|
||||||
const baseRoute = `/${schema.table.replaceAll('_', '-')}`;
|
const baseRoute = `/${schema.table.replaceAll('_', '-')}`;
|
||||||
|
|
||||||
|
@ -62,16 +67,16 @@ describe('SchemaRouter', () => {
|
||||||
it('should be able to get all entities', async () => {
|
it('should be able to get all entities', async () => {
|
||||||
const response = await request.get(baseRoute);
|
const response = await request.get(baseRoute);
|
||||||
|
|
||||||
expect(actions.get).toHaveBeenCalledWith(
|
expect(queries.findAll).toHaveBeenCalledWith(20, 0);
|
||||||
expect.objectContaining({ disabled: false, offset: 0, limit: 20 })
|
expect(queries.findTotalNumber).toHaveBeenCalled();
|
||||||
);
|
|
||||||
expect(response.body).toStrictEqual(entities);
|
expect(response.body).toStrictEqual(entities);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to get all entities with pagination', async () => {
|
it('should be able to get all entities with pagination', async () => {
|
||||||
const response = await request.get(`${baseRoute}?page=1&page_size=10`);
|
const response = await request.get(`${baseRoute}?page=1&page_size=10`);
|
||||||
|
|
||||||
expect(actions.get).toHaveBeenCalledWith(expect.objectContaining({ offset: 0, limit: 10 }));
|
expect(queries.findAll).toHaveBeenCalledWith(10, 0);
|
||||||
|
expect(queries.findTotalNumber).toHaveBeenCalled();
|
||||||
expect(response.body).toStrictEqual(entities);
|
expect(response.body).toStrictEqual(entities);
|
||||||
expect(response.header).toHaveProperty('total-number', '2');
|
expect(response.header).toHaveProperty('total-number', '2');
|
||||||
});
|
});
|
||||||
|
@ -81,7 +86,10 @@ describe('SchemaRouter', () => {
|
||||||
it('should be able to create an entity', async () => {
|
it('should be able to create an entity', async () => {
|
||||||
const response = await request.post(baseRoute).send({});
|
const response = await request.post(baseRoute).send({});
|
||||||
|
|
||||||
expect(actions.post).toHaveBeenCalledWith({});
|
expect(queries.insert).toHaveBeenCalledWith(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||||
|
expect.objectContaining({ id: expect.any(String) })
|
||||||
|
);
|
||||||
expect(response.body).toStrictEqual({ id: 'new', name: 'test_new' });
|
expect(response.body).toStrictEqual({ id: 'new', name: 'test_new' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -96,7 +104,7 @@ describe('SchemaRouter', () => {
|
||||||
it('should be able to get an entity by id', async () => {
|
it('should be able to get an entity by id', async () => {
|
||||||
const response = await request.get(`${baseRoute}/1`);
|
const response = await request.get(`${baseRoute}/1`);
|
||||||
|
|
||||||
expect(actions.getById).toHaveBeenCalledWith('1');
|
expect(queries.findById).toHaveBeenCalledWith('1');
|
||||||
expect(response.body).toStrictEqual(entities[0]);
|
expect(response.body).toStrictEqual(entities[0]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -112,7 +120,7 @@ describe('SchemaRouter', () => {
|
||||||
it('should be able to patch an entity by id', async () => {
|
it('should be able to patch an entity by id', async () => {
|
||||||
const response = await request.patch(`${baseRoute}/test`).send({ name: 'test_new' });
|
const response = await request.patch(`${baseRoute}/test`).send({ name: 'test_new' });
|
||||||
|
|
||||||
expect(actions.patchById).toHaveBeenCalledWith('test', { name: 'test_new' });
|
expect(queries.updateById).toHaveBeenCalledWith('test', { name: 'test_new' });
|
||||||
expect(response.body).toStrictEqual({ id: 'test', name: 'test_new' });
|
expect(response.body).toStrictEqual({ id: 'test', name: 'test_new' });
|
||||||
expect(response.status).toEqual(200);
|
expect(response.status).toEqual(200);
|
||||||
});
|
});
|
||||||
|
@ -122,8 +130,41 @@ describe('SchemaRouter', () => {
|
||||||
it('should be able to delete an entity by id', async () => {
|
it('should be able to delete an entity by id', async () => {
|
||||||
const response = await request.delete(`${baseRoute}/test`);
|
const response = await request.delete(`${baseRoute}/test`);
|
||||||
|
|
||||||
expect(actions.deleteById).toHaveBeenCalledWith('test');
|
expect(queries.deleteById).toHaveBeenCalledWith('test');
|
||||||
expect(response.status).toEqual(204);
|
expect(response.status).toEqual(204);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('disable routes', () => {
|
||||||
|
it('should be able to disable routes', async () => {
|
||||||
|
const disabledSchemaRouter = new SchemaRouter(schema, queries, {
|
||||||
|
disabled: { post: true, patchById: true, deleteById: true },
|
||||||
|
});
|
||||||
|
const disabledRequest = createRequester({
|
||||||
|
authedRoutes: (router) => router.use(disabledSchemaRouter.routes()),
|
||||||
|
});
|
||||||
|
|
||||||
|
await disabledRequest.post(baseRoute).send({});
|
||||||
|
expect(queries.insert).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await disabledRequest.patch(`${baseRoute}/test`).send({ name: 'test_new' });
|
||||||
|
expect(queries.updateById).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
await disabledRequest.delete(`${baseRoute}/test`);
|
||||||
|
expect(queries.deleteById).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('error handler', () => {
|
||||||
|
it('should be able to customize error handler', async () => {
|
||||||
|
const errorHandler = jest.fn();
|
||||||
|
const errorHandlerSchemaRouter = new SchemaRouter(schema, queries, { errorHandler });
|
||||||
|
const errorHandlerRequest = createRequester({
|
||||||
|
authedRoutes: (router) => router.use(errorHandlerSchemaRouter.routes()),
|
||||||
|
});
|
||||||
|
|
||||||
|
await errorHandlerRequest.get(`${baseRoute}/foo`);
|
||||||
|
expect(errorHandler).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { type SchemaLike, type GeneratedSchema, type Guard } from '@logto/schemas';
|
import { type SchemaLike, type GeneratedSchema } from '@logto/schemas';
|
||||||
import { generateStandardId, type OmitAutoSetFields } from '@logto/shared';
|
import { generateStandardId } from '@logto/shared';
|
||||||
import { type DeepPartial } from '@silverhand/essentials';
|
import { type DeepPartial } from '@silverhand/essentials';
|
||||||
import camelcase from 'camelcase';
|
import camelcase from 'camelcase';
|
||||||
import deepmerge from 'deepmerge';
|
import deepmerge from 'deepmerge';
|
||||||
|
@ -7,7 +7,7 @@ import Router, { type IRouterParamContext } from 'koa-router';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import koaGuard from '#src/middleware/koa-guard.js';
|
import koaGuard from '#src/middleware/koa-guard.js';
|
||||||
import koaPagination, { type Pagination } from '#src/middleware/koa-pagination.js';
|
import koaPagination from '#src/middleware/koa-pagination.js';
|
||||||
|
|
||||||
import type RelationQueries from './RelationQueries.js';
|
import type RelationQueries from './RelationQueries.js';
|
||||||
import type SchemaQueries from './SchemaQueries.js';
|
import type SchemaQueries from './SchemaQueries.js';
|
||||||
|
@ -34,79 +34,6 @@ const tableToPathname = (tableName: string) => tableName.replaceAll('_', '-');
|
||||||
const camelCaseSchemaId = <T extends { tableSingular: Table }, Table extends string>(schema: T) =>
|
const camelCaseSchemaId = <T extends { tableSingular: Table }, Table extends string>(schema: T) =>
|
||||||
`${camelcase(schema.tableSingular)}Id` as const;
|
`${camelcase(schema.tableSingular)}Id` as const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Actions configuration for a {@link SchemaRouter}. It contains the
|
|
||||||
* necessary functions to handle the CRUD operations for a schema.
|
|
||||||
*/
|
|
||||||
export class SchemaActions<
|
|
||||||
Key extends string,
|
|
||||||
CreateSchema extends Partial<SchemaLike<Key> & { id: string }>,
|
|
||||||
Schema extends SchemaLike<Key> & { id: string },
|
|
||||||
> {
|
|
||||||
constructor(public readonly queries: SchemaQueries<Key, CreateSchema, Schema>) {}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function for `GET /` route to get a list of entities.
|
|
||||||
*
|
|
||||||
* @param pagination The request pagination info parsed from `koa-pagination`. The
|
|
||||||
* function should honor the pagination info and return the correct entities.
|
|
||||||
* @returns A tuple of `[totalCount, entities]`. `totalCount` is the total count of
|
|
||||||
* entities in the database; `entities` is the list of entities to be returned.
|
|
||||||
*/
|
|
||||||
public async get({
|
|
||||||
limit,
|
|
||||||
offset,
|
|
||||||
}: Pick<Pagination, 'limit' | 'offset'>): Promise<
|
|
||||||
[totalCount: number, entries: readonly Schema[]]
|
|
||||||
> {
|
|
||||||
return Promise.all([this.queries.findTotalNumber(), this.queries.findAll(limit, offset)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function for `GET /:id` route to get an entity by ID.
|
|
||||||
*
|
|
||||||
* @param id The ID of the entity to be fetched.
|
|
||||||
* @returns The entity to be returned.
|
|
||||||
* @throws An `RequestError` with 404 status code if the entity is not found.
|
|
||||||
*/
|
|
||||||
public async getById(id: string): Promise<Readonly<Schema>> {
|
|
||||||
return this.queries.findById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function for `POST /` route to create an entity.
|
|
||||||
*
|
|
||||||
* @param data The data of the entity to be created.
|
|
||||||
* @returns The created entity.
|
|
||||||
*/
|
|
||||||
public async post(data: Omit<OmitAutoSetFields<CreateSchema>, 'id'>): Promise<Readonly<Schema>>;
|
|
||||||
public async post(data: OmitAutoSetFields<CreateSchema>): Promise<Readonly<Schema>> {
|
|
||||||
return this.queries.insert({ id: generateStandardId(), ...data });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function for `PATCH /:id` route to update the entity by ID.
|
|
||||||
*
|
|
||||||
* @param id The ID of the entity to be updated.
|
|
||||||
* @param data The data of the entity to be updated.
|
|
||||||
* @returns The updated entity.
|
|
||||||
* @throws An `UpdateError` if the entity is not found.
|
|
||||||
*/
|
|
||||||
public async patchById(id: string, data: Partial<Schema>): Promise<Readonly<Schema>> {
|
|
||||||
return this.queries.updateById(id, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The function for `DELETE /:id` route to delete an entity by ID.
|
|
||||||
*
|
|
||||||
* @param id The ID of the entity to be deleted.
|
|
||||||
* @throws An `DeletionError` if the entity is not found.
|
|
||||||
*/
|
|
||||||
public async deleteById(id: string): Promise<void> {
|
|
||||||
return this.queries.deleteById(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type SchemaRouterConfig = {
|
type SchemaRouterConfig = {
|
||||||
/** Disable certain routes for the router. */
|
/** Disable certain routes for the router. */
|
||||||
disabled: {
|
disabled: {
|
||||||
|
@ -150,7 +77,7 @@ export default class SchemaRouter<
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public readonly schema: GeneratedSchema<Key, CreateSchema, Schema>,
|
public readonly schema: GeneratedSchema<Key, CreateSchema, Schema>,
|
||||||
public readonly actions: SchemaActions<Key, CreateSchema, Schema>,
|
public readonly queries: SchemaQueries<Key, CreateSchema, Schema>,
|
||||||
config: DeepPartial<SchemaRouterConfig> = {}
|
config: DeepPartial<SchemaRouterConfig> = {}
|
||||||
) {
|
) {
|
||||||
super({ prefix: '/' + tableToPathname(schema.table) });
|
super({ prefix: '/' + tableToPathname(schema.table) });
|
||||||
|
@ -187,7 +114,11 @@ export default class SchemaRouter<
|
||||||
koaPagination(),
|
koaPagination(),
|
||||||
koaGuard({ response: schema.guard.array(), status: [200] }),
|
koaGuard({ response: schema.guard.array(), status: [200] }),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
const [count, entities] = await actions.get(ctx.pagination);
|
const { limit, offset } = ctx.pagination;
|
||||||
|
const [count, entities] = await Promise.all([
|
||||||
|
queries.findTotalNumber(),
|
||||||
|
queries.findAll(limit, offset),
|
||||||
|
]);
|
||||||
ctx.pagination.totalCount = count;
|
ctx.pagination.totalCount = count;
|
||||||
ctx.body = entities;
|
ctx.body = entities;
|
||||||
return next();
|
return next();
|
||||||
|
@ -199,13 +130,16 @@ export default class SchemaRouter<
|
||||||
this.post(
|
this.post(
|
||||||
'/',
|
'/',
|
||||||
koaGuard({
|
koaGuard({
|
||||||
// eslint-disable-next-line no-restricted-syntax -- `.omit()` doesn't play well for generic types
|
body: schema.createGuard.omit({ id: true }),
|
||||||
body: schema.createGuard.omit({ id: true }) as Guard<Omit<CreateSchema, 'id'>>,
|
|
||||||
response: schema.guard,
|
response: schema.guard,
|
||||||
status: [201],
|
status: [201],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
ctx.body = await actions.post(ctx.guard.body);
|
// eslint-disable-next-line no-restricted-syntax -- `.omit()` doesn't play well with generics
|
||||||
|
ctx.body = await queries.insert({
|
||||||
|
id: generateStandardId(),
|
||||||
|
...ctx.guard.body,
|
||||||
|
} as CreateSchema);
|
||||||
ctx.status = 201;
|
ctx.status = 201;
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
@ -221,7 +155,7 @@ export default class SchemaRouter<
|
||||||
status: [200, 404],
|
status: [200, 404],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
ctx.body = await actions.getById(ctx.guard.params.id);
|
ctx.body = await queries.findById(ctx.guard.params.id);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -237,7 +171,7 @@ export default class SchemaRouter<
|
||||||
status: [200, 404],
|
status: [200, 404],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
ctx.body = await actions.patchById(ctx.guard.params.id, ctx.guard.body);
|
ctx.body = await queries.updateById(ctx.guard.params.id, ctx.guard.body);
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -251,7 +185,7 @@ export default class SchemaRouter<
|
||||||
status: [204, 404],
|
status: [204, 404],
|
||||||
}),
|
}),
|
||||||
async (ctx, next) => {
|
async (ctx, next) => {
|
||||||
await actions.deleteById(ctx.guard.params.id);
|
await queries.deleteById(ctx.guard.params.id);
|
||||||
ctx.status = 204;
|
ctx.status = 204;
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
@ -315,7 +249,7 @@ export default class SchemaRouter<
|
||||||
const { id } = ctx.guard.params;
|
const { id } = ctx.guard.params;
|
||||||
|
|
||||||
// Ensure that the main entry exists
|
// Ensure that the main entry exists
|
||||||
await this.actions.getById(id);
|
await this.queries.findById(id);
|
||||||
|
|
||||||
const [totalCount, entities] = await relationQueries.getEntities(
|
const [totalCount, entities] = await relationQueries.getEntities(
|
||||||
relationSchema,
|
relationSchema,
|
||||||
|
|
Loading…
Add table
Reference in a new issue