feat(web)!: SPA (#5069)
* feat(web): SPA * chore: remove unnecessary prune * feat(web): merge with immich-server * Correct method name * fix: bugs, docs, workflows, etc. * chore: keep dockerignore for dev * chore: remove license * fix: expose 2283 --------- Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
@@ -13,6 +13,7 @@ import {
|
||||
SwaggerDocumentOptions,
|
||||
SwaggerModule,
|
||||
} from '@nestjs/swagger';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { writeFileSync } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
@@ -56,6 +57,12 @@ const patchOpenAPI = (document: OpenAPIObject) => {
|
||||
document.components.schemas = sortKeys(document.components.schemas);
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(document.paths)) {
|
||||
const newKey = key.replace('/api/', '/');
|
||||
delete document.paths[key];
|
||||
document.paths[newKey] = value;
|
||||
}
|
||||
|
||||
for (const path of Object.values(document.paths)) {
|
||||
const operations = {
|
||||
get: path.get,
|
||||
@@ -94,6 +101,14 @@ const patchOpenAPI = (document: OpenAPIObject) => {
|
||||
return document;
|
||||
};
|
||||
|
||||
export const indexFallback = (excludePaths: string[]) => (req: Request, res: Response, next: NextFunction) => {
|
||||
if (req.url.startsWith('/api') || req.method.toLowerCase() !== 'get' || excludePaths.indexOf(req.url) !== -1) {
|
||||
next();
|
||||
} else {
|
||||
res.sendFile('/www/index.html', { root: process.cwd() });
|
||||
}
|
||||
};
|
||||
|
||||
export const useSwagger = (app: INestApplication, isDev: boolean) => {
|
||||
const config = new DocumentBuilder()
|
||||
.setTitle('Immich')
|
||||
|
||||
@@ -1,15 +1,34 @@
|
||||
import { SystemConfigService } from '@app/domain';
|
||||
import { Controller, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||
import { Controller, Get, Header, HttpCode, HttpStatus, Post } from '@nestjs/common';
|
||||
import { ApiExcludeEndpoint } from '@nestjs/swagger';
|
||||
import { PublicRoute } from '../app.guard';
|
||||
|
||||
@Controller()
|
||||
export class AppController {
|
||||
constructor(private configService: SystemConfigService) {}
|
||||
constructor(private service: SystemConfigService) {}
|
||||
|
||||
@ApiExcludeEndpoint()
|
||||
@Get('.well-known/immich')
|
||||
getImmichWellKnown() {
|
||||
return {
|
||||
api: {
|
||||
endpoint: '/api',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ApiExcludeEndpoint()
|
||||
@PublicRoute()
|
||||
@Get('custom.css')
|
||||
@Header('Content-Type', 'text/css')
|
||||
getCustomCss() {
|
||||
return this.service.getCustomCss();
|
||||
}
|
||||
|
||||
@ApiExcludeEndpoint()
|
||||
@Post('refresh-config')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
public reloadConfig() {
|
||||
return this.configService.refreshConfig();
|
||||
return this.service.refreshConfig();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { json } from 'body-parser';
|
||||
import cookieParser from 'cookie-parser';
|
||||
import { AppModule } from './app.module';
|
||||
import { useSwagger } from './app.utils';
|
||||
import { indexFallback, useSwagger } from './app.utils';
|
||||
|
||||
const logger = new Logger('ImmichServer');
|
||||
const port = Number(process.env.SERVER_PORT) || 3001;
|
||||
@@ -24,6 +24,11 @@ export async function bootstrap() {
|
||||
app.useWebSocketAdapter(new RedisIoAdapter(app));
|
||||
useSwagger(app, isDev);
|
||||
|
||||
const excludePaths = ['/.well-known/immich', '/custom.css'];
|
||||
app.setGlobalPrefix('api', { exclude: excludePaths });
|
||||
app.useStaticAssets('www');
|
||||
app.use(indexFallback(excludePaths));
|
||||
|
||||
const server = await app.listen(port);
|
||||
server.requestTimeout = 30 * 60 * 1000;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user