From 15beeb5897a72299d956b9e2efd56c3398b84ee5 Mon Sep 17 00:00:00 2001 From: alisaza Date: Mon, 7 Sep 2026 14:17:33 +0330 Subject: [PATCH] chore(api): rely on sibling backend or committed OpenAPI for codegen Drop live Swagger fetch so clients stay aligned through backend OpenAPI sync PRs. --- README.md | 8 +++++ orval.config.ts | 3 +- scripts/generate-api.mjs | 67 +++++++++++++++++++++++++++------------- 3 files changed, 54 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 77ffbdc..3f11513 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,12 @@ pnpm dev The development server uses port **3009**. +API client generation: + +```bash +pnpm generate:api +``` + +Uses sibling `../ghabilee-backend` when present, otherwise the committed `openapi.json`. Cross-repo sync is handled by the backend `sync-openapi-clients` workflow. + This admin application is intentionally excluded from search-engine indexing and does not include Microsoft Clarity. Deployment secrets and environment-specific credentials will be added later by the repository owner. diff --git a/orval.config.ts b/orval.config.ts index 45778ba..97c5b78 100644 --- a/orval.config.ts +++ b/orval.config.ts @@ -3,8 +3,7 @@ import { defineConfig } from 'orval' export default defineConfig({ api: { input: { - // Committed mirror of backend/openapi.json so ghabilee-frontend - // (satellite) can generate without a Nest sibling. + // Sibling backend export or committed mirror (kept in sync by backend OpenAPI PRs). target: './openapi.json', }, output: { diff --git a/scripts/generate-api.mjs b/scripts/generate-api.mjs index bbe6279..76594ce 100644 --- a/scripts/generate-api.mjs +++ b/scripts/generate-api.mjs @@ -2,23 +2,29 @@ /** * Generate Orval client into api/generated/. * - * Monorepo: refresh OpenAPI from Nest when ../backend exists, then orval. - * Satellite (ghabilee-frontend): orval only from committed ./openapi.json. + * OpenAPI source priority: + * 1. Sibling Nest package (`../ghabilee-backend` or `../backend`) via `generate:openapi` + * 2. Committed `./openapi.json` (CI, satellite clones, OpenAPI sync PRs) + * + * Live Swagger fetch is intentionally not used — clients stay in sync via + * ghabilee-backend's `sync-openapi-clients` workflow. */ import { spawnSync } from 'node:child_process' import { copyFileSync, existsSync } from 'node:fs' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' -const frontendRoot = join(dirname(fileURLToPath(import.meta.url)), '..') -const backendOpenapi = join(frontendRoot, '../backend/openapi.json') -const localOpenapi = join(frontendRoot, 'openapi.json') -const backendDir = join(frontendRoot, '../backend') +const projectRoot = join(dirname(fileURLToPath(import.meta.url)), '..') +const localOpenapi = join(projectRoot, 'openapi.json') +const siblingBackendDirs = [ + join(projectRoot, '../ghabilee-backend'), + join(projectRoot, '../backend'), +] function run(command, args, opts = {}) { const result = spawnSync(command, args, { stdio: 'inherit', - cwd: frontendRoot, + cwd: projectRoot, shell: process.platform === 'win32', ...opts, }) @@ -27,23 +33,40 @@ function run(command, args, opts = {}) { } } -if (existsSync(backendDir) && existsSync(join(backendDir, 'package.json'))) { - console.log('==> Exporting OpenAPI from backend...') - run('pnpm', ['--dir', backendDir, 'generate:openapi']) - if (!existsSync(backendOpenapi)) { - console.error(`Missing ${backendOpenapi} after export`) +function trySiblingBackend() { + for (const backendDir of siblingBackendDirs) { + if (!existsSync(backendDir) || !existsSync(join(backendDir, 'package.json'))) { + continue + } + + const backendOpenapi = join(backendDir, 'openapi.json') + console.log(`==> Exporting OpenAPI from sibling backend (${backendDir})...`) + run('pnpm', ['--dir', backendDir, 'generate:openapi']) + + if (!existsSync(backendOpenapi)) { + console.error(`Missing ${backendOpenapi} after export`) + process.exit(1) + } + + copyFileSync(backendOpenapi, localOpenapi) + console.log('==> Copied sibling openapi.json → ./openapi.json') + return true + } + + return false +} + +if (!trySiblingBackend()) { + if (!existsSync(localOpenapi)) { + console.error( + [ + 'No ../ghabilee-backend (or ../backend) and no ./openapi.json — cannot generate API client.', + 'Place ghabilee-backend next to this repo, or wait for an OpenAPI sync PR / commit openapi.json.', + ].join('\n'), + ) process.exit(1) } - copyFileSync(backendOpenapi, localOpenapi) - console.log('==> Copied backend/openapi.json → frontend/openapi.json') -} else if (!existsSync(localOpenapi)) { - console.error( - 'No ../backend and no ./openapi.json — cannot generate API client.\n' + - 'In the satellite repo, openapi.json must be committed; re-sync from the monorepo.', - ) - process.exit(1) -} else { - console.log('==> No backend sibling — using committed ./openapi.json') + console.log('==> Using committed ./openapi.json') } console.log('==> Running orval...')