diff --git a/npm/ng-packs/apps/dev-app/project.json b/npm/ng-packs/apps/dev-app/project.json index 69a76c645b..c77c3c3cee 100644 --- a/npm/ng-packs/apps/dev-app/project.json +++ b/npm/ng-packs/apps/dev-app/project.json @@ -6,13 +6,12 @@ "prefix": "app", "targets": { "build": { - "executor": "@angular-devkit/build-angular:application", + "executor": "@angular/build:application", "outputs": ["{options.outputPath}"], "options": { "outputPath": "dist/apps/dev-app", - "index": "apps/dev-app/src/index.html", "browser": "apps/dev-app/src/main.ts", - "polyfills": ["apps/dev-app/src/polyfills.ts"], + "polyfills": ["apps/dev-app/src/polyfills.ts", "zone.js"], "tsConfig": "apps/dev-app/tsconfig.app.json", "inlineStyleLanguage": "scss", "allowedCommonJsDependencies": ["chart.js", "js-sha256"], @@ -115,7 +114,12 @@ }, "apps/dev-app/src/styles.scss" ], - "scripts": [] + "scripts": [], + "server": "apps/dev-app/src/main.server.ts", + "ssr": { + "entry": "apps/dev-app/src/server.ts" + }, + "outputMode": "server" }, "configurations": { "production": { @@ -149,7 +153,8 @@ "defaultConfiguration": "production" }, "serve": { - "executor": "@angular-devkit/build-angular:dev-server", + "continuous": true, + "executor": "@angular/build:dev-server", "configurations": { "production": { "buildTarget": "dev-app:build:production" @@ -178,66 +183,15 @@ "jestConfig": "apps/dev-app/jest.config.ts" } }, - "server": { - "executor": "@angular-devkit/build-angular:server", + "serve-static": { + "continuous": true, + "executor": "@nx/web:file-server", "options": { - "outputPath": "dist/dev-app/server", - "main": "apps/dev-app/src/server.ts", - "tsConfig": "apps/dev-app/tsconfig.server.json", - "inlineStyleLanguage": "scss" - }, - "configurations": { - "production": { - "outputHashing": "media", - "fileReplacements": [ - { - "replace": "apps/dev-app/src/environments/environment.ts", - "with": "apps/dev-app/src/environments/environment.prod.ts" - } - ] - }, - "development": { - "buildOptimizer": false, - "optimization": false, - "sourceMap": true, - "extractLicenses": false, - "vendorChunk": true - } - }, - "defaultConfiguration": "production" - }, - "serve-ssr": { - "executor": "@angular-devkit/build-angular:ssr-dev-server", - "configurations": { - "development": { - "browserTarget": "dev-app:build:development", - "serverTarget": "dev-app:server:development" - }, - "production": { - "browserTarget": "dev-app:build:production", - "serverTarget": "dev-app:server:production" - } - }, - "defaultConfiguration": "development" - }, - "prerender": { - "executor": "@angular-devkit/build-angular:prerender", - "options": { - "routes": [ - "/" - ] - }, - "configurations": { - "production": { - "browserTarget": "dev-app:build:production", - "serverTarget": "dev-app:server:production" - }, - "development": { - "browserTarget": "dev-app:build:development", - "serverTarget": "dev-app:server:development" - } - }, - "defaultConfiguration": "production" + "buildTarget": "my-app:build", + "port": 4200, + "staticFilePath": "dist/apps/dev-app/browser", + "spa": true + } } } } diff --git a/npm/ng-packs/apps/dev-app/src/app/app.routes.server.ts b/npm/ng-packs/apps/dev-app/src/app/app.routes.server.ts index 08b8805de1..2dc219e7b1 100644 --- a/npm/ng-packs/apps/dev-app/src/app/app.routes.server.ts +++ b/npm/ng-packs/apps/dev-app/src/app/app.routes.server.ts @@ -2,23 +2,7 @@ import { RenderMode, ServerRoute } from '@angular/ssr'; export const appServerRoutes: ServerRoute[] = [ { - path: '', + path: '**', renderMode: RenderMode.Server, - }, - { - path: 'account', - renderMode: RenderMode.Server, - }, - { - path: 'identity', - renderMode: RenderMode.Server, - }, - { - path: 'tenant-management', - renderMode: RenderMode.Server, - }, - { - path: 'setting-management', - renderMode: RenderMode.Server, - }, + } ]; diff --git a/npm/ng-packs/apps/dev-app/src/server.ts b/npm/ng-packs/apps/dev-app/src/server.ts index 304a3ba710..02f0c51d16 100644 --- a/npm/ng-packs/apps/dev-app/src/server.ts +++ b/npm/ng-packs/apps/dev-app/src/server.ts @@ -1,87 +1,68 @@ -import { environment } from './environments/environment'; -if (environment.production === false) { - process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0'; -} -import 'zone.js/node'; - -import { APP_BASE_HREF } from '@angular/common'; -import { CommonEngine } from '@angular/ssr/node'; +import { + AngularNodeAppEngine, + createNodeRequestHandler, + isMainModule, + writeResponseToNodeResponse, +} from '@angular/ssr/node'; import express from 'express'; -import { existsSync } from 'node:fs'; -import { join } from 'node:path'; -import bootstrap from './main.server'; - -// The Express app is exported so that it can be used by serverless Functions. -export function app(): express.Express { - const server = express(); - const distFolder = join(process.cwd(), 'dist/dev-app/browser'); - const indexHtml = existsSync(join(distFolder, 'index.original.html')) - ? join(distFolder, 'index.original.html') - : join(distFolder, 'index.html'); +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; - const commonEngine = new CommonEngine(); - - server.set('view engine', 'html'); - server.set('views', distFolder); +if (process.env['NODE_ENV'] === 'development') { + process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"; +} - server.get('/.well-known/appspecific/com.chrome.devtools.json', (req, res) => { - res.status(404).send('Not Found'); - }); +const serverDistFolder = dirname(fileURLToPath(import.meta.url)); +const browserDistFolder = resolve(serverDistFolder, '../browser'); - // Example Express Rest API endpoints - // server.get('/api/{*splat}', (req, res) => { }); - // Serve static files from /browser - server.use( - express.static(distFolder, { - maxAge: '1y', - index: false, - }), - ); +const app = express(); +const angularApp = new AngularNodeAppEngine(); - // All regular routes use the Angular engine - server.use((req, res, next) => { - const { protocol, originalUrl, baseUrl, headers } = req; +/** + * Example Express Rest API endpoints can be defined here. + * Uncomment and define endpoints as necessary. + * + * Example: + * ```ts + * app.get('/api/**', (req, res) => { + * // Handle API request + * }); + * ``` + */ - commonEngine - .render({ - bootstrap, - documentFilePath: indexHtml, - url: `${protocol}://${headers.host}${originalUrl}`, - publicPath: distFolder, - providers: [ - { provide: APP_BASE_HREF, useValue: baseUrl }, - { provide: 'cookies', useValue: JSON.stringify(req.headers.cookie) }, - ], - }) - .then(html => res.send(html)) - .catch(err => next(err)); - }); +/** + * Serve static files from /browser + */ +app.use( + express.static(browserDistFolder, { + maxAge: '1y', + index: false, + redirect: false, + }), +); - return server; -} +/** + * Handle all other requests by rendering the Angular application. + */ +app.use((req, res, next) => { + angularApp + .handle(req) + .then(response => (response ? writeResponseToNodeResponse(response, res) : next())) + .catch(next); +}); -function run(): void { +/** + * Start the server if this module is the main entry point. + * The server listens on the port defined by the `PORT` environment variable, or defaults to 4000. + */ +if (isMainModule(import.meta.url)) { const port = process.env['PORT'] || 4000; - - // Start up the Node server - const server = app(); - server.listen(port, error => { - if (error) { - throw error; - } - + app.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); }); } -// Webpack will replace 'require' with '__webpack_require__' -// '__non_webpack_require__' is a proxy to Node 'require' -// The below code is to ensure that the server is run only when not requiring the bundle. -declare const __non_webpack_require__: NodeRequire; -const mainModule = __non_webpack_require__.main; -const moduleFilename = (mainModule && mainModule.filename) || ''; -if (moduleFilename === __filename || moduleFilename.includes('iisnode')) { - run(); -} - -export default bootstrap; +/** + * Request handler used by the Angular CLI (for dev-server and during build) or Firebase Cloud Functions. + */ +export const reqHandler = createNodeRequestHandler(app); diff --git a/npm/ng-packs/apps/dev-app/tsconfig.app.json b/npm/ng-packs/apps/dev-app/tsconfig.app.json index adbc754523..35197aed67 100644 --- a/npm/ng-packs/apps/dev-app/tsconfig.app.json +++ b/npm/ng-packs/apps/dev-app/tsconfig.app.json @@ -2,11 +2,8 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../dist/out-tsc", - "types": [], - "target": "ES2022", - "useDefineForClassFields": false + "types": ["node"] }, - "files": ["src/main.ts", "src/polyfills.ts"], - "include": ["src/**/*.d.ts"], - "exclude": ["jest.config.ts"] + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/test-setup.ts", "src/**/*.test.ts", "src/**/*.spec.ts"] } diff --git a/npm/ng-packs/apps/dev-app/tsconfig.server.json b/npm/ng-packs/apps/dev-app/tsconfig.server.json deleted file mode 100644 index 0e16840a42..0000000000 --- a/npm/ng-packs/apps/dev-app/tsconfig.server.json +++ /dev/null @@ -1,17 +0,0 @@ -/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ -/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ -{ - "extends": "./tsconfig.app.json", - "compilerOptions": { - "outDir": "../../out-tsc/server", - "types": [ - "node", - "@angular/localize" - ] - }, - "files": [ - "src/main.server.ts", - "src/server.ts", - "src/server.ts" - ] -} diff --git a/npm/ng-packs/nx.json b/npm/ng-packs/nx.json index 0c52ac4bfe..500c939ad2 100644 --- a/npm/ng-packs/nx.json +++ b/npm/ng-packs/nx.json @@ -9,10 +9,10 @@ "defaultProject": "dev-app", "generators": { "@nx/angular:application": { - "style": "scss", + "e2eTestRunner": "cypress", "linter": "eslint", - "unitTestRunner": "jest", - "e2eTestRunner": "cypress" + "style": "scss", + "unitTestRunner": "jest" }, "@nx/angular:library": { "linter": "eslint", @@ -113,6 +113,11 @@ "@nx/eslint:lint": { "inputs": ["default", "{workspaceRoot}/.eslintrc.json"], "cache": true + }, + "@angular/build:application": { + "cache": true, + "dependsOn": ["^build"], + "inputs": ["production", "^production"] } }, "namedInputs": { diff --git a/npm/ng-packs/packages/oauth/src/lib/providers/oauth-module-config.provider.ts b/npm/ng-packs/packages/oauth/src/lib/providers/oauth-module-config.provider.ts index a3994d419a..9030319b3e 100644 --- a/npm/ng-packs/packages/oauth/src/lib/providers/oauth-module-config.provider.ts +++ b/npm/ng-packs/packages/oauth/src/lib/providers/oauth-module-config.provider.ts @@ -32,7 +32,7 @@ export function provideAbpOAuth({ ssr = false }: { ssr?: boolean }) { { provide: authGuard, useValue: abpOAuthGuard, - }, + }, { provide: asyncAuthGuard, useValue: asyncAbpOAuthGuard, @@ -59,18 +59,14 @@ export function provideAbpOAuth({ ssr = false }: { ssr?: boolean }) { inject(OAuthConfigurationHandler); }), OAuthModule.forRoot().providers as Provider[], + ServerTokenStorageService, + BrowserTokenStorageService, { provide: OAuthStorage, useFactory: oAuthStorageFactory, }, { provide: AuthErrorFilterService, useExisting: OAuthErrorFilterService }, ]; - console.log('ssr --->>>>', ssr); - if (ssr) { - providers.push(ServerTokenStorageService); - } else { - providers.push(BrowserTokenStorageService); - } return makeEnvironmentProviders(providers); } diff --git a/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts b/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts index e5c57bd110..fbd40093b2 100644 --- a/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts +++ b/npm/ng-packs/packages/oauth/src/lib/utils/storage.factory.ts @@ -2,6 +2,7 @@ import { inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; import { ServerTokenStorageService } from '../services/server-token-storage.service'; import { BrowserTokenStorageService } from '../services'; +import { OAuthStorage } from 'angular-oauth2-oidc'; export class MockStorage implements Storage { private data = new Map(); @@ -25,7 +26,7 @@ export class MockStorage implements Storage { } } -export function oAuthStorageFactory(): ServerTokenStorageService | BrowserTokenStorageService { +export function oAuthStorageFactory(): OAuthStorage { const platformId = inject(PLATFORM_ID); return isPlatformBrowser(platformId) ? inject(BrowserTokenStorageService)