mirror of
https://github.com/immich-app/immich.git
synced 2025-12-05 20:40:29 -08:00
Compare commits
1 Commits
6c44ba0324
...
feat/stati
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6fd39767db |
19
pnpm-lock.yaml
generated
19
pnpm-lock.yaml
generated
@@ -789,6 +789,9 @@ importers:
|
||||
'@koddsson/eslint-plugin-tscompat':
|
||||
specifier: ^0.2.0
|
||||
version: 0.2.0(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)
|
||||
'@rollup/plugin-replace':
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2(rollup@4.52.5)
|
||||
'@socket.io/component-emitter':
|
||||
specifier: ^3.1.0
|
||||
version: 3.1.2
|
||||
@@ -3681,6 +3684,15 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^18.0 || ^19.0 || ^19.0.0-rc
|
||||
|
||||
'@rollup/plugin-replace@6.0.2':
|
||||
resolution: {integrity: sha512-7QaYCf8bqF04dOy7w/eHmJeNExxTYwvKAmlSAH/EaWWUzbT0h5sbF6bktFoX/0F/0qwng5/dWFMyf3gzaM8DsQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/pluginutils@5.3.0':
|
||||
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
@@ -15290,6 +15302,13 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.2.0
|
||||
|
||||
'@rollup/plugin-replace@6.0.2(rollup@4.52.5)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@4.52.5)
|
||||
magic-string: 0.30.19
|
||||
optionalDependencies:
|
||||
rollup: 4.52.5
|
||||
|
||||
'@rollup/pluginutils@5.3.0(rollup@4.52.5)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
|
||||
@@ -195,4 +195,10 @@ export class EnvDto {
|
||||
@IsString()
|
||||
@Optional()
|
||||
REDIS_URL?: string;
|
||||
|
||||
@ValidateBoolean({ optional: true })
|
||||
IMMICH_DEV_CORS_ALL_ORIGINS?: boolean;
|
||||
|
||||
@ValidateBoolean({ optional: true })
|
||||
IMMICH_DEV_CORS_CREDENTIALS?: boolean;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { RegisterQueueOptions } from '@nestjs/bullmq';
|
||||
import { Inject, Injectable, Optional } from '@nestjs/common';
|
||||
import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
|
||||
import { QueueOptions } from 'bullmq';
|
||||
import { plainToInstance } from 'class-transformer';
|
||||
import { validateSync } from 'class-validator';
|
||||
@@ -30,6 +31,13 @@ export interface EnvData {
|
||||
configFile?: string;
|
||||
logLevel?: LogLevel;
|
||||
|
||||
dev: {
|
||||
cors: {
|
||||
allOrigins?: boolean;
|
||||
credentials?: boolean;
|
||||
};
|
||||
};
|
||||
|
||||
buildMetadata: {
|
||||
build?: string;
|
||||
buildUrl?: string;
|
||||
@@ -222,6 +230,13 @@ const getEnv = (): EnvData => {
|
||||
configFile: dto.IMMICH_CONFIG_FILE,
|
||||
logLevel: dto.IMMICH_LOG_LEVEL,
|
||||
|
||||
dev: {
|
||||
cors: {
|
||||
allOrigins: dto.IMMICH_DEV_CORS_ALL_ORIGINS,
|
||||
credentials: dto.IMMICH_DEV_CORS_CREDENTIALS,
|
||||
},
|
||||
},
|
||||
|
||||
buildMetadata: {
|
||||
build: dto.IMMICH_BUILD,
|
||||
buildUrl: dto.IMMICH_BUILD_URL,
|
||||
@@ -342,6 +357,24 @@ export class ConfigRepository {
|
||||
return this.getEnv().environment === ImmichEnvironment.Development;
|
||||
}
|
||||
|
||||
getCorsOptions(): CorsOptions | undefined {
|
||||
const options: Partial<CorsOptions> = {};
|
||||
const env = this.getEnv();
|
||||
|
||||
if (env.dev.cors.allOrigins) {
|
||||
options.origin = (requestOrigin, callback) => {
|
||||
callback(null, requestOrigin);
|
||||
};
|
||||
}
|
||||
if (env.dev.cors.credentials) {
|
||||
options.credentials = env.dev.cors.credentials;
|
||||
}
|
||||
if (Object.keys(options).length > 0) {
|
||||
return options;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
getWorker() {
|
||||
return this.worker;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,17 @@ async function bootstrap() {
|
||||
app.use(cookieParser());
|
||||
app.use(json({ limit: '10mb' }));
|
||||
if (configRepository.isDev()) {
|
||||
app.enableCors();
|
||||
const options = configRepository.getCorsOptions();
|
||||
if (options) {
|
||||
logger.warn(`Enabling CORS: ${JSON.stringify(configRepository.getEnv().dev.cors)}`);
|
||||
logger.warn(
|
||||
'NOTE: to properly support a fully statically hosted frontend you MUST configure the frontend/backend to be on the same site. i.e. frontend=https://localhost:1234 and backend=http://localhost:2283 or configure TLS',
|
||||
);
|
||||
app.enableCors(options);
|
||||
} else {
|
||||
logger.warn('Enabling CORS');
|
||||
app.enableCors();
|
||||
}
|
||||
}
|
||||
app.useWebSocketAdapter(new WebSocketAdapter(app));
|
||||
useSwagger(app, { write: configRepository.isDev() });
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
"@eslint/js": "^9.36.0",
|
||||
"@faker-js/faker": "^10.0.0",
|
||||
"@koddsson/eslint-plugin-tscompat": "^0.2.0",
|
||||
"@rollup/plugin-replace": "^6.0.2",
|
||||
"@socket.io/component-emitter": "^3.1.0",
|
||||
"@sveltejs/adapter-static": "^3.0.8",
|
||||
"@sveltejs/enhanced-img": "^0.8.0",
|
||||
|
||||
@@ -1,15 +1,48 @@
|
||||
import { retrieveServerConfig } from '$lib/stores/server-config.store';
|
||||
import { initLanguage } from '$lib/utils';
|
||||
import { AbortError, initLanguage, sleep } from '$lib/utils';
|
||||
import { defaults } from '@immich/sdk';
|
||||
import { memoize } from 'lodash-es';
|
||||
|
||||
type Fetch = typeof fetch;
|
||||
|
||||
const api_server: string = '@IMMICH_API_SERVER@';
|
||||
|
||||
const tryServers = async (fetchFn: typeof fetch) => {
|
||||
const servers = api_server
|
||||
.split(',')
|
||||
.map((v) => v.trim())
|
||||
.filter((v) => v !== '');
|
||||
if (servers.length === 0) {
|
||||
return true;
|
||||
}
|
||||
// servers are in priority order, try in parallel, use first success
|
||||
const fetchers = servers.map(async (url: string) => {
|
||||
const response = await fetchFn(url + '/server/config');
|
||||
if (response.ok) {
|
||||
return url;
|
||||
}
|
||||
throw new AbortError();
|
||||
});
|
||||
try {
|
||||
const urlWinner = await Promise.any(fetchers);
|
||||
defaults.baseUrl = urlWinner;
|
||||
defaults.fetch = (url, options) => fetchFn(url, { credentials: 'include', ...options });
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
async function _init(fetch: Fetch) {
|
||||
// set event.fetch on the fetch-client used by @immich/sdk
|
||||
// https://kit.svelte.dev/docs/load#making-fetch-requests
|
||||
// https://github.com/oazapfts/oazapfts/blob/main/README.md#fetch-options
|
||||
defaults.fetch = fetch;
|
||||
try {
|
||||
await Promise.race([tryServers(fetch), sleep(5000)]);
|
||||
} catch {
|
||||
throw 'Could not connect to any server';
|
||||
}
|
||||
await initLanguage();
|
||||
await retrieveServerConfig();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import { enhancedImages } from '@sveltejs/enhanced-img';
|
||||
import { sveltekit } from '@sveltejs/kit/vite';
|
||||
import tailwindcss from '@tailwindcss/vite';
|
||||
@@ -39,6 +40,16 @@ export default defineConfig({
|
||||
enhancedImages(),
|
||||
tailwindcss(),
|
||||
sveltekit(),
|
||||
replace({
|
||||
preventAssignment: true,
|
||||
include: ['**/server.ts'],
|
||||
sourceMap: true,
|
||||
objectGuards: false,
|
||||
delimiters: ['@', '@'],
|
||||
values: {
|
||||
IMMICH_API_SERVER: process.env.IMMICH_API_SERVER ?? '',
|
||||
},
|
||||
}),
|
||||
process.env.BUILD_STATS === 'true'
|
||||
? visualizer({
|
||||
emitFile: true,
|
||||
|
||||
Reference in New Issue
Block a user