@treeseed/sdk 0.10.6 → 0.10.8

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 (50) hide show
  1. package/dist/api/auth/d1-provider.d.ts +5 -0
  2. package/dist/api/auth/d1-provider.js +3 -0
  3. package/dist/api/auth/d1-store.d.ts +5 -0
  4. package/dist/api/auth/d1-store.js +62 -0
  5. package/dist/api/auth/memory-provider.d.ts +5 -0
  6. package/dist/api/auth/memory-provider.js +41 -0
  7. package/dist/api/types.d.ts +5 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.js +58 -0
  10. package/dist/market-client.d.ts +119 -0
  11. package/dist/market-client.js +79 -0
  12. package/dist/operations/repository-operations.d.ts +129 -0
  13. package/dist/operations/repository-operations.js +634 -0
  14. package/dist/operations/services/config-runtime.d.ts +7 -6
  15. package/dist/operations/services/config-runtime.js +45 -25
  16. package/dist/operations/services/deploy.d.ts +42 -0
  17. package/dist/operations/services/deploy.js +1 -1
  18. package/dist/operations/services/project-platform.d.ts +41 -1
  19. package/dist/operations/services/project-platform.js +14 -1
  20. package/dist/operations/services/railway-api.d.ts +35 -1
  21. package/dist/operations/services/railway-api.js +240 -35
  22. package/dist/operations/services/railway-deploy.d.ts +16 -234
  23. package/dist/operations/services/railway-deploy.js +177 -62
  24. package/dist/operations/services/release-candidate.js +1 -2
  25. package/dist/operations/services/runtime-tools.d.ts +14 -0
  26. package/dist/operations/services/runtime-tools.js +15 -1
  27. package/dist/operations/services/workspace-save.d.ts +24 -0
  28. package/dist/operations/services/workspace-save.js +143 -3
  29. package/dist/operations/services/workspace-tools.js +1 -1
  30. package/dist/platform/env.yaml +163 -2
  31. package/dist/platform/environment.d.ts +1 -0
  32. package/dist/platform/environment.js +9 -0
  33. package/dist/platform-operation-store.d.ts +90 -0
  34. package/dist/platform-operation-store.js +505 -0
  35. package/dist/platform-operations.d.ts +265 -0
  36. package/dist/platform-operations.js +421 -0
  37. package/dist/reconcile/bootstrap-systems.js +3 -3
  38. package/dist/reconcile/builtin-adapters.js +225 -29
  39. package/dist/reconcile/contracts.d.ts +1 -1
  40. package/dist/reconcile/desired-state.d.ts +14 -0
  41. package/dist/reconcile/desired-state.js +4 -0
  42. package/dist/reconcile/engine.d.ts +28 -0
  43. package/dist/reconcile/state.js +3 -0
  44. package/dist/reconcile/units.js +2 -0
  45. package/dist/workflow/operations.d.ts +13 -5
  46. package/dist/workflow/operations.js +69 -12
  47. package/dist/workflow-state.d.ts +2 -0
  48. package/dist/workflow-state.js +7 -2
  49. package/dist/workflow.d.ts +2 -0
  50. package/package.json +15 -2
@@ -30,7 +30,8 @@ import {
30
30
  maybeResolveGitHubRepositorySlug
31
31
  } from "./github-automation.js";
32
32
  import {
33
- buildRailwayCommandEnv
33
+ buildRailwayCommandEnv,
34
+ configuredRailwayServices
34
35
  } from "./railway-deploy.js";
35
36
  import {
36
37
  normalizeRailwayEnvironmentName,
@@ -2235,45 +2236,63 @@ function syncTreeseedCloudflareEnvironment({ tenantRoot, scope = "prod", dryRun
2235
2236
  varsManagedByWranglerConfig: cloudflareVars
2236
2237
  };
2237
2238
  }
2239
+ function environmentEntryTargetsService(entry, serviceKey) {
2240
+ const targets = Array.isArray(entry.serviceTargets) ? entry.serviceTargets.map((value) => String(value).trim()).filter(Boolean) : [];
2241
+ return targets.length === 0 || targets.includes(serviceKey);
2242
+ }
2243
+ function railwayEnvironmentEntryIdsForService(registry, values, scope, target, serviceKey) {
2244
+ return registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes(target) && environmentEntryTargetsService(entry, serviceKey)).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
2245
+ }
2238
2246
  function syncTreeseedRailwayEnvironment({ tenantRoot, scope = "prod", dryRun = false } = {}) {
2239
2247
  const config = syncManagedServiceSettingsFromDeployConfig(tenantRoot);
2240
- const deployConfig = loadTenantDeployConfig(tenantRoot);
2241
2248
  const values = resolveTreeseedMachineEnvironmentValues(tenantRoot, scope);
2249
+ const deployConfig = loadCliDeployConfig(tenantRoot);
2250
+ const marketDatabaseService = deployConfig.services?.marketDatabase;
2251
+ const marketDatabaseBaseName = typeof marketDatabaseService?.railway?.serviceName === "string" && marketDatabaseService.railway.serviceName.trim() ? marketDatabaseService.railway.serviceName.trim() : `${deployConfig.slug ?? "treeseed-market"}-postgres`;
2252
+ const marketDatabaseServiceName = `${marketDatabaseBaseName.replace(/-(staging|prod|production)$/u, "")}-${scope === "prod" ? "prod" : scope}`;
2253
+ const marketDatabaseUrl = typeof values.TREESEED_MARKET_DATABASE_URL === "string" && values.TREESEED_MARKET_DATABASE_URL.length > 0 ? values.TREESEED_MARKET_DATABASE_URL : marketDatabaseService?.enabled !== false && marketDatabaseService?.provider === "railway" ? `\${{${marketDatabaseServiceName}.DATABASE_URL}}` : "";
2242
2254
  const registry = collectTreeseedEnvironmentContext(tenantRoot);
2243
- const railwaySecretNames = registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("railway-secret")).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
2244
- const railwayVariableNames = registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("railway-var")).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
2245
- const services = ["api", "workdayManager", "workerRunner"].map((serviceKey) => {
2246
- const service = deployConfig.services?.[serviceKey];
2247
- if (!service || service.enabled === false || (service.provider ?? "railway") !== "railway") {
2248
- return null;
2249
- }
2250
- const environment = service.environments?.[scope];
2251
- const fallbackServiceName = serviceKey === "api" ? config.settings.services.railway.apiServiceName : "";
2252
- const defaultRootDir = ["api", "workdayManager", "workerRunner"].includes(serviceKey) ? "." : "packages/core";
2255
+ const serviceValuesByName = /* @__PURE__ */ new Map();
2256
+ const services = configuredRailwayServices(tenantRoot, scope).map((service) => {
2257
+ const fallbackServiceName = service.key === "api" ? config.settings.services.railway.apiServiceName : service.serviceName;
2258
+ const environmentName = normalizeRailwayEnvironmentName(service.railwayEnvironment ?? scope);
2259
+ const serviceValues = {
2260
+ ...values,
2261
+ ...service.key === "marketOperationsRunner" ? {
2262
+ TREESEED_PLATFORM_RUNNER_ID: service.runnerId ?? service.serviceName,
2263
+ TREESEED_PLATFORM_RUNNER_DATA_DIR: service.volumeMountPath ?? values.TREESEED_PLATFORM_RUNNER_DATA_DIR,
2264
+ TREESEED_PLATFORM_RUNNER_ENVIRONMENT: scope === "prod" ? "production" : scope
2265
+ } : {},
2266
+ ...marketDatabaseUrl && ["api", "marketOperationsRunner"].includes(service.key) ? { TREESEED_MARKET_DATABASE_URL: marketDatabaseUrl } : {}
2267
+ };
2268
+ const serviceName = service.serviceName ?? fallbackServiceName;
2269
+ serviceValuesByName.set(serviceName || service.serviceId || service.instanceKey || service.key, serviceValues);
2253
2270
  return {
2254
- service: serviceKey,
2255
- projectName: service.railway?.projectName ?? config.settings.services.railway.projectName,
2256
- serviceName: service.railway?.serviceName ?? fallbackServiceName,
2257
- serviceId: service.railway?.serviceId ?? "",
2258
- rootDir: resolve(tenantRoot, service.railway?.rootDir ?? service.rootDir ?? defaultRootDir),
2259
- baseUrl: environment?.baseUrl ?? service.publicBaseUrl ?? "(unset)",
2260
- environmentName: normalizeRailwayEnvironmentName(environment?.railwayEnvironment ?? scope),
2261
- secrets: railwaySecretNames,
2262
- variables: railwayVariableNames,
2271
+ service: service.key,
2272
+ instanceKey: service.instanceKey ?? service.key,
2273
+ projectName: service.projectName ?? config.settings.services.railway.projectName,
2274
+ serviceName,
2275
+ serviceId: service.serviceId ?? "",
2276
+ rootDir: service.rootDir,
2277
+ baseUrl: service.publicBaseUrl ?? "(unset)",
2278
+ environmentName,
2279
+ secrets: railwayEnvironmentEntryIdsForService(registry, serviceValues, scope, "railway-secret", service.key),
2280
+ variables: railwayEnvironmentEntryIdsForService(registry, serviceValues, scope, "railway-var", service.key),
2263
2281
  dryRun
2264
2282
  };
2265
2283
  }).filter(Boolean);
2266
2284
  for (const service of services) {
2285
+ const serviceValues = serviceValuesByName.get(service.serviceName || service.serviceId || service.instanceKey || service.service) ?? values;
2267
2286
  for (const key of service.secrets) {
2268
2287
  runRailway(
2269
2288
  ["variable", "set", "--service", service.serviceName || service.serviceId, "--environment", service.environmentName, "--stdin", "--skip-deploys", key],
2270
- { cwd: service.rootDir, dryRun, input: values[key] }
2289
+ { cwd: service.rootDir, dryRun, input: serviceValues[key] }
2271
2290
  );
2272
2291
  }
2273
2292
  for (const key of service.variables) {
2274
2293
  runRailway(
2275
2294
  ["variable", "set", "--service", service.serviceName || service.serviceId, "--environment", service.environmentName, "--stdin", "--skip-deploys", key],
2276
- { cwd: service.rootDir, dryRun, input: values[key] }
2295
+ { cwd: service.rootDir, dryRun, input: serviceValues[key] }
2277
2296
  );
2278
2297
  }
2279
2298
  }
@@ -2555,7 +2574,8 @@ function buildConfigEntrySnapshot(scope, entry, currentValue, suggestedValue) {
2555
2574
  return true;
2556
2575
  }
2557
2576
  })();
2558
- const allowSuggestedDefault = !(entry.sensitivity === "secret" && entry.requirement !== "optional");
2577
+ const allowGeneratedSecretDefault = entry.id === "TREESEED_PLATFORM_RUNNER_SECRET";
2578
+ const allowSuggestedDefault = allowGeneratedSecretDefault || !(entry.sensitivity === "secret" && entry.requirement !== "optional");
2559
2579
  const effectiveValue = currentValueValid ? currentValue || (allowSuggestedDefault ? suggestedValue : "") || "" : (allowSuggestedDefault ? suggestedValue : "") || currentValue || "";
2560
2580
  return {
2561
2581
  id: entry.id,
@@ -2898,7 +2918,7 @@ async function finalizeTreeseedConfig({
2898
2918
  result: {}
2899
2919
  });
2900
2920
  }
2901
- const deploySystems = selection.runnable.filter((system) => system === "data" || system === "web" || system === "api" || system === "agents");
2921
+ const deploySystems = selection.runnable.filter((system) => system === "data" || system === "web");
2902
2922
  if (deploySystems.length > 0) {
2903
2923
  progress(`[${scope}][bootstrap][deploy] Deploying ${deploySystems.join(", ")}...`);
2904
2924
  applyTreeseedEnvironmentToProcess({ tenantRoot, scope, override: true });
@@ -232,9 +232,23 @@ export declare function ensureGeneratedWranglerConfig(tenantRoot: any, options?:
232
232
  projectName: string | undefined;
233
233
  serviceId: string | undefined;
234
234
  serviceName: string | undefined;
235
+ resourceType: string | undefined;
236
+ environmentVariable: string | undefined;
237
+ serviceTargets: any;
235
238
  rootDir: string | undefined;
236
239
  buildCommand: string | undefined;
237
240
  startCommand: string | undefined;
241
+ healthcheckPath: string | undefined;
242
+ healthcheckTimeoutSeconds: number | undefined;
243
+ healthcheckIntervalSeconds: number | undefined;
244
+ restartPolicy: string | undefined;
245
+ runtimeMode: string | undefined;
246
+ volumeMountPath: string | undefined;
247
+ runnerPool: {
248
+ bootstrapCount: number | undefined;
249
+ maxRunners: number | undefined;
250
+ volumeMountPath: string | undefined;
251
+ } | undefined;
238
252
  schedule: any;
239
253
  };
240
254
  environments: {
@@ -614,9 +628,23 @@ export declare function validateDeployPrerequisites(tenantRoot: any, { requireRe
614
628
  projectName: string | undefined;
615
629
  serviceId: string | undefined;
616
630
  serviceName: string | undefined;
631
+ resourceType: string | undefined;
632
+ environmentVariable: string | undefined;
633
+ serviceTargets: any;
617
634
  rootDir: string | undefined;
618
635
  buildCommand: string | undefined;
619
636
  startCommand: string | undefined;
637
+ healthcheckPath: string | undefined;
638
+ healthcheckTimeoutSeconds: number | undefined;
639
+ healthcheckIntervalSeconds: number | undefined;
640
+ restartPolicy: string | undefined;
641
+ runtimeMode: string | undefined;
642
+ volumeMountPath: string | undefined;
643
+ runnerPool: {
644
+ bootstrapCount: number | undefined;
645
+ maxRunners: number | undefined;
646
+ volumeMountPath: string | undefined;
647
+ } | undefined;
620
648
  schedule: any;
621
649
  };
622
650
  environments: {
@@ -793,9 +821,23 @@ export declare function validateDestroyPrerequisites(tenantRoot: any, { requireR
793
821
  projectName: string | undefined;
794
822
  serviceId: string | undefined;
795
823
  serviceName: string | undefined;
824
+ resourceType: string | undefined;
825
+ environmentVariable: string | undefined;
826
+ serviceTargets: any;
796
827
  rootDir: string | undefined;
797
828
  buildCommand: string | undefined;
798
829
  startCommand: string | undefined;
830
+ healthcheckPath: string | undefined;
831
+ healthcheckTimeoutSeconds: number | undefined;
832
+ healthcheckIntervalSeconds: number | undefined;
833
+ restartPolicy: string | undefined;
834
+ runtimeMode: string | undefined;
835
+ volumeMountPath: string | undefined;
836
+ runnerPool: {
837
+ bootstrapCount: number | undefined;
838
+ maxRunners: number | undefined;
839
+ volumeMountPath: string | undefined;
840
+ } | undefined;
799
841
  schedule: any;
800
842
  };
801
843
  environments: {
@@ -13,7 +13,7 @@ const GENERATED_ROOT = ".treeseed/generated";
13
13
  const STATE_ROOT = ".treeseed/state";
14
14
  const WORKTREE_METADATA_RELATIVE_PATH = ".treeseed/worktree.json";
15
15
  const PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "staging", "prod"]);
16
- const MANAGED_SERVICE_KEYS = ["api", "workdayManager", "workerRunner"];
16
+ const MANAGED_SERVICE_KEYS = ["api"];
17
17
  const TRESEED_ENVELOPE_SCHEMA_GENERATION = "runtime-envelopes-v1";
18
18
  const TRESEED_MIGRATION_WAVE_ID = "0005_runtime_envelopes";
19
19
  const TRESEED_SUPPORTED_PAYLOAD_RANGE = { min: 1, max: 1 };
@@ -76,7 +76,7 @@ export declare function provisionProjectPlatform(options: ProjectPlatformActionO
76
76
  }[];
77
77
  };
78
78
  railway: {
79
- services: string[];
79
+ services: any[];
80
80
  schedules: any[];
81
81
  verification: {
82
82
  ok: boolean;
@@ -189,17 +189,27 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
189
189
  reason: string;
190
190
  };
191
191
  scaleProbe: {
192
+ ok: boolean;
193
+ mocked: boolean;
194
+ serviceId: any;
195
+ serviceName: any;
196
+ runnerKind: string;
197
+ skipped?: undefined;
198
+ reason?: undefined;
199
+ } | {
192
200
  ok: boolean;
193
201
  skipped: boolean;
194
202
  reason: string;
195
203
  mocked: boolean;
196
204
  serviceId: any;
197
205
  serviceName?: undefined;
206
+ runnerKind?: undefined;
198
207
  } | {
199
208
  ok: boolean;
200
209
  mocked: boolean;
201
210
  serviceId: any;
202
211
  serviceName: any;
212
+ runnerKind?: undefined;
203
213
  skipped?: undefined;
204
214
  reason?: undefined;
205
215
  };
@@ -388,17 +398,27 @@ export declare function monitorProjectPlatform(options: ProjectPlatformActionOpt
388
398
  reason: string;
389
399
  };
390
400
  scaleProbe: {
401
+ ok: boolean;
402
+ mocked: boolean;
403
+ serviceId: any;
404
+ serviceName: any;
405
+ runnerKind: string;
406
+ skipped?: undefined;
407
+ reason?: undefined;
408
+ } | {
391
409
  ok: boolean;
392
410
  skipped: boolean;
393
411
  reason: string;
394
412
  mocked: boolean;
395
413
  serviceId: any;
396
414
  serviceName?: undefined;
415
+ runnerKind?: undefined;
397
416
  } | {
398
417
  ok: boolean;
399
418
  mocked: boolean;
400
419
  serviceId: any;
401
420
  serviceName: any;
421
+ runnerKind?: undefined;
402
422
  skipped?: undefined;
403
423
  reason?: undefined;
404
424
  };
@@ -539,17 +559,27 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
539
559
  reason: string;
540
560
  };
541
561
  scaleProbe: {
562
+ ok: boolean;
563
+ mocked: boolean;
564
+ serviceId: any;
565
+ serviceName: any;
566
+ runnerKind: string;
567
+ skipped?: undefined;
568
+ reason?: undefined;
569
+ } | {
542
570
  ok: boolean;
543
571
  skipped: boolean;
544
572
  reason: string;
545
573
  mocked: boolean;
546
574
  serviceId: any;
547
575
  serviceName?: undefined;
576
+ runnerKind?: undefined;
548
577
  } | {
549
578
  ok: boolean;
550
579
  mocked: boolean;
551
580
  serviceId: any;
552
581
  serviceName: any;
582
+ runnerKind?: undefined;
553
583
  skipped?: undefined;
554
584
  reason?: undefined;
555
585
  };
@@ -683,17 +713,27 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
683
713
  reason: string;
684
714
  };
685
715
  scaleProbe: {
716
+ ok: boolean;
717
+ mocked: boolean;
718
+ serviceId: any;
719
+ serviceName: any;
720
+ runnerKind: string;
721
+ skipped?: undefined;
722
+ reason?: undefined;
723
+ } | {
686
724
  ok: boolean;
687
725
  skipped: boolean;
688
726
  reason: string;
689
727
  mocked: boolean;
690
728
  serviceId: any;
691
729
  serviceName?: undefined;
730
+ runnerKind?: undefined;
692
731
  } | {
693
732
  ok: boolean;
694
733
  mocked: boolean;
695
734
  serviceId: any;
696
735
  serviceName: any;
736
+ runnerKind?: undefined;
697
737
  skipped?: undefined;
698
738
  reason?: undefined;
699
739
  };
@@ -45,7 +45,7 @@ import { CloudflareQueuePullClient, CloudflareQueuePushClient } from "../../remo
45
45
  import { runPrefixedCommand, runTreeseedBootstrapDag, sleep, writeTreeseedBootstrapLine } from "./bootstrap-runner.js";
46
46
  import { runTenantDeployPreflight } from "./save-deploy-preflight.js";
47
47
  const PROJECT_PLATFORM_BOOTSTRAP_SYSTEMS = ["data", "web", "api", "agents"];
48
- const WEB_PLATFORM_BOOTSTRAP_SYSTEMS = ["data", "web"];
48
+ const WEB_PLATFORM_BOOTSTRAP_SYSTEMS = PROJECT_PLATFORM_BOOTSTRAP_SYSTEMS;
49
49
  const PROCESSING_PLATFORM_BOOTSTRAP_SYSTEMS = ["api", "agents"];
50
50
  function stableHash(value) {
51
51
  return createHash("sha256").update(value).digest("hex");
@@ -757,7 +757,20 @@ function probeR2(tenantRoot, siteConfig, state, target) {
757
757
  function probeScaleConfiguration(siteConfig, state) {
758
758
  const worker = state.services?.workerRunner ?? state.services?.worker ?? {};
759
759
  const workerConfig = siteConfig.services?.workerRunner ?? siteConfig.services?.worker ?? {};
760
+ const marketRunner = state.services?.marketOperationsRunner ?? {};
761
+ const marketRunnerConfig = siteConfig.services?.marketOperationsRunner ?? {};
760
762
  const scalerKind = String(process.env.TREESEED_WORKER_POOL_SCALER ?? "").trim();
763
+ if (marketRunnerConfig.provider === "railway" && workerConfig.provider !== "railway") {
764
+ const runnerServiceId = marketRunner.serviceId ?? null;
765
+ const runnerServiceName = marketRunner.serviceName ?? marketRunnerConfig.railway?.serviceName ?? null;
766
+ return {
767
+ ok: Boolean(runnerServiceId || runnerServiceName),
768
+ mocked: true,
769
+ serviceId: runnerServiceId,
770
+ serviceName: runnerServiceName,
771
+ runnerKind: "market_operations_runner"
772
+ };
773
+ }
761
774
  if (scalerKind !== "railway" && workerConfig.provider !== "railway") {
762
775
  return {
763
776
  ok: true,
@@ -15,6 +15,7 @@ export type RailwayProjectSummary = {
15
15
  id: string;
16
16
  name: string;
17
17
  workspaceId: string | null;
18
+ deletedAt: string | null;
18
19
  environments: RailwayEnvironmentSummary[];
19
20
  services: RailwayServiceSummary[];
20
21
  };
@@ -59,6 +60,7 @@ export type RailwayVolumeInstanceSummary = {
59
60
  serviceId: string | null;
60
61
  environmentId: string | null;
61
62
  mountPath: string | null;
63
+ state: string | null;
62
64
  sizeGb: number | null;
63
65
  usedGb: number | null;
64
66
  };
@@ -144,6 +146,22 @@ export declare function ensureRailwayService({ projectId, serviceName, serviceId
144
146
  service: RailwayServiceSummary;
145
147
  created: boolean;
146
148
  }>;
149
+ export declare function updateRailwayServiceName({ serviceId, name, env, fetchImpl, }: {
150
+ serviceId: string;
151
+ name: string;
152
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
153
+ fetchImpl?: typeof fetch;
154
+ }): Promise<RailwayServiceSummary>;
155
+ export declare function ensureRailwayPostgresService({ projectId, environmentId, serviceName, env, fetchImpl, }: {
156
+ projectId: string;
157
+ environmentId: string;
158
+ serviceName: string;
159
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
160
+ fetchImpl?: typeof fetch;
161
+ }): Promise<{
162
+ service: RailwayServiceSummary;
163
+ created: boolean;
164
+ }>;
147
165
  export declare function listRailwayServices({ projectId, env, fetchImpl, }: {
148
166
  projectId: string;
149
167
  env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
@@ -270,7 +288,12 @@ export declare function ensureRailwayServiceVolume({ projectId, environmentId, s
270
288
  env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
271
289
  fetchImpl?: typeof fetch;
272
290
  }): Promise<{
273
- volume: RailwayVolumeSummary;
291
+ volume: {
292
+ instances: RailwayVolumeInstanceSummary[];
293
+ id: string;
294
+ name: string;
295
+ projectId: string | null;
296
+ } | null;
274
297
  instance: RailwayVolumeInstanceSummary | null;
275
298
  created: boolean;
276
299
  updated: boolean;
@@ -282,3 +305,14 @@ export declare function listRailwayCustomDomains({ projectId, environmentId, ser
282
305
  env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
283
306
  fetchImpl?: typeof fetch;
284
307
  }): Promise<RailwayCustomDomainSummary[]>;
308
+ export declare function ensureRailwayCustomDomain({ projectId, environmentId, serviceId, domain, env, fetchImpl, }: {
309
+ projectId: string;
310
+ environmentId: string;
311
+ serviceId: string;
312
+ domain: string;
313
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
314
+ fetchImpl?: typeof fetch;
315
+ }): Promise<{
316
+ domain: RailwayCustomDomainSummary;
317
+ created: boolean;
318
+ }>;