Skip to content

Commit ba1718b

Browse files
committed
fix(cli): recourse generation and schema types
1 parent ef99970 commit ba1718b

10 files changed

Lines changed: 129 additions & 74 deletions

File tree

.github/workflows/cli.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CLI tests
2+
on:
3+
push:
4+
branches: [main]
5+
pull_request:
6+
branches: [main]
7+
jobs:
8+
test:
9+
timeout-minutes: 60
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Check out frontend
13+
uses: actions/checkout@v4
14+
- uses: actions/setup-node@v4
15+
with:
16+
node-version: 22
17+
- name: Install dependencies
18+
run: npm ci
19+
- name: Generate resources and fields
20+
run: npm run generate:resource -- --name=Department
21+
- run: npm run generate:resource -- --name=People
22+
- run: npm run generate:field -- --name=Department --property=name --kind=primitive --type=string --isOptional=false --isShowInTable=true
23+
- run: npm run generate:field -- --name=People --property=profilePicture --kind=reference --type=File --isOptional=true --isShowInTable=true
24+
- run: npm run generate:field -- --name=People --property=firstName --kind=primitive --type=string --isOptional=false --isShowInTable=true
25+
- run: npm run generate:field -- --name=People --property=lastName --kind=primitive --type=string --isOptional=false --isShowInTable=true
26+
- run: npm run generate:field -- --name=People --property=department --kind=reference --referenceType=toOne --type=Department --isOptional=true --isShowInTable=true --propertyForSelect=name
27+
- run: npm run generate:field -- --name=People --property=isActive --kind=primitive --type=boolean --isOptional=false --isShowInTable=true
28+
- run: npm run generate:field -- --name=People --property=birthDate --kind=primitive --type=Date --isOptional=true --isShowInTable=true
29+
- run: npm run generate:field -- --name=People --property=hireDate --kind=primitive --type=Date --isOptional=false --isShowInTable=true
30+
- run: npm run generate:field -- --name=People --property=salary --kind=primitive --type=number --isOptional=false --isShowInTable=true
31+
- name: Build
32+
run: npm run build

.github/workflows/e2e.yml

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,52 @@
11
name: E2E tests
22
on:
33
push:
4-
branches: [ main ]
4+
branches: [main]
55
pull_request:
6-
branches: [ main ]
6+
branches: [main]
77
jobs:
88
test:
99
timeout-minutes: 60
1010
runs-on: ubuntu-latest
1111
steps:
12-
- name: Check out backend
13-
uses: actions/checkout@v4
14-
with:
15-
repository: brocoders/nestjs-boilerplate
16-
# Use token for private repository
17-
# token: ${{ secrets.CI_PAT }}
18-
path: backend
19-
- run: cd backend && cp env-example-document .env
20-
- run: cd backend && sed -i 's/APP_PORT=3000/APP_PORT=3001/g' .env
21-
- run: cd backend && sed -i 's/BACKEND_DOMAIN=http:\/\/localhost:3000/BACKEND_DOMAIN=http:\/\/localhost:3001/g' .env
22-
- name: Run backend
23-
# print output of the command to file and store it as artifact
24-
run: cd backend && docker compose -f docker-compose.document.yaml up > ${{ runner.temp }}/backend.log 2>&1 &
25-
- run: cd backend && sed -i 's/\r//g' wait-for-it.sh
26-
- run: cd backend && ./wait-for-it.sh localhost:3001 -- echo "Backend is up"
12+
- name: Check out backend
13+
uses: actions/checkout@v4
14+
with:
15+
repository: brocoders/nestjs-boilerplate
16+
# Use token for private repository
17+
# token: ${{ secrets.CI_PAT }}
18+
path: backend
19+
- run: cd backend && cp env-example-document .env
20+
- run: cd backend && sed -i 's/APP_PORT=3000/APP_PORT=3001/g' .env
21+
- run: cd backend && sed -i 's/BACKEND_DOMAIN=http:\/\/localhost:3000/BACKEND_DOMAIN=http:\/\/localhost:3001/g' .env
22+
- name: Run backend
23+
# print output of the command to file and store it as artifact
24+
run: cd backend && docker compose -f docker-compose.document.yaml up > ${{ runner.temp }}/backend.log 2>&1 &
25+
- run: cd backend && sed -i 's/\r//g' wait-for-it.sh
26+
- run: cd backend && ./wait-for-it.sh localhost:3001 -- echo "Backend is up"
2727

28-
- uses: actions/checkout@v4
29-
- uses: actions/setup-node@v4
30-
with:
31-
node-version: 22
32-
- name: Install dependencies
33-
run: npm ci
34-
- name: Run lint
35-
run: npm run lint
36-
- name: Install Playwright Browsers
37-
run: npx playwright install --with-deps
38-
- name: Run Playwright tests
39-
run: npx playwright test
40-
- uses: actions/upload-artifact@v4
41-
if: ${{ !cancelled() }}
42-
with:
43-
name: playwright-report
44-
path: playwright-report/
45-
retention-days: 30
46-
- uses: actions/upload-artifact@v4
47-
if: ${{ !cancelled() }}
48-
with:
49-
name: backend-log
50-
path: ${{ runner.temp }}/backend.log
51-
retention-days: 30
28+
- name: Check out frontend
29+
uses: actions/checkout@v4
30+
- uses: actions/setup-node@v4
31+
with:
32+
node-version: 22
33+
- name: Install dependencies
34+
run: npm ci
35+
- name: Run lint
36+
run: npm run lint
37+
- name: Install Playwright Browsers
38+
run: npx playwright install --with-deps
39+
- name: Run Playwright tests
40+
run: npx playwright test
41+
- uses: actions/upload-artifact@v4
42+
if: ${{ !cancelled() }}
43+
with:
44+
name: playwright-report
45+
path: playwright-report/
46+
retention-days: 30
47+
- uses: actions/upload-artifact@v4
48+
if: ${{ !cancelled() }}
49+
with:
50+
name: backend-log
51+
path: ${{ runner.temp }}/backend.log
52+
retention-days: 30

.hygen/generate/field/create/field-property-type.ejs.t

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ after: type CreateFormData
66

77
<% if (kind === 'primitive') { -%>
88
<% if (type === 'string') { -%>
9-
<%= property %><% if (isOptional) { -%>?<% } -%>: string;
9+
<%= property %>: string;
1010
<% } else if (type === 'number') { -%>
11-
<%= property %><% if (isOptional) { -%>?<% } -%>: string;
11+
<%= property %>: string;
1212
<% } else if (type === 'boolean') { -%>
13-
<%= property %><% if (isOptional) { -%>?<% } -%>: boolean;
13+
<%= property %>: boolean;
1414
<% } else if (type === 'Date') { -%>
15-
<%= property %><% if (isOptional) { -%>?<% } -%>: Date | null;
15+
<%= property %>: Date | null;
1616
<% } -%>
1717
<% } else if (kind === 'reference') { -%>
1818
<% if (referenceType === 'toMany') { -%>
@@ -23,9 +23,9 @@ after: type CreateFormData
2323
<% } -%>
2424
<% } else { -%>
2525
<% if (type === 'File') { -%>
26-
<%= property %><% if (isOptional) { -%>?<% } -%>: FileEntity | null;
26+
<%= property %>: FileEntity | null;
2727
<% } else { -%>
28-
<%= property %><% if (isOptional) { -%>?<% } -%>: <%= type %> | null;
28+
<%= property %>: <%= type %> | null;
2929
<% } -%>
3030
<% } -%>
3131
<% } -%>

.hygen/generate/field/create/field-property-validation.ejs.t

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,31 @@ before: \<create\-form\-validation\-schema \/\>
1010
.string()
1111
<% if (!isOptional) { -%>
1212
.required(t("inputs.<%= property %>.validation.required"))
13+
<% } else { -%>
14+
.defined()
1315
<% } -%>
1416
,
1517
<% } else if (type === 'number') { -%>
1618
<%= property %>: yup
1719
.string()
1820
<% if (!isOptional) { -%>
1921
.required(t("inputs.<%= property %>.validation.required"))
22+
<% } else { -%>
23+
.defined()
2024
<% } -%>
2125
,
2226
<% } else if (type === 'boolean') { -%>
23-
<%= property %>: yup.boolean(),
27+
<%= property %>: yup.boolean().defined(),
2428
<% } else if (type === 'Date') { -%>
2529
<%= property %>: yup
2630
.date()
2731
<% if (!isOptional) { -%>
2832
.required(t("inputs.<%= property %>.validation.required"))
2933
<% } -%>
30-
.nullable(),
34+
.nullable()
35+
<% if (isOptional) { -%>
36+
.defined()
37+
<% } -%>,
3138
<% } -%>
3239
<% } else if (kind === 'reference') { -%>
3340
<% if (referenceType === 'toMany') { -%>
@@ -57,6 +64,9 @@ before: \<create\-form\-validation\-schema \/\>
5764
<% if (!isOptional) { -%>
5865
.required(t("inputs.<%= property %>.validation.required"))
5966
<% } -%>
60-
.nullable(),
67+
.nullable()
68+
<% if (isOptional) { -%>
69+
.defined()
70+
<% } -%>,
6171
<% } -%>
6272
<% } -%>

.hygen/generate/field/edit/field-property-type.ejs.t

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ after: type EditFormData
66

77
<% if (kind === 'primitive') { -%>
88
<% if (type === 'string') { -%>
9-
<%= property %><% if (isOptional) { -%>?<% } -%>: string;
9+
<%= property %>: string;
1010
<% } else if (type === 'number') { -%>
11-
<%= property %><% if (isOptional) { -%>?<% } -%>: string;
11+
<%= property %>: string;
1212
<% } else if (type === 'boolean') { -%>
13-
<%= property %><% if (isOptional) { -%>?<% } -%>: boolean;
13+
<%= property %>: boolean;
1414
<% } else if (type === 'Date') { -%>
15-
<%= property %><% if (isOptional) { -%>?<% } -%>: Date | null;
15+
<%= property %>: Date | null;
1616
<% } -%>
1717
<% } else if (kind === 'reference') { -%>
1818
<% if (referenceType === 'toMany') { -%>
@@ -23,9 +23,9 @@ after: type EditFormData
2323
<% } -%>
2424
<% } else { -%>
2525
<% if (type === 'File') { -%>
26-
<%= property %><% if (isOptional) { -%>?<% } -%>: FileEntity | null;
26+
<%= property %>: FileEntity | null;
2727
<% } else { -%>
28-
<%= property %><% if (isOptional) { -%>?<% } -%>: <%= type %> | null;
28+
<%= property %>: <%= type %> | null;
2929
<% } -%>
3030
<% } -%>
3131
<% } -%>

.hygen/generate/field/edit/field-property-validation.ejs.t

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,31 @@ before: \<edit\-form\-validation\-schema \/\>
1010
.string()
1111
<% if (!isOptional) { -%>
1212
.required(t("inputs.<%= property %>.validation.required"))
13+
<% } else { -%>
14+
.defined()
1315
<% } -%>
1416
,
1517
<% } else if (type === 'number') { -%>
1618
<%= property %>: yup
1719
.string()
1820
<% if (!isOptional) { -%>
1921
.required(t("inputs.<%= property %>.validation.required"))
22+
<% } else { -%>
23+
.defined()
2024
<% } -%>
2125
,
2226
<% } else if (type === 'boolean') { -%>
23-
<%= property %>: yup.boolean(),
27+
<%= property %>: yup.boolean().defined(),
2428
<% } else if (type === 'Date') { -%>
2529
<%= property %>: yup
2630
.date()
2731
<% if (!isOptional) { -%>
2832
.required(t("inputs.<%= property %>.validation.required"))
2933
<% } -%>
30-
.nullable(),
34+
.nullable()
35+
<% if (isOptional) { -%>
36+
.defined()
37+
<% } -%>,
3138
<% } -%>
3239
<% } else if (kind === 'reference') { -%>
3340
<% if (referenceType === 'toMany') { -%>
@@ -57,6 +64,9 @@ before: \<edit\-form\-validation\-schema \/\>
5764
<% if (!isOptional) { -%>
5865
.required(t("inputs.<%= property %>.validation.required"))
5966
<% } -%>
60-
.nullable(),
67+
.nullable()
68+
<% if (isOptional) { -%>
69+
.defined()
70+
<% } -%>,
6171
<% } -%>
6272
<% } -%>

.hygen/generate/resource/api-service.ejs.t

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,26 @@ import { InfinityPaginationType } from "../types/infinity-pagination";
99
import { RequestConfigType } from "./types/request-config";
1010
import { <%= name %> as Entity } from "../types/<%= h.inflection.transform(name, ['underscore', 'dasherize']) %>";
1111

12-
export type Get<%= h.inflection.transform(name, ['pluralize']) %>Request = {
12+
export type Get<%= h.inflection.transform(name, ['pluralize']) %>ListRequest = {
1313
page: number;
1414
limit: number;
1515
};
1616

17-
export type Get<%= h.inflection.transform(name, ['pluralize']) %>Response = InfinityPaginationType<Entity>;
17+
export type Get<%= h.inflection.transform(name, ['pluralize']) %>ListResponse = InfinityPaginationType<Entity>;
1818

19-
export function useGet<%= h.inflection.transform(name, ['pluralize']) %>Service() {
19+
export function useGet<%= h.inflection.transform(name, ['pluralize']) %>ListService() {
2020
const fetch = useFetch();
2121

2222
return useCallback(
23-
(data: Get<%= h.inflection.transform(name, ['pluralize']) %>Request, requestConfig?: RequestConfigType) => {
23+
(data: Get<%= h.inflection.transform(name, ['pluralize']) %>ListRequest, requestConfig?: RequestConfigType) => {
2424
const requestUrl = new URL(`${API_URL}/v1/<%= h.inflection.transform(name, ['pluralize', 'underscore', 'dasherize']) %>`);
2525
requestUrl.searchParams.append("page", data.page.toString());
2626
requestUrl.searchParams.append("limit", data.limit.toString());
2727

2828
return fetch(requestUrl, {
2929
method: "GET",
3030
...requestConfig,
31-
}).then(wrapperFetchJsonResponse<Get<%= h.inflection.transform(name, ['pluralize']) %>Response>);
31+
}).then(wrapperFetchJsonResponse<Get<%= h.inflection.transform(name, ['pluralize']) %>ListResponse>);
3232
},
3333
[fetch]
3434
);

.hygen/generate/resource/page-content.ejs.t

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Container from "@mui/material/Container";
1010
import Grid from "@mui/material/Grid";
1111
import Typography from "@mui/material/Typography";
1212
import { useCallback, useMemo, useRef, useState } from "react";
13-
import { useGet<%= h.inflection.transform(name, ['pluralize']) %>Query, <%= h.inflection.camelize(h.inflection.pluralize(name), true) %>QueryKeys } from "./queries/queries";
13+
import { useGet<%= h.inflection.transform(name, ['pluralize']) %>ListQuery, <%= h.inflection.camelize(h.inflection.pluralize(name), true) %>QueryKeys } from "./queries/queries";
1414
import { TableVirtuoso } from "react-virtuoso";
1515
import TableCell from "@mui/material/TableCell";
1616
import TableRow from "@mui/material/TableRow";
@@ -172,11 +172,11 @@ function Actions({ entityItem }: { entityItem: <%= name %> }) {
172172
);
173173
}
174174

175-
function <%= h.inflection.transform(name, ['pluralize']) %>() {
175+
function <%= h.inflection.transform(name, ['pluralize']) %>PageContent() {
176176
const { t } = useTranslation("admin-panel-<%= h.inflection.transform(name, ['pluralize', 'underscore', 'dasherize']) %>");
177177

178178
const { data, hasNextPage, isFetchingNextPage, fetchNextPage } =
179-
useGet<%= h.inflection.transform(name, ['pluralize']) %>Query();
179+
useGet<%= h.inflection.transform(name, ['pluralize']) %>ListQuery();
180180

181181
const handleScroll = useCallback(() => {
182182
if (!hasNextPage || isFetchingNextPage) return;
@@ -255,4 +255,4 @@ function <%= h.inflection.transform(name, ['pluralize']) %>() {
255255
);
256256
}
257257

258-
export default withPageRequiredAuth(<%= h.inflection.transform(name, ['pluralize']) %>, { roles: [RoleEnum.ADMIN] });
258+
export default withPageRequiredAuth(<%= h.inflection.transform(name, ['pluralize']) %>PageContent, { roles: [RoleEnum.ADMIN] });

.hygen/generate/resource/page.ejs.t

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
---
22
to: src/app/[language]/admin-panel/<%= h.inflection.transform(name, ['pluralize', 'underscore', 'dasherize']) %>/page.tsx
33
---
4+
"use server";
5+
46
import type { Metadata } from "next";
57
import { getServerTranslation } from "@/services/i18n";
6-
import <%= h.inflection.transform(name, ['pluralize']) %> from "./page-content";
8+
import <%= h.inflection.transform(name, ['pluralize']) %>PageContent from "./page-content";
79

810
type Props = {
911
params: Promise<{ language: string }>;
@@ -22,6 +24,6 @@ export async function generateMetadata(props: Props): Promise<Metadata> {
2224
};
2325
}
2426

25-
export default function Page() {
26-
return <<%= h.inflection.transform(name, ['pluralize']) %> />;
27+
export default async function Page() {
28+
return <<%= h.inflection.transform(name, ['pluralize']) %>PageContent />;
2729
}

.hygen/generate/resource/queries/queries.ejs.t

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
99
import {
1010
Get<%= name %>Request,
1111
useGet<%= name %>Service,
12-
useGet<%= h.inflection.transform(name, ['pluralize']) %>Service,
12+
useGet<%= h.inflection.transform(name, ['pluralize']) %>ListService,
1313
} from "@/services/api/services/<%= h.inflection.transform(name, ['pluralize', 'underscore', 'dasherize']) %>";
1414

1515
export const <%= h.inflection.camelize(h.inflection.pluralize(name), true) %>QueryKeys = createQueryKeys(["<%= h.inflection.transform(name, ['pluralize', 'underscore', 'dasherize']) %>"], {
@@ -21,8 +21,8 @@ export const <%= h.inflection.camelize(h.inflection.pluralize(name), true) %>Que
2121
}),
2222
});
2323

24-
export const useGet<%= h.inflection.transform(name, ['pluralize']) %>Query = () => {
25-
const fetch = useGet<%= h.inflection.transform(name, ['pluralize']) %>Service();
24+
export const useGet<%= h.inflection.transform(name, ['pluralize']) %>ListQuery = () => {
25+
const fetch = useGet<%= h.inflection.transform(name, ['pluralize']) %>ListService();
2626

2727
const query = useInfiniteQuery({
2828
queryKey: <%= h.inflection.camelize(h.inflection.pluralize(name), true) %>QueryKeys.list().key,

0 commit comments

Comments
 (0)