Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 0 additions & 260 deletions IMPLEMENTATION_SUMMARY.md

This file was deleted.

4 changes: 4 additions & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
"reflect-metadata": "^0.2.2",
"sql.js": "^1.14.1",
"sqlite3": "^5.1.7",
"swagger-jsdoc": "^6.3.0",
"swagger-ui-express": "^5.0.1",
"uuid": "^9.0.1",
"winston": "^3.14.2",
"zod": "^3.22.0"
Expand All @@ -49,6 +51,8 @@
"@types/jest": "^29.0.0",
"@types/jsonwebtoken": "^9.0.10",
"@types/node": "^20.0.0",
"@types/swagger-jsdoc": "^6.0.4",
"@types/swagger-ui-express": "^4.1.8",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
Expand Down
72 changes: 72 additions & 0 deletions backend/scripts/generate-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Generate TypeScript types from the OpenAPI specification.
*
* Usage:
* npx ts-node scripts/generate-types.ts
* # or via npm script:
* pnpm --filter @chenaikit/backend run generate:api-types
*
* Output:
* src/types/generated-api.ts
*/

import fs from "fs";
import path from "path";

async function main() {
// Dynamically import the swagger spec (it runs swagger-jsdoc at import time)
const { swaggerSpec } = await import("../src/config/swagger");

const specJson = JSON.stringify(swaggerSpec, null, 2);
const outputDir = path.resolve(__dirname, "..", "src", "types");
const specOutputPath = path.resolve(outputDir, "openapi-spec.json");

// Ensure output directory exists
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true });
}

// Write the resolved OpenAPI spec as JSON
fs.writeFileSync(specOutputPath, specJson, "utf-8");
console.log(`✅ OpenAPI spec written to ${specOutputPath}`);

// Generate TypeScript types using openapi-typescript (if installed)
try {
const openapiTS = await import("openapi-typescript");
const generateFn = openapiTS.default || openapiTS;

if (typeof generateFn === "function") {
const output = await generateFn(swaggerSpec as any);
const tsOutputPath = path.resolve(outputDir, "generated-api.ts");
const content = typeof output === "string" ? output : String(output);
fs.writeFileSync(tsOutputPath, content, "utf-8");
console.log(`✅ TypeScript types written to ${tsOutputPath}`);
} else {
console.log(
"ℹ️ openapi-typescript loaded but generate function not found.",
);
console.log(
" The OpenAPI spec JSON has been saved — you can generate types manually with:",
);
console.log(
` npx openapi-typescript ${specOutputPath} -o ${path.resolve(outputDir, "generated-api.ts")}`,
);
}
} catch {
console.log(
"ℹ️ openapi-typescript not installed. Skipping TypeScript type generation.",
);
console.log(
" Install it with: pnpm add -D openapi-typescript --filter @chenaikit/backend",
);
console.log(" Then re-run this script, or generate types manually with:");
console.log(
` npx openapi-typescript ${specOutputPath} -o ${path.resolve(outputDir, "generated-api.ts")}`,
);
}
Comment on lines +34 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Catch block is masking real generation failures as “dependency missing.”

Line 55 catches all errors from import, generation, and file write, but always logs “not installed.” If generation fails for a bad spec or runtime error, this script misreports success conditions and skips actionable failure reporting.

Proposed fix
-  try {
-    const openapiTS = await import("openapi-typescript");
-    const generateFn = openapiTS.default || openapiTS;
-
-    if (typeof generateFn === "function") {
-      const output = await generateFn(swaggerSpec as any);
-      const tsOutputPath = path.resolve(outputDir, "generated-api.ts");
-      const content = typeof output === "string" ? output : String(output);
-      fs.writeFileSync(tsOutputPath, content, "utf-8");
-      console.log(`✅ TypeScript types written to ${tsOutputPath}`);
-    } else {
-      console.log(
-        "ℹ️  openapi-typescript loaded but generate function not found.",
-      );
-      console.log(
-        "   The OpenAPI spec JSON has been saved — you can generate types manually with:",
-      );
-      console.log(
-        `   npx openapi-typescript ${specOutputPath} -o ${path.resolve(outputDir, "generated-api.ts")}`,
-      );
-    }
-  } catch {
+  let generateFn: unknown;
+  try {
+    const openapiTS = await import("openapi-typescript");
+    generateFn = openapiTS.default || openapiTS;
+  } catch {
     console.log(
       "ℹ️  openapi-typescript not installed. Skipping TypeScript type generation.",
     );
@@
-  }
+    return;
+  }
+
+  if (typeof generateFn !== "function") {
+    console.log("ℹ️  openapi-typescript loaded but generate function not found.");
+    return;
+  }
+
+  const output = await generateFn(swaggerSpec as any);
+  const tsOutputPath = path.resolve(outputDir, "generated-api.ts");
+  fs.writeFileSync(tsOutputPath, typeof output === "string" ? output : String(output), "utf-8");
+  console.log(`✅ TypeScript types written to ${tsOutputPath}`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/scripts/generate-types.ts` around lines 34 - 66, The catch block at
line 55 catches all errors (import failures, generation failures, file write
failures) but always logs "openapi-typescript not installed," masking real
generation failures. Refactor the catch block to distinguish between import
errors (where the "not installed" message is appropriate) and other errors
(which should be reported with actual error details). Check the error type or
error message to determine if it's a module not found error versus a genuine
generation or file system failure, and log accordingly with the actual error
information for non-import failures.

}

main().catch((err) => {
console.error("Failed to generate types:", err);
process.exit(1);
});
Loading