@treeseed/sdk 0.10.5 → 0.10.7
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/dist/index.d.ts +2 -0
- package/dist/index.js +58 -0
- package/dist/operations/repository-operations.d.ts +129 -0
- package/dist/operations/repository-operations.js +634 -0
- package/dist/operations/services/config-runtime.d.ts +7 -6
- package/dist/operations/services/config-runtime.js +45 -25
- package/dist/operations/services/deploy.d.ts +42 -0
- package/dist/operations/services/deploy.js +1 -1
- package/dist/operations/services/project-platform.d.ts +41 -1
- package/dist/operations/services/project-platform.js +13 -0
- package/dist/operations/services/railway-api.d.ts +35 -1
- package/dist/operations/services/railway-api.js +240 -35
- package/dist/operations/services/railway-deploy.d.ts +16 -234
- package/dist/operations/services/railway-deploy.js +177 -62
- package/dist/operations/services/release-candidate.js +1 -2
- package/dist/operations/services/runtime-tools.d.ts +14 -0
- package/dist/operations/services/runtime-tools.js +15 -1
- package/dist/operations/services/workspace-save.d.ts +24 -0
- package/dist/operations/services/workspace-save.js +143 -3
- package/dist/operations/services/workspace-tools.js +1 -1
- package/dist/platform/env.yaml +163 -2
- package/dist/platform/environment.d.ts +1 -0
- package/dist/platform/environment.js +9 -0
- package/dist/platform-operation-store.d.ts +90 -0
- package/dist/platform-operation-store.js +505 -0
- package/dist/platform-operations.d.ts +265 -0
- package/dist/platform-operations.js +421 -0
- package/dist/reconcile/bootstrap-systems.js +3 -3
- package/dist/reconcile/builtin-adapters.js +225 -29
- package/dist/reconcile/contracts.d.ts +1 -1
- package/dist/reconcile/desired-state.d.ts +14 -0
- package/dist/reconcile/desired-state.js +4 -0
- package/dist/reconcile/engine.d.ts +28 -0
- package/dist/reconcile/state.js +3 -0
- package/dist/reconcile/units.js +2 -0
- package/dist/workflow/operations.d.ts +13 -5
- package/dist/workflow/operations.js +69 -12
- package/dist/workflow-state.d.ts +2 -0
- package/dist/workflow-state.js +7 -2
- package/dist/workflow.d.ts +2 -0
- package/package.json +15 -2
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const DEFAULT_RAILWAY_API_URL = "https://backboard.railway.com/graphql/v2";
|
|
2
2
|
const DEFAULT_RAILWAY_WORKSPACE = "knowledge-coop";
|
|
3
|
+
const RAILWAY_POSTGRES_TEMPLATE_ID = "b55da7dc-09be-4140-bc65-1284d15d349c";
|
|
4
|
+
const RAILWAY_POSTGRES_TEMPLATE_SERVICE_ID = "b55da7dc-09be-4140-bc65-1284b15d349b";
|
|
3
5
|
function normalizeRailwayEnvironmentName(value) {
|
|
4
6
|
const normalized = typeof value === "string" ? value.trim() : "";
|
|
5
7
|
if (!normalized) {
|
|
@@ -114,6 +116,7 @@ function normalizeProject(node) {
|
|
|
114
116
|
id,
|
|
115
117
|
name,
|
|
116
118
|
workspaceId: railwayConnectionLabel(node.workspaceId) || null,
|
|
119
|
+
deletedAt: railwayConnectionLabel(node.deletedAt) || null,
|
|
117
120
|
environments: normalizeConnectionNodes(node.environments, normalizeEnvironment),
|
|
118
121
|
services: normalizeConnectionNodes(node.services, normalizeService)
|
|
119
122
|
};
|
|
@@ -203,10 +206,15 @@ function normalizeRailwayVolumeInstance(node) {
|
|
|
203
206
|
serviceId: railwayConnectionLabel(node.serviceId) || railwayConnectionLabel(node.service?.id) || null,
|
|
204
207
|
environmentId: railwayConnectionLabel(node.environmentId) || railwayConnectionLabel(node.environment?.id) || null,
|
|
205
208
|
mountPath: railwayConnectionLabel(node.mountPath) || railwayConnectionLabel(node.mount_path) || null,
|
|
209
|
+
state: railwayConnectionLabel(node.state) || null,
|
|
206
210
|
sizeGb,
|
|
207
211
|
usedGb
|
|
208
212
|
};
|
|
209
213
|
}
|
|
214
|
+
function isActiveRailwayVolumeInstance(instance) {
|
|
215
|
+
const state = String(instance.state ?? "READY").toUpperCase();
|
|
216
|
+
return state !== "DELETING" && state !== "DELETED";
|
|
217
|
+
}
|
|
210
218
|
function normalizeVolumeInstances(value) {
|
|
211
219
|
const direct = Array.isArray(value) ? value : null;
|
|
212
220
|
if (direct) {
|
|
@@ -389,6 +397,7 @@ query TreeseedRailwayProjects($workspaceId: String!, $first: Int!) {
|
|
|
389
397
|
id
|
|
390
398
|
name
|
|
391
399
|
workspaceId
|
|
400
|
+
deletedAt
|
|
392
401
|
environments(first: 50) {
|
|
393
402
|
edges {
|
|
394
403
|
node {
|
|
@@ -428,6 +437,7 @@ query TreeseedRailwayProject($projectId: String!) {
|
|
|
428
437
|
id
|
|
429
438
|
name
|
|
430
439
|
workspaceId
|
|
440
|
+
deletedAt
|
|
431
441
|
environments(first: 50) {
|
|
432
442
|
edges {
|
|
433
443
|
node {
|
|
@@ -466,7 +476,7 @@ async function ensureRailwayProject({
|
|
|
466
476
|
const desiredProjectName = railwayConnectionLabel(projectName);
|
|
467
477
|
const desiredProjectId = railwayConnectionLabel(projectId);
|
|
468
478
|
const existing = projects.find(
|
|
469
|
-
(project2) => desiredProjectId && project2.id === desiredProjectId || desiredProjectName && project2.name === desiredProjectName
|
|
479
|
+
(project2) => !project2.deletedAt && (desiredProjectId && project2.id === desiredProjectId || desiredProjectName && project2.name === desiredProjectName)
|
|
470
480
|
) ?? null;
|
|
471
481
|
if (existing) {
|
|
472
482
|
return { workspace: workspaceContext, project: existing, created: false };
|
|
@@ -481,6 +491,7 @@ mutation TreeseedRailwayProjectCreate($input: ProjectCreateInput!) {
|
|
|
481
491
|
id
|
|
482
492
|
name
|
|
483
493
|
workspaceId
|
|
494
|
+
deletedAt
|
|
484
495
|
environments(first: 50) {
|
|
485
496
|
edges {
|
|
486
497
|
node {
|
|
@@ -622,6 +633,81 @@ mutation TreeseedRailwayServiceCreate($input: ServiceCreateInput!) {
|
|
|
622
633
|
}
|
|
623
634
|
return { service, created: true };
|
|
624
635
|
}
|
|
636
|
+
async function updateRailwayServiceName({
|
|
637
|
+
serviceId,
|
|
638
|
+
name,
|
|
639
|
+
env = process.env,
|
|
640
|
+
fetchImpl = fetch
|
|
641
|
+
}) {
|
|
642
|
+
const desiredName = railwayConnectionLabel(name);
|
|
643
|
+
if (!serviceId || !desiredName) {
|
|
644
|
+
throw new Error("Railway service rename requires a service id and name.");
|
|
645
|
+
}
|
|
646
|
+
const payload = await railwayGraphqlRequest({
|
|
647
|
+
query: `
|
|
648
|
+
mutation TreeseedRailwayServiceUpdate($id: String!, $input: ServiceUpdateInput!) {
|
|
649
|
+
serviceUpdate(id: $id, input: $input) {
|
|
650
|
+
id
|
|
651
|
+
name
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
`.trim(),
|
|
655
|
+
variables: {
|
|
656
|
+
id: serviceId,
|
|
657
|
+
input: { name: desiredName }
|
|
658
|
+
},
|
|
659
|
+
env,
|
|
660
|
+
fetchImpl
|
|
661
|
+
});
|
|
662
|
+
const service = payload.data?.serviceUpdate ? normalizeService(payload.data.serviceUpdate) : null;
|
|
663
|
+
if (!service) {
|
|
664
|
+
throw new Error(`Railway service rename did not return a usable service for ${desiredName}.`);
|
|
665
|
+
}
|
|
666
|
+
return service;
|
|
667
|
+
}
|
|
668
|
+
async function ensureRailwayPostgresService({
|
|
669
|
+
projectId,
|
|
670
|
+
environmentId,
|
|
671
|
+
serviceName,
|
|
672
|
+
env = process.env,
|
|
673
|
+
fetchImpl = fetch
|
|
674
|
+
}) {
|
|
675
|
+
const desiredServiceName = railwayConnectionLabel(serviceName);
|
|
676
|
+
if (!desiredServiceName) {
|
|
677
|
+
throw new Error("Railway Postgres service creation requires a service name.");
|
|
678
|
+
}
|
|
679
|
+
const services = await listRailwayServices({ projectId, env, fetchImpl });
|
|
680
|
+
const existing = services.find((service2) => service2.name === desiredServiceName || service2.id === desiredServiceName) ?? null;
|
|
681
|
+
if (existing) {
|
|
682
|
+
return { service: existing, created: false };
|
|
683
|
+
}
|
|
684
|
+
const created = await railwayGraphqlRequest({
|
|
685
|
+
query: `
|
|
686
|
+
mutation TreeseedRailwayPostgresServiceCreate($input: ServiceCreateInput!) {
|
|
687
|
+
serviceCreate(input: $input) {
|
|
688
|
+
id
|
|
689
|
+
name
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
`.trim(),
|
|
693
|
+
variables: {
|
|
694
|
+
input: {
|
|
695
|
+
projectId,
|
|
696
|
+
environmentId,
|
|
697
|
+
name: desiredServiceName,
|
|
698
|
+
templateId: RAILWAY_POSTGRES_TEMPLATE_ID,
|
|
699
|
+
templateServiceId: RAILWAY_POSTGRES_TEMPLATE_SERVICE_ID
|
|
700
|
+
}
|
|
701
|
+
},
|
|
702
|
+
env,
|
|
703
|
+
fetchImpl
|
|
704
|
+
});
|
|
705
|
+
const service = created.data?.serviceCreate ? normalizeService(created.data.serviceCreate) : null;
|
|
706
|
+
if (!service) {
|
|
707
|
+
throw new Error(`Railway Postgres service create did not return a usable service for ${desiredServiceName}.`);
|
|
708
|
+
}
|
|
709
|
+
return { service, created: true };
|
|
710
|
+
}
|
|
625
711
|
async function listRailwayServices({
|
|
626
712
|
projectId,
|
|
627
713
|
env = process.env,
|
|
@@ -877,25 +963,49 @@ async function upsertRailwayVariables({
|
|
|
877
963
|
if (Object.keys(variables).length === 0) {
|
|
878
964
|
return;
|
|
879
965
|
}
|
|
880
|
-
|
|
881
|
-
query: `
|
|
966
|
+
const query = `
|
|
882
967
|
mutation TreeseedRailwayVariableCollectionUpsert($input: VariableCollectionUpsertInput!) {
|
|
883
968
|
variableCollectionUpsert(input: $input)
|
|
884
969
|
}
|
|
885
|
-
`.trim()
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
970
|
+
`.trim();
|
|
971
|
+
const input = {
|
|
972
|
+
projectId,
|
|
973
|
+
environmentId,
|
|
974
|
+
serviceId: serviceId || null,
|
|
975
|
+
variables,
|
|
976
|
+
replace: false,
|
|
977
|
+
skipDeploys: true
|
|
978
|
+
};
|
|
979
|
+
try {
|
|
980
|
+
await railwayGraphqlRequest({
|
|
981
|
+
query,
|
|
982
|
+
variables: { input },
|
|
983
|
+
env,
|
|
984
|
+
fetchImpl
|
|
985
|
+
});
|
|
986
|
+
} catch (error) {
|
|
987
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
988
|
+
if (!/Problem processing request/iu.test(message) || Object.keys(variables).length <= 1) {
|
|
989
|
+
throw error;
|
|
990
|
+
}
|
|
991
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
992
|
+
await railwayGraphqlRequest({
|
|
993
|
+
query,
|
|
994
|
+
variables: {
|
|
995
|
+
input: {
|
|
996
|
+
projectId,
|
|
997
|
+
environmentId,
|
|
998
|
+
serviceId: serviceId || null,
|
|
999
|
+
variables: { [key]: value },
|
|
1000
|
+
replace: false,
|
|
1001
|
+
skipDeploys: true
|
|
1002
|
+
}
|
|
1003
|
+
},
|
|
1004
|
+
env,
|
|
1005
|
+
fetchImpl
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
899
1009
|
}
|
|
900
1010
|
async function listRailwayVolumes({
|
|
901
1011
|
projectId,
|
|
@@ -919,6 +1029,7 @@ query TreeseedRailwayVolumeList($projectId: String!) {
|
|
|
919
1029
|
serviceId
|
|
920
1030
|
environmentId
|
|
921
1031
|
mountPath
|
|
1032
|
+
state
|
|
922
1033
|
}
|
|
923
1034
|
}
|
|
924
1035
|
}
|
|
@@ -958,6 +1069,7 @@ mutation TreeseedRailwayVolumeCreate($input: VolumeCreateInput!) {
|
|
|
958
1069
|
serviceId
|
|
959
1070
|
environmentId
|
|
960
1071
|
mountPath
|
|
1072
|
+
state
|
|
961
1073
|
}
|
|
962
1074
|
}
|
|
963
1075
|
}
|
|
@@ -971,7 +1083,6 @@ mutation TreeseedRailwayVolumeCreate($input: VolumeCreateInput!) {
|
|
|
971
1083
|
projectId,
|
|
972
1084
|
environmentId,
|
|
973
1085
|
serviceId,
|
|
974
|
-
name,
|
|
975
1086
|
mountPath
|
|
976
1087
|
}
|
|
977
1088
|
},
|
|
@@ -982,6 +1093,25 @@ mutation TreeseedRailwayVolumeCreate($input: VolumeCreateInput!) {
|
|
|
982
1093
|
if (!volume) {
|
|
983
1094
|
throw new Error(`Railway volume create did not return a usable volume for ${name}.`);
|
|
984
1095
|
}
|
|
1096
|
+
if (name && volume.name !== name) {
|
|
1097
|
+
try {
|
|
1098
|
+
const renamed = await updateRailwayVolumeName({
|
|
1099
|
+
volumeId: volume.id,
|
|
1100
|
+
name,
|
|
1101
|
+
env,
|
|
1102
|
+
fetchImpl
|
|
1103
|
+
});
|
|
1104
|
+
return {
|
|
1105
|
+
...volume,
|
|
1106
|
+
name: renamed.name || name
|
|
1107
|
+
};
|
|
1108
|
+
} catch {
|
|
1109
|
+
return {
|
|
1110
|
+
...volume,
|
|
1111
|
+
name: volume.name || name
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
}
|
|
985
1115
|
return volume;
|
|
986
1116
|
}
|
|
987
1117
|
async function updateRailwayVolumeName({
|
|
@@ -991,8 +1121,8 @@ async function updateRailwayVolumeName({
|
|
|
991
1121
|
fetchImpl = fetch
|
|
992
1122
|
}) {
|
|
993
1123
|
const mutation = configuredEnvValue(env, "TREESEED_RAILWAY_VOLUME_UPDATE_MUTATION") || `
|
|
994
|
-
mutation TreeseedRailwayVolumeUpdate($
|
|
995
|
-
volumeUpdate(
|
|
1124
|
+
mutation TreeseedRailwayVolumeUpdate($volumeId: String!, $input: VolumeUpdateInput!) {
|
|
1125
|
+
volumeUpdate(volumeId: $volumeId, input: $input) {
|
|
996
1126
|
id
|
|
997
1127
|
name
|
|
998
1128
|
projectId
|
|
@@ -1003,6 +1133,7 @@ mutation TreeseedRailwayVolumeUpdate($id: String!, $input: VolumeUpdateInput!) {
|
|
|
1003
1133
|
serviceId
|
|
1004
1134
|
environmentId
|
|
1005
1135
|
mountPath
|
|
1136
|
+
state
|
|
1006
1137
|
}
|
|
1007
1138
|
}
|
|
1008
1139
|
}
|
|
@@ -1012,7 +1143,7 @@ mutation TreeseedRailwayVolumeUpdate($id: String!, $input: VolumeUpdateInput!) {
|
|
|
1012
1143
|
const payload = await railwayGraphqlRequest({
|
|
1013
1144
|
query: mutation,
|
|
1014
1145
|
variables: {
|
|
1015
|
-
|
|
1146
|
+
volumeId,
|
|
1016
1147
|
input: { name }
|
|
1017
1148
|
},
|
|
1018
1149
|
env,
|
|
@@ -1021,26 +1152,25 @@ mutation TreeseedRailwayVolumeUpdate($id: String!, $input: VolumeUpdateInput!) {
|
|
|
1021
1152
|
return collectRailwayVolumes(payload.data)[0] ?? null;
|
|
1022
1153
|
}
|
|
1023
1154
|
async function updateRailwayVolumeInstanceMountPath({
|
|
1024
|
-
|
|
1155
|
+
volumeId,
|
|
1156
|
+
serviceId,
|
|
1025
1157
|
mountPath,
|
|
1026
1158
|
env = process.env,
|
|
1027
1159
|
fetchImpl = fetch
|
|
1028
1160
|
}) {
|
|
1029
1161
|
const mutation = configuredEnvValue(env, "TREESEED_RAILWAY_VOLUME_INSTANCE_UPDATE_MUTATION") || `
|
|
1030
|
-
mutation TreeseedRailwayVolumeInstanceUpdate($
|
|
1031
|
-
volumeInstanceUpdate(
|
|
1032
|
-
id
|
|
1033
|
-
serviceId
|
|
1034
|
-
environmentId
|
|
1035
|
-
mountPath
|
|
1036
|
-
}
|
|
1162
|
+
mutation TreeseedRailwayVolumeInstanceUpdate($volumeId: String!, $input: VolumeInstanceUpdateInput!) {
|
|
1163
|
+
volumeInstanceUpdate(volumeId: $volumeId, input: $input)
|
|
1037
1164
|
}
|
|
1038
1165
|
`.trim();
|
|
1039
1166
|
await railwayGraphqlRequest({
|
|
1040
1167
|
query: mutation,
|
|
1041
1168
|
variables: {
|
|
1042
|
-
|
|
1043
|
-
input: {
|
|
1169
|
+
volumeId,
|
|
1170
|
+
input: {
|
|
1171
|
+
...serviceId ? { serviceId } : {},
|
|
1172
|
+
mountPath
|
|
1173
|
+
}
|
|
1044
1174
|
},
|
|
1045
1175
|
env,
|
|
1046
1176
|
fetchImpl
|
|
@@ -1059,9 +1189,13 @@ async function ensureRailwayServiceVolume({
|
|
|
1059
1189
|
throw new Error(`Railway volume mount path must be absolute: ${mountPath}`);
|
|
1060
1190
|
}
|
|
1061
1191
|
const volumes = await listRailwayVolumes({ projectId, env, fetchImpl });
|
|
1062
|
-
|
|
1192
|
+
const activeVolumes = volumes.map((candidate) => ({
|
|
1193
|
+
...candidate,
|
|
1194
|
+
instances: candidate.instances.filter(isActiveRailwayVolumeInstance)
|
|
1195
|
+
})).filter((candidate) => candidate.instances.length > 0);
|
|
1196
|
+
let volume = activeVolumes.find(
|
|
1063
1197
|
(candidate) => candidate.instances.some((instance2) => instance2.serviceId === serviceId && instance2.environmentId === environmentId)
|
|
1064
|
-
) ??
|
|
1198
|
+
) ?? activeVolumes.find((candidate) => candidate.name === name) ?? null;
|
|
1065
1199
|
let created = false;
|
|
1066
1200
|
let updated = false;
|
|
1067
1201
|
if (!volume) {
|
|
@@ -1080,9 +1214,15 @@ async function ensureRailwayServiceVolume({
|
|
|
1080
1214
|
volume = await updateRailwayVolumeName({ volumeId: volume.id, name, env, fetchImpl }) ?? { ...volume, name };
|
|
1081
1215
|
updated = true;
|
|
1082
1216
|
}
|
|
1083
|
-
|
|
1217
|
+
let instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? null;
|
|
1218
|
+
if (!instance && volume.instances.some((entry) => entry.environmentId === environmentId)) {
|
|
1219
|
+
await updateRailwayVolumeInstanceMountPath({ volumeId: volume.id, serviceId, mountPath, env, fetchImpl });
|
|
1220
|
+
volume = await listRailwayVolumes({ projectId, env, fetchImpl }).then((refreshed) => refreshed.find((candidate) => candidate.id === volume?.id) ?? volume);
|
|
1221
|
+
instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? null;
|
|
1222
|
+
updated = true;
|
|
1223
|
+
}
|
|
1084
1224
|
if (instance && instance.mountPath !== mountPath) {
|
|
1085
|
-
await updateRailwayVolumeInstanceMountPath({
|
|
1225
|
+
await updateRailwayVolumeInstanceMountPath({ volumeId: volume.id, mountPath, env, fetchImpl });
|
|
1086
1226
|
volume = {
|
|
1087
1227
|
...volume,
|
|
1088
1228
|
instances: volume.instances.map((entry) => entry.id === instance.id ? { ...entry, mountPath } : entry)
|
|
@@ -1138,8 +1278,72 @@ query TreeseedRailwayCustomDomains($projectId: String!, $environmentId: String!,
|
|
|
1138
1278
|
});
|
|
1139
1279
|
return Array.isArray(payload.data?.domains?.customDomains) ? payload.data.domains.customDomains.map((entry) => entry && typeof entry === "object" ? normalizeRailwayCustomDomain(entry) : null).filter(Boolean) : [];
|
|
1140
1280
|
}
|
|
1281
|
+
async function ensureRailwayCustomDomain({
|
|
1282
|
+
projectId,
|
|
1283
|
+
environmentId,
|
|
1284
|
+
serviceId,
|
|
1285
|
+
domain,
|
|
1286
|
+
env = process.env,
|
|
1287
|
+
fetchImpl = fetch
|
|
1288
|
+
}) {
|
|
1289
|
+
const normalizedDomain = railwayConnectionLabel(domain);
|
|
1290
|
+
if (!normalizedDomain) {
|
|
1291
|
+
throw new Error("Railway custom domain creation requires a domain.");
|
|
1292
|
+
}
|
|
1293
|
+
const existing = await listRailwayCustomDomains({ projectId, environmentId, serviceId, env, fetchImpl });
|
|
1294
|
+
const matched = existing.find((entry) => entry.domain === normalizedDomain) ?? null;
|
|
1295
|
+
if (matched) {
|
|
1296
|
+
return { domain: matched, created: false };
|
|
1297
|
+
}
|
|
1298
|
+
const payload = await railwayGraphqlRequest({
|
|
1299
|
+
query: `
|
|
1300
|
+
mutation TreeseedRailwayCustomDomainCreate($input: CustomDomainCreateInput!) {
|
|
1301
|
+
customDomainCreate(input: $input) {
|
|
1302
|
+
id
|
|
1303
|
+
domain
|
|
1304
|
+
environmentId
|
|
1305
|
+
serviceId
|
|
1306
|
+
targetPort
|
|
1307
|
+
status {
|
|
1308
|
+
verified
|
|
1309
|
+
certificateStatus
|
|
1310
|
+
verificationDnsHost
|
|
1311
|
+
verificationToken
|
|
1312
|
+
dnsRecords {
|
|
1313
|
+
fqdn
|
|
1314
|
+
hostlabel
|
|
1315
|
+
recordType
|
|
1316
|
+
requiredValue
|
|
1317
|
+
currentValue
|
|
1318
|
+
status
|
|
1319
|
+
zone
|
|
1320
|
+
purpose
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
`.trim(),
|
|
1326
|
+
variables: {
|
|
1327
|
+
input: {
|
|
1328
|
+
projectId,
|
|
1329
|
+
environmentId,
|
|
1330
|
+
serviceId,
|
|
1331
|
+
domain: normalizedDomain
|
|
1332
|
+
}
|
|
1333
|
+
},
|
|
1334
|
+
env,
|
|
1335
|
+
fetchImpl
|
|
1336
|
+
});
|
|
1337
|
+
const created = payload.data?.customDomainCreate ? normalizeRailwayCustomDomain(payload.data.customDomainCreate) : null;
|
|
1338
|
+
if (!created) {
|
|
1339
|
+
throw new Error(`Railway custom domain create did not return a usable domain for ${normalizedDomain}.`);
|
|
1340
|
+
}
|
|
1341
|
+
return { domain: created, created: true };
|
|
1342
|
+
}
|
|
1141
1343
|
export {
|
|
1344
|
+
ensureRailwayCustomDomain,
|
|
1142
1345
|
ensureRailwayEnvironment,
|
|
1346
|
+
ensureRailwayPostgresService,
|
|
1143
1347
|
ensureRailwayProject,
|
|
1144
1348
|
ensureRailwayService,
|
|
1145
1349
|
ensureRailwayServiceInstanceConfiguration,
|
|
@@ -1160,5 +1364,6 @@ export {
|
|
|
1160
1364
|
resolveRailwayApiUrl,
|
|
1161
1365
|
resolveRailwayWorkspace,
|
|
1162
1366
|
resolveRailwayWorkspaceContext,
|
|
1367
|
+
updateRailwayServiceName,
|
|
1163
1368
|
upsertRailwayVariables
|
|
1164
1369
|
};
|