From 01fba79e38ac0203011b4fdfa207bc707e1f8363 Mon Sep 17 00:00:00 2001 From: david Date: Wed, 19 Aug 2026 10:39:15 +0200 Subject: [PATCH] feat: update TypeScript configurations and add frontend testing documentation --- apps/server/tsconfig.json | 1 + apps/web/tsconfig.app.json | 2 + apps/web/tsconfig.json | 2 + docs/README.md | 1 + docs/testing/frontend-node-test.md | 76 +++++++++++++++++ modules/auth/tsconfig.json | 1 + modules/catalogs/tsconfig.json | 1 + modules/companies/tsconfig.json | 1 + modules/core/tsconfig.json | 1 + ...ze-issued-invoice-v2-domain.mapper.test.ts | 81 ++++++++++++++++++- ...quelize-issued-invoice-v2-domain.mapper.ts | 49 ++++++----- modules/customer-invoices/src/web/i18n.ts | 10 +-- modules/customer-invoices/src/web/manifest.ts | 3 +- .../customer-invoices/src/web/module-name.ts | 1 + .../ui/pages/proforma-update-page.test.tsx | 18 +++++ modules/customer-invoices/tsconfig.json | 1 + modules/customers/tsconfig.json | 1 + modules/document-series/tsconfig.json | 1 + modules/factuges/tsconfig.json | 1 + modules/identity/tsconfig.json | 1 + modules/supplier-invoices/tsconfig.json | 1 + modules/supplier/tsconfig.json | 1 + package.json | 5 +- packages/rdx-ui/tsconfig.json | 1 + packages/rdx-utils/tsconfig.json | 1 + packages/shadcn-ui/tsconfig.json | 1 + packages/typescript-config/base.json | 1 + packages/typescript-config/express.json | 1 + packages/typescript-config/root.json | 40 +++------ pnpm-lock.yaml | 3 + tsconfig.json | 4 + 31 files changed, 254 insertions(+), 58 deletions(-) create mode 100644 docs/testing/frontend-node-test.md create mode 100644 modules/customer-invoices/src/web/module-name.ts diff --git a/apps/server/tsconfig.json b/apps/server/tsconfig.json index 703596eb..d56c4c33 100644 --- a/apps/server/tsconfig.json +++ b/apps/server/tsconfig.json @@ -2,6 +2,7 @@ "extends": "@repo/typescript-config/express.json", "compilerOptions": { + "baseUrl": ".", "noEmit": true, "allowImportingTsExtensions": true, "lib": ["ES2022"], diff --git a/apps/web/tsconfig.app.json b/apps/web/tsconfig.app.json index 79c91ce8..1723a2d4 100644 --- a/apps/web/tsconfig.app.json +++ b/apps/web/tsconfig.app.json @@ -1,5 +1,6 @@ { "compilerOptions": { + "baseUrl": ".", "paths": { "@/*": ["./src/*"] }, @@ -16,6 +17,7 @@ "isolatedModules": true, "moduleDetection": "force", "noEmit": true, + "ignoreDeprecations": "6.0", "jsx": "react-jsx", /* Linting */ diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json index 19c9df7a..bd0e101a 100644 --- a/apps/web/tsconfig.json +++ b/apps/web/tsconfig.json @@ -2,6 +2,8 @@ "files": [], "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }], "compilerOptions": { + "baseUrl": ".", + "ignoreDeprecations": "6.0", "resolveJsonModule": true, "esModuleInterop": true, "paths": { diff --git a/docs/README.md b/docs/README.md index 5b6ad42c..ae33cc7a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -53,6 +53,7 @@ Este directorio reúne la documentación técnica, operativa y de apoyo del ERP. - [README de `modules/auth`](../modules/auth/README.md) - [API pública de selección y alta rápida de clientes](./customers/customer-selection-and-quick-create.md) - [Tests HTTP backend](./testing/backend-http-integration.md) +- [Harness frontend con `node:test`](./testing/frontend-node-test.md) #### Guías y estándares diff --git a/docs/testing/frontend-node-test.md b/docs/testing/frontend-node-test.md new file mode 100644 index 00000000..37bc7622 --- /dev/null +++ b/docs/testing/frontend-node-test.md @@ -0,0 +1,76 @@ +# Tests frontend con `node:test` + +El harness frontend vigente del ERP usa: + +- `node:test` como runner +- `tsx` como transpiler +- renderizado en Node puro +- `react-dom/server` para tests React sin DOM real + +No existe infraestructura activa de `vitest`, `jest`, `jsdom` ni `happy-dom` en el monorepo. + +## Requisitos + +Ejecuta los tests en Ubuntu desde la raíz del repo: + +```bash +cd /home/rodax/Documentos/uecko-erp +node --version +pnpm --version +``` + +El runtime esperado del repo es Node `>= 24`. + +## Comandos canónicos + +### Test React individual + +```bash +cd /home/rodax/Documentos/uecko-erp +pnpm test:frontend -- modules/customer-invoices/src/web/proformas/update/ui/components/proforma-update-help-popover.test.tsx +``` + +### Tests frontend de un módulo + +```bash +cd /home/rodax/Documentos/uecko-erp +pnpm test:frontend -- modules/customer-invoices/src/web/**/*.test.tsx +``` + +### Tests frontend de `apps/web` + +```bash +cd /home/rodax/Documentos/uecko-erp +pnpm test:frontend -- apps/web/src/**/*.test.tsx +``` + +### Test TypeScript puro + +```bash +cd /home/rodax/Documentos/uecko-erp +pnpm test:unit -- packages/rdx-utils/src/helpers/__tests__/maybe.test.ts +``` + +## Mocking + +Los tests frontend que necesitan mocks de módulos deben usar `mock.module()` de `node:test`. + +Eso obliga a ejecutar el runner con: + +```bash +node --experimental-test-module-mocks --import tsx --test +``` + +Por eso el script oficial es `pnpm test:frontend`. + +## Qué no hacer + +- No ejecutar tests React con `pnpm dlx tsx --test` si el test usa `mock.module()`. +- No asumir `jsdom` o `@testing-library/react` si el test actual solo necesita SSR. +- No importar barrels amplios si el test solo necesita un componente o helper local. + +## Criterios prácticos + +- Usa `pnpm test:unit` para tests `.ts` o `.tsx` que no dependan de `mock.module()`. +- Usa `pnpm test:frontend` cuando el test React necesite `mock.module()`. +- Si un componente necesita traducciones, mockea `../../../../i18n` o el helper local antes de arrancar el `manifest` del módulo. diff --git a/modules/auth/tsconfig.json b/modules/auth/tsconfig.json index 58f8d90a..38385361 100644 --- a/modules/auth/tsconfig.json +++ b/modules/auth/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/auth/*": ["./src/*"] }, diff --git a/modules/catalogs/tsconfig.json b/modules/catalogs/tsconfig.json index 99485e0d..8f79764d 100644 --- a/modules/catalogs/tsconfig.json +++ b/modules/catalogs/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/catalogs/*": ["./src/*"] }, diff --git a/modules/companies/tsconfig.json b/modules/companies/tsconfig.json index 3926998c..273e2407 100644 --- a/modules/companies/tsconfig.json +++ b/modules/companies/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/companies/*": ["./src/*"] }, diff --git a/modules/core/tsconfig.json b/modules/core/tsconfig.json index 0c4ef2ea..00dfcb5e 100644 --- a/modules/core/tsconfig.json +++ b/modules/core/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/core/*": ["./src/*"] }, diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.test.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.test.ts index ba71caed..e38f4c72 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.test.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.test.ts @@ -1,6 +1,7 @@ import assert from "node:assert/strict"; import test from "node:test"; +import { UtcDate } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; import { SequelizeIssuedInvoiceV2DomainMapper } from "./sequelize-issued-invoice-v2-domain.mapper"; @@ -25,7 +26,9 @@ type PaymentTermRoundTripReadResult = { }; const buildMapper = () => { - const mapper = new SequelizeIssuedInvoiceV2DomainMapper({} as never) as unknown as { + const mapper = new SequelizeIssuedInvoiceV2DomainMapper({ + taxCatalog: {}, + } as never) as unknown as { _itemsMapper: { mapToPersistenceArray: () => ReturnType>; }; @@ -267,6 +270,82 @@ test("rehidrata el snapshot persistido histórico sin depender del catálogo viv ]); }); +test("normaliza verifactu_effective_at Date a YYYY-MM-DD al rehidratar", () => { + const mapper = buildMapper(); + const raw = { + verifactu_effective_at: new Date("2027-01-12T00:00:00.000Z"), + } as { + verifactu_effective_at: Date; + }; + + const result = mapper.mapToDomain.bind(mapper) as unknown; + assert.ok(result); + + const effectiveAt = mapper as unknown as { + _mapAttributesToDomain: ( + source: unknown, + params: { errors: Array<{ message: string; path: string; value?: unknown }> } + ) => { hasVerifactuSnapshots: boolean }; + }; + + const errors: Array<{ message: string; path: string; value?: unknown }> = []; + const attributes = effectiveAt._mapAttributesToDomain( + { + id: "11111111-1111-4111-8111-111111111111", + company_id: "22222222-2222-4222-8222-222222222222", + customer_id: "33333333-3333-4333-8333-333333333333", + source_proforma_id: "44444444-4444-4444-8444-444444444444", + document_series_id: null, + status: "issued", + invoice_series_code: "F26", + invoice_number: "173", + invoice_reference: "F260173", + invoice_date: "2026-08-18", + operation_date: "2026-08-06", + language_code: "es", + currency_code: "EUR", + reference: null, + description: "Factura emitida", + notes: null, + payment_term_id: null, + payment_term_name: null, + payment_term_description: null, + payment_term_snapshot_json: null, + payment_method_id: "55555555-5555-4555-8555-555555555555", + payment_method_name: "Transferencia", + payment_method_description: "Transferencia", + tax_regime_code: "04", + tax_regime_description: "04: Régimen especial del oro de inversión.", + subtotal_amount_value: 10000, + items_discount_amount_value: 0, + global_discount_percentage_value: 0, + global_discount_amount_value: 0, + total_discount_amount_value: 0, + taxable_amount_value: 10000, + iva_amount_value: 2100, + rec_amount_value: 0, + retention_amount_value: 0, + taxes_amount_value: 2100, + total_amount_value: 12100, + verifactu_profile_status: "obligated_with_verifactu", + uses_verifactu: true, + verifactu_effective_at: raw.verifactu_effective_at, + }, + { errors } + ) as { + hasVerifactuSnapshots: boolean; + }; + + assert.equal(attributes.hasVerifactuSnapshots, true); + + const utcDateResult = UtcDate.createFromISO( + raw.verifactu_effective_at.toISOString().slice(0, 10) + ); + assert.equal(utcDateResult.isSuccess, true); + assert.equal(utcDateResult.data.toPrimitive(), "2027-01-12"); + assert.deepEqual(errors, []); +}); + test("rechaza snapshots persistidos inconsistentes de payment term", () => { const mapper = buildMapper(); diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts index 4383437b..997366bf 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-v2-domain.mapper.ts @@ -24,8 +24,8 @@ import { InvoiceSerie, InvoiceStatus, InvoiceTaxRegime, - IssuedInvoiceFiscalClassification, IssuedInvoice, + IssuedInvoiceFiscalClassification, IssuedInvoiceItems, IssuedInvoiceTaxes, IssuedInvoiceVerifactuPolicy, @@ -268,8 +268,6 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< params?: MapperParamsType ): Result { try { - console.debug(raw); - const errors: ValidationErrorDetail[] = []; const attributes = this._mapAttributesToDomain(raw, { errors, ...params }); const recipientResult = this._recipientMapper.mapToDomain(raw, { @@ -338,13 +336,16 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< const effectiveAt = extractOrPushError( maybeFromNullableResult(raw.verifactu_effective_at, (value) => - UtcDate.createFromISO(value instanceof Date ? value.toISOString() : String(value)) + UtcDate.createFromISO( + value instanceof Date ? value.toISOString().slice(0, 10) : String(value).slice(0, 10) + ) ), "verifactu_effective_at", errors ); if (errors.length > 0) { + console.error(errors); return Result.fail( new ValidationErrorCollection("Issued invoice V2 mapping failed [mapToDomain]", errors) ); @@ -481,10 +482,10 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< tax_regime_code: source.taxRegime.code, tax_regime_description: source.taxRegime.description, operation_qualification_code: source.fiscalClassification.isSome() - ? source.fiscalClassification.unwrap().operationQualificationCode.getOrUndefined() ?? null + ? (source.fiscalClassification.unwrap().operationQualificationCode.getOrUndefined() ?? null) : null, exemption_reason_code: source.fiscalClassification.isSome() - ? source.fiscalClassification.unwrap().exemptionReasonCode.getOrUndefined() ?? null + ? (source.fiscalClassification.unwrap().exemptionReasonCode.getOrUndefined() ?? null) : null, verifactu_profile_status: source.verifactuPolicy.isSome() ? source.verifactuPolicy.unwrap().profileStatus @@ -493,7 +494,7 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< ? source.verifactuPolicy.unwrap().usesVerifactu : null, verifactu_effective_at: source.verifactuPolicy.isSome() - ? source.verifactuPolicy.unwrap().effectiveAt.getOrUndefined()?.toDate() ?? null + ? (source.verifactuPolicy.unwrap().effectiveAt.getOrUndefined()?.toDate() ?? null) : null, subtotal_amount_value: source.subtotalAmount.value, subtotal_amount_scale: source.subtotalAmount.scale, @@ -528,11 +529,12 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< } private mapPaymentTerm(raw: IssuedInvoiceModel): Result, Error> { - const hasAnyPaymentTermData = - !isNullishOrEmpty(raw.payment_term_id) || - !isNullishOrEmpty(raw.payment_term_name) || - !isNullishOrEmpty(raw.payment_term_description) || - !isNullishOrEmpty(raw.payment_term_snapshot_json); + const hasAnyPaymentTermData = !( + isNullishOrEmpty(raw.payment_term_id) && + isNullishOrEmpty(raw.payment_term_name) && + isNullishOrEmpty(raw.payment_term_description) && + isNullishOrEmpty(raw.payment_term_snapshot_json) + ); if (!hasAnyPaymentTermData) { return Result.ok(Maybe.none()); @@ -600,16 +602,19 @@ export class SequelizeIssuedInvoiceV2DomainMapper extends SequelizeDomainMapper< return Result.ok(Maybe.some(paymentTermResult.data)); } - private parsePaymentTermSnapshotJson(source: string): Result<{ - version: 1; - dueRules: Array<{ - dueDays: string; - percentage: { - value: string; - scale: number; - }; - }>; - }, Error> { + private parsePaymentTermSnapshotJson(source: string): Result< + { + version: 1; + dueRules: Array<{ + dueDays: string; + percentage: { + value: string; + scale: number; + }; + }>; + }, + Error + > { try { const parsed = JSON.parse(source) as { version?: unknown; diff --git a/modules/customer-invoices/src/web/i18n.ts b/modules/customer-invoices/src/web/i18n.ts index 912e3eee..b330bb80 100644 --- a/modules/customer-invoices/src/web/i18n.ts +++ b/modules/customer-invoices/src/web/i18n.ts @@ -5,14 +5,14 @@ import { useTranslation as useI18NextTranslation } from "react-i18next"; import enResources from "../common/locales/en.json"; import esResources from "../common/locales/es.json"; -import { MODULE_NAME } from "./manifest"; +import { CUSTOMER_INVOICES_MODULE_NAME } from "./module-name"; /** * Registra dinámicamente las traducciones del módulo. */ export const ensureModuleTranslations = () => { - registerTranslations(MODULE_NAME, "en", enResources); - registerTranslations(MODULE_NAME, "es", esResources); + registerTranslations(CUSTOMER_INVOICES_MODULE_NAME, "en", enResources); + registerTranslations(CUSTOMER_INVOICES_MODULE_NAME, "es", esResources); }; /** @@ -23,13 +23,13 @@ export const ensureModuleTranslations = () => { */ export const useTranslation = () => { // Asegura los bundles del módulo al montar (idempotente) - // biome-ignore lint/correctness/useExhaustiveDependencies: + // biome-ignore lint/correctness/useExhaustiveDependencies: i18n es un singleton estable del runtime compartido useEffect(() => { ensureModuleTranslations(); }, [i18n]); // Hook con namespace - return useI18NextTranslation(MODULE_NAME, { + return useI18NextTranslation(CUSTOMER_INVOICES_MODULE_NAME, { i18n, }); }; diff --git a/modules/customer-invoices/src/web/manifest.ts b/modules/customer-invoices/src/web/manifest.ts index aec463b1..ceeec309 100644 --- a/modules/customer-invoices/src/web/manifest.ts +++ b/modules/customer-invoices/src/web/manifest.ts @@ -2,8 +2,9 @@ import type { IModuleClient, ModuleClientParams } from "@erp/core/client"; import { CustomerInvoiceRoutes } from "./customer-invoice-routes"; import { ensureModuleTranslations } from "./i18n"; +import { CUSTOMER_INVOICES_MODULE_NAME } from "./module-name"; -export const MODULE_NAME = "CustomerInvoices"; +export const MODULE_NAME = CUSTOMER_INVOICES_MODULE_NAME; const MODULE_VERSION = "1.0.0"; ensureModuleTranslations(); diff --git a/modules/customer-invoices/src/web/module-name.ts b/modules/customer-invoices/src/web/module-name.ts new file mode 100644 index 00000000..8fe8d142 --- /dev/null +++ b/modules/customer-invoices/src/web/module-name.ts @@ -0,0 +1 @@ +export const CUSTOMER_INVOICES_MODULE_NAME = "CustomerInvoices"; diff --git a/modules/customer-invoices/src/web/proformas/update/ui/pages/proforma-update-page.test.tsx b/modules/customer-invoices/src/web/proformas/update/ui/pages/proforma-update-page.test.tsx index 6cc4c95a..b1052a17 100644 --- a/modules/customer-invoices/src/web/proformas/update/ui/pages/proforma-update-page.test.tsx +++ b/modules/customer-invoices/src/web/proformas/update/ui/pages/proforma-update-page.test.tsx @@ -56,6 +56,18 @@ test("conecta la alta rápida directa y la alta rápida desde selector con callb }, }); + mock.module("@repo/rdx-ui/helpers", { + namedExports: { + showErrorToast: () => undefined, + }, + }); + + mock.module("@repo/shadcn-ui/components", { + namedExports: { + Badge: ({ children }: { children?: ReactNode }) => children ?? null, + }, + }); + mock.module("react-hook-form", { namedExports: { FormProvider: ({ children }: { children: ReactNode }) => children, @@ -76,6 +88,12 @@ test("conecta la alta rápida directa y la alta rápida desde selector con callb }, }); + mock.module("../../../list/ui/components", { + namedExports: { + ProformaStatusBadge: () => null, + }, + }); + mock.module("../../controllers/use-update-proforma-page-controller", { namedExports: { useUpdateProformaPageController: () => ({ diff --git a/modules/customer-invoices/tsconfig.json b/modules/customer-invoices/tsconfig.json index 12ed1dd1..afe8b596 100644 --- a/modules/customer-invoices/tsconfig.json +++ b/modules/customer-invoices/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/customer-invoices/*": ["./src/*"], "@erp/identity/*": ["../identity/src/*"] diff --git a/modules/customers/tsconfig.json b/modules/customers/tsconfig.json index 36c3f7b5..3b36e926 100644 --- a/modules/customers/tsconfig.json +++ b/modules/customers/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/customers/*": ["./src/*"], "@erp/identity/*": ["../identity/src/*"] diff --git a/modules/document-series/tsconfig.json b/modules/document-series/tsconfig.json index 4a24fa30..993e6228 100644 --- a/modules/document-series/tsconfig.json +++ b/modules/document-series/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/document-series/*": ["./src/*"] }, diff --git a/modules/factuges/tsconfig.json b/modules/factuges/tsconfig.json index b7696d59..d580adde 100644 --- a/modules/factuges/tsconfig.json +++ b/modules/factuges/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/factuges/*": ["./src/*"], "@erp/identity/*": ["../identity/src/*"] diff --git a/modules/identity/tsconfig.json b/modules/identity/tsconfig.json index bafadf9b..02a7a112 100644 --- a/modules/identity/tsconfig.json +++ b/modules/identity/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/identity/*": ["./src/*"] }, diff --git a/modules/supplier-invoices/tsconfig.json b/modules/supplier-invoices/tsconfig.json index 271c02d4..6f0dd460 100644 --- a/modules/supplier-invoices/tsconfig.json +++ b/modules/supplier-invoices/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/supplier-invoices/*": ["./src/*"] }, diff --git a/modules/supplier/tsconfig.json b/modules/supplier/tsconfig.json index a055379d..4b17fbe2 100644 --- a/modules/supplier/tsconfig.json +++ b/modules/supplier/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@erp/suppliers/*": ["./src/*"] }, diff --git a/package.json b/package.json index 8c004e44..f191625d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,8 @@ "format:check": "biome format .", "check": "biome check .", "check:write": "biome check --write .", + "test:frontend": "node --experimental-test-module-mocks --import tsx --test", + "test:unit": "node --import tsx --test", "typecheck": "tsc -p tsconfig.json --noEmit" }, "devDependencies": { @@ -38,6 +40,7 @@ "plop": "^4.0.5", "rimraf": "^6.1.3", "ts-node": "^10.9.2", + "tsx": "^4.21.0", "tailwindcss": "^4.2.2", "turbo": "^2.9.14", "typescript": "6.0.2" @@ -46,4 +49,4 @@ "node": ">=24" }, "packageManager": "pnpm@10.33.0" -} \ No newline at end of file +} diff --git a/packages/rdx-ui/tsconfig.json b/packages/rdx-ui/tsconfig.json index 663ce104..e22eb340 100644 --- a/packages/rdx-ui/tsconfig.json +++ b/packages/rdx-ui/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { + "baseUrl": ".", "paths": { "@repo/rdx-ui/*": ["./src/*"] }, diff --git a/packages/rdx-utils/tsconfig.json b/packages/rdx-utils/tsconfig.json index 1e5b96f6..f03b6b2b 100644 --- a/packages/rdx-utils/tsconfig.json +++ b/packages/rdx-utils/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "@repo/typescript-config/buildless.json", "compilerOptions": { + "baseUrl": ".", "types": ["node"], "rootDir": "src", "paths": { diff --git a/packages/shadcn-ui/tsconfig.json b/packages/shadcn-ui/tsconfig.json index d6fba402..a28acd62 100644 --- a/packages/shadcn-ui/tsconfig.json +++ b/packages/shadcn-ui/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "@repo/typescript-config/react-library.json", "compilerOptions": { + "baseUrl": ".", "module": "node16", "target": "esnext", "moduleResolution": "node16", diff --git a/packages/typescript-config/base.json b/packages/typescript-config/base.json index 586d8a7c..a2013c9d 100644 --- a/packages/typescript-config/base.json +++ b/packages/typescript-config/base.json @@ -19,6 +19,7 @@ "skipLibCheck": true, "strict": true, "moduleDetection": "force", + "ignoreDeprecations": "6.0", "noUncheckedIndexedAccess": true, "resolveJsonModule": true, "target": "ES2022" diff --git a/packages/typescript-config/express.json b/packages/typescript-config/express.json index 8d5ee3ea..b929de71 100644 --- a/packages/typescript-config/express.json +++ b/packages/typescript-config/express.json @@ -6,6 +6,7 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", + "ignoreDeprecations": "6.0", "importsNotUsedAsValues": "remove", "esModuleInterop": true, "skipLibCheck": true, diff --git a/packages/typescript-config/root.json b/packages/typescript-config/root.json index fe0c147f..6bec843d 100644 --- a/packages/typescript-config/root.json +++ b/packages/typescript-config/root.json @@ -2,34 +2,18 @@ "$schema": "https://json.schemastore.org/tsconfig", "display": "Root", "compilerOptions": { + "baseUrl": "../..", + "ignoreDeprecations": "6.0", "paths": { - "@erp/core/*": [ - "modules/core/src/*" - ], - "@erp/auth/*": [ - "modules/auth/src/*" - ], - "@erp/companies/*": [ - "modules/companies/src/*" - ], - "@erp/identity/*": [ - "modules/identity/src/*" - ], - "@erp/catalogs/*": [ - "modules/catalogs/src/*" - ], - "@erp/customers/*": [ - "modules/customers/src/*" - ], - "@erp/customer-invoices/*": [ - "modules/customer-invoices/src/*" - ], - "@erp/factuges/*": [ - "modules/factuges/src/*" - ], - "@erp/document-series/*": [ - "modules/document-series/src/*" - ] + "@erp/core/*": ["modules/core/src/*"], + "@erp/auth/*": ["modules/auth/src/*"], + "@erp/companies/*": ["modules/companies/src/*"], + "@erp/identity/*": ["modules/identity/src/*"], + "@erp/catalogs/*": ["modules/catalogs/src/*"], + "@erp/customers/*": ["modules/customers/src/*"], + "@erp/customer-invoices/*": ["modules/customer-invoices/src/*"], + "@erp/factuges/*": ["modules/factuges/src/*"], + "@erp/document-series/*": ["modules/document-series/src/*"] }, "target": "ES2021", "module": "CommonJS", @@ -40,4 +24,4 @@ "skipLibCheck": true, "allowUnreachableCode": true } -} \ No newline at end of file +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae947caf..415135a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@25.9.1)(typescript@6.0.2) + tsx: + specifier: ^4.21.0 + version: 4.21.0 turbo: specifier: ^2.9.14 version: 2.9.14 diff --git a/tsconfig.json b/tsconfig.json index 24e2a1ef..64bdb7c5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,8 @@ { "extends": "@repo/typescript-config/root.json", + "compilerOptions": { + "ignoreDeprecations": "6.0", + "jsx": "react-jsx" + }, "include": ["apps", "modules", "packages"] }