Refactor TypeScript RPC codebase and API structure
- Simplified error handling in `getFieldInfo` and `getFieldTsInfo` functions. - Removed unused `getSourceInfo` function and its references. - Updated `getStruct` method in `TSStruct` to eliminate source info retrieval. - Cleaned up `TSSouces` population logic by commenting out unnecessary debug statements. - Adjusted TypeScript source generation to use type imports instead of default imports. - Consolidated API endpoints into dedicated files for better organization (admin, systemUtils, users). - Introduced new types for API responses and requests to enhance type safety. - Removed redundant code and comments from generated API files. - Updated frontend components to reflect new API structure and types. - Ensured consistent naming conventions and type usage across the codebase.
This commit is contained in:
parent
3461395eb3
commit
b260daffed
|
|
@ -1,9 +1,10 @@
|
|||
import { api } from "./api.ts";
|
||||
import { Nullable } from "./apiTypes.ts";
|
||||
import * as users from "./users.ts";
|
||||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
import type * as users from "./users.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users; name=listUsers; method=POST; request=admin.ListUsersRequest; response=users.[]User
|
||||
// internal/admin/routes.go Line: 12
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/admin/routes.go Line: 13
|
||||
export const listUsers = async (
|
||||
data: ListUsersRequest,
|
||||
): Promise<{ data: users.User[]; error: Nullable<string> }> => {
|
||||
|
|
@ -14,7 +15,8 @@ export const listUsers = async (
|
|||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users/:uuid/block; name=blockUser; method=PUT; request=admin.BlockUserRequest; response=users.User
|
||||
// internal/admin/routes.go Line: 16
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/admin/routes.go Line: 17
|
||||
export const blockUser = async (
|
||||
data: BlockUserRequest,
|
||||
): Promise<{ data: users.User; error: Nullable<string> }> => {
|
||||
|
|
@ -24,11 +26,11 @@ export const blockUser = async (
|
|||
};
|
||||
};
|
||||
|
||||
export interface BlockUserRequest {
|
||||
action: string;
|
||||
}
|
||||
|
||||
export interface ListUsersRequest {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface BlockUserRequest {
|
||||
action: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
//
|
||||
// This file was generated by github.com/millevolte/ts-rpc
|
||||
//
|
||||
// Apr 14, 2026 21:39:07 UTC
|
||||
// Apr 26, 2026 14:23:26 UTC
|
||||
//
|
||||
|
||||
export interface ApiRestResponse {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// API Declarations
|
||||
export type Nullable<T> = T | null;
|
||||
|
||||
export type Record<K extends string | number | symbol, T> = { [P in K]: T };
|
||||
|
||||
export type Nullable<T> = T | null;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,22 @@
|
|||
import { api } from "./api.ts";
|
||||
import { Nullable } from "./apiTypes.ts";
|
||||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/health; name=health; method=GET; response=string
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/systemUtils/routes.go Line: 39
|
||||
export const health = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/health")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/metrics; name=metrics; method=GET; response=string
|
||||
// internal/systemUtils/routes.go Line: 41
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/systemUtils/routes.go Line: 42
|
||||
export const metrics = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
|
|
@ -14,7 +28,8 @@ export const metrics = async (): Promise<{
|
|||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/maildebug; name=mailDebug; method=GET; response=[]MailDebugItem
|
||||
// internal/systemUtils/routes.go Line: 53
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/systemUtils/routes.go Line: 54
|
||||
export const mailDebug = async (): Promise<{
|
||||
data: MailDebugItem[];
|
||||
error: Nullable<string>;
|
||||
|
|
@ -25,18 +40,6 @@ export const mailDebug = async (): Promise<{
|
|||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/health; name=health; method=GET; response=string
|
||||
// internal/systemUtils/routes.go Line: 38
|
||||
export const health = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/health")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface MailDebugItem {
|
||||
name: string;
|
||||
content: string;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { api } from "./api.ts";
|
||||
import { Nullable } from "./apiTypes.ts";
|
||||
import * as responses from "./responses.ts";
|
||||
import * as tokens from "./tokens.ts";
|
||||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
import type * as responses from "./responses.ts";
|
||||
import type * as tokens from "./tokens.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/refresh; name=refresh; method=POST; request=users.RefreshRequest; response=tokens.TokenPair
|
||||
// internal/user/routes.go Line: 46
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 47
|
||||
export const refresh = async (
|
||||
data: RefreshRequest,
|
||||
): Promise<{ data: tokens.TokenPair; error: Nullable<string> }> => {
|
||||
|
|
@ -14,61 +15,9 @@ export const refresh = async (
|
|||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/reset; name=resetPassword; method=POST; request=users.ResetPasswordRequest; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 55
|
||||
export const resetPassword = async (
|
||||
data: ResetPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/reset", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=getUser; method=GET; response=users.User
|
||||
// internal/user/routes.go Line: 27
|
||||
export const getUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.GET(`/users/${uuid}`)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/me; name=me; method=GET; response=users.User
|
||||
// internal/user/routes.go Line: 39
|
||||
export const me = async (): Promise<{
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/auth/me")) as { data: User; error: Nullable<string> };
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=users.UserCreateInput; response=users.User
|
||||
// internal/user/routes.go Line: 49
|
||||
export const register = async (
|
||||
data: UserCreateInput,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/register", data)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/forgot; name=forgotPassword; method=POST; request=users.ForgotPasswordRequest; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 52
|
||||
export const forgotPassword = async (
|
||||
data: ForgotPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/forgot", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=updateUser; method=PUT; request=users.UpdateUserRequest; response=users.User
|
||||
// internal/user/routes.go Line: 33
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 34
|
||||
export const updateUser = async (
|
||||
data: UpdateUserRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
|
|
@ -78,30 +27,43 @@ export const updateUser = async (
|
|||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=deleteUser; method=DELETE; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 36
|
||||
export const deleteUser = async (
|
||||
uuid: string,
|
||||
// Typescript: TSEndpoint= path=/auth/me; name=me; method=GET; response=users.User
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 40
|
||||
export const me = async (): Promise<{
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/auth/me")) as { data: User; error: Nullable<string> };
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/forgot; name=forgotPassword; method=POST; request=users.ForgotPasswordRequest; response=responses.SimpleResponse
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 53
|
||||
export const forgotPassword = async (
|
||||
data: ForgotPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.DELETE(`/users/${uuid}`)) as {
|
||||
return (await api.POST("/auth/password/forgot", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/login; name=login; method=POST; request=users.LoginRequest; response=tokens.TokenPair
|
||||
// internal/user/routes.go Line: 43
|
||||
export const login = async (
|
||||
data: LoginRequest,
|
||||
): Promise<{ data: tokens.TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/login", data)) as {
|
||||
data: tokens.TokenPair;
|
||||
// Typescript: TSEndpoint= path=/auth/password/reset; name=resetPassword; method=POST; request=users.ResetPasswordRequest; response=responses.SimpleResponse
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 56
|
||||
export const resetPassword = async (
|
||||
data: ResetPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/reset", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/valid; name=validToken; method=POST; request=string; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 58
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 59
|
||||
export const validToken = async (
|
||||
data: string,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
|
|
@ -111,10 +73,47 @@ export const validToken = async (
|
|||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=users.UserCreateInput; response=users.User
|
||||
// internal/user/routes.go Line: 30
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=deleteUser; method=DELETE; response=responses.SimpleResponse
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 37
|
||||
export const deleteUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.DELETE(`/users/${uuid}`)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=getUser; method=GET; response=users.User
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 28
|
||||
export const getUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.GET(`/users/${uuid}`)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 50
|
||||
export const register = async (
|
||||
data: UserCreateRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/register", data)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 31
|
||||
export const createUser = async (
|
||||
data: UserCreateInput,
|
||||
data: UserCreateRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.POST("/users", data)) as {
|
||||
data: User;
|
||||
|
|
@ -122,8 +121,28 @@ export const createUser = async (
|
|||
};
|
||||
};
|
||||
|
||||
export interface RefreshRequest {
|
||||
refresh_token: string;
|
||||
// Typescript: TSEndpoint= path=/auth/login; name=login; method=POST; request=users.LoginRequest; response=tokens.TokenPair
|
||||
|
||||
// /Users/fabio/CODE/omnimed/go-quasar-partial-ssr/backend/internal/user/routes.go Line: 44
|
||||
export const login = async (
|
||||
data: LoginRequest,
|
||||
): Promise<{ data: tokens.TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/login", data)) as {
|
||||
data: tokens.TokenPair;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface UpdateUserRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
types: UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
|
|
@ -142,16 +161,13 @@ export interface User {
|
|||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface UserCreateInput {
|
||||
name: string;
|
||||
export interface ForgotPasswordRequest {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordRequest {
|
||||
token: string;
|
||||
password: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
types: UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
|
|
@ -169,11 +185,7 @@ export interface UserPreferences {
|
|||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordRequest {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserRequest {
|
||||
export interface UserCreateRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
|
|
@ -201,37 +213,20 @@ export interface UserDetails {
|
|||
zipCode: string;
|
||||
country: string;
|
||||
phone: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
createdAt: Nullable<Date>;
|
||||
updatedAt: Nullable<Date>;
|
||||
}
|
||||
|
||||
export interface UserProfile {
|
||||
id: number;
|
||||
email: string;
|
||||
name: string;
|
||||
roles: UserRoles;
|
||||
types: UserTypes;
|
||||
status: UserStatus;
|
||||
activatedAt: Date;
|
||||
uuid: string;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
avatar: Nullable<string>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ResetPasswordRequest {
|
||||
token: string;
|
||||
password: string;
|
||||
export interface RefreshRequest {
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
export type UserRoles = string[];
|
||||
|
||||
export type UserTypes = string[];
|
||||
|
||||
export type UserStatus = (typeof EnumUserStatus)[keyof typeof EnumUserStatus];
|
||||
|
||||
export type UserTypes = string[];
|
||||
|
||||
export const EnumUserStatus = {
|
||||
UserStatusPending: "pending",
|
||||
UserStatusActive: "active",
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ require (
|
|||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
golang.org/x/crypto v0.48.0
|
||||
golang.org/x/crypto v0.50.0
|
||||
gorm.io/driver/postgres v1.6.0
|
||||
gorm.io/driver/sqlite v1.6.0
|
||||
gorm.io/gorm v1.31.1
|
||||
|
|
@ -45,9 +45,11 @@ require (
|
|||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.69.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
)
|
||||
|
|
|
|||
|
|
@ -101,15 +101,29 @@ go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
|||
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
|
|||
|
|
@ -106,7 +106,8 @@ func (ac *AdminController) BlockUser(c fiber.Ctx) error {
|
|||
default:
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid action")
|
||||
}
|
||||
u.UpdatedAt = time.Now().UTC()
|
||||
now := time.Now().UTC()
|
||||
u.UpdatedAt = &now
|
||||
|
||||
if err := db.Save(&u).Error; err != nil {
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "failed to update user status")
|
||||
|
|
|
|||
|
|
@ -73,8 +73,8 @@ func SeedUsers(db *gorm.DB, n int) ([]users.User, []Credential, error) {
|
|||
Language: gofakeit.Language(),
|
||||
},
|
||||
Avatar: nil,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
ActivatedAt: func() *time.Time {
|
||||
ts := now
|
||||
return &ts
|
||||
|
|
|
|||
|
|
@ -31,19 +31,6 @@ func NewUserController(tockenService *tokens.TockenService) *UserController {
|
|||
}
|
||||
}
|
||||
|
||||
// Typescript: interface
|
||||
type UpdateUserRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"omitempty,min=8,max=128"`
|
||||
Roles UserRoles `json:"roles"`
|
||||
Status UserStatus `json:"status"`
|
||||
Types UserTypes `json:"types"`
|
||||
Avatar *string `json:"avatar"`
|
||||
Details *UserDetails `json:"details"`
|
||||
Preferences *UserPreferences `json:"preferences"`
|
||||
}
|
||||
|
||||
// GetUser returns a single user by UUID.
|
||||
func (uc *UserController) GetUser(c fiber.Ctx) error {
|
||||
user, err := loadUserByUUID(c)
|
||||
|
|
@ -55,7 +42,7 @@ func (uc *UserController) GetUser(c fiber.Ctx) error {
|
|||
|
||||
// CreateUser creates a user together with optional details and preferences.
|
||||
func (uc *UserController) CreateUser(c fiber.Ctx) error {
|
||||
var req UserCreateInput
|
||||
var req UserCreateRequest
|
||||
if err := c.Bind().Body(&req); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid payload")
|
||||
}
|
||||
|
|
@ -107,8 +94,8 @@ func (uc *UserController) CreateUser(c fiber.Ctx) error {
|
|||
UUID: uuid.NewString(),
|
||||
Details: req.Details,
|
||||
Preferences: req.Preferences,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
}
|
||||
|
||||
if err := db.Create(&user).Error; err != nil {
|
||||
|
|
@ -155,7 +142,7 @@ func (uc *UserController) UpdateUser(c fiber.Ctx) error {
|
|||
user.Name = req.Name
|
||||
user.Email = req.Email
|
||||
user.Avatar = req.Avatar
|
||||
user.UpdatedAt = now
|
||||
user.UpdatedAt = &now
|
||||
if req.Status != "" {
|
||||
user.Status = req.Status
|
||||
}
|
||||
|
|
@ -277,7 +264,7 @@ func (uc *UserController) Login(c fiber.Ctx) error {
|
|||
|
||||
// Register creates a new user with optional roles/types/preferences.
|
||||
func (uc *UserController) Register(c fiber.Ctx) error {
|
||||
var req UserCreateInput
|
||||
var req UserCreateRequest
|
||||
if err := c.Bind().Body(&req); err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "invalid payload")
|
||||
}
|
||||
|
|
@ -342,8 +329,8 @@ func (uc *UserController) Register(c fiber.Ctx) error {
|
|||
Language: req.Preferences.Language,
|
||||
}
|
||||
}(),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
CreatedAt: &now,
|
||||
UpdatedAt: &now,
|
||||
}
|
||||
|
||||
if err := db.Create(&user).Error; err != nil {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,8 @@ import (
|
|||
)
|
||||
|
||||
// UserRoles is stored as JSON array of strings.
|
||||
|
||||
// Typescript: type
|
||||
type UserRoles []string
|
||||
|
||||
// Typescript: interface
|
||||
type User struct {
|
||||
ID int `json:"id" gorm:"primaryKey"`
|
||||
Email string `json:"email" gorm:"uniqueIndex;size:255"`
|
||||
|
|
@ -25,32 +22,15 @@ type User struct {
|
|||
Details *UserDetails `json:"details" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
|
||||
Preferences *UserPreferences `json:"preferences" gorm:"constraint:OnUpdate:CASCADE,OnDelete:SET NULL;"`
|
||||
Avatar *string `json:"avatar" gorm:"size:512"`
|
||||
CreatedAt time.Time `json:"createdAt" ts:"type=Date"`
|
||||
UpdatedAt time.Time `json:"updatedAt" ts:"type=Date"`
|
||||
DeletedAt gorm.DeletedAt `json:"-" gorm:"index" ts:"type=Date"`
|
||||
}
|
||||
|
||||
// UserCreateInput captures the minimal payload to create a user.
|
||||
|
||||
// Typescript: interface
|
||||
type UserCreateInput struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
Roles UserRoles `json:"roles"`
|
||||
Status UserStatus `json:"status"`
|
||||
Types UserTypes `json:"types"`
|
||||
Avatar *string `json:"avatar"`
|
||||
Details *UserDetails `json:"details" `
|
||||
Preferences *UserPreferences `json:"preferences" `
|
||||
CreatedAt *time.Time `json:"createdAt" ts:"type=Date"`
|
||||
UpdatedAt *time.Time `json:"updatedAt" ts:"type=Date"`
|
||||
DeletedAt *gorm.DeletedAt `json:"-" gorm:"index" ts:"type=Date"`
|
||||
}
|
||||
|
||||
// UserTypes is stored as JSON array (e.g. ["internal","external"]).
|
||||
type UserTypes []string
|
||||
|
||||
// UserProfile is the safe full representation of a user returned by CRUD endpoints.
|
||||
|
||||
// Typescript: interface
|
||||
type UserProfile struct {
|
||||
ID int `json:"id"`
|
||||
Email string `json:"email"`
|
||||
|
|
@ -63,8 +43,8 @@ type UserProfile struct {
|
|||
Details *UserDetails `json:"details"`
|
||||
Preferences *UserPreferences `json:"preferences"`
|
||||
Avatar *string `json:"avatar"`
|
||||
CreatedAt time.Time `json:"createdAt" ts:"type=Date"`
|
||||
UpdatedAt time.Time `json:"updatedAt" ts:"type=Date"`
|
||||
CreatedAt *time.Time `json:"createdAt" ts:"type=Date"`
|
||||
UpdatedAt *time.Time `json:"updatedAt" ts:"type=Date"`
|
||||
}
|
||||
|
||||
// ToUserProfile maps a User to a full response without exposing the password hash.
|
||||
|
|
@ -91,7 +71,6 @@ func ToUserProfile(u *User) UserProfile {
|
|||
|
||||
// UserPreferences holds per-user settings stored as JSON.
|
||||
|
||||
// Typescript: interface
|
||||
type UserPreferences struct {
|
||||
ID int `json:"id" gorm:"primaryKey"`
|
||||
UserID int `json:"userId" gorm:"index"`
|
||||
|
|
@ -109,7 +88,6 @@ type UserPreferences struct {
|
|||
|
||||
// UserDetails holds optional profile data.
|
||||
|
||||
// Typescript: interface
|
||||
type UserDetails struct {
|
||||
ID int `json:"id" gorm:"primaryKey"`
|
||||
UserID int `json:"userId" gorm:"index"`
|
||||
|
|
@ -121,8 +99,8 @@ type UserDetails struct {
|
|||
ZipCode string `json:"zipCode"`
|
||||
Country string `json:"country"`
|
||||
Phone string `json:"phone"`
|
||||
CreatedAt time.Time `json:"createdAt" ts:"type=Date"`
|
||||
UpdatedAt time.Time `json:"updatedAt" ts:"type=Date"`
|
||||
CreatedAt time.Time `json:"createdAt" ts:"type=Nullable<Date>"`
|
||||
UpdatedAt time.Time `json:"updatedAt" ts:"type=Nullable<Date>"`
|
||||
}
|
||||
|
||||
// UserDetails holds optional profile data.
|
||||
|
|
@ -164,24 +142,46 @@ const (
|
|||
UserStatusDisabled UserStatus = "disabled"
|
||||
)
|
||||
|
||||
// Typescript: interface
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
}
|
||||
|
||||
// Typescript: interface
|
||||
type RefreshRequest struct {
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
}
|
||||
|
||||
// Typescript: interface
|
||||
type ForgotPasswordRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
}
|
||||
|
||||
// Typescript: interface
|
||||
type ResetPasswordRequest struct {
|
||||
Token string `json:"token" validate:"required,min=20,max=255"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
}
|
||||
|
||||
type UpdateUserRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"omitempty,min=8,max=128"`
|
||||
Roles UserRoles `json:"roles"`
|
||||
Status UserStatus `json:"status"`
|
||||
Types UserTypes `json:"types"`
|
||||
Avatar *string `json:"avatar"`
|
||||
Details *UserDetails `json:"details"`
|
||||
Preferences *UserPreferences `json:"preferences"`
|
||||
}
|
||||
|
||||
// UserCreateRequest captures the minimal payload to create a user.
|
||||
|
||||
type UserCreateRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Password string `json:"password" validate:"required,min=8,max=128"`
|
||||
Roles UserRoles `json:"roles"`
|
||||
Status UserStatus `json:"status"`
|
||||
Types UserTypes `json:"types"`
|
||||
Avatar *string `json:"avatar"`
|
||||
Details *UserDetails `json:"details" `
|
||||
Preferences *UserPreferences `json:"preferences" `
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ func RegisterUserRoutes(app *fiber.App) {
|
|||
// Typescript: TSEndpoint= path=/users/:uuid; name=getUser; method=GET; response=users.User
|
||||
app.Get("/users/:uuid", tockenService.Middleware(), userController.GetUser)
|
||||
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=users.UserCreateInput; response=users.User
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
app.Post("/users", tockenService.Middleware(), userController.CreateUser)
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=updateUser; method=PUT; request=users.UpdateUserRequest; response=users.User
|
||||
|
|
@ -46,7 +46,7 @@ func RegisterUserRoutes(app *fiber.App) {
|
|||
// Typescript: TSEndpoint= path=/auth/refresh; name=refresh; method=POST; request=users.RefreshRequest; response=tokens.TokenPair
|
||||
app.Post("/auth/refresh", authRateLimiter, userController.Refresh)
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=users.UserCreateInput; response=users.User
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
app.Post("/auth/register", authRateLimiter, userController.Register)
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/forgot; name=forgotPassword; method=POST; request=users.ForgotPasswordRequest; response=responses.SimpleResponse
|
||||
|
|
|
|||
|
|
@ -33,10 +33,6 @@ func (t *TSFiles) Save() error {
|
|||
return fmt.Errorf("TS Files not initialized")
|
||||
}
|
||||
|
||||
for k, v := range *t {
|
||||
fmt.Printf("file: %s\nsource:\n%s\n\n", k, v)
|
||||
}
|
||||
|
||||
for name, source := range *t {
|
||||
formatted, err := formatJS(source)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ func ParseEndpoint(source string, file string, line int) TSEndpoint {
|
|||
endpoint.Request = strings.Trim(t[1], " ")
|
||||
case "response":
|
||||
n++
|
||||
endpoint.Response = strings.Trim(t[1], " ")
|
||||
endpoint.Response = strings.Trim(t[1], " \n")
|
||||
}
|
||||
} else {
|
||||
exitOnError(fmt.Errorf("wrong endpoint props: %s", s))
|
||||
|
|
@ -85,11 +85,6 @@ type tplData struct {
|
|||
|
||||
func (e *TSEndpoint) VerifyTypes(info TSInfo, p string) {
|
||||
kind := ""
|
||||
|
||||
if e.Name == "listUsers" {
|
||||
fmt.Println("endpoint request", e.Request)
|
||||
}
|
||||
|
||||
a := strings.Split(e.Request, ".")
|
||||
if e.Request != "" {
|
||||
if len(a) == 2 {
|
||||
|
|
@ -159,7 +154,7 @@ func (e *TSEndpoint) VerifyTypes(info TSInfo, p string) {
|
|||
allreadyImported := slices.Contains(e.Imports[a[0]], strings.Trim(a[1], "[]*"))
|
||||
if !allreadyImported {
|
||||
e.Imports[a[0]] = append(e.Imports[a[0]], strings.Trim(a[1], "[]*"))
|
||||
fmt.Printf("endpoint %s response import: %s.%s\n", e.Name, a[0], a[1])
|
||||
//fmt.Printf("endpoint %s response import: %s.%s\n", e.Name, a[0], a[1])
|
||||
}
|
||||
}
|
||||
info.setTypescript(a[0], a[1], true)
|
||||
|
|
|
|||
|
|
@ -4,15 +4,16 @@
|
|||
package tsrpc
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/doc"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
type TSInfoPakage struct {
|
||||
|
|
@ -27,9 +28,8 @@ type TSInfoPakage struct {
|
|||
}
|
||||
|
||||
type TSDec struct {
|
||||
Name string
|
||||
Value string
|
||||
SourceInfo string
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type TSType struct {
|
||||
|
|
@ -38,7 +38,6 @@ type TSType struct {
|
|||
TsType string
|
||||
Typescript bool
|
||||
dependOn bool
|
||||
SourceInfo string
|
||||
}
|
||||
|
||||
type TSInfo struct {
|
||||
|
|
@ -128,7 +127,7 @@ func (ts TSInfo) find(p string, n string) bool {
|
|||
|
||||
// popola TsInfo con tutte le definizioni dei tipi
|
||||
|
||||
func (i *TSInfo) getConst(p string, c *doc.Value, src []TSSourceFile) {
|
||||
func (i *TSInfo) getConst(p string, c *doc.Value) {
|
||||
var isTypescript = strings.HasPrefix(c.Doc, "Typescript:")
|
||||
if isTypescript {
|
||||
command := strings.TrimPrefix(c.Doc, "Typescript:")
|
||||
|
|
@ -150,7 +149,7 @@ func (i *TSInfo) getConst(p string, c *doc.Value, src []TSSourceFile) {
|
|||
be, ok := v.Values[0].(*ast.BinaryExpr)
|
||||
if ok {
|
||||
x := be.X.(*ast.BasicLit)
|
||||
exitOnError(fmt.Errorf("enum binary expression not implemented %s %s %s AT: %s", x.Value, be.Op.String(), be.Y, getSourceInfo(int(x.ValuePos), src)))
|
||||
exitOnError(fmt.Errorf("enum binary expression not implemented %s %s %s", x.Value, be.Op.String(), be.Y))
|
||||
}
|
||||
ident, ok := v.Values[0].(*ast.Ident)
|
||||
if ok {
|
||||
|
|
@ -177,11 +176,10 @@ func (i *TSInfo) getConst(p string, c *doc.Value, src []TSSourceFile) {
|
|||
i.Packages[p].enums[enumName] = enum
|
||||
t1 := TSType{
|
||||
Name: enumName,
|
||||
Typescript: true,
|
||||
Typescript: false,
|
||||
Type: "",
|
||||
TsType: fmt.Sprintf("typeof Enum%s[keyof typeof Enum%s] ", enumName, enumName), //getFieldTsInfo(expr.Type),
|
||||
dependOn: false,
|
||||
SourceInfo: "",
|
||||
}
|
||||
i.Packages[p].types[enumName] = t1
|
||||
}
|
||||
|
|
@ -204,32 +202,10 @@ func (i *TSInfo) getConst(p string, c *doc.Value, src []TSSourceFile) {
|
|||
}
|
||||
}
|
||||
|
||||
func (i *TSInfo) getType(p string, t *doc.Type, src []TSSourceFile) {
|
||||
var isType = t.Decl.Tok == token.TYPE && t.Doc == ""
|
||||
var isTypescript = strings.HasPrefix(t.Doc, "Typescript:")
|
||||
command := ""
|
||||
param := ""
|
||||
if isTypescript {
|
||||
//fmt.Println(t.Doc)
|
||||
command = strings.TrimPrefix(t.Doc, "Typescript:")
|
||||
command = strings.TrimSpace(command)
|
||||
command = strings.Trim(command, "\n")
|
||||
|
||||
if strings.Contains(command, "=") {
|
||||
a := strings.Split(command, "=")
|
||||
if len(a) == 2 {
|
||||
param = a[1]
|
||||
}
|
||||
command = strings.Trim(a[0], " ")
|
||||
}
|
||||
}
|
||||
if isType {
|
||||
//fmt.Println(t.Doc)
|
||||
command = "interface"
|
||||
}
|
||||
func (i *TSInfo) getType(p string, t *doc.Type) {
|
||||
for _, spec := range t.Decl.Specs {
|
||||
if len(t.Consts) > 0 {
|
||||
i.getConst(p, t.Consts[0], src)
|
||||
i.getConst(p, t.Consts[0])
|
||||
continue
|
||||
}
|
||||
switch spec.(type) {
|
||||
|
|
@ -237,32 +213,28 @@ func (i *TSInfo) getType(p string, t *doc.Type, src []TSSourceFile) {
|
|||
typeSpec := spec.(*ast.TypeSpec)
|
||||
switch typeSpec.Type.(type) {
|
||||
case *ast.StructType:
|
||||
if (isTypescript || isType) && command != "interface" {
|
||||
exitOnError(fmt.Errorf("mismatch delaration for interface %s AT: %s", t.Doc, getSourceInfo(int(typeSpec.Name.NamePos), src)))
|
||||
}
|
||||
// if isType && command != "interface" {
|
||||
// exitOnError(fmt.Errorf("mismatch delaration for interface %s AT: %s", t.Doc, getSourceInfo(int(typeSpec.Name.NamePos), src)))
|
||||
// }
|
||||
v := TSStruct{
|
||||
Name: typeSpec.Name.Name,
|
||||
Typescript: isTypescript,
|
||||
Typescript: false,
|
||||
Fields: []TSSField{},
|
||||
SourceInfo: getSourceInfo(int(typeSpec.Name.NamePos), src),
|
||||
SourceInfo: "",
|
||||
}
|
||||
v.getStruct(typeSpec, src)
|
||||
v.getStruct(typeSpec)
|
||||
i.Packages[p].structs[typeSpec.Name.Name] = v
|
||||
default:
|
||||
if isTypescript && command != "type" {
|
||||
exitOnError(fmt.Errorf("mismatch delaration for type %s AT: %s", t.Doc, getSourceInfo(int(typeSpec.Name.NamePos), src)))
|
||||
}
|
||||
// if isType && command != "interface" {
|
||||
// exitOnError(fmt.Errorf("mismatch delaration for interface %s AT: %s", t.Doc, getSourceInfo(int(typeSpec.Name.NamePos), src)))
|
||||
// }
|
||||
tsInfo := getFieldTsInfo(typeSpec.Type)
|
||||
if command == "type" && param != "" {
|
||||
tsInfo = param
|
||||
}
|
||||
t := TSType{
|
||||
Name: typeSpec.Name.Name,
|
||||
Typescript: isTypescript,
|
||||
Typescript: false,
|
||||
Type: getFieldInfo(typeSpec.Type),
|
||||
TsType: tsInfo,
|
||||
dependOn: toBeImported(typeSpec.Type),
|
||||
SourceInfo: getSourceInfo(int(typeSpec.Name.NamePos), src),
|
||||
}
|
||||
//fmt.Printf("Type found: %s Type: %s TsType: %s AT: %s\n", t.Name, t.Type, t.TsType, t.SourceInfo)
|
||||
i.Packages[p].types[typeSpec.Name.Name] = t
|
||||
|
|
@ -271,160 +243,186 @@ func (i *TSInfo) getType(p string, t *doc.Type, src []TSSourceFile) {
|
|||
}
|
||||
}
|
||||
|
||||
func (i *TSInfo) Populate(path string) {
|
||||
i.Packages = make(map[string]TSInfoPakage)
|
||||
err := filepath.Walk(path,
|
||||
func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
fset := token.NewFileSet()
|
||||
packages, err := parser.ParseDir(fset, path, nil, parser.ParseComments)
|
||||
|
||||
if err != nil {
|
||||
exitOnError(err)
|
||||
}
|
||||
|
||||
for pkg, f := range packages {
|
||||
if _, ok := i.Packages[pkg]; !ok {
|
||||
i.Packages[pkg] = TSInfoPakage{structs: make(map[string]TSStruct), types: make(map[string]TSType), enums: make(map[string]TSEnum), consts: make(map[string]TSConst), decs: make(map[string]TSDec), endpoints: make(map[string]TSEndpoint)}
|
||||
}
|
||||
if pkg == "typescript" || pkg == "tsrpc" {
|
||||
continue
|
||||
}
|
||||
|
||||
var src = []TSSourceFile{}
|
||||
for n := range f.Files {
|
||||
|
||||
dat, err := os.ReadFile(n)
|
||||
if err == nil {
|
||||
lines := []TSSourceLine{}
|
||||
pos := 0
|
||||
line := 1
|
||||
for p, k := range dat {
|
||||
if string(k) == "\n" {
|
||||
l := TSSourceLine{
|
||||
Pos: pos,
|
||||
End: p,
|
||||
Line: line,
|
||||
Source: string(dat[pos:p]),
|
||||
}
|
||||
lines = append(lines, l)
|
||||
pos = p + 1
|
||||
line++
|
||||
if strings.Contains(l.Source, "// Typescript:") {
|
||||
|
||||
if strings.Contains(l.Source, "TStype=") {
|
||||
p := strings.Index(l.Source, "TStype=")
|
||||
s := strings.Trim(l.Source[p+len("TStype="):], " ")
|
||||
a := strings.Split(s, "=")
|
||||
if len(a) == 2 {
|
||||
t := TSType{
|
||||
Name: strings.Trim(a[0], " "),
|
||||
Typescript: true,
|
||||
Type: "UserDefined",
|
||||
TsType: strings.Trim(a[1], " "),
|
||||
dependOn: false,
|
||||
SourceInfo: getSourceInfo(int(l.Pos), src),
|
||||
}
|
||||
i.Packages[pkg].types[strings.Trim(a[0], " ")] = t
|
||||
}
|
||||
|
||||
}
|
||||
if strings.Contains(l.Source, "TSDeclaration=") {
|
||||
p := strings.Index(l.Source, "TSDeclaration=")
|
||||
s := strings.Trim(l.Source[p+len("TSDeclaration="):], " ")
|
||||
a := strings.Split(s, "=")
|
||||
if len(a) == 2 {
|
||||
t := TSDec{
|
||||
Name: strings.Trim(a[0], " "),
|
||||
Value: strings.Trim(a[1], " "),
|
||||
SourceInfo: getSourceInfo(int(l.Pos), src),
|
||||
}
|
||||
i.Packages[pkg].decs[strings.Trim(a[0], " ")] = t
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(l.Source, "TSEndpoint= ") {
|
||||
e := ParseEndpoint(l.Source, n, l.Line)
|
||||
if _, ok := i.Packages[pkg].endpoints[e.Name]; ok {
|
||||
exitOnError(fmt.Errorf("enpoint name %s allready in use: %s", e.Name, l.Source))
|
||||
}
|
||||
pkg_info := i.Packages[pkg]
|
||||
pkg_info.endpoints[e.Name] = e
|
||||
pkg_info.imports = e.Imports
|
||||
pkg_info.isUsed = true
|
||||
i.Packages[pkg] = pkg_info
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
s := TSSourceFile{
|
||||
Name: n,
|
||||
Source: string(dat),
|
||||
Len: len(dat),
|
||||
Lines: lines,
|
||||
}
|
||||
src = append(src, s)
|
||||
}
|
||||
}
|
||||
|
||||
p := doc.New(f, "./", 0)
|
||||
|
||||
for _, t := range p.Types {
|
||||
i.getType(pkg, t, src)
|
||||
}
|
||||
|
||||
for _, c := range p.Consts {
|
||||
i.getConst(pkg, c, src)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
func parseTypescriptDeclarations(n string, pkg TSInfoPakage) {
|
||||
f, err := os.OpenFile(n, os.O_RDONLY, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
log.Fatalf("open file error: %v", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
l := 1
|
||||
dat := ""
|
||||
lines := []TSSourceLine{}
|
||||
rd := bufio.NewReader(f)
|
||||
for {
|
||||
line, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
|
||||
log.Fatalf("read file line error: %v", err)
|
||||
return
|
||||
}
|
||||
lines = append(lines, TSSourceLine{Pos: l, End: l + len(line), Line: l, Source: line})
|
||||
l++
|
||||
dat += line
|
||||
|
||||
if strings.Contains(line, "// Typescript:") {
|
||||
if strings.Contains(line, "TStype=") {
|
||||
p := strings.Index(line, "TStype=")
|
||||
s := strings.Trim(line[p+len("TStype="):], " ")
|
||||
a := strings.Split(s, "=")
|
||||
if len(a) == 2 {
|
||||
t := TSType{
|
||||
Name: strings.Trim(a[0], " "),
|
||||
Typescript: true,
|
||||
Type: "UserDefined",
|
||||
TsType: strings.Trim(a[1], " "),
|
||||
dependOn: false,
|
||||
}
|
||||
pkg.types[strings.Trim(a[0], " ")] = t
|
||||
}
|
||||
|
||||
}
|
||||
if strings.Contains(line, "TSDeclaration=") {
|
||||
p := strings.Index(line, "TSDeclaration=")
|
||||
s := strings.Trim(line[p+len("TSDeclaration="):], " ")
|
||||
a := strings.Split(s, "=")
|
||||
if len(a) == 2 {
|
||||
t := TSDec{
|
||||
Name: strings.Trim(a[0], " "),
|
||||
Value: strings.Trim(a[1], " "),
|
||||
}
|
||||
pkg.decs[strings.Trim(a[0], " ")] = t
|
||||
}
|
||||
}
|
||||
|
||||
if strings.Contains(line, "TSEndpoint= ") {
|
||||
e := ParseEndpoint(line, n, l)
|
||||
if _, ok := pkg.endpoints[e.Name]; ok {
|
||||
exitOnError(fmt.Errorf("enpoint name %s allready in use: %s", e.Name, line))
|
||||
}
|
||||
pkg_info := pkg
|
||||
pkg_info.endpoints[e.Name] = e
|
||||
pkg_info.imports = e.Imports
|
||||
pkg_info.isUsed = true
|
||||
pkg = pkg_info
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TSInfo) findAvailableStruct(n string) (TSStruct, bool) {
|
||||
func (i *TSInfo) Populate(path string) {
|
||||
i.Packages = make(map[string]TSInfoPakage)
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedName |
|
||||
packages.NeedFiles |
|
||||
packages.NeedCompiledGoFiles |
|
||||
packages.NeedSyntax,
|
||||
Dir: path,
|
||||
}
|
||||
|
||||
pkgs, err := packages.Load(cfg, "./...")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if packages.PrintErrors(pkgs) > 0 {
|
||||
log.Fatal("package loading failed")
|
||||
}
|
||||
|
||||
//to get line info for endpoints and typescript declarations
|
||||
for _, loadedPkg := range pkgs {
|
||||
pkg := loadedPkg.Name
|
||||
// skip packages
|
||||
if pkg == "typescript" || pkg == "tsrpc" {
|
||||
continue
|
||||
}
|
||||
// initialize package info if not exists
|
||||
if _, ok := i.Packages[pkg]; !ok {
|
||||
i.Packages[pkg] = TSInfoPakage{structs: make(map[string]TSStruct), types: make(map[string]TSType), enums: make(map[string]TSEnum), consts: make(map[string]TSConst), decs: make(map[string]TSDec), endpoints: make(map[string]TSEndpoint)}
|
||||
}
|
||||
// start parsing files
|
||||
for _, n := range loadedPkg.CompiledGoFiles {
|
||||
// search for declarative // Typescript: declarations and endpoints
|
||||
parseTypescriptDeclarations(n, i.Packages[pkg])
|
||||
}
|
||||
// parse doc to get all types and consts
|
||||
docPkg, err := doc.NewFromFiles(loadedPkg.Fset, loadedPkg.Syntax, loadedPkg.PkgPath)
|
||||
if err != nil {
|
||||
exitOnError(err)
|
||||
}
|
||||
|
||||
for _, t := range docPkg.Types {
|
||||
i.getType(pkg, t)
|
||||
}
|
||||
|
||||
for _, c := range docPkg.Consts {
|
||||
i.getConst(pkg, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ts *TSInfo) findAvailableStruct(pkg string, n string, deep int) (int, bool) {
|
||||
a := strings.Split(n, ".")
|
||||
if n == "" || IsNativeType(n) {
|
||||
return deep, true
|
||||
}
|
||||
|
||||
deep++
|
||||
if deep > 10 {
|
||||
exitOnError(fmt.Errorf("too much deep for struct %s", n))
|
||||
}
|
||||
|
||||
if len(a) == 1 {
|
||||
n = strings.TrimPrefix(n, "[]")
|
||||
n = strings.TrimPrefix(n, "*")
|
||||
if _, ok := ts.Packages[pkg].structs[n]; ok {
|
||||
s := ts.Packages[pkg].structs[n]
|
||||
s.Typescript = true
|
||||
ts.Packages[pkg].structs[n] = s // write back
|
||||
for _, v := range s.Fields {
|
||||
deep, _ = ts.findAvailableStruct(pkg, v.Type, deep)
|
||||
}
|
||||
deep--
|
||||
return deep, true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if len(a) == 2 {
|
||||
a[1] = strings.TrimPrefix(a[1], "[]")
|
||||
a[1] = strings.TrimPrefix(a[1], "*")
|
||||
if _, ok := ts.Packages[a[0]]; ok {
|
||||
if _, ok := ts.Packages[a[0]].structs[a[1]]; ok {
|
||||
return ts.Packages[a[0]].structs[a[1]], true
|
||||
s := ts.Packages[a[0]].structs[a[1]]
|
||||
if s.Typescript {
|
||||
deep--
|
||||
return deep, true
|
||||
}
|
||||
s.Typescript = true
|
||||
ts.Packages[a[0]].structs[a[1]] = s // write back
|
||||
for _, v := range s.Fields {
|
||||
ts.findAvailableStruct(pkg, v.Type, deep)
|
||||
}
|
||||
deep--
|
||||
return deep, true
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(a) == 1 {
|
||||
n = strings.TrimPrefix(n, "[]")
|
||||
n = strings.TrimPrefix(n, "*")
|
||||
for p := range ts.Packages {
|
||||
if _, ok := ts.Packages[p].structs[n]; ok {
|
||||
return ts.Packages[p].structs[n], true
|
||||
}
|
||||
}
|
||||
}
|
||||
if n == "" || IsNativeType(n) {
|
||||
return TSStruct{}, true
|
||||
}
|
||||
|
||||
return TSStruct{}, false
|
||||
return deep, false
|
||||
}
|
||||
|
||||
func (i *TSInfo) TestEndpoints() {
|
||||
for p := range i.Packages {
|
||||
for _, v1 := range i.Packages[p].endpoints {
|
||||
_, f := i.findAvailableStruct(v1.Request)
|
||||
_, f := i.findAvailableStruct(p, v1.Request, 0)
|
||||
if !f {
|
||||
fmt.Printf("??Endpoint: request %s not found\n", v1.Request)
|
||||
}
|
||||
_, f = i.findAvailableStruct(v1.Response)
|
||||
_, f = i.findAvailableStruct(p, v1.Response, 0)
|
||||
if !f {
|
||||
fmt.Printf("??Endpoint: response %s not found\n", v1.Response)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,9 +79,7 @@ func getFieldInfo(t ast.Expr) string {
|
|||
case *ast.InterfaceType:
|
||||
result = "interface{}"
|
||||
default:
|
||||
f := fmt.Sprintf("this go type: %T is not evaluated", ft)
|
||||
fmt.Println(f)
|
||||
//exitOnError(fmt.Errorf("this go type: %T is not evaluated", ft))
|
||||
exitOnError(fmt.Errorf("this go type: %T is not evaluated", ft))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -104,25 +102,12 @@ func getFieldTsInfo(t ast.Expr) string {
|
|||
case *ast.FuncType:
|
||||
fmt.Println("*ast.FuncType found, skipping...")
|
||||
default:
|
||||
//f := fmt.Sprintf("getFieldTsInfo can't evaluate type: %T %T", t, ft)
|
||||
//fmt.Println(f)
|
||||
exitOnError(fmt.Errorf("getFieldTsInfo can't evaluate type: %T %T", t, ft))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func getSourceInfo(pos int, src []TSSourceFile) string {
|
||||
for _, v := range src {
|
||||
for _, l := range v.Lines {
|
||||
if pos >= l.Pos && pos <= l.End {
|
||||
return fmt.Sprintf("%s Line: %d", v.Name, l.Line)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *TSStruct) getStruct(ts *ast.TypeSpec, src []TSSourceFile) {
|
||||
func (s *TSStruct) getStruct(ts *ast.TypeSpec) {
|
||||
if st, ok := ts.Type.(*ast.StructType); ok {
|
||||
for _, field := range st.Fields.List {
|
||||
|
||||
|
|
@ -148,7 +133,7 @@ func (s *TSStruct) getStruct(ts *ast.TypeSpec, src []TSSourceFile) {
|
|||
Type: getFieldInfo(field.Type),
|
||||
TsType: tsType,
|
||||
DependOn: toBeImported(field.Type),
|
||||
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
||||
SourceInfo: "",
|
||||
}
|
||||
s.Fields = append(s.Fields, f)
|
||||
} else {
|
||||
|
|
@ -160,7 +145,7 @@ func (s *TSStruct) getStruct(ts *ast.TypeSpec, src []TSSourceFile) {
|
|||
Type: getFieldInfo(field.Type),
|
||||
TsType: tsType,
|
||||
DependOn: toBeImported(field.Type),
|
||||
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
||||
SourceInfo: "",
|
||||
}
|
||||
s.Fields = append(s.Fields, f)
|
||||
} else {
|
||||
|
|
@ -172,11 +157,9 @@ func (s *TSStruct) getStruct(ts *ast.TypeSpec, src []TSSourceFile) {
|
|||
Type: se.Name,
|
||||
TsType: tsType,
|
||||
DependOn: false,
|
||||
SourceInfo: getSourceInfo(int(field.Type.Pos()), src),
|
||||
SourceInfo: "",
|
||||
}
|
||||
s.Fields = append(s.Fields, f)
|
||||
|
||||
fmt.Println(f)
|
||||
} else {
|
||||
exitOnError(fmt.Errorf("this typescript type: %T is not evaluated", field.Type))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ type TSModule struct {
|
|||
GTypes map[string]string
|
||||
Endpoints map[string]string
|
||||
Imports map[string][]string
|
||||
Source string
|
||||
}
|
||||
|
||||
type TSOutputSources []string
|
||||
|
|
@ -222,7 +221,7 @@ func (ts *TSSouces) Populate(info TSInfo) {
|
|||
for p := range info.Packages {
|
||||
ts.ensurePackage(p)
|
||||
|
||||
ts.Errors = append(ts.Errors, fmt.Sprintf("Process pakage %s\n", p))
|
||||
// ts.Errors = append(ts.Errors, fmt.Sprintf("Process pakage %s\n", p))
|
||||
|
||||
for _, st := range info.Packages[p].structs {
|
||||
if st.Typescript {
|
||||
|
|
@ -259,30 +258,6 @@ func (ts *TSSouces) Populate(info TSInfo) {
|
|||
}
|
||||
|
||||
for _, e := range info.Packages[p].endpoints {
|
||||
|
||||
/* if e.Request != "" {
|
||||
a := strings.Split(e.Request, ".")
|
||||
if len(a) == 2 {
|
||||
s, d, err := structToTs(info, a[0], a[1])
|
||||
if err != nil {
|
||||
ts.Errors = append(ts.Errors, err.Error())
|
||||
}
|
||||
fmt.Println(s, d)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if e.Response != "" {
|
||||
a := strings.Split(e.Response, ".")
|
||||
if len(a) == 2 {
|
||||
s, d, err := structToTs(info, a[0], a[1])
|
||||
if err != nil {
|
||||
ts.Errors = append(ts.Errors, err.Error())
|
||||
}
|
||||
fmt.Println(s, d)
|
||||
}
|
||||
|
||||
} */
|
||||
responseAndRequest := ""
|
||||
|
||||
if e.Request != "" {
|
||||
|
|
@ -303,10 +278,6 @@ func (ts *TSSouces) Populate(info TSInfo) {
|
|||
}
|
||||
pkg.Endpoints[e.Name] = e.ToTs()
|
||||
ts.Pakages[p] = pkg
|
||||
if p == "users" {
|
||||
fmt.Printf("endpoint %s imports: %v\n", e.Name, pkg.Imports)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,9 +61,6 @@ func GetTSSource() error {
|
|||
tsFiles.Add("apiTypes.ts", tsIndexSource)
|
||||
|
||||
for p := range tsSourcesData.Pakages {
|
||||
if p == "users" {
|
||||
fmt.Println("users package")
|
||||
}
|
||||
source := ""
|
||||
for _, v1 := range tsSourcesData.Pakages[p].Endpoints {
|
||||
source += fmt.Sprintln(v1)
|
||||
|
|
@ -90,7 +87,7 @@ func GetTSSource() error {
|
|||
}
|
||||
}
|
||||
if found {
|
||||
tmp += "import { api } from './api.ts'\n"
|
||||
tmp += "import { api } from './api'\n"
|
||||
}
|
||||
|
||||
if len(tsApiDeclarations) > 0 {
|
||||
|
|
@ -108,20 +105,19 @@ func GetTSSource() error {
|
|||
}
|
||||
}
|
||||
if len(decs) > 0 {
|
||||
TSApiDeclarations := "import { "
|
||||
TSApiDeclarations := "import type { "
|
||||
for _, d := range decs {
|
||||
TSApiDeclarations += d + ", "
|
||||
}
|
||||
TSApiDeclarations = TSApiDeclarations[:len(TSApiDeclarations)-2]
|
||||
TSApiDeclarations += " } from './apiTypes.ts'\n"
|
||||
fmt.Println("tsApiDeclarations", TSApiDeclarations)
|
||||
tmp += TSApiDeclarations
|
||||
}
|
||||
}
|
||||
|
||||
imports := ""
|
||||
for f := range tsSourcesData.Pakages[p].Imports {
|
||||
imports += "import * as " + f + " from './" + f + ".ts'\n"
|
||||
imports += "import type * as " + f + " from './" + f + ".ts'\n"
|
||||
}
|
||||
tmp += imports
|
||||
tmp += source
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
import type * as users from "./users.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users/:uuid/block; name=blockUser; method=PUT; request=admin.BlockUserRequest; response=users.User
|
||||
// internal/admin/routes.go Line: 16
|
||||
export const blockUser = async (
|
||||
data: BlockUserRequest,
|
||||
): Promise<{ data: users.User; error: Nullable<string> }> => {
|
||||
return (await api.PUT("/admin/users/:uuid/block", data)) as {
|
||||
data: users.User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users; name=listUsers; method=POST; request=admin.ListUsersRequest; response=users.[]User
|
||||
// internal/admin/routes.go Line: 12
|
||||
export const listUsers = async (
|
||||
data: ListUsersRequest,
|
||||
): Promise<{ data: users.User[]; error: Nullable<string> }> => {
|
||||
return (await api.POST("/admin/users", data)) as {
|
||||
data: users.User[];
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface BlockUserRequest {
|
||||
action: string;
|
||||
}
|
||||
|
||||
export interface ListUsersRequest {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
//
|
||||
// This file was generated by github.com/millevolte/ts-rpc
|
||||
//
|
||||
// Apr 05, 2026 17:08:11 UTC
|
||||
// Apr 15, 2026 18:49:19 UTC
|
||||
//
|
||||
|
||||
export interface ApiRestResponse {
|
||||
|
|
@ -273,341 +273,4 @@ export default class Api {
|
|||
}
|
||||
}
|
||||
|
||||
const api = new Api("http://localhost:3000");
|
||||
|
||||
// Global Declarations
|
||||
export type Nullable<T> = T | null;
|
||||
|
||||
export type Record<K extends string | number | symbol, T> = { [P in K]: T };
|
||||
|
||||
//
|
||||
// package model
|
||||
//
|
||||
|
||||
export interface RefreshRequest {
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
export interface TokenPair {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordRequest {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface LoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordRequest {
|
||||
token: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
//
|
||||
// package controllers
|
||||
//
|
||||
|
||||
export interface BlockUserRequest {
|
||||
action: string;
|
||||
}
|
||||
|
||||
export interface ListUsersRequest {
|
||||
page: number;
|
||||
pageSize: number;
|
||||
}
|
||||
|
||||
export interface SimpleResponse {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: models.UserRoles;
|
||||
status: models.UserStatus;
|
||||
types: models.UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<models.UserDetailsShort>;
|
||||
preferences: Nullable<models.UserPreferencesShort>;
|
||||
}
|
||||
|
||||
//
|
||||
// package routes
|
||||
//
|
||||
|
||||
// Typescript: TSEndpoint= path=/metrics; name=metrics; method=GET; response=string
|
||||
// internal/http/routes/system_routes.go Line: 37
|
||||
export const metrics = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/metrics")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/maildebug; name=mailDebug; method=GET; response=routes.[]MailDebugItem
|
||||
// internal/http/routes/system_routes.go Line: 48
|
||||
export const mailDebug = async (): Promise<{
|
||||
data: MailDebugItem[];
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/maildebug")) as {
|
||||
data: MailDebugItem[];
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=getUser; method=GET; response=models.UserProfile
|
||||
// internal/http/routes/user_routes.go Line: 13
|
||||
export const getUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: UserProfile; error: Nullable<string> }> => {
|
||||
return (await api.GET(`/users/${uuid}`)) as {
|
||||
data: UserProfile;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=updateUser; method=PUT; request=controllers.UpdateUserRequest; response=models.UserProfile
|
||||
// internal/http/routes/user_routes.go Line: 19
|
||||
|
||||
export const updateUser = async (
|
||||
data: UpdateUserRequest,
|
||||
): Promise<{ data: UserProfile; error: Nullable<string> }> => {
|
||||
return (await api.PUT("/users/:uuid", data)) as {
|
||||
data: UserProfile;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users; name=listUsers; method=POST; request=controllers.ListUsersRequest; response=models.[]UserShort
|
||||
// internal/http/routes/admin_routes.go Line: 12
|
||||
|
||||
export const listUsers = async (
|
||||
data: ListUsersRequest,
|
||||
): Promise<{ data: UserShort[]; error: Nullable<string> }> => {
|
||||
return (await api.POST("/admin/users", data)) as {
|
||||
data: UserShort[];
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/admin/users/:uuid/block; name=blockUser; method=PUT; request=controllers.BlockUserRequest; response=models.UserShort
|
||||
// internal/http/routes/admin_routes.go Line: 15
|
||||
|
||||
export const blockUser = async (
|
||||
data: BlockUserRequest,
|
||||
): Promise<{ data: UserShort; error: Nullable<string> }> => {
|
||||
return (await api.PUT("/admin/users/:uuid/block", data)) as {
|
||||
data: UserShort;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=models.UserCreateInput; response=models.UserProfile
|
||||
// internal/http/routes/user_routes.go Line: 16
|
||||
|
||||
export const createUser = async (
|
||||
data: UserCreateInput,
|
||||
): Promise<{ data: UserProfile; error: Nullable<string> }> => {
|
||||
return (await api.POST("/users", data)) as {
|
||||
data: UserProfile;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=deleteUser; method=DELETE; response=controllers.SimpleResponse
|
||||
// internal/http/routes/user_routes.go Line: 22
|
||||
|
||||
export const deleteUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.DELETE(`/users/${uuid}`)) as {
|
||||
data: SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/health; name=health; method=GET; response=string
|
||||
// internal/http/routes/system_routes.go Line: 34
|
||||
export const health = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/health")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface FormRequest {
|
||||
req: string;
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface FormResponse {
|
||||
test: string;
|
||||
}
|
||||
|
||||
export interface MailDebugItem {
|
||||
name: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
//
|
||||
// package endpoint
|
||||
//
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/forgot; name=forgotPassword; method=POST; request=model.ForgotPasswordRequest; response=controllers.SimpleResponse
|
||||
// internal/auth/endpoint/routes.go Line: 34
|
||||
|
||||
export const forgotPassword = async (
|
||||
data: ForgotPasswordRequest,
|
||||
): Promise<{ data: SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/forgot", data)) as {
|
||||
data: SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/reset; name=resetPassword; method=POST; request=model.ResetPasswordRequest; response=controllers.SimpleResponse
|
||||
// internal/auth/endpoint/routes.go Line: 37
|
||||
|
||||
export const resetPassword = async (
|
||||
data: ResetPasswordRequest,
|
||||
): Promise<{ data: SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/reset", data)) as {
|
||||
data: SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/valid; name=validToken; method=POST; request=string; response=controllers.SimpleResponse
|
||||
// internal/auth/endpoint/routes.go Line: 40
|
||||
|
||||
export const validToken = async (
|
||||
data: string,
|
||||
): Promise<{ data: SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/valid", data)) as {
|
||||
data: SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/login; name=login; method=POST; request=model.LoginRequest; response=model.TokenPair
|
||||
// internal/auth/endpoint/routes.go Line: 22
|
||||
|
||||
export const login = async (
|
||||
data: LoginRequest,
|
||||
): Promise<{ data: TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/login", data)) as {
|
||||
data: TokenPair;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/refresh; name=refresh; method=POST; request=model.RefreshRequest; response=model.TokenPair
|
||||
// internal/auth/endpoint/routes.go Line: 25
|
||||
|
||||
export const refresh = async (
|
||||
data: RefreshRequest,
|
||||
): Promise<{ data: TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/refresh", data)) as {
|
||||
data: TokenPair;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/me; name=me; method=GET; response=models.UserShort
|
||||
// internal/auth/endpoint/routes.go Line: 28
|
||||
export const me = async (): Promise<{
|
||||
data: UserShort;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/auth/me")) as {
|
||||
data: UserShort;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=models.UserCreateInput; response=models.UserShort
|
||||
// internal/auth/endpoint/routes.go Line: 31
|
||||
|
||||
export const register = async (
|
||||
data: UserCreateInput,
|
||||
): Promise<{ data: UserShort; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/register", data)) as {
|
||||
data: UserShort;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// package models
|
||||
//
|
||||
|
||||
export interface UserCreateInput {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
types: UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<UserDetailsShort>;
|
||||
preferences: Nullable<UserPreferencesShort>;
|
||||
}
|
||||
|
||||
export interface UserDetailsShort {
|
||||
title: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
address: string;
|
||||
city: string;
|
||||
zipCode: string;
|
||||
country: string;
|
||||
phone: string;
|
||||
}
|
||||
|
||||
export interface UserPreferencesShort {
|
||||
useIdle: boolean;
|
||||
idleTimeout: number;
|
||||
useIdlePassword: boolean;
|
||||
idlePin: string;
|
||||
useDirectLogin: boolean;
|
||||
useQuadcodeLogin: boolean;
|
||||
sendNoticesMail: boolean;
|
||||
language: string;
|
||||
}
|
||||
|
||||
export interface UserShort {
|
||||
email: string;
|
||||
name: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
uuid: string;
|
||||
details: Nullable<UserDetailsShort>;
|
||||
preferences: Nullable<UserPreferencesShort>;
|
||||
avatar: Nullable<string>;
|
||||
}
|
||||
|
||||
export type UserRoles = string[];
|
||||
|
||||
export type UserStatus = (typeof EnumUserStatus)[keyof typeof EnumUserStatus];
|
||||
|
||||
export type UserTypes = string[];
|
||||
|
||||
export type UsersShort = UserShort[];
|
||||
|
||||
export const EnumUserStatus = {
|
||||
UserStatusPending: "pending",
|
||||
UserStatusActive: "active",
|
||||
UserStatusDisabled: "disabled",
|
||||
} as const;
|
||||
export const api = new Api("http://localhost:3000");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
// API Declarations
|
||||
export type Nullable<T> = T | null;
|
||||
|
||||
export type Record<K extends string | number | symbol, T> = { [P in K]: T };
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export interface SimpleResponse {
|
||||
message: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/health; name=health; method=GET; response=string
|
||||
// internal/systemUtils/routes.go Line: 38
|
||||
export const health = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/health")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/metrics; name=metrics; method=GET; response=string
|
||||
// internal/systemUtils/routes.go Line: 41
|
||||
export const metrics = async (): Promise<{
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/metrics")) as {
|
||||
data: string;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/maildebug; name=mailDebug; method=GET; response=[]MailDebugItem
|
||||
// internal/systemUtils/routes.go Line: 53
|
||||
export const mailDebug = async (): Promise<{
|
||||
data: MailDebugItem[];
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/maildebug")) as {
|
||||
data: MailDebugItem[];
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface MailDebugItem {
|
||||
name: string;
|
||||
content: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
export interface TokenPair {
|
||||
access_token: string;
|
||||
refresh_token: string;
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
import { api } from "./api";
|
||||
import type { Nullable } from "./apiTypes.ts";
|
||||
import type * as tokens from "./tokens.ts";
|
||||
import type * as responses from "./responses.ts";
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/valid; name=validToken; method=POST; request=string; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 58
|
||||
export const validToken = async (
|
||||
data: string,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/valid", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=updateUser; method=PUT; request=users.UpdateUserRequest; response=users.User
|
||||
// internal/user/routes.go Line: 33
|
||||
export const updateUser = async (
|
||||
data: UpdateUserRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.PUT("/users/:uuid", data)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=deleteUser; method=DELETE; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 36
|
||||
export const deleteUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.DELETE(`/users/${uuid}`)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/register; name=register; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
// internal/user/routes.go Line: 49
|
||||
export const register = async (
|
||||
data: UserCreateRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/register", data)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/forgot; name=forgotPassword; method=POST; request=users.ForgotPasswordRequest; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 52
|
||||
export const forgotPassword = async (
|
||||
data: ForgotPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/forgot", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users; name=createUser; method=POST; request=users.UserCreateRequest; response=users.User
|
||||
// internal/user/routes.go Line: 30
|
||||
export const createUser = async (
|
||||
data: UserCreateRequest,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.POST("/users", data)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/refresh; name=refresh; method=POST; request=users.RefreshRequest; response=tokens.TokenPair
|
||||
// internal/user/routes.go Line: 46
|
||||
export const refresh = async (
|
||||
data: RefreshRequest,
|
||||
): Promise<{ data: tokens.TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/refresh", data)) as {
|
||||
data: tokens.TokenPair;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/users/:uuid; name=getUser; method=GET; response=users.User
|
||||
// internal/user/routes.go Line: 27
|
||||
export const getUser = async (
|
||||
uuid: string,
|
||||
): Promise<{ data: User; error: Nullable<string> }> => {
|
||||
return (await api.GET(`/users/${uuid}`)) as {
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/me; name=me; method=GET; response=users.User
|
||||
// internal/user/routes.go Line: 39
|
||||
export const me = async (): Promise<{
|
||||
data: User;
|
||||
error: Nullable<string>;
|
||||
}> => {
|
||||
return (await api.GET("/auth/me")) as { data: User; error: Nullable<string> };
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/login; name=login; method=POST; request=users.LoginRequest; response=tokens.TokenPair
|
||||
// internal/user/routes.go Line: 43
|
||||
export const login = async (
|
||||
data: LoginRequest,
|
||||
): Promise<{ data: tokens.TokenPair; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/login", data)) as {
|
||||
data: tokens.TokenPair;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
// Typescript: TSEndpoint= path=/auth/password/reset; name=resetPassword; method=POST; request=users.ResetPasswordRequest; response=responses.SimpleResponse
|
||||
// internal/user/routes.go Line: 55
|
||||
export const resetPassword = async (
|
||||
data: ResetPasswordRequest,
|
||||
): Promise<{ data: responses.SimpleResponse; error: Nullable<string> }> => {
|
||||
return (await api.POST("/auth/password/reset", data)) as {
|
||||
data: responses.SimpleResponse;
|
||||
error: Nullable<string>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface LoginRequest {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface RefreshRequest {
|
||||
refresh_token: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number;
|
||||
email: string;
|
||||
name: string;
|
||||
roles: UserRoles;
|
||||
types: UserTypes;
|
||||
status: UserStatus;
|
||||
activatedAt: Date;
|
||||
uuid: string;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
avatar: Nullable<string>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface ForgotPasswordRequest {
|
||||
email: string;
|
||||
}
|
||||
|
||||
export interface ResetPasswordRequest {
|
||||
token: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface UpdateUserRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
types: UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
}
|
||||
|
||||
export interface UserCreateRequest {
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
roles: UserRoles;
|
||||
status: UserStatus;
|
||||
types: UserTypes;
|
||||
avatar: Nullable<string>;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
}
|
||||
|
||||
export interface UserDetails {
|
||||
id: number;
|
||||
userId: number;
|
||||
title: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
address: string;
|
||||
city: string;
|
||||
zipCode: string;
|
||||
country: string;
|
||||
phone: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface UserPreferences {
|
||||
id: number;
|
||||
userId: number;
|
||||
useIdle: boolean;
|
||||
idleTimeout: number;
|
||||
useIdlePassword: boolean;
|
||||
idlePin: string;
|
||||
useDirectLogin: boolean;
|
||||
useQuadcodeLogin: boolean;
|
||||
sendNoticesMail: boolean;
|
||||
language: string;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface UserProfile {
|
||||
id: number;
|
||||
email: string;
|
||||
name: string;
|
||||
roles: UserRoles;
|
||||
types: UserTypes;
|
||||
status: UserStatus;
|
||||
activatedAt: Date;
|
||||
uuid: string;
|
||||
details: Nullable<UserDetails>;
|
||||
preferences: Nullable<UserPreferences>;
|
||||
avatar: Nullable<string>;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export type UserTypes = string[];
|
||||
|
||||
export type UserRoles = string[];
|
||||
|
||||
export type UserStatus = (typeof EnumUserStatus)[keyof typeof EnumUserStatus];
|
||||
|
||||
export const EnumUserStatus = {
|
||||
UserStatusPending: "pending",
|
||||
UserStatusActive: "active",
|
||||
UserStatusDisabled: "disabled",
|
||||
} as const;
|
||||
|
|
@ -108,14 +108,14 @@ import { computed, onMounted, ref, watch } from 'vue';
|
|||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import LogoUrl from 'src/assets/home/logo.png';
|
||||
import { me, type UserShort } from 'src/api/api';
|
||||
import { me, type User } from 'src/api/users';
|
||||
import { usePreferencesStore, type LanguageCode } from 'src/stores/preferences-store';
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
const preferencesStore = usePreferencesStore();
|
||||
const currentUser = ref<UserShort | null>(null);
|
||||
const currentUser = ref<User | null>(null);
|
||||
const model = computed({
|
||||
get: () => preferencesStore.language,
|
||||
set: (language: LanguageCode) => {
|
||||
|
|
|
|||
|
|
@ -509,21 +509,24 @@ import VuePictureCropper from 'vue-picture-cropper';
|
|||
|
||||
import {
|
||||
blockUser,
|
||||
createUser,
|
||||
getUser,
|
||||
listUsers,
|
||||
updateUser,
|
||||
EnumUserStatus,
|
||||
type BlockUserRequest,
|
||||
type ListUsersRequest,
|
||||
}from 'src/api/admin';
|
||||
|
||||
import {
|
||||
createUser,
|
||||
getUser,
|
||||
updateUser,
|
||||
EnumUserStatus,
|
||||
type UpdateUserRequest,
|
||||
type UserCreateInput,
|
||||
type UserDetailsShort,
|
||||
type UserPreferencesShort,
|
||||
type UserCreateRequest,
|
||||
type UserProfile,
|
||||
type UserShort,
|
||||
type User,
|
||||
type UserStatus,
|
||||
} from 'src/api/api';
|
||||
type UserDetails,
|
||||
type UserPreferences,
|
||||
} from 'src/api/users';
|
||||
|
||||
type DialogMode = 'create' | 'edit' | 'view';
|
||||
|
||||
|
|
@ -536,8 +539,8 @@ interface UserFormState {
|
|||
roles: string[];
|
||||
types: string[];
|
||||
avatar: string;
|
||||
details: UserDetailsShort;
|
||||
preferences: UserPreferencesShort;
|
||||
details: UserDetails;
|
||||
preferences: UserPreferences;
|
||||
}
|
||||
|
||||
const $q = useQuasar();
|
||||
|
|
@ -550,7 +553,7 @@ const avatarDialogOpen = ref(false);
|
|||
const dialogMode = ref<DialogMode>('create');
|
||||
const editorTab = ref<'account' | 'details' | 'preferences'>('account');
|
||||
const filter = ref('');
|
||||
const rows = ref<UserShort[]>([]);
|
||||
const rows = ref<User[]>([]);
|
||||
const detailsEnabled = ref(true);
|
||||
const preferencesEnabled = ref(true);
|
||||
const passwordDialogUserUuid = ref('');
|
||||
|
|
@ -593,7 +596,7 @@ const avatarPresetMode = {
|
|||
height: 320,
|
||||
} as const;
|
||||
|
||||
const columns: QTableColumn<UserShort>[] = [
|
||||
const columns: QTableColumn<User>[] = [
|
||||
{ name: 'name', label: 'Utente', field: 'name', align: 'left', sortable: true },
|
||||
{ name: 'status', label: 'Status', field: 'status', align: 'left', sortable: true },
|
||||
{ name: 'roles', label: 'Roles', field: (row) => row.roles.join(', '), align: 'left' },
|
||||
|
|
@ -608,7 +611,7 @@ const passwordForm = reactive({
|
|||
confirmPassword: '',
|
||||
});
|
||||
|
||||
const payload = computed<UserCreateInput | UpdateUserRequest>(() => ({
|
||||
const payload = computed<UserCreateRequest | UpdateUserRequest>(() => ({
|
||||
name: form.name.trim(),
|
||||
email: form.email.trim(),
|
||||
password: dialogMode.value === 'create' ? form.password : '',
|
||||
|
|
@ -643,6 +646,10 @@ function emptyForm(): UserFormState {
|
|||
zipCode: '',
|
||||
country: '',
|
||||
phone: '',
|
||||
id: 0,
|
||||
userId: 0,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined
|
||||
},
|
||||
preferences: {
|
||||
useIdle: false,
|
||||
|
|
@ -653,6 +660,10 @@ function emptyForm(): UserFormState {
|
|||
useQuadcodeLogin: false,
|
||||
sendNoticesMail: false,
|
||||
language: 'it',
|
||||
id: 0,
|
||||
userId: 0,
|
||||
createdAt: undefined,
|
||||
updatedAt: undefined
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -955,7 +966,7 @@ async function saveUser(): Promise<void> {
|
|||
saving.value = true;
|
||||
try {
|
||||
if (dialogMode.value === 'create') {
|
||||
const response = await createUser(payload.value as UserCreateInput);
|
||||
const response = await createUser(payload.value as UserCreateRequest);
|
||||
if (response.error) {
|
||||
throw new Error(response.error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -124,16 +124,22 @@
|
|||
import { reactive, ref } from 'vue';
|
||||
import {
|
||||
forgotPassword,
|
||||
health,
|
||||
listUsers,
|
||||
login,
|
||||
me,
|
||||
metrics,
|
||||
refresh,
|
||||
register,
|
||||
resetPassword,
|
||||
} from 'src/api/api';
|
||||
import type { UserCreateInput } from 'src/api/api';
|
||||
type UserCreateRequest,
|
||||
} from 'src/api/users';
|
||||
|
||||
import {
|
||||
health,
|
||||
metrics,
|
||||
} from 'src/api/systemUtils';
|
||||
|
||||
import {
|
||||
listUsers,
|
||||
} from 'src/api/admin';
|
||||
|
||||
type Method = 'GET' | 'POST';
|
||||
type FieldType = 'text' | 'password' | 'number' | 'textarea';
|
||||
|
|
@ -385,7 +391,7 @@ const endpoints: EndpointConfig[] = [
|
|||
details: '',
|
||||
preferences: '',
|
||||
},
|
||||
call: (payload) => register(payload as UserCreateInput),
|
||||
call: (payload) => register(payload as UserCreateRequest),
|
||||
buildPayload: (form) => ({
|
||||
name: String(form.name ?? ''),
|
||||
email: String(form.email ?? ''),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
import { reactive, ref } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { login } from 'src/api/api';
|
||||
import { login } from 'src/api/users';
|
||||
|
||||
const router = useRouter();
|
||||
const $q = useQuasar();
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { mailDebug, type MailDebugItem } from 'src/api/api';
|
||||
import { mailDebug, type MailDebugItem } from 'src/api/systemUtils';
|
||||
|
||||
const $q = useQuasar();
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { forgotPassword } from 'src/api/api';
|
||||
import { forgotPassword } from 'src/api/users';
|
||||
|
||||
const $q = useQuasar();
|
||||
const loading = ref(false);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { resetPassword } from 'src/api/api';
|
||||
import { resetPassword } from 'src/api/users';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
<script setup lang="ts">
|
||||
import { nextTick, onMounted, reactive, ref, watch } from 'vue';
|
||||
import { useQuasar } from 'quasar';
|
||||
import { EnumUserStatus, register, type UserCreateInput } from 'src/api/api';
|
||||
import { EnumUserStatus, register, type UserCreateRequest } from 'src/api/users';
|
||||
|
||||
const $q = useQuasar();
|
||||
const loading = ref(false);
|
||||
|
|
@ -107,7 +107,7 @@ async function submit(): Promise<void> {
|
|||
|
||||
loading.value = true;
|
||||
try {
|
||||
const payload: UserCreateInput = {
|
||||
const payload: UserCreateRequest = {
|
||||
name: `${form.firstName.trim()} ${form.lastName.trim()}`.trim(),
|
||||
email: form.email.trim(),
|
||||
password: form.password,
|
||||
|
|
@ -124,6 +124,10 @@ async function submit(): Promise<void> {
|
|||
zipCode: '',
|
||||
country: '',
|
||||
phone: '',
|
||||
id: 0,
|
||||
userId: 0,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
},
|
||||
preferences: null,
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue