1
0

feat(sdk): add OpenAPI export script and TypeScript SDK package

- Add export-openapi.ts script for server OpenAPI spec export
- Add shared/sdk-ts package with generated API clients (accounts, bills, customers, vendors, etc.)
- Update Customers and Vendors controllers
- Update ReportsEventsTracker
- Update .gitignore, package.json, and pnpm-lock

Made-with: Cursor
This commit is contained in:
Ahmed Bouhuolia
2026-03-03 23:26:24 +02:00
parent b81fcdfbd8
commit e3c55c5d6f
49 changed files with 104701 additions and 13277 deletions
+5 -3
View File
@@ -27,15 +27,17 @@
"cli:tenants:migrate:rollback": "ts-node -r tsconfig-paths/register src/cli.ts tenants:migrate:rollback",
"cli:tenants:migrate:make": "ts-node -r tsconfig-paths/register src/cli.ts tenants:migrate:make",
"cli:tenants:list": "ts-node -r tsconfig-paths/register src/cli.ts tenants:list",
"openapi:export": "ts-node -r tsconfig-paths/register scripts/export-openapi.ts",
"cli:system:seed:latest": "ts-node -r tsconfig-paths/register src/cli.ts system:seed:latest",
"cli:tenants:seed:latest": "ts-node -r tsconfig-paths/register src/cli.ts tenants:seed:latest"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.576.0",
"@aws-sdk/s3-request-presigner": "^3.583.0",
"@bigcapital/email-components": "*",
"@bigcapital/pdf-templates": "*",
"@bigcapital/utils": "*",
"@bigcapital/email-components": "workspace:*",
"@bigcapital/pdf-templates": "workspace:*",
"@bigcapital/sdk-ts": "workspace:*",
"@bigcapital/utils": "workspace:*",
"@casl/ability": "^5.4.3",
"@lemonsqueezy/lemonsqueezy.js": "^2.2.0",
"@liaoliaots/nestjs-redis": "^10.0.0",
+46
View File
@@ -0,0 +1,46 @@
/**
* Exports the OpenAPI document from the NestJS app to shared/sdk-ts/openapi.json.
* Run from packages/server: pnpm run openapi:export
*/
/// <reference path="../src/common/types/Objection.d.ts" />
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { ClsMiddleware } from 'nestjs-cls';
import * as path from 'path';
import * as fs from 'fs';
import '@/utils/moment-mysql';
import { AppModule } from '@/modules/App/App.module';
import { NestExpressApplication } from '@nestjs/platform-express';
async function exportOpenApi() {
global.__public_dirname = path.join(__dirname, '..', 'public');
global.__static_dirname = path.join(__dirname, '..', 'static');
global.__views_dirname = path.join(global.__static_dirname, '/views');
global.__images_dirname = path.join(global.__static_dirname, '/images');
const app = await NestFactory.create<NestExpressApplication>(AppModule, {
rawBody: true,
});
app.set('query parser', 'extended');
app.setGlobalPrefix('/api');
app.use(new ClsMiddleware({}).use);
const config = new DocumentBuilder()
.setTitle('Bigcapital')
.setDescription('Financial accounting software')
.setVersion('1.0')
.build();
const document = SwaggerModule.createDocument(app, config);
await app.close();
const outputPath = path.resolve(__dirname, '../../../shared/sdk-ts/openapi.json');
fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.writeFileSync(outputPath, JSON.stringify(document, null, 2), 'utf-8');
console.log(`OpenAPI spec written to ${outputPath}`);
}
exportOpenApi().catch((err) => {
console.error(err);
process.exit(1);
});
@@ -36,6 +36,7 @@ import { CustomerAction } from './types/Customers.types';
@Controller('customers')
@ApiTags('Customers')
@ApiExtraModels(CustomerResponseDto)
@ApiExtraModels(ValidateBulkDeleteCustomersResponseDto)
@ApiCommonHeaders()
@UseGuards(AuthorizationGuard, PermissionGuard)
export class CustomersController {
@@ -25,7 +25,7 @@ export class ReportsEventsTracker {
constructor(private readonly posthog: EventTrackerService) {}
@OnEvent(events.reports.onBalanceSheetViewed)
handleTrackBalanceSheetViewedEvent({ tenantId }: ReportsEvents) {
handleTrackBalanceSheetViewedEvent() {
this.posthog.trackEvent({
event: BALANCE_SHEET_VIEWED,
properties: {},
@@ -33,7 +33,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onTrialBalanceSheetView)
handleTrackTrialBalanceSheetViewedEvent({ tenantId }: ReportsEvents) {
handleTrackTrialBalanceSheetViewedEvent() {
this.posthog.trackEvent({
event: TRIAL_BALANCE_SHEET_VIEWED,
properties: {},
@@ -41,7 +41,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onProfitLossSheetViewed)
handleTrackProfitLossSheetViewedEvent({ tenantId }: ReportsEvents) {
handleTrackProfitLossSheetViewedEvent() {
this.posthog.trackEvent({
event: PROFIT_LOSS_SHEET_VIEWED,
properties: {},
@@ -49,7 +49,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onCashflowStatementViewed)
handleTrackCashflowStatementViewedEvent({ tenantId }: ReportsEvents) {
handleTrackCashflowStatementViewedEvent() {
this.posthog.trackEvent({
event: CASHFLOW_STATEMENT_VIEWED,
properties: {},
@@ -57,7 +57,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onGeneralLedgerViewed)
handleTrackGeneralLedgerViewedEvent({ tenantId }: ReportsEvents) {
handleTrackGeneralLedgerViewedEvent() {
this.posthog.trackEvent({
event: GENERAL_LEDGER_VIEWED,
properties: {},
@@ -65,7 +65,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onJournalViewed)
handleTrackJournalViewedEvent({ tenantId }: ReportsEvents) {
handleTrackJournalViewedEvent() {
this.posthog.trackEvent({
event: JOURNAL_VIEWED,
properties: {},
@@ -73,7 +73,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onReceivableAgingViewed)
handleTrackReceivableAgingViewedEvent({ tenantId }: ReportsEvents) {
handleTrackReceivableAgingViewedEvent() {
this.posthog.trackEvent({
event: RECEIVABLE_AGING_VIEWED,
properties: {},
@@ -81,7 +81,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onPayableAgingViewed)
handleTrackPayableAgingViewedEvent({ tenantId }: ReportsEvents) {
handleTrackPayableAgingViewedEvent() {
this.posthog.trackEvent({
event: PAYABLE_AGING_VIEWED,
properties: {},
@@ -89,7 +89,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onCustomerBalanceSummaryViewed)
handleTrackCustomerBalanceSummaryViewedEvent({ tenantId }: ReportsEvents) {
handleTrackCustomerBalanceSummaryViewedEvent() {
this.posthog.trackEvent({
event: CUSTOMER_BALANCE_SUMMARY_VIEWED,
properties: {},
@@ -97,7 +97,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onVendorBalanceSummaryViewed)
handleTrackVendorBalanceSummaryViewedEvent({ tenantId }: ReportsEvents) {
handleTrackVendorBalanceSummaryViewedEvent() {
this.posthog.trackEvent({
event: VENDOR_BALANCE_SUMMARY_VIEWED,
properties: {},
@@ -105,7 +105,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onInventoryValuationViewed)
handleTrackInventoryValuationViewedEvent({ tenantId }: ReportsEvents) {
handleTrackInventoryValuationViewedEvent() {
this.posthog.trackEvent({
event: INVENTORY_VALUATION_VIEWED,
properties: {},
@@ -113,7 +113,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onCustomerTransactionsViewed)
handleTrackCustomerTransactionsViewedEvent({ tenantId }: ReportsEvents) {
handleTrackCustomerTransactionsViewedEvent() {
this.posthog.trackEvent({
event: CUSTOMER_TRANSACTIONS_VIEWED,
properties: {},
@@ -121,7 +121,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onVendorTransactionsViewed)
handleTrackVendorTransactionsViewedEvent({ tenantId }: ReportsEvents) {
handleTrackVendorTransactionsViewedEvent() {
this.posthog.trackEvent({
event: VENDOR_TRANSACTIONS_VIEWED,
properties: {},
@@ -129,7 +129,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onSalesByItemViewed)
handleTrackSalesByItemViewedEvent({ tenantId }: ReportsEvents) {
handleTrackSalesByItemViewedEvent() {
this.posthog.trackEvent({
event: SALES_BY_ITEM_VIEWED,
properties: {},
@@ -137,7 +137,7 @@ export class ReportsEventsTracker {
}
@OnEvent(events.reports.onPurchasesByItemViewed)
handleTrackPurchasesByItemViewedEvent({ tenantId }: ReportsEvents) {
handleTrackPurchasesByItemViewedEvent() {
this.posthog.trackEvent({
event: PURCHASES_BY_ITEM_VIEWED,
properties: {},
@@ -12,6 +12,7 @@ import {
import { VendorsApplication } from './VendorsApplication.service';
import { VendorOpeningBalanceEditDto } from './dtos/VendorOpeningBalanceEdit.dto';
import {
ApiExtraModels,
ApiOperation,
ApiResponse,
ApiTags,
@@ -33,6 +34,7 @@ import { VendorAction } from '../Customers/types/Customers.types';
@Controller('vendors')
@ApiTags('Vendors')
@ApiExtraModels(ValidateBulkDeleteVendorsResponseDto)
@ApiCommonHeaders()
@UseGuards(AuthorizationGuard, PermissionGuard)
export class VendorsController {