Possible bug with `.ManageType`
shackra opened this issue · 5 comments
so I get
'd the new version of this package and generate a few more types for my project, but for some reasons empty interfaces like Time
and Decimal
(that one was new) were getting generated despite having ts_type
set on some fields of some structs and also using the new feature you recently merged and polished.
This is the generated file:
/* Do not change, this code is generated from Golang structs */
import { Decimal } from 'decimal.js'
export interface UpdateInvoicesRequest {
claves: string[];
estado: number;
}
export interface InformacionReferencia {
tipo_doc: number;
numero: string;
fecha_emision: Date;
codigo: number;
razon: string;
}
export interface OtroCargo {
tipo_documento: number;
detalle: string;
porcentaje: Decimal;
monto_cargo: Decimal;
}
export interface Exoneracion {
tipo_documento: number;
numero_documento: string;
nombre_institucion: string;
fecha_emision: Date;
porcentaje_exoneracion: Decimal;
monto_exoneracion: Decimal;
}
export interface Impuesto {
codigo: number;
codigo_tarifa: number;
tarifa: Decimal;
factor_iva?: Decimal;
monto: Decimal;
exoneracion?: Exoneracion;
}
export interface CodigoComercial {
tipo: number;
codigo: string;
}
export interface LineaDetalle {
numero_linea: number;
partida_arancelaria?: string;
codigos_comerciales: CodigoComercial[];
codigo_producto: string;
cantidad: Decimal;
unidad_medida: string;
unidad_medida_comercial?: string;
detalle: string;
impuesto: Impuesto[];
impuesto_neto: Decimal;
precio_unitario: Decimal;
monto_descuento?: Decimal;
naturaleza_descuento?: string;
monto_total: Decimal;
sub_total: Decimal;
base_imponible?: Decimal;
monto_total_linea: Decimal;
}
export interface Receptor {
nombre: string;
nombre_comercial: string;
identificacion_tipo: number;
identificacion_numero: string;
identificacion_extranjero: string;
provincia: number;
canton: number;
distrito: number;
barrio: number;
otras_senas: string;
otras_senas_extranjero: string;
correo_electronico: string;
telefono_codigo: number;
telefono_numero: string;
fax_codigo: number;
fax_numero: string;
}
export interface InvoiceCreateRequest {
emisor: string;
email: string;
tipo: number;
codigo_moneda: string;
tipo_cambio: Decimal;
actividad_economica: string;
condicion_venta: number;
plazo_credito: number;
caja: number;
sucursal: number;
receptor?: Receptor;
linea_detalle: LineaDetalle[];
otros_cargos: OtroCargo[];
informacion_referencia: InformacionReferencia[];
}
export interface UpdatePasswordRequest {
clave: string;
token: string;
}
export interface RefreshTokenRequest {
token: string;
}
export interface CredentialsRequest {
cuenta: string;
clave: string;
}
export interface PasswordResetRequest {
cuenta: string;
}
export interface ForwardInvoiceTo {
email: string;
}
export interface Consecutivo {
id: number;
tipo: number;
sucursal: number;
caja: number;
contador: number;
}
export interface GetCountersResp {
consecutivos: Consecutivo[];
cantidad: number;
}
export interface Emisor {
nombre: string;
nombre_comercial: string;
identificacion_tipo: number;
identificacion_numero: string;
provincia: number;
canton: number;
distrito: number;
barrio: number;
otras_senas: string;
correo_electronico: string;
telefono_codigo: number;
telefono_numero: string;
fax_codigo: number;
fax_numero: string;
}
export interface SearchIssuersResp {
issuers: Emisor[];
}
export interface UpdateCounterReq {
emisor: string;
tipo: number;
sucursal: number;
caja: number;
top: number;
}
export interface UpdateIssuerInfoReq {
nombre?: string;
nombre_comercial?: string;
id_tipo?: number;
id_num?: string;
correo?: string;
telf_codigo?: number;
telf_num?: string;
fax_codigo?: number;
fax_num?: string;
}
export interface UpdateIssuerLocationReq {
otras_senas?: string;
provincia?: number;
canton?: number;
distrito?: number;
barrio?: number;
}
export interface CreateSubscriptionReq {
identificacion: string;
identificacion_tipo: number;
tipo: number;
nombre: string;
correo: string;
primer_usuario_correo: string;
}
export interface SubscriptionIsDueResponse {
yes: boolean;
}
export interface Decimal { // HERE!!
}
export interface Subscription {
tipo: number;
identificacion_tipo: number;
identificacion_numero: string;
nombre: string;
email: string;
primer_pago?: Date;
siguiente_pago?: Date;
fecha_creado: Date;
fecha_actualizado: Date;
costo: Decimal;
adicional: Decimal;
}
export interface ListSubscriptionsResponse {
suscripciones: Subscription[];
cantidad: number;
}
export interface UpdateSubscriptionPrice {
base?: Decimal;
adicional?: Decimal;
}
export interface UpdateSubscriptionStatus {
emisores: string[];
estado: number;
}
export interface Time { // HERE TOO!
}
export interface Token {
iss?: string;
sub?: string;
aud?: string[];
exp?: Time;
nbf?: Time;
iat?: Time;
jti?: string;
user: string;
subcripcion: string;
rules: {[key: string]: string[]};
}
export interface Resumen {
total_servicios_gravados: Decimal;
total_servicios_exentos: Decimal;
total_servicios_exonerado: Decimal;
total_mercancias_gravadas: Decimal;
total_mercancias_exentas: Decimal;
total_mercancias_exonerada: Decimal;
total_gravado: Decimal;
total_exento: Decimal;
total_exonerado: Decimal;
total_venta: Decimal;
total_descuentos: Decimal;
total_venta_neta: Decimal;
total_impuesto: Decimal;
total_iva_devuelto: Decimal;
total_otros_cargos: Decimal;
total_comprobante: Decimal;
}
export interface FormaPago {
nombre: string;
codigo: number;
}
export interface Documento {
id: number;
clave: string;
consecutivo: string;
tipo: number;
caja: number;
sucursal: number;
estado: number;
emisor: Emisor;
receptor?: Receptor;
actividad: string;
fecha_emision: Date;
condicion_venta: number;
plazo_credito: number;
forma_pago: FormaPago[];
linea_detalle: LineaDetalle[];
otros_cargos: OtroCargo[];
informacion_referencia: InformacionReferencia[];
codigo_moneda: string;
tipo_cambio: Decimal;
normativa: string;
resumenes?: Resumen;
}
export interface Tokens {
access: string;
refresh: string;
}
and this is the Golang file:
package main
import (
"flag"
"os"
"path/filepath"
"time"
"github.com/sirupsen/logrus"
"github.com/tkrajina/typescriptify-golang-structs/typescriptify"
http_transport "gitlab.com/kuecr/fero/backend/monolith/pkg/http"
"gitlab.com/kuecr/fero/backend/monolith/pkg/json_web_token"
"gitlab.com/kuecr/fero/backend/monolith/pkg/service"
)
func main() {
ubicacionPtr := flag.String("salida", "", "archivo ts donde iran los tipos generados")
flag.Parse()
archivo, err := filepath.Abs(*ubicacionPtr)
if err != nil {
logrus.Panicf("no se pudo obtener ubicacion absoluta: %v", err)
}
converter := typescriptify.New()
// convierte time.Time en Date para Typescript
converter = converter.ManageType(time.Time{}, typescriptify.TypeOptions{TSType: "Date"})
converter.Add(http_transport.UpdateInvoicesRequest{})
converter.Add(http_transport.InvoiceCreateRequest{})
converter.Add(http_transport.UpdatePasswordRequest{})
converter.Add(http_transport.RefreshTokenRequest{})
converter.Add(http_transport.CredentialsRequest{})
converter.Add(http_transport.PasswordResetRequest{})
converter.Add(http_transport.ForwardInvoiceTo{})
converter.Add(http_transport.GetCountersResp{})
converter.Add(http_transport.SearchIssuersResp{})
converter.Add(http_transport.UpdateCounterReq{})
converter.Add(http_transport.UpdateIssuerInfoReq{})
converter.Add(http_transport.UpdateIssuerLocationReq{})
converter.Add(http_transport.CreateSubscriptionReq{})
converter.Add(http_transport.SubscriptionIsDueResponse{})
converter.Add(http_transport.ListSubscriptionsResponse{})
converter.Add(http_transport.UpdateSubscriptionPrice{})
converter.Add(http_transport.UpdateSubscriptionStatus{})
converter.Add(json_web_token.Token{})
converter.Add(service.Documento{})
converter.Add(service.Tokens{})
converter.AddImport("import { Decimal } from 'decimal.js'")
converter.BackupDir = ""
converter.CreateInterface = true
err = converter.ConvertToFile(archivo)
if err != nil {
logrus.Errorf("no se pudo convertir structs a tipos typescript: %v", err)
os.Exit(1)
}
}
I want through each struct there and checked that each field with a decimal.Decimal
type has its ts_type:"Decimal"
tag set and converter = converter.ManageType(time.Time{}, typescriptify.TypeOptions{TSType: "Date"})
seems correct to me, but, yeah, despite that I get empty interfaces (and Decimal as an empty interface is a new error, I've never see that behavior before)
In my fork I tried to reproduce the error with what I thought was the culprid: https://github.com/shackra/typescriptify-golang-structs/blob/weird-bug/typescriptify/typescriptify_test.go#L444
But surprisingly the test runs fine:
➜ go test ./... -run TestAnonymousStructWithManagedType
? _/home/jorge/code/typescriptify-golang-structs/example [no test files]
? _/home/jorge/code/typescriptify-golang-structs/tscriptify [no test files]
----------------------------------------------------------------------------------------------------
export interface Target {
my_time: Date;
price: Decimal;
}
----------------------------------------------------------------------------------------------------
OK: export interface Target {
OK: my_time: Date;
OK: price: Decimal;
OK: }
tmp ts: /tmp/728430900.ts
executing: /tmp/728430900.js
--- FAIL: TestAnonymousStructWithManagedType (1.30s)
typescriptify_test.go:342:
Error Trace: typescriptify_test.go:342
typescriptify_test.go:319
typescriptify_test.go:469
Error: Expected nil, but got: &exec.ExitError{ProcessState:(*os.ProcessState)(0xc00000e640), Stderr:[]uint8(nil)}
Test: TestAnonymousStructWithManagedType
Messages: ../../../../../tmp/728430900.ts(3,12): error TS2304: Cannot find name 'Decimal'.
FAIL
FAIL _/home/jorge/code/typescriptify-golang-structs/typescriptify 1.300s
FAIL
I pushed another branch debug-logging
. With it you can add some additional debug logging by setting converter.Debug = true
. With that, you'll get the fields which cause the converter to create new models, for example:
Converting struct typescriptify.TestCustomType
Struct TestCustomType.Time (time.Time) => convert
So here, the Test
field in TestCustomType
is causing a new Time
class/interface to be created. Then, find which field is causing the empty Time
, and try to write a minimal reproducible test with that struct.
Also, add this:
converter.AddImport("type Decimal = number;") // Not an import, I know :)
in your TestAnonymousStructWithManagedType
not make the generated script to compile (and the test to finish without errors).
I use Go modules in my project, to use your branch I need to clone the repository in vendors/
maybe? I'll try to figure that out tonight
Yes, you can clone it temporary. But you can also:
go get github.com/tkrajina/typescriptify-golang-structs@ddc6a2f51e3cde9d0c1dae7b9f3e50b433f6e9d3
go mod vendor
ddc6a2f is the last commit in debug-logging
. Or, you can specify a branch:
go get github.com/tkrajina/typescriptify-golang-structs@debug-logging
go mod vendor
I get the following:
Converting struct http_transport.UpdateInvoicesRequest
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.InvoiceCreateRequest
Struct InvoiceCreateRequest.Receptor (service.Receptor) => convert
Converting struct service.Receptor
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct InvoiceCreateRequest.LineaDetalle ([]service.LineaDetalle) => convert
Converting struct service.LineaDetalle
Struct LineaDetalle.CodigosComerciales ([]service.CodigoComercial) => convert
Converting struct service.CodigoComercial
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct LineaDetalle.Impuesto ([]service.Impuesto) => convert
Converting struct service.Impuesto
Struct Impuesto.Exoneracion (service.Exoneracion) => convert
Converting struct service.Exoneracion
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct InvoiceCreateRequest.OtrosCargos ([]service.OtroCargo) => convert
Converting struct service.OtroCargo
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct InvoiceCreateRequest.InformacionReferencia ([]service.InformacionReferencia) => convert
Converting struct service.InformacionReferencia
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdatePasswordRequest
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.RefreshTokenRequest
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.CredentialsRequest
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.PasswordResetRequest
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.ForwardInvoiceTo
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.GetCountersResp
Struct GetCountersResp.Consecutivos ([]service.Consecutivo) => convert
Converting struct service.Consecutivo
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.SearchIssuersResp
Struct SearchIssuersResp.Issuers ([]service.Emisor) => convert
Converting struct service.Emisor
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdateCounterReq
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdateIssuerInfoReq
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdateIssuerLocationReq
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.CreateSubscriptionReq
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.SubscriptionIsDueResponse
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.ListSubscriptionsResponse
Struct ListSubscriptionsResponse.Suscripciones ([]service.Subscription) => convert
Converting struct service.Subscription
Struct Subscription.Costo (decimal.Decimal) => convert
Converting struct decimal.Decimal
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct Subscription.Adicional (decimal.Decimal) => convert
Converting struct decimal.Decimal
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdateSubscriptionPrice
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct http_transport.UpdateSubscriptionStatus
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct json_web_token.Token
Struct Token.ExpirationTime (jwt.Time) => convert
Converting struct jwt.Time
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct Token.NotBefore (jwt.Time) => convert
Converting struct jwt.Time
Struct Token.IssuedAt (jwt.Time) => convert
Converting struct jwt.Time
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct service.Documento
Struct Documento.Emisor (service.Emisor) => convert
Converting struct service.Emisor
Struct Documento.Receptor (service.Receptor) => convert
Converting struct service.Receptor
Struct Documento.FormaPago ([]service.FormaPago) => convert
Converting struct service.FormaPago
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Struct Documento.LineaDetalle ([]service.LineaDetalle) => convert
Converting struct service.LineaDetalle
Struct Documento.OtrosCargos ([]service.OtroCargo) => convert
Converting struct service.OtroCargo
Struct Documento.InformacionReferencia ([]service.InformacionReferencia) => convert
Converting struct service.InformacionReferencia
Struct Documento.Resumenes (service.Resumen) => convert
Converting struct service.Resumen
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
Converting struct service.Tokens
FromMethod METHOD IS DEPRECATED AND WILL BE REMOVED!!!!!!
I think I can see the offender
Converting struct service.Subscription
Struct Subscription.Costo (decimal.Decimal) => convert
Converting struct decimal.Decimal
Indeed, there is no bug, there was another struct called Time
that needed to be managed, and I was missing tags in some of my structs too.