deepline 0.1.31 → 0.1.33
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 +33 -20
- package/dist/cli/index.js +169 -188
- package/dist/cli/index.mjs +180 -199
- package/dist/index.d.mts +6 -24
- package/dist/index.d.ts +6 -24
- package/dist/index.js +55 -81
- package/dist/index.mjs +56 -82
- package/dist/repo/sdk/src/config.ts +109 -233
- package/dist/repo/sdk/src/types.ts +3 -1
- package/dist/repo/sdk/src/version.ts +2 -2
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -186,7 +186,7 @@ type PlayCompilerManifest = {
|
|
|
186
186
|
interface DeeplineClientOptions {
|
|
187
187
|
/** API key. Overrides `DEEPLINE_API_KEY` env var and CLI-stored keys. */
|
|
188
188
|
apiKey?: string;
|
|
189
|
-
/** Base URL of the Deepline API. Overrides `
|
|
189
|
+
/** Base URL of the Deepline API. Overrides `DEEPLINE_HOST_URL`. */
|
|
190
190
|
baseUrl?: string;
|
|
191
191
|
/** Per-request timeout in milliseconds. Default: `60_000` (60 seconds). */
|
|
192
192
|
timeout?: number;
|
|
@@ -393,6 +393,8 @@ interface PlayStatus {
|
|
|
393
393
|
name?: string;
|
|
394
394
|
/** Alias for `name` used by run/result APIs. */
|
|
395
395
|
playName?: string;
|
|
396
|
+
/** Dashboard URL for inspecting the play and its run output in the app. */
|
|
397
|
+
dashboardUrl?: string;
|
|
396
398
|
/** Product-level play-run state. */
|
|
397
399
|
status: 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
|
|
398
400
|
/** Execution progress with logs and error details. */
|
|
@@ -1438,8 +1440,8 @@ declare class DeeplineClient {
|
|
|
1438
1440
|
}>;
|
|
1439
1441
|
}
|
|
1440
1442
|
|
|
1441
|
-
declare const SDK_VERSION = "0.1.
|
|
1442
|
-
declare const SDK_API_CONTRACT = "2026-05-
|
|
1443
|
+
declare const SDK_VERSION = "0.1.33";
|
|
1444
|
+
declare const SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
|
|
1443
1445
|
|
|
1444
1446
|
/**
|
|
1445
1447
|
* Base error class for all Deepline SDK errors.
|
|
@@ -1557,27 +1559,7 @@ declare class ConfigError extends DeeplineError {
|
|
|
1557
1559
|
/** Production API base URL. */
|
|
1558
1560
|
declare const PROD_URL = "https://code.deepline.com";
|
|
1559
1561
|
/**
|
|
1560
|
-
* Resolve SDK configuration from
|
|
1561
|
-
*
|
|
1562
|
-
* Merges explicit options, environment variables, and CLI-managed config files
|
|
1563
|
-
* into a fully validated {@link ResolvedConfig}. See the module-level docs for
|
|
1564
|
-
* the complete resolution order.
|
|
1565
|
-
*
|
|
1566
|
-
* @param options - Optional overrides (highest priority)
|
|
1567
|
-
* @returns Fully resolved configuration with all fields populated
|
|
1568
|
-
* @throws {@link ConfigError} if no API key can be found from any source
|
|
1569
|
-
*
|
|
1570
|
-
* @example
|
|
1571
|
-
* ```typescript
|
|
1572
|
-
* import { resolveConfig } from 'deepline';
|
|
1573
|
-
*
|
|
1574
|
-
* // Auto-resolve everything:
|
|
1575
|
-
* const config = resolveConfig();
|
|
1576
|
-
* console.log(config.baseUrl); // "http://localhost:3000" or "https://code.deepline.com"
|
|
1577
|
-
*
|
|
1578
|
-
* // Override specific values:
|
|
1579
|
-
* const config2 = resolveConfig({ baseUrl: 'http://localhost:4000', timeout: 10_000 });
|
|
1580
|
-
* ```
|
|
1562
|
+
* Resolve SDK configuration from the public SDK CLI env contract.
|
|
1581
1563
|
*/
|
|
1582
1564
|
declare function resolveConfig(options?: DeeplineClientOptions): ResolvedConfig;
|
|
1583
1565
|
|
package/dist/index.d.ts
CHANGED
|
@@ -186,7 +186,7 @@ type PlayCompilerManifest = {
|
|
|
186
186
|
interface DeeplineClientOptions {
|
|
187
187
|
/** API key. Overrides `DEEPLINE_API_KEY` env var and CLI-stored keys. */
|
|
188
188
|
apiKey?: string;
|
|
189
|
-
/** Base URL of the Deepline API. Overrides `
|
|
189
|
+
/** Base URL of the Deepline API. Overrides `DEEPLINE_HOST_URL`. */
|
|
190
190
|
baseUrl?: string;
|
|
191
191
|
/** Per-request timeout in milliseconds. Default: `60_000` (60 seconds). */
|
|
192
192
|
timeout?: number;
|
|
@@ -393,6 +393,8 @@ interface PlayStatus {
|
|
|
393
393
|
name?: string;
|
|
394
394
|
/** Alias for `name` used by run/result APIs. */
|
|
395
395
|
playName?: string;
|
|
396
|
+
/** Dashboard URL for inspecting the play and its run output in the app. */
|
|
397
|
+
dashboardUrl?: string;
|
|
396
398
|
/** Product-level play-run state. */
|
|
397
399
|
status: 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled';
|
|
398
400
|
/** Execution progress with logs and error details. */
|
|
@@ -1438,8 +1440,8 @@ declare class DeeplineClient {
|
|
|
1438
1440
|
}>;
|
|
1439
1441
|
}
|
|
1440
1442
|
|
|
1441
|
-
declare const SDK_VERSION = "0.1.
|
|
1442
|
-
declare const SDK_API_CONTRACT = "2026-05-
|
|
1443
|
+
declare const SDK_VERSION = "0.1.33";
|
|
1444
|
+
declare const SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
|
|
1443
1445
|
|
|
1444
1446
|
/**
|
|
1445
1447
|
* Base error class for all Deepline SDK errors.
|
|
@@ -1557,27 +1559,7 @@ declare class ConfigError extends DeeplineError {
|
|
|
1557
1559
|
/** Production API base URL. */
|
|
1558
1560
|
declare const PROD_URL = "https://code.deepline.com";
|
|
1559
1561
|
/**
|
|
1560
|
-
* Resolve SDK configuration from
|
|
1561
|
-
*
|
|
1562
|
-
* Merges explicit options, environment variables, and CLI-managed config files
|
|
1563
|
-
* into a fully validated {@link ResolvedConfig}. See the module-level docs for
|
|
1564
|
-
* the complete resolution order.
|
|
1565
|
-
*
|
|
1566
|
-
* @param options - Optional overrides (highest priority)
|
|
1567
|
-
* @returns Fully resolved configuration with all fields populated
|
|
1568
|
-
* @throws {@link ConfigError} if no API key can be found from any source
|
|
1569
|
-
*
|
|
1570
|
-
* @example
|
|
1571
|
-
* ```typescript
|
|
1572
|
-
* import { resolveConfig } from 'deepline';
|
|
1573
|
-
*
|
|
1574
|
-
* // Auto-resolve everything:
|
|
1575
|
-
* const config = resolveConfig();
|
|
1576
|
-
* console.log(config.baseUrl); // "http://localhost:3000" or "https://code.deepline.com"
|
|
1577
|
-
*
|
|
1578
|
-
* // Override specific values:
|
|
1579
|
-
* const config2 = resolveConfig({ baseUrl: 'http://localhost:4000', timeout: 10_000 });
|
|
1580
|
-
* ```
|
|
1562
|
+
* Resolve SDK configuration from the public SDK CLI env contract.
|
|
1581
1563
|
*/
|
|
1582
1564
|
declare function resolveConfig(options?: DeeplineClientOptions): ResolvedConfig;
|
|
1583
1565
|
|
package/dist/index.js
CHANGED
|
@@ -85,13 +85,12 @@ var ConfigError = class extends DeeplineError {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
// src/config.ts
|
|
88
|
+
var HOST_URL_ENV = "DEEPLINE_HOST_URL";
|
|
89
|
+
var API_KEY_ENV = "DEEPLINE_API_KEY";
|
|
88
90
|
var PROD_URL = "https://code.deepline.com";
|
|
89
91
|
var DEFAULT_TIMEOUT = 6e4;
|
|
90
92
|
var DEFAULT_MAX_RETRIES = 3;
|
|
91
|
-
var
|
|
92
|
-
function projectEnvStartDir() {
|
|
93
|
-
return process.env.DEEPLINE_PROJECT_ENV_DIR?.trim() || process.cwd();
|
|
94
|
-
}
|
|
93
|
+
var PROJECT_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
95
94
|
function baseUrlSlug(baseUrl) {
|
|
96
95
|
let url;
|
|
97
96
|
try {
|
|
@@ -100,7 +99,7 @@ function baseUrlSlug(baseUrl) {
|
|
|
100
99
|
return "unknown";
|
|
101
100
|
}
|
|
102
101
|
const host = url.hostname || "unknown";
|
|
103
|
-
const port = url.port ? parseInt(url.port, 10) : null;
|
|
102
|
+
const port = url.port ? Number.parseInt(url.port, 10) : null;
|
|
104
103
|
let slug = host.replace(/[^a-zA-Z0-9]/g, "-");
|
|
105
104
|
if (port && port !== 80 && port !== 443) {
|
|
106
105
|
slug = `${slug}-${port}`;
|
|
@@ -127,109 +126,84 @@ function parseEnvFile(filePath) {
|
|
|
127
126
|
}
|
|
128
127
|
return env;
|
|
129
128
|
}
|
|
130
|
-
function findNearestEnvFile(
|
|
129
|
+
function findNearestEnvFile(name, startDir = process.cwd()) {
|
|
131
130
|
let current = (0, import_node_path.resolve)(startDir);
|
|
132
131
|
while (true) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if ((0, import_node_fs.existsSync)(filePath)) return filePath;
|
|
136
|
-
}
|
|
132
|
+
const filePath = (0, import_node_path.join)(current, name);
|
|
133
|
+
if ((0, import_node_fs.existsSync)(filePath)) return filePath;
|
|
137
134
|
const parent = (0, import_node_path.dirname)(current);
|
|
138
135
|
if (parent === current) return null;
|
|
139
136
|
current = parent;
|
|
140
137
|
}
|
|
141
138
|
}
|
|
142
|
-
function
|
|
143
|
-
const filePath = findNearestEnvFile(
|
|
139
|
+
function loadProjectDeeplineEnv(startDir = process.cwd()) {
|
|
140
|
+
const filePath = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
144
141
|
return filePath ? parseEnvFile(filePath) : {};
|
|
145
142
|
}
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
function resolveProfileEnvFileNames() {
|
|
150
|
-
const explicitProfile = process.env.DEEPLINE_ENV_PROFILE?.trim() || process.env.DEEPLINE_PROFILE?.trim() || "";
|
|
151
|
-
const names = [];
|
|
152
|
-
if (explicitProfile) names.push(`.env.deepline.${explicitProfile}`);
|
|
153
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
154
|
-
if (nodeEnv === "production") names.push(".env.deepline.prod");
|
|
155
|
-
else if (nodeEnv === "staging") names.push(".env.deepline.staging");
|
|
156
|
-
names.push(ACTIVE_DEEPLINE_ENV_FILE);
|
|
157
|
-
return names;
|
|
158
|
-
}
|
|
159
|
-
function resolveProjectAppEnvFileNames() {
|
|
160
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
161
|
-
const names = [];
|
|
162
|
-
if (nodeEnv === "production") names.push(".env.prod");
|
|
163
|
-
if (nodeEnv === "staging") names.push(".env.staging");
|
|
164
|
-
names.push(".env.local", ".env");
|
|
165
|
-
return names;
|
|
166
|
-
}
|
|
167
|
-
function resolveBaseUrlFromEnvValues(env) {
|
|
168
|
-
return env.DEEPLINE_ORIGIN_URL?.trim() || env.DEEPLINE_API_BASE_URL?.trim() || "";
|
|
169
|
-
}
|
|
170
|
-
function loadProjectDeeplineEnv() {
|
|
171
|
-
return findNearestEnv(resolveProfileEnvFileNames(), projectEnvStartDir());
|
|
172
|
-
}
|
|
173
|
-
function loadProjectAppEnv() {
|
|
174
|
-
return findNearestEnv(resolveProjectAppEnvFileNames(), projectEnvStartDir());
|
|
175
|
-
}
|
|
176
|
-
function normalizeWorktreeBaseUrl(baseUrl, worktreeEnv = findNearestWorktreeEnv()) {
|
|
177
|
-
const trimmed = baseUrl.trim().replace(/\/$/, "");
|
|
178
|
-
if (!trimmed) return trimmed;
|
|
143
|
+
function normalizeBaseUrl(baseUrl) {
|
|
144
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
145
|
+
if (!trimmed) return "";
|
|
179
146
|
try {
|
|
180
147
|
const parsed = new URL(trimmed);
|
|
181
|
-
if (parsed.
|
|
182
|
-
|
|
183
|
-
if (port) return `${parsed.protocol}//localhost:${port}`;
|
|
148
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
149
|
+
return "";
|
|
184
150
|
}
|
|
151
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
185
152
|
} catch {
|
|
153
|
+
return "";
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function firstNonEmpty(...values) {
|
|
157
|
+
for (const value of values) {
|
|
158
|
+
const trimmed = value?.trim();
|
|
159
|
+
if (trimmed) return trimmed;
|
|
186
160
|
}
|
|
187
|
-
return
|
|
161
|
+
return "";
|
|
188
162
|
}
|
|
189
|
-
function
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
if (declared) return normalizeWorktreeBaseUrl(declared, worktreeEnv);
|
|
193
|
-
const port = worktreeEnv.WORKTREE_APP_PORT || worktreeEnv.PORT || "";
|
|
194
|
-
return port ? `http://localhost:${port}` : "";
|
|
163
|
+
function sdkCliConfigDir(baseUrl) {
|
|
164
|
+
const home = process.env.HOME?.trim() || (0, import_node_os.homedir)();
|
|
165
|
+
return (0, import_node_path.join)(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL));
|
|
195
166
|
}
|
|
196
167
|
function sdkCliEnvFilePath(baseUrl) {
|
|
197
|
-
|
|
198
|
-
return (0, import_node_path.join)(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL), ".env");
|
|
168
|
+
return (0, import_node_path.join)(sdkCliConfigDir(baseUrl), ".env");
|
|
199
169
|
}
|
|
200
170
|
function loadCliEnv(baseUrl = PROD_URL) {
|
|
201
|
-
|
|
202
|
-
return parseEnvFile(envPath);
|
|
171
|
+
return parseEnvFile(sdkCliEnvFilePath(baseUrl));
|
|
203
172
|
}
|
|
204
173
|
function loadGlobalCliEnv() {
|
|
205
174
|
return loadCliEnv(PROD_URL);
|
|
206
175
|
}
|
|
207
176
|
function autoDetectBaseUrl() {
|
|
208
|
-
const
|
|
209
|
-
if (envOrigin) return normalizeWorktreeBaseUrl(envOrigin);
|
|
210
|
-
const envBase = process.env.DEEPLINE_API_BASE_URL?.trim();
|
|
211
|
-
if (envBase) return normalizeWorktreeBaseUrl(envBase);
|
|
212
|
-
const projectDeeplineBaseUrl = resolveBaseUrlFromEnvValues(loadProjectDeeplineEnv());
|
|
213
|
-
if (projectDeeplineBaseUrl) return normalizeWorktreeBaseUrl(projectDeeplineBaseUrl);
|
|
214
|
-
const projectAppBaseUrl = resolveBaseUrlFromEnvValues(loadProjectAppEnv());
|
|
215
|
-
if (projectAppBaseUrl) return normalizeWorktreeBaseUrl(projectAppBaseUrl);
|
|
216
|
-
const worktreeBaseUrl = resolveWorktreeBaseUrl();
|
|
217
|
-
if (worktreeBaseUrl) return worktreeBaseUrl;
|
|
177
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
218
178
|
const globalEnv = loadGlobalCliEnv();
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
179
|
+
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") || normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "") || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
180
|
+
}
|
|
181
|
+
function resolveApiKeyForBaseUrl(baseUrl, explicitApiKey) {
|
|
182
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
183
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
184
|
+
const cliEnv = loadCliEnv(normalizedBaseUrl || baseUrl);
|
|
185
|
+
const projectBaseUrl = normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "");
|
|
186
|
+
const projectKeyApplies = projectBaseUrl === normalizedBaseUrl;
|
|
187
|
+
return firstNonEmpty(
|
|
188
|
+
explicitApiKey,
|
|
189
|
+
process.env[API_KEY_ENV],
|
|
190
|
+
projectKeyApplies ? projectEnv[API_KEY_ENV] : "",
|
|
191
|
+
cliEnv[API_KEY_ENV]
|
|
192
|
+
);
|
|
222
193
|
}
|
|
223
194
|
function resolveConfig(options) {
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
195
|
+
const baseUrl = normalizeBaseUrl(
|
|
196
|
+
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
197
|
+
);
|
|
198
|
+
if (!baseUrl) {
|
|
199
|
+
throw new ConfigError(
|
|
200
|
+
`Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
const apiKey = resolveApiKeyForBaseUrl(baseUrl, options?.apiKey);
|
|
230
204
|
if (!apiKey) {
|
|
231
205
|
throw new ConfigError(
|
|
232
|
-
`No API key found. Set
|
|
206
|
+
`No API key found. Set ${API_KEY_ENV}, add it to .env.deepline, or run: deepline auth register`
|
|
233
207
|
);
|
|
234
208
|
}
|
|
235
209
|
return {
|
|
@@ -241,8 +215,8 @@ function resolveConfig(options) {
|
|
|
241
215
|
}
|
|
242
216
|
|
|
243
217
|
// src/version.ts
|
|
244
|
-
var SDK_VERSION = "0.1.
|
|
245
|
-
var SDK_API_CONTRACT = "2026-05-
|
|
218
|
+
var SDK_VERSION = "0.1.33";
|
|
219
|
+
var SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
|
|
246
220
|
|
|
247
221
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
248
222
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/config.ts
|
|
2
|
-
import {
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { dirname, join, resolve } from "path";
|
|
5
5
|
|
|
@@ -39,13 +39,12 @@ var ConfigError = class extends DeeplineError {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
// src/config.ts
|
|
42
|
+
var HOST_URL_ENV = "DEEPLINE_HOST_URL";
|
|
43
|
+
var API_KEY_ENV = "DEEPLINE_API_KEY";
|
|
42
44
|
var PROD_URL = "https://code.deepline.com";
|
|
43
45
|
var DEFAULT_TIMEOUT = 6e4;
|
|
44
46
|
var DEFAULT_MAX_RETRIES = 3;
|
|
45
|
-
var
|
|
46
|
-
function projectEnvStartDir() {
|
|
47
|
-
return process.env.DEEPLINE_PROJECT_ENV_DIR?.trim() || process.cwd();
|
|
48
|
-
}
|
|
47
|
+
var PROJECT_DEEPLINE_ENV_FILE = ".env.deepline";
|
|
49
48
|
function baseUrlSlug(baseUrl) {
|
|
50
49
|
let url;
|
|
51
50
|
try {
|
|
@@ -54,7 +53,7 @@ function baseUrlSlug(baseUrl) {
|
|
|
54
53
|
return "unknown";
|
|
55
54
|
}
|
|
56
55
|
const host = url.hostname || "unknown";
|
|
57
|
-
const port = url.port ? parseInt(url.port, 10) : null;
|
|
56
|
+
const port = url.port ? Number.parseInt(url.port, 10) : null;
|
|
58
57
|
let slug = host.replace(/[^a-zA-Z0-9]/g, "-");
|
|
59
58
|
if (port && port !== 80 && port !== 443) {
|
|
60
59
|
slug = `${slug}-${port}`;
|
|
@@ -81,109 +80,84 @@ function parseEnvFile(filePath) {
|
|
|
81
80
|
}
|
|
82
81
|
return env;
|
|
83
82
|
}
|
|
84
|
-
function findNearestEnvFile(
|
|
83
|
+
function findNearestEnvFile(name, startDir = process.cwd()) {
|
|
85
84
|
let current = resolve(startDir);
|
|
86
85
|
while (true) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (existsSync(filePath)) return filePath;
|
|
90
|
-
}
|
|
86
|
+
const filePath = join(current, name);
|
|
87
|
+
if (existsSync(filePath)) return filePath;
|
|
91
88
|
const parent = dirname(current);
|
|
92
89
|
if (parent === current) return null;
|
|
93
90
|
current = parent;
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
|
-
function
|
|
97
|
-
const filePath = findNearestEnvFile(
|
|
93
|
+
function loadProjectDeeplineEnv(startDir = process.cwd()) {
|
|
94
|
+
const filePath = findNearestEnvFile(PROJECT_DEEPLINE_ENV_FILE, startDir);
|
|
98
95
|
return filePath ? parseEnvFile(filePath) : {};
|
|
99
96
|
}
|
|
100
|
-
function
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
function resolveProfileEnvFileNames() {
|
|
104
|
-
const explicitProfile = process.env.DEEPLINE_ENV_PROFILE?.trim() || process.env.DEEPLINE_PROFILE?.trim() || "";
|
|
105
|
-
const names = [];
|
|
106
|
-
if (explicitProfile) names.push(`.env.deepline.${explicitProfile}`);
|
|
107
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
108
|
-
if (nodeEnv === "production") names.push(".env.deepline.prod");
|
|
109
|
-
else if (nodeEnv === "staging") names.push(".env.deepline.staging");
|
|
110
|
-
names.push(ACTIVE_DEEPLINE_ENV_FILE);
|
|
111
|
-
return names;
|
|
112
|
-
}
|
|
113
|
-
function resolveProjectAppEnvFileNames() {
|
|
114
|
-
const nodeEnv = process.env.NODE_ENV?.trim();
|
|
115
|
-
const names = [];
|
|
116
|
-
if (nodeEnv === "production") names.push(".env.prod");
|
|
117
|
-
if (nodeEnv === "staging") names.push(".env.staging");
|
|
118
|
-
names.push(".env.local", ".env");
|
|
119
|
-
return names;
|
|
120
|
-
}
|
|
121
|
-
function resolveBaseUrlFromEnvValues(env) {
|
|
122
|
-
return env.DEEPLINE_ORIGIN_URL?.trim() || env.DEEPLINE_API_BASE_URL?.trim() || "";
|
|
123
|
-
}
|
|
124
|
-
function loadProjectDeeplineEnv() {
|
|
125
|
-
return findNearestEnv(resolveProfileEnvFileNames(), projectEnvStartDir());
|
|
126
|
-
}
|
|
127
|
-
function loadProjectAppEnv() {
|
|
128
|
-
return findNearestEnv(resolveProjectAppEnvFileNames(), projectEnvStartDir());
|
|
129
|
-
}
|
|
130
|
-
function normalizeWorktreeBaseUrl(baseUrl, worktreeEnv = findNearestWorktreeEnv()) {
|
|
131
|
-
const trimmed = baseUrl.trim().replace(/\/$/, "");
|
|
132
|
-
if (!trimmed) return trimmed;
|
|
97
|
+
function normalizeBaseUrl(baseUrl) {
|
|
98
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
99
|
+
if (!trimmed) return "";
|
|
133
100
|
try {
|
|
134
101
|
const parsed = new URL(trimmed);
|
|
135
|
-
if (parsed.
|
|
136
|
-
|
|
137
|
-
if (port) return `${parsed.protocol}//localhost:${port}`;
|
|
102
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
103
|
+
return "";
|
|
138
104
|
}
|
|
105
|
+
return parsed.toString().replace(/\/+$/, "");
|
|
139
106
|
} catch {
|
|
107
|
+
return "";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function firstNonEmpty(...values) {
|
|
111
|
+
for (const value of values) {
|
|
112
|
+
const trimmed = value?.trim();
|
|
113
|
+
if (trimmed) return trimmed;
|
|
140
114
|
}
|
|
141
|
-
return
|
|
115
|
+
return "";
|
|
142
116
|
}
|
|
143
|
-
function
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
if (declared) return normalizeWorktreeBaseUrl(declared, worktreeEnv);
|
|
147
|
-
const port = worktreeEnv.WORKTREE_APP_PORT || worktreeEnv.PORT || "";
|
|
148
|
-
return port ? `http://localhost:${port}` : "";
|
|
117
|
+
function sdkCliConfigDir(baseUrl) {
|
|
118
|
+
const home = process.env.HOME?.trim() || homedir();
|
|
119
|
+
return join(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL));
|
|
149
120
|
}
|
|
150
121
|
function sdkCliEnvFilePath(baseUrl) {
|
|
151
|
-
|
|
152
|
-
return join(home, ".local", "deepline", baseUrlSlug(baseUrl || PROD_URL), ".env");
|
|
122
|
+
return join(sdkCliConfigDir(baseUrl), ".env");
|
|
153
123
|
}
|
|
154
124
|
function loadCliEnv(baseUrl = PROD_URL) {
|
|
155
|
-
|
|
156
|
-
return parseEnvFile(envPath);
|
|
125
|
+
return parseEnvFile(sdkCliEnvFilePath(baseUrl));
|
|
157
126
|
}
|
|
158
127
|
function loadGlobalCliEnv() {
|
|
159
128
|
return loadCliEnv(PROD_URL);
|
|
160
129
|
}
|
|
161
130
|
function autoDetectBaseUrl() {
|
|
162
|
-
const
|
|
163
|
-
if (envOrigin) return normalizeWorktreeBaseUrl(envOrigin);
|
|
164
|
-
const envBase = process.env.DEEPLINE_API_BASE_URL?.trim();
|
|
165
|
-
if (envBase) return normalizeWorktreeBaseUrl(envBase);
|
|
166
|
-
const projectDeeplineBaseUrl = resolveBaseUrlFromEnvValues(loadProjectDeeplineEnv());
|
|
167
|
-
if (projectDeeplineBaseUrl) return normalizeWorktreeBaseUrl(projectDeeplineBaseUrl);
|
|
168
|
-
const projectAppBaseUrl = resolveBaseUrlFromEnvValues(loadProjectAppEnv());
|
|
169
|
-
if (projectAppBaseUrl) return normalizeWorktreeBaseUrl(projectAppBaseUrl);
|
|
170
|
-
const worktreeBaseUrl = resolveWorktreeBaseUrl();
|
|
171
|
-
if (worktreeBaseUrl) return worktreeBaseUrl;
|
|
131
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
172
132
|
const globalEnv = loadGlobalCliEnv();
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
133
|
+
return normalizeBaseUrl(process.env[HOST_URL_ENV] ?? "") || normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "") || normalizeBaseUrl(globalEnv[HOST_URL_ENV] ?? "") || PROD_URL;
|
|
134
|
+
}
|
|
135
|
+
function resolveApiKeyForBaseUrl(baseUrl, explicitApiKey) {
|
|
136
|
+
const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
|
|
137
|
+
const projectEnv = loadProjectDeeplineEnv();
|
|
138
|
+
const cliEnv = loadCliEnv(normalizedBaseUrl || baseUrl);
|
|
139
|
+
const projectBaseUrl = normalizeBaseUrl(projectEnv[HOST_URL_ENV] ?? "");
|
|
140
|
+
const projectKeyApplies = projectBaseUrl === normalizedBaseUrl;
|
|
141
|
+
return firstNonEmpty(
|
|
142
|
+
explicitApiKey,
|
|
143
|
+
process.env[API_KEY_ENV],
|
|
144
|
+
projectKeyApplies ? projectEnv[API_KEY_ENV] : "",
|
|
145
|
+
cliEnv[API_KEY_ENV]
|
|
146
|
+
);
|
|
176
147
|
}
|
|
177
148
|
function resolveConfig(options) {
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
149
|
+
const baseUrl = normalizeBaseUrl(
|
|
150
|
+
options?.baseUrl?.trim() || autoDetectBaseUrl()
|
|
151
|
+
);
|
|
152
|
+
if (!baseUrl) {
|
|
153
|
+
throw new ConfigError(
|
|
154
|
+
`Invalid ${HOST_URL_ENV}. Expected an http(s) URL such as https://code.deepline.com.`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
const apiKey = resolveApiKeyForBaseUrl(baseUrl, options?.apiKey);
|
|
184
158
|
if (!apiKey) {
|
|
185
159
|
throw new ConfigError(
|
|
186
|
-
`No API key found. Set
|
|
160
|
+
`No API key found. Set ${API_KEY_ENV}, add it to .env.deepline, or run: deepline auth register`
|
|
187
161
|
);
|
|
188
162
|
}
|
|
189
163
|
return {
|
|
@@ -195,8 +169,8 @@ function resolveConfig(options) {
|
|
|
195
169
|
}
|
|
196
170
|
|
|
197
171
|
// src/version.ts
|
|
198
|
-
var SDK_VERSION = "0.1.
|
|
199
|
-
var SDK_API_CONTRACT = "2026-05-
|
|
172
|
+
var SDK_VERSION = "0.1.33";
|
|
173
|
+
var SDK_API_CONTRACT = "2026-05-host-env-generic-play-input-flags";
|
|
200
174
|
|
|
201
175
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
202
176
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|