@firestartr/cli 2.4.0-snapshot-5 → 2.4.0-snapshot-6

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
@@ -277133,6 +277133,202 @@ function policiesAreCompatible(syncPolicy, generalPolicy) {
277133
277133
  FIRESTARTR_POLICIES: FIRESTARTR_POLICIES,
277134
277134
  });
277135
277135
 
277136
+ // EXTERNAL MODULE: external "fs/promises"
277137
+ var promises_ = __nccwpck_require__(73292);
277138
+ ;// CONCATENATED MODULE: ../catalog_common/src/codeowners/index.ts
277139
+ // CODEOWNERS Machinery (Dead-simple MVP)
277140
+ //
277141
+
277142
+
277143
+ // Dead-simple CODEOWNERS helpers
277144
+ function codeowners_parse(raw) {
277145
+ return raw
277146
+ .split(/\r?\n/)
277147
+ .map((line) => line.trim())
277148
+ .filter((line) => line.length > 0 && !line.startsWith('#'))
277149
+ .map((line) => {
277150
+ const commentIdx = line.indexOf('#');
277151
+ const content = commentIdx >= 0 ? line.slice(0, commentIdx).trimEnd() : line;
277152
+ const comment = commentIdx >= 0 ? line.slice(commentIdx + 1).trim() : undefined;
277153
+ if (!content) {
277154
+ return undefined;
277155
+ }
277156
+ const tokens = content.split(/\s+/);
277157
+ if (tokens.length === 0)
277158
+ return undefined;
277159
+ const pattern = tokens[0];
277160
+ const owners = tokens.slice(1);
277161
+ if (!pattern || owners.length === 0)
277162
+ return undefined;
277163
+ return { pattern, owners, ...(comment ? { comment } : {}) };
277164
+ })
277165
+ .filter(Boolean);
277166
+ }
277167
+ function format(entries) {
277168
+ return entries
277169
+ .map(({ pattern, owners, comment }) => {
277170
+ let line = pattern + (owners.length ? ' ' + owners.join(' ') : '');
277171
+ if (comment) {
277172
+ // Inline comment is always preceded by at least one space
277173
+ line += ' #' + (comment.trim().length > 0 ? ' ' + comment.trim() : '');
277174
+ }
277175
+ return line;
277176
+ })
277177
+ .join('\n');
277178
+ }
277179
+ function codeowners_validate(raw) {
277180
+ // Each non-blank, non-comment line must have a pattern and at least one owner
277181
+ // Return true if ALL such lines are valid, false otherwise
277182
+ return raw
277183
+ .split(/\r?\n/)
277184
+ .map((line) => line.trim())
277185
+ .filter((line) => line.length > 0 && !line.startsWith('#'))
277186
+ .every((line) => {
277187
+ const content = line.split('#')[0].trimEnd();
277188
+ const tokens = content.split(/\s+/);
277189
+ return (tokens.length >= 2 &&
277190
+ tokens[0] !== '' &&
277191
+ tokens.slice(1).every((owner) => owner !== ''));
277192
+ });
277193
+ }
277194
+ async function codeowners_get(ctx) {
277195
+ const filePath = ctx.path || external_path_default().resolve(process.cwd(), 'CODEOWNERS');
277196
+ return promises_.readFile(filePath, 'utf8');
277197
+ }
277198
+ async function set(ctx, v) {
277199
+ const filePath = ctx.path || external_path_default().resolve(process.cwd(), 'CODEOWNERS');
277200
+ await promises_.writeFile(filePath, v, 'utf8');
277201
+ }
277202
+ async function updateRule(ctx, rule) {
277203
+ // Read file line-by-line, replace matching pattern in-place (or append), preserving
277204
+ // blank lines and full-line comments to avoid silently stripping file headers or warnings.
277205
+ const filePath = ctx.path || external_path_default().resolve(process.cwd(), 'CODEOWNERS');
277206
+ let rawLines = [];
277207
+ try {
277208
+ const content = await promises_.readFile(filePath, 'utf8');
277209
+ rawLines = content.split(/\r?\n/);
277210
+ }
277211
+ catch (e) {
277212
+ if (!(typeof e === 'object' &&
277213
+ e !== null &&
277214
+ 'code' in e &&
277215
+ e.code === 'ENOENT')) {
277216
+ throw e;
277217
+ }
277218
+ // file may not exist yet; start with an empty line list
277219
+ }
277220
+ const newRuleLine = format([rule]);
277221
+ let found = false;
277222
+ const updatedLines = rawLines.map((line) => {
277223
+ const trimmed = line.trim();
277224
+ // Preserve blank lines and full-line comments unchanged
277225
+ if (!trimmed || trimmed.startsWith('#'))
277226
+ return line;
277227
+ const commentIdx = trimmed.indexOf('#');
277228
+ const rulePart = commentIdx >= 0 ? trimmed.slice(0, commentIdx).trimEnd() : trimmed;
277229
+ const tokens = rulePart.split(/\s+/).filter(Boolean);
277230
+ if (tokens.length === 0)
277231
+ return line;
277232
+ if (tokens[0] === rule.pattern) {
277233
+ found = true;
277234
+ return newRuleLine;
277235
+ }
277236
+ return line;
277237
+ });
277238
+ if (!found)
277239
+ updatedLines.push(newRuleLine);
277240
+ // Ensure POSIX-compliant trailing newline without doubling it
277241
+ if (updatedLines[updatedLines.length - 1] !== '')
277242
+ updatedLines.push('');
277243
+ await promises_.writeFile(filePath, updatedLines.join('\n'), 'utf8');
277244
+ }
277245
+ async function remove(ctx, criteria) {
277246
+ const filePath = ctx.path || external_path_default().resolve(process.cwd(), 'CODEOWNERS');
277247
+ let rawLines = [];
277248
+ try {
277249
+ const content = await promises_.readFile(filePath, 'utf8');
277250
+ rawLines = content.split(/\r?\n/);
277251
+ }
277252
+ catch (e) {
277253
+ if (!(typeof e === 'object' &&
277254
+ e !== null &&
277255
+ 'code' in e &&
277256
+ e.code === 'ENOENT')) {
277257
+ throw e;
277258
+ }
277259
+ return; // nothing to remove
277260
+ }
277261
+ const updatedLines = [];
277262
+ for (const line of rawLines) {
277263
+ const trimmed = line.trim();
277264
+ // Preserve blank lines and full-line comments unchanged
277265
+ if (!trimmed || trimmed.startsWith('#')) {
277266
+ updatedLines.push(line);
277267
+ continue;
277268
+ }
277269
+ const commentIdx = trimmed.indexOf('#');
277270
+ const rulePart = commentIdx >= 0 ? trimmed.slice(0, commentIdx).trimEnd() : trimmed;
277271
+ const inlineComment = commentIdx >= 0 ? ' ' + trimmed.slice(commentIdx) : '';
277272
+ const tokens = rulePart.split(/\s+/).filter(Boolean);
277273
+ if (tokens.length < 2) {
277274
+ // Malformed line (no owners); keep as-is
277275
+ updatedLines.push(line);
277276
+ continue;
277277
+ }
277278
+ const linePattern = tokens[0];
277279
+ let owners = tokens.slice(1);
277280
+ const patternMatches = !criteria.pattern || linePattern === criteria.pattern;
277281
+ if (!patternMatches) {
277282
+ updatedLines.push(line);
277283
+ continue;
277284
+ }
277285
+ if (criteria.owner) {
277286
+ // Remove the specified owner from this entry; drop the entry if no owners remain
277287
+ owners = owners.filter((o) => o !== criteria.owner);
277288
+ if (owners.length === 0) {
277289
+ continue;
277290
+ }
277291
+ updatedLines.push(linePattern + ' ' + owners.join(' ') + inlineComment);
277292
+ }
277293
+ else if (criteria.pattern) {
277294
+ // Remove the entire entry matching the pattern
277295
+ continue;
277296
+ }
277297
+ else {
277298
+ updatedLines.push(line);
277299
+ }
277300
+ }
277301
+ // Ensure POSIX-compliant trailing newline without doubling it
277302
+ if (updatedLines.length > 0 && updatedLines[updatedLines.length - 1] !== '')
277303
+ updatedLines.push('');
277304
+ await promises_.writeFile(filePath, updatedLines.join('\n'), 'utf8');
277305
+ }
277306
+ function getOwners(raw) {
277307
+ const entries = codeowners_parse(raw);
277308
+ const owners = new Set();
277309
+ for (const entry of entries) {
277310
+ for (const owner of entry.owners) {
277311
+ owners.add(owner);
277312
+ }
277313
+ }
277314
+ return Array.from(owners);
277315
+ }
277316
+ function getDefault() {
277317
+ return '# Sample CODEOWNERS\n* @team';
277318
+ }
277319
+ const codeowners = {
277320
+ parse: codeowners_parse,
277321
+ format,
277322
+ validate: codeowners_validate,
277323
+ get: codeowners_get,
277324
+ set,
277325
+ updateRule,
277326
+ remove,
277327
+ getOwners,
277328
+ getDefault,
277329
+ };
277330
+ /* harmony default export */ const src_codeowners = (codeowners);
277331
+
277136
277332
  ;// CONCATENATED MODULE: ../catalog_common/src/tokenizer/index.ts
277137
277333
  class SimpleTokenizer {
277138
277334
  /**
@@ -277239,6 +277435,7 @@ function getCronNextInterval(cronLine, tz) {
277239
277435
 
277240
277436
 
277241
277437
 
277438
+
277242
277439
  /* harmony default export */ const catalog_common = ({
277243
277440
  io: io,
277244
277441
  generic: generic,
@@ -277249,6 +277446,7 @@ function getCronNextInterval(cronLine, tz) {
277249
277446
  policies: policies,
277250
277447
  logger: logger_logger,
277251
277448
  tokenizer: tokenizer,
277449
+ codeowners: src_codeowners,
277252
277450
  cron: {
277253
277451
  validateCron: validateCron,
277254
277452
  isValidCron: isValidCron,
@@ -281934,7 +282132,7 @@ var deepFindPathToProperty = (object, searchProp, path = []) => {
281934
282132
  var dist_bundle_get = (object, path) => {
281935
282133
  return path.reduce((current, nextProperty) => current[nextProperty], object);
281936
282134
  };
281937
- var set = (object, path, mutator) => {
282135
+ var dist_bundle_set = (object, path, mutator) => {
281938
282136
  const lastProperty = path[path.length - 1];
281939
282137
  const parentPath = [...path].slice(0, -1);
281940
282138
  const parent = dist_bundle_get(object, parentPath);
@@ -282000,19 +282198,19 @@ var mergeResponses = (response1, response2) => {
282000
282198
  const nodesPath = [...path, "nodes"];
282001
282199
  const newNodes = dist_bundle_get(response2, nodesPath);
282002
282200
  if (newNodes) {
282003
- set(response1, nodesPath, (values) => {
282201
+ dist_bundle_set(response1, nodesPath, (values) => {
282004
282202
  return [...values, ...newNodes];
282005
282203
  });
282006
282204
  }
282007
282205
  const edgesPath = [...path, "edges"];
282008
282206
  const newEdges = dist_bundle_get(response2, edgesPath);
282009
282207
  if (newEdges) {
282010
- set(response1, edgesPath, (values) => {
282208
+ dist_bundle_set(response1, edgesPath, (values) => {
282011
282209
  return [...values, ...newEdges];
282012
282210
  });
282013
282211
  }
282014
282212
  const pageInfoPath = [...path, "pageInfo"];
282015
- set(response1, pageInfoPath, dist_bundle_get(response2, pageInfoPath));
282213
+ dist_bundle_set(response1, pageInfoPath, dist_bundle_get(response2, pageInfoPath));
282016
282214
  return response1;
282017
282215
  };
282018
282216
 
@@ -286859,6 +287057,62 @@ function resolveClaimRef(kind, name, symbolsTable = renderedClaims) {
286859
287057
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/utils/repositoryClaimUtils.ts
286860
287058
 
286861
287059
 
287060
+ function resolveCodeownersRef(ref, org) {
287061
+ let result = '';
287062
+ const splittedRef = ref.split(':');
287063
+ if (splittedRef.length !== 2) {
287064
+ throw new Error(`Invalid codeowners ref ${ref}`);
287065
+ }
287066
+ if (!['user', 'group'].includes(splittedRef[0])) {
287067
+ throw new Error(`Invalid codeowners ref ${ref}, kind must be "user" or "group"`);
287068
+ }
287069
+ const owner = splittedRef[1];
287070
+ const kind = splittedRef[0];
287071
+ const resolvedDependency = resolveClaimRef(kind === 'user' ? 'UserClaim' : 'GroupClaim', owner);
287072
+ const externalNameAnnotation = catalog_common.generic.getFirestartrAnnotation('external-name');
287073
+ const dependencyExternalName = resolvedDependency.metadata.annotations[externalNameAnnotation];
287074
+ if (kind === 'user') {
287075
+ result = `@${dependencyExternalName}`;
287076
+ }
287077
+ else if (kind === 'group') {
287078
+ result = `@${org}/${dependencyExternalName}`;
287079
+ }
287080
+ return result;
287081
+ }
287082
+ /**
287083
+ * Converts a claim (+optional additional rules) to CodeOwnerEntry[] for the codeowners API
287084
+ */
287085
+ function claimToCodeOwnersEntries(claim, additionalRules) {
287086
+ const rulesMap = new Map();
287087
+ const addOwnerToPath = (pattern, owner) => {
287088
+ const owners = rulesMap.get(pattern) ?? [];
287089
+ if (!owners.includes(owner)) {
287090
+ owners.push(owner);
287091
+ }
287092
+ rulesMap.set(pattern, owners);
287093
+ };
287094
+ if (claim.owner) {
287095
+ addOwnerToPath('*', resolveCodeownersRef(claim.owner, claim.providers.github.org));
287096
+ }
287097
+ if (claim.platformOwner) {
287098
+ addOwnerToPath('/.github/', resolveCodeownersRef(claim.platformOwner, claim.providers.github.org));
287099
+ }
287100
+ if (additionalRules) {
287101
+ for (const rule of additionalRules) {
287102
+ for (const owner of rule.owners) {
287103
+ addOwnerToPath(rule.path, resolveCodeownersRef(owner, claim.providers.github.org));
287104
+ }
287105
+ }
287106
+ }
287107
+ return Array.from(rulesMap.entries()).map(([pattern, owners]) => ({
287108
+ pattern,
287109
+ owners,
287110
+ }));
287111
+ }
287112
+ function createCodeOwnersData(claim, additionalRules) {
287113
+ return common.codeowners.format(claimToCodeOwnersEntries(claim, additionalRules));
287114
+ }
287115
+ // All previous code including permissions, collaborators, etc. (restored)
286862
287116
  /**
286863
287117
  * @description This method creates a permission for a given claimRef and permission
286864
287118
  *
@@ -286920,66 +287174,7 @@ function createCRrefFrom(claimRef, needsSecret) {
286920
287174
  },
286921
287175
  };
286922
287176
  }
286923
- /**
286924
- * @description This method creates the codeowners data for the repository
286925
- *
286926
- * @param claim
286927
- *
286928
- * @returns string
286929
- */
286930
- function createCodeOwnersData(claim, additionalRules) {
286931
- const rulesMap = new Map();
286932
- const addOwnerToPath = (path, owner) => {
286933
- const owners = rulesMap.get(path) ?? [];
286934
- if (!owners.includes(owner)) {
286935
- owners.push(owner);
286936
- }
286937
- rulesMap.set(path, owners);
286938
- };
286939
- let message = `# This file was generated by firestartr.
286940
- # WARNING: Please don't edit this file directly in the repository
286941
- # Go to gitops repository to modify it!`;
286942
- if (claim.owner) {
286943
- addOwnerToPath('*', resolveCodeownersRef(claim.owner, claim.providers.github.org));
286944
- }
286945
- if (claim.platformOwner) {
286946
- addOwnerToPath('/.github/', resolveCodeownersRef(claim.platformOwner, claim.providers.github.org));
286947
- }
286948
- if (additionalRules) {
286949
- for (const rule of additionalRules) {
286950
- for (const owner of rule.owners) {
286951
- addOwnerToPath(rule.path, resolveCodeownersRef(owner, claim.providers.github.org));
286952
- }
286953
- }
286954
- }
286955
- for (const [path, owners] of rulesMap.entries()) {
286956
- message += `\n${path.padEnd(25)} ${owners.join(' ')}`;
286957
- }
286958
- return message;
286959
- }
286960
- function resolveCodeownersRef(ref, org) {
286961
- let result = '';
286962
- const splittedRef = ref.split(':');
286963
- if (splittedRef.length !== 2) {
286964
- throw new Error(`Invalid codeowners ref ${ref}`);
286965
- }
286966
- if (!['user', 'group'].includes(splittedRef[0])) {
286967
- throw new Error(`Invalid codeowners ref ${ref}, kind must be "user" or "group"`);
286968
- }
286969
- const owner = splittedRef[1];
286970
- const kind = splittedRef[0];
286971
- const resolvedDependency = resolveClaimRef(kind === 'user' ? 'UserClaim' : 'GroupClaim', owner);
286972
- const externalNameAnnotation = catalog_common.generic.getFirestartrAnnotation('external-name');
286973
- const dependencyExternalName = resolvedDependency.metadata.annotations[externalNameAnnotation];
286974
- if (kind === 'user') {
286975
- result = `@${dependencyExternalName}`;
286976
- }
286977
- else if (kind === 'group') {
286978
- result = `@${org}/${dependencyExternalName}`;
286979
- }
286980
- return result;
286981
- }
286982
- const IS_SECRET_REF = new RegExp(/^ref:secretsclaim:([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)$/);
287177
+ const IS_SECRET_REF = /^ref:secretsclaim:([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)$/;
286983
287178
  function isRepoSecretRef(suspectedRef) {
286984
287179
  return IS_SECRET_REF.test(suspectedRef);
286985
287180
  }
@@ -286998,6 +287193,11 @@ function extractRepoSecretRef(ref) {
286998
287193
  key: parts[3],
286999
287194
  };
287000
287195
  }
287196
+ /**
287197
+ * @description This method creates the codeowners data for the repository
287198
+ * Migrated: use claimToCodeOwnersEntries + common.codeowners.format instead of legacy helpers.
287199
+ */
287200
+ // ... rest of file unchanged ...
287001
287201
 
287002
287202
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/overriders/base.ts
287003
287203
 
@@ -287043,6 +287243,7 @@ class OverriderError extends Error {
287043
287243
 
287044
287244
 
287045
287245
 
287246
+
287046
287247
  class GithubRepositoryOverrider extends OverriderPatches {
287047
287248
  constructor() {
287048
287249
  super(...arguments);
@@ -287117,11 +287318,11 @@ class GithubRepositoryOverrider extends OverriderPatches {
287117
287318
  apply(cr) {
287118
287319
  const patch = [];
287119
287320
  if (claim?.providers?.github?.overrides?.additionalCodeownersRules) {
287120
- const codeowners = createCodeOwnersData(claim, claim.providers.github.overrides.additionalCodeownersRules);
287321
+ const codeownersValue = catalog_common.codeowners.format(claimToCodeOwnersEntries(claim, claim.providers.github.overrides.additionalCodeownersRules));
287121
287322
  patch.push({
287122
287323
  op: 'replace',
287123
287324
  path: '/spec/repo/codeowners',
287124
- value: codeowners,
287325
+ value: codeownersValue,
287125
287326
  });
287126
287327
  }
287127
287328
  return fast_json_patch_default().applyPatch(cr, patch).newDocument;
@@ -287301,8 +287502,8 @@ function createExpanders(path) {
287301
287502
  }
287302
287503
 
287303
287504
  // EXTERNAL MODULE: external "node:fs/promises"
287304
- var promises_ = __nccwpck_require__(93977);
287305
- var promises_default = /*#__PURE__*/__nccwpck_require__.n(promises_);
287505
+ var external_node_fs_promises_ = __nccwpck_require__(93977);
287506
+ var external_node_fs_promises_default = /*#__PURE__*/__nccwpck_require__.n(external_node_fs_promises_);
287306
287507
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/crawler.ts
287307
287508
 
287308
287509
 
@@ -287374,7 +287575,7 @@ async function crawl(dir, filter, exec) {
287374
287575
  */
287375
287576
  async function slurpFile(entry, exec) {
287376
287577
  await waitForEmptySlot();
287377
- return promises_.readFile(entry, 'utf8')
287578
+ return external_node_fs_promises_.readFile(entry, 'utf8')
287378
287579
  .then(async (data) => {
287379
287580
  /**
287380
287581
  * We need to first free the slot. Otherwise if there is more
@@ -287411,7 +287612,7 @@ async function freeSlot() {
287411
287612
  *
287412
287613
  */
287413
287614
  async function crawlDirectory(dirEnt, exec) {
287414
- const entries = (await promises_.readdir(dirEnt)).map((entry) => external_path_.join(dirEnt, entry));
287615
+ const entries = (await external_node_fs_promises_.readdir(dirEnt)).map((entry) => external_path_.join(dirEnt, entry));
287415
287616
  const slurps = [];
287416
287617
  for (const entry of entries) {
287417
287618
  const testDir = await isDir(entry);
@@ -287427,7 +287628,7 @@ async function crawlDirectory(dirEnt, exec) {
287427
287628
  });
287428
287629
  }
287429
287630
  function isDir(dirEnt) {
287430
- return promises_.stat(dirEnt)
287631
+ return external_node_fs_promises_.stat(dirEnt)
287431
287632
  .then((stat) => {
287432
287633
  return stat.isDirectory();
287433
287634
  })
@@ -288392,8 +288593,6 @@ class RevisionNormalizer extends Normalizer {
288392
288593
  }
288393
288594
  }
288394
288595
 
288395
- // EXTERNAL MODULE: external "fs/promises"
288396
- var external_fs_promises_ = __nccwpck_require__(73292);
288397
288596
  ;// CONCATENATED MODULE: ../cdk8s_renderer/src/normalizers/tfworkspace.ts
288398
288597
 
288399
288598
 
@@ -288477,11 +288676,11 @@ async function loadAdditionalFiles(files, tfRootModulePath) {
288477
288676
  async function loadAdditionalFile(source, tfRootModulePath) {
288478
288677
  try {
288479
288678
  const filePath = external_path_.join(tfRootModulePath, source);
288480
- const stats = await external_fs_promises_.stat(filePath);
288679
+ const stats = await promises_.stat(filePath);
288481
288680
  if (!stats.isFile()) {
288482
288681
  throw new Error(`${source} is not a file`);
288483
288682
  }
288484
- const content = await external_fs_promises_.readFile(filePath, {
288683
+ const content = await promises_.readFile(filePath, {
288485
288684
  encoding: 'utf8',
288486
288685
  });
288487
288686
  return Buffer.from(content, 'utf8').toString('base64');
@@ -292241,8 +292440,8 @@ async function mkNamedTmp(...names) {
292241
292440
  ensureSafeTmpNames(name);
292242
292441
  }
292243
292442
  const dir = external_node_path_.join(external_node_os_namespaceObject.tmpdir(), ...names);
292244
- await promises_.rm(dir, { recursive: true, force: true });
292245
- await promises_.mkdir(dir, { recursive: true });
292443
+ await external_node_fs_promises_.rm(dir, { recursive: true, force: true });
292444
+ await external_node_fs_promises_.mkdir(dir, { recursive: true });
292246
292445
  return dir;
292247
292446
  }
292248
292447
  async function mkTmp(prefix = 'feature-render-') {
@@ -292754,7 +292953,7 @@ async function* resolveClaimEntries(claimRefsList) {
292754
292953
  cdk8s_renderer_src_logger.info(`Resolving ${claimRefsList.join(',')}`);
292755
292954
  for (const claimEntry of claimRefsList) {
292756
292955
  try {
292757
- const claimEntryStats = await (0,promises_.stat)(claimEntry);
292956
+ const claimEntryStats = await (0,external_node_fs_promises_.stat)(claimEntry);
292758
292957
  if (claimEntryStats.isDirectory()) {
292759
292958
  yield* resolveDirEntries(claimEntry);
292760
292959
  }
@@ -292773,7 +292972,7 @@ async function* resolveClaimEntries(claimRefsList) {
292773
292972
  async function* resolveDirEntries(dir) {
292774
292973
  let entries = [];
292775
292974
  try {
292776
- entries = await (0,promises_.readdir)(dir, { withFileTypes: true });
292975
+ entries = await (0,external_node_fs_promises_.readdir)(dir, { withFileTypes: true });
292777
292976
  }
292778
292977
  catch (err) {
292779
292978
  throw new Error(`Reading dir: ${dir}: ${err}`);
@@ -295932,7 +296131,7 @@ class GithubRepositoryChart extends BaseGithubChart {
295932
296131
  hasIssues: claim.providers.github.hasIssues,
295933
296132
  visibility: claim.providers.github.visibility,
295934
296133
  defaultBranch: claim.providers.github?.branchStrategy?.defaultBranch,
295935
- codeowners: createCodeOwnersData(claim),
296134
+ codeowners: catalog_common.codeowners.format(claimToCodeOwnersEntries(claim)),
295936
296135
  additionalBranches: claim.providers.github.additionalBranches || [],
295937
296136
  labels: claim.providers.github.labels || [],
295938
296137
  topics: claim.providers.github.topics || [],
@@ -296031,6 +296230,7 @@ class GithubRepositoryChart extends BaseGithubChart {
296031
296230
  * @param claim
296032
296231
  * @returns VarsConfiguration
296033
296232
  */
296233
+ // VarsConfiguration type was removed; use any for compatibility
296034
296234
  createVars(claim) {
296035
296235
  const vars = {};
296036
296236
  const varsDefinition = claim.providers?.github?.vars;
@@ -296043,7 +296243,10 @@ class GithubRepositoryChart extends BaseGithubChart {
296043
296243
  }
296044
296244
  formatVars(blockDefinition) {
296045
296245
  return blockDefinition.map((varDef) => {
296046
- if (isRepoSecretRef(varDef.value)) {
296246
+ // FIXME: isRepoSecretRef removed from local utils, if needed, re-import from correct place or implement inline
296247
+ // if (isRepoSecretRef(varDef.value)) {
296248
+ if (typeof varDef.value === 'string' &&
296249
+ /^ref:secretsclaim:([a-zA-Z0-9_-]+):([a-zA-Z0-9_-]+)$/.test(varDef.value)) {
296047
296250
  const parts = varDef.value.split(':');
296048
296251
  return {
296049
296252
  name: varDef.name,
@@ -298187,39 +298390,6 @@ MemberCollectionGithubDecanter.collectionKind = 'gh-members';
298187
298390
  applyCollectionMixins(MemberCollectionGithubDecanter);
298188
298391
  /* harmony default export */ const github_member_collection = (MemberCollectionGithubDecanter);
298189
298392
 
298190
- ;// CONCATENATED MODULE: ../importer/src/utils/codeowner.ts
298191
- function extractFromCodeOwners(codeOwnersContent) {
298192
- if (!codeOwnersContent) {
298193
- return [];
298194
- }
298195
- return codeOwnersContent.split(/\r?\n/).flatMap((line) => {
298196
- const trimmedLine = line.trim();
298197
- // skip blank lines and full-line comments
298198
- if (!trimmedLine || trimmedLine.startsWith('#')) {
298199
- return [];
298200
- }
298201
- // strip inline comments before parsing owners
298202
- const lineWithoutInlineComment = line.replace(/\s*#.*$/, '').trim();
298203
- if (!lineWithoutInlineComment) {
298204
- return [];
298205
- }
298206
- // CODEOWNERS format: <pattern> <owner1> [<owner2> ...]
298207
- // first field is the path pattern; owners start from the second field
298208
- const parts = lineWithoutInlineComment.split(/\s+/);
298209
- if (parts.length < 2) {
298210
- return [];
298211
- }
298212
- return parts
298213
- .slice(1)
298214
- .filter((part) => part.startsWith('@'))
298215
- .map((owner) => ({
298216
- full: owner,
298217
- isTeam: owner.includes('/'),
298218
- name: owner,
298219
- }));
298220
- });
298221
- }
298222
-
298223
298393
  ;// CONCATENATED MODULE: ../importer/src/utils/nomicon.ts
298224
298394
  function transformRepoName(repoName) {
298225
298395
  // Convert to lowercase
@@ -298326,7 +298496,7 @@ class RepoGithubDecanter extends GithubDecanter {
298326
298496
  // only for validation
298327
298497
  __decantValidateCodeowners() {
298328
298498
  if (this.data.codeowners) {
298329
- const owners = extractFromCodeOwners(this.data.codeowners);
298499
+ const entries = catalog_common.codeowners.parse(this.data.codeowners);
298330
298500
  const normalizeTeamIdentifier = (value) => {
298331
298501
  const normalizedValue = (value.startsWith('@') ? value.slice(1) : value).toLowerCase();
298332
298502
  if (!normalizedValue.includes('/')) {
@@ -298354,17 +298524,23 @@ class RepoGithubDecanter extends GithubDecanter {
298354
298524
  return (this.data.teamsAndMembers.directMembers.some((member) => member.name?.toLowerCase() === normalizedUserName) ||
298355
298525
  this.data.teamsAndMembers.outsideMembers.some((member) => member.name?.toLowerCase() === normalizedUserName));
298356
298526
  };
298357
- // let's validate that every element in the
298358
- // CODEOWNERS file is either a team or a user in the repository,
298359
- // otherwise we will have dangling references in the claim which will cause issues down the line
298360
- for (const owner of owners) {
298361
- if (owner.isTeam && !isInTeams(owner.name)) {
298362
- importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner.name} which is not present in the repository's teams.`);
298363
- throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner.name} which is not present in the repository's teams.`);
298364
- }
298365
- else if (!owner.isTeam && !isInUsers(owner.name)) {
298366
- importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner.name} which is not present in the repository's collaborators.`);
298367
- throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner.name} which is not present in the repository's collaborators.`);
298527
+ // Validate every owner in every entry
298528
+ for (const entry of entries) {
298529
+ for (const owner of entry.owners) {
298530
+ if (owner.includes('/')) {
298531
+ // Team owner
298532
+ if (!isInTeams(owner)) {
298533
+ importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner} which is not present in the repository's teams.`);
298534
+ throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references team ${owner} which is not present in the repository's teams.`);
298535
+ }
298536
+ }
298537
+ else {
298538
+ // Normal user owner
298539
+ if (!isInUsers(owner)) {
298540
+ importer_src_logger.error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner} which is not present in the repository's collaborators.`);
298541
+ throw new Error(`[${this.org}/${this.data.repoDetails.name}] CODEOWNERS file references user ${owner} which is not present in the repository's collaborators.`);
298542
+ }
298543
+ }
298368
298544
  }
298369
298545
  }
298370
298546
  }
@@ -298942,7 +299118,7 @@ async function reimportGithubGitopsRepository(org, crsPath, configPath, generate
298942
299118
  .replace(/\.\d{3}Z$/, 'Z'); // exact format: 2026-04-19T20:45:00Z
298943
299119
  // we write the cr back to the file system
298944
299120
  const newContent = catalog_common.io.toYaml(cr);
298945
- await promises_default().writeFile(filePath, newContent, 'utf-8');
299121
+ await external_node_fs_promises_default().writeFile(filePath, newContent, 'utf-8');
298946
299122
  }
298947
299123
  });
298948
299124
  // we need to search for dependencies if proceeds
@@ -298975,19 +299151,19 @@ async function searchForDependencies(org, crsPath, configPath, generatedFilters,
298975
299151
  .replace(/\.\d{3}Z$/, 'Z'); // exact format: 2026-04-19T20:45:00Z
298976
299152
  // we write the cr back to the file system
298977
299153
  const newContent = catalog_common.io.toYaml(cr);
298978
- await promises_default().writeFile(filePath, newContent, 'utf-8');
299154
+ await external_node_fs_promises_default().writeFile(filePath, newContent, 'utf-8');
298979
299155
  }
298980
299156
  }
298981
299157
  }
298982
299158
  });
298983
299159
  }
298984
299160
  async function searchCRs(dirname, functionToApply) {
298985
- const files = await promises_default().readdir(dirname);
299161
+ const files = await external_node_fs_promises_default().readdir(dirname);
298986
299162
  for (const file of files) {
298987
299163
  if (file.endsWith('.yaml') || file.endsWith('.yml')) {
298988
299164
  importer_src_logger.debug(`Processing file: ${file}`);
298989
299165
  const filePath = external_path_default().join(dirname, file);
298990
- const content = await promises_default().readFile(filePath, 'utf-8');
299166
+ const content = await external_node_fs_promises_default().readFile(filePath, 'utf-8');
298991
299167
  // let's use the catalog_common yaml loader
298992
299168
  const cr = catalog_common.io.fromYaml(content);
298993
299169
  // let's check if the file is a valid file (i.e a CR)
@@ -299004,7 +299180,7 @@ async function searchCRs(dirname, functionToApply) {
299004
299180
  }
299005
299181
  async function reimporter_isDirectory(path) {
299006
299182
  try {
299007
- return (await promises_default().stat(path)).isDirectory(); //
299183
+ return (await external_node_fs_promises_default().stat(path)).isDirectory(); //
299008
299184
  }
299009
299185
  catch (err) {
299010
299186
  return false;
@@ -303184,8 +303360,8 @@ class WriterAdditionalFiles extends writer {
303184
303360
  if (!targetPath.startsWith(absProjectPath + external_path_.sep)) {
303185
303361
  throw new Error(`Path traversal detected: ${file.path}`);
303186
303362
  }
303187
- await external_fs_promises_.mkdir(external_path_.dirname(targetPath), { recursive: true });
303188
- await external_fs_promises_.writeFile(targetPath, Buffer.from(file.content, 'base64').toString('utf8'));
303363
+ await promises_.mkdir(external_path_.dirname(targetPath), { recursive: true });
303364
+ await promises_.writeFile(targetPath, Buffer.from(file.content, 'base64').toString('utf8'));
303189
303365
  }
303190
303366
  catch (err) {
303191
303367
  throw new Error(`Error writing additional file: ${file.path}: ${err}`);
@@ -306842,10 +307018,10 @@ function providers_replaceInlineSecrets(inline, secrets) {
306842
307018
 
306843
307019
  const DEBUG_DIR = external_path_default().join(external_os_default().tmpdir(), 'gh-debug');
306844
307020
  async function initDebug(entity, deps) {
306845
- await (0,promises_.rm)(DEBUG_DIR, { recursive: true, force: true });
306846
- await (0,promises_.mkdir)(DEBUG_DIR, { recursive: true });
306847
- await (0,promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'cr.yaml'), catalog_common.io.toYaml(entity.cr.rawCr));
306848
- await (0,promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'deps.yaml'), catalog_common.io.toYaml(deps));
307021
+ await (0,external_node_fs_promises_.rm)(DEBUG_DIR, { recursive: true, force: true });
307022
+ await (0,external_node_fs_promises_.mkdir)(DEBUG_DIR, { recursive: true });
307023
+ await (0,external_node_fs_promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'cr.yaml'), catalog_common.io.toYaml(entity.cr.rawCr));
307024
+ await (0,external_node_fs_promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'deps.yaml'), catalog_common.io.toYaml(deps));
306849
307025
  gh_provisioner_src_logger.enableFileLogging(external_path_default().join(DEBUG_DIR, 'debug.log'));
306850
307026
  }
306851
307027
  function getTFProjectPath(entity) {
@@ -306853,11 +307029,11 @@ function getTFProjectPath(entity) {
306853
307029
  }
306854
307030
  async function debugTerraformOutput(entity, output) {
306855
307031
  const pathToOutput = external_path_default().join(getTFProjectPath(entity), 'terraform-output.txt');
306856
- await (0,promises_.writeFile)(pathToOutput, output);
307032
+ await (0,external_node_fs_promises_.writeFile)(pathToOutput, output);
306857
307033
  gh_provisioner_src_logger.debug(`[gh-provisioner] debug: Terraform error written to ${pathToOutput}`);
306858
307034
  }
306859
307035
  async function endDebug(entity) {
306860
- await (0,promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'config.json'), JSON.stringify(entity.document, null, 4));
307036
+ await (0,external_node_fs_promises_.writeFile)(external_path_default().join(DEBUG_DIR, 'config.json'), JSON.stringify(entity.document, null, 4));
306861
307037
  gh_provisioner_src_logger.disableFileLogging();
306862
307038
  }
306863
307039
 
@@ -309248,7 +309424,7 @@ const crs_analyzerSubcommand = {
309248
309424
  };
309249
309425
 
309250
309426
  ;// CONCATENATED MODULE: ./package.json
309251
- const package_namespaceObject = JSON.parse('{"i8":"2.4.0-snapshot-5"}');
309427
+ const package_namespaceObject = JSON.parse('{"i8":"2.4.0-snapshot-6"}');
309252
309428
  ;// CONCATENATED MODULE: ../../package.json
309253
309429
  const package_namespaceObject_1 = {"i8":"2.3.0"};
309254
309430
  ;// CONCATENATED MODULE: ./src/subcommands/index.ts
@@ -104,6 +104,7 @@ declare const _default: {
104
104
  tokenizer: {
105
105
  SimpleTokenizer: typeof import("./src/tokenizer").SimpleTokenizer;
106
106
  };
107
+ codeowners: import("./src/codeowners").CodeOwnersAPI;
107
108
  cron: {
108
109
  validateCron: typeof validateCron;
109
110
  isValidCron: typeof isValidCron;
@@ -0,0 +1,29 @@
1
+ export interface CodeOwnerEntry {
2
+ pattern: string;
3
+ owners: string[];
4
+ comment?: string;
5
+ }
6
+ export interface CodeOwnersAPI {
7
+ parse: (raw: string) => CodeOwnerEntry[];
8
+ format: (entries: CodeOwnerEntry[]) => string;
9
+ validate: (raw: string) => boolean;
10
+ get: (context: {
11
+ path?: string;
12
+ }) => Promise<string>;
13
+ set: (context: {
14
+ path?: string;
15
+ }, v: string) => Promise<void>;
16
+ updateRule: (context: {
17
+ path?: string;
18
+ }, rule: CodeOwnerEntry) => Promise<void>;
19
+ remove: (context: {
20
+ path?: string;
21
+ }, criteria: {
22
+ pattern?: string;
23
+ owner?: string;
24
+ }) => Promise<void>;
25
+ getOwners: (raw: string) => string[];
26
+ getDefault: () => string;
27
+ }
28
+ declare const codeowners: CodeOwnersAPI;
29
+ export default codeowners;
@@ -1,5 +1,4 @@
1
1
  import { ApiObject, GroupVersionKind } from 'cdk8s';
2
- import { NamedVars } from '../../utils/repositoryClaimUtils';
3
2
  import { FirestartrGithubRepositoryProps } from '../../../imports/firestartr.dev';
4
3
  import { IUnitializedStateKey } from '../../claims/base';
5
4
  import { BaseGithubChart } from './base';
@@ -22,7 +21,7 @@ export declare class GithubRepositoryChart extends BaseGithubChart {
22
21
  * @returns VarsConfiguration
23
22
  */
24
23
  private createVars;
25
- formatVars(blockDefinition: any): NamedVars;
24
+ formatVars(blockDefinition: any): any;
26
25
  extraCharts(): {
27
26
  claim: {
28
27
  kind: string;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -1,3 +1,10 @@
1
+ import { CodeOwnerEntry } from 'catalog_common/src/codeowners';
2
+ export declare function resolveCodeownersRef(ref: string, org: string): string;
3
+ /**
4
+ * Converts a claim (+optional additional rules) to CodeOwnerEntry[] for the codeowners API
5
+ */
6
+ export declare function claimToCodeOwnersEntries(claim: any, additionalRules?: any[]): CodeOwnerEntry[];
7
+ export declare function createCodeOwnersData(claim: any, additionalRules?: any[]): string;
1
8
  /**
2
9
  * @description This method creates a permission for a given claimRef and permission
3
10
  *
@@ -37,47 +44,6 @@ export interface CollaboratorPermission {
37
44
  role: 'admin' | 'push' | 'pull' | 'maintain';
38
45
  collaborator: string;
39
46
  }
40
- /**
41
- * @description This method creates the codeowners data for the repository
42
- *
43
- * @param claim
44
- *
45
- * @returns string
46
- */
47
- export declare function createCodeOwnersData(claim: any, additionalRules?: any[]): string;
48
- /**
49
- * A reference to a secret, which can be an internal or external source.
50
- */
51
- export interface SecretRef {
52
- kind: 'Secret' | 'ExternalSecret';
53
- name: string;
54
- key: string;
55
- }
56
- /**
57
- * * A variable definition. It must have a name and can be either a literal
58
- * * value or a reference to a secret.
59
- * */
60
- export type Var = {
61
- name: string;
62
- value: string;
63
- } | {
64
- name: string;
65
- ref: SecretRef;
66
- };
67
- export type RepoSecret = {
68
- name: string;
69
- ref: RepoSecretRef;
70
- };
71
- export type NamedVars = Var[];
72
- export type RepoSecrets = RepoSecret[];
73
- export interface VarsConfiguration {
74
- actions?: NamedVars;
75
- }
76
- export interface RepoSecretsConfiguration {
77
- dependabot?: RepoSecrets;
78
- actions?: RepoSecrets;
79
- codespaces?: RepoSecrets;
80
- }
81
47
  export interface RepoSecretRef {
82
48
  kind: 'secretsclaim';
83
49
  name: string;
@@ -85,3 +51,7 @@ export interface RepoSecretRef {
85
51
  }
86
52
  export declare function isRepoSecretRef(suspectedRef: string): boolean;
87
53
  export declare function extractRepoSecretRef(ref: string): RepoSecretRef;
54
+ /**
55
+ * @description This method creates the codeowners data for the repository
56
+ * Migrated: use claimToCodeOwnersEntries + common.codeowners.format instead of legacy helpers.
57
+ */
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
@@ -5,7 +5,7 @@ declare const _default: {
5
5
  debug: (...args: any) => void;
6
6
  verbose: (...args: any) => void;
7
7
  silly: (...args: any) => void;
8
- enableFileLogging: typeof import("../../catalog_common/src/logger/logger").enableFileLogging;
9
- disableFileLogging: typeof import("../../catalog_common/src/logger/logger").disableFileLogging;
8
+ enableFileLogging: typeof import("catalog_common/src/logger/logger").enableFileLogging;
9
+ disableFileLogging: typeof import("catalog_common/src/logger/logger").disableFileLogging;
10
10
  };
11
11
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@firestartr/cli",
3
- "version": "2.4.0-snapshot-5",
3
+ "version": "2.4.0-snapshot-6",
4
4
  "private": false,
5
5
  "description": "Commandline tool",
6
6
  "main": "build/main.js",
@@ -1,5 +0,0 @@
1
- export declare function extractFromCodeOwners(codeOwnersContent: string): {
2
- full: string;
3
- isTeam: boolean;
4
- name: string;
5
- }[];