Skip to content

Commit 54b1d40

Browse files
committed
feat: adding route generation and moved build to script
1 parent f089f5c commit 54b1d40

20 files changed

+278
-6
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ To build the Angular application for production:
7272
bun run build
7373
```
7474

75+
This will run all the required build steps.
76+
I've included a routes.txt generator, so you can add the routes you want to pre-render in the `routes.txt` file.
77+
You can remove that library and build steps if you don't want to pre-render the routes.
78+
7579
To run the Application:
7680

7781
```bash

libs/backend/root/src/app.module.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import { Module } from '@nestjs/common';
2-
import { BackendTestModule } from '@backend/test';
2+
import { BackendTestModule } from '@app/backend-test';
3+
import { RoutesGeneratorModule } from '@app/backend-routes-generator';
34

45
@Module({
5-
imports: [BackendTestModule],
6+
imports: [BackendTestModule, RoutesGeneratorModule],
67
controllers: [],
78
})
89
export class AppModule {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"extends": ["../../../.eslintrc.json"],
3+
"ignorePatterns": ["!**/*"],
4+
"overrides": [
5+
{
6+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7+
"rules": {}
8+
},
9+
{
10+
"files": ["*.ts", "*.tsx"],
11+
"rules": {}
12+
},
13+
{
14+
"files": ["*.js", "*.jsx"],
15+
"rules": {}
16+
}
17+
]
18+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# backend-routes-generator
2+
3+
This library was generated with [Nx](https://nx.dev).
4+
5+
## Running unit tests
6+
7+
Run `nx test backend-routes-generator` to execute the unit tests via [Jest](https://jestjs.io).
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* eslint-disable */
2+
export default {
3+
displayName: 'backend-routes-generator',
4+
preset: '../../../jest.preset.js',
5+
testEnvironment: 'node',
6+
transform: {
7+
'^.+\\.[tj]s$': ['ts-jest', { tsconfig: '<rootDir>/tsconfig.spec.json' }],
8+
},
9+
moduleFileExtensions: ['ts', 'js', 'html'],
10+
coverageDirectory: '../../../coverage/libs/backend/routes-generator',
11+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "backend-routes-generator",
3+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "libs/backend/routes-generator/src",
5+
"projectType": "library",
6+
"tags": [],
7+
"targets": {
8+
"test": {
9+
"executor": "@nx/jest:jest",
10+
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
11+
"options": {
12+
"jestConfig": "libs/backend/routes-generator/jest.config.ts"
13+
}
14+
}
15+
}
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Test } from '@nestjs/testing';
2+
import { RoutesGeneratorController } from './routes-generator.controller';
3+
import { RoutesGeneratorService } from '../services/routes-generator.service';
4+
5+
describe('RoutesGeneratorController', () => {
6+
let controller: RoutesGeneratorController;
7+
8+
beforeEach(async () => {
9+
const module = await Test.createTestingModule({
10+
providers: [RoutesGeneratorService],
11+
controllers: [RoutesGeneratorController],
12+
}).compile();
13+
14+
controller = module.get(RoutesGeneratorController);
15+
});
16+
17+
it('should be defined', () => {
18+
expect(controller).toBeTruthy();
19+
});
20+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Controller, Get } from '@nestjs/common';
2+
import { RoutesGeneratorService } from '../services/routes-generator.service';
3+
4+
@Controller('routes')
5+
export class RoutesGeneratorController {
6+
constructor(private routeGenerator: RoutesGeneratorService) {}
7+
8+
@Get()
9+
generateRoutes() {
10+
return this.routeGenerator.generateRoutesTxt();
11+
}
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './routes-generator.module';
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Module } from '@nestjs/common';
2+
import { RoutesGeneratorController } from './controllers/routes-generator.controller';
3+
import { RoutesGeneratorService } from './services/routes-generator.service';
4+
5+
@Module({
6+
controllers: [RoutesGeneratorController],
7+
providers: [RoutesGeneratorService],
8+
exports: [RoutesGeneratorService],
9+
})
10+
export class RoutesGeneratorModule {}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Test } from '@nestjs/testing';
2+
import { RoutesGeneratorService } from './routes-generator.service';
3+
4+
describe('RoutesGeneratorService', () => {
5+
let service: RoutesGeneratorService;
6+
7+
beforeEach(async () => {
8+
const module = await Test.createTestingModule({
9+
providers: [RoutesGeneratorService],
10+
}).compile();
11+
12+
service = module.get(RoutesGeneratorService);
13+
});
14+
15+
it('should be defined', () => {
16+
expect(service).toBeTruthy();
17+
});
18+
});
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { Injectable } from '@nestjs/common';
2+
3+
@Injectable()
4+
export class RoutesGeneratorService {
5+
generateRoutesTxt() {
6+
return `/home`;
7+
}
8+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"extends": "../../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "commonjs",
5+
"forceConsistentCasingInFileNames": true,
6+
"strict": true,
7+
"noImplicitOverride": true,
8+
"noPropertyAccessFromIndexSignature": true,
9+
"noImplicitReturns": true,
10+
"noFallthroughCasesInSwitch": true
11+
},
12+
"files": [],
13+
"include": [],
14+
"references": [
15+
{
16+
"path": "./tsconfig.lib.json"
17+
},
18+
{
19+
"path": "./tsconfig.spec.json"
20+
}
21+
]
22+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../../dist/out-tsc",
5+
"declaration": true,
6+
"types": ["node"],
7+
"target": "es2021",
8+
"strictNullChecks": true,
9+
"noImplicitAny": true,
10+
"strictBindCallApply": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"noFallthroughCasesInSwitch": true
13+
},
14+
"include": ["src/**/*.ts"],
15+
"exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"]
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "../../../dist/out-tsc",
5+
"module": "commonjs",
6+
"types": ["jest", "node"]
7+
},
8+
"include": [
9+
"jest.config.ts",
10+
"src/**/*.test.ts",
11+
"src/**/*.spec.ts",
12+
"src/**/*.d.ts"
13+
]
14+
}

libs/backend/test/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "@backend/test",
2+
"name": "@app/backend-test",
33
"version": "0.0.1",
44
"dependencies": {
55
"tslib": "^2.3.0",

package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
"license": "MIT",
55
"scripts": {
66
"start": "nx run-many -t serve -p tag:scope:app",
7-
"build": "concurrently \"nx serve api\" \"bun run wait-and-build\" --kill-others --success last --kill-signal SIGINT",
8-
"wait-and-build": "wait-on tcp:3000 && nx build app"
7+
"build": "node scripts/build.js"
98
},
109
"private": true,
1110
"dependencies": {

routes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/home

scripts/build.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const { exec } = require('child_process');
2+
const fs = require('fs');
3+
4+
// Function to run a shell command
5+
function runCommand(command) {
6+
return new Promise((resolve, reject) => {
7+
const process = exec(command);
8+
9+
process.stdout.on('data', (data) => {
10+
console.log(data);
11+
});
12+
13+
process.stderr.on('data', (data) => {
14+
console.error(data);
15+
});
16+
17+
process.on('close', (code) => {
18+
if (code === 0) {
19+
resolve();
20+
} else {
21+
reject(`Command failed with code ${code}`);
22+
}
23+
});
24+
});
25+
}
26+
27+
// Function to wait for the server to be ready
28+
function waitForServer(port) {
29+
return new Promise((resolve) => {
30+
const interval = setInterval(async () => {
31+
try {
32+
console.log('Checking server status...');
33+
const response = await fetch(`http://localhost:${port}/api/routes`);
34+
if (response.ok) {
35+
clearInterval(interval);
36+
resolve();
37+
}
38+
} catch (error) {
39+
// Server is not ready yet
40+
}
41+
}, 1000);
42+
});
43+
}
44+
45+
// Function to make a GET request and save the response to a file
46+
async function getAndSaveRoutes(port, filePath) {
47+
try {
48+
const response = await fetch(`http://localhost:${port}/api/routes`);
49+
if (!response.ok) {
50+
throw new Error(`Failed to fetch routes: ${response.statusText}`);
51+
}
52+
const data = await response.text();
53+
fs.writeFileSync(filePath, data);
54+
} catch (error) {
55+
throw new Error(`GET request failed: ${error}`);
56+
}
57+
}
58+
59+
// Main function to run the tasks
60+
async function main() {
61+
const port = process.env.PORT || 3000;
62+
if (!port) {
63+
console.error('Environment variable PORT is not set');
64+
process.exit(1);
65+
}
66+
67+
try {
68+
console.log('Starting server...');
69+
runCommand('nx serve api');
70+
71+
console.log(`Waiting for server to be ready on port ${port}...`);
72+
await waitForServer(port);
73+
74+
console.log('Server is ready. Fetching routes...');
75+
await getAndSaveRoutes(port, 'routes.txt');
76+
77+
console.log('Routes saved to routes.txt');
78+
79+
console.log('Building app...');
80+
await runCommand('nx build app');
81+
82+
console.log('App build completed');
83+
84+
process.exit(0);
85+
} catch (error) {
86+
console.error(`Error: ${error}`);
87+
process.exit(1);
88+
}
89+
}
90+
91+
main();

tsconfig.base.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
"skipDefaultLibCheck": true,
1616
"baseUrl": ".",
1717
"paths": {
18-
"@backend/test": ["libs/backend/test/src/index.ts"],
18+
"@app/backend-test": ["libs/backend/test/src/index.ts"],
19+
"@app/backend-routes-generator": [
20+
"libs/backend/routes-generator/src/index.ts"
21+
],
1922
"@app/backend-root": ["libs/backend/root/src/index.ts"],
2023
"@app/frontend-root": ["libs/frontend/root/src/index.ts"]
2124
}

0 commit comments

Comments
 (0)