Skip to content

Commit

Permalink
feat(code-gen): add support for transformContext with custom readab…
Browse files Browse the repository at this point in the history
…le types in CRUD

- Fixes checks around custom readable types in `T.crud()`
- Add `xxxTransformContext` as a hook. The returned `transformContext` is then passed to `xxxTransform`. This can be used to pass ctx based data to the transform function (like the base url).
- Fixes using the custom readable type in the create route
  • Loading branch information
dirkdev98 committed May 10, 2023
1 parent 4ecd95d commit 65979a0
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 27 deletions.
2 changes: 1 addition & 1 deletion packages/code-gen/src/builders/CrudType.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ export class CrudType extends TypeBuilder {
const { readable, writable } = fieldOptions;

if (readable instanceof TypeBuilder) {
if (!readable.data.name) {
if (!readable.data.name && !readable.data.reference?.name) {
throw AppError.serverError({
message:
"A custom readable type should have a name, e.g 'T.object('item').keys(...)'.",
Expand Down
6 changes: 0 additions & 6 deletions packages/code-gen/src/crud/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
crudPartialEventTransformer,
crudPartialEventUpdate,
} from "./partials/events.js";
import { crudQueryBuilderGet } from "./query-builder.js";

/**
* Generate events that are necessary for CRUD. This currently only works with js and Koa.
Expand Down Expand Up @@ -189,11 +188,6 @@ function crudEventsCreate(generateContext, file, crud) {
writableType: crudInformationGetWritableType(crud),

inlineRelations: crudEventsGetInlineRelations(crud),
builder: crudQueryBuilderGet(crud, {
includeOwnParam: false,
includeJoins: true,
traverseParents: false,
}),
};

// @ts-expect-error
Expand Down
19 changes: 16 additions & 3 deletions packages/code-gen/src/crud/handlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,19 @@ function crudHandlersGetModifiers(crud) {

if (crudInformationGetHasCustomReadableType(crud)) {
modifierDocs.push(
`${crudName}Transform: (entity: QueryResult${modelUniqueName}) => ${upperCaseFirst(
`${crudName}TransformContext?: (ctx: Context) => (any|Promise<any>),`,
);
modifierDocs.push(
`${crudName}Transform: (entity: QueryResult${modelUniqueName}, transformContext?: any) => ${upperCaseFirst(
// @ts-expect-error
crud.fieldOptions.readableType.reference.group,
)}${upperCaseFirst(
// @ts-expect-error
crud.fieldOptions.readableType.reference.name,
)},`,
);

modifierDestructure.push(`${crudName}TransformContext,`);
modifierDestructure.push(`${crudName}Transform,`);
}

Expand All @@ -150,8 +155,8 @@ function crudHandlersGetModifiers(crud) {

if (crud.routeOptions.createRoute) {
modifierDocs.push(
`${crudName}CreatePreModifier?: (event: InsightEvent, ctx: ${upperCrudName}CreateCtx ${
relation?.subType === "oneToMany"
`${crudName}CreatePreModifier?: (event: InsightEvent, ctx: ${upperCrudName}CreateCtx, builder: ${modelUniqueName}QueryBuilder${
relation?.subType !== "oneToOneReverse"
? ""
: `, singleBuilder: ${modelUniqueName}QueryBuilder`
}) => void|Promise<void>,`,
Expand Down Expand Up @@ -238,6 +243,7 @@ function crudHandlersList(generateContext, file, crud) {
crud,
"list",
)}`,
hasTransformContext: crudInformationGetHasCustomReadableType(crud),
crudName: crud.group + upperCaseFirst(crudInformationGetName(crud, "")),
countBuilder: crudQueryBuilderGet(crud, {
includeOwnParam: false,
Expand Down Expand Up @@ -290,6 +296,7 @@ function crudHandlersSingle(generateContext, file, crud) {
"single",
)}`,
crudName: crud.group + upperCaseFirst(crudInformationGetName(crud, "")),
hasTransformContext: crudInformationGetHasCustomReadableType(crud),
builder: crudQueryBuilderGet(crud, {
includeOwnParam: true,
includeJoins: true,
Expand Down Expand Up @@ -326,12 +333,18 @@ function crudHandlersCreate(generateContext, file, crud) {
"create",
)}`,
crudName: crud.group + upperCaseFirst(crudInformationGetName(crud, "")),
hasTransformContext: crudInformationGetHasCustomReadableType(crud),
applyParams: crud.fromParent
? {
bodyKey: relation.referencedKey,
paramsKey: crudInformationGetParamName(parent),
}
: undefined,
builder: crudQueryBuilderGet(crud, {
includeOwnParam: false,
includeJoins: true,
traverseParents: false,
}),
oneToOneChecks:
relation?.subType === "oneToOneReverse"
? {
Expand Down
1 change: 0 additions & 1 deletion packages/code-gen/src/crud/partials/events.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ export function crudPartialEventCreate(data: {
crudName: string;
entityUniqueName: string;
entityName: string;
builder: string;
primaryKey: string;
writableType: {
group: string;
Expand Down
5 changes: 2 additions & 3 deletions packages/code-gen/src/crud/partials/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ export async function ${data.crudName}Single(event, sql, builder) {
* crudName: string,
* entityUniqueName: string,
* entityName: string,
* builder: string,
* primaryKey: string,
* writableType: { group: string, name: string },
* inlineRelations: {
Expand All @@ -137,9 +136,10 @@ export const crudPartialEventCreate = (data) => `
* @param {${upperCaseFirst(data.writableType.group)}${upperCaseFirst(
data.writableType.name,
)}} body
* @param {${data.entityUniqueName}QueryBuilder} builder
* @returns {Promise<QueryResult${data.entityUniqueName}>}
*/
export async function ${data.crudName}Create(event, sql, body) {
export async function ${data.crudName}Create(event, sql, body, builder) {
eventStart(event, "${data.crudName}.create");
${partialAsString(
Expand All @@ -156,7 +156,6 @@ export async function ${data.crudName}Create(event, sql, body) {
${crudPartialInlineRelationInserts(data.inlineRelations, "result")}
const builder = ${data.builder};
builder.where.${data.primaryKey} = result[0].${data.primaryKey};
const _item = await ${
data.crudName
Expand Down
4 changes: 4 additions & 0 deletions packages/code-gen/src/crud/partials/routes.d.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
export function crudPartialRouteList(data: {
handlerName: string;
crudName: string;
hasTransformContext: boolean;
countBuilder: string;
listBuilder: string;
primaryKey: string;
}): string;
export function crudPartialRouteSingle(data: {
handlerName: string;
hasTransformContext: boolean;
crudName: string;
builder: string;
}): string;
export function crudPartialRouteCreate(data: {
handlerName: string;
crudName: string;
hasTransformContext: boolean;
builder: string;
applyParams?: {
bodyKey: string;
paramsKey: string;
Expand Down
65 changes: 52 additions & 13 deletions packages/code-gen/src/crud/partials/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* @param {{
* handlerName: string,
* crudName: string,
* hasTransformContext: boolean,
* countBuilder: string,
* listBuilder: string,
* primaryKey: string,
Expand All @@ -19,24 +20,39 @@ ${data.handlerName} = async (ctx) => {
const listBuilder = ${data.listBuilder};
${data.crudName}ListPreModifier && await ${data.crudName}ListPreModifier(newEventFromEvent(ctx.event), ctx, countBuilder, listBuilder);
${data.crudName}ListPreModifier && await ${
data.crudName
}ListPreModifier(newEventFromEvent(ctx.event), ctx, countBuilder, listBuilder);
const { total, ${data.primaryKey}In } = await ${data.crudName}Count(newEventFromEvent(ctx.event), sql, countBuilder, ctx.validatedQuery);
const { total, ${data.primaryKey}In } = await ${
data.crudName
}Count(newEventFromEvent(ctx.event), sql, countBuilder, ctx.validatedQuery);
listBuilder.where.${data.primaryKey}In = ${data.primaryKey}In;
const result = await ${data.crudName}List(newEventFromEvent(ctx.event), sql, listBuilder);
const result = await ${
data.crudName
}List(newEventFromEvent(ctx.event), sql, listBuilder);
${
data.hasTransformContext
? `const transformContext = ${data.crudName}TransformContext ? await ${data.crudName}TransformContext(ctx) : undefined;`
: ""
}
ctx.body = {
total,
list: result.map(it => ${data.crudName}Transform(it)),
list: result.map(it => ${data.crudName}Transform(it${
data.hasTransformContext ? ", transformContext" : ""
})),
};
};
`;

/**
* @param {{
* handlerName: string,
* hasTransformContext: boolean,
* crudName: string,
* builder: string,
* }} data
Expand All @@ -46,13 +62,25 @@ export const crudPartialRouteSingle = (data) => `
${data.handlerName} = async (ctx) => {
const builder = ${data.builder};
${data.crudName}SinglePreModifier && await ${data.crudName}SinglePreModifier(newEventFromEvent(ctx.event), ctx, builder);
${data.crudName}SinglePreModifier && await ${
data.crudName
}SinglePreModifier(newEventFromEvent(ctx.event), ctx, builder);
const item = await ${data.crudName}Single(newEventFromEvent(ctx.event), sql, builder);
const item = await ${
data.crudName
}Single(newEventFromEvent(ctx.event), sql, builder);
${
data.hasTransformContext
? `const transformContext = ${data.crudName}TransformContext ? await ${data.crudName}TransformContext(ctx) : undefined;`
: ""
}
ctx.body = {
item: ${data.crudName}Transform(item),
item: ${data.crudName}Transform(item${
data.hasTransformContext ? ", transformContext" : ""
}),
};
};
`;
Expand All @@ -61,6 +89,8 @@ ${data.handlerName} = async (ctx) => {
* @param {{
* handlerName: string,
* crudName: string,
* hasTransformContext: boolean,
* builder: string,
* applyParams?: {
* bodyKey: string,
* paramsKey: string,
Expand All @@ -73,15 +103,16 @@ ${data.handlerName} = async (ctx) => {
*/
export const crudPartialRouteCreate = (data) => `
${data.handlerName} = async (ctx) => {
const builder = ${data.builder};
${
data.oneToOneChecks
? `const builder = ${data.oneToOneChecks.builder};`
? `const oneToOneBuilder = ${data.oneToOneChecks.builder};`
: ``
}
${data.crudName}CreatePreModifier && await ${
data.crudName
}CreatePreModifier(newEventFromEvent(ctx.event), ctx ${
data.oneToOneChecks ? `, builder` : ""
}CreatePreModifier(newEventFromEvent(ctx.event), ctx, builder${
data.oneToOneChecks ? `, oneToOneBuilder` : ""
});
${
Expand All @@ -93,7 +124,7 @@ ${data.handlerName} = async (ctx) => {
data.oneToOneChecks
? `
try {
const exists = await ${data.crudName}Single(newEventFromEvent(ctx.event), sql, builder);
const exists = await ${data.crudName}Single(newEventFromEvent(ctx.event), sql, oneToOneBuilder);
if (exists) {
throw AppError.validationError("${data.crudName}.create.alreadyExists");
}
Expand All @@ -108,10 +139,18 @@ ${data.handlerName} = async (ctx) => {
const item = await sql.begin(sql => ${
data.crudName
}Create(newEventFromEvent(ctx.event), sql, ctx.validatedBody));
}Create(newEventFromEvent(ctx.event), sql, ctx.validatedBody, builder));
${
data.hasTransformContext
? `const transformContext = ${data.crudName}TransformContext ? await ${data.crudName}TransformContext(ctx) : undefined;`
: ""
}
ctx.body = {
item: ${data.crudName}Transform(item),
item: ${data.crudName}Transform(item${
data.hasTransformContext ? ", transformContext" : ""
}),
};
};
`;
Expand Down

0 comments on commit 65979a0

Please sign in to comment.