@appswave/rq-codegen 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1279 -0
- package/dist/bin/cli.js +1788 -0
- package/dist/bin/cli.js.map +1 -0
- package/dist/index.d.ts +79 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
- package/templates/component-form/FormComponent.tsx.hbs +60 -0
- package/templates/component-form/index.ts.hbs +1 -0
- package/templates/component-shared/Component.tsx.hbs +37 -0
- package/templates/component-shared/index.ts.hbs +1 -0
- package/templates/component-ui/Component.tsx.hbs +41 -0
- package/templates/component-ui/index.ts.hbs +1 -0
- package/templates/handler/handler.ts.hbs +80 -0
- package/templates/mutation-hook/hook.ts.hbs +53 -0
- package/templates/page/Page.tsx.hbs +7 -0
- package/templates/query-hook/hook-details.ts.hbs +12 -0
- package/templates/query-hook/hook-paginated.ts.hbs +12 -0
- package/templates/query-hook/hook.ts.hbs +12 -0
- package/templates/shared-hook/hook.ts.hbs +9 -0
- package/templates/types-dto/dto.ts.hbs +40 -0
- package/templates/validation/validation.ts.hbs +22 -0
- package/templates/view/View.tsx.hbs +13 -0
- package/templates/view/index.ts.hbs +1 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ApiEndpoints, HttpClient } from '{{configAlias "api"}}/config';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
{{pascalCase name}}{{dtoSuffix "read"}},
|
|
5
|
+
{{#if (includes operations "list")}}
|
|
6
|
+
{{pascalCase name}}{{dtoSuffix "listResponse"}},
|
|
7
|
+
{{/if}}
|
|
8
|
+
{{#if (includes operations "create")}}
|
|
9
|
+
{{pascalCase name}}{{dtoSuffix "create"}},
|
|
10
|
+
{{/if}}
|
|
11
|
+
{{#if (includes operations "update")}}
|
|
12
|
+
{{pascalCase name}}{{dtoSuffix "update"}},
|
|
13
|
+
{{/if}}
|
|
14
|
+
} from '{{configAlias "types"}}';
|
|
15
|
+
|
|
16
|
+
const URL = ApiEndpoints.{{constantCase endpointKey}};
|
|
17
|
+
|
|
18
|
+
{{#if (includes operations "list")}}
|
|
19
|
+
function get{{pascalCase name}}List(queryString?: string): Promise<{{pascalCase name}}{{dtoSuffix "listResponse"}}> {
|
|
20
|
+
const url = queryString ? `${URL.INDEX}?${queryString}` : URL.INDEX;
|
|
21
|
+
return HttpClient.get<{{pascalCase name}}{{dtoSuffix "listResponse"}}>(url);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
{{/if}}
|
|
25
|
+
{{#if (includes operations "details")}}
|
|
26
|
+
function get{{pascalCase name}}Details(id: string): Promise<{{pascalCase name}}{{dtoSuffix "read"}}> {
|
|
27
|
+
return HttpClient.get<{{pascalCase name}}{{dtoSuffix "read"}}>(URL.DETAILS.replace(':id', id));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
{{/if}}
|
|
31
|
+
{{#if (includes operations "create")}}
|
|
32
|
+
function create{{pascalCase name}}(payload: {{pascalCase name}}{{dtoSuffix "create"}}): Promise<{{pascalCase name}}{{dtoSuffix "read"}}> {
|
|
33
|
+
return HttpClient.post<{{pascalCase name}}{{dtoSuffix "read"}}>(URL.INDEX, payload);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
{{/if}}
|
|
37
|
+
{{#if (includes operations "update")}}
|
|
38
|
+
function update{{pascalCase name}}(id: string, payload: {{pascalCase name}}{{dtoSuffix "update"}}): Promise<{{pascalCase name}}{{dtoSuffix "read"}}> {
|
|
39
|
+
return HttpClient.put<{{pascalCase name}}{{dtoSuffix "read"}}>(URL.DETAILS.replace(':id', id), payload);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
{{/if}}
|
|
43
|
+
{{#if (includes operations "delete")}}
|
|
44
|
+
function remove{{pascalCase name}}(id: string): Promise<void> {
|
|
45
|
+
return HttpClient.delete<void>(URL.DETAILS.replace(':id', id));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
{{/if}}
|
|
49
|
+
export const {{pascalCase name}}Handler = {
|
|
50
|
+
{{#if (includes operations "list")}}
|
|
51
|
+
list: {
|
|
52
|
+
queryKey: '{{kebabCase name}}/list',
|
|
53
|
+
request: get{{pascalCase name}}List,
|
|
54
|
+
},
|
|
55
|
+
{{/if}}
|
|
56
|
+
{{#if (includes operations "details")}}
|
|
57
|
+
details: {
|
|
58
|
+
queryKey: '{{kebabCase name}}/details',
|
|
59
|
+
request: get{{pascalCase name}}Details,
|
|
60
|
+
},
|
|
61
|
+
{{/if}}
|
|
62
|
+
{{#if (includes operations "create")}}
|
|
63
|
+
create: {
|
|
64
|
+
mutationKey: '{{kebabCase name}}/create',
|
|
65
|
+
mutationFn: create{{pascalCase name}},
|
|
66
|
+
},
|
|
67
|
+
{{/if}}
|
|
68
|
+
{{#if (includes operations "update")}}
|
|
69
|
+
update: {
|
|
70
|
+
mutationKey: '{{kebabCase name}}/update',
|
|
71
|
+
mutationFn: update{{pascalCase name}},
|
|
72
|
+
},
|
|
73
|
+
{{/if}}
|
|
74
|
+
{{#if (includes operations "delete")}}
|
|
75
|
+
remove: {
|
|
76
|
+
mutationKey: '{{kebabCase name}}/remove',
|
|
77
|
+
mutationFn: remove{{pascalCase name}},
|
|
78
|
+
},
|
|
79
|
+
{{/if}}
|
|
80
|
+
} as const;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { {{pascalCase handlerName}}Handler } from '{{configAlias "api"}}/handlers';
|
|
2
|
+
{{#ifFeature "toast"}}
|
|
3
|
+
import { {{config.hooks.toast.import}} } from '{{config.hooks.toast.from}}';
|
|
4
|
+
{{/ifFeature}}
|
|
5
|
+
{{#ifFeature "i18n"}}
|
|
6
|
+
import { {{config.hooks.translation.import}} } from '{{config.hooks.translation.from}}';
|
|
7
|
+
{{/ifFeature}}
|
|
8
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
9
|
+
|
|
10
|
+
export const use{{pascalCase mutationName}}Mutation = () => {
|
|
11
|
+
const queryClient = useQueryClient();
|
|
12
|
+
{{#ifFeature "toast"}}
|
|
13
|
+
const { toast } = {{config.hooks.toast.import}}();
|
|
14
|
+
{{/ifFeature}}
|
|
15
|
+
{{#ifFeature "i18n"}}
|
|
16
|
+
const { t } = {{config.hooks.translation.import}}();
|
|
17
|
+
{{/ifFeature}}
|
|
18
|
+
|
|
19
|
+
return useMutation({
|
|
20
|
+
mutationKey: [{{pascalCase handlerName}}Handler.{{handlerKey}}.mutationKey],
|
|
21
|
+
mutationFn: {{pascalCase handlerName}}Handler.{{handlerKey}}.mutationFn,
|
|
22
|
+
onSuccess: () => {
|
|
23
|
+
queryClient.invalidateQueries({
|
|
24
|
+
queryKey: [{{pascalCase handlerName}}Handler.{{invalidateKey}}.queryKey],
|
|
25
|
+
});
|
|
26
|
+
{{#ifFeature "toast"}}
|
|
27
|
+
toast({
|
|
28
|
+
variant: 'success',
|
|
29
|
+
{{#ifFeature "i18n"}}
|
|
30
|
+
title: t('common.success'),
|
|
31
|
+
{{else}}
|
|
32
|
+
title: 'Success',
|
|
33
|
+
{{/ifFeature}}
|
|
34
|
+
});
|
|
35
|
+
{{/ifFeature}}
|
|
36
|
+
},
|
|
37
|
+
onError: (error: { response: { data: { title: string; message?: string; detail: string } } }) => {
|
|
38
|
+
{{#ifFeature "toast"}}
|
|
39
|
+
const errorMessage =
|
|
40
|
+
{{#ifFeature "i18n"}}
|
|
41
|
+
error?.response?.data?.title || error?.response?.data?.message || t('errors.unexpectedError');
|
|
42
|
+
{{else}}
|
|
43
|
+
error?.response?.data?.title || error?.response?.data?.message || 'An unexpected error occurred';
|
|
44
|
+
{{/ifFeature}}
|
|
45
|
+
toast({
|
|
46
|
+
variant: 'destructive',
|
|
47
|
+
title: errorMessage,
|
|
48
|
+
description: error?.response?.data?.detail || '',
|
|
49
|
+
});
|
|
50
|
+
{{/ifFeature}}
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { {{pascalCase handlerName}}Handler } from '{{configAlias "api"}}/handlers';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
|
|
4
|
+
export const use{{pascalCase hookName}}Query = (id: string | undefined, enabled = true) => {
|
|
5
|
+
return useQuery({
|
|
6
|
+
queryKey: [{{pascalCase handlerName}}Handler.{{handlerKey}}.queryKey, id],
|
|
7
|
+
queryFn: () => {{pascalCase handlerName}}Handler.{{handlerKey}}.request(id!),
|
|
8
|
+
enabled: enabled && !!id,
|
|
9
|
+
staleTime: 5 * 60 * 1000,
|
|
10
|
+
gcTime: 10 * 60 * 1000,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { {{pascalCase handlerName}}Handler } from '{{configAlias "api"}}/handlers';
|
|
2
|
+
import { {{config.hooks.paginatedQuery.import}} } from '{{config.hooks.paginatedQuery.from}}';
|
|
3
|
+
|
|
4
|
+
import type { {{pascalCase handlerName}}{{dtoSuffix "list"}} } from '{{configAlias "types"}}';
|
|
5
|
+
|
|
6
|
+
export const use{{pascalCase hookName}}Query = () => {
|
|
7
|
+
return {{config.hooks.paginatedQuery.import}}<{{pascalCase handlerName}}{{dtoSuffix "list"}}>({
|
|
8
|
+
queryKey: [{{pascalCase handlerName}}Handler.{{handlerKey}}.queryKey],
|
|
9
|
+
queryFn: (params: string) => {{pascalCase handlerName}}Handler.{{handlerKey}}.request(params),
|
|
10
|
+
defaultPageSize: 10,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { {{pascalCase handlerName}}Handler } from '{{configAlias "api"}}/handlers';
|
|
2
|
+
import { useQuery } from '@tanstack/react-query';
|
|
3
|
+
|
|
4
|
+
export const use{{pascalCase hookName}}Query = (enabled = true) => {
|
|
5
|
+
return useQuery({
|
|
6
|
+
queryKey: [{{pascalCase handlerName}}Handler.{{handlerKey}}.queryKey],
|
|
7
|
+
queryFn: () => {{pascalCase handlerName}}Handler.{{handlerKey}}.request(),
|
|
8
|
+
enabled,
|
|
9
|
+
staleTime: 5 * 60 * 1000,
|
|
10
|
+
gcTime: 10 * 60 * 1000,
|
|
11
|
+
});
|
|
12
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type {{pascalCase name}}{{dtoSuffix "read"}} = {
|
|
2
|
+
id: number;
|
|
3
|
+
// TODO: Add read fields
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
{{#if includeCreateDto}}
|
|
7
|
+
export type {{pascalCase name}}{{dtoSuffix "create"}} = {
|
|
8
|
+
// TODO: Add create fields
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
{{/if}}
|
|
12
|
+
{{#if includeUpdateDto}}
|
|
13
|
+
export type {{pascalCase name}}{{dtoSuffix "update"}} = {
|
|
14
|
+
id: number;
|
|
15
|
+
// TODO: Add update fields
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
{{/if}}
|
|
19
|
+
export type {{pascalCase name}}{{dtoSuffix "list"}} = {
|
|
20
|
+
id: number;
|
|
21
|
+
// TODO: Add minimal list fields
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type {{pascalCase name}}{{dtoSuffix "listResponse"}} = {
|
|
25
|
+
items: {{pascalCase name}}{{dtoSuffix "list"}}[];
|
|
26
|
+
page: number;
|
|
27
|
+
pageSize: number;
|
|
28
|
+
totalCount: number;
|
|
29
|
+
lastPage: number;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
{{#if includeParamsDto}}
|
|
33
|
+
export type {{pascalCase name}}{{dtoSuffix "params"}} = {
|
|
34
|
+
page?: number;
|
|
35
|
+
pageSize?: number;
|
|
36
|
+
search?: string;
|
|
37
|
+
sort?: string;
|
|
38
|
+
filter?: string;
|
|
39
|
+
};
|
|
40
|
+
{{/if}}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
{{#ifFeature "i18n"}}
|
|
3
|
+
import type { TFunction } from 'i18next';
|
|
4
|
+
|
|
5
|
+
export const {{camelCase name}}Schema = (t: TFunction) =>
|
|
6
|
+
z.object({
|
|
7
|
+
// TODO: Add validation fields
|
|
8
|
+
// Example:
|
|
9
|
+
// name: z.string().min(1, t('validation.{{camelCase name}}.name.required')),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type {{pascalCase name}}FormData = z.infer<ReturnType<typeof {{camelCase name}}Schema>>;
|
|
13
|
+
{{else}}
|
|
14
|
+
|
|
15
|
+
export const {{camelCase name}}Schema = z.object({
|
|
16
|
+
// TODO: Add validation fields
|
|
17
|
+
// Example:
|
|
18
|
+
// name: z.string().min(1, 'Name is required'),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export type {{pascalCase name}}FormData = z.infer<typeof {{camelCase name}}Schema>;
|
|
22
|
+
{{/ifFeature}}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { cn } from '{{configAlias "utils"}}';
|
|
2
|
+
|
|
3
|
+
type {{pascalCase name}}Props = {
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export default function {{pascalCase name}}({ className }: {{pascalCase name}}Props) {
|
|
8
|
+
return (
|
|
9
|
+
<div className={cn('', className)}>
|
|
10
|
+
<h2>{{pascalCase name}}</h2>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as {{pascalCase name}} } from './{{pascalCase name}}';
|