@firestartr/cli 3.1.1 → 3.2.0-snapshot-01

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/build/index.js CHANGED
@@ -34415,7 +34415,7 @@ const resolve_1 = __nccwpck_require__(50921);
34415
34415
  const API_OBJECT_SYMBOL = Symbol.for('cdk8s.ApiObject');
34416
34416
  class ApiObject extends constructs_1.Construct {
34417
34417
  props;
34418
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ApiObject", version: "2.70.111" };
34418
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ApiObject", version: "2.70.115" };
34419
34419
  /**
34420
34420
  * Return whether the given object is an `ApiObject`.
34421
34421
  *
@@ -34662,7 +34662,7 @@ class SynthRequestCache {
34662
34662
  * Represents a cdk8s application.
34663
34663
  */
34664
34664
  class App extends constructs_1.Construct {
34665
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.App", version: "2.70.111" };
34665
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.App", version: "2.70.115" };
34666
34666
  /**
34667
34667
  * Synthesize a single chart.
34668
34668
  *
@@ -34947,7 +34947,7 @@ const names_1 = __nccwpck_require__(21021);
34947
34947
  const CHART_SYMBOL = Symbol.for('cdk8s.Chart');
34948
34948
  const CRONJOB = 'CronJob';
34949
34949
  class Chart extends constructs_1.Construct {
34950
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Chart", version: "2.70.111" };
34950
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Chart", version: "2.70.115" };
34951
34951
  /**
34952
34952
  * Return whether the given object is a Chart.
34953
34953
  *
@@ -35071,7 +35071,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
35071
35071
  * Represents a cron schedule
35072
35072
  */
35073
35073
  class Cron {
35074
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Cron", version: "2.70.111" };
35074
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Cron", version: "2.70.115" };
35075
35075
  /**
35076
35076
  * Create a cron schedule which runs every minute
35077
35077
  */
@@ -35157,7 +35157,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
35157
35157
  *
35158
35158
  */
35159
35159
  class DependencyGraph {
35160
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.DependencyGraph", version: "2.70.111" };
35160
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.DependencyGraph", version: "2.70.115" };
35161
35161
  _fosterParent;
35162
35162
  constructor(node) {
35163
35163
  this._fosterParent = new DependencyVertex();
@@ -35222,7 +35222,7 @@ exports.DependencyGraph = DependencyGraph;
35222
35222
  * The value of each vertex is an `IConstruct` that is accessible via the `.value` getter.
35223
35223
  */
35224
35224
  class DependencyVertex {
35225
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.DependencyVertex", version: "2.70.111" };
35225
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.DependencyVertex", version: "2.70.115" };
35226
35226
  _value;
35227
35227
  _children = new Set();
35228
35228
  _parents = new Set();
@@ -35328,7 +35328,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
35328
35328
  *
35329
35329
  */
35330
35330
  class Duration {
35331
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Duration", version: "2.70.111" };
35331
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Duration", version: "2.70.115" };
35332
35332
  /**
35333
35333
  * Create a Duration representing an amount of milliseconds
35334
35334
  *
@@ -35608,7 +35608,7 @@ const MAX_HELM_BUFFER = 10 * 1024 * 1024;
35608
35608
  * Use this construct to import an existing Helm chart and incorporate it into your constructs.
35609
35609
  */
35610
35610
  class Helm extends include_1.Include {
35611
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Helm", version: "2.70.111" };
35611
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Helm", version: "2.70.115" };
35612
35612
  /**
35613
35613
  * The helm release name.
35614
35614
  */
@@ -35690,7 +35690,7 @@ const yaml_1 = __nccwpck_require__(84286);
35690
35690
  * from the manifest.
35691
35691
  */
35692
35692
  class Include extends constructs_1.Construct {
35693
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Include", version: "2.70.111" };
35693
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Include", version: "2.70.115" };
35694
35694
  constructor(scope, id, props) {
35695
35695
  super(scope, id);
35696
35696
  const objects = yaml_1.Yaml.load(props.url);
@@ -35780,7 +35780,7 @@ const fast_json_patch_1 = __nccwpck_require__(34151);
35780
35780
  */
35781
35781
  class JsonPatch {
35782
35782
  operation;
35783
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.JsonPatch", version: "2.70.111" };
35783
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.JsonPatch", version: "2.70.115" };
35784
35784
  /**
35785
35785
  * Applies a set of JSON-Patch (RFC-6902) operations to `document` and returns the result.
35786
35786
  * @param document The document to patch
@@ -35858,7 +35858,7 @@ exports.Lazy = void 0;
35858
35858
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
35859
35859
  class Lazy {
35860
35860
  producer;
35861
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Lazy", version: "2.70.111" };
35861
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Lazy", version: "2.70.115" };
35862
35862
  static any(producer) {
35863
35863
  return new Lazy(producer);
35864
35864
  }
@@ -35887,7 +35887,7 @@ const resolve_1 = __nccwpck_require__(50921);
35887
35887
  * Object metadata.
35888
35888
  */
35889
35889
  class ApiObjectMetadataDefinition {
35890
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ApiObjectMetadataDefinition", version: "2.70.111" };
35890
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ApiObjectMetadataDefinition", version: "2.70.115" };
35891
35891
  /**
35892
35892
  * The name of the API object.
35893
35893
  *
@@ -36056,7 +36056,7 @@ const HASH_LEN = 8;
36056
36056
  * Utilities for generating unique and stable names.
36057
36057
  */
36058
36058
  class Names {
36059
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Names", version: "2.70.111" };
36059
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Names", version: "2.70.115" };
36060
36060
  /**
36061
36061
  * Generates a unique and stable name compatible DNS_LABEL from RFC-1123 from
36062
36062
  * a path.
@@ -36224,7 +36224,7 @@ class ResolutionContext {
36224
36224
  obj;
36225
36225
  key;
36226
36226
  value;
36227
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ResolutionContext", version: "2.70.111" };
36227
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ResolutionContext", version: "2.70.115" };
36228
36228
  /**
36229
36229
  * The replaced value that was set via the `replaceValue` method.
36230
36230
  */
@@ -36264,7 +36264,7 @@ exports.ResolutionContext = ResolutionContext;
36264
36264
  * Resolvers instanecs of `Lazy`.
36265
36265
  */
36266
36266
  class LazyResolver {
36267
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.LazyResolver", version: "2.70.111" };
36267
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.LazyResolver", version: "2.70.115" };
36268
36268
  resolve(context) {
36269
36269
  if (context.value instanceof lazy_1.Lazy) {
36270
36270
  const resolved = context.value.produce();
@@ -36277,7 +36277,7 @@ exports.LazyResolver = LazyResolver;
36277
36277
  * Resolves implicit tokens.
36278
36278
  */
36279
36279
  class ImplicitTokenResolver {
36280
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ImplicitTokenResolver", version: "2.70.111" };
36280
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.ImplicitTokenResolver", version: "2.70.115" };
36281
36281
  resolve(context) {
36282
36282
  if (typeof (context.value.resolve) === 'function') {
36283
36283
  const resolved = context.value.resolve();
@@ -36292,7 +36292,7 @@ exports.ImplicitTokenResolver = ImplicitTokenResolver;
36292
36292
  * E.g IntOrString, Quantity, ...
36293
36293
  */
36294
36294
  class NumberStringUnionResolver {
36295
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.NumberStringUnionResolver", version: "2.70.111" };
36295
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.NumberStringUnionResolver", version: "2.70.115" };
36296
36296
  static TYPES = ['number', 'string'];
36297
36297
  resolve(context) {
36298
36298
  if (context.value.constructor === Object) {
@@ -36358,7 +36358,7 @@ const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
36358
36358
  * When the amount is passed as a token, unit conversion is not possible.
36359
36359
  */
36360
36360
  class Size {
36361
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Size", version: "2.70.111" };
36361
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Size", version: "2.70.115" };
36362
36362
  /**
36363
36363
  * Create a Storage representing an amount kibibytes.
36364
36364
  * 1 KiB = 1024 bytes
@@ -36546,7 +36546,7 @@ const chart_1 = __nccwpck_require__(75525);
36546
36546
  * Testing utilities for cdk8s applications.
36547
36547
  */
36548
36548
  class Testing {
36549
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Testing", version: "2.70.111" };
36549
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Testing", version: "2.70.115" };
36550
36550
  /**
36551
36551
  * Returns an app for testing with the following properties:
36552
36552
  * - Output directory is a temp dir.
@@ -36637,7 +36637,7 @@ const yamlSchemaVersion = '1.1';
36637
36637
  * YAML utilities.
36638
36638
  */
36639
36639
  class Yaml {
36640
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Yaml", version: "2.70.111" };
36640
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk8s.Yaml", version: "2.70.115" };
36641
36641
  /**
36642
36642
  * @deprecated use `stringify(doc[, doc, ...])`
36643
36643
  */
@@ -49054,6 +49054,13 @@ class Address4 {
49054
49054
  * address.correctForm(); // '192.0.2.42'
49055
49055
  */
49056
49056
  static fromArpa(arpaFormAddress) {
49057
+ // A 15-character address, a "/32" prefix length and ".in-addr.arpa.": the
49058
+ // longest name is 32 characters. Longer input is rejected before its
49059
+ // labels are split, as the constructor does at its own limit.
49060
+ const longest = constants.GROUPS * 4 - 1 + '/32'.length + '.in-addr.arpa.'.length;
49061
+ if (arpaFormAddress.length > longest) {
49062
+ throw new address_error_1.AddressError(`in-addr.arpa names are at most ${longest} characters.`);
49063
+ }
49057
49064
  // remove an ending ".in-addr.arpa", in any case and with or without the
49058
49065
  // root dot, as Address6.fromArpa does for ".ip6.arpa"
49059
49066
  const leader = arpaFormAddress.replace(/(\.in-addr\.arpa)?\.?$/i, '');
@@ -49559,10 +49566,13 @@ class Address6 {
49559
49566
  if (/\//.test(address)) {
49560
49567
  throw new address_error_1.AddressError('Invalid subnet mask.');
49561
49568
  }
49562
- const zone = constants6.RE_ZONE_STRING.exec(address);
49563
- if (zone) {
49564
- this.zone = zone[0];
49565
- address = address.replace(constants6.RE_ZONE_STRING, '');
49569
+ // A zone runs from the first `%` to the end of the input and holds no line
49570
+ // terminator. Finding it by index reads the input once, where matching
49571
+ // RE_ZONE_STRING retries from every `%` that a line terminator disqualifies.
49572
+ const zoneStart = address.indexOf('%');
49573
+ if (zoneStart !== -1 && /^.*$/.test(address.slice(zoneStart))) {
49574
+ this.zone = address.slice(zoneStart);
49575
+ address = address.slice(0, zoneStart);
49566
49576
  }
49567
49577
  // The longest well-formed address is all but the last two groups written
49568
49578
  // as four hex digits with their colons, then a 15-character dotted quad:
@@ -51022,6 +51032,9 @@ exports.RE_SUBNET_STRING = /\/\d{1,3}(?=%|$)/;
51022
51032
  * A regular expression that matches an IPv6 zone
51023
51033
  * @memberof Address6
51024
51034
  * @static
51035
+ * @deprecated Takes quadratic time on input holding many `%` characters
51036
+ * followed by a line terminator. The library finds the zone by index, as
51037
+ * `Address6`'s constructor shows, and 11.0.0 removes this export.
51025
51038
  */
51026
51039
  exports.RE_ZONE_STRING = /%.*$/;
51027
51040
  exports.RE_URL = /^(?:\[([0-9a-f:.]+)\]|([0-9a-f:.]+))(?:[/?#].*)?$/i;
@@ -94020,7 +94033,7 @@ class Range {
94020
94033
  debug('hyphen replace', range)
94021
94034
 
94022
94035
  // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5`
94023
- range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace)
94036
+ range = trimComparatorWhitespace(range)
94024
94037
  debug('comparator trim', range)
94025
94038
 
94026
94039
  // `~ 1.2.3` => `~1.2.3`
@@ -94125,11 +94138,11 @@ const parseOptions = __nccwpck_require__(74464)
94125
94138
  const Comparator = __nccwpck_require__(15895)
94126
94139
  const debug = __nccwpck_require__(28195)
94127
94140
  const SemVer = __nccwpck_require__(69855)
94141
+ const trimComparatorWhitespace = __nccwpck_require__(99853)
94128
94142
  const {
94129
94143
  safeRe: re,
94130
94144
  src,
94131
94145
  t,
94132
- comparatorTrimReplace,
94133
94146
  tildeTrimReplace,
94134
94147
  caretTrimReplace,
94135
94148
  } = __nccwpck_require__(23227)
@@ -95512,6 +95525,35 @@ const MAX_SAFE_COMPONENT_LENGTH = 16
95512
95525
  // the shortest version with a build 0.0.0+BUILD.
95513
95526
  const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6
95514
95527
 
95528
+ // ECMAScript whitespace and line terminators matched by \s.
95529
+ const WHITESPACE_CHARACTERS = [
95530
+ '\t',
95531
+ '\n',
95532
+ '\v',
95533
+ '\f',
95534
+ '\r',
95535
+ ' ',
95536
+ '\u00a0',
95537
+ '\u1680',
95538
+ '\u2000',
95539
+ '\u2001',
95540
+ '\u2002',
95541
+ '\u2003',
95542
+ '\u2004',
95543
+ '\u2005',
95544
+ '\u2006',
95545
+ '\u2007',
95546
+ '\u2008',
95547
+ '\u2009',
95548
+ '\u200a',
95549
+ '\u2028',
95550
+ '\u2029',
95551
+ '\u202f',
95552
+ '\u205f',
95553
+ '\u3000',
95554
+ '\ufeff',
95555
+ ]
95556
+
95515
95557
  const RELEASE_TYPES = [
95516
95558
  'major',
95517
95559
  'premajor',
@@ -95527,6 +95569,7 @@ module.exports = {
95527
95569
  MAX_SAFE_COMPONENT_LENGTH,
95528
95570
  MAX_SAFE_BUILD_LENGTH,
95529
95571
  MAX_SAFE_INTEGER,
95572
+ WHITESPACE_CHARACTERS,
95530
95573
  RELEASE_TYPES,
95531
95574
  SEMVER_SPEC_VERSION,
95532
95575
  FLAG_INCLUDE_PRERELEASE: 0b001,
@@ -95891,6 +95934,451 @@ createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
95891
95934
  createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')
95892
95935
 
95893
95936
 
95937
+ /***/ }),
95938
+
95939
+ /***/ 99853:
95940
+ /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => {
95941
+
95942
+ // @ts-check
95943
+
95944
+
95945
+ // Reproduce safeRe[COMPARATORTRIM] replacement boundaries, not version
95946
+ // validation. Each end-index finder returns an exclusive end, or its start
95947
+ // on no match.
95948
+ // Positions count from zero. An end of 3 means characters 0, 1, and 2 were read;
95949
+ // range.slice(start, end) gives the matched text, not a converted number.
95950
+ const {
95951
+ MAX_LENGTH,
95952
+ MAX_SAFE_BUILD_LENGTH,
95953
+ WHITESPACE_CHARACTERS,
95954
+ } = __nccwpck_require__(1825)
95955
+
95956
+ /**
95957
+ * Remembers the last two rows of digits so their characters need not be reread.
95958
+ * Positions start at -1 until a row has been found.
95959
+ *
95960
+ * @typedef {object} DigitRunCache
95961
+ * @property {number} start The first character of the most recently found row.
95962
+ * @property {number} end The position after that row's last character.
95963
+ * @property {number} previousStart The first character of the previous row.
95964
+ * @property {number} previousEnd The position after the previous row.
95965
+ */
95966
+
95967
+ // One entry per UTF-16 code unit keeps membership checks constant-time.
95968
+ const whitespace = new Uint8Array(0x10000)
95969
+ for (const char of WHITESPACE_CHARACTERS) {
95970
+ whitespace[char.charCodeAt(0)] = 1
95971
+ }
95972
+
95973
+ /**
95974
+ * Checks whether a character is whitespace, like a space, tab, or newline.
95975
+ * Looking past the end of the string returns false.
95976
+ *
95977
+ * @param {string|undefined} char One character, or undefined past the string's end.
95978
+ * @returns {boolean} Whether the character is whitespace.
95979
+ * @example isWhitespace(' ') // true
95980
+ * @example isWhitespace('1') // false
95981
+ */
95982
+ const isWhitespace = char =>
95983
+ char !== undefined && whitespace[char.charCodeAt(0)] === 1
95984
+
95985
+ /**
95986
+ * Checks for v, =, or whitespace before the version number.
95987
+ * These are historical version prefixes, not range operators:
95988
+ * < and > are handled separately, as are tilde and caret ranges.
95989
+ *
95990
+ * @param {string|undefined} char One character to check.
95991
+ * @returns {boolean} Whether the character can belong to a version prefix.
95992
+ * @example isVersionPrefix('=') // true
95993
+ * @example isVersionPrefix('>') // false
95994
+ */
95995
+ const isVersionPrefix = char =>
95996
+ char === 'v' ||
95997
+ char === '=' ||
95998
+ isWhitespace(char)
95999
+
96000
+ /**
96001
+ * Checks whether a character is one of the digits 0 through 9.
96002
+ *
96003
+ * @param {string|undefined} char One character to check.
96004
+ * @returns {boolean} Whether the character is an ASCII digit.
96005
+ * @example isDigit('7') // true
96006
+ * @example isDigit('.') // false
96007
+ */
96008
+ const isDigit = char => char !== undefined && char >= '0' && char <= '9'
96009
+
96010
+ /**
96011
+ * Checks whether a character is an English letter, uppercase or lowercase.
96012
+ *
96013
+ * @param {string|undefined} char One character to check.
96014
+ * @returns {boolean} Whether the character is an ASCII letter.
96015
+ * @example isLetter('b') // true
96016
+ * @example isLetter('7') // false
96017
+ */
96018
+ const isLetter = char =>
96019
+ char !== undefined && (
96020
+ (char >= 'a' && char <= 'z') ||
96021
+ (char >= 'A' && char <= 'Z')
96022
+ )
96023
+
96024
+ /**
96025
+ * Checks for a letter, digit, or hyphen: the characters allowed inside
96026
+ * prerelease and build names such as beta-1.
96027
+ *
96028
+ * @param {string|undefined} char One character to check.
96029
+ * @returns {boolean} Whether the character can be part of an identifier.
96030
+ * @example isIdentifierCharacter('-') // true
96031
+ * @example isIdentifierCharacter('.') // false; dots separate identifiers
96032
+ */
96033
+ const isIdentifierCharacter = char => isDigit(char) || isLetter(char) || char === '-'
96034
+
96035
+ /**
96036
+ * Checks whether a version component can begin here: with a digit or
96037
+ * a wildcard such as x, X, or *.
96038
+ *
96039
+ * @param {string|undefined} char One character to check.
96040
+ * @returns {boolean} Whether a number or wildcard can start with this character.
96041
+ * @example isVersionStart('x') // true
96042
+ * @example isVersionStart('v') // false; v belongs to the prefix
96043
+ */
96044
+ const isVersionStart = char =>
96045
+ isDigit(char) ||
96046
+ char === 'x' ||
96047
+ char === 'X' ||
96048
+ char === '*'
96049
+
96050
+ /**
96051
+ * Finds the end of a row of digits, but returns no more than limit digits.
96052
+ * Remembers the last two rows so looking at them again does not reread them.
96053
+ *
96054
+ * @param {string} range The text to read; it is not changed.
96055
+ * @param {number} start The position of the first character to check.
96056
+ * @param {number} limit The most digit characters the returned match can include.
96057
+ * @param {DigitRunCache} digitRuns Shared cache of digit-run positions, updated in place.
96058
+ * @returns {number} The position after the matched digits, or start if none match.
96059
+ * @example findDigitsEndIndex('123abc', 0, 10, digitRuns) // 3, pointing at a
96060
+ * @example findDigitsEndIndex('123abc', 0, 2, digitRuns) // 2, pointing at the unread 3
96061
+ */
96062
+ const findDigitsEndIndex = (range, start, limit, digitRuns) => {
96063
+ if (!isDigit(range[start])) {
96064
+ return start
96065
+ }
96066
+ if (start >= digitRuns.start && start < digitRuns.end) {
96067
+ return Math.min(start + limit, digitRuns.end)
96068
+ }
96069
+ if (start >= digitRuns.previousStart && start < digitRuns.previousEnd) {
96070
+ return Math.min(start + limit, digitRuns.previousEnd)
96071
+ }
96072
+ let end = start + 1
96073
+ while (isDigit(range[end])) {
96074
+ end++
96075
+ }
96076
+ // A failed full version can rewind from its second run to its first.
96077
+ digitRuns.previousStart = digitRuns.start
96078
+ digitRuns.previousEnd = digitRuns.end
96079
+ digitRuns.start = start
96080
+ digitRuns.end = end
96081
+ return Math.min(start + limit, end)
96082
+ }
96083
+
96084
+ /**
96085
+ * Reads a number using the old regex's length and leading-zero rules.
96086
+ * Strict mode reads just the first zero in 012; loose mode can read all three.
96087
+ *
96088
+ * @param {string} range The text to read; it is not changed.
96089
+ * @param {number} start The position where the number should begin.
96090
+ * @param {boolean} loose Whether to allow leading zeros.
96091
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96092
+ * @returns {number} The position after the matched digits, not their numeric value.
96093
+ * @example findVersionNumberEndIndex('012', 0, false, digitRuns) // 1
96094
+ * @example findVersionNumberEndIndex('012', 0, true, digitRuns) // 3
96095
+ */
96096
+ const findVersionNumberEndIndex = (range, start, loose, digitRuns) => {
96097
+ if (!loose && range[start] === '0') {
96098
+ return start + 1
96099
+ }
96100
+ // Strict syntax allows an initial nonzero digit plus MAX_LENGTH digits.
96101
+ return findDigitsEndIndex(range, start, loose ? MAX_LENGTH : MAX_LENGTH + 1, digitRuns)
96102
+ }
96103
+
96104
+ /**
96105
+ * Reads one piece of a prerelease name, such as beta or 1 in beta.1.
96106
+ * Tries the letter-or-hyphen form first, then the number-only form.
96107
+ *
96108
+ * @param {string} range The text to read; it is not changed.
96109
+ * @param {number} start The position where the identifier should begin.
96110
+ * @param {boolean} loose Whether numeric identifiers may have leading zeros.
96111
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96112
+ * @returns {number} The position after the identifier, or start if none matches.
96113
+ * @example findPrereleaseIdentifierEndIndex('beta.1', 0, false, digitRuns) // 4, at the dot
96114
+ * @example findPrereleaseIdentifierEndIndex('001beta', 0, false, digitRuns) // 7
96115
+ */
96116
+ const findPrereleaseIdentifierEndIndex = (range, start, loose, digitRuns) => {
96117
+ const digitsEnd = findDigitsEndIndex(range, start, MAX_LENGTH, digitRuns)
96118
+ // The legacy regex tries a nonnumeric identifier before a numeric one.
96119
+ if (isLetter(range[digitsEnd]) || range[digitsEnd] === '-') {
96120
+ let end = digitsEnd + 1
96121
+ const limit = end + MAX_SAFE_BUILD_LENGTH
96122
+ while (end < limit && isIdentifierCharacter(range[end])) {
96123
+ end++
96124
+ }
96125
+ return end
96126
+ }
96127
+ return findVersionNumberEndIndex(range, start, loose, digitRuns)
96128
+ }
96129
+
96130
+ /**
96131
+ * Reads a prerelease suffix such as -beta.1, one dot-separated piece at a time.
96132
+ * Loose mode also allows the name without its opening hyphen.
96133
+ *
96134
+ * @param {string} range The text to read; it is not changed.
96135
+ * @param {number} start The position where the suffix should begin, including -.
96136
+ * @param {boolean} loose Whether the opening hyphen is optional and zeros allowed.
96137
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96138
+ * @returns {number} The position after the matched suffix, or start if absent.
96139
+ * @example findPrereleaseEndIndex('-beta.1+sha', 0, false, digitRuns) // 7, at the plus
96140
+ * @example findPrereleaseEndIndex('beta', 0, false, digitRuns) // 0; no opening hyphen
96141
+ */
96142
+ const findPrereleaseEndIndex = (range, start, loose, digitRuns) => {
96143
+ const hyphen = range[start] === '-'
96144
+ if (!loose && !hyphen) {
96145
+ return start
96146
+ }
96147
+ const identifierStart = start + (hyphen ? 1 : 0)
96148
+ let end = findPrereleaseIdentifierEndIndex(range, identifierStart, loose, digitRuns)
96149
+ if (end === identifierStart) {
96150
+ if (!loose || !hyphen) {
96151
+ return start
96152
+ }
96153
+ // In loose syntax, a lone hyphen can itself be the identifier.
96154
+ end = findPrereleaseIdentifierEndIndex(range, start, loose, digitRuns)
96155
+ }
96156
+ while (range[end] === '.') {
96157
+ const next = findPrereleaseIdentifierEndIndex(range, end + 1, loose, digitRuns)
96158
+ if (next === end + 1) {
96159
+ break
96160
+ }
96161
+ end = next
96162
+ }
96163
+ return end
96164
+ }
96165
+
96166
+ /**
96167
+ * Reads one build-name piece, such as sha or 123 in +sha.123.
96168
+ * Stops at a disallowed character or the old regex's length limit.
96169
+ *
96170
+ * @param {string} range The text to read; it is not changed.
96171
+ * @param {number} start The position where the identifier should begin.
96172
+ * @returns {number} The position after the identifier, or start if none matches.
96173
+ * @example findBuildIdentifierEndIndex('sha.123', 0) // 3, at the dot
96174
+ * @example findBuildIdentifierEndIndex('001', 0) // 3; leading zeros are allowed
96175
+ */
96176
+ const findBuildIdentifierEndIndex = (range, start) => {
96177
+ let end = start
96178
+ while (end - start < MAX_SAFE_BUILD_LENGTH && isIdentifierCharacter(range[end])) {
96179
+ end++
96180
+ }
96181
+ return end
96182
+ }
96183
+
96184
+ /**
96185
+ * Reads optional build metadata such as +sha.123.
96186
+ * Leaves the position unchanged if there is no plus sign followed by a name.
96187
+ *
96188
+ * @param {string} range The text to read; it is not changed.
96189
+ * @param {number} start The position where the opening + should be.
96190
+ * @returns {number} The position after the matched metadata, or start if absent.
96191
+ * @example findBuildEndIndex('+sha.123 <2', 0) // 8, at the space
96192
+ * @example findBuildEndIndex('+', 0) // 0; a plus sign alone is not a match
96193
+ */
96194
+ const findBuildEndIndex = (range, start) => {
96195
+ if (range[start] !== '+') {
96196
+ return start
96197
+ }
96198
+ let end = findBuildIdentifierEndIndex(range, start + 1)
96199
+ if (end === start + 1) {
96200
+ return start
96201
+ }
96202
+ while (range[end] === '.') {
96203
+ const next = findBuildIdentifierEndIndex(range, end + 1)
96204
+ if (next === end + 1) {
96205
+ break
96206
+ }
96207
+ end = next
96208
+ }
96209
+ return end
96210
+ }
96211
+
96212
+ /**
96213
+ * Reads three numbers separated by dots, then any prerelease and build suffixes.
96214
+ * Uses loose rules, so forms such as 01.02.03beta can match here.
96215
+ *
96216
+ * @param {string} range The text to read; it is not changed.
96217
+ * @param {number} start The position of the first number, after any prefix.
96218
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96219
+ * @returns {number} The position after the version match, or start if none matches.
96220
+ * @example findLooseFullVersionEndIndex('1.2.3-beta+sha <2', 0, digitRuns) // 14
96221
+ * @example findLooseFullVersionEndIndex('1.2', 0, digitRuns) // 0; needs three numbers
96222
+ */
96223
+ const findLooseFullVersionEndIndex = (range, start, digitRuns) => {
96224
+ let end = start
96225
+ for (let component = 0; component < 3; component++) {
96226
+ const next = findVersionNumberEndIndex(range, end, true, digitRuns)
96227
+ if (next === end) {
96228
+ return start
96229
+ }
96230
+ end = next
96231
+ if (component < 2) {
96232
+ if (range[end] !== '.') {
96233
+ return start
96234
+ }
96235
+ end++
96236
+ }
96237
+ }
96238
+ const prereleaseEnd = findPrereleaseEndIndex(range, end, true, digitRuns)
96239
+ return findBuildEndIndex(range, prereleaseEnd)
96240
+ }
96241
+
96242
+ /**
96243
+ * Reads one component of a partial or wildcard version, such as 2 or x in 2.x.
96244
+ * Numbers use strict leading-zero rules; wildcards take up one character.
96245
+ *
96246
+ * @param {string} range The text to read; it is not changed.
96247
+ * @param {number} start The position where the component should begin.
96248
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96249
+ * @returns {number} The position after the component, or start if none matches.
96250
+ * @example findPartialVersionComponentEndIndex('2.x', 0, digitRuns) // 1, at the dot
96251
+ * @example findPartialVersionComponentEndIndex('2.x', 2, digitRuns) // 3, after x
96252
+ */
96253
+ const findPartialVersionComponentEndIndex = (range, start, digitRuns) => {
96254
+ if (isDigit(range[start])) {
96255
+ return findVersionNumberEndIndex(range, start, false, digitRuns)
96256
+ }
96257
+ return isVersionStart(range[start]) ? start + 1 : start
96258
+ }
96259
+
96260
+ /**
96261
+ * Reads up to three components, allowing forms such as 1, 1.2, or 1.x.
96262
+ * After the third component, also reads any strict prerelease and build suffixes.
96263
+ *
96264
+ * @param {string} range The text to read; it is not changed.
96265
+ * @param {number} start The position of a number or wildcard, after any prefix.
96266
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96267
+ * @returns {number} The position after the matched version text.
96268
+ * @example findPartialVersionEndIndex('1.x <2', 0, digitRuns) // 3, at the space
96269
+ * @example findPartialVersionEndIndex('1.', 0, digitRuns) // 1; the trailing dot is unread
96270
+ */
96271
+ const findPartialVersionEndIndex = (range, start, digitRuns) => {
96272
+ let end = findPartialVersionComponentEndIndex(range, start, digitRuns)
96273
+ for (let component = 0; component < 2; component++) {
96274
+ if (range[end] !== '.') {
96275
+ return end
96276
+ }
96277
+ const next = findPartialVersionComponentEndIndex(range, end + 1, digitRuns)
96278
+ if (next === end + 1) {
96279
+ return end
96280
+ }
96281
+ end = next
96282
+ }
96283
+ const prereleaseEnd = findPrereleaseEndIndex(range, end, false, digitRuns)
96284
+ return findBuildEndIndex(range, prereleaseEnd)
96285
+ }
96286
+
96287
+ /**
96288
+ * Finds where a version match ends, without deciding whether the range is valid.
96289
+ * Tries a loose full version first, then a partial or wildcard version, just
96290
+ * like the old regex's LOOSEPLAIN and XRANGEPLAIN alternatives.
96291
+ *
96292
+ * @param {string} range The text to read; it is not changed.
96293
+ * @param {number} start The position of a number or wildcard, after any prefix.
96294
+ * @param {DigitRunCache} digitRuns Shared digit-run cache, updated as needed.
96295
+ * @returns {number} The position where scanning the next candidate can resume.
96296
+ * @example findVersionEndIndex('1.2.3 <2', 0, digitRuns) // 5, at the space
96297
+ * @example findVersionEndIndex('1.x <2', 0, digitRuns) // 3, at the space
96298
+ */
96299
+ const findVersionEndIndex = (range, start, digitRuns) => {
96300
+ const fullVersionEnd = findLooseFullVersionEndIndex(range, start, digitRuns)
96301
+ return fullVersionEnd !== start
96302
+ ? fullVersionEnd
96303
+ : findPartialVersionEndIndex(range, start, digitRuns)
96304
+ }
96305
+
96306
+ /**
96307
+ * Finds the one whitespace character the old replacement would remove.
96308
+ * Keeps leading whitespace, skips an optional operator, and checks immediately
96309
+ * after it. Returns -1 if there is nothing to remove.
96310
+ *
96311
+ * @param {string} range The text containing a candidate already found by the caller.
96312
+ * @param {number} matchStart The candidate's position, including leading whitespace.
96313
+ * @returns {number} The position of the removable whitespace, or -1 if absent.
96314
+ * @example findRemovableWhitespaceIndex(' > 1', 0) // 2; keep the space at position 0
96315
+ * @example findRemovableWhitespaceIndex('>1', 0) // -1
96316
+ */
96317
+ const findRemovableWhitespaceIndex = (range, matchStart) => {
96318
+ let position = matchStart
96319
+ if (isWhitespace(range[position])) {
96320
+ position++
96321
+ }
96322
+ if (range[position] === '<' || range[position] === '>') {
96323
+ position++
96324
+ }
96325
+ if (range[position] === '=') {
96326
+ position++
96327
+ }
96328
+ return isWhitespace(range[position]) ? position : -1
96329
+ }
96330
+
96331
+ /**
96332
+ * Joins an operator to its version, turning > 1.2.3 into >1.2.3.
96333
+ * Copies everything else according to the old regex's matching rules.
96334
+ * Moves forward through prefixes and whole versions to avoid repeatedly
96335
+ * searching the same characters on long inputs.
96336
+ *
96337
+ * @param {string} range The range text to process; the original string is unchanged.
96338
+ * @returns {string} The range with matched operator whitespace removed.
96339
+ * @example trimComparatorWhitespace('> 1.2.3 < 2') // '>1.2.3 <2'
96340
+ * @example trimComparatorWhitespace('> invalid') // '> invalid'
96341
+ */
96342
+ const trimComparatorWhitespace = range => {
96343
+ let result = ''
96344
+ let copyFrom = 0
96345
+ let cursor = 0
96346
+ const digitRuns = { start: -1, end: -1, previousStart: -1, previousEnd: -1 }
96347
+
96348
+ while (cursor < range.length) {
96349
+ const matchStart = cursor
96350
+ if (range[cursor] === '<' || range[cursor] === '>') {
96351
+ cursor++
96352
+ } else if (!isVersionPrefix(range[cursor]) && !isVersionStart(range[cursor])) {
96353
+ cursor++
96354
+ continue
96355
+ }
96356
+
96357
+ // Consume a v/=/whitespace run once, even when no version follows it.
96358
+ while (cursor < range.length && isVersionPrefix(range[cursor])) {
96359
+ cursor++
96360
+ }
96361
+ if (!isVersionStart(range[cursor])) {
96362
+ continue
96363
+ }
96364
+
96365
+ const whitespacePosition = findRemovableWhitespaceIndex(range, matchStart)
96366
+ if (whitespacePosition !== -1) {
96367
+ result += range.slice(copyFrom, whitespacePosition)
96368
+ copyFrom = whitespacePosition + 1
96369
+ }
96370
+
96371
+ // Skip the entire match, so a prerelease's trailing v cannot be
96372
+ // reconsidered as the prefix of another version.
96373
+ cursor = findVersionEndIndex(range, cursor, digitRuns)
96374
+ }
96375
+
96376
+ return result + range.slice(copyFrom)
96377
+ }
96378
+
96379
+ module.exports = trimComparatorWhitespace
96380
+
96381
+
95894
96382
  /***/ }),
95895
96383
 
95896
96384
  /***/ 98736:
@@ -124740,22 +125228,37 @@ async function getOrgTeamsDirectAccess(org, octokit) {
124740
125228
  id
124741
125229
  name
124742
125230
  slug
124743
- repositories {
125231
+ }
125232
+ pageInfo {
125233
+ hasNextPage
125234
+ endCursor
125235
+ }
125236
+ }
125237
+ }
125238
+ }`, { org });
125239
+ // The GraphQL paginator handles one connection per query, so each team's
125240
+ // repositories must be paginated separately from the organization's teams.
125241
+ for (const team of response?.organization?.teams?.nodes ?? []) {
125242
+ const repositoryResponse = await octokit.graphql.paginate(`query paginate($cursor: String, $org: String!, $slug: String!) {
125243
+ organization(login: $org) {
125244
+ team(slug: $slug) {
125245
+ repositories(first: 100, after: $cursor) {
124744
125246
  edges {
124745
125247
  permission
124746
125248
  node {
124747
125249
  name
124748
125250
  }
124749
125251
  }
125252
+ pageInfo {
125253
+ hasNextPage
125254
+ endCursor
125255
+ }
124750
125256
  }
124751
125257
  }
124752
- pageInfo {
124753
- hasNextPage
124754
- endCursor
124755
- }
124756
125258
  }
124757
- }
124758
- }`, { org });
125259
+ }`, { org, slug: team.slug });
125260
+ team.repositories = repositoryResponse.organization.team.repositories;
125261
+ }
124759
125262
  return transformGraphQLResponse(response);
124760
125263
  }
124761
125264
  function transformGraphQLResponse(response) {
@@ -139639,22 +140142,30 @@ function seededRandom(str) {
139639
140142
 
139640
140143
 
139641
140144
 
139642
- const { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = __nccwpck_require__(88753)
140145
+ const { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = __nccwpck_require__(88753)
139643
140146
  const { SCHEMES, getSchemeHandler } = __nccwpck_require__(52256)
139644
140147
 
139645
140148
  const VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u
139646
140149
  const MALFORMED_SCHEME_ERROR = 'URI scheme is malformed.'
140150
+ const MALFORMED_HOST_ERROR = 'URI host is malformed.'
140151
+ // ASCII characters outside the RFC 3986 reg-name set (unreserved, sub-delims
140152
+ // and "%" for pct-encoded): C0 controls, space, DEL, and "#/:<>?@[\]^`{|}.
140153
+ const FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u
139647
140154
 
139648
140155
  /**
140156
+ * RFC 3986 section 3.1 does not allow percent-encoding in a scheme, so the
140157
+ * scheme is validated as-is and never decoded. Decoding would let inert input
140158
+ * such as `%6Aavascript:` become a live `javascript:` scheme.
140159
+ *
139649
140160
  * @param {string} scheme
139650
140161
  * @returns {string}
139651
140162
  */
139652
- function decodeValidScheme (scheme) {
139653
- const decodedScheme = unescape(String(scheme))
139654
- if (!VALID_SCHEME.test(decodedScheme)) {
140163
+ function validateScheme (scheme) {
140164
+ const stringScheme = String(scheme)
140165
+ if (!VALID_SCHEME.test(stringScheme)) {
139655
140166
  throw new TypeError(MALFORMED_SCHEME_ERROR)
139656
140167
  }
139657
- return decodedScheme
140168
+ return stringScheme
139658
140169
  }
139659
140170
 
139660
140171
  /**
@@ -139715,6 +140226,12 @@ function resolve (baseURI, relativeURI, options) {
139715
140226
  const resolvedHost = resolved.host
139716
140227
  const resolvedHostIsIP = resolvedHost !== undefined && resolvedHost !== '' &&
139717
140228
  (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6)
140229
+ // Inputs are parsed scheme-neutrally, so delimiters and controls in a domain
140230
+ // host are only detected here, once the final scheme is known. They always
140231
+ // fail closed, including in percent-encoded hosts.
140232
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
140233
+ throw new Error(MALFORMED_HOST_ERROR)
140234
+ }
139718
140235
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)
139719
140236
  // Percent escapes in an ASCII reg-name are encoded data. The WHATWG hostname
139720
140237
  // parser can reject them even though fast-uri preserves them safely as RFC
@@ -139772,14 +140289,17 @@ function resolveComponent (base, relative, options, skipNormalization) {
139772
140289
  if (relative.path[0] === '/') {
139773
140290
  target.path = removeDotSegments(relative.path)
139774
140291
  } else {
139775
- if ((base.userinfo !== undefined || base.host !== undefined || base.port !== undefined) && !base.path) {
140292
+ const baseHasAuthority = base.userinfo !== undefined || base.host !== undefined || base.port !== undefined
140293
+ if (baseHasAuthority && !base.path) {
139776
140294
  target.path = '/' + relative.path
139777
140295
  } else if (!base.path) {
139778
140296
  target.path = relative.path
139779
140297
  } else {
139780
140298
  target.path = base.path.slice(0, base.path.lastIndexOf('/') + 1) + relative.path
139781
140299
  }
139782
- target.path = removeDotSegments(target.path)
140300
+ target.path = base.scheme === undefined && !baseHasAuthority && target.path[0] !== '/'
140301
+ ? removeDotSegmentsRelative(target.path)
140302
+ : removeDotSegments(target.path)
139783
140303
  }
139784
140304
  target.query = relative.query
139785
140305
  }
@@ -139835,7 +140355,7 @@ function serialize (cmpts, opts) {
139835
140355
  const uriTokens = []
139836
140356
 
139837
140357
  if (component.scheme) {
139838
- component.scheme = decodeValidScheme(component.scheme)
140358
+ component.scheme = validateScheme(component.scheme)
139839
140359
  }
139840
140360
 
139841
140361
  // find scheme handler
@@ -139845,7 +140365,11 @@ function serialize (cmpts, opts) {
139845
140365
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options)
139846
140366
 
139847
140367
  const hasAuthority = component.userinfo !== undefined || component.host !== undefined || component.port !== undefined
139848
- const pathNoScheme = !options.skipEscape && component.scheme === undefined && !hasAuthority
140368
+ // A reference with no emitted scheme is path-noscheme: a bare ':' in its
140369
+ // first path segment would reparse as a scheme (RFC 3986 3.3/4.2). Enforced
140370
+ // under skipEscape too (resolve()), so the reapply below gates on this flag.
140371
+ const schemelessReference = (component.scheme === undefined || options.reference === 'suffix') && !hasAuthority
140372
+ const pathNoScheme = !options.skipEscape && schemelessReference
139849
140373
 
139850
140374
  if (component.path !== undefined) {
139851
140375
  if (!options.skipEscape) {
@@ -139857,7 +140381,7 @@ function serialize (cmpts, opts) {
139857
140381
 
139858
140382
  if (options.reference !== 'suffix' && component.scheme) {
139859
140383
  // Scheme handlers may replace the scheme during serialization.
139860
- component.scheme = decodeValidScheme(component.scheme)
140384
+ component.scheme = validateScheme(component.scheme)
139861
140385
  uriTokens.push(component.scheme, ':')
139862
140386
  }
139863
140387
 
@@ -139877,13 +140401,18 @@ function serialize (cmpts, opts) {
139877
140401
  let s = component.path
139878
140402
 
139879
140403
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
139880
- s = removeDotSegments(s)
140404
+ // A relative-path reference keeps its unresolvable leading ".." segments
140405
+ // and must never become root-relative (RFC 3986 section 5.2.4 applies to
140406
+ // merged target paths, not to the reference itself).
140407
+ s = schemelessReference && s[0] !== '/'
140408
+ ? removeDotSegmentsRelative(s)
140409
+ : removeDotSegments(s)
139881
140410
  }
139882
140411
 
139883
140412
  // Dot-segment removal can expose a colon that was not originally in the
139884
140413
  // first segment (for example, "./a:b"). Reapply path-noscheme encoding so
139885
140414
  // the serialized relative reference cannot be reparsed as a URI scheme.
139886
- if (pathNoScheme) {
140415
+ if (schemelessReference) {
139887
140416
  s = serializePathEncoding(s, true)
139888
140417
  }
139889
140418
 
@@ -139998,6 +140527,11 @@ function hasMalformedComponentPercentEncoding (matches) {
139998
140527
  * @returns {boolean} whether host conversion failed
139999
140528
  */
140000
140529
  function canonicalizeHost (parsed, options, schemeHandler, isIP) {
140530
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
140531
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
140532
+ return true
140533
+ }
140534
+
140001
140535
  if (
140002
140536
  !options.unicodeSupport &&
140003
140537
  (!schemeHandler || !schemeHandler.unicodeSupport) &&
@@ -140007,16 +140541,62 @@ function canonicalizeHost (parsed, options, schemeHandler, isIP) {
140007
140541
  isIP === false &&
140008
140542
  nonSimpleDomain(parsed.host)
140009
140543
  ) {
140544
+ let url
140010
140545
  try {
140011
- parsed.host = new URL('http://' + parsed.host).hostname
140546
+ url = new URL('http://' + parsed.host)
140012
140547
  } catch (e) {
140013
140548
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e
140014
140549
  return true
140015
140550
  }
140551
+ // The WHATWG parser must have read the whole input as a host. Anything
140552
+ // else means it found a delimiter fast-uri did not, so its hostname would
140553
+ // describe a different authority.
140554
+ if (!isHostOnlyURL(url)) {
140555
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
140556
+ return true
140557
+ }
140558
+ parsed.host = url.hostname
140016
140559
  }
140017
140560
  return false
140018
140561
  }
140019
140562
 
140563
+ /**
140564
+ * Whether a domain host contains an ASCII character that RFC 3986 does not
140565
+ * allow in a reg-name (unreserved, sub-delims, or pct-encoded). Such a host is
140566
+ * rejected instead of being handed to the WHATWG URL parser, which would treat
140567
+ * "@" as a userinfo delimiter (silently dropping the data before it) and strip
140568
+ * TAB, LF, and CR. Non-ASCII characters remain allowed for IDNs.
140569
+ *
140570
+ * @param {import('./types/index').URIComponent} parsed
140571
+ * @param {import('./types/index').Options} options
140572
+ * @param {{ domainHost?: boolean }|undefined} schemeHandler
140573
+ * @param {boolean} isIP
140574
+ * @returns {boolean}
140575
+ */
140576
+ function hasForbiddenDomainHost (parsed, options, schemeHandler, isIP) {
140577
+ return Boolean(
140578
+ parsed.host &&
140579
+ isIP === false &&
140580
+ !isIPLiteral(parsed.host) &&
140581
+ (options.domainHost || (schemeHandler && schemeHandler.domainHost)) &&
140582
+ FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host)
140583
+ )
140584
+ }
140585
+
140586
+ /**
140587
+ * @param {URL} url
140588
+ * @returns {boolean}
140589
+ */
140590
+ function isHostOnlyURL (url) {
140591
+ return url.username === '' &&
140592
+ url.password === '' &&
140593
+ url.port === '' &&
140594
+ url.pathname === '/' &&
140595
+ url.search === '' &&
140596
+ url.hash === '' &&
140597
+ url.hostname !== ''
140598
+ }
140599
+
140020
140600
  /**
140021
140601
  * @param {string} uri
140022
140602
  * @param {import('./types/index').Options} [opts]
@@ -140099,9 +140679,8 @@ function parseWithStatus (uri, opts) {
140099
140679
  parsed.fragment = matches[8]
140100
140680
 
140101
140681
  if (parsed.scheme !== undefined) {
140102
- const decodedScheme = unescape(parsed.scheme)
140103
- if (VALID_SCHEME.test(decodedScheme)) {
140104
- parsed.scheme = decodedScheme.toLowerCase()
140682
+ if (VALID_SCHEME.test(parsed.scheme)) {
140683
+ parsed.scheme = parsed.scheme.toLowerCase()
140105
140684
  } else {
140106
140685
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR
140107
140686
  malformedScheme = true
@@ -140135,7 +140714,7 @@ function parseWithStatus (uri, opts) {
140135
140714
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase()
140136
140715
 
140137
140716
  if (malformedIPLiteral) {
140138
- parsed.error = parsed.error || 'URI host is malformed.'
140717
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR
140139
140718
  malformedAuthorityOrPort = true
140140
140719
  }
140141
140720
  } else {
@@ -140172,7 +140751,11 @@ function parseWithStatus (uri, opts) {
140172
140751
  // pass only restores uppercase hex in escapes that remain encoded.
140173
140752
  host = normalizePercentEncoding(host.toLowerCase())
140174
140753
  }
140175
- parsed.host = reescapeHostDelimiters(host, isIP)
140754
+ // Resolution parses both inputs with the internal `null` scheme before
140755
+ // the effective scheme is known. Keep raw host delimiters for that step
140756
+ // so resolve() can reject them for domain-host schemes; the resolved
140757
+ // authority is encoded when it is serialized.
140758
+ parsed.host = isIP || options.scheme !== 'null' ? reescapeHostDelimiters(host, isIP) : host
140176
140759
  }
140177
140760
 
140178
140761
  if (!schemeHandler || (schemeHandler && !schemeHandler.skipNormalize)) {
@@ -140901,6 +141484,57 @@ function removeDotSegments (path) {
140901
141484
  return output.join('')
140902
141485
  }
140903
141486
 
141487
+ /**
141488
+ * Removes dot segments from the path of a relative reference (a path that does
141489
+ * not start with "/") without changing what it resolves to against any base.
141490
+ * Unlike `removeDotSegments`, leading ".." segments that cannot be collapsed
141491
+ * are kept, the result never becomes root-relative, and a result that would be
141492
+ * empty or start with an empty segment is prefixed with "." (an empty path
141493
+ * means "same document" and a leading "//" would introduce an authority).
141494
+ *
141495
+ * @param {string} path
141496
+ * @returns {string}
141497
+ */
141498
+ function removeDotSegmentsRelative (path) {
141499
+ if (path === '' || path[0] === '/') {
141500
+ return removeDotSegments(path)
141501
+ }
141502
+
141503
+ const segments = path.split('/')
141504
+ const last = segments.length - 1
141505
+ /** @type {string[]} */
141506
+ const output = []
141507
+ let trailingDirectory = false
141508
+
141509
+ for (let i = 0; i <= last; i++) {
141510
+ const segment = segments[i]
141511
+ if (segment === '.' || segment === '..') {
141512
+ if (segment === '..') {
141513
+ if (output.length !== 0 && output[output.length - 1] !== '..') {
141514
+ output.pop()
141515
+ } else {
141516
+ output.push('..')
141517
+ }
141518
+ }
141519
+ trailingDirectory = i === last
141520
+ } else {
141521
+ output.push(segment)
141522
+ }
141523
+ }
141524
+
141525
+ if (trailingDirectory && output[output.length - 1] !== '..') {
141526
+ output.push('')
141527
+ }
141528
+ if (output.length === 0 || output[0] === '' || output[0].includes(':')) {
141529
+ // An empty path, a leading empty segment ("//"), or a first segment
141530
+ // containing ":" (which would be mistaken for a scheme, RFC 3986 section
141531
+ // 4.2) must stay behind a "." segment so the reference keeps its meaning.
141532
+ output.unshift('.')
141533
+ }
141534
+
141535
+ return output.join('/')
141536
+ }
141537
+
140904
141538
  /**
140905
141539
  * Re-escape RFC 3986 gen-delims that must not appear literally in the host.
140906
141540
  * After the URI regex parses, these characters cannot be literal in the host
@@ -141296,6 +141930,7 @@ module.exports = {
141296
141930
  encodeFragment,
141297
141931
  escapePreservingEscapes,
141298
141932
  removeDotSegments,
141933
+ removeDotSegmentsRelative,
141299
141934
  isIPv4,
141300
141935
  isUUID,
141301
141936
  normalizeIPv6,
@@ -154998,9 +155633,25 @@ function createExpanders(path) {
154998
155633
  ;// CONCATENATED MODULE: external "node:fs/promises"
154999
155634
  const promises_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs/promises");
155000
155635
  var promises_default = /*#__PURE__*/__nccwpck_require__.n(promises_namespaceObject);
155636
+ // EXTERNAL MODULE: external "node:fs"
155637
+ var external_node_fs_ = __nccwpck_require__(73024);
155638
+ // EXTERNAL MODULE: external "node:path"
155639
+ var external_node_path_ = __nccwpck_require__(76760);
155640
+ var external_node_path_default = /*#__PURE__*/__nccwpck_require__.n(external_node_path_);
155641
+ ;// CONCATENATED MODULE: ../cdk8s_renderer/src/utils/fileIgnore.ts
155642
+
155643
+
155644
+ const FIRESTARTR_IGNORE_FILE = '.firestartrignore';
155645
+ /** Only the file's own directory matters; markers are not inherited. */
155646
+ function fileIgnore_isIgnoredFile(file) {
155647
+ return (/\.(yaml|yml)$/.test(file) &&
155648
+ (0,external_node_fs_.existsSync)(external_node_path_default().join(external_node_path_default().dirname(file), FIRESTARTR_IGNORE_FILE)));
155649
+ }
155650
+
155001
155651
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/crawler.ts
155002
155652
 
155003
155653
 
155654
+
155004
155655
  // Number of files being currently slurped
155005
155656
  let activeSlurps = 0;
155006
155657
  // Max number of files that can be being slurped at a given time
@@ -155110,11 +155761,16 @@ async function crawlDirectory(dirEnt, exec) {
155110
155761
  const entries = (await promises_namespaceObject.readdir(dirEnt))
155111
155762
  .map((entry) => external_path_.join(dirEnt, entry))
155112
155763
  .sort();
155764
+ const ignoreFiles = entries.includes(external_path_.join(dirEnt, FIRESTARTR_IGNORE_FILE));
155113
155765
  for (const entry of entries) {
155114
155766
  const testDir = await isDir(entry);
155115
155767
  if (testDir) {
155116
155768
  await crawlDirectory(entry, exec);
155117
155769
  }
155770
+ else if (external_path_.basename(entry) === FIRESTARTR_IGNORE_FILE ||
155771
+ (ignoreFiles && /\.(yaml|yml)$/.test(entry))) {
155772
+ continue;
155773
+ }
155118
155774
  else {
155119
155775
  await slurpFile(entry, exec);
155120
155776
  }
@@ -159484,10 +160140,6 @@ function addTraceabilityStamp(context, content) {
159484
160140
  }
159485
160141
  }
159486
160142
 
159487
- // EXTERNAL MODULE: external "node:path"
159488
- var external_node_path_ = __nccwpck_require__(76760);
159489
- // EXTERNAL MODULE: external "node:fs"
159490
- var external_node_fs_ = __nccwpck_require__(73024);
159491
160143
  ;// CONCATENATED MODULE: external "node:os"
159492
160144
  const external_node_os_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:os");
159493
160145
  ;// CONCATENATED MODULE: ../features_renderer/src/auxiliar.ts
@@ -160861,6 +161513,7 @@ function extractClaimPatches(rendered) {
160861
161513
 
160862
161514
 
160863
161515
 
161516
+
160864
161517
  // We need to ensure the grep command is a gnu version
160865
161518
  let IS_GNU_GREP = false;
160866
161519
  let GREP_ON_CHECK = false;
@@ -161054,7 +161707,9 @@ async function getClaimsByName(name, cwd = '.') {
161054
161707
  if (Object.values(VisitedClaims).includes(fileName)) {
161055
161708
  continue;
161056
161709
  }
161057
- entradas.push(external_path_.join(cwd, fileName));
161710
+ const entry = external_path_.join(cwd, fileName);
161711
+ if (!fileIgnore_isIgnoredFile(entry))
161712
+ entradas.push(entry);
161058
161713
  }
161059
161714
  return Promise.all(entradas.map((entrada) => {
161060
161715
  return loadRawClaim(entrada);
@@ -161184,6 +161839,7 @@ function claimsDefaulter_hasDeepPath(data, deepPath) {
161184
161839
 
161185
161840
 
161186
161841
 
161842
+
161187
161843
  const isYamlFile = new RegExp(/\.(yaml|yml)$/);
161188
161844
  /**
161189
161845
  *
@@ -161307,6 +161963,9 @@ async function loadInitializers(claim, claimPath, initializersPath = getPath('in
161307
161963
  return result;
161308
161964
  }
161309
161965
  function loadClaimDefaults() {
161966
+ if (fileIgnore_isIgnoredFile(`${getPath('claimsDefaults')}/claims_defaults.yaml`)) {
161967
+ return {};
161968
+ }
161310
161969
  try {
161311
161970
  return catalog_common/* default */.A.io.fromYaml(external_fs_.readFileSync(`${getPath('claimsDefaults')}/claims_defaults.yaml`, 'utf-8'));
161312
161971
  }
@@ -161891,6 +162550,7 @@ const KINDS_CR_MAP = {
161891
162550
 
161892
162551
 
161893
162552
 
162553
+
161894
162554
  function resolveStringReference(reference) {
161895
162555
  const referenceElements = reference.split(':');
161896
162556
  const actualKind = KINDS_CR_MAP[referenceElements[0]];
@@ -161911,6 +162571,8 @@ function resolveClaimFilesList(claimRefsList) {
161911
162571
  const fileList = claimRefsList.replace(/\s/g, '').split(',');
161912
162572
  const refList = [];
161913
162573
  for (const file of fileList) {
162574
+ if (isIgnoredFile(file))
162575
+ continue;
161914
162576
  try {
161915
162577
  const data = fs.readFileSync(file, 'utf-8');
161916
162578
  const claim = common.io.fromYaml(data);
@@ -161941,6 +162603,8 @@ async function* resolveClaimEntries(claimRefsList) {
161941
162603
  yield* resolveDirEntries(claimEntry);
161942
162604
  }
161943
162605
  else if (claimEntryStats.isFile()) {
162606
+ if (fileIgnore_isIgnoredFile(claimEntry))
162607
+ continue;
161944
162608
  logger.debug(`Sending entry ${resolveClaimFileRef(claimEntry)} (${claimEntry})`);
161945
162609
  yield resolveClaimFileRef(claimEntry);
161946
162610
  }
@@ -161960,12 +162624,15 @@ async function* resolveDirEntries(dir) {
161960
162624
  catch (err) {
161961
162625
  throw new Error(`Reading dir: ${dir}: ${err}`);
161962
162626
  }
162627
+ const ignoreFiles = entries.some((entry) => entry.name === FIRESTARTR_IGNORE_FILE);
161963
162628
  for (const entry of entries) {
161964
162629
  const fullPath = external_path_default().join(dir, entry.name);
161965
162630
  if (entry.isDirectory()) {
161966
162631
  yield* resolveDirEntries(fullPath);
161967
162632
  }
161968
- else if (entry.isFile() && entry.name.match(/\.yaml$|\.yml$/)) {
162633
+ else if (!ignoreFiles &&
162634
+ entry.isFile() &&
162635
+ entry.name.match(/\.yaml$|\.yml$/)) {
161969
162636
  const claimRef = await resolveClaimFileRef(fullPath);
161970
162637
  logger.debug(`Sending entry ${claimRef} (${fullPath})`);
161971
162638
  yield claimRef;
@@ -162040,12 +162707,15 @@ async function crawlClaimsDir(dir, basePath, claims) {
162040
162707
  catch (err) {
162041
162708
  throw new Error(`Reading directory ${dir}: ${err}`);
162042
162709
  }
162710
+ const ignoreFiles = entries.some((entry) => entry.name === FIRESTARTR_IGNORE_FILE);
162043
162711
  for (const entry of entries) {
162044
162712
  const fullPath = external_path_default().join(dir, entry.name);
162045
162713
  if (entry.isDirectory()) {
162046
162714
  await crawlClaimsDir(fullPath, basePath, claims);
162047
162715
  }
162048
- else if (entry.isFile() && entry.name.match(/\.yaml$|\.yml$/)) {
162716
+ else if (!ignoreFiles &&
162717
+ entry.isFile() &&
162718
+ entry.name.match(/\.yaml$|\.yml$/)) {
162049
162719
  try {
162050
162720
  const data = await external_fs_default().promises.readFile(fullPath, 'utf-8');
162051
162721
  const claim = catalog_common/* default */.A.io.fromYaml(data);
@@ -165582,17 +166252,17 @@ class GithubRepositoryChart extends BaseGithubChart {
165582
166252
  /**
165583
166253
  * @description This method creates the vars data for the repository
165584
166254
  * @param claim
165585
- * @returns VarsConfiguration
166255
+ * @returns VarsConfiguration, or undefined when the claim has no variables
165586
166256
  */
165587
166257
  createVars(claim) {
165588
- const vars = {};
165589
- const varsDefinition = claim.providers?.github?.vars;
165590
- if (varsDefinition) {
165591
- if (varsDefinition.actions) {
165592
- vars.actions = this.formatVars(varsDefinition.actions);
165593
- }
165594
- }
165595
- return vars;
166258
+ const actions = claim.providers?.github?.vars?.actions;
166259
+ // Omit the field entirely: an empty `vars: {}` becomes null under
166260
+ // Kubernetes Server-Side Apply when the last variable is removed.
166261
+ if (!actions?.length)
166262
+ return undefined;
166263
+ return {
166264
+ actions: this.formatVars(actions),
166265
+ };
165596
166266
  }
165597
166267
  formatVars(blockDefinition) {
165598
166268
  return blockDefinition.map((varDef) => {
@@ -351586,7 +352256,9 @@ async function upsertInitialStatus(pluralKind, namespace, item) {
351586
352256
  async function needsProvisioningOnCreateOrUpdate(cr) {
351587
352257
  const fCrLog = (cr) => `The item ${cr.kind}: ${cr.metadata.name}`;
351588
352258
  // NO STATUS
351589
- if (!('status' in cr) || !('conditions' in cr.status)) {
352259
+ if (!('status' in cr) ||
352260
+ !('conditions' in cr.status) ||
352261
+ cr.status.conditions.length === 0) {
351590
352262
  operator_src_logger.debug(`The custom resource '${cr.kind}/${cr.metadata.name}' is missing a status and any conditions.`);
351591
352263
  return { needs: true, reason: 'CREATED' };
351592
352264
  }
@@ -354124,87 +354796,94 @@ function getDiagnosticErrorCount() {
354124
354796
 
354125
354797
 
354126
354798
 
354127
-
354128
354799
  const DIAGNOSTIC_FILE = '/tmp/diagnostic';
354129
- const DIAGNOSTIC_INTERVAL_MS = 10 * 1000;
354800
+ const DEFAULT_DIAGNOSTIC_INTERVAL_SECONDS = 10;
354801
+ // setTimeout/setInterval clamp any delay above 2^31-1 ms to 1 ms, which would
354802
+ // turn a large configured interval into a tight write loop.
354803
+ const MAX_DIAGNOSTIC_INTERVAL_SECONDS = Math.floor((2 ** 31 - 1) / 1000);
354130
354804
  let _diagnosticTimer;
354131
- // Capture the set of CRD plurals that were missing when diagnostics began.
354132
- // Once recorded, observedKinds will permanently exclude kinds whose plural
354133
- // was missing at startup so that CRDs applied later while the operator is
354134
- // running do not retroactively appear in the observed list.
354135
- let _initialMissingPlurals;
354136
- function clearTimer() {
354137
- if (_diagnosticTimer !== undefined) {
354138
- clearInterval(_diagnosticTimer);
354139
- _diagnosticTimer = undefined;
354805
+ /**
354806
+ * Reads `OPERATOR_DIAGNOSTIC_INTERVAL_SECONDS`, falling back to the default for
354807
+ * absent or unusable values so a typo cannot disable diagnostics.
354808
+ */
354809
+ function getDiagnosticIntervalSeconds(env = process.env) {
354810
+ const raw = env.OPERATOR_DIAGNOSTIC_INTERVAL_SECONDS;
354811
+ if (raw === undefined)
354812
+ return DEFAULT_DIAGNOSTIC_INTERVAL_SECONDS;
354813
+ const parsed = Number(raw.trim());
354814
+ if (!Number.isFinite(parsed) ||
354815
+ parsed < 1 ||
354816
+ parsed > MAX_DIAGNOSTIC_INTERVAL_SECONDS) {
354817
+ return DEFAULT_DIAGNOSTIC_INTERVAL_SECONDS;
354140
354818
  }
354819
+ return Math.round(parsed);
354141
354820
  }
354142
- function loopDiagnosticFile(queue, maxSlots) {
354143
- if (process.env.DISABLE_DIAGNOSTIC_FILE) {
354821
+ /**
354822
+ * Starts the periodic diagnostic writer and writes the first snapshot right
354823
+ * away, so the file exists before any work item arrives.
354824
+ *
354825
+ * Idempotent: a second call while a writer is running is a no-op, so the
354826
+ * startup path and the in-loop call never race on the same file.
354827
+ *
354828
+ * @returns whether this call started the writer.
354829
+ */
354830
+ function startDiagnosticFile(source, maxSlots, env = process.env) {
354831
+ if (_diagnosticTimer !== undefined) {
354832
+ operator_src_logger.info('Diagnostic file writer already running, keeping the active one');
354833
+ return false;
354834
+ }
354835
+ if (env.DISABLE_DIAGNOSTIC_FILE) {
354144
354836
  operator_src_logger.info('Diagnostic file disabled by DISABLE_DIAGNOSTIC_FILE');
354145
- return;
354837
+ return false;
354146
354838
  }
354839
+ const intervalSeconds = getDiagnosticIntervalSeconds(env);
354147
354840
  let running = false;
354148
- _diagnosticTimer = setInterval(() => {
354841
+ const writeSnapshot = () => {
354149
354842
  if (running)
354150
354843
  return;
354151
354844
  running = true;
354152
- writeDiagnosticSnapshot(queue, maxSlots)
354845
+ // The source is read inside the snapshot builder, so a throwing seam becomes
354846
+ // a logged rejection instead of escaping into the caller.
354847
+ writeDiagnosticSnapshot(source, maxSlots)
354153
354848
  .then(() => {
354154
354849
  running = false;
354155
354850
  })
354156
354851
  .catch((err) => {
354852
+ // Best-effort: a failed snapshot never crashes the operator; the next
354853
+ // tick retries with a fresh snapshot.
354157
354854
  running = false;
354158
354855
  operator_src_logger.error(`Error writing diagnostic file: ${err}`);
354159
354856
  });
354160
- }, DIAGNOSTIC_INTERVAL_MS);
354161
- // Clear the interval on termination signals so the process can exit cleanly
354162
- const onSignal = () => clearTimer();
354163
- process.on('SIGTERM', onSignal);
354164
- process.on('SIGINT', onSignal);
354857
+ };
354858
+ writeSnapshot();
354859
+ _diagnosticTimer = setInterval(writeSnapshot, intervalSeconds * 1000);
354860
+ // Diagnostics must never keep the process alive nor change termination
354861
+ // behaviour: an unref'd timer cannot hold the process open, so shutting down
354862
+ // is left entirely to the operator's own signal handlers.
354863
+ if (typeof _diagnosticTimer.unref === 'function')
354864
+ _diagnosticTimer.unref();
354865
+ operator_src_logger.info(`Diagnostic file writer started (every ${intervalSeconds}s)`);
354866
+ return true;
354867
+ }
354868
+ function stopDiagnosticFile() {
354869
+ if (_diagnosticTimer !== undefined) {
354870
+ clearInterval(_diagnosticTimer);
354871
+ _diagnosticTimer = undefined;
354872
+ }
354165
354873
  }
354166
354874
  /** @internal for testing */
354167
354875
  function getDiagnosticTimer() {
354168
354876
  return _diagnosticTimer;
354169
354877
  }
354170
- async function writeDiagnosticSnapshot(queue, maxSlots) {
354878
+ async function writeDiagnosticSnapshot(source, maxSlots) {
354879
+ const snapshot = source();
354171
354880
  const now = new Date().toISOString();
354172
- // Queue counts
354173
- let pending = 0;
354174
- let processing = 0;
354175
- let finished = 0;
354176
- let blocked = 0;
354177
- let deadLetter = 0;
354881
+ const { pending, processing, finished, blocked, deadLetter } = snapshot;
354178
354882
  // Per-slot items
354179
354883
  const slotsMap = {};
354180
- for (const wi of queue) {
354181
- switch (wi.workStatus) {
354182
- case WorkStatus.PENDING:
354183
- pending++;
354184
- break;
354185
- case WorkStatus.PROCESSING:
354186
- processing++;
354187
- break;
354188
- case WorkStatus.FINISHED:
354189
- finished++;
354190
- break;
354191
- }
354192
- if (wi.isBlocked) {
354193
- blocked++;
354194
- }
354195
- if (wi.isDeadLetter) {
354196
- deadLetter++;
354197
- }
354198
- if (wi.workStatus === WorkStatus.PROCESSING && wi.slotId !== undefined) {
354199
- slotsMap[`slot-${wi.slotId}`] =
354200
- `${wi.item.kind}/${wi.item.metadata.name}`;
354201
- }
354202
- }
354203
- // Fill empty slots with null
354204
354884
  for (let i = 0; i < maxSlots; i++) {
354205
- if (!slotsMap[`slot-${i}`]) {
354206
- slotsMap[`slot-${i}`] = 'null';
354207
- }
354885
+ const key = `slot-${i}`;
354886
+ slotsMap[key] = snapshot.slots[key] ?? 'null';
354208
354887
  }
354209
354888
  // Semaphore stats
354210
354889
  const semaphoreCurrent = getCurrentConcurrentApiCalls();
@@ -354223,23 +354902,32 @@ async function writeDiagnosticSnapshot(queue, maxSlots) {
354223
354902
  const envBackendProvider = process.env.BACKEND_PROVIDER_NAME || 'kubernetes-provider';
354224
354903
  const envGithubAppId = process.env.GITHUB_APP_ID || '';
354225
354904
  const envTfmSkipGitConfig = process.env.TFM_SKIP_GIT_CONFIG || 'false';
354226
- // CRD diagnostics: observed kinds (from OPERATOR_KIND_LIST) and missing CRDs
354227
- // missing CRDs are derived from the runtime __crdMonitors map; any monitor
354228
- // that is started indicates an actively-missing CRD that is being watched.
354905
+ // CRD diagnostics: observed kinds (from OPERATOR_KIND_LIST) and missing CRDs.
354906
+ // `__crdMonitors` keeps one registration per kind whose CRD was absent when
354907
+ // observeKind ran, and a stopped monitor stays registered (crdMonitor only
354908
+ // flips isStarted). Such a kind has no informer attached until the operator is
354909
+ // restarted, so it must never be reported as observed. Deriving the
354910
+ // exclusions from the retained registrations - not from a sampled isStarted()
354911
+ // state - keeps a kind excluded when its monitor starts and stops between two
354912
+ // ticks, or registers after the first snapshot.
354229
354913
  const observedKindsRaw = envKindList
354230
354914
  .split(',')
354231
354915
  .map((s) => s.trim())
354232
354916
  .filter((s) => s.length > 0);
354233
354917
  const missingCrds = [];
354918
+ const registeredPlurals = new Set();
354234
354919
  try {
354235
354920
  const monitors = global.__crdMonitors;
354236
354921
  if (monitors && typeof monitors === 'object') {
354237
354922
  for (const [key, monitor] of monitors) {
354923
+ // key shape is namespace/plural (reflector uses `${namespace}/${plural}`)
354924
+ const plural = String(key).split('/').pop()?.toLowerCase();
354925
+ if (plural)
354926
+ registeredPlurals.add(plural);
354238
354927
  try {
354239
354928
  if (monitor &&
354240
354929
  typeof monitor.isStarted === 'function' &&
354241
354930
  monitor.isStarted()) {
354242
- // key shape is namespace/plural (reflector uses `${namespace}/${plural}`)
354243
354931
  missingCrds.push(String(key));
354244
354932
  }
354245
354933
  }
@@ -354252,13 +354940,7 @@ async function writeDiagnosticSnapshot(queue, maxSlots) {
354252
354940
  catch (e) {
354253
354941
  // defensive: do not fail diagnostic writing if globals are not present
354254
354942
  }
354255
- // Compute the set of plurals that were missing when diagnostics started.
354256
- // We only capture this once so that CRDs installed while the operator
354257
- // is running do not cause previously-missing kinds to become observed.
354258
- if (!_initialMissingPlurals) {
354259
- _initialMissingPlurals = new Set(missingCrds.map((k) => String(k).split('/').pop()?.toLowerCase() || ''));
354260
- }
354261
- const observedKinds = observedKindsRaw.filter((k) => !_initialMissingPlurals.has(k.toLowerCase()));
354943
+ const observedKinds = observedKindsRaw.filter((k) => !registeredPlurals.has(k.toLowerCase()));
354262
354944
  // Build YAML output
354263
354945
  let output = '';
354264
354946
  output += `timestamp: "${now}"\n`;
@@ -354273,7 +354955,7 @@ async function writeDiagnosticSnapshot(queue, maxSlots) {
354273
354955
  output += ` GITHUB_APP_ID: ${envGithubAppId}\n`;
354274
354956
  output += ` TFM_SKIP_GIT_CONFIG: ${envTfmSkipGitConfig}\n`;
354275
354957
  output += 'queue:\n';
354276
- output += ` total: ${queue.length}\n`;
354958
+ output += ` total: ${snapshot.total}\n`;
354277
354959
  output += ` pending: ${pending}\n`;
354278
354960
  output += ` processing: ${processing}\n`;
354279
354961
  output += ` finished: ${finished}\n`;
@@ -355157,6 +355839,13 @@ function getMaxSlotsFromEnvironment() {
355157
355839
  return parsedMaxSlots;
355158
355840
  }
355159
355841
  const MAX_SLOTS = getMaxSlotsFromEnvironment();
355842
+ /**
355843
+ * Number of concurrent processing slots, used by startup wiring that needs the
355844
+ * same capacity the processor loop uses.
355845
+ */
355846
+ function getMaxSlots() {
355847
+ return MAX_SLOTS;
355848
+ }
355160
355849
  function getQueueMetrics() {
355161
355850
  let renamed = 0;
355162
355851
  let updated = 0;
@@ -355217,6 +355906,37 @@ function getQueueMetrics() {
355217
355906
  },
355218
355907
  };
355219
355908
  }
355909
+ /**
355910
+ * Queue state for the diagnostic file. Counts come from the existing metrics
355911
+ * seam (`getQueueMetrics`) so scheduling state is never counted twice, and only
355912
+ * the fields the diagnostic file documents differently are derived here: `blocked`
355913
+ * keeps the historical `isBlocked` meaning instead of the parent-aware gauge,
355914
+ * and `slots` needs the per-slot assignment the gauge does not expose.
355915
+ */
355916
+ function getOperatorQueueSnapshot() {
355917
+ const metrics = getQueueMetrics();
355918
+ const slots = {};
355919
+ let blocked = 0;
355920
+ for (const workItem of queue) {
355921
+ if (workItem.isBlocked) {
355922
+ blocked++;
355923
+ }
355924
+ if (workItem.workStatus === WorkStatus.PROCESSING &&
355925
+ workItem.slotId !== undefined) {
355926
+ slots[`slot-${workItem.slotId}`] =
355927
+ `${workItem.item.kind}/${workItem.item.metadata.name}`;
355928
+ }
355929
+ }
355930
+ return {
355931
+ total: metrics.nItems,
355932
+ pending: metrics.nItemsPending,
355933
+ processing: metrics.nItemsProcessing,
355934
+ finished: metrics.nItemsFinished,
355935
+ blocked,
355936
+ deadLetter: metrics.nItemsInDeadLetterHandling,
355937
+ slots,
355938
+ };
355939
+ }
355220
355940
  let INIT = false;
355221
355941
  let podIsTerminating = false;
355222
355942
  const handleTerminationSignal = (signal) => {
@@ -355252,7 +355972,7 @@ async function processItem(workItem) {
355252
355972
  */
355253
355973
  async function processItem_loop() {
355254
355974
  loopWorkItemDebug(queue);
355255
- loopDiagnosticFile(queue, MAX_SLOTS);
355975
+ startDiagnosticFile(getOperatorQueueSnapshot, MAX_SLOTS);
355256
355976
  const deferredBookkeeper = new DeferredSchedulingBookkeeper();
355257
355977
  _deferredBookkeeper = deferredBookkeeper;
355258
355978
  const processItemSlotsManager = initProcessItemsSlots(MAX_SLOTS, true, (w) => deferredBookkeeper.incrementBlockedAttempt(w));
@@ -362088,6 +362808,11 @@ async function planTerraformWorkspace(cr, status, opts) {
362088
362808
  async function planGithubResource(cr, status, opts) {
362089
362809
  fDebug('Resolving references');
362090
362810
  const deps = await resolve(cr, getPrAwareItemByItemPath(opts, status), getSecret, opts.namespace);
362811
+ deps['self-outputs'] = {
362812
+ cr: cr?.metadata?.name
362813
+ ? await resolveSecretRef(cr.metadata.namespace || opts.namespace, cr, getSecret)
362814
+ : undefined,
362815
+ };
362091
362816
  fDebug('Running GitHub provisioner plan');
362092
362817
  return await gh_provisioner.runGhProvisioner({
362093
362818
  mainCr: cr,
@@ -363176,6 +363901,7 @@ async function tfLocal(cr, namespace, cmd = 'plan') {
363176
363901
 
363177
363902
 
363178
363903
 
363904
+
363179
363905
  let importModeActive = false;
363180
363906
  let withMetricsMode = false;
363181
363907
 
@@ -363209,6 +363935,9 @@ function runOperator(opts) {
363209
363935
  if (importModeSkipPlan)
363210
363936
  importModeSkipPlanActive = importModeSkipPlan;
363211
363937
  initActivityLog();
363938
+ // Start the /tmp/diagnostic flight recorder before any work arrives so the
363939
+ // file exists right after startup, independently of the processor loop.
363940
+ startDiagnosticFile(getOperatorQueueSnapshot, getMaxSlots());
363212
363941
  operator_src_logger.info(`started the operator with options ${JSON.stringify(opts)}`);
363213
363942
  // Create the immutable operator profile from startup env snapshot
363214
363943
  // Must happen before any work processing or feedback machinery
@@ -364223,7 +364952,7 @@ const crsStatusSubcommand = {
364223
364952
  };
364224
364953
 
364225
364954
  ;// CONCATENATED MODULE: ./package.json
364226
- const package_namespaceObject = {"rE":"3.1.1"};
364955
+ const package_namespaceObject = /*#__PURE__*/JSON.parse('{"rE":"3.2.0-snapshot-01"}');
364227
364956
  ;// CONCATENATED MODULE: ../../package.json
364228
364957
  const package_namespaceObject_1 = {"rE":"3.1.1"};
364229
364958
  // EXTERNAL MODULE: ../../node_modules/semver/index.js