ras-stack 1.1.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/config/oxlint/domain.json +29 -0
- package/config/oxlint/layers.json +116 -0
- package/dist/auth/providers.js +1 -1
- package/dist/auth/providers.js.map +1 -1
- package/dist/email/index.d.ts +11 -0
- package/dist/email/index.js +16 -0
- package/dist/email/index.js.map +1 -1
- package/dist/policy/changesets.d.ts +1 -0
- package/dist/policy/changesets.js +37 -0
- package/dist/policy/changesets.js.map +1 -0
- package/dist/policy/cli.js +2 -1
- package/dist/policy/cli.js.map +1 -1
- package/dist/policy/index.js +5 -2
- package/dist/policy/index.js.map +1 -1
- package/dist/posthog/proxy.d.ts +1 -1
- package/dist/posthog/proxy.js +11 -5
- package/dist/posthog/proxy.js.map +1 -1
- package/dist/posthog/server.d.ts +6 -1
- package/dist/posthog/server.js +31 -0
- package/dist/posthog/server.js.map +1 -1
- package/dist/preview/dokploy.d.ts +1 -0
- package/dist/preview/dokploy.js +17 -0
- package/dist/preview/dokploy.js.map +1 -1
- package/dist/realtime/environment.d.ts +10 -0
- package/dist/realtime/environment.js +27 -0
- package/dist/realtime/environment.js.map +1 -0
- package/dist/realtime/index.d.ts +2 -0
- package/dist/realtime/index.js +1 -0
- package/dist/realtime/index.js.map +1 -1
- package/dist/realtime/publisher.d.ts +3 -1
- package/dist/realtime/publisher.js +19 -2
- package/dist/realtime/publisher.js.map +1 -1
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.js +15 -0
- package/dist/runtime/index.js.map +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/rpc.d.ts +2 -0
- package/dist/server/rpc.js +19 -14
- package/dist/server/rpc.js.map +1 -1
- package/dist/uploads/index.d.ts +7 -2
- package/dist/uploads/index.js +64 -33
- package/dist/uploads/index.js.map +1 -1
- package/package.json +6 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/posthog/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { CaptureMetricOptions, PostHog, PostHogOptions, Span, StartSpanOptions } from 'posthog-node'\nimport type { RpcErrorContext, RpcLogger } from '../server/rpc.js'\nimport type { PostHogEnvironment } from './config.js'\nimport { postHogRequestContext, type PostHogRequestContextOptions } from './request.js'\n\ntype LogProvider = InstanceType<(typeof import('@opentelemetry/sdk-logs'))['LoggerProvider']>\n\nexport type PostHogLogValue = string | number | boolean | null | PostHogLogValue[]\n\nexport type PostHogLogRecord = {\n body: string\n severityText?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'\n timestamp?: number\n attributes?: Record<string, unknown>\n}\n\nexport type ManagedPostHogServerTelemetryOptions = {\n environment: PostHogEnvironment | undefined\n serviceName: string\n serviceVersion?: string\n deploymentEnvironment?: string\n resourceAttributes?: Record<string, string>\n clientOptions?: Omit<PostHogOptions, 'host'>\n onError?: (error: unknown) => void\n}\n\nexport type PostHogServerTelemetry = ReturnType<typeof createManagedPostHogServerTelemetry>\n\nexport type PostHogTelemetryContext = {\n distinctId?: string\n sessionId?: string\n properties?: Record<string, unknown>\n}\n\nexport type PostHogTraceSpan = Span | undefined\n\nexport type PostHogRpcLoggerOptions = {\n logError?: (error: unknown, context: RpcErrorContext) => void\n resolveAuthenticatedDistinctId?: (request: Request) => string | undefined | Promise<string | undefined>\n allowAnonymousDistinctId?: boolean\n fallbackDistinctId?: string\n}\n\ntype PostHogShutdownProcess = {\n pid: number\n on(signal: 'SIGINT' | 'SIGTERM', listener: () => void): void\n off(signal: 'SIGINT' | 'SIGTERM', listener: () => void): void\n kill(pid: number, signal: 'SIGINT' | 'SIGTERM'): void\n}\n\nexport async function createPostHogServerClient(\n environment: PostHogEnvironment | undefined,\n options: Omit<PostHogOptions, 'host'> = {},\n): Promise<PostHog | undefined> {\n if (!environment) return undefined\n const { PostHog } = await import('posthog-node')\n return new PostHog(environment.projectToken, {\n host: environment.host,\n enableExceptionAutocapture: true,\n ...options,\n })\n}\n\nexport async function shutdownPostHogServerClient(client: PostHog | undefined, timeoutMs = 10_000) {\n assertShutdownTimeout(timeoutMs)\n // oxlint-disable-next-line no-underscore-dangle -- posthog-node's async shutdown API is named `_shutdown`.\n await client?._shutdown(timeoutMs)\n}\n\nexport function createManagedPostHogServerTelemetry(options: ManagedPostHogServerTelemetryOptions) {\n let client: Promise<PostHog | undefined> | undefined\n let logProvider: Promise<LogProvider | undefined> | undefined\n let closed = false\n const context = new AsyncLocalStorage<PostHogTelemetryContext>()\n\n const report = (error: unknown) => {\n try {\n options.onError?.(error)\n } catch {}\n }\n\n const getClient = () => {\n if (closed || !options.environment) return undefined\n if (!client) {\n const pending = createPostHogServerClient(options.environment, managedClientOptions(options))\n client = pending\n void pending.catch(() => {\n if (client === pending) client = undefined\n })\n }\n return client\n }\n\n const getLogProvider = () => {\n if (closed || !options.environment) return undefined\n if (!logProvider) {\n const pending = createPostHogLogProvider(options)\n logProvider = pending\n void pending.catch(() => {\n if (logProvider === pending) logProvider = undefined\n })\n }\n return logProvider\n }\n\n const safely = async (work: () => void | Promise<void>) => {\n if (closed || !options.environment) return\n try {\n await work()\n } catch (error) {\n report(error)\n }\n }\n\n const loadClient = async () => {\n try {\n return await getClient()\n } catch (error) {\n report(error)\n return undefined\n }\n }\n\n async function withContext<T>(telemetryContext: PostHogTelemetryContext, work: () => T): Promise<Awaited<T>> {\n const inherited = context.getStore()\n const correlation = {\n ...(inherited?.distinctId ? { distinctId: inherited.distinctId } : {}),\n ...(inherited?.sessionId ? { sessionId: inherited.sessionId } : {}),\n ...telemetryContext,\n }\n const requestContext: PostHogTelemetryContext = {\n ...(correlation.distinctId ? { distinctId: correlation.distinctId } : {}),\n ...(correlation.sessionId ? { sessionId: correlation.sessionId } : {}),\n properties: {\n ...inherited?.properties,\n ...telemetryContext.properties,\n ...(correlation.sessionId ? { $session_id: correlation.sessionId } : {}),\n },\n }\n const run = () => context.run(requestContext, work)\n const value = await loadClient()\n return (value ? value.withContext(telemetryContext, run) : run()) as Awaited<T>\n }\n\n async function withRequestContext<T>(request: Request, requestOptions: PostHogRequestContextOptions, work: () => T): Promise<Awaited<T>> {\n const correlation = postHogRequestContext(request, requestOptions)\n return withContext(\n {\n ...(correlation.distinctId ? { distinctId: correlation.distinctId } : {}),\n ...(correlation.sessionId ? { sessionId: correlation.sessionId } : {}),\n },\n work,\n )\n }\n\n async function withSpan<T>(name: string, work: (span: PostHogTraceSpan) => T): Promise<Awaited<T>>\n async function withSpan<T>(name: string, spanOptions: StartSpanOptions, work: (span: PostHogTraceSpan) => T): Promise<Awaited<T>>\n async function withSpan<T>(\n name: string,\n optionsOrWork: StartSpanOptions | ((span: PostHogTraceSpan) => T),\n maybeWork?: (span: PostHogTraceSpan) => T,\n ): Promise<Awaited<T>> {\n const spanOptions = typeof optionsOrWork === 'function' ? undefined : optionsOrWork\n const work = typeof optionsOrWork === 'function' ? optionsOrWork : maybeWork!\n const value = await loadClient()\n if (!value) return work(undefined) as Awaited<T>\n return (spanOptions ? value.withSpan(name, spanOptions, work) : value.withSpan(name, work)) as Awaited<T>\n }\n\n const metrics = {\n count(name: string, value = 1, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.count(name, value, metricOptions))\n },\n gauge(name: string, value: number, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.gauge(name, value, metricOptions))\n },\n histogram(name: string, value: number, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.histogram(name, value, metricOptions))\n },\n }\n\n return {\n metrics,\n async start() {\n await safely(async () => {\n await Promise.all([getClient(), getLogProvider()])\n })\n },\n async capture(distinctId: string, event: string, properties?: Record<string, unknown>) {\n await safely(async () => {\n const value = await getClient()\n value?.capture({ distinctId, event, ...(properties ? { properties } : {}) })\n })\n },\n async exception(error: unknown, distinctId?: string, properties?: Record<string, unknown>) {\n await safely(async () => {\n const value = await getClient()\n const correlation = context.getStore()\n const capturedProperties = mergeProperties(properties, correlation?.properties)\n value?.captureException(error, distinctId ?? correlation?.distinctId ?? 'server', capturedProperties)\n })\n },\n async log(record: PostHogLogRecord) {\n await safely(async () => {\n const provider = await getLogProvider()\n const correlation = context.getStore()\n const attributes = boundedAttributes(\n mergeProperties(record.attributes, {\n ...(correlation?.distinctId ? { posthogDistinctId: correlation.distinctId } : {}),\n ...(correlation?.sessionId ? { sessionId: correlation.sessionId } : {}),\n }),\n )\n provider?.getLogger(options.serviceName).emit({\n body: boundedString(record.body),\n ...(record.severityText ? { severityText: record.severityText } : {}),\n ...(record.timestamp === undefined ? {} : { timestamp: record.timestamp }),\n ...(attributes ? { attributes } : {}),\n })\n })\n },\n async flush() {\n await safely(async () => {\n const [value, provider] = await Promise.all([getClient(), getLogProvider()])\n await Promise.all([value?.flush(), provider?.forceFlush()])\n })\n },\n async startSpan(name: string, spanOptions?: StartSpanOptions) {\n return (await loadClient())?.startSpan(name, spanOptions)\n },\n withContext,\n withRequestContext,\n withSpan,\n async shutdown(timeoutMs = 10_000) {\n if (closed) return\n assertShutdownTimeout(timeoutMs)\n closed = true\n const results = await Promise.allSettled([\n client?.then((value) => shutdownPostHogServerClient(value, timeoutMs)),\n logProvider?.then((value) => shutdownPostHogLogProvider(value, timeoutMs)),\n ])\n for (const result of results) if (result.status === 'rejected') report(result.reason)\n },\n }\n}\n\nfunction managedClientOptions(options: ManagedPostHogServerTelemetryOptions): Omit<PostHogOptions, 'host'> {\n const { metrics, traces, ...clientOptions } = options.clientOptions ?? {}\n const service = {\n serviceName: options.serviceName,\n ...(options.serviceVersion ? { serviceVersion: options.serviceVersion } : {}),\n ...(options.deploymentEnvironment ? { environment: options.deploymentEnvironment } : {}),\n ...(options.resourceAttributes ? { resourceAttributes: options.resourceAttributes } : {}),\n }\n return {\n ...clientOptions,\n metrics: { ...service, ...metrics },\n traces: { ...service, ...traces },\n }\n}\n\nexport function createPostHogRpcLogger(telemetry: PostHogServerTelemetry, options: PostHogRpcLoggerOptions = {}): RpcLogger {\n return async (error, context, request) => {\n try {\n options.logError?.(error, context)\n } catch {}\n let authenticatedDistinctId: string | undefined\n if (request && options.resolveAuthenticatedDistinctId) {\n try {\n authenticatedDistinctId = await options.resolveAuthenticatedDistinctId(request)\n } catch {}\n }\n const correlation = request\n ? postHogRequestContext(request, {\n ...(authenticatedDistinctId ? { authenticatedDistinctId } : {}),\n ...(options.allowAnonymousDistinctId === undefined ? {} : { allowAnonymousDistinctId: options.allowAnonymousDistinctId }),\n })\n : { properties: {} }\n const distinctId = correlation.distinctId ?? options.fallbackDistinctId ?? 'server'\n const properties = {\n ...correlation.properties,\n ...(context.method ? { request_method: context.method } : {}),\n ...(context.path ? { request_path: context.path } : {}),\n }\n await Promise.all([\n telemetry.exception(error, distinctId, properties),\n telemetry.log({\n body: 'server function failed',\n severityText: 'error',\n attributes: { ...properties, posthogDistinctId: distinctId },\n }),\n ])\n }\n}\n\nexport function installPostHogServerTelemetryShutdown(\n telemetry: Pick<PostHogServerTelemetry, 'shutdown'>,\n target: PostHogShutdownProcess = process,\n) {\n let shuttingDown = false\n const listeners = new Map<'SIGINT' | 'SIGTERM', () => void>()\n const remove = () => {\n for (const [signal, listener] of listeners) target.off(signal, listener)\n listeners.clear()\n }\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n const listener = () => {\n if (shuttingDown) return\n shuttingDown = true\n void telemetry\n .shutdown()\n .catch(() => undefined)\n .finally(() => {\n remove()\n target.kill(target.pid, signal)\n })\n }\n listeners.set(signal, listener)\n target.on(signal, listener)\n }\n return remove\n}\n\nasync function createPostHogLogProvider(options: ManagedPostHogServerTelemetryOptions): Promise<LogProvider | undefined> {\n if (!options.environment) return undefined\n const [{ OTLPLogExporter }, { resourceFromAttributes }, { BatchLogRecordProcessor, LoggerProvider }] = await Promise.all([\n import('@opentelemetry/exporter-logs-otlp-http'),\n import('@opentelemetry/resources'),\n import('@opentelemetry/sdk-logs'),\n ])\n const exporter = new OTLPLogExporter({\n url: `${options.environment.host.replace(/\\/$/, '')}/i/v1/logs`,\n headers: { Authorization: `Bearer ${options.environment.projectToken}` },\n })\n return new LoggerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.serviceName,\n ...(options.serviceVersion ? { 'service.version': options.serviceVersion } : {}),\n ...(options.deploymentEnvironment ? { 'deployment.environment': options.deploymentEnvironment } : {}),\n ...options.resourceAttributes,\n }),\n processors: [new BatchLogRecordProcessor({ exporter })],\n })\n}\n\nfunction mergeProperties(...values: Array<Record<string, unknown> | undefined>) {\n const merged = Object.assign({}, ...values.filter(Boolean))\n return Object.keys(merged).length ? merged : undefined\n}\n\nfunction boundedAttributes(attributes: Record<string, unknown> | undefined) {\n if (!attributes) return undefined\n return Object.fromEntries(\n Object.entries(attributes)\n .slice(0, 64)\n .map(([key, value]) => [key.slice(0, 128), boundedLogValue(value, 0)])\n .filter((entry): entry is [string, PostHogLogValue] => entry[1] !== undefined),\n )\n}\n\nfunction boundedLogValue(value: unknown, depth: number): PostHogLogValue | undefined {\n if (value === null || typeof value === 'number' || typeof value === 'boolean') return value\n if (typeof value === 'string') return boundedString(value)\n if (depth >= 3) return '[Truncated]'\n if (Array.isArray(value)) {\n return value\n .slice(0, 32)\n .map((entry) => boundedLogValue(entry, depth + 1))\n .filter((entry): entry is PostHogLogValue => entry !== undefined)\n }\n if (value === undefined) return undefined\n try {\n return boundedString(JSON.stringify(value))\n } catch {\n return '[Unserializable value]'\n }\n}\n\nfunction boundedString(value: string) {\n return value.slice(0, 2_048)\n}\n\nasync function shutdownPostHogLogProvider(provider: LogProvider | undefined, timeoutMs: number) {\n if (!provider) return\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n provider.shutdown(),\n new Promise<never>((_resolve, reject) => {\n timeout = setTimeout(() => reject(new Error(`PostHog log shutdown timed out after ${timeoutMs}ms`)), timeoutMs)\n timeout.unref?.()\n }),\n ])\n } finally {\n if (timeout) clearTimeout(timeout)\n }\n}\n\nfunction assertShutdownTimeout(timeoutMs: number) {\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 0) throw new Error('timeoutMs must be a non-negative integer')\n}\n"]}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/posthog/server.ts"],"names":[],"mappings":"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","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { CaptureMetricOptions, PostHog, PostHogOptions, Span, StartSpanOptions } from 'posthog-node'\nimport type { RpcErrorContext, RpcLogger, RpcObserver } from '../server/rpc.js'\nimport type { PostHogEnvironment } from './config.js'\nimport { postHogRequestContext, type PostHogRequestContextOptions } from './request.js'\n\ntype LogProvider = InstanceType<(typeof import('@opentelemetry/sdk-logs'))['LoggerProvider']>\n\nexport type PostHogLogValue = string | number | boolean | null | PostHogLogValue[]\n\nexport type PostHogLogRecord = {\n body: string\n severityText?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal'\n timestamp?: number\n attributes?: Record<string, unknown>\n}\n\nexport type ManagedPostHogServerTelemetryOptions = {\n environment: PostHogEnvironment | undefined\n serviceName: string\n serviceVersion?: string\n deploymentEnvironment?: string\n resourceAttributes?: Record<string, string>\n clientOptions?: Omit<PostHogOptions, 'host'>\n onError?: (error: unknown) => void\n}\n\nexport type PostHogServerTelemetry = ReturnType<typeof createManagedPostHogServerTelemetry>\n\nexport type PostHogTelemetryContext = {\n distinctId?: string\n sessionId?: string\n properties?: Record<string, unknown>\n}\n\nexport type PostHogTraceSpan = Span | undefined\n\nexport type PostHogRpcLoggerOptions = {\n logError?: (error: unknown, context: RpcErrorContext) => void\n resolveAuthenticatedDistinctId?: (request: Request) => string | undefined | Promise<string | undefined>\n allowAnonymousDistinctId?: boolean\n fallbackDistinctId?: string\n}\n\nexport type PostHogRpcObserverOptions = {\n metricPrefix?: string\n spanName?: string\n}\n\ntype PostHogShutdownProcess = {\n pid: number\n on(signal: 'SIGINT' | 'SIGTERM', listener: () => void): void\n off(signal: 'SIGINT' | 'SIGTERM', listener: () => void): void\n kill(pid: number, signal: 'SIGINT' | 'SIGTERM'): void\n}\n\nexport async function createPostHogServerClient(\n environment: PostHogEnvironment | undefined,\n options: Omit<PostHogOptions, 'host'> = {},\n): Promise<PostHog | undefined> {\n if (!environment) return undefined\n const { PostHog } = await import('posthog-node')\n return new PostHog(environment.projectToken, {\n host: environment.host,\n enableExceptionAutocapture: true,\n ...options,\n })\n}\n\nexport async function shutdownPostHogServerClient(client: PostHog | undefined, timeoutMs = 10_000) {\n assertShutdownTimeout(timeoutMs)\n // oxlint-disable-next-line no-underscore-dangle -- posthog-node's async shutdown API is named `_shutdown`.\n await client?._shutdown(timeoutMs)\n}\n\nexport function createManagedPostHogServerTelemetry(options: ManagedPostHogServerTelemetryOptions) {\n let client: Promise<PostHog | undefined> | undefined\n let logProvider: Promise<LogProvider | undefined> | undefined\n let closed = false\n const context = new AsyncLocalStorage<PostHogTelemetryContext>()\n\n const report = (error: unknown) => {\n try {\n options.onError?.(error)\n } catch {}\n }\n\n const getClient = () => {\n if (closed || !options.environment) return undefined\n if (!client) {\n const pending = createPostHogServerClient(options.environment, managedClientOptions(options))\n client = pending\n void pending.catch(() => {\n if (client === pending) client = undefined\n })\n }\n return client\n }\n\n const getLogProvider = () => {\n if (closed || !options.environment) return undefined\n if (!logProvider) {\n const pending = createPostHogLogProvider(options)\n logProvider = pending\n void pending.catch(() => {\n if (logProvider === pending) logProvider = undefined\n })\n }\n return logProvider\n }\n\n const safely = async (work: () => void | Promise<void>) => {\n if (closed || !options.environment) return\n try {\n await work()\n } catch (error) {\n report(error)\n }\n }\n\n const loadClient = async () => {\n try {\n return await getClient()\n } catch (error) {\n report(error)\n return undefined\n }\n }\n\n async function withContext<T>(telemetryContext: PostHogTelemetryContext, work: () => T): Promise<Awaited<T>> {\n const inherited = context.getStore()\n const correlation = {\n ...(inherited?.distinctId ? { distinctId: inherited.distinctId } : {}),\n ...(inherited?.sessionId ? { sessionId: inherited.sessionId } : {}),\n ...telemetryContext,\n }\n const requestContext: PostHogTelemetryContext = {\n ...(correlation.distinctId ? { distinctId: correlation.distinctId } : {}),\n ...(correlation.sessionId ? { sessionId: correlation.sessionId } : {}),\n properties: {\n ...inherited?.properties,\n ...telemetryContext.properties,\n ...(correlation.sessionId ? { $session_id: correlation.sessionId } : {}),\n },\n }\n const run = () => context.run(requestContext, work)\n const value = await loadClient()\n return (value ? value.withContext(telemetryContext, run) : run()) as Awaited<T>\n }\n\n async function withRequestContext<T>(request: Request, requestOptions: PostHogRequestContextOptions, work: () => T): Promise<Awaited<T>> {\n const correlation = postHogRequestContext(request, requestOptions)\n return withContext(\n {\n ...(correlation.distinctId ? { distinctId: correlation.distinctId } : {}),\n ...(correlation.sessionId ? { sessionId: correlation.sessionId } : {}),\n },\n work,\n )\n }\n\n async function withSpan<T>(name: string, work: (span: PostHogTraceSpan) => T): Promise<Awaited<T>>\n async function withSpan<T>(name: string, spanOptions: StartSpanOptions, work: (span: PostHogTraceSpan) => T): Promise<Awaited<T>>\n async function withSpan<T>(\n name: string,\n optionsOrWork: StartSpanOptions | ((span: PostHogTraceSpan) => T),\n maybeWork?: (span: PostHogTraceSpan) => T,\n ): Promise<Awaited<T>> {\n const spanOptions = typeof optionsOrWork === 'function' ? undefined : optionsOrWork\n const work = typeof optionsOrWork === 'function' ? optionsOrWork : maybeWork!\n const value = await loadClient()\n if (!value) return work(undefined) as Awaited<T>\n return (spanOptions ? value.withSpan(name, spanOptions, work) : value.withSpan(name, work)) as Awaited<T>\n }\n\n const metrics = {\n count(name: string, value = 1, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.count(name, value, metricOptions))\n },\n gauge(name: string, value: number, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.gauge(name, value, metricOptions))\n },\n histogram(name: string, value: number, metricOptions?: CaptureMetricOptions) {\n return safely(async () => (await getClient())?.metrics.histogram(name, value, metricOptions))\n },\n }\n\n return {\n metrics,\n async start() {\n await safely(async () => {\n await Promise.all([getClient(), getLogProvider()])\n })\n },\n async capture(distinctId: string, event: string, properties?: Record<string, unknown>) {\n await safely(async () => {\n const value = await getClient()\n value?.capture({ distinctId, event, ...(properties ? { properties } : {}) })\n })\n },\n async exception(error: unknown, distinctId?: string, properties?: Record<string, unknown>) {\n await safely(async () => {\n const value = await getClient()\n const correlation = context.getStore()\n const capturedProperties = mergeProperties(properties, correlation?.properties)\n value?.captureException(error, distinctId ?? correlation?.distinctId ?? 'server', capturedProperties)\n })\n },\n async log(record: PostHogLogRecord) {\n await safely(async () => {\n const provider = await getLogProvider()\n const correlation = context.getStore()\n const attributes = boundedAttributes(\n mergeProperties(record.attributes, {\n ...(correlation?.distinctId ? { posthogDistinctId: correlation.distinctId } : {}),\n ...(correlation?.sessionId ? { sessionId: correlation.sessionId } : {}),\n }),\n )\n provider?.getLogger(options.serviceName).emit({\n body: boundedString(record.body),\n ...(record.severityText ? { severityText: record.severityText } : {}),\n ...(record.timestamp === undefined ? {} : { timestamp: record.timestamp }),\n ...(attributes ? { attributes } : {}),\n })\n })\n },\n async flush() {\n await safely(async () => {\n const [value, provider] = await Promise.all([getClient(), getLogProvider()])\n await Promise.all([value?.flush(), provider?.forceFlush()])\n })\n },\n async startSpan(name: string, spanOptions?: StartSpanOptions) {\n return (await loadClient())?.startSpan(name, spanOptions)\n },\n withContext,\n withRequestContext,\n withSpan,\n async shutdown(timeoutMs = 10_000) {\n if (closed) return\n assertShutdownTimeout(timeoutMs)\n closed = true\n const results = await Promise.allSettled([\n client?.then((value) => shutdownPostHogServerClient(value, timeoutMs)),\n logProvider?.then((value) => shutdownPostHogLogProvider(value, timeoutMs)),\n ])\n for (const result of results) if (result.status === 'rejected') report(result.reason)\n },\n }\n}\n\nfunction managedClientOptions(options: ManagedPostHogServerTelemetryOptions): Omit<PostHogOptions, 'host'> {\n const { metrics, traces, ...clientOptions } = options.clientOptions ?? {}\n const service = {\n serviceName: options.serviceName,\n ...(options.serviceVersion ? { serviceVersion: options.serviceVersion } : {}),\n ...(options.deploymentEnvironment ? { environment: options.deploymentEnvironment } : {}),\n ...(options.resourceAttributes ? { resourceAttributes: options.resourceAttributes } : {}),\n }\n return {\n ...clientOptions,\n metrics: { ...service, ...metrics },\n traces: { ...service, ...traces },\n }\n}\n\nexport function createPostHogRpcLogger(telemetry: PostHogServerTelemetry, options: PostHogRpcLoggerOptions = {}): RpcLogger {\n return async (error, context, request) => {\n try {\n options.logError?.(error, context)\n } catch {}\n let authenticatedDistinctId: string | undefined\n if (request && options.resolveAuthenticatedDistinctId) {\n try {\n authenticatedDistinctId = await options.resolveAuthenticatedDistinctId(request)\n } catch {}\n }\n const correlation = request\n ? postHogRequestContext(request, {\n ...(authenticatedDistinctId ? { authenticatedDistinctId } : {}),\n ...(options.allowAnonymousDistinctId === undefined ? {} : { allowAnonymousDistinctId: options.allowAnonymousDistinctId }),\n })\n : { properties: {} }\n const distinctId = correlation.distinctId ?? options.fallbackDistinctId ?? 'server'\n const properties = {\n ...correlation.properties,\n ...(context.method ? { request_method: context.method } : {}),\n ...(context.path ? { request_path: context.path } : {}),\n }\n await Promise.all([\n telemetry.exception(error, distinctId, properties),\n telemetry.log({\n body: 'server function failed',\n severityText: 'error',\n attributes: { ...properties, posthogDistinctId: distinctId },\n }),\n ])\n }\n}\n\nexport function createPostHogRpcObserver(\n telemetry: Pick<PostHogServerTelemetry, 'metrics' | 'withRequestContext' | 'withSpan'>,\n options: PostHogRpcObserverOptions = {},\n): RpcObserver {\n const metricPrefix = options.metricPrefix ?? 'server_function'\n const spanName = options.spanName ?? 'server_function'\n return async function observe<T>(request: Request | undefined, work: () => Promise<T>) {\n if (!request) return work()\n const method = request.method.toUpperCase()\n const attributes = { method }\n const parent = request.headers.get('traceparent')\n return telemetry.withRequestContext(request, {}, () =>\n telemetry.withSpan(spanName, { kind: 'server', ...(parent ? { parent } : {}) }, async (span) => {\n const startedAt = performance.now()\n span?.setAttribute('http.request.method', method)\n let outcome = 'error'\n try {\n const result = await work()\n outcome = 'success'\n return result\n } finally {\n span?.setAttribute('server.function.outcome', outcome)\n await Promise.all([\n telemetry.metrics.count(`${metricPrefix}.requests`, 1, { attributes: { ...attributes, outcome } }),\n telemetry.metrics.histogram(`${metricPrefix}.duration`, Math.max(0, performance.now() - startedAt), {\n unit: 'ms',\n attributes,\n }),\n ])\n }\n }),\n )\n }\n}\n\nexport function installPostHogServerTelemetryShutdown(\n telemetry: Pick<PostHogServerTelemetry, 'shutdown'>,\n target: PostHogShutdownProcess = process,\n) {\n let shuttingDown = false\n const listeners = new Map<'SIGINT' | 'SIGTERM', () => void>()\n const remove = () => {\n for (const [signal, listener] of listeners) target.off(signal, listener)\n listeners.clear()\n }\n for (const signal of ['SIGINT', 'SIGTERM'] as const) {\n const listener = () => {\n if (shuttingDown) return\n shuttingDown = true\n void telemetry\n .shutdown()\n .catch(() => undefined)\n .finally(() => {\n remove()\n target.kill(target.pid, signal)\n })\n }\n listeners.set(signal, listener)\n target.on(signal, listener)\n }\n return remove\n}\n\nasync function createPostHogLogProvider(options: ManagedPostHogServerTelemetryOptions): Promise<LogProvider | undefined> {\n if (!options.environment) return undefined\n const [{ OTLPLogExporter }, { resourceFromAttributes }, { BatchLogRecordProcessor, LoggerProvider }] = await Promise.all([\n import('@opentelemetry/exporter-logs-otlp-http'),\n import('@opentelemetry/resources'),\n import('@opentelemetry/sdk-logs'),\n ])\n const exporter = new OTLPLogExporter({\n url: `${options.environment.host.replace(/\\/$/, '')}/i/v1/logs`,\n headers: { Authorization: `Bearer ${options.environment.projectToken}` },\n })\n return new LoggerProvider({\n resource: resourceFromAttributes({\n 'service.name': options.serviceName,\n ...(options.serviceVersion ? { 'service.version': options.serviceVersion } : {}),\n ...(options.deploymentEnvironment ? { 'deployment.environment': options.deploymentEnvironment } : {}),\n ...options.resourceAttributes,\n }),\n processors: [new BatchLogRecordProcessor({ exporter })],\n })\n}\n\nfunction mergeProperties(...values: Array<Record<string, unknown> | undefined>) {\n const merged = Object.assign({}, ...values.filter(Boolean))\n return Object.keys(merged).length ? merged : undefined\n}\n\nfunction boundedAttributes(attributes: Record<string, unknown> | undefined) {\n if (!attributes) return undefined\n return Object.fromEntries(\n Object.entries(attributes)\n .slice(0, 64)\n .map(([key, value]) => [key.slice(0, 128), boundedLogValue(value, 0)])\n .filter((entry): entry is [string, PostHogLogValue] => entry[1] !== undefined),\n )\n}\n\nfunction boundedLogValue(value: unknown, depth: number): PostHogLogValue | undefined {\n if (value === null || typeof value === 'number' || typeof value === 'boolean') return value\n if (typeof value === 'string') return boundedString(value)\n if (depth >= 3) return '[Truncated]'\n if (Array.isArray(value)) {\n return value\n .slice(0, 32)\n .map((entry) => boundedLogValue(entry, depth + 1))\n .filter((entry): entry is PostHogLogValue => entry !== undefined)\n }\n if (value === undefined) return undefined\n try {\n return boundedString(JSON.stringify(value))\n } catch {\n return '[Unserializable value]'\n }\n}\n\nfunction boundedString(value: string) {\n return value.slice(0, 2_048)\n}\n\nasync function shutdownPostHogLogProvider(provider: LogProvider | undefined, timeoutMs: number) {\n if (!provider) return\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n provider.shutdown(),\n new Promise<never>((_resolve, reject) => {\n timeout = setTimeout(() => reject(new Error(`PostHog log shutdown timed out after ${timeoutMs}ms`)), timeoutMs)\n timeout.unref?.()\n }),\n ])\n } finally {\n if (timeout) clearTimeout(timeout)\n }\n}\n\nfunction assertShutdownTimeout(timeoutMs: number) {\n if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 0) throw new Error('timeoutMs must be a non-negative integer')\n}\n"]}
|
|
@@ -99,3 +99,4 @@ export declare class DokployPreviewManager {
|
|
|
99
99
|
}
|
|
100
100
|
export declare function pullRequestNumber(value: string): string;
|
|
101
101
|
export declare function previewHostname(value: string): string;
|
|
102
|
+
export declare function loadPreviewAppSecrets(allowed: Iterable<string>, source?: NodeJS.ProcessEnv, target?: NodeJS.ProcessEnv): void;
|
package/dist/preview/dokploy.js
CHANGED
|
@@ -357,4 +357,21 @@ function requiredEnvironment(environment, name) {
|
|
|
357
357
|
function optionalEnvironment(environment, name) {
|
|
358
358
|
return environment[name]?.trim() || undefined;
|
|
359
359
|
}
|
|
360
|
+
// Deploy scripts receive product secrets as one JSON object; an unknown key is a mistake, not a passthrough.
|
|
361
|
+
export function loadPreviewAppSecrets(allowed, source = process.env, target = process.env) {
|
|
362
|
+
const serialized = source.PREVIEW_APP_SECRETS?.trim();
|
|
363
|
+
if (!serialized)
|
|
364
|
+
return;
|
|
365
|
+
const parsed = JSON.parse(serialized);
|
|
366
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
367
|
+
throw new Error('PREVIEW_APP_SECRETS must be a JSON object');
|
|
368
|
+
const names = new Set(allowed);
|
|
369
|
+
for (const [name, value] of Object.entries(parsed)) {
|
|
370
|
+
if (!names.has(name))
|
|
371
|
+
throw new Error(`PREVIEW_APP_SECRETS contains unsupported key ${name}`);
|
|
372
|
+
if (typeof value !== 'string')
|
|
373
|
+
throw new Error(`PREVIEW_APP_SECRETS.${name} must be a string`);
|
|
374
|
+
target[name] = value;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
360
377
|
//# sourceMappingURL=dokploy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dokploy.js","sourceRoot":"","sources":["../../src/preview/dokploy.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFileSync } from 'node:fs'\nimport { BlockList, isIP } from 'node:net'\n\nexport type DokployApplication = { applicationId: string; name: string; serverId?: string | null }\n\nexport function dokployPreviewFromEnvironment(environment: NodeJS.ProcessEnv = process.env) {\n const githubOutput = optionalEnvironment(environment, 'GITHUB_OUTPUT')\n const username = optionalEnvironment(environment, 'PREVIEW_REGISTRY_USERNAME')\n const password = optionalEnvironment(environment, 'PREVIEW_REGISTRY_PASSWORD')\n if (Boolean(username) !== Boolean(password)) throw new Error('preview registry username and password must be configured together')\n const port = Number(requiredEnvironment(environment, 'PREVIEW_PORT'))\n if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('PREVIEW_PORT must be a valid port')\n const applicationPrefix = requiredEnvironment(environment, 'PREVIEW_APPLICATION_PREFIX')\n if (!/^[a-z\\d](?:[a-z\\d-]*[a-z\\d])?$/.test(applicationPrefix)) throw new Error('PREVIEW_APPLICATION_PREFIX must be a slug')\n const domain = optionalEnvironment(environment, 'PREVIEW_DOMAIN')\n const subdomainPrefix = optionalEnvironment(environment, 'PREVIEW_SUBDOMAIN_PREFIX') ?? 'pr'\n if (!/^[a-z\\d](?:[a-z\\d-]*[a-z\\d])?$/.test(subdomainPrefix)) throw new Error('PREVIEW_SUBDOMAIN_PREFIX must be a slug')\n if (domain) previewHostname(`${subdomainPrefix}-1.${domain}`)\n const config = {\n url: requiredEnvironment(environment, 'DOKPLOY_URL'),\n apiKey: requiredEnvironment(environment, 'DOKPLOY_API_KEY'),\n environmentId: requiredEnvironment(environment, 'DOKPLOY_ENVIRONMENT_ID'),\n applicationPrefix,\n domain,\n subdomainPrefix,\n port,\n healthPath: optionalEnvironment(environment, 'PREVIEW_HEALTH_PATH'),\n ...(username && password ? { registry: { username, password } } : {}),\n }\n const client = new DokployClient(config)\n return {\n config,\n manager: new DokployPreviewManager({\n client,\n applicationName: (prNumber) => `${applicationPrefix}-pr-${prNumber}`,\n ...(domain ? { hostname: (prNumber: string) => `${subdomainPrefix}-${prNumber}.${domain}` } : {}),\n port,\n ...(config.healthPath ? { healthPath: config.healthPath } : {}),\n ...(githubOutput ? { onResolved: ({ url }: { url: string }) => appendFileSync(githubOutput, `preview-url=${url}\\n`) } : {}),\n }),\n }\n}\n\nexport type DokployClientOptions = {\n url: string\n apiKey: string\n environmentId: string\n fetch?: typeof fetch\n log?: (message: string) => void\n}\n\nexport class DokployClient {\n private readonly request: typeof fetch\n private readonly log: (message: string) => void\n\n constructor(private readonly options: DokployClientOptions) {\n this.request = options.fetch ?? fetch\n this.log = options.log ?? console.log\n }\n\n get environmentId() {\n return this.options.environmentId\n }\n\n async api<T = unknown>(\n procedure: string,\n options: { query?: Record<string, string>; body?: unknown; signal?: AbortSignal } = {},\n ): Promise<T> {\n const url = new URL(`${this.options.url.replace(/\\/$/, '')}/api/${procedure}`)\n for (const [key, value] of Object.entries(options.query ?? {})) url.searchParams.set(key, value)\n this.log(`→ ${procedure}`)\n const response = await this.request(url, {\n method: options.body === undefined ? 'GET' : 'POST',\n headers: {\n 'x-api-key': this.options.apiKey,\n ...(options.body === undefined ? {} : { 'content-type': 'application/json' }),\n },\n ...(options.signal ? { signal: options.signal } : {}),\n ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),\n })\n const text = await response.text()\n if (!response.ok) throw new Error(`${procedure} failed with ${response.status}: ${text.slice(0, 500)}`)\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch {\n throw new Error(`${procedure} returned ${response.status} with a non-JSON body: ${text.slice(0, 200)}`)\n }\n }\n\n async applications() {\n const environment = await this.api<{ applications?: DokployApplication[] } | undefined>('environment.one', {\n query: { environmentId: this.options.environmentId },\n })\n if (!environment) throw new Error('environment.one returned an empty response')\n return environment.applications ?? []\n }\n\n async application(name: string) {\n return (await this.applications()).find((application) => application.name === name)\n }\n\n async generatedDomain(appName: string, serverId?: string, existing: string[] = []) {\n const publicIp = await this.publicIp(serverId)\n const current = existing.find((host) => isCurrentGeneratedPreviewHostname(host, appName, publicIp))\n if (current) return current\n const generated = await this.api('domain.generateDomain', {\n body: { appName, ...(serverId ? { serverId } : {}) },\n })\n if (typeof generated !== 'string') throw new Error('domain.generateDomain returned an invalid hostname')\n return generatedPreviewHostname(generated, publicIp, appName)\n }\n\n async publicIp(serverId?: string) {\n const serverIp = serverId\n ? await this.api('domain.canGenerateTraefikMeDomains', { query: { serverId } })\n : await this.api('settings.getIp')\n return previewServerIp(serverIp)\n }\n}\n\nexport type DokployPreviewOptions = {\n client: DokployClient\n applicationName: (prNumber: string) => string\n hostname?: (prNumber: string) => string\n port: number\n healthPath?: string\n deploymentTimeoutMs?: number\n healthTimeoutMs?: number\n pollIntervalMs?: number\n fetch?: typeof fetch\n sleep?: (milliseconds: number) => Promise<void>\n now?: () => number\n log?: (message: string) => void\n onResolved?: (context: { host: string; url: string }) => void | Promise<void>\n}\n\nexport type DeployPreviewOptions = {\n prNumber: string\n image: string\n environment: string | ((context: { host: string; url: string }) => string)\n registry?: { username: string; password: string }\n configure?: (context: {\n applicationId: string\n client: DokployClient\n host: string\n url: string\n serverId?: string\n }) => void | Promise<void>\n}\n\nexport class DokployPreviewManager {\n private readonly request: typeof fetch\n private readonly pause: (milliseconds: number) => Promise<void>\n private readonly log: (message: string) => void\n private readonly now: () => number\n\n constructor(private readonly options: DokployPreviewOptions) {\n this.request = options.fetch ?? fetch\n this.pause = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)))\n this.log = options.log ?? console.log\n this.now = options.now ?? Date.now\n }\n\n async deploy(options: DeployPreviewOptions) {\n const prNumber = pullRequestNumber(options.prNumber)\n const name = this.options.applicationName(prNumber)\n let application = await this.options.client.application(name)\n if (!application) {\n await this.options.client.api('application.create', {\n body: { name, appName: name, environmentId: this.options.client.environmentId },\n })\n application = await this.options.client.application(name)\n if (!application) throw new Error(`Dokploy did not report ${name} after creating it`)\n }\n const applicationId = application.applicationId\n const details = await this.options.client.api<\n { domains?: { domainId?: string; host: string }[]; serverId?: string | null } | undefined\n >('application.one', { query: { applicationId } })\n const generated = !this.options.hostname\n const managedDomains = details?.domains?.filter((domain) => isGeneratedPreviewHostname(domain.host, generatedPreviewName)) ?? []\n const host = previewHostname(\n this.options.hostname\n ? this.options.hostname(prNumber)\n : await this.options.client.generatedDomain(\n generatedPreviewName,\n details?.serverId ?? application.serverId ?? undefined,\n managedDomains.map((domain) => domain.host),\n ),\n )\n const url = `${generated ? 'http' : 'https'}://${host}`\n if (!details?.domains?.some((domain) => domain.host === host)) {\n await this.options.client.api('domain.create', {\n body: {\n applicationId,\n host,\n path: '/',\n port: this.options.port,\n https: !generated,\n certificateType: generated ? 'none' : 'letsencrypt',\n domainType: 'application',\n },\n })\n }\n await this.options.onResolved?.({ host, url })\n const serverId = details?.serverId || application.serverId || undefined\n await options.configure?.({\n applicationId,\n client: this.options.client,\n host,\n url,\n ...(serverId ? { serverId } : {}),\n })\n await this.options.client.api('application.saveDockerProvider', {\n body: {\n applicationId,\n dockerImage: options.image,\n username: options.registry?.username ?? null,\n password: options.registry?.password ?? null,\n registryUrl: options.registry ? options.image.split('/')[0] : null,\n },\n })\n await this.options.client.api('application.saveEnvironment', {\n body: {\n applicationId,\n env: typeof options.environment === 'function' ? options.environment({ host, url }) : options.environment,\n buildArgs: null,\n buildSecrets: null,\n createEnvFile: false,\n },\n })\n await this.options.client.api('application.deploy', { body: { applicationId } })\n await this.waitForDeployment(applicationId)\n await this.waitForHealth(new URL(this.options.healthPath ?? '/api/health', url).toString())\n for (const domain of managedDomains.filter((candidate) => candidate.host !== host)) {\n if (!domain.domainId) throw new Error(`Dokploy did not report an ID for generated domain ${domain.host}`)\n // oxlint-disable-next-line no-await-in-loop\n await this.options.client.api('domain.delete', { body: { domainId: domain.domainId } })\n }\n this.log(`Preview ready at ${url}`)\n return { applicationId, host, url }\n }\n\n async delete(prNumber: string, beforeDelete?: (application: DokployApplication | undefined) => void | Promise<void>) {\n const name = this.options.applicationName(pullRequestNumber(prNumber))\n const application = await this.options.client.application(name)\n await beforeDelete?.(application)\n if (!application) return false\n await this.options.client.api('application.delete', { body: { applicationId: application.applicationId } })\n return true\n }\n\n async prune(\n openPullRequests: ReadonlySet<string>,\n beforeDelete?: (prNumber: string, application: DokployApplication) => void | Promise<void>,\n ) {\n const deleted: string[] = []\n for (const application of await this.options.client.applications()) {\n const prNumber = previewApplicationPrNumber(application.name, this.options.applicationName)\n if (!prNumber || openPullRequests.has(prNumber)) continue\n // Dokploy mutations are intentionally ordered to avoid overwhelming one environment.\n // oxlint-disable-next-line no-await-in-loop\n await beforeDelete?.(prNumber, application)\n // oxlint-disable-next-line no-await-in-loop\n await this.options.client.api('application.delete', { body: { applicationId: application.applicationId } })\n deleted.push(prNumber)\n }\n return deleted\n }\n\n private async waitForDeployment(applicationId: string) {\n const deadline = this.now() + (this.options.deploymentTimeoutMs ?? 600_000)\n while (this.now() < deadline) {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n await this.pause(this.options.pollIntervalMs ?? 5_000)\n let applicationStatus: string\n try {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n const details = await this.options.client.api<{ applicationStatus: string }>('application.one', {\n query: { applicationId },\n signal: AbortSignal.timeout(Math.max(1, deadline - this.now())),\n })\n applicationStatus = details.applicationStatus\n } catch (error) {\n if (error instanceof DOMException && error.name === 'TimeoutError') break\n throw error\n }\n if (applicationStatus === 'done') return\n if (applicationStatus === 'error') throw new Error('Dokploy reported a failed deployment')\n }\n throw new Error('Timed out waiting for the Dokploy deployment to finish')\n }\n\n private async waitForHealth(url: string) {\n const deadline = this.now() + (this.options.healthTimeoutMs ?? 300_000)\n let lastFailure = 'no response'\n while (this.now() < deadline) {\n try {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n const response = await this.request(url, { signal: AbortSignal.timeout(Math.max(1, deadline - this.now())) })\n if (response.status === 200) return\n lastFailure = `status ${response.status}`\n } catch (error) {\n lastFailure = error instanceof Error ? error.message : String(error)\n }\n // oxlint-disable-next-line no-await-in-loop\n await this.pause(this.options.pollIntervalMs ?? 5_000)\n }\n throw new Error(`Timed out waiting for ${url} (${lastFailure})`)\n }\n}\n\nexport function pullRequestNumber(value: string) {\n if (!/^\\d+$/.test(value)) throw new Error('pull request number must contain only digits')\n return value\n}\n\nexport function previewHostname(value: string) {\n const parsed = new URL(`https://${value}`)\n if (parsed.hostname !== value || parsed.port || parsed.username || parsed.password || parsed.pathname !== '/') {\n throw new Error('preview hostname must be a bare hostname')\n }\n return value\n}\n\nfunction generatedPreviewHostname(value: string, serverIp: string, appName: string) {\n const host = previewHostname(value)\n if (!isCurrentGeneratedPreviewHostname(host, appName, serverIp))\n throw new Error('domain.generateDomain did not return an sslip.io hostname for the Dokploy server')\n return host\n}\n\nfunction isGeneratedPreviewHostname(host: string, appName: string) {\n return new RegExp(`^${regularExpressionLiteral(appName.slice(0, 40))}-[a-f\\\\d]{6}-[a-f\\\\d-]+\\\\.sslip\\\\.io$`).test(host)\n}\n\nfunction isCurrentGeneratedPreviewHostname(host: string, appName: string, serverIp: string) {\n return new RegExp(\n `^${regularExpressionLiteral(appName.slice(0, 40))}-[a-f\\\\d]{6}-${regularExpressionLiteral(encodedIp(serverIp))}\\\\.sslip\\\\.io$`,\n ).test(host)\n}\n\nfunction regularExpressionLiteral(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction encodedIp(address: string) {\n return address.replaceAll('.', '-').replaceAll(':', '-')\n}\n\nconst generatedPreviewName = 'ras-preview'\n\nconst blockedPreviewAddresses = new BlockList()\nfor (const [address, prefix, family] of [\n ['0.0.0.0', 8, 'ipv4'],\n ['10.0.0.0', 8, 'ipv4'],\n ['100.64.0.0', 10, 'ipv4'],\n ['127.0.0.0', 8, 'ipv4'],\n ['169.254.0.0', 16, 'ipv4'],\n ['172.16.0.0', 12, 'ipv4'],\n ['192.0.0.0', 24, 'ipv4'],\n ['192.0.2.0', 24, 'ipv4'],\n ['192.88.99.0', 24, 'ipv4'],\n ['192.168.0.0', 16, 'ipv4'],\n ['198.18.0.0', 15, 'ipv4'],\n ['198.51.100.0', 24, 'ipv4'],\n ['203.0.113.0', 24, 'ipv4'],\n ['224.0.0.0', 4, 'ipv4'],\n ['240.0.0.0', 4, 'ipv4'],\n ['::', 128, 'ipv6'],\n ['::1', 128, 'ipv6'],\n ['64:ff9b:1::', 48, 'ipv6'],\n ['100::', 64, 'ipv6'],\n ['100:0:0:1::', 64, 'ipv6'],\n ['2001::', 23, 'ipv6'],\n ['2001:db8::', 32, 'ipv6'],\n ['2002::', 16, 'ipv6'],\n ['3fff::', 20, 'ipv6'],\n ['5f00::', 16, 'ipv6'],\n ['fc00::', 7, 'ipv6'],\n ['fe80::', 10, 'ipv6'],\n ['ff00::', 8, 'ipv6'],\n] as const) {\n blockedPreviewAddresses.addSubnet(address, prefix, family)\n}\n\nfunction previewServerIp(value: unknown) {\n if (typeof value !== 'string') throw new Error('Dokploy requires a public server IP before it can generate preview domains')\n const address = value.trim().toLowerCase()\n const version = isIP(address)\n const family = version === 4 ? 'ipv4' : version === 6 ? 'ipv6' : undefined\n if (!family || address.startsWith('::ffff:') || blockedPreviewAddresses.check(address, family)) {\n throw new Error('Dokploy requires a public server IP before it can generate preview domains')\n }\n return address\n}\n\nfunction previewApplicationPrNumber(name: string, applicationName: (prNumber: string) => string) {\n const match = /^(\\d+)$/.exec(name.match(/(\\d+)$/)?.[1] ?? '')\n const prNumber = match?.[1]\n return prNumber && applicationName(prNumber) === name ? prNumber : undefined\n}\n\nfunction requiredEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n const value = optionalEnvironment(environment, name)\n if (!value) throw new Error(`${name} is required`)\n return value\n}\n\nfunction optionalEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n return environment[name]?.trim() || undefined\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dokploy.js","sourceRoot":"","sources":["../../src/preview/dokploy.ts"],"names":[],"mappings":"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","sourcesContent":["import { appendFileSync } from 'node:fs'\nimport { BlockList, isIP } from 'node:net'\n\nexport type DokployApplication = { applicationId: string; name: string; serverId?: string | null }\n\nexport function dokployPreviewFromEnvironment(environment: NodeJS.ProcessEnv = process.env) {\n const githubOutput = optionalEnvironment(environment, 'GITHUB_OUTPUT')\n const username = optionalEnvironment(environment, 'PREVIEW_REGISTRY_USERNAME')\n const password = optionalEnvironment(environment, 'PREVIEW_REGISTRY_PASSWORD')\n if (Boolean(username) !== Boolean(password)) throw new Error('preview registry username and password must be configured together')\n const port = Number(requiredEnvironment(environment, 'PREVIEW_PORT'))\n if (!Number.isInteger(port) || port < 1 || port > 65_535) throw new Error('PREVIEW_PORT must be a valid port')\n const applicationPrefix = requiredEnvironment(environment, 'PREVIEW_APPLICATION_PREFIX')\n if (!/^[a-z\\d](?:[a-z\\d-]*[a-z\\d])?$/.test(applicationPrefix)) throw new Error('PREVIEW_APPLICATION_PREFIX must be a slug')\n const domain = optionalEnvironment(environment, 'PREVIEW_DOMAIN')\n const subdomainPrefix = optionalEnvironment(environment, 'PREVIEW_SUBDOMAIN_PREFIX') ?? 'pr'\n if (!/^[a-z\\d](?:[a-z\\d-]*[a-z\\d])?$/.test(subdomainPrefix)) throw new Error('PREVIEW_SUBDOMAIN_PREFIX must be a slug')\n if (domain) previewHostname(`${subdomainPrefix}-1.${domain}`)\n const config = {\n url: requiredEnvironment(environment, 'DOKPLOY_URL'),\n apiKey: requiredEnvironment(environment, 'DOKPLOY_API_KEY'),\n environmentId: requiredEnvironment(environment, 'DOKPLOY_ENVIRONMENT_ID'),\n applicationPrefix,\n domain,\n subdomainPrefix,\n port,\n healthPath: optionalEnvironment(environment, 'PREVIEW_HEALTH_PATH'),\n ...(username && password ? { registry: { username, password } } : {}),\n }\n const client = new DokployClient(config)\n return {\n config,\n manager: new DokployPreviewManager({\n client,\n applicationName: (prNumber) => `${applicationPrefix}-pr-${prNumber}`,\n ...(domain ? { hostname: (prNumber: string) => `${subdomainPrefix}-${prNumber}.${domain}` } : {}),\n port,\n ...(config.healthPath ? { healthPath: config.healthPath } : {}),\n ...(githubOutput ? { onResolved: ({ url }: { url: string }) => appendFileSync(githubOutput, `preview-url=${url}\\n`) } : {}),\n }),\n }\n}\n\nexport type DokployClientOptions = {\n url: string\n apiKey: string\n environmentId: string\n fetch?: typeof fetch\n log?: (message: string) => void\n}\n\nexport class DokployClient {\n private readonly request: typeof fetch\n private readonly log: (message: string) => void\n\n constructor(private readonly options: DokployClientOptions) {\n this.request = options.fetch ?? fetch\n this.log = options.log ?? console.log\n }\n\n get environmentId() {\n return this.options.environmentId\n }\n\n async api<T = unknown>(\n procedure: string,\n options: { query?: Record<string, string>; body?: unknown; signal?: AbortSignal } = {},\n ): Promise<T> {\n const url = new URL(`${this.options.url.replace(/\\/$/, '')}/api/${procedure}`)\n for (const [key, value] of Object.entries(options.query ?? {})) url.searchParams.set(key, value)\n this.log(`→ ${procedure}`)\n const response = await this.request(url, {\n method: options.body === undefined ? 'GET' : 'POST',\n headers: {\n 'x-api-key': this.options.apiKey,\n ...(options.body === undefined ? {} : { 'content-type': 'application/json' }),\n },\n ...(options.signal ? { signal: options.signal } : {}),\n ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),\n })\n const text = await response.text()\n if (!response.ok) throw new Error(`${procedure} failed with ${response.status}: ${text.slice(0, 500)}`)\n if (!text) return undefined as T\n try {\n return JSON.parse(text) as T\n } catch {\n throw new Error(`${procedure} returned ${response.status} with a non-JSON body: ${text.slice(0, 200)}`)\n }\n }\n\n async applications() {\n const environment = await this.api<{ applications?: DokployApplication[] } | undefined>('environment.one', {\n query: { environmentId: this.options.environmentId },\n })\n if (!environment) throw new Error('environment.one returned an empty response')\n return environment.applications ?? []\n }\n\n async application(name: string) {\n return (await this.applications()).find((application) => application.name === name)\n }\n\n async generatedDomain(appName: string, serverId?: string, existing: string[] = []) {\n const publicIp = await this.publicIp(serverId)\n const current = existing.find((host) => isCurrentGeneratedPreviewHostname(host, appName, publicIp))\n if (current) return current\n const generated = await this.api('domain.generateDomain', {\n body: { appName, ...(serverId ? { serverId } : {}) },\n })\n if (typeof generated !== 'string') throw new Error('domain.generateDomain returned an invalid hostname')\n return generatedPreviewHostname(generated, publicIp, appName)\n }\n\n async publicIp(serverId?: string) {\n const serverIp = serverId\n ? await this.api('domain.canGenerateTraefikMeDomains', { query: { serverId } })\n : await this.api('settings.getIp')\n return previewServerIp(serverIp)\n }\n}\n\nexport type DokployPreviewOptions = {\n client: DokployClient\n applicationName: (prNumber: string) => string\n hostname?: (prNumber: string) => string\n port: number\n healthPath?: string\n deploymentTimeoutMs?: number\n healthTimeoutMs?: number\n pollIntervalMs?: number\n fetch?: typeof fetch\n sleep?: (milliseconds: number) => Promise<void>\n now?: () => number\n log?: (message: string) => void\n onResolved?: (context: { host: string; url: string }) => void | Promise<void>\n}\n\nexport type DeployPreviewOptions = {\n prNumber: string\n image: string\n environment: string | ((context: { host: string; url: string }) => string)\n registry?: { username: string; password: string }\n configure?: (context: {\n applicationId: string\n client: DokployClient\n host: string\n url: string\n serverId?: string\n }) => void | Promise<void>\n}\n\nexport class DokployPreviewManager {\n private readonly request: typeof fetch\n private readonly pause: (milliseconds: number) => Promise<void>\n private readonly log: (message: string) => void\n private readonly now: () => number\n\n constructor(private readonly options: DokployPreviewOptions) {\n this.request = options.fetch ?? fetch\n this.pause = options.sleep ?? ((milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)))\n this.log = options.log ?? console.log\n this.now = options.now ?? Date.now\n }\n\n async deploy(options: DeployPreviewOptions) {\n const prNumber = pullRequestNumber(options.prNumber)\n const name = this.options.applicationName(prNumber)\n let application = await this.options.client.application(name)\n if (!application) {\n await this.options.client.api('application.create', {\n body: { name, appName: name, environmentId: this.options.client.environmentId },\n })\n application = await this.options.client.application(name)\n if (!application) throw new Error(`Dokploy did not report ${name} after creating it`)\n }\n const applicationId = application.applicationId\n const details = await this.options.client.api<\n { domains?: { domainId?: string; host: string }[]; serverId?: string | null } | undefined\n >('application.one', { query: { applicationId } })\n const generated = !this.options.hostname\n const managedDomains = details?.domains?.filter((domain) => isGeneratedPreviewHostname(domain.host, generatedPreviewName)) ?? []\n const host = previewHostname(\n this.options.hostname\n ? this.options.hostname(prNumber)\n : await this.options.client.generatedDomain(\n generatedPreviewName,\n details?.serverId ?? application.serverId ?? undefined,\n managedDomains.map((domain) => domain.host),\n ),\n )\n const url = `${generated ? 'http' : 'https'}://${host}`\n if (!details?.domains?.some((domain) => domain.host === host)) {\n await this.options.client.api('domain.create', {\n body: {\n applicationId,\n host,\n path: '/',\n port: this.options.port,\n https: !generated,\n certificateType: generated ? 'none' : 'letsencrypt',\n domainType: 'application',\n },\n })\n }\n await this.options.onResolved?.({ host, url })\n const serverId = details?.serverId || application.serverId || undefined\n await options.configure?.({\n applicationId,\n client: this.options.client,\n host,\n url,\n ...(serverId ? { serverId } : {}),\n })\n await this.options.client.api('application.saveDockerProvider', {\n body: {\n applicationId,\n dockerImage: options.image,\n username: options.registry?.username ?? null,\n password: options.registry?.password ?? null,\n registryUrl: options.registry ? options.image.split('/')[0] : null,\n },\n })\n await this.options.client.api('application.saveEnvironment', {\n body: {\n applicationId,\n env: typeof options.environment === 'function' ? options.environment({ host, url }) : options.environment,\n buildArgs: null,\n buildSecrets: null,\n createEnvFile: false,\n },\n })\n await this.options.client.api('application.deploy', { body: { applicationId } })\n await this.waitForDeployment(applicationId)\n await this.waitForHealth(new URL(this.options.healthPath ?? '/api/health', url).toString())\n for (const domain of managedDomains.filter((candidate) => candidate.host !== host)) {\n if (!domain.domainId) throw new Error(`Dokploy did not report an ID for generated domain ${domain.host}`)\n // oxlint-disable-next-line no-await-in-loop\n await this.options.client.api('domain.delete', { body: { domainId: domain.domainId } })\n }\n this.log(`Preview ready at ${url}`)\n return { applicationId, host, url }\n }\n\n async delete(prNumber: string, beforeDelete?: (application: DokployApplication | undefined) => void | Promise<void>) {\n const name = this.options.applicationName(pullRequestNumber(prNumber))\n const application = await this.options.client.application(name)\n await beforeDelete?.(application)\n if (!application) return false\n await this.options.client.api('application.delete', { body: { applicationId: application.applicationId } })\n return true\n }\n\n async prune(\n openPullRequests: ReadonlySet<string>,\n beforeDelete?: (prNumber: string, application: DokployApplication) => void | Promise<void>,\n ) {\n const deleted: string[] = []\n for (const application of await this.options.client.applications()) {\n const prNumber = previewApplicationPrNumber(application.name, this.options.applicationName)\n if (!prNumber || openPullRequests.has(prNumber)) continue\n // Dokploy mutations are intentionally ordered to avoid overwhelming one environment.\n // oxlint-disable-next-line no-await-in-loop\n await beforeDelete?.(prNumber, application)\n // oxlint-disable-next-line no-await-in-loop\n await this.options.client.api('application.delete', { body: { applicationId: application.applicationId } })\n deleted.push(prNumber)\n }\n return deleted\n }\n\n private async waitForDeployment(applicationId: string) {\n const deadline = this.now() + (this.options.deploymentTimeoutMs ?? 600_000)\n while (this.now() < deadline) {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n await this.pause(this.options.pollIntervalMs ?? 5_000)\n let applicationStatus: string\n try {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n const details = await this.options.client.api<{ applicationStatus: string }>('application.one', {\n query: { applicationId },\n signal: AbortSignal.timeout(Math.max(1, deadline - this.now())),\n })\n applicationStatus = details.applicationStatus\n } catch (error) {\n if (error instanceof DOMException && error.name === 'TimeoutError') break\n throw error\n }\n if (applicationStatus === 'done') return\n if (applicationStatus === 'error') throw new Error('Dokploy reported a failed deployment')\n }\n throw new Error('Timed out waiting for the Dokploy deployment to finish')\n }\n\n private async waitForHealth(url: string) {\n const deadline = this.now() + (this.options.healthTimeoutMs ?? 300_000)\n let lastFailure = 'no response'\n while (this.now() < deadline) {\n try {\n // Polling is intentionally sequential; each response determines whether another request is needed.\n // oxlint-disable-next-line no-await-in-loop\n const response = await this.request(url, { signal: AbortSignal.timeout(Math.max(1, deadline - this.now())) })\n if (response.status === 200) return\n lastFailure = `status ${response.status}`\n } catch (error) {\n lastFailure = error instanceof Error ? error.message : String(error)\n }\n // oxlint-disable-next-line no-await-in-loop\n await this.pause(this.options.pollIntervalMs ?? 5_000)\n }\n throw new Error(`Timed out waiting for ${url} (${lastFailure})`)\n }\n}\n\nexport function pullRequestNumber(value: string) {\n if (!/^\\d+$/.test(value)) throw new Error('pull request number must contain only digits')\n return value\n}\n\nexport function previewHostname(value: string) {\n const parsed = new URL(`https://${value}`)\n if (parsed.hostname !== value || parsed.port || parsed.username || parsed.password || parsed.pathname !== '/') {\n throw new Error('preview hostname must be a bare hostname')\n }\n return value\n}\n\nfunction generatedPreviewHostname(value: string, serverIp: string, appName: string) {\n const host = previewHostname(value)\n if (!isCurrentGeneratedPreviewHostname(host, appName, serverIp))\n throw new Error('domain.generateDomain did not return an sslip.io hostname for the Dokploy server')\n return host\n}\n\nfunction isGeneratedPreviewHostname(host: string, appName: string) {\n return new RegExp(`^${regularExpressionLiteral(appName.slice(0, 40))}-[a-f\\\\d]{6}-[a-f\\\\d-]+\\\\.sslip\\\\.io$`).test(host)\n}\n\nfunction isCurrentGeneratedPreviewHostname(host: string, appName: string, serverIp: string) {\n return new RegExp(\n `^${regularExpressionLiteral(appName.slice(0, 40))}-[a-f\\\\d]{6}-${regularExpressionLiteral(encodedIp(serverIp))}\\\\.sslip\\\\.io$`,\n ).test(host)\n}\n\nfunction regularExpressionLiteral(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\nfunction encodedIp(address: string) {\n return address.replaceAll('.', '-').replaceAll(':', '-')\n}\n\nconst generatedPreviewName = 'ras-preview'\n\nconst blockedPreviewAddresses = new BlockList()\nfor (const [address, prefix, family] of [\n ['0.0.0.0', 8, 'ipv4'],\n ['10.0.0.0', 8, 'ipv4'],\n ['100.64.0.0', 10, 'ipv4'],\n ['127.0.0.0', 8, 'ipv4'],\n ['169.254.0.0', 16, 'ipv4'],\n ['172.16.0.0', 12, 'ipv4'],\n ['192.0.0.0', 24, 'ipv4'],\n ['192.0.2.0', 24, 'ipv4'],\n ['192.88.99.0', 24, 'ipv4'],\n ['192.168.0.0', 16, 'ipv4'],\n ['198.18.0.0', 15, 'ipv4'],\n ['198.51.100.0', 24, 'ipv4'],\n ['203.0.113.0', 24, 'ipv4'],\n ['224.0.0.0', 4, 'ipv4'],\n ['240.0.0.0', 4, 'ipv4'],\n ['::', 128, 'ipv6'],\n ['::1', 128, 'ipv6'],\n ['64:ff9b:1::', 48, 'ipv6'],\n ['100::', 64, 'ipv6'],\n ['100:0:0:1::', 64, 'ipv6'],\n ['2001::', 23, 'ipv6'],\n ['2001:db8::', 32, 'ipv6'],\n ['2002::', 16, 'ipv6'],\n ['3fff::', 20, 'ipv6'],\n ['5f00::', 16, 'ipv6'],\n ['fc00::', 7, 'ipv6'],\n ['fe80::', 10, 'ipv6'],\n ['ff00::', 8, 'ipv6'],\n] as const) {\n blockedPreviewAddresses.addSubnet(address, prefix, family)\n}\n\nfunction previewServerIp(value: unknown) {\n if (typeof value !== 'string') throw new Error('Dokploy requires a public server IP before it can generate preview domains')\n const address = value.trim().toLowerCase()\n const version = isIP(address)\n const family = version === 4 ? 'ipv4' : version === 6 ? 'ipv6' : undefined\n if (!family || address.startsWith('::ffff:') || blockedPreviewAddresses.check(address, family)) {\n throw new Error('Dokploy requires a public server IP before it can generate preview domains')\n }\n return address\n}\n\nfunction previewApplicationPrNumber(name: string, applicationName: (prNumber: string) => string) {\n const match = /^(\\d+)$/.exec(name.match(/(\\d+)$/)?.[1] ?? '')\n const prNumber = match?.[1]\n return prNumber && applicationName(prNumber) === name ? prNumber : undefined\n}\n\nfunction requiredEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n const value = optionalEnvironment(environment, name)\n if (!value) throw new Error(`${name} is required`)\n return value\n}\n\nfunction optionalEnvironment(environment: NodeJS.ProcessEnv, name: string) {\n return environment[name]?.trim() || undefined\n}\n\n// Deploy scripts receive product secrets as one JSON object; an unknown key is a mistake, not a passthrough.\nexport function loadPreviewAppSecrets(\n allowed: Iterable<string>,\n source: NodeJS.ProcessEnv = process.env,\n target: NodeJS.ProcessEnv = process.env,\n) {\n const serialized = source.PREVIEW_APP_SECRETS?.trim()\n if (!serialized) return\n const parsed: unknown = JSON.parse(serialized)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) throw new Error('PREVIEW_APP_SECRETS must be a JSON object')\n const names = new Set(allowed)\n for (const [name, value] of Object.entries(parsed)) {\n if (!names.has(name)) throw new Error(`PREVIEW_APP_SECRETS contains unsupported key ${name}`)\n if (typeof value !== 'string') throw new Error(`PREVIEW_APP_SECRETS.${name} must be a string`)\n target[name] = value\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type RealtimeEnvironmentOptions = {
|
|
2
|
+
prefix?: string;
|
|
3
|
+
developmentSecret?: string;
|
|
4
|
+
};
|
|
5
|
+
export type RealtimeEnvironment = {
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
apiKey: string;
|
|
8
|
+
secret: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function realtimeEnvironment(environment?: NodeJS.ProcessEnv, options?: RealtimeEnvironmentOptions): RealtimeEnvironment | undefined;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
export function realtimeEnvironment(environment = process.env, options = {}) {
|
|
3
|
+
const value = (name) => environment[`${options.prefix ?? ''}REALTIME_${name}`]?.trim() || undefined;
|
|
4
|
+
const secret = value('SECRET') ??
|
|
5
|
+
secretFromFile(value('SECRET_FILE')) ??
|
|
6
|
+
(environment.NODE_ENV === 'production' ? undefined : options.developmentSecret);
|
|
7
|
+
if (!secret)
|
|
8
|
+
return undefined;
|
|
9
|
+
return {
|
|
10
|
+
apiUrl: (value('API_URL') ?? 'http://127.0.0.1:8000/api').replace(/\/$/, ''),
|
|
11
|
+
apiKey: value('API_KEY') ?? secret,
|
|
12
|
+
secret,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function secretFromFile(file) {
|
|
16
|
+
if (!file)
|
|
17
|
+
return undefined;
|
|
18
|
+
try {
|
|
19
|
+
return fs.readFileSync(file, 'utf8').trim() || undefined;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if (error.code === 'ENOENT')
|
|
23
|
+
return undefined;
|
|
24
|
+
throw error;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=environment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/realtime/environment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AASxB,MAAM,UAAU,mBAAmB,CACjC,WAAW,GAAsB,OAAO,CAAC,GAAG,EAC5C,OAAO,GAA+B,EAAE;IAExC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,YAAY,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAA;IAC3G,MAAM,MAAM,GACV,KAAK,CAAC,QAAQ,CAAC;QACf,cAAc,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QACpC,CAAC,WAAW,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACjF,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAA;IAC7B,OAAO;QACL,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,2BAA2B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5E,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,MAAM;QAClC,MAAM;KACP,CAAA;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAwB;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAA;IAC3B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAA;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAA;QACxE,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC","sourcesContent":["import fs from 'node:fs'\n\nexport type RealtimeEnvironmentOptions = {\n prefix?: string\n developmentSecret?: string\n}\n\nexport type RealtimeEnvironment = { apiUrl: string; apiKey: string; secret: string }\n\nexport function realtimeEnvironment(\n environment: NodeJS.ProcessEnv = process.env,\n options: RealtimeEnvironmentOptions = {},\n): RealtimeEnvironment | undefined {\n const value = (name: string) => environment[`${options.prefix ?? ''}REALTIME_${name}`]?.trim() || undefined\n const secret =\n value('SECRET') ??\n secretFromFile(value('SECRET_FILE')) ??\n (environment.NODE_ENV === 'production' ? undefined : options.developmentSecret)\n if (!secret) return undefined\n return {\n apiUrl: (value('API_URL') ?? 'http://127.0.0.1:8000/api').replace(/\\/$/, ''),\n apiKey: value('API_KEY') ?? secret,\n secret,\n }\n}\n\nfunction secretFromFile(file: string | undefined) {\n if (!file) return undefined\n try {\n return fs.readFileSync(file, 'utf8').trim() || undefined\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n}\n"]}
|
package/dist/realtime/index.d.ts
CHANGED
|
@@ -4,3 +4,5 @@ export { CentrifugoPublisher } from './publisher.js';
|
|
|
4
4
|
export type { CentrifugoPublisherOptions } from './publisher.js';
|
|
5
5
|
export { signRealtimeToken } from './tokens.js';
|
|
6
6
|
export type { RealtimeTokenOptions } from './tokens.js';
|
|
7
|
+
export { realtimeEnvironment } from './environment.js';
|
|
8
|
+
export type { RealtimeEnvironment, RealtimeEnvironmentOptions } from './environment.js';
|
package/dist/realtime/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { connectRealtimeClient, createSameOriginRealtimeClient, openRealtimeSubscription, requestRealtimeTicket, sameOriginWebSocketUrl, watchServerChannel, watchSubscriptionPresence, } from './client.js';
|
|
2
2
|
export { CentrifugoPublisher } from './publisher.js';
|
|
3
3
|
export { signRealtimeToken } from './tokens.js';
|
|
4
|
+
export { realtimeEnvironment } from './environment.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA","sourcesContent":["export {\n connectRealtimeClient,\n createSameOriginRealtimeClient,\n openRealtimeSubscription,\n requestRealtimeTicket,\n sameOriginWebSocketUrl,\n watchServerChannel,\n watchSubscriptionPresence,\n} from './client.js'\nexport type { RealtimeSubscription, RealtimeTicketOptions } from './client.js'\nexport { CentrifugoPublisher } from './publisher.js'\nexport type { CentrifugoPublisherOptions } from './publisher.js'\nexport { signRealtimeToken } from './tokens.js'\nexport type { RealtimeTokenOptions } from './tokens.js'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/realtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,wBAAwB,EACxB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA","sourcesContent":["export {\n connectRealtimeClient,\n createSameOriginRealtimeClient,\n openRealtimeSubscription,\n requestRealtimeTicket,\n sameOriginWebSocketUrl,\n watchServerChannel,\n watchSubscriptionPresence,\n} from './client.js'\nexport type { RealtimeSubscription, RealtimeTicketOptions } from './client.js'\nexport { CentrifugoPublisher } from './publisher.js'\nexport type { CentrifugoPublisherOptions } from './publisher.js'\nexport { signRealtimeToken } from './tokens.js'\nexport type { RealtimeTokenOptions } from './tokens.js'\nexport { realtimeEnvironment } from './environment.js'\nexport type { RealtimeEnvironment, RealtimeEnvironmentOptions } from './environment.js'\n"]}
|
|
@@ -23,7 +23,9 @@ export declare class CentrifugoPublisher {
|
|
|
23
23
|
constructor(options: CentrifugoPublisherOptions);
|
|
24
24
|
publish(channel: string, data: unknown): boolean;
|
|
25
25
|
idle(): Promise<void>;
|
|
26
|
-
close(
|
|
26
|
+
close(options?: {
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
}): Promise<void>;
|
|
27
29
|
private pump;
|
|
28
30
|
private flush;
|
|
29
31
|
private deliver;
|
|
@@ -42,9 +42,12 @@ export class CentrifugoPublisher {
|
|
|
42
42
|
return Promise.resolve();
|
|
43
43
|
return new Promise((resolve) => this.idleWaiters.add(resolve));
|
|
44
44
|
}
|
|
45
|
-
async close() {
|
|
45
|
+
async close(options = {}) {
|
|
46
46
|
this.closed = true;
|
|
47
|
-
|
|
47
|
+
const idle = this.idle();
|
|
48
|
+
if (!options.signal)
|
|
49
|
+
return idle;
|
|
50
|
+
await abortable(idle, options.signal);
|
|
48
51
|
}
|
|
49
52
|
pump() {
|
|
50
53
|
while (this.active < this.maxConcurrentChannels) {
|
|
@@ -156,6 +159,20 @@ export class CentrifugoPublisher {
|
|
|
156
159
|
this.idleWaiters.clear();
|
|
157
160
|
}
|
|
158
161
|
}
|
|
162
|
+
async function abortable(work, signal) {
|
|
163
|
+
signal.throwIfAborted();
|
|
164
|
+
let abort;
|
|
165
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
166
|
+
abort = () => reject(signal.reason);
|
|
167
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
168
|
+
});
|
|
169
|
+
try {
|
|
170
|
+
await Promise.race([work, aborted]);
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
signal.removeEventListener('abort', abort);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
159
176
|
class TransientPublishError extends Error {
|
|
160
177
|
}
|
|
161
178
|
function isTimeout(error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/realtime/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["export type CentrifugoPublisherOptions = {\n apiUrl: string\n apiKey: string\n fetch?: typeof fetch\n timeoutMs?: number\n retryMs?: number\n maxRetries?: number\n maxConcurrentChannels?: number\n maxPendingChannels?: number\n onError: (error: unknown, channel: string) => void\n onRetry?: (error: unknown, channel: string) => void\n}\n\ntype PendingPublication = { dirty: boolean; data: unknown; running: boolean }\n\nexport class CentrifugoPublisher {\n private readonly pending = new Map<string, PendingPublication>()\n private readonly queue: string[] = []\n private readonly idleWaiters = new Set<() => void>()\n private readonly request: typeof fetch\n private readonly maxConcurrentChannels: number\n private readonly maxPendingChannels: number\n private active = 0\n private closed = false\n\n constructor(private readonly options: CentrifugoPublisherOptions) {\n this.request = options.fetch ?? fetch\n this.maxConcurrentChannels = positiveInteger(options.maxConcurrentChannels ?? 8, 'maxConcurrentChannels')\n this.maxPendingChannels = positiveInteger(options.maxPendingChannels ?? 1_024, 'maxPendingChannels')\n }\n\n publish(channel: string, data: unknown) {\n if (!this.options.apiUrl) return false\n if (this.closed) {\n this.reportError(new Error('Realtime publisher is closed'), channel)\n return false\n }\n const pending = this.pending.get(channel)\n if (pending) {\n pending.dirty = true\n pending.data = data\n return true\n }\n if (this.pending.size >= this.maxPendingChannels) {\n this.reportError(new Error('Realtime publisher queue is full'), channel)\n return false\n }\n\n const state = { dirty: true, data, running: false }\n this.pending.set(channel, state)\n this.queue.push(channel)\n this.pump()\n return true\n }\n\n idle() {\n if (this.isIdle()) return Promise.resolve()\n return new Promise<void>((resolve) => this.idleWaiters.add(resolve))\n }\n\n async close() {\n this.closed = true\n await this.idle()\n }\n\n private pump() {\n while (this.active < this.maxConcurrentChannels) {\n const channel = this.queue.shift()\n if (!channel) break\n const state = this.pending.get(channel)\n if (!state || state.running) continue\n state.running = true\n this.active++\n void this.flush(channel, state).finally(() => {\n this.active--\n this.pump()\n this.resolveIdle()\n })\n }\n }\n\n private async flush(channel: string, state: PendingPublication) {\n let failure: unknown\n try {\n while (state.dirty) {\n state.dirty = false\n // Publications for one channel must preserve mutation order.\n // oxlint-disable-next-line no-await-in-loop\n await this.deliver(channel, state.data)\n }\n } catch (error) {\n failure = error\n } finally {\n if (this.pending.get(channel) === state) this.pending.delete(channel)\n }\n if (failure) {\n if (state.dirty) {\n this.pending.set(channel, { dirty: true, data: state.data, running: false })\n this.queue.push(channel)\n this.pump()\n }\n this.reportError(failure, channel)\n }\n }\n\n private async deliver(channel: string, data: unknown) {\n const maxRetries = this.options.maxRetries ?? 3\n for (let retries = 0; ; retries++) {\n try {\n // Retrying must finish before a later publication can overtake this one.\n // oxlint-disable-next-line no-await-in-loop\n await this.deliverOnce(channel, data)\n return\n } catch (error) {\n if (!(error instanceof TransientPublishError)) throw error\n if (retries >= maxRetries) throw error\n this.options.onRetry?.(error, channel)\n // oxlint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setTimeout(resolve, this.options.retryMs ?? 1_000))\n }\n }\n }\n\n private async deliverOnce(channel: string, data: unknown) {\n let response: Response\n try {\n response = await this.request(`${this.options.apiUrl.replace(/\\/$/, '')}/publish`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-API-Key': this.options.apiKey },\n body: JSON.stringify({ channel, data }),\n signal: AbortSignal.timeout(this.options.timeoutMs ?? 5_000),\n })\n } catch (error) {\n if (error instanceof TypeError || isTimeout(error))\n throw new TransientPublishError('Realtime publish request failed', { cause: error })\n throw error\n }\n\n if (!response.ok) {\n const message = `Realtime publish failed with status ${response.status}`\n if (response.status >= 500 || response.status === 429) throw new TransientPublishError(message)\n throw new Error(message)\n }\n\n const result: unknown = await response.json()\n const error = centrifugoError(result)\n if (!error) return\n const message = `Realtime publish failed: ${error.message ?? `code ${error.code ?? 'unknown'}`}`\n if (error.code === 100) throw new TransientPublishError(message)\n throw new Error(message)\n }\n\n private reportError(error: unknown, channel: string) {\n try {\n this.options.onError(error, channel)\n } catch {}\n }\n\n private isIdle() {\n return this.pending.size === 0 && this.active === 0 && this.queue.length === 0\n }\n\n private resolveIdle() {\n if (!this.isIdle()) return\n for (const resolve of this.idleWaiters) resolve()\n this.idleWaiters.clear()\n }\n}\n\nclass TransientPublishError extends Error {}\n\nfunction isTimeout(error: unknown) {\n return error instanceof DOMException && error.name === 'TimeoutError'\n}\n\nfunction centrifugoError(result: unknown): { code?: number; message?: string } | undefined {\n if (!result || typeof result !== 'object' || !('error' in result) || !result.error || typeof result.error !== 'object') return undefined\n const code = 'code' in result.error && typeof result.error.code === 'number' ? result.error.code : undefined\n const message = 'message' in result.error && typeof result.error.message === 'string' ? result.error.message : undefined\n return { ...(code === undefined ? {} : { code }), ...(message === undefined ? {} : { message }) }\n}\n\nfunction positiveInteger(value: number, name: string) {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${name} must be a positive integer`)\n return value\n}\n"]}
|
|
1
|
+
{"version":3,"file":"publisher.js","sourceRoot":"","sources":["../../src/realtime/publisher.ts"],"names":[],"mappings":"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","sourcesContent":["export type CentrifugoPublisherOptions = {\n apiUrl: string\n apiKey: string\n fetch?: typeof fetch\n timeoutMs?: number\n retryMs?: number\n maxRetries?: number\n maxConcurrentChannels?: number\n maxPendingChannels?: number\n onError: (error: unknown, channel: string) => void\n onRetry?: (error: unknown, channel: string) => void\n}\n\ntype PendingPublication = { dirty: boolean; data: unknown; running: boolean }\n\nexport class CentrifugoPublisher {\n private readonly pending = new Map<string, PendingPublication>()\n private readonly queue: string[] = []\n private readonly idleWaiters = new Set<() => void>()\n private readonly request: typeof fetch\n private readonly maxConcurrentChannels: number\n private readonly maxPendingChannels: number\n private active = 0\n private closed = false\n\n constructor(private readonly options: CentrifugoPublisherOptions) {\n this.request = options.fetch ?? fetch\n this.maxConcurrentChannels = positiveInteger(options.maxConcurrentChannels ?? 8, 'maxConcurrentChannels')\n this.maxPendingChannels = positiveInteger(options.maxPendingChannels ?? 1_024, 'maxPendingChannels')\n }\n\n publish(channel: string, data: unknown) {\n if (!this.options.apiUrl) return false\n if (this.closed) {\n this.reportError(new Error('Realtime publisher is closed'), channel)\n return false\n }\n const pending = this.pending.get(channel)\n if (pending) {\n pending.dirty = true\n pending.data = data\n return true\n }\n if (this.pending.size >= this.maxPendingChannels) {\n this.reportError(new Error('Realtime publisher queue is full'), channel)\n return false\n }\n\n const state = { dirty: true, data, running: false }\n this.pending.set(channel, state)\n this.queue.push(channel)\n this.pump()\n return true\n }\n\n idle() {\n if (this.isIdle()) return Promise.resolve()\n return new Promise<void>((resolve) => this.idleWaiters.add(resolve))\n }\n\n async close(options: { signal?: AbortSignal } = {}) {\n this.closed = true\n const idle = this.idle()\n if (!options.signal) return idle\n await abortable(idle, options.signal)\n }\n\n private pump() {\n while (this.active < this.maxConcurrentChannels) {\n const channel = this.queue.shift()\n if (!channel) break\n const state = this.pending.get(channel)\n if (!state || state.running) continue\n state.running = true\n this.active++\n void this.flush(channel, state).finally(() => {\n this.active--\n this.pump()\n this.resolveIdle()\n })\n }\n }\n\n private async flush(channel: string, state: PendingPublication) {\n let failure: unknown\n try {\n while (state.dirty) {\n state.dirty = false\n // Publications for one channel must preserve mutation order.\n // oxlint-disable-next-line no-await-in-loop\n await this.deliver(channel, state.data)\n }\n } catch (error) {\n failure = error\n } finally {\n if (this.pending.get(channel) === state) this.pending.delete(channel)\n }\n if (failure) {\n if (state.dirty) {\n this.pending.set(channel, { dirty: true, data: state.data, running: false })\n this.queue.push(channel)\n this.pump()\n }\n this.reportError(failure, channel)\n }\n }\n\n private async deliver(channel: string, data: unknown) {\n const maxRetries = this.options.maxRetries ?? 3\n for (let retries = 0; ; retries++) {\n try {\n // Retrying must finish before a later publication can overtake this one.\n // oxlint-disable-next-line no-await-in-loop\n await this.deliverOnce(channel, data)\n return\n } catch (error) {\n if (!(error instanceof TransientPublishError)) throw error\n if (retries >= maxRetries) throw error\n this.options.onRetry?.(error, channel)\n // oxlint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setTimeout(resolve, this.options.retryMs ?? 1_000))\n }\n }\n }\n\n private async deliverOnce(channel: string, data: unknown) {\n let response: Response\n try {\n response = await this.request(`${this.options.apiUrl.replace(/\\/$/, '')}/publish`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-API-Key': this.options.apiKey },\n body: JSON.stringify({ channel, data }),\n signal: AbortSignal.timeout(this.options.timeoutMs ?? 5_000),\n })\n } catch (error) {\n if (error instanceof TypeError || isTimeout(error))\n throw new TransientPublishError('Realtime publish request failed', { cause: error })\n throw error\n }\n\n if (!response.ok) {\n const message = `Realtime publish failed with status ${response.status}`\n if (response.status >= 500 || response.status === 429) throw new TransientPublishError(message)\n throw new Error(message)\n }\n\n const result: unknown = await response.json()\n const error = centrifugoError(result)\n if (!error) return\n const message = `Realtime publish failed: ${error.message ?? `code ${error.code ?? 'unknown'}`}`\n if (error.code === 100) throw new TransientPublishError(message)\n throw new Error(message)\n }\n\n private reportError(error: unknown, channel: string) {\n try {\n this.options.onError(error, channel)\n } catch {}\n }\n\n private isIdle() {\n return this.pending.size === 0 && this.active === 0 && this.queue.length === 0\n }\n\n private resolveIdle() {\n if (!this.isIdle()) return\n for (const resolve of this.idleWaiters) resolve()\n this.idleWaiters.clear()\n }\n}\n\nasync function abortable(work: Promise<void>, signal: AbortSignal) {\n signal.throwIfAborted()\n let abort!: () => void\n const aborted = new Promise<never>((_resolve, reject) => {\n abort = () => reject(signal.reason)\n signal.addEventListener('abort', abort, { once: true })\n })\n try {\n await Promise.race([work, aborted])\n } finally {\n signal.removeEventListener('abort', abort)\n }\n}\n\nclass TransientPublishError extends Error {}\n\nfunction isTimeout(error: unknown) {\n return error instanceof DOMException && error.name === 'TimeoutError'\n}\n\nfunction centrifugoError(result: unknown): { code?: number; message?: string } | undefined {\n if (!result || typeof result !== 'object' || !('error' in result) || !result.error || typeof result.error !== 'object') return undefined\n const code = 'code' in result.error && typeof result.error.code === 'number' ? result.error.code : undefined\n const message = 'message' in result.error && typeof result.error.message === 'string' ? result.error.message : undefined\n return { ...(code === undefined ? {} : { code }), ...(message === undefined ? {} : { message }) }\n}\n\nfunction positiveInteger(value: number, name: string) {\n if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${name} must be a positive integer`)\n return value\n}\n"]}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -57,3 +57,8 @@ export type CaddyRealtimeProxyOptions = {
|
|
|
57
57
|
encode?: boolean;
|
|
58
58
|
};
|
|
59
59
|
export declare function caddyRealtimeProxy(options?: CaddyRealtimeProxyOptions): string;
|
|
60
|
+
export type PersistedRealtimeSecretOptions = {
|
|
61
|
+
prefix?: string;
|
|
62
|
+
defaultFile?: string;
|
|
63
|
+
};
|
|
64
|
+
export declare function persistedRealtimeSecret(environment?: NodeJS.ProcessEnv, options?: PersistedRealtimeSecretOptions): string;
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { persistedSecret } from '../auth/secret.js';
|
|
4
5
|
export { runRealtimeDev } from './dev.js';
|
|
5
6
|
export async function superviseProcesses(processes, options = {}) {
|
|
6
7
|
return runSupervisor(processes, options);
|
|
@@ -238,4 +239,18 @@ function absolutePath(value, name) {
|
|
|
238
239
|
throw new Error(`${name} must be an absolute path`);
|
|
239
240
|
return value;
|
|
240
241
|
}
|
|
242
|
+
// The secret lands back in the environment so the supervised application inherits the value Centrifugo was given.
|
|
243
|
+
export function persistedRealtimeSecret(environment = process.env, options = {}) {
|
|
244
|
+
const prefix = options.prefix ?? '';
|
|
245
|
+
const file = environment[`${prefix}REALTIME_SECRET_FILE`]?.trim() || options.defaultFile || '/data/realtime-secret';
|
|
246
|
+
const secret = persistedSecret({
|
|
247
|
+
directory: path.dirname(file),
|
|
248
|
+
filename: path.basename(file),
|
|
249
|
+
environment,
|
|
250
|
+
environmentKey: `${prefix}REALTIME_SECRET`,
|
|
251
|
+
bytes: 48,
|
|
252
|
+
});
|
|
253
|
+
environment[`${prefix}REALTIME_SECRET`] = secret;
|
|
254
|
+
return secret;
|
|
255
|
+
}
|
|
241
256
|
//# sourceMappingURL=index.js.map
|