From 63558973ff3e06058b6fc649fbb9a954a25e3986 Mon Sep 17 00:00:00 2001 From: mauro-defilippo Date: Tue, 7 Apr 2026 17:54:00 +0200 Subject: [PATCH] third commit --- .prettierignore | 5 ++ .prettierrc | 3 ++ .vscode/launch.json | 59 +++++++++++++++++++++++ eslint.config.mjs | 42 ++++++++++++++++ gateway/.env | 9 ++++ gateway/eslint.config.mjs | 3 ++ gateway/project.json | 65 +++++++++++++++++++++++++ gateway/src/app/app.module.ts | 34 +++++++++++++ gateway/src/app/app.service.ts | 8 +++ gateway/src/app/shopController.ts | 13 +++++ gateway/src/assets/.gitkeep | 0 gateway/src/main.ts | 22 +++++++++ gateway/tsconfig.app.json | 13 +++++ gateway/tsconfig.json | 13 +++++ gateway/webpack.config.js | 25 ++++++++++ module/README.md | 3 ++ module/eslint.config.mjs | 3 ++ module/project.json | 9 ++++ module/src/index.ts | 1 + module/src/lib/keycloak.module.ts | 67 ++++++++++++++++++++++++++ module/tsconfig.json | 20 ++++++++ module/tsconfig.lib.json | 17 +++++++ shared/README.md | 7 +++ shared/eslint.config.mjs | 19 ++++++++ shared/package.json | 11 +++++ shared/project.json | 19 ++++++++ shared/src/index.ts | 1 + shared/src/lib/constants.ts | 11 +++++ shared/tsconfig.json | 20 ++++++++ shared/tsconfig.lib.json | 9 ++++ shop-service/eslint.config.mjs | 3 ++ shop-service/project.json | 65 +++++++++++++++++++++++++ shop-service/src/app/app.controller.ts | 12 +++++ shop-service/src/app/app.module.ts | 10 ++++ shop-service/src/app/app.service.ts | 8 +++ shop-service/src/assets/.gitkeep | 0 shop-service/src/main.ts | 21 ++++++++ shop-service/tsconfig.app.json | 13 +++++ shop-service/tsconfig.json | 13 +++++ shop-service/webpack.config.js | 25 ++++++++++ tsconfig.base.json | 23 +++++++++ user-service/eslint.config.mjs | 3 ++ user-service/project.json | 65 +++++++++++++++++++++++++ user-service/src/app/app.controller.ts | 12 +++++ user-service/src/app/app.module.ts | 21 ++++++++ user-service/src/app/app.service.ts | 8 +++ user-service/src/assets/.gitkeep | 0 user-service/src/main.ts | 21 ++++++++ user-service/tsconfig.app.json | 13 +++++ user-service/tsconfig.json | 13 +++++ user-service/webpack.config.js | 25 ++++++++++ 51 files changed, 905 insertions(+) create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 .vscode/launch.json create mode 100644 eslint.config.mjs create mode 100644 gateway/.env create mode 100644 gateway/eslint.config.mjs create mode 100644 gateway/project.json create mode 100644 gateway/src/app/app.module.ts create mode 100644 gateway/src/app/app.service.ts create mode 100644 gateway/src/app/shopController.ts create mode 100644 gateway/src/assets/.gitkeep create mode 100644 gateway/src/main.ts create mode 100644 gateway/tsconfig.app.json create mode 100644 gateway/tsconfig.json create mode 100644 gateway/webpack.config.js create mode 100644 module/README.md create mode 100644 module/eslint.config.mjs create mode 100644 module/project.json create mode 100644 module/src/index.ts create mode 100644 module/src/lib/keycloak.module.ts create mode 100644 module/tsconfig.json create mode 100644 module/tsconfig.lib.json create mode 100644 shared/README.md create mode 100644 shared/eslint.config.mjs create mode 100644 shared/package.json create mode 100644 shared/project.json create mode 100644 shared/src/index.ts create mode 100644 shared/src/lib/constants.ts create mode 100644 shared/tsconfig.json create mode 100644 shared/tsconfig.lib.json create mode 100644 shop-service/eslint.config.mjs create mode 100644 shop-service/project.json create mode 100644 shop-service/src/app/app.controller.ts create mode 100644 shop-service/src/app/app.module.ts create mode 100644 shop-service/src/app/app.service.ts create mode 100644 shop-service/src/assets/.gitkeep create mode 100644 shop-service/src/main.ts create mode 100644 shop-service/tsconfig.app.json create mode 100644 shop-service/tsconfig.json create mode 100644 shop-service/webpack.config.js create mode 100644 tsconfig.base.json create mode 100644 user-service/eslint.config.mjs create mode 100644 user-service/project.json create mode 100644 user-service/src/app/app.controller.ts create mode 100644 user-service/src/app/app.module.ts create mode 100644 user-service/src/app/app.service.ts create mode 100644 user-service/src/assets/.gitkeep create mode 100644 user-service/src/main.ts create mode 100644 user-service/tsconfig.app.json create mode 100644 user-service/tsconfig.json create mode 100644 user-service/webpack.config.js diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..e26f0b3 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +# Add files here to ignore them from prettier formatting +/dist +/coverage +/.nx/cache +/.nx/workspace-data \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..544138b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..86ca82b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,59 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Debug gateway with Nx", + "runtimeExecutable": "pnpm exec", + "runtimeArgs": ["nx", "serve", "gateway"], + "env": { + "NODE_OPTIONS": "--inspect=9229" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "skipFiles": ["/**"], + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/gateway/dist/**/*.(m|c|)js", + "!**/node_modules/**" + ] + }, + { + "type": "node", + "request": "launch", + "name": "Debug shop-service with Nx", + "runtimeExecutable": "pnpm exec", + "runtimeArgs": ["nx", "serve", "shop-service"], + "env": { + "NODE_OPTIONS": "--inspect=9230" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "skipFiles": ["/**"], + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/shop-service/dist/**/*.(m|c|)js", + "!**/node_modules/**" + ] + }, + { + "type": "node", + "request": "launch", + "name": "Debug user-service with Nx", + "runtimeExecutable": "pnpm exec", + "runtimeArgs": ["nx", "serve", "user-service"], + "env": { + "NODE_OPTIONS": "--inspect=9231" + }, + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "skipFiles": ["/**"], + "sourceMaps": true, + "outFiles": [ + "${workspaceFolder}/user-service/dist/**/*.(m|c|)js", + "!**/node_modules/**" + ] + } + ] +} diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..5f08df3 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,42 @@ +import nx from '@nx/eslint-plugin'; + +export default [ + ...nx.configs['flat/base'], + ...nx.configs['flat/typescript'], + ...nx.configs['flat/javascript'], + { + ignores: ['**/dist', '**/out-tsc'], + }, + { + files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'], + rules: { + '@nx/enforce-module-boundaries': [ + 'error', + { + enforceBuildableLibDependency: true, + allow: ['^.*/eslint(\\.base)?\\.config\\.[cm]?[jt]s$'], + depConstraints: [ + { + sourceTag: '*', + onlyDependOnLibsWithTags: ['*'], + }, + ], + }, + ], + }, + }, + { + files: [ + '**/*.ts', + '**/*.tsx', + '**/*.cts', + '**/*.mts', + '**/*.js', + '**/*.jsx', + '**/*.cjs', + '**/*.mjs', + ], + // Override or add rules here + rules: {}, + }, +]; diff --git a/gateway/.env b/gateway/.env new file mode 100644 index 0000000..8210198 --- /dev/null +++ b/gateway/.env @@ -0,0 +1,9 @@ +# +PORT=3001 +# +KEYCLOAK_URL=http://localhost:8080 +KEYCLOAK_REALM=appweb +KEYCLOAK_CLIENT_ID=gateway +KEYCLOAK_CLIENT_SECRET=IJQG0mzAdauXlyqh0NsSBpZnI2J8XoI7 +# +SHOP_URL=http://localhost:8080 diff --git a/gateway/eslint.config.mjs b/gateway/eslint.config.mjs new file mode 100644 index 0000000..fef103b --- /dev/null +++ b/gateway/eslint.config.mjs @@ -0,0 +1,3 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [...baseConfig]; diff --git a/gateway/project.json b/gateway/project.json new file mode 100644 index 0000000..3bd6228 --- /dev/null +++ b/gateway/project.json @@ -0,0 +1,65 @@ +{ + "name": "gateway", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "gateway/src", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "webpack-cli build", + "args": ["--node-env=production"], + "cwd": "gateway" + }, + "configurations": { + "development": { + "args": ["--node-env=development"] + } + } + }, + "prune-lockfile": { + "dependsOn": ["build"], + "cache": true, + "executor": "@nx/js:prune-lockfile", + "outputs": [ + "{workspaceRoot}/dist/gateway/package.json", + "{workspaceRoot}/dist/gateway/pnpm-lock.yaml" + ], + "options": { + "buildTarget": "build" + } + }, + "copy-workspace-modules": { + "dependsOn": ["build"], + "cache": true, + "outputs": ["{workspaceRoot}/dist/gateway/workspace_modules"], + "executor": "@nx/js:copy-workspace-modules", + "options": { + "buildTarget": "build" + } + }, + "prune": { + "dependsOn": ["prune-lockfile", "copy-workspace-modules"], + "executor": "nx:noop" + }, + "serve": { + "continuous": true, + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "dependsOn": ["build"], + "options": { + "buildTarget": "gateway:build", + "runBuildTargetDependencies": false + }, + "configurations": { + "development": { + "buildTarget": "gateway:build:development" + }, + "production": { + "buildTarget": "gateway:build:production" + } + } + } + } +} diff --git a/gateway/src/app/app.module.ts b/gateway/src/app/app.module.ts new file mode 100644 index 0000000..7c65ae5 --- /dev/null +++ b/gateway/src/app/app.module.ts @@ -0,0 +1,34 @@ +import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; +import { join } from 'path'; +import * as fs from 'fs'; +import { AppService } from './app.service'; +import { ShopController } from './shopController'; +import { ConfigModule } from '@nestjs/config'; +import { KeycloakModule } from '@appweb/module'; +import { TraceMiddleware } from '../common/middleware/trace.middleware'; + +const debugPath = join(__dirname, '..', 'environment', '.env'); +console.log('--- DEBUG ENV ---'); +console.log('CWD attuale:', process.cwd()); +console.log('Percorso calcolato:', debugPath); +console.log('Il file esiste?', fs.existsSync(debugPath)); +console.log('-----------------'); + +@Module({ + imports: [ + // 1. Configurazione del ConfigModule con le tue specifiche + ConfigModule.forRoot({ + isGlobal: true, // Variabili disponibili ovunque + cache: true, // Migliora le performance leggendo dal file solo una volta + envFilePath: join(process.cwd(), 'gateway/.env'), // Percorso del file (cercato nella root del workspace Nx) + }), + KeycloakModule, + ], + providers: [AppService], + controllers: [ShopController], +}) +export class AppModule implements NestModule { + configure(consumer: MiddlewareConsumer) { + consumer.apply(TraceMiddleware).forRoutes('*'); // Applica a tutte le rotte + } +} diff --git a/gateway/src/app/app.service.ts b/gateway/src/app/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/gateway/src/app/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' }; + } +} diff --git a/gateway/src/app/shopController.ts b/gateway/src/app/shopController.ts new file mode 100644 index 0000000..53bec94 --- /dev/null +++ b/gateway/src/app/shopController.ts @@ -0,0 +1,13 @@ +import { Controller, Get, Req } from '@nestjs/common'; +import { Roles } from 'nest-keycloak-connect'; + +@Controller('shop') +export class ShopController { + @Get('products') + @Roles({ roles: ['shop'] }) + async getProducts(@Req() req) { + return { + user: req.user, + }; + } +} diff --git a/gateway/src/assets/.gitkeep b/gateway/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/gateway/src/main.ts b/gateway/src/main.ts new file mode 100644 index 0000000..c7e5cc6 --- /dev/null +++ b/gateway/src/main.ts @@ -0,0 +1,22 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app/app.module'; +import { join } from 'path'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.PORT || 3000; + await app.listen(port); + Logger.log( + `๐Ÿš€ Application is running on: http://localhost:${port}/${globalPrefix}`, + ); +} + +bootstrap(); diff --git a/gateway/tsconfig.app.json b/gateway/tsconfig.app.json new file mode 100644 index 0000000..ec8c890 --- /dev/null +++ b/gateway/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "target": "es2021", + "moduleResolution": "node" + }, + "include": ["src/**/*.ts"] +} diff --git a/gateway/tsconfig.json b/gateway/tsconfig.json new file mode 100644 index 0000000..d4b12b9 --- /dev/null +++ b/gateway/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/gateway/webpack.config.js b/gateway/webpack.config.js new file mode 100644 index 0000000..175377c --- /dev/null +++ b/gateway/webpack.config.js @@ -0,0 +1,25 @@ +const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin'); +const { join } = require('path'); + +module.exports = { + output: { + path: join(__dirname, '../dist/gateway'), + clean: true, + ...(process.env.NODE_ENV !== 'production' && { + devtoolModuleFilenameTemplate: '[absolute-resource-path]', + }), + }, + plugins: [ + new NxAppWebpackPlugin({ + target: 'node', + compiler: 'tsc', + main: './src/main.ts', + tsConfig: './tsconfig.app.json', + assets: ['./src/assets'], + optimization: false, + outputHashing: 'none', + generatePackageJson: true, + sourceMap: true, + }), + ], +}; diff --git a/module/README.md b/module/README.md new file mode 100644 index 0000000..55d7d0f --- /dev/null +++ b/module/README.md @@ -0,0 +1,3 @@ +# module + +This library was generated with [Nx](https://nx.dev). diff --git a/module/eslint.config.mjs b/module/eslint.config.mjs new file mode 100644 index 0000000..fef103b --- /dev/null +++ b/module/eslint.config.mjs @@ -0,0 +1,3 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [...baseConfig]; diff --git a/module/project.json b/module/project.json new file mode 100644 index 0000000..fed44d9 --- /dev/null +++ b/module/project.json @@ -0,0 +1,9 @@ +{ + "name": "module", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "module/src", + "projectType": "library", + "tags": [], + "// targets": "to see all targets run: nx show project module --web", + "targets": {} +} diff --git a/module/src/index.ts b/module/src/index.ts new file mode 100644 index 0000000..4c88264 --- /dev/null +++ b/module/src/index.ts @@ -0,0 +1 @@ +export * from './lib/keycloak.module'; diff --git a/module/src/lib/keycloak.module.ts b/module/src/lib/keycloak.module.ts new file mode 100644 index 0000000..0fe30e6 --- /dev/null +++ b/module/src/lib/keycloak.module.ts @@ -0,0 +1,67 @@ +import { Module } from '@nestjs/common'; +import { AuthGuard, ResourceGuard, RoleGuard } from 'nest-keycloak-connect'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { + KeycloakConnectModule, + PolicyEnforcementMode, + TokenValidation, +} from 'nest-keycloak-connect'; +import { KeycloakConfigKeys } from '@appweb/shared'; +import { APP_GUARD } from '@nestjs/core'; + +@Module({ + imports: [ + KeycloakConnectModule.registerAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: async (config: ConfigService) => { + console.debug('URL: ', KeycloakConfigKeys.BASE_URL); + console.debug('CLIENT_ID: ', KeycloakConfigKeys.CLIENT_ID); + console.debug('REALM: ', KeycloakConfigKeys.REALM); + console.debug('CLIENT_SECRET: ', KeycloakConfigKeys.CLIENT_SECRET); + // Recuperiamo i valori assicurandoci che non siano undefined + const authServerUrl = config.get(KeycloakConfigKeys.BASE_URL); + const realm = config.get(KeycloakConfigKeys.REALM); + const clientId = config.get(KeycloakConfigKeys.CLIENT_ID); + const secret = config.get(KeycloakConfigKeys.CLIENT_SECRET); + + console.debug('authServerUrl: ', authServerUrl); + console.debug('realm: ', realm); + console.debug('clientId: ', clientId); + console.debug('secret: ', secret); + + // Se mancano, NestJS lancerร  un errore chiaro all'avvio + if (!authServerUrl || !realm || !clientId || !secret) { + throw new Error("Mancano variabili d'ambiente critiche per Keycloak"); + } + + return { + authServerUrl, + realm, + clientId, + secret, + // Aggiungi queste se necessario per completare il tipo richiesto + policyEnforcement: PolicyEnforcementMode.PERMISSIVE, + tokenValidation: TokenValidation.ONLINE, + }; + }, + }), + ], + providers: [ + // Registriamo i Guard qui dentro! + { + provide: APP_GUARD, + useClass: AuthGuard, + }, + { + provide: APP_GUARD, + useClass: ResourceGuard, + }, + { + provide: APP_GUARD, + useClass: RoleGuard, + }, + ], + exports: [KeycloakConnectModule], +}) +export class KeycloakModule {} diff --git a/module/tsconfig.json b/module/tsconfig.json new file mode 100644 index 0000000..a44d9be --- /dev/null +++ b/module/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "importHelpers": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/module/tsconfig.lib.json b/module/tsconfig.lib.json new file mode 100644 index 0000000..2f126eb --- /dev/null +++ b/module/tsconfig.lib.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es2021", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"] +} diff --git a/shared/README.md b/shared/README.md new file mode 100644 index 0000000..93629ba --- /dev/null +++ b/shared/README.md @@ -0,0 +1,7 @@ +# shared + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build shared` to build the library. diff --git a/shared/eslint.config.mjs b/shared/eslint.config.mjs new file mode 100644 index 0000000..cf2600c --- /dev/null +++ b/shared/eslint.config.mjs @@ -0,0 +1,19 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [ + ...baseConfig, + { + files: ['**/*.json'], + rules: { + '@nx/dependency-checks': [ + 'error', + { + ignoredFiles: ['{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}'], + }, + ], + }, + languageOptions: { + parser: await import('jsonc-eslint-parser'), + }, + }, +]; diff --git a/shared/package.json b/shared/package.json new file mode 100644 index 0000000..21c5a6e --- /dev/null +++ b/shared/package.json @@ -0,0 +1,11 @@ +{ + "name": "@appweb/shared", + "version": "0.0.1", + "private": true, + "type": "commonjs", + "main": "./src/index.js", + "types": "./src/index.d.ts", + "dependencies": { + "tslib": "^2.3.0" + } +} diff --git a/shared/project.json b/shared/project.json new file mode 100644 index 0000000..01c737e --- /dev/null +++ b/shared/project.json @@ -0,0 +1,19 @@ +{ + "name": "shared", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "shared/src", + "projectType": "library", + "tags": [], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/shared", + "main": "shared/src/index.ts", + "tsConfig": "shared/tsconfig.lib.json", + "assets": ["shared/*.md"] + } + } + } +} diff --git a/shared/src/index.ts b/shared/src/index.ts new file mode 100644 index 0000000..4ddb942 --- /dev/null +++ b/shared/src/index.ts @@ -0,0 +1 @@ +export * from './lib/constants'; diff --git a/shared/src/lib/constants.ts b/shared/src/lib/constants.ts new file mode 100644 index 0000000..df9acaf --- /dev/null +++ b/shared/src/lib/constants.ts @@ -0,0 +1,11 @@ +/** + * Nomi delle chiavi per le variabili d'ambiente. + * Centralizzandole qui, evitiamo di scrivere stringhe a mano nei vari moduli. + */ +export class KeycloakConfigKeys { + static readonly BASE_URL = 'KEYCLOAK_BASE_URL'; + static readonly URL_AUTH = 'KEYCLOAK_URL_AUTH'; + static readonly REALM = 'KEYCLOAK_REALM'; + static readonly CLIENT_ID = 'KEYCLOAK_CLIENT_ID'; + static readonly CLIENT_SECRET = 'KEYCLOAK_CLIENT_SECRET'; +} diff --git a/shared/tsconfig.json b/shared/tsconfig.json new file mode 100644 index 0000000..a44d9be --- /dev/null +++ b/shared/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "importHelpers": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/shared/tsconfig.lib.json b/shared/tsconfig.lib.json new file mode 100644 index 0000000..aa49926 --- /dev/null +++ b/shared/tsconfig.lib.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"] +} diff --git a/shop-service/eslint.config.mjs b/shop-service/eslint.config.mjs new file mode 100644 index 0000000..fef103b --- /dev/null +++ b/shop-service/eslint.config.mjs @@ -0,0 +1,3 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [...baseConfig]; diff --git a/shop-service/project.json b/shop-service/project.json new file mode 100644 index 0000000..62fce47 --- /dev/null +++ b/shop-service/project.json @@ -0,0 +1,65 @@ +{ + "name": "shop-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "shop-service/src", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "webpack-cli build", + "args": ["--node-env=production"], + "cwd": "shop-service" + }, + "configurations": { + "development": { + "args": ["--node-env=development"] + } + } + }, + "prune-lockfile": { + "dependsOn": ["build"], + "cache": true, + "executor": "@nx/js:prune-lockfile", + "outputs": [ + "{workspaceRoot}/dist/shop-service/package.json", + "{workspaceRoot}/dist/shop-service/pnpm-lock.yaml" + ], + "options": { + "buildTarget": "build" + } + }, + "copy-workspace-modules": { + "dependsOn": ["build"], + "cache": true, + "outputs": ["{workspaceRoot}/dist/shop-service/workspace_modules"], + "executor": "@nx/js:copy-workspace-modules", + "options": { + "buildTarget": "build" + } + }, + "prune": { + "dependsOn": ["prune-lockfile", "copy-workspace-modules"], + "executor": "nx:noop" + }, + "serve": { + "continuous": true, + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "dependsOn": ["build"], + "options": { + "buildTarget": "shop-service:build", + "runBuildTargetDependencies": false + }, + "configurations": { + "development": { + "buildTarget": "shop-service:build:development" + }, + "production": { + "buildTarget": "shop-service:build:production" + } + } + } + } +} diff --git a/shop-service/src/app/app.controller.ts b/shop-service/src/app/app.controller.ts new file mode 100644 index 0000000..aa4a3dd --- /dev/null +++ b/shop-service/src/app/app.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getData() { + return this.appService.getData(); + } +} diff --git a/shop-service/src/app/app.module.ts b/shop-service/src/app/app.module.ts new file mode 100644 index 0000000..8662803 --- /dev/null +++ b/shop-service/src/app/app.module.ts @@ -0,0 +1,10 @@ +import { Module } from '@nestjs/common'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; + +@Module({ + imports: [], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/shop-service/src/app/app.service.ts b/shop-service/src/app/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/shop-service/src/app/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' }; + } +} diff --git a/shop-service/src/assets/.gitkeep b/shop-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/shop-service/src/main.ts b/shop-service/src/main.ts new file mode 100644 index 0000000..27cc058 --- /dev/null +++ b/shop-service/src/main.ts @@ -0,0 +1,21 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app/app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.PORT || 3000; + await app.listen(port); + Logger.log( + `๐Ÿš€ Application is running on: http://localhost:${port}/${globalPrefix}`, + ); +} + +bootstrap(); diff --git a/shop-service/tsconfig.app.json b/shop-service/tsconfig.app.json new file mode 100644 index 0000000..ec8c890 --- /dev/null +++ b/shop-service/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "target": "es2021", + "moduleResolution": "node" + }, + "include": ["src/**/*.ts"] +} diff --git a/shop-service/tsconfig.json b/shop-service/tsconfig.json new file mode 100644 index 0000000..d4b12b9 --- /dev/null +++ b/shop-service/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/shop-service/webpack.config.js b/shop-service/webpack.config.js new file mode 100644 index 0000000..ac1165f --- /dev/null +++ b/shop-service/webpack.config.js @@ -0,0 +1,25 @@ +const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin'); +const { join } = require('path'); + +module.exports = { + output: { + path: join(__dirname, '../dist/shop-service'), + clean: true, + ...(process.env.NODE_ENV !== 'production' && { + devtoolModuleFilenameTemplate: '[absolute-resource-path]', + }), + }, + plugins: [ + new NxAppWebpackPlugin({ + target: 'node', + compiler: 'tsc', + main: './src/main.ts', + tsConfig: './tsconfig.app.json', + assets: ['./src/assets'], + optimization: false, + outputHashing: 'none', + generatePackageJson: true, + sourceMap: true, + }), + ], +}; diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..841928a --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,23 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "rootDir": ".", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "es2015", + "module": "esnext", + "lib": ["es2020", "dom"], + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "baseUrl": ".", + "paths": { + "@appweb/shared": ["shared/src/index.ts"], + "@appweb/module": ["module/src/index.ts"] + } + }, + "exclude": ["node_modules", "tmp"] +} diff --git a/user-service/eslint.config.mjs b/user-service/eslint.config.mjs new file mode 100644 index 0000000..fef103b --- /dev/null +++ b/user-service/eslint.config.mjs @@ -0,0 +1,3 @@ +import baseConfig from '../eslint.config.mjs'; + +export default [...baseConfig]; diff --git a/user-service/project.json b/user-service/project.json new file mode 100644 index 0000000..55f9cc9 --- /dev/null +++ b/user-service/project.json @@ -0,0 +1,65 @@ +{ + "name": "user-service", + "$schema": "../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "user-service/src", + "projectType": "application", + "tags": [], + "targets": { + "build": { + "executor": "nx:run-commands", + "options": { + "command": "webpack-cli build", + "args": ["--node-env=production"], + "cwd": "user-service" + }, + "configurations": { + "development": { + "args": ["--node-env=development"] + } + } + }, + "prune-lockfile": { + "dependsOn": ["build"], + "cache": true, + "executor": "@nx/js:prune-lockfile", + "outputs": [ + "{workspaceRoot}/dist/user-service/package.json", + "{workspaceRoot}/dist/user-service/pnpm-lock.yaml" + ], + "options": { + "buildTarget": "build" + } + }, + "copy-workspace-modules": { + "dependsOn": ["build"], + "cache": true, + "outputs": ["{workspaceRoot}/dist/user-service/workspace_modules"], + "executor": "@nx/js:copy-workspace-modules", + "options": { + "buildTarget": "build" + } + }, + "prune": { + "dependsOn": ["prune-lockfile", "copy-workspace-modules"], + "executor": "nx:noop" + }, + "serve": { + "continuous": true, + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "dependsOn": ["build"], + "options": { + "buildTarget": "user-service:build", + "runBuildTargetDependencies": false + }, + "configurations": { + "development": { + "buildTarget": "user-service:build:development" + }, + "production": { + "buildTarget": "user-service:build:production" + } + } + } + } +} diff --git a/user-service/src/app/app.controller.ts b/user-service/src/app/app.controller.ts new file mode 100644 index 0000000..aa4a3dd --- /dev/null +++ b/user-service/src/app/app.controller.ts @@ -0,0 +1,12 @@ +import { Controller, Get } from '@nestjs/common'; +import { AppService } from './app.service'; + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getData() { + return this.appService.getData(); + } +} diff --git a/user-service/src/app/app.module.ts b/user-service/src/app/app.module.ts new file mode 100644 index 0000000..2bb8e84 --- /dev/null +++ b/user-service/src/app/app.module.ts @@ -0,0 +1,21 @@ +import { Module } from '@nestjs/common'; +import { ConfigModule } from '@nestjs/config'; +import { AppController } from './app.controller'; +import { AppService } from './app.service'; +import { join } from 'path'; +import { KeycloakModule } from '@appweb/module'; + +@Module({ + imports: [ + // 1. Configurazione del ConfigModule con le tue specifiche + ConfigModule.forRoot({ + isGlobal: true, // Variabili disponibili ovunque + cache: true, // Migliora le performance leggendo dal file solo una volta + envFilePath: join(process.cwd(), 'user-service/.env'), // Percorso del file (cercato nella root del workspace Nx) + }), + KeycloakModule, + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/user-service/src/app/app.service.ts b/user-service/src/app/app.service.ts new file mode 100644 index 0000000..cd8cede --- /dev/null +++ b/user-service/src/app/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' }; + } +} diff --git a/user-service/src/assets/.gitkeep b/user-service/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/user-service/src/main.ts b/user-service/src/main.ts new file mode 100644 index 0000000..27cc058 --- /dev/null +++ b/user-service/src/main.ts @@ -0,0 +1,21 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common'; +import { NestFactory } from '@nestjs/core'; +import { AppModule } from './app/app.module'; + +async function bootstrap() { + const app = await NestFactory.create(AppModule); + const globalPrefix = 'api'; + app.setGlobalPrefix(globalPrefix); + const port = process.env.PORT || 3000; + await app.listen(port); + Logger.log( + `๐Ÿš€ Application is running on: http://localhost:${port}/${globalPrefix}`, + ); +} + +bootstrap(); diff --git a/user-service/tsconfig.app.json b/user-service/tsconfig.app.json new file mode 100644 index 0000000..ec8c890 --- /dev/null +++ b/user-service/tsconfig.app.json @@ -0,0 +1,13 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "target": "es2021", + "moduleResolution": "node" + }, + "include": ["src/**/*.ts"] +} diff --git a/user-service/tsconfig.json b/user-service/tsconfig.json new file mode 100644 index 0000000..d4b12b9 --- /dev/null +++ b/user-service/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/user-service/webpack.config.js b/user-service/webpack.config.js new file mode 100644 index 0000000..e9cfb84 --- /dev/null +++ b/user-service/webpack.config.js @@ -0,0 +1,25 @@ +const { NxAppWebpackPlugin } = require('@nx/webpack/app-plugin'); +const { join } = require('path'); + +module.exports = { + output: { + path: join(__dirname, '../dist/user-service'), + clean: true, + ...(process.env.NODE_ENV !== 'production' && { + devtoolModuleFilenameTemplate: '[absolute-resource-path]', + }), + }, + plugins: [ + new NxAppWebpackPlugin({ + target: 'node', + compiler: 'tsc', + main: './src/main.ts', + tsConfig: './tsconfig.app.json', + assets: ['./src/assets'], + optimization: false, + outputHashing: 'none', + generatePackageJson: true, + sourceMap: true, + }), + ], +};