From b25a39df8cfa71f56ad4b8194830fba6babdd095 Mon Sep 17 00:00:00 2001 From: Marco Santos Date: Thu, 24 Jul 2025 11:40:08 +0100 Subject: [PATCH] Fix a generate --- README.md | 3 + geradoresfe/.env | 2 +- geradoresfe/package.json | 3 +- geradoresfe/src/Api/GeradorApi.tsx | 4 +- geradoresfe/src/App.tsx | 3 +- .../src/components/Geradores/GeradorCard.tsx | 2 +- .../Geradores/Tipos/GenerateNIF.tsx | 1 - .../Geradores/Tipos/GenerateNISS.tsx | 1 - geradoresfe/src/layout/Layout.tsx | 1 - geradoresfe/src/pages/Blank.tsx | 3 - geradoresfe/src/service/api.ts | 285 ++++++++---------- 11 files changed, 144 insertions(+), 164 deletions(-) diff --git a/README.md b/README.md index 22efff8..7bec620 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,6 @@ docker build -t shini89/geradoresws .. docker run --rm -p 44329:8080 shini89/geradoresws +npx swagger-typescript-api generate -p http://localhost:29191/swagger/v1/swagger.json -o src/service -n api.ts --enum-names-as-values + +npx swagger-typescript-api generate -p http://localhost:29191/swagger/v1/swagger.json -o src/service -n api.ts --http-client axios --enum-names-as-values \ No newline at end of file diff --git a/geradoresfe/.env b/geradoresfe/.env index 386a66c..e88a86e 100644 --- a/geradoresfe/.env +++ b/geradoresfe/.env @@ -1 +1 @@ -VITE_API_URL=http://localhost:44329/ \ No newline at end of file +VITE_API_URL=https://localhost:44329/ \ No newline at end of file diff --git a/geradoresfe/package.json b/geradoresfe/package.json index 1af4f62..9e54fa3 100644 --- a/geradoresfe/package.json +++ b/geradoresfe/package.json @@ -5,7 +5,7 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", + "build": "vite build", "lint": "eslint .", "preview": "vite preview" }, @@ -35,6 +35,7 @@ "eslint-plugin-react-refresh": "^0.4.20", "globals": "^16.3.0", "postcss": "^8.5.6", + "swagger-typescript-api": "^13.2.7", "tailwindcss": "^4.1.11", "typescript": "~5.8.3", "typescript-eslint": "^8.35.1", diff --git a/geradoresfe/src/Api/GeradorApi.tsx b/geradoresfe/src/Api/GeradorApi.tsx index 4dd910c..6a5c5a2 100644 --- a/geradoresfe/src/Api/GeradorApi.tsx +++ b/geradoresfe/src/Api/GeradorApi.tsx @@ -1,6 +1,5 @@ import axios from 'axios'; import type { AxiosResponse } from 'axios'; -import { NIFType } from '../service/api'; import { toast } from 'react-hot-toast'; const API_URL = import.meta.env.VITE_API_URL; @@ -8,6 +7,7 @@ const API_URL = import.meta.env.VITE_API_URL; class GeradorService { static async GenerateNIF(type: string | null): Promise { try { + debugger; const response: AxiosResponse = await axios.get(API_URL + 'Generate/GenerateNIF', { params: { @@ -15,7 +15,7 @@ class GeradorService { } }); return response.data; - } catch (error) { + } catch (error : any) { toast.error('Error fetching NIF:' + error.message); return []; diff --git a/geradoresfe/src/App.tsx b/geradoresfe/src/App.tsx index 0310a4a..efa6731 100644 --- a/geradoresfe/src/App.tsx +++ b/geradoresfe/src/App.tsx @@ -22,8 +22,7 @@ function App() { background: theme === 'dark' ? '#1f2937' : '#fff', color: theme === 'dark' ? '#fff' : '#000', }, - }} - theme={theme} /> + }} /> ); diff --git a/geradoresfe/src/components/Geradores/GeradorCard.tsx b/geradoresfe/src/components/Geradores/GeradorCard.tsx index d3bf3e9..b27e9c4 100644 --- a/geradoresfe/src/components/Geradores/GeradorCard.tsx +++ b/geradoresfe/src/components/Geradores/GeradorCard.tsx @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import { useState } from "react"; import { RefreshCwIcon, CopyIcon } from "lucide-react"; import { Button } from "../ui/Button"; import { Input } from "../ui/Input"; diff --git a/geradoresfe/src/components/Geradores/Tipos/GenerateNIF.tsx b/geradoresfe/src/components/Geradores/Tipos/GenerateNIF.tsx index d036215..d203e2e 100644 --- a/geradoresfe/src/components/Geradores/Tipos/GenerateNIF.tsx +++ b/geradoresfe/src/components/Geradores/Tipos/GenerateNIF.tsx @@ -1,4 +1,3 @@ -import React from "react"; import GeradorCard from "../GeradorCard"; import { EnumToOptions } from "../../../library/utils"; import { NIFType } from "../../../service/api"; diff --git a/geradoresfe/src/components/Geradores/Tipos/GenerateNISS.tsx b/geradoresfe/src/components/Geradores/Tipos/GenerateNISS.tsx index 28a434f..ad450b4 100644 --- a/geradoresfe/src/components/Geradores/Tipos/GenerateNISS.tsx +++ b/geradoresfe/src/components/Geradores/Tipos/GenerateNISS.tsx @@ -1,4 +1,3 @@ -import { useEffect, useState } from "react"; import GeradorService from "../../../Api/GeradorApi"; import GeradorCard from "../GeradorCard.tsx"; diff --git a/geradoresfe/src/layout/Layout.tsx b/geradoresfe/src/layout/Layout.tsx index 2fcc986..b6c8eae 100644 --- a/geradoresfe/src/layout/Layout.tsx +++ b/geradoresfe/src/layout/Layout.tsx @@ -1,7 +1,6 @@ // components/layout/Layout.tsx import Footer from './Footer'; import Header from './Header'; -import { useTheme } from "../context/ThemeContext"; // caminho conforme a tua estrutura export const Layout = ({ children }: { children: React.ReactNode }) => { diff --git a/geradoresfe/src/pages/Blank.tsx b/geradoresfe/src/pages/Blank.tsx index e18a83c..f084490 100644 --- a/geradoresfe/src/pages/Blank.tsx +++ b/geradoresfe/src/pages/Blank.tsx @@ -1,6 +1,3 @@ -import React from "react"; - - export default function Blank() { console.log("inicalizar componente"); return ( diff --git a/geradoresfe/src/service/api.ts b/geradoresfe/src/service/api.ts index f6d74dc..702a3c5 100644 --- a/geradoresfe/src/service/api.ts +++ b/geradoresfe/src/service/api.ts @@ -1,5 +1,6 @@ /* eslint-disable */ /* tslint:disable */ +// @ts-nocheck /* * --------------------------------------------------------------- * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ## @@ -10,12 +11,19 @@ */ export enum NIFType { + /** Pessoa singular (1) */ PessoaSingular1 = "Pessoa singular (1)", + /** Pessoa singular (2) */ PessoaSingular2 = "Pessoa singular (2)", + /** Pessoa singular (3; novo em 2019) */ PessoaSingular3 = "Pessoa singular (3; novo em 2019)", + /** Pessoa colectiva (5) */ PessoaColectiva = "Pessoa colectiva (5)", + /** Pessoa colectiva pública (6) */ PessoaColectivaPublica = "Pessoa colectiva pública (6)", + /** Empresário em nome individual (8) */ EmpresarioIndividual = "Empresário em nome individual (8)", + /** Pessoa colectiva irregular ou número provisório (9) */ PessoaColectivaIrregular = "Pessoa colectiva irregular ou número provisório (9)", } @@ -29,10 +37,19 @@ export interface WeatherForecast { summary?: string | null; } -export type QueryParamsType = Record; -export type ResponseFormat = keyof Omit; +import type { + AxiosInstance, + AxiosRequestConfig, + AxiosResponse, + HeadersDefaults, + ResponseType, +} from "axios"; +import axios from "axios"; -export interface FullRequestParams extends Omit { +export type QueryParamsType = Record; + +export interface FullRequestParams + extends Omit { /** set parameter to `true` for call `securityWorker` for this request */ secure?: boolean; /** request path */ @@ -42,199 +59,155 @@ export interface FullRequestParams extends Omit { /** query params */ query?: QueryParamsType; /** format of response (i.e. response.json() -> format: "json") */ - format?: ResponseFormat; + format?: ResponseType; /** request body */ body?: unknown; - /** base url */ - baseUrl?: string; - /** request cancellation token */ - cancelToken?: CancelToken; } -export type RequestParams = Omit; +export type RequestParams = Omit< + FullRequestParams, + "body" | "method" | "query" | "path" +>; -export interface ApiConfig { - baseUrl?: string; - baseApiParams?: Omit; - securityWorker?: (securityData: SecurityDataType | null) => Promise | RequestParams | void; - customFetch?: typeof fetch; +export interface ApiConfig + extends Omit { + securityWorker?: ( + securityData: SecurityDataType | null, + ) => Promise | AxiosRequestConfig | void; + secure?: boolean; + format?: ResponseType; } -export interface HttpResponse extends Response { - data: D; - error: E; -} - -type CancelToken = Symbol | string | number; - export enum ContentType { Json = "application/json", + JsonApi = "application/vnd.api+json", FormData = "multipart/form-data", UrlEncoded = "application/x-www-form-urlencoded", Text = "text/plain", } export class HttpClient { - public baseUrl: string = ""; + public instance: AxiosInstance; private securityData: SecurityDataType | null = null; private securityWorker?: ApiConfig["securityWorker"]; - private abortControllers = new Map(); - private customFetch = (...fetchParams: Parameters) => fetch(...fetchParams); + private secure?: boolean; + private format?: ResponseType; - private baseApiParams: RequestParams = { - credentials: "same-origin", - headers: {}, - redirect: "follow", - referrerPolicy: "no-referrer", - }; - - constructor(apiConfig: ApiConfig = {}) { - Object.assign(this, apiConfig); + constructor({ + securityWorker, + secure, + format, + ...axiosConfig + }: ApiConfig = {}) { + this.instance = axios.create({ + ...axiosConfig, + baseURL: axiosConfig.baseURL || "", + }); + this.secure = secure; + this.format = format; + this.securityWorker = securityWorker; } public setSecurityData = (data: SecurityDataType | null) => { this.securityData = data; }; - protected encodeQueryParam(key: string, value: any) { - const encodedKey = encodeURIComponent(key); - return `${encodedKey}=${encodeURIComponent(typeof value === "number" ? value : `${value}`)}`; - } + protected mergeRequestParams( + params1: AxiosRequestConfig, + params2?: AxiosRequestConfig, + ): AxiosRequestConfig { + const method = params1.method || (params2 && params2.method); - protected addQueryParam(query: QueryParamsType, key: string) { - return this.encodeQueryParam(key, query[key]); - } - - protected addArrayQueryParam(query: QueryParamsType, key: string) { - const value = query[key]; - return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); - } - - protected toQueryString(rawQuery?: QueryParamsType): string { - const query = rawQuery || {}; - const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]); - return keys - .map((key) => (Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key))) - .join("&"); - } - - protected addQueryParams(rawQuery?: QueryParamsType): string { - const queryString = this.toQueryString(rawQuery); - return queryString ? `?${queryString}` : ""; - } - - private contentFormatters: Record any> = { - [ContentType.Json]: (input: any) => - input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input, - [ContentType.Text]: (input: any) => (input !== null && typeof input !== "string" ? JSON.stringify(input) : input), - [ContentType.FormData]: (input: any) => - Object.keys(input || {}).reduce((formData, key) => { - const property = input[key]; - formData.append( - key, - property instanceof Blob - ? property - : typeof property === "object" && property !== null - ? JSON.stringify(property) - : `${property}`, - ); - return formData; - }, new FormData()), - [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input), - }; - - protected mergeRequestParams(params1: RequestParams, params2?: RequestParams): RequestParams { return { - ...this.baseApiParams, + ...this.instance.defaults, ...params1, ...(params2 || {}), headers: { - ...(this.baseApiParams.headers || {}), + ...((method && + this.instance.defaults.headers[ + method.toLowerCase() as keyof HeadersDefaults + ]) || + {}), ...(params1.headers || {}), ...((params2 && params2.headers) || {}), }, }; } - protected createAbortSignal = (cancelToken: CancelToken): AbortSignal | undefined => { - if (this.abortControllers.has(cancelToken)) { - const abortController = this.abortControllers.get(cancelToken); - if (abortController) { - return abortController.signal; + protected stringifyFormItem(formItem: unknown) { + if (typeof formItem === "object" && formItem !== null) { + return JSON.stringify(formItem); + } else { + return `${formItem}`; + } + } + + protected createFormData(input: Record): FormData { + if (input instanceof FormData) { + return input; + } + return Object.keys(input || {}).reduce((formData, key) => { + const property = input[key]; + const propertyContent: any[] = + property instanceof Array ? property : [property]; + + for (const formItem of propertyContent) { + const isFileType = formItem instanceof Blob || formItem instanceof File; + formData.append( + key, + isFileType ? formItem : this.stringifyFormItem(formItem), + ); } - return void 0; - } - const abortController = new AbortController(); - this.abortControllers.set(cancelToken, abortController); - return abortController.signal; - }; + return formData; + }, new FormData()); + } - public abortRequest = (cancelToken: CancelToken) => { - const abortController = this.abortControllers.get(cancelToken); - - if (abortController) { - abortController.abort(); - this.abortControllers.delete(cancelToken); - } - }; - - public request = async ({ - body, + public request = async ({ secure, path, type, query, format, - baseUrl, - cancelToken, + body, ...params - }: FullRequestParams): Promise> => { + }: FullRequestParams): Promise> => { const secureParams = - ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) && + ((typeof secure === "boolean" ? secure : this.secure) && this.securityWorker && (await this.securityWorker(this.securityData))) || {}; const requestParams = this.mergeRequestParams(params, secureParams); - const queryString = query && this.toQueryString(query); - const payloadFormatter = this.contentFormatters[type || ContentType.Json]; - const responseFormat = format || requestParams.format; + const responseFormat = format || this.format || undefined; - return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, { + if ( + type === ContentType.FormData && + body && + body !== null && + typeof body === "object" + ) { + body = this.createFormData(body as Record); + } + + if ( + type === ContentType.Text && + body && + body !== null && + typeof body !== "string" + ) { + body = JSON.stringify(body); + } + + return this.instance.request({ ...requestParams, headers: { ...(requestParams.headers || {}), - ...(type && type !== ContentType.FormData ? { "Content-Type": type } : {}), + ...(type ? { "Content-Type": type } : {}), }, - signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null, - body: typeof body === "undefined" || body === null ? null : payloadFormatter(body), - }).then(async (response) => { - const r = response.clone() as HttpResponse; - r.data = null as unknown as T; - r.error = null as unknown as E; - - const data = !responseFormat - ? r - : await response[responseFormat]() - .then((data) => { - if (r.ok) { - r.data = data; - } else { - r.error = data; - } - return r; - }) - .catch((e) => { - r.error = e; - return r; - }); - - if (cancelToken) { - this.abortControllers.delete(cancelToken); - } - - if (!response.ok) throw data; - return data; + params: query, + responseType: responseFormat, + data: body, + url: path, }); }; } @@ -244,7 +217,9 @@ export class HttpClient { * @version v1 * @contact Marco Santos */ -export class Api extends HttpClient { +export class Api< + SecurityDataType extends unknown, +> extends HttpClient { generate = { /** * No description @@ -255,14 +230,7 @@ export class Api extends HttpClient @@ -330,6 +298,21 @@ export class Api extends HttpClient + this.request({ + path: `/Generate/GenerateCC`, + method: "GET", + format: "json", + ...params, + }), }; weatherForecast = { /**