deepline 0.1.119 → 0.1.121

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.
Files changed (148) hide show
  1. package/README.md +4 -0
  2. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +21 -0
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/batching.ts +185 -0
  4. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-batch.ts +107 -0
  5. package/dist/{repo → bundling-sources}/sdk/src/client.ts +116 -12
  6. package/dist/bundling-sources/sdk/src/compat.ts +191 -0
  7. package/dist/bundling-sources/sdk/src/gtm.ts +146 -0
  8. package/dist/bundling-sources/sdk/src/helpers.ts +12 -0
  9. package/dist/{repo → bundling-sources}/sdk/src/index.ts +2 -1
  10. package/dist/{repo → bundling-sources}/sdk/src/play.ts +3 -1
  11. package/dist/{repo → bundling-sources}/sdk/src/plays/bundle-play-file.ts +17 -5
  12. package/dist/{repo → bundling-sources}/sdk/src/release.ts +2 -2
  13. package/dist/{repo → bundling-sources}/sdk/src/runs/observe-transport.ts +2 -3
  14. package/dist/bundling-sources/shared_libs/play-data-plane/index.ts +3 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +838 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +5510 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +261 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +828 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts +10 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/daytona-runtime-config.ts +50 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/durability-store.ts +20 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/event-wait-tools.ts +9 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +171 -0
  24. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-diagnosis.ts +321 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-target.ts +158 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/internal-step-ids.ts +34 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +34 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/live-state-contract.ts +50 -0
  29. package/dist/bundling-sources/shared_libs/play-runtime/map-execution-frame.ts +119 -0
  30. package/dist/{repo → bundling-sources}/shared_libs/play-runtime/map-row-identity.ts +1 -1
  31. package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +636 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/postgres-json.ts +9 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/progress-emitter.ts +197 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/projection.ts +262 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +143 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/public-play-contract.ts +42 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +40 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +178 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +4015 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constraints.ts +2 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +238 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts +53 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts +149 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/suspension.ts +68 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/tool-batch-executor.ts +149 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/tool-result-types.ts +159 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/tracing.ts +33 -0
  48. package/dist/bundling-sources/shared_libs/play-runtime/waterfall-replay.ts +79 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +139 -0
  50. package/dist/bundling-sources/shared_libs/plays/artifact-transport.ts +14 -0
  51. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +49 -0
  52. package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +41 -0
  53. package/dist/bundling-sources/shared_libs/plays/dataset-summary.ts +163 -0
  54. package/dist/bundling-sources/shared_libs/plays/definition.ts +267 -0
  55. package/dist/bundling-sources/shared_libs/plays/file-refs.ts +11 -0
  56. package/dist/bundling-sources/shared_libs/plays/input-contract.ts +146 -0
  57. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +190 -0
  58. package/dist/bundling-sources/shared_libs/plays/runtime-validation.ts +417 -0
  59. package/dist/bundling-sources/shared_libs/plays/tool-codegen.ts +142 -0
  60. package/dist/bundling-sources/shared_libs/security/safe-outbound-fetch.ts +274 -0
  61. package/dist/bundling-sources/shared_libs/temporal/preview-config.ts +150 -0
  62. package/dist/cli/index.js +811 -2207
  63. package/dist/cli/index.mjs +847 -2258
  64. package/dist/compiler-manifest-BjoRENv9.d.mts +227 -0
  65. package/dist/compiler-manifest-BjoRENv9.d.ts +227 -0
  66. package/dist/index.d.mts +8 -231
  67. package/dist/index.d.ts +8 -231
  68. package/dist/index.js +101 -15
  69. package/dist/index.mjs +101 -15
  70. package/dist/plays/bundle-play-file.d.mts +120 -0
  71. package/dist/plays/bundle-play-file.d.ts +120 -0
  72. package/dist/plays/bundle-play-file.mjs +1830 -0
  73. package/package.json +4 -9
  74. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-await.ts +0 -0
  75. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/child-play-submit.ts +0 -0
  76. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/coordinator-entry.ts +0 -0
  77. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/dedup-do.ts +0 -0
  78. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/entry.ts +0 -0
  79. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/csv-rows.ts +0 -0
  80. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/dataset-handles.ts +0 -0
  81. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +0 -0
  82. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/live-progress.ts +0 -0
  83. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/map-chunk-plan.ts +0 -0
  84. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/receipts.ts +0 -0
  85. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/row-isolation.ts +0 -0
  86. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/runtime/tool-http-errors.ts +0 -0
  87. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-instance-create.ts +0 -0
  88. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry-state.ts +0 -0
  89. /package/dist/{repo → bundling-sources}/apps/play-runner-workers/src/workflow-retry.ts +0 -0
  90. /package/dist/{repo → bundling-sources}/sdk/src/agent-runtime.ts +0 -0
  91. /package/dist/{repo → bundling-sources}/sdk/src/config.ts +0 -0
  92. /package/dist/{repo → bundling-sources}/sdk/src/errors.ts +0 -0
  93. /package/dist/{repo → bundling-sources}/sdk/src/http.ts +0 -0
  94. /package/dist/{repo → bundling-sources}/sdk/src/plays/harness-stub.ts +0 -0
  95. /package/dist/{repo → bundling-sources}/sdk/src/plays/local-file-discovery.ts +0 -0
  96. /package/dist/{repo → bundling-sources}/sdk/src/stream-reconnect.ts +0 -0
  97. /package/dist/{repo → bundling-sources}/sdk/src/tool-output.ts +0 -0
  98. /package/dist/{repo → bundling-sources}/sdk/src/types.ts +0 -0
  99. /package/dist/{repo → bundling-sources}/sdk/src/version.ts +0 -0
  100. /package/dist/{repo → bundling-sources}/sdk/src/worker-play-entry.ts +0 -0
  101. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/cell-policy.ts +0 -0
  102. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/column-names.ts +0 -0
  103. /package/dist/{repo → bundling-sources}/shared_libs/play-data-plane/sheet-contract.ts +0 -0
  104. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/backend.ts +0 -0
  105. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batch-runtime.ts +0 -0
  106. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/batching-types.ts +0 -0
  107. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/cell-staleness.ts +0 -0
  108. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/coordinator-headers.ts +0 -0
  109. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/csv-rename.ts +0 -0
  110. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-crypto.ts +0 -0
  111. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session-plan.ts +0 -0
  112. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/db-session.ts +0 -0
  113. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/dedup-backend.ts +0 -0
  114. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/default-batch-strategies.ts +0 -0
  115. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/email-status.ts +0 -0
  116. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/execution-plan.ts +0 -0
  117. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/extractor-targets.ts +0 -0
  118. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/fullenrich-batching.ts +0 -0
  119. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/coordinator-rate-state-backend.ts +0 -0
  120. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/governor.ts +0 -0
  121. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/policy.ts +0 -0
  122. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/governor/rate-state-backend.ts +0 -0
  123. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/live-events.ts +0 -0
  124. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/play-runtime-batching-registry.ts +0 -0
  125. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/profiles.ts +0 -0
  126. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/providers.ts +0 -0
  127. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-failure.ts +0 -0
  128. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-ledger.ts +0 -0
  129. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/run-snapshot-stream.ts +0 -0
  130. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/scheduler-backend.ts +0 -0
  131. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-capability.ts +0 -0
  132. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/secret-redaction.ts +0 -0
  133. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-lifecycle-tracker.ts +0 -0
  134. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/step-program-dataset-builder.ts +0 -0
  135. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/submit-limits.ts +0 -0
  136. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/tool-result.ts +0 -0
  137. /package/dist/{repo → bundling-sources}/shared_libs/play-runtime/work-receipts.ts +0 -0
  138. /package/dist/{repo → bundling-sources}/shared_libs/plays/bootstrap-routes.ts +0 -0
  139. /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/index.ts +0 -0
  140. /package/dist/{repo → bundling-sources}/shared_libs/plays/bundling/limits.ts +0 -0
  141. /package/dist/{repo → bundling-sources}/shared_libs/plays/contracts.ts +0 -0
  142. /package/dist/{repo → bundling-sources}/shared_libs/plays/dataset.ts +0 -0
  143. /package/dist/{repo → bundling-sources}/shared_libs/plays/row-identity.ts +0 -0
  144. /package/dist/{repo → bundling-sources}/shared_libs/plays/secret-guardrails.ts +0 -0
  145. /package/dist/{repo → bundling-sources}/shared_libs/plays/static-pipeline.ts +0 -0
  146. /package/dist/{repo → bundling-sources}/shared_libs/security/outbound-url-policy.ts +0 -0
  147. /package/dist/{repo → bundling-sources}/shared_libs/security/safe-fetch.ts +0 -0
  148. /package/dist/{repo → bundling-sources}/shared_libs/temporal/constants.ts +0 -0
@@ -0,0 +1,274 @@
1
+ import dns from 'node:dns';
2
+ import http from 'node:http';
3
+ import https from 'node:https';
4
+ import type { LookupFunction } from 'node:net';
5
+ import {
6
+ assertPublicHttpUrl,
7
+ isBlockedIpAddress,
8
+ isRedirectStatus,
9
+ normalizeUrlHostname,
10
+ resolveRedirectUrl,
11
+ UnsafeOutboundUrlError,
12
+ } from '@shared_libs/security/outbound-url-policy';
13
+
14
+ type NodeSafeFetchOptions = {
15
+ maxRedirects?: number;
16
+ sensitiveHeaders?: Iterable<string>;
17
+ };
18
+
19
+ type PreparedBody = {
20
+ body: Buffer | string | undefined;
21
+ headers: Headers;
22
+ };
23
+
24
+ export { UnsafeOutboundUrlError };
25
+
26
+ function cloneHeaders(headers: RequestInit['headers']): Headers {
27
+ return new Headers(headers);
28
+ }
29
+
30
+ function deleteHeader(headers: Headers, name: string) {
31
+ if (headers.has(name)) headers.delete(name);
32
+ }
33
+
34
+ async function prepareBody(init: RequestInit): Promise<PreparedBody> {
35
+ const headers = cloneHeaders(init.headers);
36
+ const body = init.body;
37
+ if (body === undefined || body === null) {
38
+ return { body: undefined, headers };
39
+ }
40
+ if (typeof body === 'string') {
41
+ return { body, headers };
42
+ }
43
+ if (body instanceof URLSearchParams) {
44
+ if (!headers.has('content-type')) {
45
+ headers.set(
46
+ 'content-type',
47
+ 'application/x-www-form-urlencoded;charset=UTF-8',
48
+ );
49
+ }
50
+ return { body: body.toString(), headers };
51
+ }
52
+ if (body instanceof ArrayBuffer) {
53
+ return { body: Buffer.from(body), headers };
54
+ }
55
+ if (ArrayBuffer.isView(body)) {
56
+ return {
57
+ body: Buffer.from(body.buffer, body.byteOffset, body.byteLength),
58
+ headers,
59
+ };
60
+ }
61
+ if (typeof Blob !== 'undefined' && body instanceof Blob) {
62
+ return { body: Buffer.from(await body.arrayBuffer()), headers };
63
+ }
64
+
65
+ throw new TypeError(
66
+ 'safeOutboundFetch does not support streaming or multipart request bodies.',
67
+ );
68
+ }
69
+
70
+ function headersToRecord(headers: Headers): Record<string, string> {
71
+ return Object.fromEntries(headers.entries());
72
+ }
73
+
74
+ function validateResolvedAddress(address: string) {
75
+ if (isBlockedIpAddress(address)) {
76
+ throw new UnsafeOutboundUrlError(
77
+ `Resolved address "${address}" is not allowed.`,
78
+ );
79
+ }
80
+ }
81
+
82
+ const safeLookup: LookupFunction = (hostname, options, callback) => {
83
+ const lookupOptions: dns.LookupAllOptions = {
84
+ all: true,
85
+ verbatim: true,
86
+ ...(typeof options.family === 'number' ? { family: options.family } : {}),
87
+ ...(typeof options.hints === 'number' ? { hints: options.hints } : {}),
88
+ };
89
+ dns.lookup(hostname, lookupOptions, (error, records) => {
90
+ if (error) {
91
+ callback(error, '', 0);
92
+ return;
93
+ }
94
+ if (!records.length) {
95
+ callback(
96
+ Object.assign(new Error(`Could not resolve host "${hostname}".`), {
97
+ code: 'ENOTFOUND',
98
+ }) as NodeJS.ErrnoException,
99
+ '',
100
+ 0,
101
+ );
102
+ return;
103
+ }
104
+
105
+ try {
106
+ for (const record of records) {
107
+ validateResolvedAddress(record.address);
108
+ }
109
+ } catch (validationError) {
110
+ callback(validationError as NodeJS.ErrnoException, '', 0);
111
+ return;
112
+ }
113
+
114
+ if (options.all) {
115
+ callback(null, records);
116
+ return;
117
+ }
118
+
119
+ callback(null, records[0]!.address, records[0]!.family);
120
+ });
121
+ };
122
+
123
+ function createRequest(
124
+ url: URL,
125
+ init: RequestInit,
126
+ prepared: PreparedBody,
127
+ ): Promise<Response> {
128
+ return new Promise((resolve, reject) => {
129
+ const transport = url.protocol === 'https:' ? https : http;
130
+ const request = transport.request(
131
+ url,
132
+ {
133
+ method: init.method ?? 'GET',
134
+ headers: headersToRecord(prepared.headers),
135
+ agent: false,
136
+ lookup: safeLookup,
137
+ signal: init.signal ?? undefined,
138
+ },
139
+ (response) => {
140
+ const chunks: Buffer[] = [];
141
+ response.on('data', (chunk) => {
142
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
143
+ });
144
+ response.on('error', reject);
145
+ response.on('end', () => {
146
+ resolve(
147
+ new Response(Buffer.concat(chunks), {
148
+ status: response.statusCode ?? 0,
149
+ statusText: response.statusMessage,
150
+ headers: response.headers as HeadersInit,
151
+ }),
152
+ );
153
+ });
154
+ },
155
+ );
156
+
157
+ request.on('error', reject);
158
+ if (prepared.body !== undefined) {
159
+ request.write(prepared.body);
160
+ }
161
+ request.end();
162
+ });
163
+ }
164
+
165
+ function initForRedirect(
166
+ init: RequestInit,
167
+ from: URL,
168
+ to: URL,
169
+ status: number,
170
+ sensitiveHeaders: Iterable<string>,
171
+ ): RequestInit {
172
+ const headers = cloneHeaders(init.headers);
173
+ let method = String(init.method ?? 'GET').toUpperCase();
174
+ let body = init.body;
175
+
176
+ if (
177
+ status === 303 ||
178
+ ((status === 301 || status === 302) && method === 'POST')
179
+ ) {
180
+ method = 'GET';
181
+ body = undefined;
182
+ deleteHeader(headers, 'content-length');
183
+ deleteHeader(headers, 'content-type');
184
+ }
185
+
186
+ if (from.origin !== to.origin) {
187
+ deleteHeader(headers, 'authorization');
188
+ deleteHeader(headers, 'cookie');
189
+ deleteHeader(headers, 'proxy-authorization');
190
+ for (const header of sensitiveHeaders) {
191
+ deleteHeader(headers, header);
192
+ }
193
+ }
194
+
195
+ return {
196
+ ...init,
197
+ method,
198
+ body,
199
+ headers,
200
+ redirect: 'manual',
201
+ };
202
+ }
203
+
204
+ export async function safeOutboundFetch(
205
+ input: string | URL,
206
+ init: RequestInit = {},
207
+ options: NodeSafeFetchOptions = {},
208
+ ): Promise<Response> {
209
+ const redirectMode = init.redirect ?? 'follow';
210
+ const maxRedirects = options.maxRedirects ?? 10;
211
+ const sensitiveHeaders = options.sensitiveHeaders ?? [];
212
+ let currentUrl = assertPublicHttpUrl(input);
213
+ let currentInit: RequestInit = { ...init, redirect: 'manual' };
214
+
215
+ for (
216
+ let redirectCount = 0;
217
+ redirectCount <= maxRedirects;
218
+ redirectCount += 1
219
+ ) {
220
+ const hostname = normalizeUrlHostname(currentUrl.hostname);
221
+ if (isBlockedIpAddress(hostname)) {
222
+ throw new UnsafeOutboundUrlError(
223
+ `Target host "${hostname}" is not allowed.`,
224
+ );
225
+ }
226
+
227
+ const response = await createRequest(
228
+ currentUrl,
229
+ currentInit,
230
+ await prepareBody(currentInit),
231
+ );
232
+
233
+ Object.defineProperty(response, 'url', {
234
+ configurable: true,
235
+ value: currentUrl.toString(),
236
+ });
237
+
238
+ if (!isRedirectStatus(response.status)) {
239
+ return response;
240
+ }
241
+ if (redirectMode === 'error') {
242
+ throw new Error(
243
+ `Redirect blocked while fetching ${currentUrl.toString()}.`,
244
+ );
245
+ }
246
+ if (redirectMode !== 'follow') {
247
+ return response;
248
+ }
249
+
250
+ const location = response.headers.get('location');
251
+ if (!location) {
252
+ return response;
253
+ }
254
+ if (redirectCount === maxRedirects) {
255
+ throw new Error(
256
+ `Too many redirects while fetching ${currentUrl.toString()}.`,
257
+ );
258
+ }
259
+
260
+ const nextUrl = resolveRedirectUrl(location, currentUrl);
261
+ currentInit = initForRedirect(
262
+ currentInit,
263
+ currentUrl,
264
+ nextUrl,
265
+ response.status,
266
+ sensitiveHeaders,
267
+ );
268
+ currentUrl = nextUrl;
269
+ }
270
+
271
+ throw new Error(
272
+ `Too many redirects while fetching ${currentUrl.toString()}.`,
273
+ );
274
+ }
@@ -0,0 +1,150 @@
1
+ import { existsSync } from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import * as dotenv from 'dotenv';
4
+ import { LOCAL_TEMPORAL_ADDRESS, LOCAL_TEMPORAL_NAMESPACE } from './constants';
5
+
6
+ export const PLAY_TASK_QUEUE = 'deepline-plays';
7
+ // Internal process flag set by `bun run dev:v2 --preview`. Do not put this in
8
+ // .env.local; the dev command owns the mode selection so local/preview runs are
9
+ // obvious at the call site.
10
+ export const DEEPLINE_V2_INFRA_MODE_ENV = 'DEEPLINE_V2_INFRA_MODE';
11
+ export const PREVIEW_PLAYS_ENV_FILE = '.env.plays.preview';
12
+
13
+ type TemporalTlsConfig = {
14
+ clientCertPair: {
15
+ crt: Uint8Array;
16
+ key: Uint8Array;
17
+ };
18
+ };
19
+
20
+ export type DeeplineTemporalConfig = {
21
+ address: string;
22
+ namespace: string;
23
+ taskQueue: string;
24
+ tls?: TemporalTlsConfig;
25
+ deployment: 'local' | 'preview';
26
+ };
27
+
28
+ let loadedPreviewEnv = false;
29
+
30
+ function decodePemEnv(value: string): Uint8Array {
31
+ return Buffer.from(value.replace(/\\n/g, '\n'), 'utf-8');
32
+ }
33
+
34
+ export function isPreviewPlaysDeployment(): boolean {
35
+ const mode = process.env[DEEPLINE_V2_INFRA_MODE_ENV]?.trim().toLowerCase();
36
+ return mode === 'external' || mode === 'preview';
37
+ }
38
+
39
+ export function isCloudflarePlaysDeployment(): boolean {
40
+ const mode = process.env[DEEPLINE_V2_INFRA_MODE_ENV]?.trim().toLowerCase();
41
+ return mode === 'cloudflare';
42
+ }
43
+
44
+ /**
45
+ * True when the play runtime callback baseUrl must be a public URL — i.e. when
46
+ * the plays runner runs outside the local app process and can't reach
47
+ * 127.0.0.1. Both `external` (Daytona) and `cloudflare` (Workers/DOs) need
48
+ * this; only fully-local mode can keep baseUrl on localhost.
49
+ */
50
+ export function requiresPublicCallbackBaseUrl(): boolean {
51
+ return isPreviewPlaysDeployment() || isCloudflarePlaysDeployment();
52
+ }
53
+
54
+ export function loadPreviewPlaysEnv(cwd = process.cwd()): void {
55
+ if (loadedPreviewEnv || !isPreviewPlaysDeployment()) {
56
+ return;
57
+ }
58
+
59
+ const envPath = path.join(cwd, PREVIEW_PLAYS_ENV_FILE);
60
+ if (existsSync(envPath)) {
61
+ dotenv.config({ path: envPath, override: true });
62
+ }
63
+
64
+ loadedPreviewEnv = true;
65
+ }
66
+
67
+ function temporalTlsFromEnv(): TemporalTlsConfig | undefined {
68
+ const cert =
69
+ process.env.TEMPORAL_TLS_CERT_DATA ?? process.env.FAS_TEMPORAL_CERT_DATA;
70
+ const key =
71
+ process.env.TEMPORAL_TLS_KEY_DATA ?? process.env.FAS_TEMPORAL_KEY_DATA;
72
+
73
+ if (!cert && !key) {
74
+ return undefined;
75
+ }
76
+ if (!cert || !key) {
77
+ throw new Error(
78
+ 'Temporal Cloud mTLS requires both TEMPORAL_TLS_CERT_DATA and TEMPORAL_TLS_KEY_DATA.',
79
+ );
80
+ }
81
+
82
+ return {
83
+ clientCertPair: {
84
+ crt: decodePemEnv(cert),
85
+ key: decodePemEnv(key),
86
+ },
87
+ };
88
+ }
89
+
90
+ function temporalAddressFromEnv(): string | undefined {
91
+ return (
92
+ process.env.TEMPORAL_ADDRESS?.trim() ||
93
+ process.env.FAS_TEMPORAL_ADDRESS?.trim() ||
94
+ undefined
95
+ );
96
+ }
97
+
98
+ function temporalNamespaceFromEnv(address: string): string | undefined {
99
+ const previewConfigured = process.env.FAS_TEMPORAL_NAMESPACE?.trim();
100
+ if (previewConfigured) {
101
+ return previewConfigured;
102
+ }
103
+
104
+ const host = address.split(':')[0] ?? '';
105
+ const temporalCloudNamespace = /^([^.]+\.[^.]+)\.tmprl\.cloud$/i.exec(host);
106
+ if (temporalCloudNamespace?.[1]) {
107
+ return temporalCloudNamespace[1];
108
+ }
109
+
110
+ const configured = process.env.TEMPORAL_NAMESPACE?.trim();
111
+ return configured || undefined;
112
+ }
113
+
114
+ export function getDeeplineTemporalConfig(options?: {
115
+ loadPreviewEnv?: boolean;
116
+ }): DeeplineTemporalConfig {
117
+ if (options?.loadPreviewEnv !== false) {
118
+ loadPreviewPlaysEnv();
119
+ }
120
+
121
+ if (isPreviewPlaysDeployment()) {
122
+ const address = temporalAddressFromEnv();
123
+ const namespace = address ? temporalNamespaceFromEnv(address) : undefined;
124
+ if (!address) {
125
+ throw new Error(
126
+ 'dev:v2 preview mode requires TEMPORAL_ADDRESS or FAS_TEMPORAL_ADDRESS.',
127
+ );
128
+ }
129
+ if (!namespace) {
130
+ throw new Error(
131
+ 'dev:v2 preview mode requires TEMPORAL_NAMESPACE or FAS_TEMPORAL_NAMESPACE.',
132
+ );
133
+ }
134
+ return {
135
+ address,
136
+ namespace,
137
+ taskQueue: process.env.TEMPORAL_TASK_QUEUE?.trim() || PLAY_TASK_QUEUE,
138
+ tls: temporalTlsFromEnv(),
139
+ deployment: 'preview',
140
+ };
141
+ }
142
+
143
+ return {
144
+ address: process.env.TEMPORAL_ADDRESS ?? LOCAL_TEMPORAL_ADDRESS,
145
+ namespace: process.env.TEMPORAL_NAMESPACE ?? LOCAL_TEMPORAL_NAMESPACE,
146
+ taskQueue: process.env.TEMPORAL_TASK_QUEUE?.trim() || PLAY_TASK_QUEUE,
147
+ tls: temporalTlsFromEnv(),
148
+ deployment: 'local',
149
+ };
150
+ }