mirror of
https://github.com/langgenius/dify.git
synced 2026-07-16 01:48:40 +08:00
410 lines
17 KiB
TypeScript
410 lines
17 KiB
TypeScript
import type { CamelCase, Replace } from 'string-ts'
|
|
import { createEnv } from '@t3-oss/env-nextjs'
|
|
import { concat, kebabCase, length, slice } from 'string-ts'
|
|
import * as z from 'zod'
|
|
import { isClient, isServer } from './utils/client'
|
|
import { ObjectFromEntries, ObjectKeys } from './utils/object'
|
|
|
|
const CLIENT_ENV_PREFIX = 'NEXT_PUBLIC_'
|
|
type ClientSchema = Record<`${typeof CLIENT_ENV_PREFIX}${string}`, z.ZodType>
|
|
|
|
const coercedBoolean = z
|
|
.string()
|
|
.refine((s) => s === 'true' || s === 'false' || s === '0' || s === '1')
|
|
.transform((s) => s === 'true' || s === '1')
|
|
const coercedNumber = z.coerce.number().int().positive()
|
|
|
|
/// Keep keys sorted except grouped feature-specific blocks.
|
|
const clientSchema = {
|
|
/**
|
|
* Default is not allow to embed into iframe to prevent Clickjacking: https://owasp.org/www-community/attacks/Clickjacking
|
|
*/
|
|
NEXT_PUBLIC_ALLOW_EMBED: coercedBoolean.default(false),
|
|
/**
|
|
* Allow inline style attributes in Markdown rendering.
|
|
* Self-hosted opt-in for workflows using styled Jinja2 templates.
|
|
*/
|
|
NEXT_PUBLIC_ALLOW_INLINE_STYLES: coercedBoolean.default(false),
|
|
/**
|
|
* Allow rendering unsafe URLs which have "data:" scheme.
|
|
*/
|
|
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME: coercedBoolean.default(false),
|
|
/**
|
|
* The API key of amplitude
|
|
*/
|
|
NEXT_PUBLIC_AMPLITUDE_API_KEY: z.string().optional(),
|
|
/**
|
|
* The base URL of console application, refers to the Console base URL of WEB service if console domain is
|
|
* different from api or web app domain.
|
|
* example: http://cloud.dify.ai/console/api
|
|
*/
|
|
NEXT_PUBLIC_API_PREFIX: z.string().optional(),
|
|
/**
|
|
* The base path for the application
|
|
*/
|
|
NEXT_PUBLIC_BASE_PATH: z
|
|
.string()
|
|
.regex(/^\/.*[^/]$/)
|
|
.or(z.literal(''))
|
|
.default(''),
|
|
/**
|
|
* number of concurrency
|
|
*/
|
|
NEXT_PUBLIC_BATCH_CONCURRENCY: coercedNumber.default(5),
|
|
/**
|
|
* When the frontend and backend run on different subdomains, set NEXT_PUBLIC_COOKIE_DOMAIN=1.
|
|
*/
|
|
NEXT_PUBLIC_COOKIE_DOMAIN: z.string().optional(),
|
|
/**
|
|
* CSP https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
|
|
*/
|
|
NEXT_PUBLIC_CSP_WHITELIST: z.string().optional(),
|
|
/**
|
|
* For production release, change this to PRODUCTION
|
|
*/
|
|
NEXT_PUBLIC_DEPLOY_ENV: z.enum(['DEVELOPMENT', 'PRODUCTION', 'TESTING']).optional(),
|
|
NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON: coercedBoolean.default(false),
|
|
/**
|
|
* The deployment edition, SELF_HOSTED
|
|
*/
|
|
NEXT_PUBLIC_EDITION: z.enum(['SELF_HOSTED', 'CLOUD']).default('SELF_HOSTED'),
|
|
NEXT_PUBLIC_ENABLE_AGENT_V2: coercedBoolean.default(false),
|
|
/**
|
|
* Enable preview features that are still in development.
|
|
* Currently gates the `/create` and `/refine` slash commands in the
|
|
* "Go to Anything" command palette (Cmd/Ctrl+K).
|
|
*/
|
|
NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW: coercedBoolean.default(true),
|
|
|
|
/**
|
|
* Cloud-only system-features defaults.
|
|
* These values are only used when NEXT_PUBLIC_EDITION=CLOUD (IS_CLOUD_EDITION).
|
|
*/
|
|
NEXT_PUBLIC_ENABLE_MARKETPLACE: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_EMAIL_CODE_LOGIN: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_EMAIL_PASSWORD_LOGIN: coercedBoolean.default(false),
|
|
NEXT_PUBLIC_ENABLE_SOCIAL_OAUTH_LOGIN: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_COLLABORATION_MODE: coercedBoolean.default(false),
|
|
NEXT_PUBLIC_ALLOW_REGISTER: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ALLOW_CREATE_WORKSPACE: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_IS_EMAIL_SETUP: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_CHANGE_EMAIL: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_CREATORS_PLATFORM_FEATURES_ENABLED: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_TRIAL_APP: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_EXPLORE_BANNER: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_LEARN_APP: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_RBAC_ENABLED: coercedBoolean.default(false),
|
|
|
|
/**
|
|
* Enable inline LaTeX rendering with single dollar signs ($...$)
|
|
* Default is false for security reasons to prevent conflicts with regular text
|
|
*/
|
|
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX: coercedBoolean.default(false),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER: coercedBoolean.default(true),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL: coercedBoolean.default(false),
|
|
/**
|
|
* The maximum number of tokens for segmentation
|
|
*/
|
|
NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: coercedNumber.default(4000),
|
|
NEXT_PUBLIC_IS_MARKETPLACE: coercedBoolean.default(false),
|
|
/**
|
|
* Maximum loop count in the workflow
|
|
*/
|
|
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: coercedNumber.default(100),
|
|
NEXT_PUBLIC_MAINTENANCE_NOTICE: z.string().optional(),
|
|
/**
|
|
* The API PREFIX for MARKETPLACE
|
|
*/
|
|
NEXT_PUBLIC_MARKETPLACE_API_PREFIX: z.url().optional(),
|
|
/**
|
|
* The URL for MARKETPLACE
|
|
*/
|
|
NEXT_PUBLIC_MARKETPLACE_URL_PREFIX: z.url().optional(),
|
|
/**
|
|
* The maximum number of iterations for agent setting
|
|
*/
|
|
NEXT_PUBLIC_MAX_ITERATIONS_NUM: coercedNumber.default(99),
|
|
/**
|
|
* Maximum number of Parallelism branches in the workflow
|
|
*/
|
|
NEXT_PUBLIC_MAX_PARALLEL_LIMIT: coercedNumber.default(10),
|
|
/**
|
|
* Maximum number of tools in the agent/workflow
|
|
*/
|
|
NEXT_PUBLIC_MAX_TOOLS_NUM: coercedNumber.default(10),
|
|
/**
|
|
* The maximum number of tree node depth for workflow
|
|
*/
|
|
NEXT_PUBLIC_MAX_TREE_DEPTH: coercedNumber.default(50),
|
|
/**
|
|
* The URL for Web APP, refers to the Web App base URL of WEB service if web app domain is different from
|
|
* console or api domain.
|
|
* example: http://udify.app/api
|
|
*/
|
|
NEXT_PUBLIC_PUBLIC_API_PREFIX: z.string().optional(),
|
|
/**
|
|
* SENTRY
|
|
*/
|
|
NEXT_PUBLIC_SENTRY_DSN: z.string().optional(),
|
|
NEXT_PUBLIC_SITE_ABOUT: z.string().optional(),
|
|
NEXT_PUBLIC_SOCKET_URL: z.string().optional(),
|
|
NEXT_PUBLIC_SUPPORT_EMAIL_ADDRESS: z.email().optional(),
|
|
NEXT_PUBLIC_SUPPORT_MAIL_LOGIN: coercedBoolean.default(false),
|
|
/**
|
|
* The timeout for the text generation in millisecond
|
|
*/
|
|
NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS: coercedNumber.default(60000),
|
|
/**
|
|
* The maximum number of top-k value for RAG.
|
|
*/
|
|
NEXT_PUBLIC_TOP_K_MAX_VALUE: coercedNumber.default(10),
|
|
/**
|
|
* Disable Upload Image as WebApp icon default is false
|
|
*/
|
|
NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON: coercedBoolean.default(false),
|
|
NEXT_PUBLIC_WEB_PREFIX: z.url().optional(),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL: z.string().optional(),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT: z.string().optional(),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN: z.string().optional(),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION: z.string().optional(),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID: z.string().optional(),
|
|
NEXT_PUBLIC_ZENDESK_WIDGET_KEY: z.string().optional(),
|
|
} satisfies ClientSchema
|
|
|
|
export const env = createEnv({
|
|
server: {
|
|
CONSOLE_API_URL: z.string().optional(),
|
|
SERVER_CONSOLE_API_URL: z.string().optional(),
|
|
/**
|
|
* Maximum length of segmentation tokens for indexing
|
|
*/
|
|
INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: coercedNumber.default(4000),
|
|
/**
|
|
* Disable Next.js Telemetry (https://nextjs.org/telemetry)
|
|
*/
|
|
NEXT_TELEMETRY_DISABLED: coercedBoolean.optional(),
|
|
PORT: coercedNumber.default(3000),
|
|
/**
|
|
* The timeout for the text generation in millisecond
|
|
*/
|
|
TEXT_GENERATION_TIMEOUT_MS: coercedNumber.default(60000),
|
|
},
|
|
client: clientSchema,
|
|
experimental__runtimeEnv: {
|
|
NEXT_PUBLIC_ALLOW_EMBED: isServer
|
|
? process.env.NEXT_PUBLIC_ALLOW_EMBED
|
|
: getRuntimeEnvFromBody('allowEmbed'),
|
|
NEXT_PUBLIC_ALLOW_INLINE_STYLES: isServer
|
|
? process.env.NEXT_PUBLIC_ALLOW_INLINE_STYLES
|
|
: getRuntimeEnvFromBody('allowInlineStyles'),
|
|
NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME: isServer
|
|
? process.env.NEXT_PUBLIC_ALLOW_UNSAFE_DATA_SCHEME
|
|
: getRuntimeEnvFromBody('allowUnsafeDataScheme'),
|
|
NEXT_PUBLIC_AMPLITUDE_API_KEY: isServer
|
|
? process.env.NEXT_PUBLIC_AMPLITUDE_API_KEY
|
|
: getRuntimeEnvFromBody('amplitudeApiKey'),
|
|
NEXT_PUBLIC_API_PREFIX: isServer
|
|
? process.env.NEXT_PUBLIC_API_PREFIX
|
|
: getRuntimeEnvFromBody('apiPrefix'),
|
|
NEXT_PUBLIC_BASE_PATH: isServer
|
|
? process.env.NEXT_PUBLIC_BASE_PATH
|
|
: getRuntimeEnvFromBody('basePath'),
|
|
NEXT_PUBLIC_BATCH_CONCURRENCY: isServer
|
|
? process.env.NEXT_PUBLIC_BATCH_CONCURRENCY
|
|
: getRuntimeEnvFromBody('batchConcurrency'),
|
|
NEXT_PUBLIC_COOKIE_DOMAIN: isServer
|
|
? process.env.NEXT_PUBLIC_COOKIE_DOMAIN
|
|
: getRuntimeEnvFromBody('cookieDomain'),
|
|
NEXT_PUBLIC_CSP_WHITELIST: isServer
|
|
? process.env.NEXT_PUBLIC_CSP_WHITELIST
|
|
: getRuntimeEnvFromBody('cspWhitelist'),
|
|
NEXT_PUBLIC_DEPLOY_ENV: isServer
|
|
? process.env.NEXT_PUBLIC_DEPLOY_ENV
|
|
: getRuntimeEnvFromBody('deployEnv'),
|
|
NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON: isServer
|
|
? process.env.NEXT_PUBLIC_DISABLE_UPLOAD_IMAGE_AS_ICON
|
|
: getRuntimeEnvFromBody('disableUploadImageAsIcon'),
|
|
NEXT_PUBLIC_EDITION: isServer
|
|
? process.env.NEXT_PUBLIC_EDITION
|
|
: getRuntimeEnvFromBody('edition'),
|
|
NEXT_PUBLIC_ENABLE_AGENT_V2: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_AGENT_V2
|
|
: getRuntimeEnvFromBody('enableAgentV2'),
|
|
NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_FEATURE_PREVIEW
|
|
: getRuntimeEnvFromBody('enableFeaturePreview'),
|
|
|
|
/**
|
|
* Cloud-only system-features defaults.
|
|
* These values are only used when NEXT_PUBLIC_EDITION=CLOUD (IS_CLOUD_EDITION).
|
|
*/
|
|
NEXT_PUBLIC_ENABLE_MARKETPLACE: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_MARKETPLACE
|
|
: getRuntimeEnvFromBody('enableMarketplace'),
|
|
NEXT_PUBLIC_ENABLE_EMAIL_CODE_LOGIN: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_EMAIL_CODE_LOGIN
|
|
: getRuntimeEnvFromBody('enableEmailCodeLogin'),
|
|
NEXT_PUBLIC_ENABLE_EMAIL_PASSWORD_LOGIN: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_EMAIL_PASSWORD_LOGIN
|
|
: getRuntimeEnvFromBody('enableEmailPasswordLogin'),
|
|
NEXT_PUBLIC_ENABLE_SOCIAL_OAUTH_LOGIN: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_SOCIAL_OAUTH_LOGIN
|
|
: getRuntimeEnvFromBody('enableSocialOauthLogin'),
|
|
NEXT_PUBLIC_ENABLE_COLLABORATION_MODE: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_COLLABORATION_MODE
|
|
: getRuntimeEnvFromBody('enableCollaborationMode'),
|
|
NEXT_PUBLIC_ALLOW_REGISTER: isServer
|
|
? process.env.NEXT_PUBLIC_ALLOW_REGISTER
|
|
: getRuntimeEnvFromBody('allowRegister'),
|
|
NEXT_PUBLIC_ALLOW_CREATE_WORKSPACE: isServer
|
|
? process.env.NEXT_PUBLIC_ALLOW_CREATE_WORKSPACE
|
|
: getRuntimeEnvFromBody('allowCreateWorkspace'),
|
|
NEXT_PUBLIC_IS_EMAIL_SETUP: isServer
|
|
? process.env.NEXT_PUBLIC_IS_EMAIL_SETUP
|
|
: getRuntimeEnvFromBody('isEmailSetup'),
|
|
NEXT_PUBLIC_ENABLE_CHANGE_EMAIL: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_CHANGE_EMAIL
|
|
: getRuntimeEnvFromBody('enableChangeEmail'),
|
|
NEXT_PUBLIC_CREATORS_PLATFORM_FEATURES_ENABLED: isServer
|
|
? process.env.NEXT_PUBLIC_CREATORS_PLATFORM_FEATURES_ENABLED
|
|
: getRuntimeEnvFromBody('creatorsPlatformFeaturesEnabled'),
|
|
NEXT_PUBLIC_ENABLE_TRIAL_APP: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_TRIAL_APP
|
|
: getRuntimeEnvFromBody('enableTrialApp'),
|
|
NEXT_PUBLIC_ENABLE_EXPLORE_BANNER: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_EXPLORE_BANNER
|
|
: getRuntimeEnvFromBody('enableExploreBanner'),
|
|
NEXT_PUBLIC_ENABLE_LEARN_APP: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_LEARN_APP
|
|
: getRuntimeEnvFromBody('enableLearnApp'),
|
|
NEXT_PUBLIC_RBAC_ENABLED: isServer
|
|
? process.env.NEXT_PUBLIC_RBAC_ENABLED
|
|
: getRuntimeEnvFromBody('rbacEnabled'),
|
|
|
|
NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_SINGLE_DOLLAR_LATEX
|
|
: getRuntimeEnvFromBody('enableSingleDollarLatex'),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_WEBSITE_FIRECRAWL
|
|
: getRuntimeEnvFromBody('enableWebsiteFirecrawl'),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_WEBSITE_JINAREADER
|
|
: getRuntimeEnvFromBody('enableWebsiteJinareader'),
|
|
NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL: isServer
|
|
? process.env.NEXT_PUBLIC_ENABLE_WEBSITE_WATERCRAWL
|
|
: getRuntimeEnvFromBody('enableWebsiteWatercrawl'),
|
|
NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH: isServer
|
|
? process.env.NEXT_PUBLIC_INDEXING_MAX_SEGMENTATION_TOKENS_LENGTH
|
|
: getRuntimeEnvFromBody('indexingMaxSegmentationTokensLength'),
|
|
NEXT_PUBLIC_IS_MARKETPLACE: isServer
|
|
? process.env.NEXT_PUBLIC_IS_MARKETPLACE
|
|
: getRuntimeEnvFromBody('isMarketplace'),
|
|
NEXT_PUBLIC_LOOP_NODE_MAX_COUNT: isServer
|
|
? process.env.NEXT_PUBLIC_LOOP_NODE_MAX_COUNT
|
|
: getRuntimeEnvFromBody('loopNodeMaxCount'),
|
|
NEXT_PUBLIC_MAINTENANCE_NOTICE: isServer
|
|
? process.env.NEXT_PUBLIC_MAINTENANCE_NOTICE
|
|
: getRuntimeEnvFromBody('maintenanceNotice'),
|
|
NEXT_PUBLIC_MARKETPLACE_API_PREFIX: isServer
|
|
? process.env.NEXT_PUBLIC_MARKETPLACE_API_PREFIX
|
|
: getRuntimeEnvFromBody('marketplaceApiPrefix'),
|
|
NEXT_PUBLIC_MARKETPLACE_URL_PREFIX: isServer
|
|
? process.env.NEXT_PUBLIC_MARKETPLACE_URL_PREFIX
|
|
: getRuntimeEnvFromBody('marketplaceUrlPrefix'),
|
|
NEXT_PUBLIC_MAX_ITERATIONS_NUM: isServer
|
|
? process.env.NEXT_PUBLIC_MAX_ITERATIONS_NUM
|
|
: getRuntimeEnvFromBody('maxIterationsNum'),
|
|
NEXT_PUBLIC_MAX_PARALLEL_LIMIT: isServer
|
|
? process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT
|
|
: getRuntimeEnvFromBody('maxParallelLimit'),
|
|
NEXT_PUBLIC_MAX_TOOLS_NUM: isServer
|
|
? process.env.NEXT_PUBLIC_MAX_TOOLS_NUM
|
|
: getRuntimeEnvFromBody('maxToolsNum'),
|
|
NEXT_PUBLIC_MAX_TREE_DEPTH: isServer
|
|
? process.env.NEXT_PUBLIC_MAX_TREE_DEPTH
|
|
: getRuntimeEnvFromBody('maxTreeDepth'),
|
|
NEXT_PUBLIC_PUBLIC_API_PREFIX: isServer
|
|
? process.env.NEXT_PUBLIC_PUBLIC_API_PREFIX
|
|
: getRuntimeEnvFromBody('publicApiPrefix'),
|
|
NEXT_PUBLIC_SENTRY_DSN: isServer
|
|
? process.env.NEXT_PUBLIC_SENTRY_DSN
|
|
: getRuntimeEnvFromBody('sentryDsn'),
|
|
NEXT_PUBLIC_SITE_ABOUT: isServer
|
|
? process.env.NEXT_PUBLIC_SITE_ABOUT
|
|
: getRuntimeEnvFromBody('siteAbout'),
|
|
NEXT_PUBLIC_SOCKET_URL: isServer
|
|
? process.env.NEXT_PUBLIC_SOCKET_URL
|
|
: getRuntimeEnvFromBody('socketUrl'),
|
|
NEXT_PUBLIC_SUPPORT_EMAIL_ADDRESS: isServer
|
|
? process.env.NEXT_PUBLIC_SUPPORT_EMAIL_ADDRESS
|
|
: getRuntimeEnvFromBody('supportEmailAddress'),
|
|
NEXT_PUBLIC_SUPPORT_MAIL_LOGIN: isServer
|
|
? process.env.NEXT_PUBLIC_SUPPORT_MAIL_LOGIN
|
|
: getRuntimeEnvFromBody('supportMailLogin'),
|
|
NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS: isServer
|
|
? process.env.NEXT_PUBLIC_TEXT_GENERATION_TIMEOUT_MS
|
|
: getRuntimeEnvFromBody('textGenerationTimeoutMs'),
|
|
NEXT_PUBLIC_TOP_K_MAX_VALUE: isServer
|
|
? process.env.NEXT_PUBLIC_TOP_K_MAX_VALUE
|
|
: getRuntimeEnvFromBody('topKMaxValue'),
|
|
NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON: isServer
|
|
? process.env.NEXT_PUBLIC_UPLOAD_IMAGE_AS_ICON
|
|
: getRuntimeEnvFromBody('uploadImageAsIcon'),
|
|
NEXT_PUBLIC_WEB_PREFIX: isServer
|
|
? process.env.NEXT_PUBLIC_WEB_PREFIX
|
|
: getRuntimeEnvFromBody('webPrefix'),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_EMAIL
|
|
: getRuntimeEnvFromBody('zendeskFieldIdEmail'),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_ENVIRONMENT
|
|
: getRuntimeEnvFromBody('zendeskFieldIdEnvironment'),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_PLAN
|
|
: getRuntimeEnvFromBody('zendeskFieldIdPlan'),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_VERSION
|
|
: getRuntimeEnvFromBody('zendeskFieldIdVersion'),
|
|
NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_FIELD_ID_WORKSPACE_ID
|
|
: getRuntimeEnvFromBody('zendeskFieldIdWorkspaceId'),
|
|
NEXT_PUBLIC_ZENDESK_WIDGET_KEY: isServer
|
|
? process.env.NEXT_PUBLIC_ZENDESK_WIDGET_KEY
|
|
: getRuntimeEnvFromBody('zendeskWidgetKey'),
|
|
},
|
|
emptyStringAsUndefined: true,
|
|
})
|
|
|
|
type ClientEnvKey = keyof typeof clientSchema
|
|
type DatasetKey = CamelCase<Replace<ClientEnvKey, typeof CLIENT_ENV_PREFIX>>
|
|
|
|
function getDatasetAttributeName(envKey: ClientEnvKey) {
|
|
const datasetName = kebabCase(slice(envKey, length(CLIENT_ENV_PREFIX))).replace(/-(\d)/g, '$1')
|
|
return concat('data-', datasetName)
|
|
}
|
|
|
|
/**
|
|
* Browser-only function to get runtime env value from HTML body dataset.
|
|
*/
|
|
function getRuntimeEnvFromBody(key: DatasetKey) {
|
|
if (typeof window === 'undefined') {
|
|
throw new TypeError('getRuntimeEnvFromBody can only be called in the browser')
|
|
}
|
|
|
|
const value = document.body.dataset[key]
|
|
return value || undefined
|
|
}
|
|
|
|
/**
|
|
* Server-only function to get dataset map for embedding into the HTML body.
|
|
*/
|
|
export function getDatasetMap() {
|
|
if (isClient) {
|
|
throw new TypeError('getDatasetMap can only be called on the server')
|
|
}
|
|
return ObjectFromEntries(
|
|
ObjectKeys(clientSchema).map((envKey) => [getDatasetAttributeName(envKey), env[envKey]]),
|
|
)
|
|
}
|