@robinmordasiewicz/f5xc-xcsh 2.0.27-2601161624 → 2.0.27-2601161808

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 (2) hide show
  1. package/dist/index.js +1271 -45
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2022,14 +2022,14 @@ var require_react_development = __commonJS({
2022
2022
  var thenableResult = result;
2023
2023
  var wasAwaited = false;
2024
2024
  var thenable = {
2025
- then: function(resolve2, reject) {
2025
+ then: function(resolve3, reject) {
2026
2026
  wasAwaited = true;
2027
2027
  thenableResult.then(function(returnValue2) {
2028
2028
  popActScope(prevActScopeDepth);
2029
2029
  if (actScopeDepth === 0) {
2030
- recursivelyFlushAsyncActWork(returnValue2, resolve2, reject);
2030
+ recursivelyFlushAsyncActWork(returnValue2, resolve3, reject);
2031
2031
  } else {
2032
- resolve2(returnValue2);
2032
+ resolve3(returnValue2);
2033
2033
  }
2034
2034
  }, function(error2) {
2035
2035
  popActScope(prevActScopeDepth);
@@ -2059,20 +2059,20 @@ var require_react_development = __commonJS({
2059
2059
  ReactCurrentActQueue.current = null;
2060
2060
  }
2061
2061
  var _thenable = {
2062
- then: function(resolve2, reject) {
2062
+ then: function(resolve3, reject) {
2063
2063
  if (ReactCurrentActQueue.current === null) {
2064
2064
  ReactCurrentActQueue.current = [];
2065
- recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
2065
+ recursivelyFlushAsyncActWork(returnValue, resolve3, reject);
2066
2066
  } else {
2067
- resolve2(returnValue);
2067
+ resolve3(returnValue);
2068
2068
  }
2069
2069
  }
2070
2070
  };
2071
2071
  return _thenable;
2072
2072
  } else {
2073
2073
  var _thenable2 = {
2074
- then: function(resolve2, reject) {
2075
- resolve2(returnValue);
2074
+ then: function(resolve3, reject) {
2075
+ resolve3(returnValue);
2076
2076
  }
2077
2077
  };
2078
2078
  return _thenable2;
@@ -2088,7 +2088,7 @@ var require_react_development = __commonJS({
2088
2088
  actScopeDepth = prevActScopeDepth;
2089
2089
  }
2090
2090
  }
2091
- function recursivelyFlushAsyncActWork(returnValue, resolve2, reject) {
2091
+ function recursivelyFlushAsyncActWork(returnValue, resolve3, reject) {
2092
2092
  {
2093
2093
  var queue = ReactCurrentActQueue.current;
2094
2094
  if (queue !== null) {
@@ -2097,16 +2097,16 @@ var require_react_development = __commonJS({
2097
2097
  enqueueTask(function() {
2098
2098
  if (queue.length === 0) {
2099
2099
  ReactCurrentActQueue.current = null;
2100
- resolve2(returnValue);
2100
+ resolve3(returnValue);
2101
2101
  } else {
2102
- recursivelyFlushAsyncActWork(returnValue, resolve2, reject);
2102
+ recursivelyFlushAsyncActWork(returnValue, resolve3, reject);
2103
2103
  }
2104
2104
  });
2105
2105
  } catch (error2) {
2106
2106
  reject(error2);
2107
2107
  }
2108
2108
  } else {
2109
- resolve2(returnValue);
2109
+ resolve3(returnValue);
2110
2110
  }
2111
2111
  }
2112
2112
  }
@@ -28134,7 +28134,7 @@ var require_command = __commonJS({
28134
28134
  var EventEmitter3 = __require("events").EventEmitter;
28135
28135
  var childProcess = __require("child_process");
28136
28136
  var path = __require("path");
28137
- var fs4 = __require("fs");
28137
+ var fs5 = __require("fs");
28138
28138
  var process13 = __require("process");
28139
28139
  var { Argument: Argument2, humanReadableArgName } = require_argument();
28140
28140
  var { CommanderError: CommanderError2 } = require_error();
@@ -29067,10 +29067,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
29067
29067
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
29068
29068
  function findFile(baseDir, baseName) {
29069
29069
  const localBin = path.resolve(baseDir, baseName);
29070
- if (fs4.existsSync(localBin)) return localBin;
29070
+ if (fs5.existsSync(localBin)) return localBin;
29071
29071
  if (sourceExt.includes(path.extname(baseName))) return void 0;
29072
29072
  const foundExt = sourceExt.find(
29073
- (ext) => fs4.existsSync(`${localBin}${ext}`)
29073
+ (ext) => fs5.existsSync(`${localBin}${ext}`)
29074
29074
  );
29075
29075
  if (foundExt) return `${localBin}${foundExt}`;
29076
29076
  return void 0;
@@ -29082,7 +29082,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
29082
29082
  if (this._scriptPath) {
29083
29083
  let resolvedScriptPath;
29084
29084
  try {
29085
- resolvedScriptPath = fs4.realpathSync(this._scriptPath);
29085
+ resolvedScriptPath = fs5.realpathSync(this._scriptPath);
29086
29086
  } catch (err) {
29087
29087
  resolvedScriptPath = this._scriptPath;
29088
29088
  }
@@ -41228,8 +41228,8 @@ var init_logo_renderer = __esm({
41228
41228
 
41229
41229
  // src/branding/index.ts
41230
41230
  function getVersion() {
41231
- if ("v2.0.27-2601161624") {
41232
- return "v2.0.27-2601161624";
41231
+ if ("v2.0.27-2601161808") {
41232
+ return "v2.0.27-2601161808";
41233
41233
  }
41234
41234
  if (process.env.XCSH_VERSION) {
41235
41235
  return process.env.XCSH_VERSION;
@@ -48151,14 +48151,14 @@ var require_parser = __commonJS({
48151
48151
  case "scalar":
48152
48152
  case "single-quoted-scalar":
48153
48153
  case "double-quoted-scalar": {
48154
- const fs4 = this.flowScalar(this.type);
48154
+ const fs5 = this.flowScalar(this.type);
48155
48155
  if (atNextItem || it.value) {
48156
- map.items.push({ start, key: fs4, sep: [] });
48156
+ map.items.push({ start, key: fs5, sep: [] });
48157
48157
  this.onKeyLine = true;
48158
48158
  } else if (it.sep) {
48159
- this.stack.push(fs4);
48159
+ this.stack.push(fs5);
48160
48160
  } else {
48161
- Object.assign(it, { key: fs4, sep: [] });
48161
+ Object.assign(it, { key: fs5, sep: [] });
48162
48162
  this.onKeyLine = true;
48163
48163
  }
48164
48164
  return;
@@ -48286,13 +48286,13 @@ var require_parser = __commonJS({
48286
48286
  case "scalar":
48287
48287
  case "single-quoted-scalar":
48288
48288
  case "double-quoted-scalar": {
48289
- const fs4 = this.flowScalar(this.type);
48289
+ const fs5 = this.flowScalar(this.type);
48290
48290
  if (!it || it.value)
48291
- fc.items.push({ start: [], key: fs4, sep: [] });
48291
+ fc.items.push({ start: [], key: fs5, sep: [] });
48292
48292
  else if (it.sep)
48293
- this.stack.push(fs4);
48293
+ this.stack.push(fs5);
48294
48294
  else
48295
- Object.assign(it, { key: fs4, sep: [] });
48295
+ Object.assign(it, { key: fs5, sep: [] });
48296
48296
  return;
48297
48297
  }
48298
48298
  case "flow-map-end":
@@ -77889,17 +77889,47 @@ var init_flag_aliases = __esm({
77889
77889
  "src/repl/completion/flag-aliases.ts"() {
77890
77890
  "use strict";
77891
77891
  FLAG_ALIAS_GROUPS = [
77892
+ // Common flags
77892
77893
  ["--namespace", "-ns"],
77893
77894
  ["--output", "-o"],
77894
77895
  ["--name", "-n"],
77895
77896
  ["--file", "-f"],
77896
77897
  ["--url", "-u"],
77897
- ["--token", "-t"],
77898
77898
  ["--limit"],
77899
77899
  ["--label"],
77900
77900
  ["--show-labels"],
77901
77901
  ["--force"],
77902
- ["--cascade"]
77902
+ ["--cascade"],
77903
+ // Creation flags for healthcheck
77904
+ ["--type", "-t"],
77905
+ ["--interval"],
77906
+ ["--timeout"],
77907
+ ["--healthy-threshold"],
77908
+ ["--unhealthy-threshold"],
77909
+ ["--path"],
77910
+ ["--expected-status"],
77911
+ ["--host-header"],
77912
+ ["--use-origin-server-name"],
77913
+ ["--use-http2"],
77914
+ // Creation flags for origin_pool
77915
+ ["--port"],
77916
+ ["--automatic-port"],
77917
+ ["--lb-port"],
77918
+ ["--public-ip"],
77919
+ ["--public-name"],
77920
+ ["--private-ip"],
77921
+ ["--private-name"],
77922
+ ["--k8s-service"],
77923
+ ["--consul-service"],
77924
+ ["--custom-endpoint"],
77925
+ ["--vn-private-ip"],
77926
+ ["--vn-private-name"],
77927
+ ["--cbip-service"],
77928
+ ["--algorithm"],
77929
+ ["--health-check"],
77930
+ ["--no-tls"],
77931
+ ["--use-tls"],
77932
+ ["--site"]
77903
77933
  ];
77904
77934
  FLAG_ALIAS_LOOKUP = buildFlagAliasLookup();
77905
77935
  }
@@ -77933,6 +77963,21 @@ function filterUsedFlagsFromStrings(flags, args) {
77933
77963
  const usedFlags = extractUsedFlags(args);
77934
77964
  return flags.filter((flag) => !usedFlags.has(flag));
77935
77965
  }
77966
+ function countFlagUsage(args) {
77967
+ const counts = /* @__PURE__ */ new Map();
77968
+ for (const arg of args) {
77969
+ let flagPart = arg;
77970
+ if (arg.includes("=")) {
77971
+ flagPart = arg.split("=")[0] ?? arg;
77972
+ }
77973
+ if (!flagPart.startsWith("-")) {
77974
+ continue;
77975
+ }
77976
+ const current = counts.get(flagPart) || 0;
77977
+ counts.set(flagPart, current + 1);
77978
+ }
77979
+ return counts;
77980
+ }
77936
77981
  var init_flag_utils = __esm({
77937
77982
  "src/repl/completion/flag-utils.ts"() {
77938
77983
  "use strict";
@@ -84659,6 +84704,275 @@ var init_resource_fetcher = __esm({
84659
84704
  }
84660
84705
  });
84661
84706
 
84707
+ // src/repl/completion/creation-flags.ts
84708
+ function getCreationFlags(resourceType) {
84709
+ return CREATION_FLAGS_REGISTRY.get(resourceType) ?? [];
84710
+ }
84711
+ function hasCreationFlags(resourceType) {
84712
+ return CREATION_FLAGS_REGISTRY.has(resourceType);
84713
+ }
84714
+ var HEALTHCHECK_CREATION_FLAGS, ORIGIN_POOL_CREATION_FLAGS, CREATION_FLAGS_REGISTRY;
84715
+ var init_creation_flags = __esm({
84716
+ "src/repl/completion/creation-flags.ts"() {
84717
+ "use strict";
84718
+ HEALTHCHECK_CREATION_FLAGS = [
84719
+ // Required flags
84720
+ {
84721
+ name: "--name",
84722
+ shortName: "-n",
84723
+ description: "Resource name",
84724
+ required: true,
84725
+ hasValue: true,
84726
+ valueType: "string"
84727
+ },
84728
+ {
84729
+ name: "--type",
84730
+ shortName: "-t",
84731
+ description: "Health check type",
84732
+ required: true,
84733
+ hasValue: true,
84734
+ valueType: "enum",
84735
+ enumValues: ["http", "tcp", "dns", "udp-icmp"]
84736
+ },
84737
+ {
84738
+ name: "--interval",
84739
+ description: "Interval between checks (1-600 sec)",
84740
+ required: true,
84741
+ hasValue: true,
84742
+ valueType: "integer"
84743
+ },
84744
+ {
84745
+ name: "--timeout",
84746
+ description: "Timeout for each check (1-600 sec)",
84747
+ required: true,
84748
+ hasValue: true,
84749
+ valueType: "integer"
84750
+ },
84751
+ {
84752
+ name: "--healthy-threshold",
84753
+ description: "Successes before healthy (1-16)",
84754
+ required: true,
84755
+ hasValue: true,
84756
+ valueType: "integer"
84757
+ },
84758
+ {
84759
+ name: "--unhealthy-threshold",
84760
+ description: "Failures before unhealthy (1-16)",
84761
+ required: true,
84762
+ hasValue: true,
84763
+ valueType: "integer"
84764
+ },
84765
+ // HTTP-specific (conditionally required when type=http)
84766
+ {
84767
+ name: "--path",
84768
+ description: "HTTP path to check",
84769
+ required: false,
84770
+ hasValue: true,
84771
+ valueType: "string"
84772
+ },
84773
+ {
84774
+ name: "--expected-status",
84775
+ description: "Expected HTTP status codes",
84776
+ required: false,
84777
+ hasValue: true,
84778
+ valueType: "string"
84779
+ },
84780
+ {
84781
+ name: "--host-header",
84782
+ description: "Host header value",
84783
+ required: false,
84784
+ hasValue: true,
84785
+ valueType: "string"
84786
+ },
84787
+ {
84788
+ name: "--use-origin-server-name",
84789
+ description: "Use origin server hostname",
84790
+ required: false,
84791
+ hasValue: false
84792
+ },
84793
+ {
84794
+ name: "--use-http2",
84795
+ description: "Use HTTP/2",
84796
+ required: false,
84797
+ hasValue: false
84798
+ }
84799
+ ];
84800
+ ORIGIN_POOL_CREATION_FLAGS = [
84801
+ // Required - Name
84802
+ {
84803
+ name: "--name",
84804
+ shortName: "-n",
84805
+ description: "Origin pool name",
84806
+ required: true,
84807
+ hasValue: true,
84808
+ valueType: "string"
84809
+ },
84810
+ // Port configuration (mutually exclusive group)
84811
+ {
84812
+ name: "--port",
84813
+ description: "Backend port (1-65535)",
84814
+ required: false,
84815
+ hasValue: true,
84816
+ valueType: "integer"
84817
+ },
84818
+ {
84819
+ name: "--automatic-port",
84820
+ description: "Use automatic port selection",
84821
+ required: false,
84822
+ hasValue: false
84823
+ },
84824
+ {
84825
+ name: "--lb-port",
84826
+ description: "Use load balancer port",
84827
+ required: false,
84828
+ hasValue: false
84829
+ },
84830
+ // Origin Server Types (ALL 10 - REPEATABLE)
84831
+ {
84832
+ name: "--public-ip",
84833
+ description: "Public IP origin server (repeatable)",
84834
+ required: false,
84835
+ hasValue: true,
84836
+ valueType: "string",
84837
+ isRepeatable: true,
84838
+ maxOccurrences: 32
84839
+ },
84840
+ {
84841
+ name: "--public-name",
84842
+ description: "Public DNS name origin (repeatable)",
84843
+ required: false,
84844
+ hasValue: true,
84845
+ valueType: "string",
84846
+ isRepeatable: true,
84847
+ maxOccurrences: 32
84848
+ },
84849
+ {
84850
+ name: "--private-ip",
84851
+ description: "Private IP origin (site required) (repeatable)",
84852
+ required: false,
84853
+ hasValue: true,
84854
+ valueType: "string",
84855
+ isRepeatable: true,
84856
+ maxOccurrences: 32
84857
+ },
84858
+ {
84859
+ name: "--private-name",
84860
+ description: "Private DNS name origin (site required) (repeatable)",
84861
+ required: false,
84862
+ hasValue: true,
84863
+ valueType: "string",
84864
+ isRepeatable: true,
84865
+ maxOccurrences: 32
84866
+ },
84867
+ {
84868
+ name: "--k8s-service",
84869
+ description: "Kubernetes service origin (format: namespace/service) (repeatable)",
84870
+ required: false,
84871
+ hasValue: true,
84872
+ valueType: "string",
84873
+ isRepeatable: true,
84874
+ maxOccurrences: 32
84875
+ },
84876
+ {
84877
+ name: "--consul-service",
84878
+ description: "Consul service origin (repeatable)",
84879
+ required: false,
84880
+ hasValue: true,
84881
+ valueType: "string",
84882
+ isRepeatable: true,
84883
+ maxOccurrences: 32
84884
+ },
84885
+ {
84886
+ name: "--custom-endpoint",
84887
+ description: "Custom endpoint object reference (repeatable)",
84888
+ required: false,
84889
+ hasValue: true,
84890
+ valueType: "string",
84891
+ isRepeatable: true,
84892
+ maxOccurrences: 32
84893
+ },
84894
+ {
84895
+ name: "--vn-private-ip",
84896
+ description: "Virtual network private IP (repeatable)",
84897
+ required: false,
84898
+ hasValue: true,
84899
+ valueType: "string",
84900
+ isRepeatable: true,
84901
+ maxOccurrences: 32
84902
+ },
84903
+ {
84904
+ name: "--vn-private-name",
84905
+ description: "Virtual network private DNS name (repeatable)",
84906
+ required: false,
84907
+ hasValue: true,
84908
+ valueType: "string",
84909
+ isRepeatable: true,
84910
+ maxOccurrences: 32
84911
+ },
84912
+ {
84913
+ name: "--cbip-service",
84914
+ description: "Cloud-based IP service (repeatable)",
84915
+ required: false,
84916
+ hasValue: true,
84917
+ valueType: "string",
84918
+ isRepeatable: true,
84919
+ maxOccurrences: 32
84920
+ },
84921
+ // Load Balancing Algorithm
84922
+ {
84923
+ name: "--algorithm",
84924
+ description: "Load balancing algorithm",
84925
+ required: false,
84926
+ hasValue: true,
84927
+ valueType: "enum",
84928
+ enumValues: [
84929
+ "ROUND_ROBIN",
84930
+ "LEAST_ACTIVE",
84931
+ "RANDOM",
84932
+ "SOURCE_IP_STICKINESS",
84933
+ "COOKIE_STICKINESS",
84934
+ "RING_HASH"
84935
+ ]
84936
+ },
84937
+ // Health Checks (repeatable, max 4)
84938
+ {
84939
+ name: "--health-check",
84940
+ description: "Health check reference (repeatable, max 4)",
84941
+ required: false,
84942
+ hasValue: true,
84943
+ valueType: "string",
84944
+ isRepeatable: true,
84945
+ maxOccurrences: 4
84946
+ },
84947
+ // TLS Configuration
84948
+ {
84949
+ name: "--no-tls",
84950
+ description: "Disable TLS for origin connections",
84951
+ required: false,
84952
+ hasValue: false
84953
+ },
84954
+ {
84955
+ name: "--use-tls",
84956
+ description: "Enable TLS for origin connections",
84957
+ required: false,
84958
+ hasValue: false
84959
+ },
84960
+ // Site reference (for private origins)
84961
+ {
84962
+ name: "--site",
84963
+ description: "Site reference for private origins",
84964
+ required: false,
84965
+ hasValue: true,
84966
+ valueType: "string"
84967
+ }
84968
+ ];
84969
+ CREATION_FLAGS_REGISTRY = /* @__PURE__ */ new Map([
84970
+ ["healthcheck", HEALTHCHECK_CREATION_FLAGS],
84971
+ ["origin_pool", ORIGIN_POOL_CREATION_FLAGS]
84972
+ ]);
84973
+ }
84974
+ });
84975
+
84662
84976
  // src/repl/completion/completer.ts
84663
84977
  function isResourceCompletionAppropriate(resource) {
84664
84978
  if (resource.isPrimary) {
@@ -84731,7 +85045,32 @@ function parseInput(text) {
84731
85045
  "--file",
84732
85046
  "-f",
84733
85047
  "--limit",
84734
- "--label"
85048
+ "--label",
85049
+ // Creation flags for healthcheck
85050
+ "--type",
85051
+ "-t",
85052
+ "--interval",
85053
+ "--timeout",
85054
+ "--healthy-threshold",
85055
+ "--unhealthy-threshold",
85056
+ "--path",
85057
+ "--expected-status",
85058
+ "--host-header",
85059
+ // Creation flags for origin_pool
85060
+ "--port",
85061
+ "--public-ip",
85062
+ "--public-name",
85063
+ "--private-ip",
85064
+ "--private-name",
85065
+ "--k8s-service",
85066
+ "--consul-service",
85067
+ "--custom-endpoint",
85068
+ "--vn-private-ip",
85069
+ "--vn-private-name",
85070
+ "--cbip-service",
85071
+ "--algorithm",
85072
+ "--health-check",
85073
+ "--site"
84735
85074
  ];
84736
85075
  if (args.length >= 1 && !currentWord.startsWith("-")) {
84737
85076
  const flagIndex = endsWithSpace ? args.length - 1 : args.length - 2;
@@ -84760,7 +85099,7 @@ function parseInput(text) {
84760
85099
  currentFlag
84761
85100
  };
84762
85101
  }
84763
- var RESOURCE_ACTIONS, GENERIC_RESOURCE_DESCRIPTIONS, EXCLUDED_RESOURCE_CATEGORIES, Completer;
85102
+ var RESOURCE_ACTIONS, CREATION_ACTIONS, GENERIC_RESOURCE_DESCRIPTIONS, EXCLUDED_RESOURCE_CATEGORIES, Completer;
84764
85103
  var init_completer = __esm({
84765
85104
  "src/repl/completion/completer.ts"() {
84766
85105
  "use strict";
@@ -84773,6 +85112,7 @@ var init_completer = __esm({
84773
85112
  init_resource_fetcher();
84774
85113
  init_settings();
84775
85114
  init_flag_utils();
85115
+ init_creation_flags();
84776
85116
  RESOURCE_ACTIONS = /* @__PURE__ */ new Set([
84777
85117
  "list",
84778
85118
  "get",
@@ -84785,6 +85125,7 @@ var init_completer = __esm({
84785
85125
  "add-labels",
84786
85126
  "remove-labels"
84787
85127
  ]);
85128
+ CREATION_ACTIONS = /* @__PURE__ */ new Set(["create", "apply"]);
84788
85129
  GENERIC_RESOURCE_DESCRIPTIONS = /* @__PURE__ */ new Set([
84789
85130
  "Resource retrieval operation",
84790
85131
  "Resource creation operation",
@@ -84857,6 +85198,12 @@ var init_completer = __esm({
84857
85198
  );
84858
85199
  }
84859
85200
  if (resourceCtx.resourceType) {
85201
+ if (resourceCtx.action && CREATION_ACTIONS.has(resourceCtx.action) && hasCreationFlags(resourceCtx.resourceType)) {
85202
+ return this.getCreationFlagSuggestions(
85203
+ resourceCtx.resourceType,
85204
+ parsed.args
85205
+ );
85206
+ }
84860
85207
  const resourceNames = await this.getResourceNameSuggestions(
84861
85208
  resourceCtx.resourceType,
84862
85209
  resourceCtx.resourceNamePartial
@@ -85418,6 +85765,60 @@ var init_completer = __esm({
85418
85765
  }
85419
85766
  return actionFlags;
85420
85767
  }
85768
+ /**
85769
+ * Get creation flag suggestions for a resource type
85770
+ * Shows flags needed to create a new resource (--name, --type, etc.)
85771
+ * instead of existing resource names
85772
+ *
85773
+ * Handles repeatable flags (e.g., --public-ip can be specified multiple times)
85774
+ * by checking maxOccurrences instead of simply filtering out used flags.
85775
+ *
85776
+ * @param resourceType - The resource type being created
85777
+ * @param args - Current command arguments to filter out used flags
85778
+ * @returns Array of flag suggestions for resource creation
85779
+ */
85780
+ getCreationFlagSuggestions(resourceType, args) {
85781
+ const creationFlags = getCreationFlags(resourceType);
85782
+ const usedFlags = extractUsedFlags(args);
85783
+ const flagUsageCounts = countFlagUsage(args);
85784
+ const suggestions = [];
85785
+ if (!usedFlags.has("--file") && !usedFlags.has("-f")) {
85786
+ suggestions.push({
85787
+ text: "--file",
85788
+ description: "Configuration file (YAML/JSON)",
85789
+ category: "flag"
85790
+ });
85791
+ }
85792
+ for (const flag of creationFlags) {
85793
+ if (flag.isRepeatable) {
85794
+ const count = flagUsageCounts.get(flag.name) || 0;
85795
+ const max = flag.maxOccurrences || Infinity;
85796
+ if (count >= max) continue;
85797
+ const marker = " (repeatable)";
85798
+ suggestions.push({
85799
+ text: flag.name,
85800
+ description: flag.description + marker,
85801
+ category: "flag"
85802
+ });
85803
+ } else {
85804
+ if (usedFlags.has(flag.name)) continue;
85805
+ if (flag.shortName && usedFlags.has(flag.shortName)) continue;
85806
+ const marker = flag.required ? " (required)" : "";
85807
+ suggestions.push({
85808
+ text: flag.name,
85809
+ description: flag.description + marker,
85810
+ category: "flag"
85811
+ });
85812
+ }
85813
+ }
85814
+ const commonFlags = this.getCommonFlagSuggestions();
85815
+ for (const flag of commonFlags) {
85816
+ if (!usedFlags.has(flag.text)) {
85817
+ suggestions.push(flag);
85818
+ }
85819
+ }
85820
+ return suggestions;
85821
+ }
85421
85822
  /**
85422
85823
  * Get flag completions filtered by prefix
85423
85824
  * @param prefix - The prefix to filter by
@@ -85522,6 +85923,159 @@ var init_completer = __esm({
85522
85923
  category: "value"
85523
85924
  }
85524
85925
  ].filter((s) => s.text.startsWith(valuePartial));
85926
+ // Creation flag value completions for healthcheck
85927
+ case "--type":
85928
+ case "-t":
85929
+ return [
85930
+ {
85931
+ text: "http",
85932
+ description: "HTTP health check",
85933
+ category: "value"
85934
+ },
85935
+ {
85936
+ text: "tcp",
85937
+ description: "TCP health check",
85938
+ category: "value"
85939
+ },
85940
+ {
85941
+ text: "dns",
85942
+ description: "DNS health check",
85943
+ category: "value"
85944
+ },
85945
+ {
85946
+ text: "udp-icmp",
85947
+ description: "UDP ICMP health check",
85948
+ category: "value"
85949
+ }
85950
+ ].filter((s) => s.text.startsWith(lowerPartial));
85951
+ case "--interval":
85952
+ case "--timeout":
85953
+ return [
85954
+ {
85955
+ text: "5",
85956
+ description: "5 seconds",
85957
+ category: "value"
85958
+ },
85959
+ {
85960
+ text: "10",
85961
+ description: "10 seconds",
85962
+ category: "value"
85963
+ },
85964
+ {
85965
+ text: "30",
85966
+ description: "30 seconds",
85967
+ category: "value"
85968
+ },
85969
+ {
85970
+ text: "60",
85971
+ description: "1 minute",
85972
+ category: "value"
85973
+ }
85974
+ ].filter((s) => s.text.startsWith(valuePartial));
85975
+ case "--healthy-threshold":
85976
+ case "--unhealthy-threshold":
85977
+ return [
85978
+ {
85979
+ text: "2",
85980
+ description: "2 checks",
85981
+ category: "value"
85982
+ },
85983
+ {
85984
+ text: "3",
85985
+ description: "3 checks",
85986
+ category: "value"
85987
+ },
85988
+ {
85989
+ text: "5",
85990
+ description: "5 checks",
85991
+ category: "value"
85992
+ }
85993
+ ].filter((s) => s.text.startsWith(valuePartial));
85994
+ case "--path":
85995
+ return [
85996
+ {
85997
+ text: "/health",
85998
+ description: "Common health endpoint",
85999
+ category: "value"
86000
+ },
86001
+ {
86002
+ text: "/healthz",
86003
+ description: "Kubernetes-style",
86004
+ category: "value"
86005
+ },
86006
+ {
86007
+ text: "/ready",
86008
+ description: "Readiness endpoint",
86009
+ category: "value"
86010
+ },
86011
+ {
86012
+ text: "/",
86013
+ description: "Root path",
86014
+ category: "value"
86015
+ }
86016
+ ].filter((s) => s.text.toLowerCase().startsWith(lowerPartial));
86017
+ // Origin pool flag value completions
86018
+ case "--algorithm":
86019
+ return [
86020
+ {
86021
+ text: "ROUND_ROBIN",
86022
+ description: "Round robin distribution",
86023
+ category: "value"
86024
+ },
86025
+ {
86026
+ text: "LEAST_ACTIVE",
86027
+ description: "Least active connections",
86028
+ category: "value"
86029
+ },
86030
+ {
86031
+ text: "RANDOM",
86032
+ description: "Random selection",
86033
+ category: "value"
86034
+ },
86035
+ {
86036
+ text: "SOURCE_IP_STICKINESS",
86037
+ description: "Sticky by source IP",
86038
+ category: "value"
86039
+ },
86040
+ {
86041
+ text: "COOKIE_STICKINESS",
86042
+ description: "Sticky by cookie",
86043
+ category: "value"
86044
+ },
86045
+ {
86046
+ text: "RING_HASH",
86047
+ description: "Consistent ring hash",
86048
+ category: "value"
86049
+ }
86050
+ ].filter((s) => s.text.toLowerCase().startsWith(lowerPartial));
86051
+ case "--port":
86052
+ return [
86053
+ {
86054
+ text: "80",
86055
+ description: "HTTP port",
86056
+ category: "value"
86057
+ },
86058
+ {
86059
+ text: "443",
86060
+ description: "HTTPS port",
86061
+ category: "value"
86062
+ },
86063
+ {
86064
+ text: "8080",
86065
+ description: "Alt HTTP port",
86066
+ category: "value"
86067
+ },
86068
+ {
86069
+ text: "8443",
86070
+ description: "Alt HTTPS port",
86071
+ category: "value"
86072
+ }
86073
+ ].filter((s) => s.text.startsWith(valuePartial));
86074
+ case "--health-check":
86075
+ return this.getResourceNameSuggestions(
86076
+ "healthcheck",
86077
+ valuePartial
86078
+ );
85525
86079
  default:
85526
86080
  return [];
85527
86081
  }
@@ -91714,8 +92268,8 @@ var Ink = class {
91714
92268
  }
91715
92269
  }
91716
92270
  async waitUntilExit() {
91717
- this.exitPromise ||= new Promise((resolve2, reject) => {
91718
- this.resolveExitPromise = resolve2;
92271
+ this.exitPromise ||= new Promise((resolve3, reject) => {
92272
+ this.resolveExitPromise = resolve3;
91719
92273
  this.rejectExitPromise = reject;
91720
92274
  });
91721
92275
  return this.exitPromise;
@@ -92477,7 +93031,7 @@ function calculateBackoffDelay(attempt, config) {
92477
93031
  return cappedDelay;
92478
93032
  }
92479
93033
  function sleep(ms) {
92480
- return new Promise((resolve2) => setTimeout(resolve2, ms));
93034
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
92481
93035
  }
92482
93036
  var APIClient = class {
92483
93037
  serverUrl;
@@ -95377,9 +95931,9 @@ async function detectWithAllDomainScan(resourceName, namespace, client) {
95377
95931
  }
95378
95932
  async function detectDependencies(resourceType, resourceName, namespace, client) {
95379
95933
  const startTime = Date.now();
95380
- const timeoutPromise = new Promise((resolve2) => {
95934
+ const timeoutPromise = new Promise((resolve3) => {
95381
95935
  setTimeout(() => {
95382
- resolve2({
95936
+ resolve3({
95383
95937
  found: false,
95384
95938
  references: [],
95385
95939
  searchedDomains: [],
@@ -95531,6 +96085,540 @@ function hasUnsubstitutedParams(path) {
95531
96085
  return /\{[^}]+\}/.test(path);
95532
96086
  }
95533
96087
 
96088
+ // src/repl/executor.ts
96089
+ var import_yaml4 = __toESM(require_dist(), 1);
96090
+ import { promises as fs4 } from "fs";
96091
+ import { resolve } from "path";
96092
+
96093
+ // src/repl/creation/flag-parser.ts
96094
+ init_creation_flags();
96095
+ function hasCreationFlagsInArgs(args, resourceType) {
96096
+ const flagDefs = getCreationFlags(resourceType);
96097
+ if (flagDefs.length === 0) return false;
96098
+ const flagNames = /* @__PURE__ */ new Set();
96099
+ for (const def of flagDefs) {
96100
+ flagNames.add(def.name);
96101
+ if (def.shortName) {
96102
+ flagNames.add(def.shortName);
96103
+ }
96104
+ }
96105
+ for (const arg of args) {
96106
+ if (!arg) continue;
96107
+ const flagPart = arg.includes("=") ? arg.split("=")[0] ?? arg : arg;
96108
+ if (flagNames.has(flagPart)) {
96109
+ return true;
96110
+ }
96111
+ }
96112
+ return false;
96113
+ }
96114
+ function hasFileFlag(args) {
96115
+ return args.some((arg) => arg === "--file" || arg.startsWith("--file="));
96116
+ }
96117
+ function getFilePath(args) {
96118
+ for (let i = 0; i < args.length; i++) {
96119
+ const arg = args[i];
96120
+ if (!arg) continue;
96121
+ if (arg === "--file" && i + 1 < args.length) {
96122
+ const nextArg = args[i + 1];
96123
+ return nextArg ?? null;
96124
+ }
96125
+ if (arg.startsWith("--file=")) {
96126
+ return arg.substring("--file=".length);
96127
+ }
96128
+ }
96129
+ return null;
96130
+ }
96131
+ function parseCreationFlags(args, resourceType) {
96132
+ const flagDefs = getCreationFlags(resourceType);
96133
+ const result = {
96134
+ values: /* @__PURE__ */ new Map(),
96135
+ errors: [],
96136
+ hasFlags: false
96137
+ };
96138
+ if (flagDefs.length === 0) {
96139
+ result.errors.push(
96140
+ `No creation flags defined for resource type: ${resourceType}`
96141
+ );
96142
+ return result;
96143
+ }
96144
+ const flagByName = /* @__PURE__ */ new Map();
96145
+ const flagByShortName = /* @__PURE__ */ new Map();
96146
+ for (const def of flagDefs) {
96147
+ flagByName.set(def.name, def);
96148
+ if (def.shortName) {
96149
+ flagByShortName.set(def.shortName, def);
96150
+ }
96151
+ }
96152
+ const usageCounts = /* @__PURE__ */ new Map();
96153
+ let i = 0;
96154
+ while (i < args.length) {
96155
+ const arg = args[i];
96156
+ if (!arg || !arg.startsWith("-")) {
96157
+ i++;
96158
+ continue;
96159
+ }
96160
+ let flagName;
96161
+ let inlineValue;
96162
+ if (arg.includes("=")) {
96163
+ const eqIndex = arg.indexOf("=");
96164
+ flagName = arg.substring(0, eqIndex);
96165
+ inlineValue = arg.substring(eqIndex + 1);
96166
+ } else {
96167
+ flagName = arg;
96168
+ }
96169
+ if (flagName === "--file") {
96170
+ i += inlineValue !== void 0 ? 1 : 2;
96171
+ continue;
96172
+ }
96173
+ if (flagName === "--namespace" || flagName === "-ns") {
96174
+ i += inlineValue !== void 0 ? 1 : 2;
96175
+ continue;
96176
+ }
96177
+ const def = flagByName.get(flagName) ?? flagByShortName.get(flagName);
96178
+ if (!def) {
96179
+ i++;
96180
+ continue;
96181
+ }
96182
+ result.hasFlags = true;
96183
+ const currentCount = usageCounts.get(def.name) ?? 0;
96184
+ usageCounts.set(def.name, currentCount + 1);
96185
+ if (def.isRepeatable && def.maxOccurrences) {
96186
+ if (currentCount + 1 > def.maxOccurrences) {
96187
+ result.errors.push(
96188
+ `Flag ${def.name} can only be used ${def.maxOccurrences} times`
96189
+ );
96190
+ i++;
96191
+ continue;
96192
+ }
96193
+ } else if (!def.isRepeatable && currentCount > 0) {
96194
+ result.errors.push(
96195
+ `Flag ${def.name} cannot be specified multiple times`
96196
+ );
96197
+ i++;
96198
+ continue;
96199
+ }
96200
+ if (!def.hasValue) {
96201
+ result.values.set(def.name, "true");
96202
+ i++;
96203
+ continue;
96204
+ }
96205
+ let value;
96206
+ if (inlineValue !== void 0) {
96207
+ value = inlineValue;
96208
+ i++;
96209
+ } else {
96210
+ const nextArg = args[i + 1];
96211
+ if (nextArg && !nextArg.startsWith("-")) {
96212
+ value = nextArg;
96213
+ i += 2;
96214
+ } else {
96215
+ result.errors.push(`Flag ${def.name} requires a value`);
96216
+ i++;
96217
+ continue;
96218
+ }
96219
+ }
96220
+ if (def.valueType === "enum" && def.enumValues) {
96221
+ if (!def.enumValues.includes(value)) {
96222
+ result.errors.push(
96223
+ `Invalid value '${value}' for ${def.name}. Allowed: ${def.enumValues.join(", ")}`
96224
+ );
96225
+ continue;
96226
+ }
96227
+ }
96228
+ if (def.valueType === "integer") {
96229
+ const num = parseInt(value, 10);
96230
+ if (isNaN(num)) {
96231
+ result.errors.push(
96232
+ `Invalid integer value '${value}' for ${def.name}`
96233
+ );
96234
+ continue;
96235
+ }
96236
+ }
96237
+ if (def.isRepeatable) {
96238
+ const existing = result.values.get(def.name);
96239
+ if (Array.isArray(existing)) {
96240
+ existing.push(value);
96241
+ } else {
96242
+ result.values.set(def.name, [value]);
96243
+ }
96244
+ } else {
96245
+ result.values.set(def.name, value);
96246
+ }
96247
+ }
96248
+ for (const def of flagDefs) {
96249
+ if (def.required && !result.values.has(def.name)) {
96250
+ if (result.hasFlags) {
96251
+ result.errors.push(`Required flag ${def.name} is missing`);
96252
+ }
96253
+ }
96254
+ }
96255
+ return result;
96256
+ }
96257
+ function getFlagValue(parsed, flagName) {
96258
+ const value = parsed.values.get(flagName);
96259
+ if (Array.isArray(value)) {
96260
+ return value[0];
96261
+ }
96262
+ return value;
96263
+ }
96264
+ function getFlagValues(parsed, flagName) {
96265
+ const value = parsed.values.get(flagName);
96266
+ if (Array.isArray(value)) {
96267
+ return value;
96268
+ }
96269
+ if (value !== void 0) {
96270
+ return [value];
96271
+ }
96272
+ return [];
96273
+ }
96274
+ function getFlagIntValue(parsed, flagName) {
96275
+ const value = getFlagValue(parsed, flagName);
96276
+ if (value !== void 0) {
96277
+ const num = parseInt(value, 10);
96278
+ return isNaN(num) ? void 0 : num;
96279
+ }
96280
+ return void 0;
96281
+ }
96282
+ function isFlagSet(parsed, flagName) {
96283
+ return parsed.values.has(flagName);
96284
+ }
96285
+
96286
+ // src/repl/creation/builders/healthcheck-builder.ts
96287
+ function buildHealthcheckRequest(flags, namespace) {
96288
+ const name = getFlagValue(flags, "--name");
96289
+ const type = getFlagValue(flags, "--type");
96290
+ const interval = getFlagIntValue(flags, "--interval");
96291
+ const timeout = getFlagIntValue(flags, "--timeout");
96292
+ const healthyThreshold = getFlagIntValue(flags, "--healthy-threshold");
96293
+ const unhealthyThreshold = getFlagIntValue(flags, "--unhealthy-threshold");
96294
+ const request = {
96295
+ metadata: {
96296
+ name: name || "",
96297
+ namespace
96298
+ },
96299
+ spec: {
96300
+ timeout: timeout || 5,
96301
+ interval: interval || 10,
96302
+ healthy_threshold: healthyThreshold || 2,
96303
+ unhealthy_threshold: unhealthyThreshold || 3
96304
+ }
96305
+ };
96306
+ switch (type) {
96307
+ case "http": {
96308
+ const path = getFlagValue(flags, "--path") || "/";
96309
+ const useOriginServerName = isFlagSet(
96310
+ flags,
96311
+ "--use-origin-server-name"
96312
+ );
96313
+ const useHttp2 = isFlagSet(flags, "--use-http2");
96314
+ const expectedStatus = getFlagValue(flags, "--expected-status");
96315
+ const hostHeader = getFlagValue(flags, "--host-header");
96316
+ request.spec.http_health_check = {
96317
+ path,
96318
+ use_origin_server_name: useOriginServerName,
96319
+ use_http2: useHttp2
96320
+ };
96321
+ if (expectedStatus) {
96322
+ request.spec.http_health_check.expected_status_codes = expectedStatus.split(",").map((s) => s.trim());
96323
+ }
96324
+ if (hostHeader) {
96325
+ request.spec.http_health_check.headers = {
96326
+ Host: hostHeader
96327
+ };
96328
+ }
96329
+ break;
96330
+ }
96331
+ case "tcp": {
96332
+ request.spec.tcp_health_check = {};
96333
+ break;
96334
+ }
96335
+ case "dns": {
96336
+ request.spec.dns_health_check = {};
96337
+ break;
96338
+ }
96339
+ case "udp-icmp": {
96340
+ break;
96341
+ }
96342
+ }
96343
+ return request;
96344
+ }
96345
+ function validateHealthcheckFlags(flags) {
96346
+ const errors = [];
96347
+ const name = getFlagValue(flags, "--name");
96348
+ if (!name) {
96349
+ errors.push("--name is required");
96350
+ } else if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name) && name.length > 1) {
96351
+ errors.push(
96352
+ "--name must contain only lowercase alphanumeric characters and hyphens"
96353
+ );
96354
+ }
96355
+ const type = getFlagValue(flags, "--type");
96356
+ if (!type) {
96357
+ errors.push("--type is required (http, tcp, dns, or udp-icmp)");
96358
+ }
96359
+ const interval = getFlagIntValue(flags, "--interval");
96360
+ if (interval === void 0) {
96361
+ errors.push("--interval is required");
96362
+ } else if (interval < 1 || interval > 600) {
96363
+ errors.push("--interval must be between 1 and 600 seconds");
96364
+ }
96365
+ const timeout = getFlagIntValue(flags, "--timeout");
96366
+ if (timeout === void 0) {
96367
+ errors.push("--timeout is required");
96368
+ } else if (timeout < 1 || timeout > 600) {
96369
+ errors.push("--timeout must be between 1 and 600 seconds");
96370
+ }
96371
+ const healthyThreshold = getFlagIntValue(flags, "--healthy-threshold");
96372
+ if (healthyThreshold === void 0) {
96373
+ errors.push("--healthy-threshold is required");
96374
+ } else if (healthyThreshold < 1 || healthyThreshold > 16) {
96375
+ errors.push("--healthy-threshold must be between 1 and 16");
96376
+ }
96377
+ const unhealthyThreshold = getFlagIntValue(flags, "--unhealthy-threshold");
96378
+ if (unhealthyThreshold === void 0) {
96379
+ errors.push("--unhealthy-threshold is required");
96380
+ } else if (unhealthyThreshold < 1 || unhealthyThreshold > 16) {
96381
+ errors.push("--unhealthy-threshold must be between 1 and 16");
96382
+ }
96383
+ if (type === "http") {
96384
+ const path = getFlagValue(flags, "--path");
96385
+ if (path && !path.startsWith("/")) {
96386
+ errors.push("--path must start with /");
96387
+ }
96388
+ }
96389
+ return {
96390
+ valid: errors.length === 0,
96391
+ errors
96392
+ };
96393
+ }
96394
+
96395
+ // src/repl/creation/builders/origin-pool-builder.ts
96396
+ function buildOriginPoolRequest(flags, namespace) {
96397
+ const name = getFlagValue(flags, "--name");
96398
+ const port = getFlagIntValue(flags, "--port");
96399
+ const algorithm = getFlagValue(flags, "--algorithm");
96400
+ const site = getFlagValue(flags, "--site");
96401
+ const originServers = [];
96402
+ const publicIps = getFlagValues(flags, "--public-ip");
96403
+ for (const ip of publicIps) {
96404
+ originServers.push({ public_ip: { ip } });
96405
+ }
96406
+ const publicNames = getFlagValues(flags, "--public-name");
96407
+ for (const dnsName of publicNames) {
96408
+ originServers.push({ public_name: { dns_name: dnsName } });
96409
+ }
96410
+ const privateIps = getFlagValues(flags, "--private-ip");
96411
+ for (const ip of privateIps) {
96412
+ const origin = {
96413
+ private_ip: { ip }
96414
+ };
96415
+ if (site) {
96416
+ origin.private_ip.site_locator = {
96417
+ site: { name: site, namespace: "system" }
96418
+ };
96419
+ }
96420
+ originServers.push(origin);
96421
+ }
96422
+ const privateNames = getFlagValues(flags, "--private-name");
96423
+ for (const dnsName of privateNames) {
96424
+ const origin = {
96425
+ private_name: { dns_name: dnsName }
96426
+ };
96427
+ if (site) {
96428
+ origin.private_name.site_locator = {
96429
+ site: { name: site, namespace: "system" }
96430
+ };
96431
+ }
96432
+ originServers.push(origin);
96433
+ }
96434
+ const k8sServices = getFlagValues(flags, "--k8s-service");
96435
+ for (const svc of k8sServices) {
96436
+ const origin = {
96437
+ k8s_service: { service_name: svc }
96438
+ };
96439
+ if (site) {
96440
+ origin.k8s_service.site_locator = {
96441
+ site: { name: site, namespace: "system" }
96442
+ };
96443
+ }
96444
+ originServers.push(origin);
96445
+ }
96446
+ const consulServices = getFlagValues(flags, "--consul-service");
96447
+ for (const svc of consulServices) {
96448
+ const origin = {
96449
+ consul_service: { service_name: svc }
96450
+ };
96451
+ if (site) {
96452
+ origin.consul_service.site_locator = {
96453
+ site: { name: site, namespace: "system" }
96454
+ };
96455
+ }
96456
+ originServers.push(origin);
96457
+ }
96458
+ const customEndpoints = getFlagValues(flags, "--custom-endpoint");
96459
+ for (const endpoint of customEndpoints) {
96460
+ originServers.push({
96461
+ custom_endpoint_object: {
96462
+ endpoint: { name: endpoint, namespace }
96463
+ }
96464
+ });
96465
+ }
96466
+ const vnPrivateIps = getFlagValues(flags, "--vn-private-ip");
96467
+ for (const ip of vnPrivateIps) {
96468
+ originServers.push({
96469
+ vn_private_ip: { ip }
96470
+ });
96471
+ }
96472
+ const vnPrivateNames = getFlagValues(flags, "--vn-private-name");
96473
+ for (const dnsName of vnPrivateNames) {
96474
+ originServers.push({
96475
+ vn_private_name: { dns_name: dnsName }
96476
+ });
96477
+ }
96478
+ const request = {
96479
+ metadata: {
96480
+ name: name || "",
96481
+ namespace
96482
+ },
96483
+ spec: {
96484
+ origin_servers: originServers
96485
+ }
96486
+ };
96487
+ if (port !== void 0) {
96488
+ request.spec.port = port;
96489
+ } else if (isFlagSet(flags, "--automatic-port")) {
96490
+ request.spec.automatic_port = {};
96491
+ } else if (isFlagSet(flags, "--lb-port")) {
96492
+ request.spec.lb_port = {};
96493
+ }
96494
+ if (algorithm) {
96495
+ request.spec.loadbalancer_algorithm = algorithm;
96496
+ }
96497
+ if (isFlagSet(flags, "--no-tls")) {
96498
+ request.spec.no_tls = {};
96499
+ } else if (isFlagSet(flags, "--use-tls")) {
96500
+ request.spec.use_tls = {
96501
+ use_host_header_as_sni: {},
96502
+ tls_config: {
96503
+ default_security: {}
96504
+ },
96505
+ skip_server_verification: {}
96506
+ };
96507
+ }
96508
+ const healthChecks = getFlagValues(flags, "--health-check");
96509
+ if (healthChecks.length > 0) {
96510
+ request.spec.healthcheck = healthChecks.map((hc) => ({
96511
+ name: hc,
96512
+ namespace
96513
+ }));
96514
+ }
96515
+ return request;
96516
+ }
96517
+ function validateOriginPoolFlags(flags) {
96518
+ const errors = [];
96519
+ const name = getFlagValue(flags, "--name");
96520
+ if (!name) {
96521
+ errors.push("--name is required");
96522
+ } else if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(name) && name.length > 1) {
96523
+ errors.push(
96524
+ "--name must contain only lowercase alphanumeric characters and hyphens"
96525
+ );
96526
+ }
96527
+ const originFlagNames = [
96528
+ "--public-ip",
96529
+ "--public-name",
96530
+ "--private-ip",
96531
+ "--private-name",
96532
+ "--k8s-service",
96533
+ "--consul-service",
96534
+ "--custom-endpoint",
96535
+ "--vn-private-ip",
96536
+ "--vn-private-name",
96537
+ "--cbip-service"
96538
+ ];
96539
+ let hasOrigin = false;
96540
+ for (const flagName of originFlagNames) {
96541
+ if (getFlagValues(flags, flagName).length > 0) {
96542
+ hasOrigin = true;
96543
+ break;
96544
+ }
96545
+ }
96546
+ if (!hasOrigin) {
96547
+ errors.push(
96548
+ "At least one origin server is required (e.g., --public-ip, --public-name)"
96549
+ );
96550
+ }
96551
+ const port = getFlagIntValue(flags, "--port");
96552
+ if (port !== void 0 && (port < 1 || port > 65535)) {
96553
+ errors.push("--port must be between 1 and 65535");
96554
+ }
96555
+ const portOptions = [
96556
+ isFlagSet(flags, "--port") || port !== void 0,
96557
+ isFlagSet(flags, "--automatic-port"),
96558
+ isFlagSet(flags, "--lb-port")
96559
+ ].filter(Boolean).length;
96560
+ if (portOptions > 1) {
96561
+ errors.push(
96562
+ "--port, --automatic-port, and --lb-port are mutually exclusive"
96563
+ );
96564
+ }
96565
+ if (isFlagSet(flags, "--no-tls") && isFlagSet(flags, "--use-tls")) {
96566
+ errors.push("--no-tls and --use-tls are mutually exclusive");
96567
+ }
96568
+ const privateIps = getFlagValues(flags, "--private-ip");
96569
+ const privateNames = getFlagValues(flags, "--private-name");
96570
+ const k8sServices = getFlagValues(flags, "--k8s-service");
96571
+ const consulServices = getFlagValues(flags, "--consul-service");
96572
+ if ((privateIps.length > 0 || privateNames.length > 0 || k8sServices.length > 0 || consulServices.length > 0) && !getFlagValue(flags, "--site")) {
96573
+ errors.push(
96574
+ "--site is required when using private origins (--private-ip, --private-name, --k8s-service, --consul-service)"
96575
+ );
96576
+ }
96577
+ const healthChecks = getFlagValues(flags, "--health-check");
96578
+ if (healthChecks.length > 4) {
96579
+ errors.push("Maximum of 4 health checks allowed");
96580
+ }
96581
+ return {
96582
+ valid: errors.length === 0,
96583
+ errors
96584
+ };
96585
+ }
96586
+
96587
+ // src/repl/creation/builders/index.ts
96588
+ var BUILDERS_REGISTRY = {
96589
+ healthcheck: {
96590
+ build: (flags, namespace) => buildHealthcheckRequest(flags, namespace),
96591
+ validate: validateHealthcheckFlags
96592
+ },
96593
+ origin_pool: {
96594
+ build: (flags, namespace) => buildOriginPoolRequest(flags, namespace),
96595
+ validate: validateOriginPoolFlags
96596
+ }
96597
+ };
96598
+ function getResourceBuilder(resourceType) {
96599
+ return BUILDERS_REGISTRY[resourceType];
96600
+ }
96601
+ function hasResourceBuilder(resourceType) {
96602
+ return resourceType in BUILDERS_REGISTRY;
96603
+ }
96604
+ function buildResource(resourceType, flags, namespace) {
96605
+ const builder = getResourceBuilder(resourceType);
96606
+ if (!builder) {
96607
+ return null;
96608
+ }
96609
+ return builder.build(flags, namespace);
96610
+ }
96611
+ function validateResourceFlags(resourceType, flags) {
96612
+ const builder = getResourceBuilder(resourceType);
96613
+ if (!builder) {
96614
+ return {
96615
+ valid: false,
96616
+ errors: [`No builder found for resource type: ${resourceType}`]
96617
+ };
96618
+ }
96619
+ return builder.validate(flags);
96620
+ }
96621
+
95534
96622
  // src/repl/executor.ts
95535
96623
  var WRITE_OPERATIONS = /* @__PURE__ */ new Set([
95536
96624
  "create",
@@ -96508,15 +97596,153 @@ async function executeAPICommand(session, ctx, cmd) {
96508
97596
  case "create":
96509
97597
  case "replace":
96510
97598
  case "apply": {
96511
- return {
96512
- output: [
97599
+ let requestBody = null;
97600
+ if (hasFileFlag(args)) {
97601
+ const filePath = getFilePath(args);
97602
+ if (!filePath) {
97603
+ return {
97604
+ output: ["Error: --file requires a file path"],
97605
+ shouldExit: false,
97606
+ shouldClear: false,
97607
+ contextChanged: false
97608
+ };
97609
+ }
97610
+ try {
97611
+ const absolutePath = resolve(filePath);
97612
+ const fileContent = await fs4.readFile(
97613
+ absolutePath,
97614
+ "utf-8"
97615
+ );
97616
+ requestBody = import_yaml4.default.parse(fileContent);
97617
+ if (!requestBody || typeof requestBody !== "object") {
97618
+ return {
97619
+ output: [
97620
+ "Error: File must contain a valid YAML/JSON object"
97621
+ ],
97622
+ shouldExit: false,
97623
+ shouldClear: false,
97624
+ contextChanged: false
97625
+ };
97626
+ }
97627
+ } catch (error) {
97628
+ const errMsg = error instanceof Error ? error.message : String(error);
97629
+ return {
97630
+ output: [`Error reading file: ${errMsg}`],
97631
+ shouldExit: false,
97632
+ shouldClear: false,
97633
+ contextChanged: false
97634
+ };
97635
+ }
97636
+ } else if (effectiveResourceType && hasResourceBuilder(effectiveResourceType) && hasCreationFlagsInArgs(args, effectiveResourceType)) {
97637
+ const parsed = parseCreationFlags(
97638
+ args,
97639
+ effectiveResourceType
97640
+ );
97641
+ if (parsed.errors.length > 0) {
97642
+ return {
97643
+ output: [
97644
+ "Error parsing creation flags:",
97645
+ ...parsed.errors.map((e) => ` - ${e}`)
97646
+ ],
97647
+ shouldExit: false,
97648
+ shouldClear: false,
97649
+ contextChanged: false
97650
+ };
97651
+ }
97652
+ const validation = validateResourceFlags(
97653
+ effectiveResourceType,
97654
+ parsed
97655
+ );
97656
+ if (!validation.valid) {
97657
+ return {
97658
+ output: [
97659
+ "Validation errors:",
97660
+ ...validation.errors.map((e) => ` - ${e}`)
97661
+ ],
97662
+ shouldExit: false,
97663
+ shouldClear: false,
97664
+ contextChanged: false
97665
+ };
97666
+ }
97667
+ requestBody = buildResource(
97668
+ effectiveResourceType,
97669
+ parsed,
97670
+ effectiveNamespace
97671
+ );
97672
+ } else {
97673
+ const supportsFlagCreation = effectiveResourceType && hasResourceBuilder(effectiveResourceType);
97674
+ const hints = [
96513
97675
  `Action '${action}' requires a resource specification.`,
96514
- "Use --file <path> to provide resource YAML/JSON."
96515
- ],
96516
- shouldExit: false,
96517
- shouldClear: false,
96518
- contextChanged: false
96519
- };
97676
+ "",
97677
+ "Options:",
97678
+ " 1. Use --file <path> to provide resource YAML/JSON"
97679
+ ];
97680
+ if (supportsFlagCreation) {
97681
+ hints.push(
97682
+ ` 2. Use creation flags (e.g., --name, --type, etc.)`,
97683
+ "",
97684
+ `Example with flags:`,
97685
+ ` create ${effectiveResourceType} --name my-resource ...`
97686
+ );
97687
+ }
97688
+ return {
97689
+ output: hints,
97690
+ shouldExit: false,
97691
+ shouldClear: false,
97692
+ contextChanged: false
97693
+ };
97694
+ }
97695
+ if (!requestBody) {
97696
+ return {
97697
+ output: ["Error: Failed to build request body"],
97698
+ shouldExit: false,
97699
+ shouldClear: false,
97700
+ contextChanged: false
97701
+ };
97702
+ }
97703
+ if (action === "create") {
97704
+ const response = await client.post(apiPath, requestBody);
97705
+ result = response.data ?? {
97706
+ message: `Created ${canonicalDomain}`
97707
+ };
97708
+ } else if (action === "replace") {
97709
+ const resourceName = requestBody.metadata?.name ?? name;
97710
+ if (resourceName && !usedOperationPath) {
97711
+ apiPath += `/${resourceName}`;
97712
+ }
97713
+ const response = await client.put(apiPath, requestBody);
97714
+ result = response.data ?? {
97715
+ message: `Replaced ${canonicalDomain}`
97716
+ };
97717
+ } else {
97718
+ try {
97719
+ const response = await client.post(
97720
+ apiPath,
97721
+ requestBody
97722
+ );
97723
+ result = response.data ?? {
97724
+ message: `Applied ${canonicalDomain}`
97725
+ };
97726
+ } catch (postError) {
97727
+ if (postError instanceof APIError && postError.statusCode === 409) {
97728
+ const resourceName = requestBody.metadata?.name ?? name;
97729
+ let putPath = apiPath;
97730
+ if (resourceName && !usedOperationPath) {
97731
+ putPath += `/${resourceName}`;
97732
+ }
97733
+ const response = await client.put(
97734
+ putPath,
97735
+ requestBody
97736
+ );
97737
+ result = response.data ?? {
97738
+ message: `Updated ${canonicalDomain}`
97739
+ };
97740
+ } else {
97741
+ throw postError;
97742
+ }
97743
+ }
97744
+ }
97745
+ break;
96520
97746
  }
96521
97747
  case "status": {
96522
97748
  if (!name) {
@@ -96747,11 +97973,11 @@ init_terminal2();
96747
97973
 
96748
97974
  // src/debug/logger.ts
96749
97975
  import { appendFileSync, writeFileSync as writeFileSync2 } from "fs";
96750
- import { resolve } from "path";
97976
+ import { resolve as resolve2 } from "path";
96751
97977
  var DEBUG_ENABLED = process.env.XCSH_DEBUG === "1" || process.env.DEBUG === "xcsh" || process.env.DEBUG === "*";
96752
97978
  var DEBUG_FILE = process.env.XCSH_DEBUG_FILE || "./xcsh-debug.log";
96753
97979
  if (DEBUG_ENABLED) {
96754
- const logPath = resolve(DEBUG_FILE);
97980
+ const logPath = resolve2(DEBUG_FILE);
96755
97981
  try {
96756
97982
  writeFileSync2(
96757
97983
  logPath,