mirror of
https://github.com/documenso/documenso.git
synced 2025-11-22 20:51:33 +10:00
feat: runtime env
Support runtime environment variables using server components. This will mean docker images can change env vars for runtime as required.
This commit is contained in:
26
packages/lib/universal/runtime-env/client.tsx
Normal file
26
packages/lib/universal/runtime-env/client.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
'use client';
|
||||
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
import { PublicEnv } from './types';
|
||||
|
||||
export type RuntimeEnvClientProviderProps = {
|
||||
value: PublicEnv;
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
const RuntimeEnvContext = React.createContext<PublicEnv | null>(null);
|
||||
|
||||
export const useRuntimeEnv = () => {
|
||||
const context = useContext(RuntimeEnvContext);
|
||||
|
||||
if (!context) {
|
||||
throw new Error('useRuntimeEnv must be used within a RuntimeEnvProvider');
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
export const RuntimeEnvClientProvider = ({ value, children }: RuntimeEnvClientProviderProps) => {
|
||||
return <RuntimeEnvContext.Provider value={value}>{children}</RuntimeEnvContext.Provider>;
|
||||
};
|
||||
22
packages/lib/universal/runtime-env/get-runtime-env.ts
Normal file
22
packages/lib/universal/runtime-env/get-runtime-env.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { PublicEnv } from './types';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
__unstable_runtimeEnv: PublicEnv;
|
||||
}
|
||||
}
|
||||
|
||||
export const getRuntimeEnv = () => {
|
||||
if (typeof window === 'undefined') {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return Object.entries(process.env)
|
||||
.filter(([key]) => key.startsWith('NEXT_PUBLIC_'))
|
||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) as PublicEnv;
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined' && window.__unstable_runtimeEnv) {
|
||||
return window.__unstable_runtimeEnv;
|
||||
}
|
||||
|
||||
throw new Error('RuntimeEnv is not available');
|
||||
};
|
||||
1
packages/lib/universal/runtime-env/index.ts
Normal file
1
packages/lib/universal/runtime-env/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export { RuntimeEnvProvider, type RuntimeEnvProviderProps } from './server';
|
||||
29
packages/lib/universal/runtime-env/server.tsx
Normal file
29
packages/lib/universal/runtime-env/server.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
'use server';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { RuntimeEnvClientProvider } from './client';
|
||||
import { PublicEnv } from './types';
|
||||
|
||||
export type RuntimeEnvProviderProps = {
|
||||
children: React.ReactNode;
|
||||
};
|
||||
|
||||
export const RuntimeEnvProvider = ({ children }: RuntimeEnvProviderProps) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
const publicEnv = Object.entries(process.env)
|
||||
.filter(([key]) => key.startsWith('NEXT_PUBLIC_'))
|
||||
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) as PublicEnv;
|
||||
|
||||
return (
|
||||
<RuntimeEnvClientProvider value={publicEnv}>
|
||||
{children}
|
||||
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `window.__unstable_runtimeEnv = ${JSON.stringify(publicEnv)}`,
|
||||
}}
|
||||
/>
|
||||
</RuntimeEnvClientProvider>
|
||||
);
|
||||
};
|
||||
3
packages/lib/universal/runtime-env/types.ts
Normal file
3
packages/lib/universal/runtime-env/types.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import { PickStartsWith } from '../../types/pick-starts-with';
|
||||
|
||||
export type PublicEnv = PickStartsWith<typeof process.env, 'NEXT_PUBLIC_'>;
|
||||
Reference in New Issue
Block a user