@living-architecture/riviere-cli 0.9.18 → 0.9.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/bin.js +1102 -2371
  2. package/dist/index.js +1101 -2370
  3. package/package.json +6 -6
package/dist/index.js CHANGED
@@ -1497,37 +1497,37 @@ var require_dataType = __commonJS({
1497
1497
  DataType2[DataType2["Wrong"] = 1] = "Wrong";
1498
1498
  })(DataType || (exports.DataType = DataType = {}));
1499
1499
  function getSchemaTypes(schema) {
1500
- const types2 = getJSONTypes(schema.type);
1501
- const hasNull = types2.includes("null");
1500
+ const types = getJSONTypes(schema.type);
1501
+ const hasNull = types.includes("null");
1502
1502
  if (hasNull) {
1503
1503
  if (schema.nullable === false)
1504
1504
  throw new Error("type: null contradicts nullable: false");
1505
1505
  } else {
1506
- if (!types2.length && schema.nullable !== void 0) {
1506
+ if (!types.length && schema.nullable !== void 0) {
1507
1507
  throw new Error('"nullable" cannot be used without "type"');
1508
1508
  }
1509
1509
  if (schema.nullable === true)
1510
- types2.push("null");
1510
+ types.push("null");
1511
1511
  }
1512
- return types2;
1512
+ return types;
1513
1513
  }
1514
1514
  exports.getSchemaTypes = getSchemaTypes;
1515
1515
  function getJSONTypes(ts) {
1516
- const types2 = Array.isArray(ts) ? ts : ts ? [ts] : [];
1517
- if (types2.every(rules_1.isJSONType))
1518
- return types2;
1519
- throw new Error("type must be JSONType or JSONType[]: " + types2.join(","));
1516
+ const types = Array.isArray(ts) ? ts : ts ? [ts] : [];
1517
+ if (types.every(rules_1.isJSONType))
1518
+ return types;
1519
+ throw new Error("type must be JSONType or JSONType[]: " + types.join(","));
1520
1520
  }
1521
1521
  exports.getJSONTypes = getJSONTypes;
1522
- function coerceAndCheckDataType(it, types2) {
1522
+ function coerceAndCheckDataType(it, types) {
1523
1523
  const { gen, data, opts } = it;
1524
- const coerceTo = coerceToTypes(types2, opts.coerceTypes);
1525
- const checkTypes = types2.length > 0 && !(coerceTo.length === 0 && types2.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types2[0]));
1524
+ const coerceTo = coerceToTypes(types, opts.coerceTypes);
1525
+ const checkTypes = types.length > 0 && !(coerceTo.length === 0 && types.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types[0]));
1526
1526
  if (checkTypes) {
1527
- const wrongType = checkDataTypes(types2, data, opts.strictNumbers, DataType.Wrong);
1527
+ const wrongType = checkDataTypes(types, data, opts.strictNumbers, DataType.Wrong);
1528
1528
  gen.if(wrongType, () => {
1529
1529
  if (coerceTo.length)
1530
- coerceData(it, types2, coerceTo);
1530
+ coerceData(it, types, coerceTo);
1531
1531
  else
1532
1532
  reportTypeError(it);
1533
1533
  });
@@ -1536,15 +1536,15 @@ var require_dataType = __commonJS({
1536
1536
  }
1537
1537
  exports.coerceAndCheckDataType = coerceAndCheckDataType;
1538
1538
  var COERCIBLE = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "null"]);
1539
- function coerceToTypes(types2, coerceTypes) {
1540
- return coerceTypes ? types2.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
1539
+ function coerceToTypes(types, coerceTypes) {
1540
+ return coerceTypes ? types.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
1541
1541
  }
1542
- function coerceData(it, types2, coerceTo) {
1542
+ function coerceData(it, types, coerceTo) {
1543
1543
  const { gen, data, opts } = it;
1544
1544
  const dataType = gen.let("dataType", (0, codegen_1._)`typeof ${data}`);
1545
1545
  const coerced = gen.let("coerced", (0, codegen_1._)`undefined`);
1546
1546
  if (opts.coerceTypes === "array") {
1547
- gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types2, data, opts.strictNumbers), () => gen.assign(coerced, data)));
1547
+ gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)));
1548
1548
  }
1549
1549
  gen.if((0, codegen_1._)`${coerced} !== undefined`);
1550
1550
  for (const t of coerceTo) {
@@ -1620,19 +1620,19 @@ var require_dataType = __commonJS({
1620
1620
  return checkDataType(dataTypes[0], data, strictNums, correct);
1621
1621
  }
1622
1622
  let cond;
1623
- const types2 = (0, util_1.toHash)(dataTypes);
1624
- if (types2.array && types2.object) {
1623
+ const types = (0, util_1.toHash)(dataTypes);
1624
+ if (types.array && types.object) {
1625
1625
  const notObj = (0, codegen_1._)`typeof ${data} != "object"`;
1626
- cond = types2.null ? notObj : (0, codegen_1._)`!${data} || ${notObj}`;
1627
- delete types2.null;
1628
- delete types2.array;
1629
- delete types2.object;
1626
+ cond = types.null ? notObj : (0, codegen_1._)`!${data} || ${notObj}`;
1627
+ delete types.null;
1628
+ delete types.array;
1629
+ delete types.object;
1630
1630
  } else {
1631
1631
  cond = codegen_1.nil;
1632
1632
  }
1633
- if (types2.number)
1634
- delete types2.integer;
1635
- for (const t in types2)
1633
+ if (types.number)
1634
+ delete types.integer;
1635
+ for (const t in types)
1636
1636
  cond = (0, codegen_1.and)(cond, checkDataType(t, data, strictNums, correct));
1637
1637
  return cond;
1638
1638
  }
@@ -2437,9 +2437,9 @@ var require_validate = __commonJS({
2437
2437
  function typeAndKeywords(it, errsCount) {
2438
2438
  if (it.opts.jtd)
2439
2439
  return schemaKeywords(it, [], false, errsCount);
2440
- const types2 = (0, dataType_1.getSchemaTypes)(it.schema);
2441
- const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types2);
2442
- schemaKeywords(it, types2, !checkedTypes, errsCount);
2440
+ const types = (0, dataType_1.getSchemaTypes)(it.schema);
2441
+ const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types);
2442
+ schemaKeywords(it, types, !checkedTypes, errsCount);
2443
2443
  }
2444
2444
  function checkRefsAndKeywords(it) {
2445
2445
  const { schema, errSchemaPath, opts, self } = it;
@@ -2489,7 +2489,7 @@ var require_validate = __commonJS({
2489
2489
  if (items instanceof codegen_1.Name)
2490
2490
  gen.assign((0, codegen_1._)`${evaluated}.items`, items);
2491
2491
  }
2492
- function schemaKeywords(it, types2, typeErrors, errsCount) {
2492
+ function schemaKeywords(it, types, typeErrors, errsCount) {
2493
2493
  const { gen, schema, data, allErrors, opts, self } = it;
2494
2494
  const { RULES } = self;
2495
2495
  if (schema.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema, RULES))) {
@@ -2497,7 +2497,7 @@ var require_validate = __commonJS({
2497
2497
  return;
2498
2498
  }
2499
2499
  if (!opts.jtd)
2500
- checkStrictTypes(it, types2);
2500
+ checkStrictTypes(it, types);
2501
2501
  gen.block(() => {
2502
2502
  for (const group of RULES.rules)
2503
2503
  groupKeywords(group);
@@ -2509,7 +2509,7 @@ var require_validate = __commonJS({
2509
2509
  if (group.type) {
2510
2510
  gen.if((0, dataType_2.checkDataType)(group.type, data, opts.strictNumbers));
2511
2511
  iterateKeywords(it, group);
2512
- if (types2.length === 1 && types2[0] === group.type && typeErrors) {
2512
+ if (types.length === 1 && types[0] === group.type && typeErrors) {
2513
2513
  gen.else();
2514
2514
  (0, dataType_2.reportTypeError)(it);
2515
2515
  }
@@ -2533,27 +2533,27 @@ var require_validate = __commonJS({
2533
2533
  }
2534
2534
  });
2535
2535
  }
2536
- function checkStrictTypes(it, types2) {
2536
+ function checkStrictTypes(it, types) {
2537
2537
  if (it.schemaEnv.meta || !it.opts.strictTypes)
2538
2538
  return;
2539
- checkContextTypes(it, types2);
2539
+ checkContextTypes(it, types);
2540
2540
  if (!it.opts.allowUnionTypes)
2541
- checkMultipleTypes(it, types2);
2541
+ checkMultipleTypes(it, types);
2542
2542
  checkKeywordTypes(it, it.dataTypes);
2543
2543
  }
2544
- function checkContextTypes(it, types2) {
2545
- if (!types2.length)
2544
+ function checkContextTypes(it, types) {
2545
+ if (!types.length)
2546
2546
  return;
2547
2547
  if (!it.dataTypes.length) {
2548
- it.dataTypes = types2;
2548
+ it.dataTypes = types;
2549
2549
  return;
2550
2550
  }
2551
- types2.forEach((t) => {
2551
+ types.forEach((t) => {
2552
2552
  if (!includesType(it.dataTypes, t)) {
2553
2553
  strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`);
2554
2554
  }
2555
2555
  });
2556
- narrowSchemaTypes(it, types2);
2556
+ narrowSchemaTypes(it, types);
2557
2557
  }
2558
2558
  function checkMultipleTypes(it, ts) {
2559
2559
  if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
@@ -2979,7 +2979,7 @@ var require_compile = __commonJS({
2979
2979
  const schOrFunc = root.refs[ref];
2980
2980
  if (schOrFunc)
2981
2981
  return schOrFunc;
2982
- let _sch = resolve5.call(this, root, ref);
2982
+ let _sch = resolve6.call(this, root, ref);
2983
2983
  if (_sch === void 0) {
2984
2984
  const schema = (_a2 = root.localRefs) === null || _a2 === void 0 ? void 0 : _a2[ref];
2985
2985
  const { schemaId } = this.opts;
@@ -3006,7 +3006,7 @@ var require_compile = __commonJS({
3006
3006
  function sameSchemaEnv(s1, s2) {
3007
3007
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3008
3008
  }
3009
- function resolve5(root, ref) {
3009
+ function resolve6(root, ref) {
3010
3010
  let sch;
3011
3011
  while (typeof (sch = this.refs[ref]) == "string")
3012
3012
  ref = sch;
@@ -3221,8 +3221,8 @@ var require_utils = __commonJS({
3221
3221
  }
3222
3222
  return ind;
3223
3223
  }
3224
- function removeDotSegments(path2) {
3225
- let input = path2;
3224
+ function removeDotSegments(path) {
3225
+ let input = path;
3226
3226
  const output = [];
3227
3227
  let nextSlash = -1;
3228
3228
  let len = 0;
@@ -3421,8 +3421,8 @@ var require_schemes = __commonJS({
3421
3421
  wsComponent.secure = void 0;
3422
3422
  }
3423
3423
  if (wsComponent.resourceName) {
3424
- const [path2, query] = wsComponent.resourceName.split("?");
3425
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3424
+ const [path, query] = wsComponent.resourceName.split("?");
3425
+ wsComponent.path = path && path !== "/" ? path : void 0;
3426
3426
  wsComponent.query = query;
3427
3427
  wsComponent.resourceName = void 0;
3428
3428
  }
@@ -3581,7 +3581,7 @@ var require_fast_uri = __commonJS({
3581
3581
  }
3582
3582
  return uri;
3583
3583
  }
3584
- function resolve5(baseURI, relativeURI, options) {
3584
+ function resolve6(baseURI, relativeURI, options) {
3585
3585
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3586
3586
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3587
3587
  schemelessOptions.skipEscape = true;
@@ -3808,7 +3808,7 @@ var require_fast_uri = __commonJS({
3808
3808
  var fastUri = {
3809
3809
  SCHEMES,
3810
3810
  normalize,
3811
- resolve: resolve5,
3811
+ resolve: resolve6,
3812
3812
  resolveComponent,
3813
3813
  equal,
3814
3814
  serialize,
@@ -7868,7 +7868,7 @@ function maybePushScalarOverwriteWarning(warnings, componentId, field, existingV
7868
7868
  });
7869
7869
  }
7870
7870
  function mergeNestedObject(existing, incoming, options, warnings, componentId, pathPrefix) {
7871
- const merged = { ...existing ?? {} };
7871
+ const merged = { ...existing };
7872
7872
  for (const [field, incomingValue] of Object.entries(incoming)) {
7873
7873
  if (!isDefined(incomingValue)) {
7874
7874
  continue;
@@ -9071,9 +9071,9 @@ function floatSafeRemainder(val, step) {
9071
9071
  const stepString = step.toString();
9072
9072
  let stepDecCount = (stepString.split(".")[1] || "").length;
9073
9073
  if (stepDecCount === 0 && /\d?e-\d?/.test(stepString)) {
9074
- const match2 = stepString.match(/\d?e-(\d?)/);
9075
- if (match2?.[1]) {
9076
- stepDecCount = Number.parseInt(match2[1]);
9074
+ const match = stepString.match(/\d?e-(\d?)/);
9075
+ if (match?.[1]) {
9076
+ stepDecCount = Number.parseInt(match[1]);
9077
9077
  }
9078
9078
  }
9079
9079
  const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
@@ -9126,10 +9126,10 @@ function mergeDefs(...defs) {
9126
9126
  function cloneDef(schema) {
9127
9127
  return mergeDefs(schema._zod.def);
9128
9128
  }
9129
- function getElementAtPath(obj, path2) {
9130
- if (!path2)
9129
+ function getElementAtPath(obj, path) {
9130
+ if (!path)
9131
9131
  return obj;
9132
- return path2.reduce((acc, key) => acc?.[key], obj);
9132
+ return path.reduce((acc, key) => acc?.[key], obj);
9133
9133
  }
9134
9134
  function promiseAllObject(promisesObj) {
9135
9135
  const keys = Object.keys(promisesObj);
@@ -9512,11 +9512,11 @@ function aborted(x, startIndex = 0) {
9512
9512
  }
9513
9513
  return false;
9514
9514
  }
9515
- function prefixIssues(path2, issues) {
9515
+ function prefixIssues(path, issues) {
9516
9516
  return issues.map((iss) => {
9517
9517
  var _a2;
9518
9518
  (_a2 = iss).path ?? (_a2.path = []);
9519
- iss.path.unshift(path2);
9519
+ iss.path.unshift(path);
9520
9520
  return iss;
9521
9521
  });
9522
9522
  }
@@ -9699,7 +9699,7 @@ function formatError(error48, mapper = (issue2) => issue2.message) {
9699
9699
  }
9700
9700
  function treeifyError(error48, mapper = (issue2) => issue2.message) {
9701
9701
  const result = { errors: [] };
9702
- const processError = (error49, path2 = []) => {
9702
+ const processError = (error49, path = []) => {
9703
9703
  var _a2, _b;
9704
9704
  for (const issue2 of error49.issues) {
9705
9705
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -9709,7 +9709,7 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
9709
9709
  } else if (issue2.code === "invalid_element") {
9710
9710
  processError({ issues: issue2.issues }, issue2.path);
9711
9711
  } else {
9712
- const fullpath = [...path2, ...issue2.path];
9712
+ const fullpath = [...path, ...issue2.path];
9713
9713
  if (fullpath.length === 0) {
9714
9714
  result.errors.push(mapper(issue2));
9715
9715
  continue;
@@ -9741,8 +9741,8 @@ function treeifyError(error48, mapper = (issue2) => issue2.message) {
9741
9741
  }
9742
9742
  function toDotPath(_path) {
9743
9743
  const segs = [];
9744
- const path2 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
9745
- for (const seg of path2) {
9744
+ const path = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
9745
+ for (const seg of path) {
9746
9746
  if (typeof seg === "number")
9747
9747
  segs.push(`[${seg}]`);
9748
9748
  else if (typeof seg === "symbol")
@@ -18855,10 +18855,10 @@ function _property(property, schema, params) {
18855
18855
  });
18856
18856
  }
18857
18857
  // @__NO_SIDE_EFFECTS__
18858
- function _mime(types2, params) {
18858
+ function _mime(types, params) {
18859
18859
  return new $ZodCheckMimeType({
18860
18860
  check: "mime_type",
18861
- mime: types2,
18861
+ mime: types,
18862
18862
  ...normalizeParams(params)
18863
18863
  });
18864
18864
  }
@@ -19384,8 +19384,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
19384
19384
  continue;
19385
19385
  }
19386
19386
  if (ctx.external) {
19387
- const ext2 = ctx.external.registry.get(entry[0])?.id;
19388
- if (schema !== entry[0] && ext2) {
19387
+ const ext = ctx.external.registry.get(entry[0])?.id;
19388
+ if (schema !== entry[0] && ext) {
19389
19389
  extractToDef(entry);
19390
19390
  continue;
19391
19391
  }
@@ -21290,7 +21290,7 @@ var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
21290
21290
  inst._zod.processJSONSchema = (ctx, json2, params) => fileProcessor(inst, ctx, json2, params);
21291
21291
  inst.min = (size, params) => inst.check(_minSize(size, params));
21292
21292
  inst.max = (size, params) => inst.check(_maxSize(size, params));
21293
- inst.mime = (types2, params) => inst.check(_mime(Array.isArray(types2) ? types2 : [types2], params));
21293
+ inst.mime = (types, params) => inst.check(_mime(Array.isArray(types) ? types : [types], params));
21294
21294
  });
21295
21295
  function file(params) {
21296
21296
  return _file(ZodFile, params);
@@ -21719,13 +21719,13 @@ function resolveRef(ref, ctx) {
21719
21719
  if (!ref.startsWith("#")) {
21720
21720
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
21721
21721
  }
21722
- const path2 = ref.slice(1).split("/").filter(Boolean);
21723
- if (path2.length === 0) {
21722
+ const path = ref.slice(1).split("/").filter(Boolean);
21723
+ if (path.length === 0) {
21724
21724
  return ctx.rootSchema;
21725
21725
  }
21726
21726
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
21727
- if (path2[0] === defsKey) {
21728
- const key = path2[1];
21727
+ if (path[0] === defsKey) {
21728
+ const key = path[1];
21729
21729
  if (!key || !ctx.defs[key]) {
21730
21730
  throw new Error(`Reference not found: ${ref}`);
21731
21731
  }
@@ -24017,9 +24017,9 @@ import { accessSync } from "node:fs";
24017
24017
  function isNodeError(error48) {
24018
24018
  return error48 instanceof Error && "code" in error48;
24019
24019
  }
24020
- function fileExists(path2) {
24020
+ function fileExists(path) {
24021
24021
  try {
24022
- accessSync(path2);
24022
+ accessSync(path);
24023
24023
  return true;
24024
24024
  } catch (error48) {
24025
24025
  if (isNodeError(error48) && error48.code === "ENOENT") {
@@ -24588,11 +24588,11 @@ function failure11(code, message, suggestions = []) {
24588
24588
  function isRestApiWithPath(component) {
24589
24589
  return component.type === "API" && "path" in component && "httpMethod" in component;
24590
24590
  }
24591
- function findApisByPath(graph, path2, method) {
24591
+ function findApisByPath(graph, path, method) {
24592
24592
  const query = new RiviereQuery(graph);
24593
24593
  const allComponents = query.componentsByType("API");
24594
24594
  const apis = allComponents.filter(isRestApiWithPath);
24595
- const matchingPath = apis.filter((api) => api.path === path2);
24595
+ const matchingPath = apis.filter((api) => api.path === path);
24596
24596
  if (method) {
24597
24597
  return matchingPath.filter((api) => api.httpMethod === method);
24598
24598
  }
@@ -25801,21 +25801,19 @@ Examples:
25801
25801
 
25802
25802
  // src/features/extract/infra/persistence/extraction-project/extraction-project-repository.ts
25803
25803
  import {
25804
- existsSync as existsSync4,
25805
- readFileSync as readFileSync3
25804
+ existsSync as existsSync5,
25805
+ readFileSync as readFileSync4
25806
25806
  } from "node:fs";
25807
- import { createRequire } from "node:module";
25808
25807
  import {
25809
- dirname as dirname2,
25810
- posix as posix4,
25811
- resolve as resolve4
25808
+ dirname as dirname3,
25809
+ posix,
25810
+ resolve as resolve5
25812
25811
  } from "node:path";
25813
- import { parse as parseYaml } from "yaml";
25812
+ import { parse as parseYaml2 } from "yaml";
25814
25813
  import { globSync } from "glob";
25815
25814
 
25816
25815
  // ../riviere-extract-ts/dist/features/extraction/domain/component-extraction/extractor.js
25817
25816
  import { Scope } from "ts-morph";
25818
- import { posix } from "node:path";
25819
25817
 
25820
25818
  // ../riviere-extract-ts/dist/features/extraction/domain/predicate-evaluation/evaluate-predicate.js
25821
25819
  import { Node as TsMorphNode } from "ts-morph";
@@ -25939,6 +25937,22 @@ function evaluateInClassWith(node, predicate) {
25939
25937
  return evaluatePredicate(parent, predicate);
25940
25938
  }
25941
25939
 
25940
+ // ../riviere-extract-ts/dist/features/extraction/domain/component-extraction/draft-component.js
25941
+ var DraftComponent = class {
25942
+ type;
25943
+ name;
25944
+ location;
25945
+ domain;
25946
+ module;
25947
+ constructor(params) {
25948
+ this.type = params.type;
25949
+ this.name = params.name;
25950
+ this.location = params.location;
25951
+ this.domain = params.domain;
25952
+ this.module = params.module;
25953
+ }
25954
+ };
25955
+
25942
25956
  // ../riviere-extract-ts/dist/features/extraction/domain/component-extraction/extractor.js
25943
25957
  var COMPONENT_TYPES = [
25944
25958
  "api",
@@ -25948,19 +25962,15 @@ var COMPONENT_TYPES = [
25948
25962
  "eventHandler",
25949
25963
  "ui"
25950
25964
  ];
25951
- function extractComponents(project, sourceFilePaths, config2, globMatcher, configDir) {
25952
- return sourceFilePaths.flatMap((filePath) => extractFromFile(project, filePath, config2, globMatcher, configDir));
25965
+ function extractComponents(project, sourceFilePaths, module) {
25966
+ return sourceFilePaths.flatMap((filePath) => extractFromFile(project, filePath, module));
25953
25967
  }
25954
- function extractFromFile(project, filePath, config2, globMatcher, configDir) {
25968
+ function extractFromFile(project, filePath, module) {
25955
25969
  const sourceFile = project.getSourceFile(filePath);
25956
25970
  if (sourceFile === void 0) {
25957
25971
  return [];
25958
25972
  }
25959
- const matchingModule = findMatchingModule(filePath, config2.modules, globMatcher, configDir);
25960
- if (matchingModule === void 0) {
25961
- return [];
25962
- }
25963
- return extractFromModule(sourceFile, filePath, matchingModule);
25973
+ return extractFromModule(sourceFile, filePath, module);
25964
25974
  }
25965
25975
  function extractFromModule(sourceFile, filePath, module) {
25966
25976
  const context = resolveComponentContext(filePath, module);
@@ -26041,7 +26051,7 @@ function createClassComponent(classDecl, filePath, context, componentType) {
26041
26051
  return [];
26042
26052
  }
26043
26053
  return [
26044
- {
26054
+ new DraftComponent({
26045
26055
  type: componentType,
26046
26056
  name,
26047
26057
  location: {
@@ -26050,13 +26060,13 @@ function createClassComponent(classDecl, filePath, context, componentType) {
26050
26060
  },
26051
26061
  domain: context.domain,
26052
26062
  module: context.module
26053
- }
26063
+ })
26054
26064
  ];
26055
26065
  }
26056
26066
  function createMethodComponent(method, filePath, context, componentType) {
26057
26067
  const name = method.getName();
26058
26068
  return [
26059
- {
26069
+ new DraftComponent({
26060
26070
  type: componentType,
26061
26071
  name,
26062
26072
  location: {
@@ -26065,7 +26075,7 @@ function createMethodComponent(method, filePath, context, componentType) {
26065
26075
  },
26066
26076
  domain: context.domain,
26067
26077
  module: context.module
26068
- }
26078
+ })
26069
26079
  ];
26070
26080
  }
26071
26081
  function createFunctionComponent(func, filePath, context, componentType) {
@@ -26074,7 +26084,7 @@ function createFunctionComponent(func, filePath, context, componentType) {
26074
26084
  return [];
26075
26085
  }
26076
26086
  return [
26077
- {
26087
+ new DraftComponent({
26078
26088
  type: componentType,
26079
26089
  name,
26080
26090
  location: {
@@ -26083,28 +26093,11 @@ function createFunctionComponent(func, filePath, context, componentType) {
26083
26093
  },
26084
26094
  domain: context.domain,
26085
26095
  module: context.module
26086
- }
26096
+ })
26087
26097
  ];
26088
26098
  }
26089
- function findMatchingModule(filePath, modules, globMatcher, configDir) {
26090
- const normalized = filePath.replaceAll(/\\+/g, "/");
26091
- if (configDir === void 0) {
26092
- return modules.find((m) => globMatcher(normalized, posix.join(m.path, m.glob)));
26093
- }
26094
- const normalizedConfigDir = configDir.replaceAll(/\\+/g, "/");
26095
- const pathToMatch = posix.relative(normalizedConfigDir, normalized);
26096
- return modules.find((m) => globMatcher(pathToMatch, posix.join(m.path, m.glob)));
26097
- }
26098
26099
 
26099
26100
  // ../riviere-extract-ts/dist/features/extraction/domain/config-resolution/config-resolution-errors.js
26100
- var ConfigLoaderRequiredError = class extends Error {
26101
- moduleName;
26102
- constructor(moduleName) {
26103
- super(`Module '${moduleName}' uses extends but no config loader was provided.`);
26104
- this.name = "ConfigLoaderRequiredError";
26105
- this.moduleName = moduleName;
26106
- }
26107
- };
26108
26101
  var MissingComponentRuleError = class extends Error {
26109
26102
  moduleName;
26110
26103
  ruleName;
@@ -26117,17 +26110,13 @@ var MissingComponentRuleError = class extends Error {
26117
26110
  };
26118
26111
 
26119
26112
  // ../riviere-extract-ts/dist/features/extraction/domain/config-resolution/resolve-config.js
26120
- function resolveConfig(config2, loader) {
26113
+ function resolveConfig(config2) {
26121
26114
  return {
26122
26115
  ...config2,
26123
- modules: config2.modules.map((m) => resolveModule(m, loader))
26116
+ modules: config2.modules.map(resolveModule)
26124
26117
  };
26125
26118
  }
26126
- function resolveModule(moduleConfig, loader) {
26127
- const extendsSource = moduleConfig.extends;
26128
- if (extendsSource !== void 0) {
26129
- return resolveModuleWithExtends(moduleConfig, extendsSource, loader);
26130
- }
26119
+ function resolveModule(moduleConfig) {
26131
26120
  return {
26132
26121
  name: moduleConfig.name,
26133
26122
  domain: moduleConfig.domain,
@@ -26143,36 +26132,6 @@ function resolveModule(moduleConfig, loader) {
26143
26132
  ...moduleConfig.customTypes !== void 0 && { customTypes: moduleConfig.customTypes }
26144
26133
  };
26145
26134
  }
26146
- function resolveModuleWithExtends(moduleConfig, extendsSource, loader) {
26147
- if (loader === void 0) {
26148
- throw new ConfigLoaderRequiredError(moduleConfig.name);
26149
- }
26150
- const baseModule = loader(extendsSource);
26151
- const mergedCustomTypes = mergeCustomTypes(baseModule.customTypes, moduleConfig.customTypes);
26152
- return {
26153
- name: moduleConfig.name,
26154
- domain: moduleConfig.domain,
26155
- path: moduleConfig.path,
26156
- glob: moduleConfig.glob,
26157
- ...moduleConfig.modules !== void 0 && { modules: moduleConfig.modules },
26158
- api: moduleConfig.api ?? baseModule.api,
26159
- useCase: moduleConfig.useCase ?? baseModule.useCase,
26160
- domainOp: moduleConfig.domainOp ?? baseModule.domainOp,
26161
- event: moduleConfig.event ?? baseModule.event,
26162
- eventHandler: moduleConfig.eventHandler ?? baseModule.eventHandler,
26163
- ui: moduleConfig.ui ?? baseModule.ui,
26164
- ...mergedCustomTypes !== void 0 && { customTypes: mergedCustomTypes }
26165
- };
26166
- }
26167
- function mergeCustomTypes(base, local) {
26168
- if (base === void 0 && local === void 0) {
26169
- return void 0;
26170
- }
26171
- return {
26172
- ...base,
26173
- ...local
26174
- };
26175
- }
26176
26135
  function requireRule(rule, ruleName, moduleName) {
26177
26136
  if (rule === void 0) {
26178
26137
  throw new MissingComponentRuleError(moduleName, ruleName);
@@ -26180,6 +26139,14 @@ function requireRule(rule, ruleName, moduleName) {
26180
26139
  return rule;
26181
26140
  }
26182
26141
 
26142
+ // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/extraction-result.js
26143
+ var ExtractionResult = class {
26144
+ value;
26145
+ constructor(params) {
26146
+ this.value = params.value;
26147
+ }
26148
+ };
26149
+
26183
26150
  // ../riviere-extract-ts/dist/platform/domain/string-transforms/transforms.js
26184
26151
  function stripSuffix(value, suffix) {
26185
26152
  if (value.endsWith(suffix)) {
@@ -26244,6 +26211,14 @@ var ExtractionError = class extends Error {
26244
26211
  };
26245
26212
  }
26246
26213
  };
26214
+ var LiteralResult = class {
26215
+ kind;
26216
+ value;
26217
+ constructor(params) {
26218
+ this.kind = params.kind;
26219
+ this.value = params.value;
26220
+ }
26221
+ };
26247
26222
  function extractString(expression) {
26248
26223
  return expression.asKindOrThrow(SyntaxKind.StringLiteral).getLiteralValue();
26249
26224
  }
@@ -26266,34 +26241,34 @@ function buildExtractionResult(expression) {
26266
26241
  const syntaxKind = expression.getKind();
26267
26242
  switch (syntaxKind) {
26268
26243
  case SyntaxKind.StringLiteral:
26269
- return {
26244
+ return new LiteralResult({
26270
26245
  kind: "string",
26271
26246
  value: extractString(expression)
26272
- };
26247
+ });
26273
26248
  case SyntaxKind.NumericLiteral:
26274
- return {
26249
+ return new LiteralResult({
26275
26250
  kind: "number",
26276
26251
  value: extractNumber(expression)
26277
- };
26252
+ });
26278
26253
  case SyntaxKind.TrueKeyword:
26279
- return {
26254
+ return new LiteralResult({
26280
26255
  kind: "boolean",
26281
26256
  value: true
26282
- };
26257
+ });
26283
26258
  case SyntaxKind.FalseKeyword:
26284
- return {
26259
+ return new LiteralResult({
26285
26260
  kind: "boolean",
26286
26261
  value: false
26287
- };
26262
+ });
26288
26263
  case SyntaxKind.ArrayLiteralExpression: {
26289
26264
  const values = extractStringArray(expression);
26290
26265
  if (values === void 0) {
26291
26266
  return void 0;
26292
26267
  }
26293
- return {
26268
+ return new LiteralResult({
26294
26269
  kind: "string[]",
26295
26270
  value: values
26296
- };
26271
+ });
26297
26272
  }
26298
26273
  default:
26299
26274
  return void 0;
@@ -26316,1911 +26291,177 @@ function extractLiteralValue(expression, file2, line) {
26316
26291
  return result;
26317
26292
  }
26318
26293
 
26319
- // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-generic.js
26320
- import { SyntaxKind as SyntaxKind2 } from "ts-morph";
26321
- function getInterfaceTypeArgs(classDecl, interfaceName) {
26322
- const implementsClause = classDecl.getImplements();
26323
- for (const impl of implementsClause) {
26324
- const expression = impl.getExpression();
26325
- if (expression.getText() === interfaceName) {
26326
- return impl.getTypeArguments();
26327
- }
26328
- }
26329
- const extendsClause = classDecl.getExtends();
26330
- if (extendsClause === void 0) {
26331
- return void 0;
26294
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/detect-connections.js
26295
+ import { performance } from "node:perf_hooks";
26296
+
26297
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/async-detection/async-detection-options.js
26298
+ var AsyncDetectionOptions = class {
26299
+ strict;
26300
+ repository;
26301
+ constructor(params) {
26302
+ this.strict = params.strict;
26303
+ this.repository = params.repository;
26332
26304
  }
26333
- const baseClass = classDecl.getBaseClass();
26334
- if (baseClass === void 0)
26335
- return void 0;
26336
- return getInterfaceTypeArgs(baseClass, interfaceName);
26305
+ };
26306
+
26307
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/component-index.js
26308
+ function locationKey(file2, line) {
26309
+ return `${file2}:${line}`;
26337
26310
  }
26338
- function extractTypeNames(typeNode) {
26339
- if (typeNode.getKind() === SyntaxKind2.UnionType) {
26340
- const unionType = typeNode.asKindOrThrow(SyntaxKind2.UnionType);
26341
- return unionType.getTypeNodes().map((t) => t.getText());
26311
+ var ComponentIndex = class {
26312
+ byName;
26313
+ byLocation;
26314
+ constructor(components) {
26315
+ const nameMap = /* @__PURE__ */ new Map();
26316
+ const locationMap = /* @__PURE__ */ new Map();
26317
+ for (const component of components) {
26318
+ nameMap.set(component.name, component);
26319
+ locationMap.set(locationKey(component.location.file, component.location.line), component);
26320
+ }
26321
+ this.byName = nameMap;
26322
+ this.byLocation = locationMap;
26342
26323
  }
26343
- return [typeNode.getText()];
26344
- }
26345
- function evaluateFromGenericArgRule(rule, classDecl) {
26346
- const { interface: interfaceName, position, transform: transform2 } = rule.fromGenericArg;
26347
- const sourceFile = classDecl.getSourceFile();
26348
- const location = {
26349
- filePath: sourceFile.getFilePath(),
26350
- line: classDecl.getStartLineNumber()
26351
- };
26352
- const typeArgs = getInterfaceTypeArgs(classDecl, interfaceName);
26353
- if (typeArgs === void 0) {
26354
- throw new ExtractionError(`Class '${classDecl.getName() ?? "anonymous"}' does not implement interface '${interfaceName}'`, location.filePath, location.line);
26324
+ isComponent(typeName) {
26325
+ return this.byName.has(this.withoutGenericArguments(typeName));
26355
26326
  }
26356
- const typeArg = typeArgs[position];
26357
- if (typeArg === void 0) {
26358
- throw new ExtractionError(`Position ${position} out of bounds. Interface has ${typeArgs.length} type argument(s)`, location.filePath, location.line);
26327
+ getComponentByTypeName(typeName) {
26328
+ return this.byName.get(this.withoutGenericArguments(typeName));
26359
26329
  }
26360
- if (typeArg.getKind() === SyntaxKind2.TypeReference) {
26361
- const typeRef = typeArg.asKindOrThrow(SyntaxKind2.TypeReference);
26362
- const typeName = typeRef.getTypeName();
26363
- if (typeName.getKind() === SyntaxKind2.Identifier) {
26364
- const classTypeParams = classDecl.getTypeParameters();
26365
- const paramName = typeName.getText();
26366
- const isTypeParam = classTypeParams.some((p) => p.getName() === paramName);
26367
- if (isTypeParam) {
26368
- throw new ExtractionError(`Generic argument at position ${position} is type parameter '${paramName}', expected concrete type`, location.filePath, location.line);
26369
- }
26370
- }
26330
+ getComponentByLocation(file2, line) {
26331
+ return this.byLocation.get(locationKey(file2, line));
26371
26332
  }
26372
- const typeNames = extractTypeNames(typeArg);
26373
- if (transform2 === void 0) {
26374
- return { value: typeNames };
26333
+ withoutGenericArguments(typeName) {
26334
+ const index = typeName.indexOf("<");
26335
+ if (index === -1) {
26336
+ return typeName;
26337
+ }
26338
+ return typeName.slice(0, index);
26375
26339
  }
26376
- return { value: typeNames.map((name) => applyTransforms(name, transform2)) };
26377
- }
26340
+ };
26378
26341
 
26379
- // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule.js
26380
- import { SyntaxKind as SyntaxKind3 } from "ts-morph";
26381
- function literal2(value) {
26382
- return { value };
26383
- }
26384
- function evaluateLiteralRule(rule) {
26385
- return literal2(rule.literal);
26386
- }
26387
- function evaluateFromClassNameRule(rule, classDecl) {
26388
- const className = classDecl.getName();
26389
- if (!className) {
26390
- const filePath = classDecl.getSourceFile().getFilePath();
26391
- const lineNumber = classDecl.getStartLineNumber();
26392
- throw new ExtractionError("Expected class name, got undefined", filePath, lineNumber);
26342
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.js
26343
+ import { Node as Node3, SyntaxKind as SyntaxKind4 } from "ts-morph";
26344
+
26345
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/call-graph-types.js
26346
+ var CallGraphOptions = class {
26347
+ strict;
26348
+ sourceFilePaths;
26349
+ repository;
26350
+ constructor(params) {
26351
+ this.strict = params.strict;
26352
+ this.sourceFilePaths = params.sourceFilePaths;
26353
+ this.repository = params.repository;
26393
26354
  }
26394
- if (rule.fromClassName === true) {
26395
- return { value: className };
26355
+ };
26356
+ var CallSite = class {
26357
+ filePath;
26358
+ lineNumber;
26359
+ methodName;
26360
+ constructor(params) {
26361
+ this.filePath = params.filePath;
26362
+ this.lineNumber = params.lineNumber;
26363
+ this.methodName = params.methodName;
26396
26364
  }
26397
- const transform2 = rule.fromClassName.transform;
26398
- if (transform2 === void 0) {
26399
- return { value: className };
26365
+ };
26366
+ var RawLink = class {
26367
+ source;
26368
+ target;
26369
+ callSite;
26370
+ constructor(params) {
26371
+ this.source = params.source;
26372
+ this.target = params.target;
26373
+ this.callSite = params.callSite;
26374
+ }
26375
+ };
26376
+ var UncertainRawLink = class {
26377
+ source;
26378
+ reason;
26379
+ callSite;
26380
+ constructor(params) {
26381
+ this.source = params.source;
26382
+ this.reason = params.reason;
26383
+ this.callSite = params.callSite;
26400
26384
  }
26401
- return { value: applyTransforms(className, transform2) };
26385
+ };
26386
+
26387
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/component-identity.js
26388
+ function componentIdentity(component) {
26389
+ return ComponentId.create({
26390
+ domain: component.domain,
26391
+ module: component.module,
26392
+ type: component.type,
26393
+ name: component.name
26394
+ }).toString();
26402
26395
  }
26403
- function evaluateFromMethodNameRule(rule, methodDecl) {
26404
- const methodName = methodDecl.getName();
26405
- if (rule.fromMethodName === true) {
26406
- return { value: methodName };
26396
+
26397
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/trace-calls.js
26398
+ import { Node as Node2, SyntaxKind as SyntaxKind3 } from "ts-morph";
26399
+
26400
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/method-level-target.js
26401
+ var MethodLevelTarget = class {
26402
+ classDecl;
26403
+ method;
26404
+ constructor(params) {
26405
+ this.classDecl = params.classDecl;
26406
+ this.method = params.method;
26407
26407
  }
26408
- const transform2 = rule.fromMethodName.transform;
26409
- if (transform2 === void 0) {
26410
- return { value: methodName };
26408
+ };
26409
+
26410
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.js
26411
+ import { CallExpression, SourceFile, Node } from "ts-morph";
26412
+
26413
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/connection-detection-error.js
26414
+ var ConnectionDetectionError = class extends Error {
26415
+ file;
26416
+ line;
26417
+ typeName;
26418
+ reason;
26419
+ constructor(params) {
26420
+ super(`Connection detection failed for ${params.typeName} at ${params.file}:${params.line}: ${params.reason}`);
26421
+ this.name = "ConnectionDetectionError";
26422
+ this.file = params.file;
26423
+ this.line = params.line;
26424
+ this.typeName = params.typeName;
26425
+ this.reason = params.reason;
26411
26426
  }
26412
- return { value: applyTransforms(methodName, transform2) };
26413
- }
26414
- function evaluateFromFilePathRule(rule, filePath) {
26415
- const pattern = rule.fromFilePath.pattern;
26416
- const capture = rule.fromFilePath.capture;
26417
- const transform2 = rule.fromFilePath.transform;
26418
- const regex = new RegExp(pattern);
26419
- const match2 = regex.exec(filePath);
26420
- if (match2 === null) {
26421
- throw new ExtractionError(`Pattern '${pattern}' did not match file path '${filePath}'`, filePath, 0);
26427
+ };
26428
+
26429
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.js
26430
+ var TypeResolution = class _TypeResolution {
26431
+ resolved;
26432
+ typeName;
26433
+ reason;
26434
+ constructor(params) {
26435
+ this.resolved = params.resolved;
26436
+ this.typeName = params.typeName;
26437
+ this.reason = params.reason;
26422
26438
  }
26423
- const capturedValue = match2[capture];
26424
- if (capturedValue === void 0) {
26425
- throw new ExtractionError(`Capture group ${capture} out of bounds. Pattern has ${match2.length - 1} capture groups`, filePath, 0);
26439
+ static resolved(typeName) {
26440
+ return new _TypeResolution({
26441
+ resolved: true,
26442
+ typeName,
26443
+ reason: void 0
26444
+ });
26426
26445
  }
26427
- if (transform2 === void 0) {
26428
- return { value: capturedValue };
26446
+ static unresolved(reason) {
26447
+ return new _TypeResolution({
26448
+ resolved: false,
26449
+ typeName: void 0,
26450
+ reason
26451
+ });
26429
26452
  }
26430
- return { value: applyTransforms(capturedValue, transform2) };
26453
+ };
26454
+ function stripGenerics(typeName) {
26455
+ const angleBracketIndex = typeName.indexOf("<");
26456
+ if (angleBracketIndex === -1)
26457
+ return typeName;
26458
+ return typeName.slice(0, angleBracketIndex);
26431
26459
  }
26432
- function findPropertyInHierarchy(classDecl, propertyName, isStatic) {
26433
- const properties = isStatic ? classDecl.getStaticProperties() : classDecl.getInstanceProperties();
26434
- const property = properties.find((p) => p.getName() === propertyName);
26435
- if (property !== void 0 && "getInitializer" in property) {
26436
- const sourceFile = classDecl.getSourceFile();
26437
- return {
26438
- initializer: property.getInitializer(),
26439
- filePath: sourceFile.getFilePath(),
26440
- line: property.getStartLineNumber()
26441
- };
26442
- }
26443
- if (classDecl.getExtends() === void 0) {
26444
- return void 0;
26460
+ function stripPromise(typeName) {
26461
+ if (typeName.startsWith("Promise<") && typeName.endsWith(">")) {
26462
+ return typeName.slice(8, -1);
26445
26463
  }
26446
- const baseClass = classDecl.getBaseClass();
26447
- if (baseClass === void 0)
26448
- return void 0;
26449
- return findPropertyInHierarchy(baseClass, propertyName, isStatic);
26450
- }
26451
- function evaluateFromPropertyRule(rule, classDecl) {
26452
- const name = rule.fromProperty.name;
26453
- const kind = rule.fromProperty.kind;
26454
- const transform2 = rule.fromProperty.transform;
26455
- const isStatic = kind === "static";
26456
- const propertyInfo = findPropertyInHierarchy(classDecl, name, isStatic);
26457
- if (propertyInfo === void 0) {
26458
- const sourceFile = classDecl.getSourceFile();
26459
- throw new ExtractionError(`Property '${name}' not found on class '${classDecl.getName() ?? "anonymous"}'`, sourceFile.getFilePath(), classDecl.getStartLineNumber());
26460
- }
26461
- const literalResult = extractLiteralValue(propertyInfo.initializer, propertyInfo.filePath, propertyInfo.line);
26462
- if (transform2 === void 0) {
26463
- return { value: literalResult.value };
26464
- }
26465
- if (typeof literalResult.value !== "string") {
26466
- return { value: literalResult.value };
26467
- }
26468
- return { value: applyTransforms(literalResult.value, transform2) };
26469
- }
26470
- function getDecoratorLocation(decorator) {
26471
- const sourceFile = decorator.getSourceFile();
26472
- return {
26473
- filePath: sourceFile.getFilePath(),
26474
- line: decorator.getStartLineNumber()
26475
- };
26476
- }
26477
- function extractPositionalArg(decorator, position) {
26478
- const args = decorator.getArguments();
26479
- const location = getDecoratorLocation(decorator);
26480
- if (args.length === 0) {
26481
- throw new ExtractionError(`Decorator '@${decorator.getName()}' has no arguments`, location.filePath, location.line);
26482
- }
26483
- const arg = args[position];
26484
- if (arg === void 0) {
26485
- throw new ExtractionError(`Argument position ${position} out of bounds. Decorator has ${args.length} argument(s)`, location.filePath, location.line);
26486
- }
26487
- if (arg.getKind() !== SyntaxKind3.StringLiteral) {
26488
- throw new ExtractionError(`Expected string literal at position ${position}, got ${arg.getKindName()}`, location.filePath, location.line);
26489
- }
26490
- return arg.asKindOrThrow(SyntaxKind3.StringLiteral).getLiteralValue();
26491
- }
26492
- function throwNoArguments(decorator, location) {
26493
- throw new ExtractionError(`Decorator '@${decorator.getName()}' has no arguments`, location.filePath, location.line);
26494
- }
26495
- function getFirstArgument(decorator, location) {
26496
- const args = decorator.getArguments();
26497
- const firstArg = args[0];
26498
- if (firstArg === void 0) {
26499
- throwNoArguments(decorator, location);
26500
- }
26501
- return firstArg;
26502
- }
26503
- function extractNamedArg(decorator, name) {
26504
- const location = getDecoratorLocation(decorator);
26505
- const firstArg = getFirstArgument(decorator, location);
26506
- if (firstArg.getKind() !== SyntaxKind3.ObjectLiteralExpression) {
26507
- throw new ExtractionError(`Expected object literal argument, got ${firstArg.getKindName()}`, location.filePath, location.line);
26508
- }
26509
- const objectLiteral = firstArg.asKindOrThrow(SyntaxKind3.ObjectLiteralExpression);
26510
- const property = objectLiteral.getProperty(name);
26511
- if (property === void 0) {
26512
- throw new ExtractionError(`Property '${name}' not found in decorator argument`, location.filePath, location.line);
26513
- }
26514
- if (!("getInitializer" in property)) {
26515
- throw new ExtractionError(`Property '${name}' has no initializer`, location.filePath, location.line);
26516
- }
26517
- const initializer3 = property.getInitializer();
26518
- if (initializer3?.getKind() !== SyntaxKind3.StringLiteral) {
26519
- throw new ExtractionError(`Expected string literal for property '${name}'`, location.filePath, location.line);
26520
- }
26521
- return initializer3.asKindOrThrow(SyntaxKind3.StringLiteral).getLiteralValue();
26522
- }
26523
- function evaluateFromDecoratorArgRule(rule, decorator) {
26524
- const decoratorName = rule.fromDecoratorArg.decorator;
26525
- const position = rule.fromDecoratorArg.position;
26526
- const name = rule.fromDecoratorArg.name;
26527
- const transform2 = rule.fromDecoratorArg.transform;
26528
- if (decoratorName !== void 0 && decorator.getName() !== decoratorName) {
26529
- const location = getDecoratorLocation(decorator);
26530
- throw new ExtractionError(`Expected decorator '@${decoratorName}', got '@${decorator.getName()}'`, location.filePath, location.line);
26531
- }
26532
- const extractValue = () => {
26533
- if (position !== void 0) {
26534
- return extractPositionalArg(decorator, position);
26535
- }
26536
- if (!name) {
26537
- const location = getDecoratorLocation(decorator);
26538
- throw new ExtractionError("Expected name parameter when position is undefined", location.filePath, location.line);
26539
- }
26540
- return extractNamedArg(decorator, name);
26541
- };
26542
- const value = extractValue();
26543
- if (transform2 === void 0) {
26544
- return { value };
26545
- }
26546
- return { value: applyTransforms(value, transform2) };
26547
- }
26548
- function evaluateFromClassDecoratorArgRule(rule, methodDecl) {
26549
- const classDecl = methodDecl.getParentIfKind(SyntaxKind3.ClassDeclaration);
26550
- if (classDecl === void 0) {
26551
- const sourceFile = methodDecl.getSourceFile();
26552
- throw new ExtractionError(`Expected method '${methodDecl.getName()}' to be declared inside a class`, sourceFile.getFilePath(), methodDecl.getStartLineNumber());
26553
- }
26554
- const classDecorator = classDecl.getDecorators().find((decorator) => decorator.getName() === rule.fromClassDecoratorArg.decorator);
26555
- if (classDecorator === void 0) {
26556
- const sourceFile = classDecl.getSourceFile();
26557
- throw new ExtractionError(`Decorator '@${rule.fromClassDecoratorArg.decorator}' not found on containing class '${classDecl.getName() ?? "anonymous"}'`, sourceFile.getFilePath(), classDecl.getStartLineNumber());
26558
- }
26559
- const fromClassDecoratorArg = rule.fromClassDecoratorArg;
26560
- const fromDecoratorArgRule = {
26561
- decorator: fromClassDecoratorArg.decorator,
26562
- ...fromClassDecoratorArg.position === void 0 ? {} : { position: fromClassDecoratorArg.position },
26563
- ...fromClassDecoratorArg.name === void 0 ? {} : { name: fromClassDecoratorArg.name },
26564
- ...fromClassDecoratorArg.transform === void 0 ? {} : { transform: fromClassDecoratorArg.transform }
26565
- };
26566
- return evaluateFromDecoratorArgRule({ fromDecoratorArg: fromDecoratorArgRule }, classDecorator);
26567
- }
26568
- function evaluateFromDecoratorNameRule(rule, decorator) {
26569
- const decoratorName = decorator.getName();
26570
- if (rule.fromDecoratorName === true) {
26571
- return { value: decoratorName };
26572
- }
26573
- const mapping = rule.fromDecoratorName.mapping;
26574
- const transform2 = rule.fromDecoratorName.transform;
26575
- const mappedValue = mapping?.[decoratorName] ?? decoratorName;
26576
- if (transform2 === void 0) {
26577
- return { value: mappedValue };
26578
- }
26579
- return { value: applyTransforms(mappedValue, transform2) };
26580
- }
26581
-
26582
- // ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
26583
- var balanced = (a, b, str) => {
26584
- const ma = a instanceof RegExp ? maybeMatch(a, str) : a;
26585
- const mb = b instanceof RegExp ? maybeMatch(b, str) : b;
26586
- const r = ma !== null && mb != null && range(ma, mb, str);
26587
- return r && {
26588
- start: r[0],
26589
- end: r[1],
26590
- pre: str.slice(0, r[0]),
26591
- body: str.slice(r[0] + ma.length, r[1]),
26592
- post: str.slice(r[1] + mb.length)
26593
- };
26594
- };
26595
- var maybeMatch = (reg, str) => {
26596
- const m = str.match(reg);
26597
- return m ? m[0] : null;
26598
- };
26599
- var range = (a, b, str) => {
26600
- let begs, beg, left, right = void 0, result;
26601
- let ai = str.indexOf(a);
26602
- let bi = str.indexOf(b, ai + 1);
26603
- let i = ai;
26604
- if (ai >= 0 && bi > 0) {
26605
- if (a === b) {
26606
- return [ai, bi];
26607
- }
26608
- begs = [];
26609
- left = str.length;
26610
- while (i >= 0 && !result) {
26611
- if (i === ai) {
26612
- begs.push(i);
26613
- ai = str.indexOf(a, i + 1);
26614
- } else if (begs.length === 1) {
26615
- const r = begs.pop();
26616
- if (r !== void 0)
26617
- result = [r, bi];
26618
- } else {
26619
- beg = begs.pop();
26620
- if (beg !== void 0 && beg < left) {
26621
- left = beg;
26622
- right = bi;
26623
- }
26624
- bi = str.indexOf(b, i + 1);
26625
- }
26626
- i = ai < bi && ai >= 0 ? ai : bi;
26627
- }
26628
- if (begs.length && right !== void 0) {
26629
- result = [left, right];
26630
- }
26631
- }
26632
- return result;
26633
- };
26634
-
26635
- // ../../node_modules/.pnpm/@isaacs+brace-expansion@5.0.0/node_modules/@isaacs/brace-expansion/dist/esm/index.js
26636
- var escSlash = "\0SLASH" + Math.random() + "\0";
26637
- var escOpen = "\0OPEN" + Math.random() + "\0";
26638
- var escClose = "\0CLOSE" + Math.random() + "\0";
26639
- var escComma = "\0COMMA" + Math.random() + "\0";
26640
- var escPeriod = "\0PERIOD" + Math.random() + "\0";
26641
- var escSlashPattern = new RegExp(escSlash, "g");
26642
- var escOpenPattern = new RegExp(escOpen, "g");
26643
- var escClosePattern = new RegExp(escClose, "g");
26644
- var escCommaPattern = new RegExp(escComma, "g");
26645
- var escPeriodPattern = new RegExp(escPeriod, "g");
26646
- var slashPattern = /\\\\/g;
26647
- var openPattern = /\\{/g;
26648
- var closePattern = /\\}/g;
26649
- var commaPattern = /\\,/g;
26650
- var periodPattern = /\\./g;
26651
- function numeric(str) {
26652
- return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
26653
- }
26654
- function escapeBraces(str) {
26655
- return str.replace(slashPattern, escSlash).replace(openPattern, escOpen).replace(closePattern, escClose).replace(commaPattern, escComma).replace(periodPattern, escPeriod);
26656
- }
26657
- function unescapeBraces(str) {
26658
- return str.replace(escSlashPattern, "\\").replace(escOpenPattern, "{").replace(escClosePattern, "}").replace(escCommaPattern, ",").replace(escPeriodPattern, ".");
26659
- }
26660
- function parseCommaParts(str) {
26661
- if (!str) {
26662
- return [""];
26663
- }
26664
- const parts = [];
26665
- const m = balanced("{", "}", str);
26666
- if (!m) {
26667
- return str.split(",");
26668
- }
26669
- const { pre, body, post } = m;
26670
- const p = pre.split(",");
26671
- p[p.length - 1] += "{" + body + "}";
26672
- const postParts = parseCommaParts(post);
26673
- if (post.length) {
26674
- ;
26675
- p[p.length - 1] += postParts.shift();
26676
- p.push.apply(p, postParts);
26677
- }
26678
- parts.push.apply(parts, p);
26679
- return parts;
26680
- }
26681
- function expand(str) {
26682
- if (!str) {
26683
- return [];
26684
- }
26685
- if (str.slice(0, 2) === "{}") {
26686
- str = "\\{\\}" + str.slice(2);
26687
- }
26688
- return expand_(escapeBraces(str), true).map(unescapeBraces);
26689
- }
26690
- function embrace(str) {
26691
- return "{" + str + "}";
26692
- }
26693
- function isPadded(el) {
26694
- return /^-?0\d/.test(el);
26695
- }
26696
- function lte(i, y) {
26697
- return i <= y;
26698
- }
26699
- function gte(i, y) {
26700
- return i >= y;
26701
- }
26702
- function expand_(str, isTop) {
26703
- const expansions = [];
26704
- const m = balanced("{", "}", str);
26705
- if (!m)
26706
- return [str];
26707
- const pre = m.pre;
26708
- const post = m.post.length ? expand_(m.post, false) : [""];
26709
- if (/\$$/.test(m.pre)) {
26710
- for (let k = 0; k < post.length; k++) {
26711
- const expansion = pre + "{" + m.body + "}" + post[k];
26712
- expansions.push(expansion);
26713
- }
26714
- } else {
26715
- const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
26716
- const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
26717
- const isSequence = isNumericSequence || isAlphaSequence;
26718
- const isOptions = m.body.indexOf(",") >= 0;
26719
- if (!isSequence && !isOptions) {
26720
- if (m.post.match(/,(?!,).*\}/)) {
26721
- str = m.pre + "{" + m.body + escClose + m.post;
26722
- return expand_(str);
26723
- }
26724
- return [str];
26725
- }
26726
- let n;
26727
- if (isSequence) {
26728
- n = m.body.split(/\.\./);
26729
- } else {
26730
- n = parseCommaParts(m.body);
26731
- if (n.length === 1 && n[0] !== void 0) {
26732
- n = expand_(n[0], false).map(embrace);
26733
- if (n.length === 1) {
26734
- return post.map((p) => m.pre + n[0] + p);
26735
- }
26736
- }
26737
- }
26738
- let N;
26739
- if (isSequence && n[0] !== void 0 && n[1] !== void 0) {
26740
- const x = numeric(n[0]);
26741
- const y = numeric(n[1]);
26742
- const width = Math.max(n[0].length, n[1].length);
26743
- let incr = n.length === 3 && n[2] !== void 0 ? Math.abs(numeric(n[2])) : 1;
26744
- let test = lte;
26745
- const reverse = y < x;
26746
- if (reverse) {
26747
- incr *= -1;
26748
- test = gte;
26749
- }
26750
- const pad = n.some(isPadded);
26751
- N = [];
26752
- for (let i = x; test(i, y); i += incr) {
26753
- let c;
26754
- if (isAlphaSequence) {
26755
- c = String.fromCharCode(i);
26756
- if (c === "\\") {
26757
- c = "";
26758
- }
26759
- } else {
26760
- c = String(i);
26761
- if (pad) {
26762
- const need = width - c.length;
26763
- if (need > 0) {
26764
- const z2 = new Array(need + 1).join("0");
26765
- if (i < 0) {
26766
- c = "-" + z2 + c.slice(1);
26767
- } else {
26768
- c = z2 + c;
26769
- }
26770
- }
26771
- }
26772
- }
26773
- N.push(c);
26774
- }
26775
- } else {
26776
- N = [];
26777
- for (let j = 0; j < n.length; j++) {
26778
- N.push.apply(N, expand_(n[j], false));
26779
- }
26780
- }
26781
- for (let j = 0; j < N.length; j++) {
26782
- for (let k = 0; k < post.length; k++) {
26783
- const expansion = pre + N[j] + post[k];
26784
- if (!isTop || isSequence || expansion) {
26785
- expansions.push(expansion);
26786
- }
26787
- }
26788
- }
26789
- }
26790
- return expansions;
26791
- }
26792
-
26793
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/assert-valid-pattern.js
26794
- var MAX_PATTERN_LENGTH = 1024 * 64;
26795
- var assertValidPattern = (pattern) => {
26796
- if (typeof pattern !== "string") {
26797
- throw new TypeError("invalid pattern");
26798
- }
26799
- if (pattern.length > MAX_PATTERN_LENGTH) {
26800
- throw new TypeError("pattern is too long");
26801
- }
26802
- };
26803
-
26804
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/brace-expressions.js
26805
- var posixClasses = {
26806
- "[:alnum:]": ["\\p{L}\\p{Nl}\\p{Nd}", true],
26807
- "[:alpha:]": ["\\p{L}\\p{Nl}", true],
26808
- "[:ascii:]": ["\\x00-\\x7f", false],
26809
- "[:blank:]": ["\\p{Zs}\\t", true],
26810
- "[:cntrl:]": ["\\p{Cc}", true],
26811
- "[:digit:]": ["\\p{Nd}", true],
26812
- "[:graph:]": ["\\p{Z}\\p{C}", true, true],
26813
- "[:lower:]": ["\\p{Ll}", true],
26814
- "[:print:]": ["\\p{C}", true],
26815
- "[:punct:]": ["\\p{P}", true],
26816
- "[:space:]": ["\\p{Z}\\t\\r\\n\\v\\f", true],
26817
- "[:upper:]": ["\\p{Lu}", true],
26818
- "[:word:]": ["\\p{L}\\p{Nl}\\p{Nd}\\p{Pc}", true],
26819
- "[:xdigit:]": ["A-Fa-f0-9", false]
26820
- };
26821
- var braceEscape = (s) => s.replace(/[[\]\\-]/g, "\\$&");
26822
- var regexpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
26823
- var rangesToString = (ranges) => ranges.join("");
26824
- var parseClass = (glob, position) => {
26825
- const pos = position;
26826
- if (glob.charAt(pos) !== "[") {
26827
- throw new Error("not in a brace expression");
26828
- }
26829
- const ranges = [];
26830
- const negs = [];
26831
- let i = pos + 1;
26832
- let sawStart = false;
26833
- let uflag = false;
26834
- let escaping = false;
26835
- let negate = false;
26836
- let endPos = pos;
26837
- let rangeStart = "";
26838
- WHILE: while (i < glob.length) {
26839
- const c = glob.charAt(i);
26840
- if ((c === "!" || c === "^") && i === pos + 1) {
26841
- negate = true;
26842
- i++;
26843
- continue;
26844
- }
26845
- if (c === "]" && sawStart && !escaping) {
26846
- endPos = i + 1;
26847
- break;
26848
- }
26849
- sawStart = true;
26850
- if (c === "\\") {
26851
- if (!escaping) {
26852
- escaping = true;
26853
- i++;
26854
- continue;
26855
- }
26856
- }
26857
- if (c === "[" && !escaping) {
26858
- for (const [cls, [unip, u, neg]] of Object.entries(posixClasses)) {
26859
- if (glob.startsWith(cls, i)) {
26860
- if (rangeStart) {
26861
- return ["$.", false, glob.length - pos, true];
26862
- }
26863
- i += cls.length;
26864
- if (neg)
26865
- negs.push(unip);
26866
- else
26867
- ranges.push(unip);
26868
- uflag = uflag || u;
26869
- continue WHILE;
26870
- }
26871
- }
26872
- }
26873
- escaping = false;
26874
- if (rangeStart) {
26875
- if (c > rangeStart) {
26876
- ranges.push(braceEscape(rangeStart) + "-" + braceEscape(c));
26877
- } else if (c === rangeStart) {
26878
- ranges.push(braceEscape(c));
26879
- }
26880
- rangeStart = "";
26881
- i++;
26882
- continue;
26883
- }
26884
- if (glob.startsWith("-]", i + 1)) {
26885
- ranges.push(braceEscape(c + "-"));
26886
- i += 2;
26887
- continue;
26888
- }
26889
- if (glob.startsWith("-", i + 1)) {
26890
- rangeStart = c;
26891
- i += 2;
26892
- continue;
26893
- }
26894
- ranges.push(braceEscape(c));
26895
- i++;
26896
- }
26897
- if (endPos < i) {
26898
- return ["", false, 0, false];
26899
- }
26900
- if (!ranges.length && !negs.length) {
26901
- return ["$.", false, glob.length - pos, true];
26902
- }
26903
- if (negs.length === 0 && ranges.length === 1 && /^\\?.$/.test(ranges[0]) && !negate) {
26904
- const r = ranges[0].length === 2 ? ranges[0].slice(-1) : ranges[0];
26905
- return [regexpEscape(r), false, endPos - pos, false];
26906
- }
26907
- const sranges = "[" + (negate ? "^" : "") + rangesToString(ranges) + "]";
26908
- const snegs = "[" + (negate ? "" : "^") + rangesToString(negs) + "]";
26909
- const comb = ranges.length && negs.length ? "(" + sranges + "|" + snegs + ")" : ranges.length ? sranges : snegs;
26910
- return [comb, uflag, endPos - pos, true];
26911
- };
26912
-
26913
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/unescape.js
26914
- var unescape2 = (s, { windowsPathsNoEscape = false, magicalBraces = true } = {}) => {
26915
- if (magicalBraces) {
26916
- return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
26917
- }
26918
- return windowsPathsNoEscape ? s.replace(/\[([^\/\\{}])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\{}])\]/g, "$1$2").replace(/\\([^\/{}])/g, "$1");
26919
- };
26920
-
26921
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/ast.js
26922
- var types = /* @__PURE__ */ new Set(["!", "?", "+", "*", "@"]);
26923
- var isExtglobType = (c) => types.has(c);
26924
- var startNoTraversal = "(?!(?:^|/)\\.\\.?(?:$|/))";
26925
- var startNoDot = "(?!\\.)";
26926
- var addPatternStart = /* @__PURE__ */ new Set(["[", "."]);
26927
- var justDots = /* @__PURE__ */ new Set(["..", "."]);
26928
- var reSpecials = new Set("().*{}+?[]^$\\!");
26929
- var regExpEscape = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
26930
- var qmark = "[^/]";
26931
- var star = qmark + "*?";
26932
- var starNoEmpty = qmark + "+?";
26933
- var AST = class _AST {
26934
- type;
26935
- #root;
26936
- #hasMagic;
26937
- #uflag = false;
26938
- #parts = [];
26939
- #parent;
26940
- #parentIndex;
26941
- #negs;
26942
- #filledNegs = false;
26943
- #options;
26944
- #toString;
26945
- // set to true if it's an extglob with no children
26946
- // (which really means one child of '')
26947
- #emptyExt = false;
26948
- constructor(type, parent, options = {}) {
26949
- this.type = type;
26950
- if (type)
26951
- this.#hasMagic = true;
26952
- this.#parent = parent;
26953
- this.#root = this.#parent ? this.#parent.#root : this;
26954
- this.#options = this.#root === this ? options : this.#root.#options;
26955
- this.#negs = this.#root === this ? [] : this.#root.#negs;
26956
- if (type === "!" && !this.#root.#filledNegs)
26957
- this.#negs.push(this);
26958
- this.#parentIndex = this.#parent ? this.#parent.#parts.length : 0;
26959
- }
26960
- get hasMagic() {
26961
- if (this.#hasMagic !== void 0)
26962
- return this.#hasMagic;
26963
- for (const p of this.#parts) {
26964
- if (typeof p === "string")
26965
- continue;
26966
- if (p.type || p.hasMagic)
26967
- return this.#hasMagic = true;
26968
- }
26969
- return this.#hasMagic;
26970
- }
26971
- // reconstructs the pattern
26972
- toString() {
26973
- if (this.#toString !== void 0)
26974
- return this.#toString;
26975
- if (!this.type) {
26976
- return this.#toString = this.#parts.map((p) => String(p)).join("");
26977
- } else {
26978
- return this.#toString = this.type + "(" + this.#parts.map((p) => String(p)).join("|") + ")";
26979
- }
26980
- }
26981
- #fillNegs() {
26982
- if (this !== this.#root)
26983
- throw new Error("should only call on root");
26984
- if (this.#filledNegs)
26985
- return this;
26986
- this.toString();
26987
- this.#filledNegs = true;
26988
- let n;
26989
- while (n = this.#negs.pop()) {
26990
- if (n.type !== "!")
26991
- continue;
26992
- let p = n;
26993
- let pp = p.#parent;
26994
- while (pp) {
26995
- for (let i = p.#parentIndex + 1; !pp.type && i < pp.#parts.length; i++) {
26996
- for (const part of n.#parts) {
26997
- if (typeof part === "string") {
26998
- throw new Error("string part in extglob AST??");
26999
- }
27000
- part.copyIn(pp.#parts[i]);
27001
- }
27002
- }
27003
- p = pp;
27004
- pp = p.#parent;
27005
- }
27006
- }
27007
- return this;
27008
- }
27009
- push(...parts) {
27010
- for (const p of parts) {
27011
- if (p === "")
27012
- continue;
27013
- if (typeof p !== "string" && !(p instanceof _AST && p.#parent === this)) {
27014
- throw new Error("invalid part: " + p);
27015
- }
27016
- this.#parts.push(p);
27017
- }
27018
- }
27019
- toJSON() {
27020
- const ret = this.type === null ? this.#parts.slice().map((p) => typeof p === "string" ? p : p.toJSON()) : [this.type, ...this.#parts.map((p) => p.toJSON())];
27021
- if (this.isStart() && !this.type)
27022
- ret.unshift([]);
27023
- if (this.isEnd() && (this === this.#root || this.#root.#filledNegs && this.#parent?.type === "!")) {
27024
- ret.push({});
27025
- }
27026
- return ret;
27027
- }
27028
- isStart() {
27029
- if (this.#root === this)
27030
- return true;
27031
- if (!this.#parent?.isStart())
27032
- return false;
27033
- if (this.#parentIndex === 0)
27034
- return true;
27035
- const p = this.#parent;
27036
- for (let i = 0; i < this.#parentIndex; i++) {
27037
- const pp = p.#parts[i];
27038
- if (!(pp instanceof _AST && pp.type === "!")) {
27039
- return false;
27040
- }
27041
- }
27042
- return true;
27043
- }
27044
- isEnd() {
27045
- if (this.#root === this)
27046
- return true;
27047
- if (this.#parent?.type === "!")
27048
- return true;
27049
- if (!this.#parent?.isEnd())
27050
- return false;
27051
- if (!this.type)
27052
- return this.#parent?.isEnd();
27053
- const pl = this.#parent ? this.#parent.#parts.length : 0;
27054
- return this.#parentIndex === pl - 1;
27055
- }
27056
- copyIn(part) {
27057
- if (typeof part === "string")
27058
- this.push(part);
27059
- else
27060
- this.push(part.clone(this));
27061
- }
27062
- clone(parent) {
27063
- const c = new _AST(this.type, parent);
27064
- for (const p of this.#parts) {
27065
- c.copyIn(p);
27066
- }
27067
- return c;
27068
- }
27069
- static #parseAST(str, ast, pos, opt) {
27070
- let escaping = false;
27071
- let inBrace = false;
27072
- let braceStart = -1;
27073
- let braceNeg = false;
27074
- if (ast.type === null) {
27075
- let i2 = pos;
27076
- let acc2 = "";
27077
- while (i2 < str.length) {
27078
- const c = str.charAt(i2++);
27079
- if (escaping || c === "\\") {
27080
- escaping = !escaping;
27081
- acc2 += c;
27082
- continue;
27083
- }
27084
- if (inBrace) {
27085
- if (i2 === braceStart + 1) {
27086
- if (c === "^" || c === "!") {
27087
- braceNeg = true;
27088
- }
27089
- } else if (c === "]" && !(i2 === braceStart + 2 && braceNeg)) {
27090
- inBrace = false;
27091
- }
27092
- acc2 += c;
27093
- continue;
27094
- } else if (c === "[") {
27095
- inBrace = true;
27096
- braceStart = i2;
27097
- braceNeg = false;
27098
- acc2 += c;
27099
- continue;
27100
- }
27101
- if (!opt.noext && isExtglobType(c) && str.charAt(i2) === "(") {
27102
- ast.push(acc2);
27103
- acc2 = "";
27104
- const ext2 = new _AST(c, ast);
27105
- i2 = _AST.#parseAST(str, ext2, i2, opt);
27106
- ast.push(ext2);
27107
- continue;
27108
- }
27109
- acc2 += c;
27110
- }
27111
- ast.push(acc2);
27112
- return i2;
27113
- }
27114
- let i = pos + 1;
27115
- let part = new _AST(null, ast);
27116
- const parts = [];
27117
- let acc = "";
27118
- while (i < str.length) {
27119
- const c = str.charAt(i++);
27120
- if (escaping || c === "\\") {
27121
- escaping = !escaping;
27122
- acc += c;
27123
- continue;
27124
- }
27125
- if (inBrace) {
27126
- if (i === braceStart + 1) {
27127
- if (c === "^" || c === "!") {
27128
- braceNeg = true;
27129
- }
27130
- } else if (c === "]" && !(i === braceStart + 2 && braceNeg)) {
27131
- inBrace = false;
27132
- }
27133
- acc += c;
27134
- continue;
27135
- } else if (c === "[") {
27136
- inBrace = true;
27137
- braceStart = i;
27138
- braceNeg = false;
27139
- acc += c;
27140
- continue;
27141
- }
27142
- if (isExtglobType(c) && str.charAt(i) === "(") {
27143
- part.push(acc);
27144
- acc = "";
27145
- const ext2 = new _AST(c, part);
27146
- part.push(ext2);
27147
- i = _AST.#parseAST(str, ext2, i, opt);
27148
- continue;
27149
- }
27150
- if (c === "|") {
27151
- part.push(acc);
27152
- acc = "";
27153
- parts.push(part);
27154
- part = new _AST(null, ast);
27155
- continue;
27156
- }
27157
- if (c === ")") {
27158
- if (acc === "" && ast.#parts.length === 0) {
27159
- ast.#emptyExt = true;
27160
- }
27161
- part.push(acc);
27162
- acc = "";
27163
- ast.push(...parts, part);
27164
- return i;
27165
- }
27166
- acc += c;
27167
- }
27168
- ast.type = null;
27169
- ast.#hasMagic = void 0;
27170
- ast.#parts = [str.substring(pos - 1)];
27171
- return i;
27172
- }
27173
- static fromGlob(pattern, options = {}) {
27174
- const ast = new _AST(null, void 0, options);
27175
- _AST.#parseAST(pattern, ast, 0, options);
27176
- return ast;
27177
- }
27178
- // returns the regular expression if there's magic, or the unescaped
27179
- // string if not.
27180
- toMMPattern() {
27181
- if (this !== this.#root)
27182
- return this.#root.toMMPattern();
27183
- const glob = this.toString();
27184
- const [re, body, hasMagic, uflag] = this.toRegExpSource();
27185
- const anyMagic = hasMagic || this.#hasMagic || this.#options.nocase && !this.#options.nocaseMagicOnly && glob.toUpperCase() !== glob.toLowerCase();
27186
- if (!anyMagic) {
27187
- return body;
27188
- }
27189
- const flags = (this.#options.nocase ? "i" : "") + (uflag ? "u" : "");
27190
- return Object.assign(new RegExp(`^${re}$`, flags), {
27191
- _src: re,
27192
- _glob: glob
27193
- });
27194
- }
27195
- get options() {
27196
- return this.#options;
27197
- }
27198
- // returns the string match, the regexp source, whether there's magic
27199
- // in the regexp (so a regular expression is required) and whether or
27200
- // not the uflag is needed for the regular expression (for posix classes)
27201
- // TODO: instead of injecting the start/end at this point, just return
27202
- // the BODY of the regexp, along with the start/end portions suitable
27203
- // for binding the start/end in either a joined full-path makeRe context
27204
- // (where we bind to (^|/), or a standalone matchPart context (where
27205
- // we bind to ^, and not /). Otherwise slashes get duped!
27206
- //
27207
- // In part-matching mode, the start is:
27208
- // - if not isStart: nothing
27209
- // - if traversal possible, but not allowed: ^(?!\.\.?$)
27210
- // - if dots allowed or not possible: ^
27211
- // - if dots possible and not allowed: ^(?!\.)
27212
- // end is:
27213
- // - if not isEnd(): nothing
27214
- // - else: $
27215
- //
27216
- // In full-path matching mode, we put the slash at the START of the
27217
- // pattern, so start is:
27218
- // - if first pattern: same as part-matching mode
27219
- // - if not isStart(): nothing
27220
- // - if traversal possible, but not allowed: /(?!\.\.?(?:$|/))
27221
- // - if dots allowed or not possible: /
27222
- // - if dots possible and not allowed: /(?!\.)
27223
- // end is:
27224
- // - if last pattern, same as part-matching mode
27225
- // - else nothing
27226
- //
27227
- // Always put the (?:$|/) on negated tails, though, because that has to be
27228
- // there to bind the end of the negated pattern portion, and it's easier to
27229
- // just stick it in now rather than try to inject it later in the middle of
27230
- // the pattern.
27231
- //
27232
- // We can just always return the same end, and leave it up to the caller
27233
- // to know whether it's going to be used joined or in parts.
27234
- // And, if the start is adjusted slightly, can do the same there:
27235
- // - if not isStart: nothing
27236
- // - if traversal possible, but not allowed: (?:/|^)(?!\.\.?$)
27237
- // - if dots allowed or not possible: (?:/|^)
27238
- // - if dots possible and not allowed: (?:/|^)(?!\.)
27239
- //
27240
- // But it's better to have a simpler binding without a conditional, for
27241
- // performance, so probably better to return both start options.
27242
- //
27243
- // Then the caller just ignores the end if it's not the first pattern,
27244
- // and the start always gets applied.
27245
- //
27246
- // But that's always going to be $ if it's the ending pattern, or nothing,
27247
- // so the caller can just attach $ at the end of the pattern when building.
27248
- //
27249
- // So the todo is:
27250
- // - better detect what kind of start is needed
27251
- // - return both flavors of starting pattern
27252
- // - attach $ at the end of the pattern when creating the actual RegExp
27253
- //
27254
- // Ah, but wait, no, that all only applies to the root when the first pattern
27255
- // is not an extglob. If the first pattern IS an extglob, then we need all
27256
- // that dot prevention biz to live in the extglob portions, because eg
27257
- // +(*|.x*) can match .xy but not .yx.
27258
- //
27259
- // So, return the two flavors if it's #root and the first child is not an
27260
- // AST, otherwise leave it to the child AST to handle it, and there,
27261
- // use the (?:^|/) style of start binding.
27262
- //
27263
- // Even simplified further:
27264
- // - Since the start for a join is eg /(?!\.) and the start for a part
27265
- // is ^(?!\.), we can just prepend (?!\.) to the pattern (either root
27266
- // or start or whatever) and prepend ^ or / at the Regexp construction.
27267
- toRegExpSource(allowDot) {
27268
- const dot = allowDot ?? !!this.#options.dot;
27269
- if (this.#root === this)
27270
- this.#fillNegs();
27271
- if (!this.type) {
27272
- const noEmpty = this.isStart() && this.isEnd() && !this.#parts.some((s) => typeof s !== "string");
27273
- const src = this.#parts.map((p) => {
27274
- const [re, _, hasMagic, uflag] = typeof p === "string" ? _AST.#parseGlob(p, this.#hasMagic, noEmpty) : p.toRegExpSource(allowDot);
27275
- this.#hasMagic = this.#hasMagic || hasMagic;
27276
- this.#uflag = this.#uflag || uflag;
27277
- return re;
27278
- }).join("");
27279
- let start2 = "";
27280
- if (this.isStart()) {
27281
- if (typeof this.#parts[0] === "string") {
27282
- const dotTravAllowed = this.#parts.length === 1 && justDots.has(this.#parts[0]);
27283
- if (!dotTravAllowed) {
27284
- const aps = addPatternStart;
27285
- const needNoTrav = (
27286
- // dots are allowed, and the pattern starts with [ or .
27287
- dot && aps.has(src.charAt(0)) || // the pattern starts with \., and then [ or .
27288
- src.startsWith("\\.") && aps.has(src.charAt(2)) || // the pattern starts with \.\., and then [ or .
27289
- src.startsWith("\\.\\.") && aps.has(src.charAt(4))
27290
- );
27291
- const needNoDot = !dot && !allowDot && aps.has(src.charAt(0));
27292
- start2 = needNoTrav ? startNoTraversal : needNoDot ? startNoDot : "";
27293
- }
27294
- }
27295
- }
27296
- let end = "";
27297
- if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") {
27298
- end = "(?:$|\\/)";
27299
- }
27300
- const final2 = start2 + src + end;
27301
- return [
27302
- final2,
27303
- unescape2(src),
27304
- this.#hasMagic = !!this.#hasMagic,
27305
- this.#uflag
27306
- ];
27307
- }
27308
- const repeated = this.type === "*" || this.type === "+";
27309
- const start = this.type === "!" ? "(?:(?!(?:" : "(?:";
27310
- let body = this.#partsToRegExp(dot);
27311
- if (this.isStart() && this.isEnd() && !body && this.type !== "!") {
27312
- const s = this.toString();
27313
- this.#parts = [s];
27314
- this.type = null;
27315
- this.#hasMagic = void 0;
27316
- return [s, unescape2(this.toString()), false, false];
27317
- }
27318
- let bodyDotAllowed = !repeated || allowDot || dot || !startNoDot ? "" : this.#partsToRegExp(true);
27319
- if (bodyDotAllowed === body) {
27320
- bodyDotAllowed = "";
27321
- }
27322
- if (bodyDotAllowed) {
27323
- body = `(?:${body})(?:${bodyDotAllowed})*?`;
27324
- }
27325
- let final = "";
27326
- if (this.type === "!" && this.#emptyExt) {
27327
- final = (this.isStart() && !dot ? startNoDot : "") + starNoEmpty;
27328
- } else {
27329
- const close = this.type === "!" ? (
27330
- // !() must match something,but !(x) can match ''
27331
- "))" + (this.isStart() && !dot && !allowDot ? startNoDot : "") + star + ")"
27332
- ) : this.type === "@" ? ")" : this.type === "?" ? ")?" : this.type === "+" && bodyDotAllowed ? ")" : this.type === "*" && bodyDotAllowed ? `)?` : `)${this.type}`;
27333
- final = start + body + close;
27334
- }
27335
- return [
27336
- final,
27337
- unescape2(body),
27338
- this.#hasMagic = !!this.#hasMagic,
27339
- this.#uflag
27340
- ];
27341
- }
27342
- #partsToRegExp(dot) {
27343
- return this.#parts.map((p) => {
27344
- if (typeof p === "string") {
27345
- throw new Error("string type in extglob ast??");
27346
- }
27347
- const [re, _, _hasMagic, uflag] = p.toRegExpSource(dot);
27348
- this.#uflag = this.#uflag || uflag;
27349
- return re;
27350
- }).filter((p) => !(this.isStart() && this.isEnd()) || !!p).join("|");
27351
- }
27352
- static #parseGlob(glob, hasMagic, noEmpty = false) {
27353
- let escaping = false;
27354
- let re = "";
27355
- let uflag = false;
27356
- for (let i = 0; i < glob.length; i++) {
27357
- const c = glob.charAt(i);
27358
- if (escaping) {
27359
- escaping = false;
27360
- re += (reSpecials.has(c) ? "\\" : "") + c;
27361
- continue;
27362
- }
27363
- if (c === "\\") {
27364
- if (i === glob.length - 1) {
27365
- re += "\\\\";
27366
- } else {
27367
- escaping = true;
27368
- }
27369
- continue;
27370
- }
27371
- if (c === "[") {
27372
- const [src, needUflag, consumed, magic] = parseClass(glob, i);
27373
- if (consumed) {
27374
- re += src;
27375
- uflag = uflag || needUflag;
27376
- i += consumed - 1;
27377
- hasMagic = hasMagic || magic;
27378
- continue;
27379
- }
27380
- }
27381
- if (c === "*") {
27382
- re += noEmpty && glob === "*" ? starNoEmpty : star;
27383
- hasMagic = true;
27384
- continue;
27385
- }
27386
- if (c === "?") {
27387
- re += qmark;
27388
- hasMagic = true;
27389
- continue;
27390
- }
27391
- re += regExpEscape(c);
27392
- }
27393
- return [re, unescape2(glob), !!hasMagic, uflag];
27394
- }
27395
- };
27396
-
27397
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/escape.js
27398
- var escape2 = (s, { windowsPathsNoEscape = false, magicalBraces = false } = {}) => {
27399
- if (magicalBraces) {
27400
- return windowsPathsNoEscape ? s.replace(/[?*()[\]{}]/g, "[$&]") : s.replace(/[?*()[\]\\{}]/g, "\\$&");
27401
- }
27402
- return windowsPathsNoEscape ? s.replace(/[?*()[\]]/g, "[$&]") : s.replace(/[?*()[\]\\]/g, "\\$&");
27403
- };
27404
-
27405
- // ../../node_modules/.pnpm/minimatch@10.1.1/node_modules/minimatch/dist/esm/index.js
27406
- var minimatch = (p, pattern, options = {}) => {
27407
- assertValidPattern(pattern);
27408
- if (!options.nocomment && pattern.charAt(0) === "#") {
27409
- return false;
27410
- }
27411
- return new Minimatch(pattern, options).match(p);
27412
- };
27413
- var starDotExtRE = /^\*+([^+@!?\*\[\(]*)$/;
27414
- var starDotExtTest = (ext2) => (f) => !f.startsWith(".") && f.endsWith(ext2);
27415
- var starDotExtTestDot = (ext2) => (f) => f.endsWith(ext2);
27416
- var starDotExtTestNocase = (ext2) => {
27417
- ext2 = ext2.toLowerCase();
27418
- return (f) => !f.startsWith(".") && f.toLowerCase().endsWith(ext2);
27419
- };
27420
- var starDotExtTestNocaseDot = (ext2) => {
27421
- ext2 = ext2.toLowerCase();
27422
- return (f) => f.toLowerCase().endsWith(ext2);
27423
- };
27424
- var starDotStarRE = /^\*+\.\*+$/;
27425
- var starDotStarTest = (f) => !f.startsWith(".") && f.includes(".");
27426
- var starDotStarTestDot = (f) => f !== "." && f !== ".." && f.includes(".");
27427
- var dotStarRE = /^\.\*+$/;
27428
- var dotStarTest = (f) => f !== "." && f !== ".." && f.startsWith(".");
27429
- var starRE = /^\*+$/;
27430
- var starTest = (f) => f.length !== 0 && !f.startsWith(".");
27431
- var starTestDot = (f) => f.length !== 0 && f !== "." && f !== "..";
27432
- var qmarksRE = /^\?+([^+@!?\*\[\(]*)?$/;
27433
- var qmarksTestNocase = ([$0, ext2 = ""]) => {
27434
- const noext = qmarksTestNoExt([$0]);
27435
- if (!ext2)
27436
- return noext;
27437
- ext2 = ext2.toLowerCase();
27438
- return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
27439
- };
27440
- var qmarksTestNocaseDot = ([$0, ext2 = ""]) => {
27441
- const noext = qmarksTestNoExtDot([$0]);
27442
- if (!ext2)
27443
- return noext;
27444
- ext2 = ext2.toLowerCase();
27445
- return (f) => noext(f) && f.toLowerCase().endsWith(ext2);
27446
- };
27447
- var qmarksTestDot = ([$0, ext2 = ""]) => {
27448
- const noext = qmarksTestNoExtDot([$0]);
27449
- return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
27450
- };
27451
- var qmarksTest = ([$0, ext2 = ""]) => {
27452
- const noext = qmarksTestNoExt([$0]);
27453
- return !ext2 ? noext : (f) => noext(f) && f.endsWith(ext2);
27454
- };
27455
- var qmarksTestNoExt = ([$0]) => {
27456
- const len = $0.length;
27457
- return (f) => f.length === len && !f.startsWith(".");
27458
- };
27459
- var qmarksTestNoExtDot = ([$0]) => {
27460
- const len = $0.length;
27461
- return (f) => f.length === len && f !== "." && f !== "..";
27462
- };
27463
- var defaultPlatform = typeof process === "object" && process ? typeof process.env === "object" && process.env && process.env.__MINIMATCH_TESTING_PLATFORM__ || process.platform : "posix";
27464
- var path = {
27465
- win32: { sep: "\\" },
27466
- posix: { sep: "/" }
27467
- };
27468
- var sep = defaultPlatform === "win32" ? path.win32.sep : path.posix.sep;
27469
- minimatch.sep = sep;
27470
- var GLOBSTAR = /* @__PURE__ */ Symbol("globstar **");
27471
- minimatch.GLOBSTAR = GLOBSTAR;
27472
- var qmark2 = "[^/]";
27473
- var star2 = qmark2 + "*?";
27474
- var twoStarDot = "(?:(?!(?:\\/|^)(?:\\.{1,2})($|\\/)).)*?";
27475
- var twoStarNoDot = "(?:(?!(?:\\/|^)\\.).)*?";
27476
- var filter = (pattern, options = {}) => (p) => minimatch(p, pattern, options);
27477
- minimatch.filter = filter;
27478
- var ext = (a, b = {}) => Object.assign({}, a, b);
27479
- var defaults = (def) => {
27480
- if (!def || typeof def !== "object" || !Object.keys(def).length) {
27481
- return minimatch;
27482
- }
27483
- const orig = minimatch;
27484
- const m = (p, pattern, options = {}) => orig(p, pattern, ext(def, options));
27485
- return Object.assign(m, {
27486
- Minimatch: class Minimatch extends orig.Minimatch {
27487
- constructor(pattern, options = {}) {
27488
- super(pattern, ext(def, options));
27489
- }
27490
- static defaults(options) {
27491
- return orig.defaults(ext(def, options)).Minimatch;
27492
- }
27493
- },
27494
- AST: class AST extends orig.AST {
27495
- /* c8 ignore start */
27496
- constructor(type, parent, options = {}) {
27497
- super(type, parent, ext(def, options));
27498
- }
27499
- /* c8 ignore stop */
27500
- static fromGlob(pattern, options = {}) {
27501
- return orig.AST.fromGlob(pattern, ext(def, options));
27502
- }
27503
- },
27504
- unescape: (s, options = {}) => orig.unescape(s, ext(def, options)),
27505
- escape: (s, options = {}) => orig.escape(s, ext(def, options)),
27506
- filter: (pattern, options = {}) => orig.filter(pattern, ext(def, options)),
27507
- defaults: (options) => orig.defaults(ext(def, options)),
27508
- makeRe: (pattern, options = {}) => orig.makeRe(pattern, ext(def, options)),
27509
- braceExpand: (pattern, options = {}) => orig.braceExpand(pattern, ext(def, options)),
27510
- match: (list, pattern, options = {}) => orig.match(list, pattern, ext(def, options)),
27511
- sep: orig.sep,
27512
- GLOBSTAR
27513
- });
27514
- };
27515
- minimatch.defaults = defaults;
27516
- var braceExpand = (pattern, options = {}) => {
27517
- assertValidPattern(pattern);
27518
- if (options.nobrace || !/\{(?:(?!\{).)*\}/.test(pattern)) {
27519
- return [pattern];
27520
- }
27521
- return expand(pattern);
27522
- };
27523
- minimatch.braceExpand = braceExpand;
27524
- var makeRe = (pattern, options = {}) => new Minimatch(pattern, options).makeRe();
27525
- minimatch.makeRe = makeRe;
27526
- var match = (list, pattern, options = {}) => {
27527
- const mm = new Minimatch(pattern, options);
27528
- list = list.filter((f) => mm.match(f));
27529
- if (mm.options.nonull && !list.length) {
27530
- list.push(pattern);
27531
- }
27532
- return list;
27533
- };
27534
- minimatch.match = match;
27535
- var globMagic = /[?*]|[+@!]\(.*?\)|\[|\]/;
27536
- var regExpEscape2 = (s) => s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
27537
- var Minimatch = class {
27538
- options;
27539
- set;
27540
- pattern;
27541
- windowsPathsNoEscape;
27542
- nonegate;
27543
- negate;
27544
- comment;
27545
- empty;
27546
- preserveMultipleSlashes;
27547
- partial;
27548
- globSet;
27549
- globParts;
27550
- nocase;
27551
- isWindows;
27552
- platform;
27553
- windowsNoMagicRoot;
27554
- regexp;
27555
- constructor(pattern, options = {}) {
27556
- assertValidPattern(pattern);
27557
- options = options || {};
27558
- this.options = options;
27559
- this.pattern = pattern;
27560
- this.platform = options.platform || defaultPlatform;
27561
- this.isWindows = this.platform === "win32";
27562
- this.windowsPathsNoEscape = !!options.windowsPathsNoEscape || options.allowWindowsEscape === false;
27563
- if (this.windowsPathsNoEscape) {
27564
- this.pattern = this.pattern.replace(/\\/g, "/");
27565
- }
27566
- this.preserveMultipleSlashes = !!options.preserveMultipleSlashes;
27567
- this.regexp = null;
27568
- this.negate = false;
27569
- this.nonegate = !!options.nonegate;
27570
- this.comment = false;
27571
- this.empty = false;
27572
- this.partial = !!options.partial;
27573
- this.nocase = !!this.options.nocase;
27574
- this.windowsNoMagicRoot = options.windowsNoMagicRoot !== void 0 ? options.windowsNoMagicRoot : !!(this.isWindows && this.nocase);
27575
- this.globSet = [];
27576
- this.globParts = [];
27577
- this.set = [];
27578
- this.make();
27579
- }
27580
- hasMagic() {
27581
- if (this.options.magicalBraces && this.set.length > 1) {
27582
- return true;
27583
- }
27584
- for (const pattern of this.set) {
27585
- for (const part of pattern) {
27586
- if (typeof part !== "string")
27587
- return true;
27588
- }
27589
- }
27590
- return false;
27591
- }
27592
- debug(..._) {
27593
- }
27594
- make() {
27595
- const pattern = this.pattern;
27596
- const options = this.options;
27597
- if (!options.nocomment && pattern.charAt(0) === "#") {
27598
- this.comment = true;
27599
- return;
27600
- }
27601
- if (!pattern) {
27602
- this.empty = true;
27603
- return;
27604
- }
27605
- this.parseNegate();
27606
- this.globSet = [...new Set(this.braceExpand())];
27607
- if (options.debug) {
27608
- this.debug = (...args) => console.error(...args);
27609
- }
27610
- this.debug(this.pattern, this.globSet);
27611
- const rawGlobParts = this.globSet.map((s) => this.slashSplit(s));
27612
- this.globParts = this.preprocess(rawGlobParts);
27613
- this.debug(this.pattern, this.globParts);
27614
- let set2 = this.globParts.map((s, _, __) => {
27615
- if (this.isWindows && this.windowsNoMagicRoot) {
27616
- const isUNC = s[0] === "" && s[1] === "" && (s[2] === "?" || !globMagic.test(s[2])) && !globMagic.test(s[3]);
27617
- const isDrive = /^[a-z]:/i.test(s[0]);
27618
- if (isUNC) {
27619
- return [...s.slice(0, 4), ...s.slice(4).map((ss) => this.parse(ss))];
27620
- } else if (isDrive) {
27621
- return [s[0], ...s.slice(1).map((ss) => this.parse(ss))];
27622
- }
27623
- }
27624
- return s.map((ss) => this.parse(ss));
27625
- });
27626
- this.debug(this.pattern, set2);
27627
- this.set = set2.filter((s) => s.indexOf(false) === -1);
27628
- if (this.isWindows) {
27629
- for (let i = 0; i < this.set.length; i++) {
27630
- const p = this.set[i];
27631
- if (p[0] === "" && p[1] === "" && this.globParts[i][2] === "?" && typeof p[3] === "string" && /^[a-z]:$/i.test(p[3])) {
27632
- p[2] = "?";
27633
- }
27634
- }
27635
- }
27636
- this.debug(this.pattern, this.set);
27637
- }
27638
- // various transforms to equivalent pattern sets that are
27639
- // faster to process in a filesystem walk. The goal is to
27640
- // eliminate what we can, and push all ** patterns as far
27641
- // to the right as possible, even if it increases the number
27642
- // of patterns that we have to process.
27643
- preprocess(globParts) {
27644
- if (this.options.noglobstar) {
27645
- for (let i = 0; i < globParts.length; i++) {
27646
- for (let j = 0; j < globParts[i].length; j++) {
27647
- if (globParts[i][j] === "**") {
27648
- globParts[i][j] = "*";
27649
- }
27650
- }
27651
- }
27652
- }
27653
- const { optimizationLevel = 1 } = this.options;
27654
- if (optimizationLevel >= 2) {
27655
- globParts = this.firstPhasePreProcess(globParts);
27656
- globParts = this.secondPhasePreProcess(globParts);
27657
- } else if (optimizationLevel >= 1) {
27658
- globParts = this.levelOneOptimize(globParts);
27659
- } else {
27660
- globParts = this.adjascentGlobstarOptimize(globParts);
27661
- }
27662
- return globParts;
27663
- }
27664
- // just get rid of adjascent ** portions
27665
- adjascentGlobstarOptimize(globParts) {
27666
- return globParts.map((parts) => {
27667
- let gs = -1;
27668
- while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
27669
- let i = gs;
27670
- while (parts[i + 1] === "**") {
27671
- i++;
27672
- }
27673
- if (i !== gs) {
27674
- parts.splice(gs, i - gs);
27675
- }
27676
- }
27677
- return parts;
27678
- });
27679
- }
27680
- // get rid of adjascent ** and resolve .. portions
27681
- levelOneOptimize(globParts) {
27682
- return globParts.map((parts) => {
27683
- parts = parts.reduce((set2, part) => {
27684
- const prev = set2[set2.length - 1];
27685
- if (part === "**" && prev === "**") {
27686
- return set2;
27687
- }
27688
- if (part === "..") {
27689
- if (prev && prev !== ".." && prev !== "." && prev !== "**") {
27690
- set2.pop();
27691
- return set2;
27692
- }
27693
- }
27694
- set2.push(part);
27695
- return set2;
27696
- }, []);
27697
- return parts.length === 0 ? [""] : parts;
27698
- });
27699
- }
27700
- levelTwoFileOptimize(parts) {
27701
- if (!Array.isArray(parts)) {
27702
- parts = this.slashSplit(parts);
27703
- }
27704
- let didSomething = false;
27705
- do {
27706
- didSomething = false;
27707
- if (!this.preserveMultipleSlashes) {
27708
- for (let i = 1; i < parts.length - 1; i++) {
27709
- const p = parts[i];
27710
- if (i === 1 && p === "" && parts[0] === "")
27711
- continue;
27712
- if (p === "." || p === "") {
27713
- didSomething = true;
27714
- parts.splice(i, 1);
27715
- i--;
27716
- }
27717
- }
27718
- if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
27719
- didSomething = true;
27720
- parts.pop();
27721
- }
27722
- }
27723
- let dd = 0;
27724
- while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
27725
- const p = parts[dd - 1];
27726
- if (p && p !== "." && p !== ".." && p !== "**") {
27727
- didSomething = true;
27728
- parts.splice(dd - 1, 2);
27729
- dd -= 2;
27730
- }
27731
- }
27732
- } while (didSomething);
27733
- return parts.length === 0 ? [""] : parts;
27734
- }
27735
- // First phase: single-pattern processing
27736
- // <pre> is 1 or more portions
27737
- // <rest> is 1 or more portions
27738
- // <p> is any portion other than ., .., '', or **
27739
- // <e> is . or ''
27740
- //
27741
- // **/.. is *brutal* for filesystem walking performance, because
27742
- // it effectively resets the recursive walk each time it occurs,
27743
- // and ** cannot be reduced out by a .. pattern part like a regexp
27744
- // or most strings (other than .., ., and '') can be.
27745
- //
27746
- // <pre>/**/../<p>/<p>/<rest> -> {<pre>/../<p>/<p>/<rest>,<pre>/**/<p>/<p>/<rest>}
27747
- // <pre>/<e>/<rest> -> <pre>/<rest>
27748
- // <pre>/<p>/../<rest> -> <pre>/<rest>
27749
- // **/**/<rest> -> **/<rest>
27750
- //
27751
- // **/*/<rest> -> */**/<rest> <== not valid because ** doesn't follow
27752
- // this WOULD be allowed if ** did follow symlinks, or * didn't
27753
- firstPhasePreProcess(globParts) {
27754
- let didSomething = false;
27755
- do {
27756
- didSomething = false;
27757
- for (let parts of globParts) {
27758
- let gs = -1;
27759
- while (-1 !== (gs = parts.indexOf("**", gs + 1))) {
27760
- let gss = gs;
27761
- while (parts[gss + 1] === "**") {
27762
- gss++;
27763
- }
27764
- if (gss > gs) {
27765
- parts.splice(gs + 1, gss - gs);
27766
- }
27767
- let next = parts[gs + 1];
27768
- const p = parts[gs + 2];
27769
- const p2 = parts[gs + 3];
27770
- if (next !== "..")
27771
- continue;
27772
- if (!p || p === "." || p === ".." || !p2 || p2 === "." || p2 === "..") {
27773
- continue;
27774
- }
27775
- didSomething = true;
27776
- parts.splice(gs, 1);
27777
- const other = parts.slice(0);
27778
- other[gs] = "**";
27779
- globParts.push(other);
27780
- gs--;
27781
- }
27782
- if (!this.preserveMultipleSlashes) {
27783
- for (let i = 1; i < parts.length - 1; i++) {
27784
- const p = parts[i];
27785
- if (i === 1 && p === "" && parts[0] === "")
27786
- continue;
27787
- if (p === "." || p === "") {
27788
- didSomething = true;
27789
- parts.splice(i, 1);
27790
- i--;
27791
- }
27792
- }
27793
- if (parts[0] === "." && parts.length === 2 && (parts[1] === "." || parts[1] === "")) {
27794
- didSomething = true;
27795
- parts.pop();
27796
- }
27797
- }
27798
- let dd = 0;
27799
- while (-1 !== (dd = parts.indexOf("..", dd + 1))) {
27800
- const p = parts[dd - 1];
27801
- if (p && p !== "." && p !== ".." && p !== "**") {
27802
- didSomething = true;
27803
- const needDot = dd === 1 && parts[dd + 1] === "**";
27804
- const splin = needDot ? ["."] : [];
27805
- parts.splice(dd - 1, 2, ...splin);
27806
- if (parts.length === 0)
27807
- parts.push("");
27808
- dd -= 2;
27809
- }
27810
- }
27811
- }
27812
- } while (didSomething);
27813
- return globParts;
27814
- }
27815
- // second phase: multi-pattern dedupes
27816
- // {<pre>/*/<rest>,<pre>/<p>/<rest>} -> <pre>/*/<rest>
27817
- // {<pre>/<rest>,<pre>/<rest>} -> <pre>/<rest>
27818
- // {<pre>/**/<rest>,<pre>/<rest>} -> <pre>/**/<rest>
27819
- //
27820
- // {<pre>/**/<rest>,<pre>/**/<p>/<rest>} -> <pre>/**/<rest>
27821
- // ^-- not valid because ** doens't follow symlinks
27822
- secondPhasePreProcess(globParts) {
27823
- for (let i = 0; i < globParts.length - 1; i++) {
27824
- for (let j = i + 1; j < globParts.length; j++) {
27825
- const matched = this.partsMatch(globParts[i], globParts[j], !this.preserveMultipleSlashes);
27826
- if (matched) {
27827
- globParts[i] = [];
27828
- globParts[j] = matched;
27829
- break;
27830
- }
27831
- }
27832
- }
27833
- return globParts.filter((gs) => gs.length);
27834
- }
27835
- partsMatch(a, b, emptyGSMatch = false) {
27836
- let ai = 0;
27837
- let bi = 0;
27838
- let result = [];
27839
- let which = "";
27840
- while (ai < a.length && bi < b.length) {
27841
- if (a[ai] === b[bi]) {
27842
- result.push(which === "b" ? b[bi] : a[ai]);
27843
- ai++;
27844
- bi++;
27845
- } else if (emptyGSMatch && a[ai] === "**" && b[bi] === a[ai + 1]) {
27846
- result.push(a[ai]);
27847
- ai++;
27848
- } else if (emptyGSMatch && b[bi] === "**" && a[ai] === b[bi + 1]) {
27849
- result.push(b[bi]);
27850
- bi++;
27851
- } else if (a[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
27852
- if (which === "b")
27853
- return false;
27854
- which = "a";
27855
- result.push(a[ai]);
27856
- ai++;
27857
- bi++;
27858
- } else if (b[bi] === "*" && a[ai] && (this.options.dot || !a[ai].startsWith(".")) && a[ai] !== "**") {
27859
- if (which === "a")
27860
- return false;
27861
- which = "b";
27862
- result.push(b[bi]);
27863
- ai++;
27864
- bi++;
27865
- } else {
27866
- return false;
27867
- }
27868
- }
27869
- return a.length === b.length && result;
27870
- }
27871
- parseNegate() {
27872
- if (this.nonegate)
27873
- return;
27874
- const pattern = this.pattern;
27875
- let negate = false;
27876
- let negateOffset = 0;
27877
- for (let i = 0; i < pattern.length && pattern.charAt(i) === "!"; i++) {
27878
- negate = !negate;
27879
- negateOffset++;
27880
- }
27881
- if (negateOffset)
27882
- this.pattern = pattern.slice(negateOffset);
27883
- this.negate = negate;
27884
- }
27885
- // set partial to true to test if, for example,
27886
- // "/a/b" matches the start of "/*/b/*/d"
27887
- // Partial means, if you run out of file before you run
27888
- // out of pattern, then that's fine, as long as all
27889
- // the parts match.
27890
- matchOne(file2, pattern, partial2 = false) {
27891
- const options = this.options;
27892
- if (this.isWindows) {
27893
- const fileDrive = typeof file2[0] === "string" && /^[a-z]:$/i.test(file2[0]);
27894
- const fileUNC = !fileDrive && file2[0] === "" && file2[1] === "" && file2[2] === "?" && /^[a-z]:$/i.test(file2[3]);
27895
- const patternDrive = typeof pattern[0] === "string" && /^[a-z]:$/i.test(pattern[0]);
27896
- const patternUNC = !patternDrive && pattern[0] === "" && pattern[1] === "" && pattern[2] === "?" && typeof pattern[3] === "string" && /^[a-z]:$/i.test(pattern[3]);
27897
- const fdi = fileUNC ? 3 : fileDrive ? 0 : void 0;
27898
- const pdi = patternUNC ? 3 : patternDrive ? 0 : void 0;
27899
- if (typeof fdi === "number" && typeof pdi === "number") {
27900
- const [fd, pd] = [file2[fdi], pattern[pdi]];
27901
- if (fd.toLowerCase() === pd.toLowerCase()) {
27902
- pattern[pdi] = fd;
27903
- if (pdi > fdi) {
27904
- pattern = pattern.slice(pdi);
27905
- } else if (fdi > pdi) {
27906
- file2 = file2.slice(fdi);
27907
- }
27908
- }
27909
- }
27910
- }
27911
- const { optimizationLevel = 1 } = this.options;
27912
- if (optimizationLevel >= 2) {
27913
- file2 = this.levelTwoFileOptimize(file2);
27914
- }
27915
- this.debug("matchOne", this, { file: file2, pattern });
27916
- this.debug("matchOne", file2.length, pattern.length);
27917
- for (var fi = 0, pi = 0, fl = file2.length, pl = pattern.length; fi < fl && pi < pl; fi++, pi++) {
27918
- this.debug("matchOne loop");
27919
- var p = pattern[pi];
27920
- var f = file2[fi];
27921
- this.debug(pattern, p, f);
27922
- if (p === false) {
27923
- return false;
27924
- }
27925
- if (p === GLOBSTAR) {
27926
- this.debug("GLOBSTAR", [pattern, p, f]);
27927
- var fr = fi;
27928
- var pr = pi + 1;
27929
- if (pr === pl) {
27930
- this.debug("** at the end");
27931
- for (; fi < fl; fi++) {
27932
- if (file2[fi] === "." || file2[fi] === ".." || !options.dot && file2[fi].charAt(0) === ".")
27933
- return false;
27934
- }
27935
- return true;
27936
- }
27937
- while (fr < fl) {
27938
- var swallowee = file2[fr];
27939
- this.debug("\nglobstar while", file2, fr, pattern, pr, swallowee);
27940
- if (this.matchOne(file2.slice(fr), pattern.slice(pr), partial2)) {
27941
- this.debug("globstar found match!", fr, fl, swallowee);
27942
- return true;
27943
- } else {
27944
- if (swallowee === "." || swallowee === ".." || !options.dot && swallowee.charAt(0) === ".") {
27945
- this.debug("dot detected!", file2, fr, pattern, pr);
27946
- break;
27947
- }
27948
- this.debug("globstar swallow a segment, and continue");
27949
- fr++;
27950
- }
27951
- }
27952
- if (partial2) {
27953
- this.debug("\n>>> no match, partial?", file2, fr, pattern, pr);
27954
- if (fr === fl) {
27955
- return true;
27956
- }
27957
- }
27958
- return false;
27959
- }
27960
- let hit;
27961
- if (typeof p === "string") {
27962
- hit = f === p;
27963
- this.debug("string match", p, f, hit);
27964
- } else {
27965
- hit = p.test(f);
27966
- this.debug("pattern match", p, f, hit);
27967
- }
27968
- if (!hit)
27969
- return false;
27970
- }
27971
- if (fi === fl && pi === pl) {
27972
- return true;
27973
- } else if (fi === fl) {
27974
- return partial2;
27975
- } else if (pi === pl) {
27976
- return fi === fl - 1 && file2[fi] === "";
27977
- } else {
27978
- throw new Error("wtf?");
27979
- }
27980
- }
27981
- braceExpand() {
27982
- return braceExpand(this.pattern, this.options);
27983
- }
27984
- parse(pattern) {
27985
- assertValidPattern(pattern);
27986
- const options = this.options;
27987
- if (pattern === "**")
27988
- return GLOBSTAR;
27989
- if (pattern === "")
27990
- return "";
27991
- let m;
27992
- let fastTest = null;
27993
- if (m = pattern.match(starRE)) {
27994
- fastTest = options.dot ? starTestDot : starTest;
27995
- } else if (m = pattern.match(starDotExtRE)) {
27996
- fastTest = (options.nocase ? options.dot ? starDotExtTestNocaseDot : starDotExtTestNocase : options.dot ? starDotExtTestDot : starDotExtTest)(m[1]);
27997
- } else if (m = pattern.match(qmarksRE)) {
27998
- fastTest = (options.nocase ? options.dot ? qmarksTestNocaseDot : qmarksTestNocase : options.dot ? qmarksTestDot : qmarksTest)(m);
27999
- } else if (m = pattern.match(starDotStarRE)) {
28000
- fastTest = options.dot ? starDotStarTestDot : starDotStarTest;
28001
- } else if (m = pattern.match(dotStarRE)) {
28002
- fastTest = dotStarTest;
28003
- }
28004
- const re = AST.fromGlob(pattern, this.options).toMMPattern();
28005
- if (fastTest && typeof re === "object") {
28006
- Reflect.defineProperty(re, "test", { value: fastTest });
28007
- }
28008
- return re;
28009
- }
28010
- makeRe() {
28011
- if (this.regexp || this.regexp === false)
28012
- return this.regexp;
28013
- const set2 = this.set;
28014
- if (!set2.length) {
28015
- this.regexp = false;
28016
- return this.regexp;
28017
- }
28018
- const options = this.options;
28019
- const twoStar = options.noglobstar ? star2 : options.dot ? twoStarDot : twoStarNoDot;
28020
- const flags = new Set(options.nocase ? ["i"] : []);
28021
- let re = set2.map((pattern) => {
28022
- const pp = pattern.map((p) => {
28023
- if (p instanceof RegExp) {
28024
- for (const f of p.flags.split(""))
28025
- flags.add(f);
28026
- }
28027
- return typeof p === "string" ? regExpEscape2(p) : p === GLOBSTAR ? GLOBSTAR : p._src;
28028
- });
28029
- pp.forEach((p, i) => {
28030
- const next = pp[i + 1];
28031
- const prev = pp[i - 1];
28032
- if (p !== GLOBSTAR || prev === GLOBSTAR) {
28033
- return;
28034
- }
28035
- if (prev === void 0) {
28036
- if (next !== void 0 && next !== GLOBSTAR) {
28037
- pp[i + 1] = "(?:\\/|" + twoStar + "\\/)?" + next;
28038
- } else {
28039
- pp[i] = twoStar;
28040
- }
28041
- } else if (next === void 0) {
28042
- pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + ")?";
28043
- } else if (next !== GLOBSTAR) {
28044
- pp[i - 1] = prev + "(?:\\/|\\/" + twoStar + "\\/)" + next;
28045
- pp[i + 1] = GLOBSTAR;
28046
- }
28047
- });
28048
- const filtered = pp.filter((p) => p !== GLOBSTAR);
28049
- if (this.partial && filtered.length >= 1) {
28050
- const prefixes = [];
28051
- for (let i = 1; i <= filtered.length; i++) {
28052
- prefixes.push(filtered.slice(0, i).join("/"));
28053
- }
28054
- return "(?:" + prefixes.join("|") + ")";
28055
- }
28056
- return filtered.join("/");
28057
- }).join("|");
28058
- const [open, close] = set2.length > 1 ? ["(?:", ")"] : ["", ""];
28059
- re = "^" + open + re + close + "$";
28060
- if (this.partial) {
28061
- re = "^(?:\\/|" + open + re.slice(1, -1) + close + ")$";
28062
- }
28063
- if (this.negate)
28064
- re = "^(?!" + re + ").+$";
28065
- try {
28066
- this.regexp = new RegExp(re, [...flags].join(""));
28067
- } catch (ex) {
28068
- this.regexp = false;
28069
- }
28070
- return this.regexp;
28071
- }
28072
- slashSplit(p) {
28073
- if (this.preserveMultipleSlashes) {
28074
- return p.split("/");
28075
- } else if (this.isWindows && /^\/\/[^\/]+/.test(p)) {
28076
- return ["", ...p.split(/\/+/)];
28077
- } else {
28078
- return p.split(/\/+/);
28079
- }
28080
- }
28081
- match(f, partial2 = this.partial) {
28082
- this.debug("match", f, this.pattern);
28083
- if (this.comment) {
28084
- return false;
28085
- }
28086
- if (this.empty) {
28087
- return f === "";
28088
- }
28089
- if (f === "/" && partial2) {
28090
- return true;
28091
- }
28092
- const options = this.options;
28093
- if (this.isWindows) {
28094
- f = f.split("\\").join("/");
28095
- }
28096
- const ff = this.slashSplit(f);
28097
- this.debug(this.pattern, "split", ff);
28098
- const set2 = this.set;
28099
- this.debug(this.pattern, "set", set2);
28100
- let filename = ff[ff.length - 1];
28101
- if (!filename) {
28102
- for (let i = ff.length - 2; !filename && i >= 0; i--) {
28103
- filename = ff[i];
28104
- }
28105
- }
28106
- for (let i = 0; i < set2.length; i++) {
28107
- const pattern = set2[i];
28108
- let file2 = ff;
28109
- if (options.matchBase && pattern.length === 1) {
28110
- file2 = [filename];
28111
- }
28112
- const hit = this.matchOne(file2, pattern, partial2);
28113
- if (hit) {
28114
- if (options.flipNegate) {
28115
- return true;
28116
- }
28117
- return !this.negate;
28118
- }
28119
- }
28120
- if (options.flipNegate) {
28121
- return false;
28122
- }
28123
- return this.negate;
28124
- }
28125
- static defaults(def) {
28126
- return minimatch.defaults(def).Minimatch;
28127
- }
28128
- };
28129
- minimatch.AST = AST;
28130
- minimatch.Minimatch = Minimatch;
28131
- minimatch.escape = escape2;
28132
- minimatch.unescape = unescape2;
28133
-
28134
- // ../riviere-extract-ts/dist/platform/infra/external-clients/minimatch/minimatch-glob.js
28135
- function matchesGlob(path2, pattern) {
28136
- return minimatch(path2, pattern);
28137
- }
28138
-
28139
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/detect-connections.js
28140
- import { performance } from "node:perf_hooks";
28141
-
28142
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/call-graph-types.js
28143
- function componentIdentity(component) {
28144
- return ComponentId.create({
28145
- domain: component.domain,
28146
- module: component.module,
28147
- type: component.type,
28148
- name: component.name
28149
- }).toString();
28150
- }
28151
- function stripGenericArgs(typeName) {
28152
- const index = typeName.indexOf("<");
28153
- if (index === -1) {
28154
- return typeName;
28155
- }
28156
- return typeName.slice(0, index);
28157
- }
28158
-
28159
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/component-index.js
28160
- function locationKey(file2, line) {
28161
- return `${file2}:${line}`;
28162
- }
28163
- var ComponentIndex = class {
28164
- byName;
28165
- byLocation;
28166
- constructor(components) {
28167
- const nameMap = /* @__PURE__ */ new Map();
28168
- const locationMap = /* @__PURE__ */ new Map();
28169
- for (const component of components) {
28170
- nameMap.set(component.name, component);
28171
- locationMap.set(locationKey(component.location.file, component.location.line), component);
28172
- }
28173
- this.byName = nameMap;
28174
- this.byLocation = locationMap;
28175
- }
28176
- isComponent(typeName) {
28177
- return this.byName.has(stripGenericArgs(typeName));
28178
- }
28179
- getComponentByTypeName(typeName) {
28180
- return this.byName.get(stripGenericArgs(typeName));
28181
- }
28182
- getComponentByLocation(file2, line) {
28183
- return this.byLocation.get(locationKey(file2, line));
28184
- }
28185
- };
28186
-
28187
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.js
28188
- import { Node as Node3, SyntaxKind as SyntaxKind6 } from "ts-morph";
28189
-
28190
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/trace-calls.js
28191
- import { Node as Node2, SyntaxKind as SyntaxKind5 } from "ts-morph";
28192
-
28193
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.js
28194
- import { CallExpression, SourceFile, Node } from "ts-morph";
28195
-
28196
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/connection-detection-error.js
28197
- var ConnectionDetectionError = class extends Error {
28198
- file;
28199
- line;
28200
- typeName;
28201
- reason;
28202
- constructor(params) {
28203
- super(`Connection detection failed for ${params.typeName} at ${params.file}:${params.line}: ${params.reason}`);
28204
- this.name = "ConnectionDetectionError";
28205
- this.file = params.file;
28206
- this.line = params.line;
28207
- this.typeName = params.typeName;
28208
- this.reason = params.reason;
28209
- }
28210
- };
28211
-
28212
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/type-resolver.js
28213
- function stripGenerics(typeName) {
28214
- const angleBracketIndex = typeName.indexOf("<");
28215
- if (angleBracketIndex === -1)
28216
- return typeName;
28217
- return typeName.slice(0, angleBracketIndex);
28218
- }
28219
- function stripPromise(typeName) {
28220
- if (typeName.startsWith("Promise<") && typeName.endsWith(">")) {
28221
- return typeName.slice(8, -1);
28222
- }
28223
- return typeName;
26464
+ return typeName;
28224
26465
  }
28225
26466
  var UNRESOLVABLE_TYPES = /* @__PURE__ */ new Set(["any", "unknown", "object"]);
28226
26467
  function isUnresolvableType(typeName) {
@@ -28310,10 +26551,7 @@ function handleUnresolvable(sourceFile, callExpression, rawTypeName, options) {
28310
26551
  if (options.strict) {
28311
26552
  throw buildError(sourceFile, callExpression, rawTypeName, reason);
28312
26553
  }
28313
- return {
28314
- resolved: false,
28315
- reason
28316
- };
26554
+ return TypeResolution.unresolved(reason);
28317
26555
  }
28318
26556
  function resolveCallExpressionReceiverType(callExpression, sourceFile, options) {
28319
26557
  const receiver = getReceiverExpression(callExpression);
@@ -28322,26 +26560,68 @@ function resolveCallExpressionReceiverType(callExpression, sourceFile, options)
28322
26560
  if (options.strict) {
28323
26561
  throw buildError(sourceFile, callExpression, "unknown", reason);
28324
26562
  }
28325
- return {
28326
- resolved: false,
28327
- reason
28328
- };
26563
+ return TypeResolution.unresolved(reason);
28329
26564
  }
28330
26565
  const rawTypeName = resolveReceiverTypeName(receiver);
28331
26566
  if (isUnresolvableType(rawTypeName)) {
28332
26567
  return handleUnresolvable(sourceFile, callExpression, rawTypeName, options);
28333
26568
  }
28334
- return {
28335
- resolved: true,
28336
- typeName: stripGenerics(rawTypeName)
28337
- };
26569
+ return TypeResolution.resolved(stripGenerics(rawTypeName));
28338
26570
  }
28339
26571
 
28340
26572
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/call-graph-shared.js
28341
- import { SyntaxKind as SyntaxKind4 } from "ts-morph";
26573
+ import { SyntaxKind as SyntaxKind2 } from "ts-morph";
26574
+
26575
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/call-graph-outcomes.js
26576
+ var InterfaceResolutionOutcome = class {
26577
+ component;
26578
+ resolvedTypeName;
26579
+ uncertain;
26580
+ constructor(params) {
26581
+ this.component = params.component;
26582
+ this.resolvedTypeName = params.resolvedTypeName;
26583
+ this.uncertain = params.uncertain;
26584
+ }
26585
+ };
26586
+ var MethodLookup = class {
26587
+ method;
26588
+ classFound;
26589
+ constructor(params) {
26590
+ this.method = params.method;
26591
+ this.classFound = params.classFound;
26592
+ }
26593
+ };
28342
26594
 
28343
26595
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/interface-resolution/resolve-interface.js
28344
26596
  import { Project, ClassDeclaration, SourceFile as SourceFile2 } from "ts-morph";
26597
+ var InterfaceResolution = class _InterfaceResolution {
26598
+ resolved;
26599
+ typeName;
26600
+ reason;
26601
+ typeDefinedInSource;
26602
+ constructor(params) {
26603
+ this.resolved = params.resolved;
26604
+ this.typeName = params.typeName;
26605
+ this.reason = params.reason;
26606
+ this.typeDefinedInSource = params.typeDefinedInSource;
26607
+ }
26608
+ static resolved(typeName) {
26609
+ return new _InterfaceResolution({
26610
+ resolved: true,
26611
+ typeName,
26612
+ reason: void 0,
26613
+ typeDefinedInSource: void 0
26614
+ });
26615
+ }
26616
+ static unresolved(params) {
26617
+ return new _InterfaceResolution({
26618
+ resolved: false,
26619
+ typeName: void 0,
26620
+ reason: params.reason,
26621
+ typeDefinedInSource: params.typeDefinedInSource
26622
+ });
26623
+ }
26624
+ };
28345
26625
  function isNodeModulesPath(filePath) {
28346
26626
  return filePath.includes("node_modules");
28347
26627
  }
@@ -28384,10 +26664,7 @@ function resolveInterface(interfaceName, project, sourceFilePaths, options) {
28384
26664
  const implementations = findImplementations(interfaceName, sourceFiles);
28385
26665
  const [singleImpl] = implementations;
28386
26666
  if (implementations.length === 1 && singleImpl) {
28387
- return {
28388
- resolved: true,
28389
- typeName: singleImpl
28390
- };
26667
+ return InterfaceResolution.resolved(singleImpl);
28391
26668
  }
28392
26669
  if (implementations.length === 0) {
28393
26670
  const definedInSource = isDefinedInSourceFiles(interfaceName, sourceFiles);
@@ -28395,50 +26672,56 @@ function resolveInterface(interfaceName, project, sourceFilePaths, options) {
28395
26672
  if (definedInSource && options.strict) {
28396
26673
  throw createError(interfaceName, reason2);
28397
26674
  }
28398
- return {
28399
- resolved: false,
26675
+ return InterfaceResolution.unresolved({
28400
26676
  reason: reason2,
28401
26677
  typeDefinedInSource: definedInSource
28402
- };
26678
+ });
28403
26679
  }
28404
26680
  const reason = `Multiple implementations found for ${interfaceName} (${implementations.length}): ${implementations.join(", ")}`;
28405
26681
  if (options.strict) {
28406
26682
  throw createError(interfaceName, reason);
28407
26683
  }
28408
- return {
28409
- resolved: false,
26684
+ return InterfaceResolution.unresolved({
28410
26685
  reason,
28411
26686
  typeDefinedInSource: true
28412
- };
26687
+ });
28413
26688
  }
28414
26689
 
28415
26690
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/call-graph-shared.js
28416
26691
  function getCalledMethodName(callExpr) {
28417
26692
  const expression = callExpr.getExpression();
28418
- return expression.asKindOrThrow(SyntaxKind4.PropertyAccessExpression).getName();
26693
+ return expression.asKindOrThrow(SyntaxKind2.PropertyAccessExpression).getName();
28419
26694
  }
28420
26695
  function resolveTypeThroughInterface(typeName, project, componentIndex, options) {
28421
26696
  const component = componentIndex.getComponentByTypeName(typeName);
28422
26697
  if (component !== void 0) {
28423
- return {
26698
+ return new InterfaceResolutionOutcome({
28424
26699
  component,
28425
26700
  resolvedTypeName: void 0,
28426
26701
  uncertain: void 0
28427
- };
26702
+ });
28428
26703
  }
28429
26704
  const interfaceResult = resolveInterface(typeName, project, options.sourceFilePaths, { strict: options.strict });
28430
26705
  if (interfaceResult.resolved) {
28431
- return {
28432
- component: componentIndex.getComponentByTypeName(interfaceResult.typeName),
28433
- resolvedTypeName: interfaceResult.typeName,
26706
+ const resolvedTypeName = requireInterfaceTypeName(interfaceResult);
26707
+ return new InterfaceResolutionOutcome({
26708
+ component: componentIndex.getComponentByTypeName(resolvedTypeName),
26709
+ resolvedTypeName,
28434
26710
  uncertain: void 0
28435
- };
26711
+ });
28436
26712
  }
28437
- return {
26713
+ return new InterfaceResolutionOutcome({
28438
26714
  component: void 0,
28439
26715
  resolvedTypeName: void 0,
28440
26716
  uncertain: interfaceResult.typeDefinedInSource ? interfaceResult.reason : void 0
28441
- };
26717
+ });
26718
+ }
26719
+ function requireInterfaceTypeName(interfaceResolution) {
26720
+ const typeName = interfaceResolution.typeName;
26721
+ if (typeName === void 0) {
26722
+ throw new TypeError("Expected interface resolution type name");
26723
+ }
26724
+ return typeName;
28442
26725
  }
28443
26726
  function findClassByNameInProject(project, typeName) {
28444
26727
  for (const sourceFile of project.getSourceFiles()) {
@@ -28467,15 +26750,15 @@ function resolveContainerMethod(project, typeName, calledMethodName, componentIn
28467
26750
  function findMethodInProject(project, typeName, methodName) {
28468
26751
  const lookup = findClassByNameInProject(project, typeName);
28469
26752
  if (lookup === void 0) {
28470
- return {
26753
+ return new MethodLookup({
28471
26754
  method: void 0,
28472
26755
  classFound: false
28473
- };
26756
+ });
28474
26757
  }
28475
- return {
26758
+ return new MethodLookup({
28476
26759
  method: lookup.classDecl.getMethod(methodName),
28477
26760
  classFound: true
28478
- };
26761
+ });
28479
26762
  }
28480
26763
 
28481
26764
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/trace-calls.js
@@ -28504,16 +26787,16 @@ function traceCallExpression(callExpr, ctx) {
28504
26787
  if (!typeResult.resolved) {
28505
26788
  return;
28506
26789
  }
28507
- const typeName = typeResult.typeName;
26790
+ const typeName = requireResolvedTypeName(typeResult);
28508
26791
  const calledMethodName = getCalledMethodName(callExpr);
28509
26792
  const outcome = resolveComponentTarget(typeName, calledMethodName, ctx);
28510
26793
  if (outcome.target !== void 0) {
28511
26794
  if (componentIdentity(ctx.sourceComponent) !== componentIdentity(outcome.target)) {
28512
- ctx.results.push({
26795
+ ctx.results.push(new RawLink({
28513
26796
  source: ctx.sourceComponent,
28514
26797
  target: outcome.target,
28515
26798
  callSite: ctx.originCallSite
28516
- });
26799
+ }));
28517
26800
  }
28518
26801
  return;
28519
26802
  }
@@ -28532,15 +26815,22 @@ function traceIntoNonComponent(typeName, calledMethodName, outcome, ctx) {
28532
26815
  return;
28533
26816
  }
28534
26817
  if (!classFound && outcome.uncertain !== void 0) {
28535
- ctx.uncertainResults.push({
26818
+ ctx.uncertainResults.push(new UncertainRawLink({
28536
26819
  source: ctx.sourceComponent,
28537
26820
  reason: outcome.uncertain,
28538
26821
  callSite: ctx.originCallSite
28539
- });
26822
+ }));
26823
+ }
26824
+ }
26825
+ function requireResolvedTypeName(typeResolution) {
26826
+ const typeName = typeResolution.typeName;
26827
+ if (typeName === void 0) {
26828
+ throw new TypeError("Expected resolved type name");
28540
26829
  }
26830
+ return typeName;
28541
26831
  }
28542
26832
  function traceBody(body, ctx) {
28543
- const callExpressions = body.getDescendantsOfKind(SyntaxKind5.CallExpression);
26833
+ const callExpressions = body.getDescendantsOfKind(SyntaxKind3.CallExpression);
28544
26834
  for (const callExpr of callExpressions) {
28545
26835
  traceCallExpression(callExpr, ctx);
28546
26836
  }
@@ -28572,10 +26862,10 @@ function findMethodLevelComponent(project, component) {
28572
26862
  for (const classDecl of sourceFile.getClasses()) {
28573
26863
  const method = classDecl.getMethods().find((m) => m.getStartLineNumber() === component.location.line);
28574
26864
  if (method !== void 0) {
28575
- return {
26865
+ return new MethodLevelTarget({
28576
26866
  classDecl,
28577
26867
  method
28578
- };
26868
+ });
28579
26869
  }
28580
26870
  }
28581
26871
  return void 0;
@@ -28588,12 +26878,34 @@ function findFunctionInProject(project, component) {
28588
26878
  return sourceFile.getFunctions().find((f) => f.getStartLineNumber() === component.location.line);
28589
26879
  }
28590
26880
 
26881
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/extracted-link.js
26882
+ var ExtractedLink = class {
26883
+ source;
26884
+ target;
26885
+ type;
26886
+ _uncertain;
26887
+ sourceLocation;
26888
+ constructor(params) {
26889
+ this.source = params.source;
26890
+ this.target = params.target;
26891
+ this.type = params.type;
26892
+ this._uncertain = params._uncertain;
26893
+ this.sourceLocation = params.sourceLocation;
26894
+ }
26895
+ };
26896
+
28591
26897
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/deduplicate-links.js
26898
+ var MissingSourceLocationError = class extends Error {
26899
+ constructor() {
26900
+ super("Expected sourceLocation on extracted link");
26901
+ this.name = "MissingSourceLocationError";
26902
+ }
26903
+ };
28592
26904
  function linkKey(source, target, type) {
28593
26905
  return `${source}|${target}|${type}`;
28594
26906
  }
28595
26907
  function buildExtractedLink(source, target, type, callSite, repository) {
28596
- return {
26908
+ const link = new ExtractedLink({
28597
26909
  source,
28598
26910
  target,
28599
26911
  type,
@@ -28603,10 +26915,15 @@ function buildExtractedLink(source, target, type, callSite, repository) {
28603
26915
  lineNumber: callSite.lineNumber,
28604
26916
  methodName: callSite.methodName
28605
26917
  }
28606
- };
26918
+ });
26919
+ const sourceLocation = link.sourceLocation;
26920
+ if (sourceLocation === void 0) {
26921
+ throw new MissingSourceLocationError();
26922
+ }
26923
+ return link;
28607
26924
  }
28608
26925
  function buildUncertainLink(source, reason, callSite, repository) {
28609
- return {
26926
+ return new ExtractedLink({
28610
26927
  source,
28611
26928
  target: "_unresolved",
28612
26929
  type: "sync",
@@ -28617,7 +26934,7 @@ function buildUncertainLink(source, reason, callSite, repository) {
28617
26934
  lineNumber: callSite.lineNumber,
28618
26935
  methodName: callSite.methodName
28619
26936
  }
28620
- };
26937
+ });
28621
26938
  }
28622
26939
  function deduplicateLinks(rawLinks, uncertainLinks, repository = "") {
28623
26940
  const seen = /* @__PURE__ */ new Map();
@@ -28628,7 +26945,7 @@ function deduplicateLinks(rawLinks, uncertainLinks, repository = "") {
28628
26945
  const key = linkKey(sourceId, targetId, type);
28629
26946
  const existing = seen.get(key);
28630
26947
  if (existing !== void 0) {
28631
- if (raw.callSite.lineNumber < existing.sourceLocation.lineNumber) {
26948
+ if (raw.callSite.lineNumber < requireSourceLocation(existing).lineNumber) {
28632
26949
  seen.set(key, buildExtractedLink(sourceId, targetId, type, raw.callSite, repository));
28633
26950
  }
28634
26951
  continue;
@@ -28641,6 +26958,24 @@ function deduplicateLinks(rawLinks, uncertainLinks, repository = "") {
28641
26958
  }
28642
26959
  return result;
28643
26960
  }
26961
+ function requireSourceLocation(link) {
26962
+ const sourceLocation = link.sourceLocation;
26963
+ if (sourceLocation === void 0) {
26964
+ throw new MissingSourceLocationError();
26965
+ }
26966
+ if (sourceLocation.lineNumber === void 0) {
26967
+ throw new MissingSourceLocationError();
26968
+ }
26969
+ if (sourceLocation.methodName === void 0) {
26970
+ throw new MissingSourceLocationError();
26971
+ }
26972
+ return {
26973
+ repository: sourceLocation.repository,
26974
+ filePath: sourceLocation.filePath,
26975
+ lineNumber: sourceLocation.lineNumber,
26976
+ methodName: sourceLocation.methodName
26977
+ };
26978
+ }
28644
26979
 
28645
26980
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/call-graph/build-call-graph.js
28646
26981
  function processCallExpression(callExpr, component, methodName, project, componentIndex, rawLinks, uncertainLinks, options) {
@@ -28649,55 +26984,65 @@ function processCallExpression(callExpr, component, methodName, project, compone
28649
26984
  }
28650
26985
  const sourceFile = callExpr.getSourceFile();
28651
26986
  const typeResult = resolveCallExpressionReceiverType(callExpr, sourceFile, { strict: options.strict });
28652
- const currentCallSite = {
26987
+ const currentCallSite = new CallSite({
28653
26988
  filePath: component.location.file,
28654
26989
  lineNumber: callExpr.getStartLineNumber(),
28655
26990
  methodName
28656
- };
26991
+ });
28657
26992
  if (!typeResult.resolved) {
28658
- uncertainLinks.push({
26993
+ uncertainLinks.push(new UncertainRawLink({
28659
26994
  source: component,
28660
- reason: typeResult.reason,
26995
+ reason: typeResult.reason ?? "Receiver type unresolved",
28661
26996
  callSite: currentCallSite
28662
- });
26997
+ }));
28663
26998
  return;
28664
26999
  }
28665
- const typeName = typeResult.typeName;
27000
+ const typeName = requireResolvedTypeName2(typeResult);
28666
27001
  const calledMethodName = getCalledMethodName(callExpr);
28667
- const { component: targetComponent, resolvedTypeName, uncertain } = resolveTypeThroughInterface(typeName, project, componentIndex, options);
27002
+ const interfaceResolution = resolveTypeThroughInterface(typeName, project, componentIndex, options);
27003
+ const targetComponent = interfaceResolution.component;
27004
+ const resolvedTypeName = interfaceResolution.resolvedTypeName;
27005
+ const uncertain = interfaceResolution.uncertain;
28668
27006
  if (targetComponent !== void 0) {
28669
27007
  if (componentIdentity(component) !== componentIdentity(targetComponent)) {
28670
- rawLinks.push({
27008
+ rawLinks.push(new RawLink({
28671
27009
  source: component,
28672
27010
  target: targetComponent,
28673
27011
  callSite: currentCallSite
28674
- });
27012
+ }));
28675
27013
  }
28676
27014
  return;
28677
27015
  }
28678
27016
  const containerTarget = resolveContainerMethod(project, resolvedTypeName ?? typeName, calledMethodName, componentIndex);
28679
27017
  if (containerTarget !== void 0) {
28680
27018
  if (componentIdentity(component) !== componentIdentity(containerTarget)) {
28681
- rawLinks.push({
27019
+ rawLinks.push(new RawLink({
28682
27020
  source: component,
28683
27021
  target: containerTarget,
28684
27022
  callSite: currentCallSite
28685
- });
27023
+ }));
28686
27024
  }
28687
27025
  return;
28688
27026
  }
28689
27027
  traceNonComponent(project, componentIndex, component, resolvedTypeName ?? typeName, calledMethodName, currentCallSite, rawLinks, uncertainLinks, uncertain, options);
28690
27028
  }
27029
+ function requireResolvedTypeName2(typeResolution) {
27030
+ const typeName = typeResolution.typeName;
27031
+ if (typeName === void 0) {
27032
+ throw new TypeError("Expected resolved type name");
27033
+ }
27034
+ return typeName;
27035
+ }
28691
27036
  function processFunction(funcDecl, component, project, componentIndex, rawLinks, uncertainLinks, options) {
28692
27037
  const functionName = funcDecl.getNameOrThrow();
28693
- const callExpressions = funcDecl.getDescendantsOfKind(SyntaxKind6.CallExpression);
27038
+ const callExpressions = funcDecl.getDescendantsOfKind(SyntaxKind4.CallExpression);
28694
27039
  for (const callExpr of callExpressions) {
28695
27040
  processCallExpression(callExpr, component, functionName, project, componentIndex, rawLinks, uncertainLinks, options);
28696
27041
  }
28697
27042
  }
28698
27043
  function processMethod(method, component, project, componentIndex, rawLinks, uncertainLinks, options) {
28699
27044
  const methodName = method.getName();
28700
- const callExpressions = method.getDescendantsOfKind(SyntaxKind6.CallExpression);
27045
+ const callExpressions = method.getDescendantsOfKind(SyntaxKind4.CallExpression);
28701
27046
  for (const callExpr of callExpressions) {
28702
27047
  processCallExpression(callExpr, component, methodName, project, componentIndex, rawLinks, uncertainLinks, options);
28703
27048
  }
@@ -28734,11 +27079,11 @@ function traceNonComponent(project, componentIndex, source, typeName, calledMeth
28734
27079
  return;
28735
27080
  }
28736
27081
  if (!classFound && interfaceUncertainty !== void 0) {
28737
- uncertainLinks.push({
27082
+ uncertainLinks.push(new UncertainRawLink({
28738
27083
  source,
28739
27084
  reason: interfaceUncertainty,
28740
27085
  callSite
28741
- });
27086
+ }));
28742
27087
  }
28743
27088
  }
28744
27089
 
@@ -28785,13 +27130,13 @@ function handleMissingMetadata(publisher, metadataKey, options) {
28785
27130
  reason: `published event type in "${metadataKey}" metadata is missing or invalid`
28786
27131
  });
28787
27132
  }
28788
- return {
27133
+ return new ExtractedLink({
28789
27134
  source: componentIdentity(publisher),
28790
27135
  target: "_unresolved",
28791
27136
  type: "async",
28792
27137
  sourceLocation: toSourceLocation(publisher, options.repository),
28793
27138
  _uncertain: `event publisher "${publisher.name}" is missing required "${metadataKey}" metadata`
28794
- };
27139
+ });
28795
27140
  }
28796
27141
  function resolvePublishTarget(publisher, publishedEventType, events, options) {
28797
27142
  const matchingEvents = events.filter((e) => e.metadata[EVENT_NAME_FIELD] === publishedEventType);
@@ -28801,7 +27146,7 @@ function resolvePublishTarget(publisher, publishedEventType, events, options) {
28801
27146
  if (matchingEvents.length > 1) {
28802
27147
  return [handleAmbiguousMatch(publisher, publishedEventType, matchingEvents.length, options)];
28803
27148
  }
28804
- return matchingEvents.map((event) => ({
27149
+ return matchingEvents.map((event) => new ExtractedLink({
28805
27150
  source: componentIdentity(publisher),
28806
27151
  target: componentIdentity(event),
28807
27152
  type: "async",
@@ -28817,13 +27162,13 @@ function handleAmbiguousMatch(publisher, publishedEventType, matchCount, options
28817
27162
  reason: `published event "${publishedEventType}" matches ${matchCount} Event components (ambiguous)`
28818
27163
  });
28819
27164
  }
28820
- return {
27165
+ return new ExtractedLink({
28821
27166
  source: componentIdentity(publisher),
28822
27167
  target: "_unresolved",
28823
27168
  type: "async",
28824
27169
  sourceLocation: toSourceLocation(publisher, options.repository),
28825
27170
  _uncertain: `ambiguous: ${matchCount} events match published event type: ${publishedEventType}`
28826
- };
27171
+ });
28827
27172
  }
28828
27173
  function handleNoMatch(publisher, publishedEventType, options) {
28829
27174
  if (options.strict) {
@@ -28834,13 +27179,13 @@ function handleNoMatch(publisher, publishedEventType, options) {
28834
27179
  reason: `published event "${publishedEventType}" does not match any Event component`
28835
27180
  });
28836
27181
  }
28837
- return {
27182
+ return new ExtractedLink({
28838
27183
  source: componentIdentity(publisher),
28839
27184
  target: "_unresolved",
28840
27185
  type: "async",
28841
27186
  sourceLocation: toSourceLocation(publisher, options.repository),
28842
27187
  _uncertain: `no event found for published event type: ${publishedEventType}`
28843
- };
27188
+ });
28844
27189
  }
28845
27190
 
28846
27191
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/async-detection/detect-subscribe-connections.js
@@ -28858,7 +27203,7 @@ function resolveSubscription(handler, eventName, events, options, repository) {
28858
27203
  if (matchingEvents.length > 1) {
28859
27204
  return [handleAmbiguousMatch2(handler, eventName, matchingEvents.length, options, repository)];
28860
27205
  }
28861
- return matchingEvents.map((event) => ({
27206
+ return matchingEvents.map((event) => new ExtractedLink({
28862
27207
  source: componentIdentity(event),
28863
27208
  target: componentIdentity(handler),
28864
27209
  type: "async",
@@ -28874,13 +27219,13 @@ function handleAmbiguousMatch2(handler, eventName, matchCount, options, reposito
28874
27219
  reason: `subscribed event "${eventName}" matches ${matchCount} Event components (ambiguous)`
28875
27220
  });
28876
27221
  }
28877
- return {
27222
+ return new ExtractedLink({
28878
27223
  source: "_unresolved",
28879
27224
  target: componentIdentity(handler),
28880
27225
  type: "async",
28881
27226
  sourceLocation: toSourceLocation(handler, repository),
28882
27227
  _uncertain: `ambiguous: ${matchCount} events match subscribed event name: ${eventName}`
28883
- };
27228
+ });
28884
27229
  }
28885
27230
  function handleNoMatch2(handler, eventName, options, repository) {
28886
27231
  if (options.strict) {
@@ -28891,13 +27236,13 @@ function handleNoMatch2(handler, eventName, options, repository) {
28891
27236
  reason: `subscribed event "${eventName}" does not match any Event component`
28892
27237
  });
28893
27238
  }
28894
- return {
27239
+ return new ExtractedLink({
28895
27240
  source: "_unresolved",
28896
27241
  target: componentIdentity(handler),
28897
27242
  type: "async",
28898
27243
  sourceLocation: toSourceLocation(handler, repository),
28899
27244
  _uncertain: `no event found for subscribed event name: ${eventName}`
28900
- };
27245
+ });
28901
27246
  }
28902
27247
  function getSubscribedEvents(handler) {
28903
27248
  const raw = handler.metadata[SUBSCRIBED_EVENTS_FIELD];
@@ -28907,13 +27252,57 @@ function getSubscribedEvents(handler) {
28907
27252
  return raw.filter((item) => typeof item === "string");
28908
27253
  }
28909
27254
 
27255
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/connection-detection-values.js
27256
+ function assignLinkCollections(target, params) {
27257
+ target.links = params.links;
27258
+ target.externalLinks = params.externalLinks;
27259
+ target.timings = params.timings;
27260
+ }
27261
+ var PerModuleTimings = class {
27262
+ callGraphMs;
27263
+ setupMs;
27264
+ constructor(params) {
27265
+ this.callGraphMs = params.callGraphMs;
27266
+ this.setupMs = params.setupMs;
27267
+ }
27268
+ };
27269
+ var PerModuleDetectionResult = class {
27270
+ constructor(params) {
27271
+ assignLinkCollections(this, params);
27272
+ }
27273
+ };
27274
+ var CrossModuleTimings = class {
27275
+ asyncDetectionMs;
27276
+ constructor(params) {
27277
+ this.asyncDetectionMs = params.asyncDetectionMs;
27278
+ }
27279
+ };
27280
+ var CrossModuleDetectionResult = class {
27281
+ links;
27282
+ timings;
27283
+ constructor(params) {
27284
+ this.links = params.links;
27285
+ this.timings = params.timings;
27286
+ }
27287
+ };
27288
+
27289
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/http-link-resolution-result.js
27290
+ var HttpLinkResolutionResult = class {
27291
+ links;
27292
+ externalLinks;
27293
+ constructor(params) {
27294
+ this.links = params.links;
27295
+ this.externalLinks = params.externalLinks;
27296
+ }
27297
+ };
27298
+
28910
27299
  // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/resolve-http-links.js
28911
27300
  function resolveHttpLinks(links, components, httpLinkConfigs) {
28912
27301
  if (httpLinkConfigs.length === 0) {
28913
- return {
27302
+ return new HttpLinkResolutionResult({
28914
27303
  links: [...links],
28915
27304
  externalLinks: []
28916
- };
27305
+ });
28917
27306
  }
28918
27307
  const resolvedCustomTypes = new Set(httpLinkConfigs.map((config2) => config2.fromCustomType));
28919
27308
  const componentsByIdentity = indexComponentsByIdentity(components);
@@ -28940,15 +27329,18 @@ function resolveHttpLinks(links, components, httpLinkConfigs) {
28940
27329
  externalLinks.push(toExternalLink(link, domainName, targetComponent, config2.matchApiBy));
28941
27330
  continue;
28942
27331
  }
28943
- resolvedLinks.push({
28944
- ...link,
28945
- target: componentIdentity(matchedApi)
28946
- });
27332
+ resolvedLinks.push(new ExtractedLink({
27333
+ source: link.source,
27334
+ target: componentIdentity(matchedApi),
27335
+ ...link.type !== void 0 && { type: link.type },
27336
+ ...link._uncertain !== void 0 && { _uncertain: link._uncertain },
27337
+ ...link.sourceLocation !== void 0 && { sourceLocation: link.sourceLocation }
27338
+ }));
28947
27339
  }
28948
- return {
27340
+ return new HttpLinkResolutionResult({
28949
27341
  links: resolvedLinks,
28950
27342
  externalLinks
28951
- };
27343
+ });
28952
27344
  }
28953
27345
  function stripResolvedCustomTypes(components, httpLinkConfigs, resolvedLinks) {
28954
27346
  const resolvedCustomTypes = new Set(httpLinkConfigs.map((config2) => config2.fromCustomType));
@@ -29019,76 +27411,368 @@ function toExternalLink(link, serviceName, targetComponent, matchApiBy) {
29019
27411
  ...link.sourceLocation !== void 0 && { sourceLocation: link.sourceLocation }
29020
27412
  };
29021
27413
  }
29022
-
29023
- // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/detect-connections.js
29024
- function computeFilteredFilePaths(project, moduleGlobs, globMatcher) {
29025
- return project.getSourceFiles().map((sf) => sf.getFilePath()).filter((filePath) => moduleGlobs.some((glob) => globMatcher(filePath, glob)));
27414
+
27415
+ // ../riviere-extract-ts/dist/features/extraction/domain/connection-detection/detect-connections.js
27416
+ function deduplicateCrossStrategy(links) {
27417
+ const seen = /* @__PURE__ */ new Map();
27418
+ for (const link of links) {
27419
+ const key = `${link.source}|${link.target}|${link.type}`;
27420
+ const existing = seen.get(key);
27421
+ if (existing !== void 0) {
27422
+ if (existing._uncertain !== void 0 && link._uncertain === void 0) {
27423
+ seen.set(key, link);
27424
+ }
27425
+ continue;
27426
+ }
27427
+ seen.set(key, link);
27428
+ }
27429
+ return [...seen.values()];
27430
+ }
27431
+ function detectPerModuleConnections(project, components, options) {
27432
+ const setupStart = performance.now();
27433
+ const visibleComponents = options.allComponents ?? components;
27434
+ const componentIndex = new ComponentIndex(visibleComponents);
27435
+ const sourceFilePaths = options.sourceFilePaths;
27436
+ const setupMs = performance.now() - setupStart;
27437
+ const strict = options.allowIncomplete !== true;
27438
+ const repository = options.repository;
27439
+ const callGraphStart = performance.now();
27440
+ const syncLinks = buildCallGraph(project, components, componentIndex, new CallGraphOptions({
27441
+ strict,
27442
+ sourceFilePaths,
27443
+ repository
27444
+ }));
27445
+ const callGraphMs = performance.now() - callGraphStart;
27446
+ const httpLinkConfigs = options.httpLinks ?? [];
27447
+ const resolved = resolveHttpLinks(syncLinks, visibleComponents, httpLinkConfigs);
27448
+ return new PerModuleDetectionResult({
27449
+ links: resolved.links,
27450
+ externalLinks: resolved.externalLinks,
27451
+ timings: new PerModuleTimings({
27452
+ callGraphMs,
27453
+ setupMs
27454
+ })
27455
+ });
27456
+ }
27457
+ function detectCrossModuleConnections(allComponents, options) {
27458
+ const strict = options.allowIncomplete !== true;
27459
+ const repository = options.repository;
27460
+ const asyncOptions = new AsyncDetectionOptions({
27461
+ strict,
27462
+ repository
27463
+ });
27464
+ const asyncStart = performance.now();
27465
+ const publishLinks = detectEventPublisherConnections(allComponents, options.eventPublishers ?? [], asyncOptions);
27466
+ const subscribeLinks = detectSubscribeConnections(allComponents, asyncOptions);
27467
+ const asyncDetectionMs = performance.now() - asyncStart;
27468
+ return new CrossModuleDetectionResult({
27469
+ links: [...publishLinks, ...subscribeLinks],
27470
+ timings: new CrossModuleTimings({ asyncDetectionMs })
27471
+ });
27472
+ }
27473
+
27474
+ // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/enriched-component.js
27475
+ var EnrichedComponent = class {
27476
+ type;
27477
+ name;
27478
+ location;
27479
+ domain;
27480
+ module;
27481
+ metadata;
27482
+ _missing;
27483
+ constructor(params) {
27484
+ this.type = params.type;
27485
+ this.name = params.name;
27486
+ this.location = params.location;
27487
+ this.domain = params.domain;
27488
+ this.module = params.module;
27489
+ this.metadata = params.metadata;
27490
+ this._missing = params._missing;
27491
+ }
27492
+ };
27493
+ var EnrichmentFailure = class {
27494
+ component;
27495
+ field;
27496
+ error;
27497
+ constructor(params) {
27498
+ this.component = params.component;
27499
+ this.field = params.field;
27500
+ this.error = params.error;
27501
+ }
27502
+ };
27503
+ var EnrichmentResult = class {
27504
+ components;
27505
+ failures;
27506
+ constructor(params) {
27507
+ this.components = params.components;
27508
+ this.failures = params.failures;
27509
+ }
27510
+ };
27511
+
27512
+ // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule-generic.js
27513
+ import { SyntaxKind as SyntaxKind5 } from "ts-morph";
27514
+ function getInterfaceTypeArgs(classDecl, interfaceName) {
27515
+ const implementsClause = classDecl.getImplements();
27516
+ for (const impl of implementsClause) {
27517
+ const expression = impl.getExpression();
27518
+ if (expression.getText() === interfaceName) {
27519
+ return impl.getTypeArguments();
27520
+ }
27521
+ }
27522
+ const extendsClause = classDecl.getExtends();
27523
+ if (extendsClause === void 0) {
27524
+ return void 0;
27525
+ }
27526
+ const baseClass = classDecl.getBaseClass();
27527
+ if (baseClass === void 0)
27528
+ return void 0;
27529
+ return getInterfaceTypeArgs(baseClass, interfaceName);
27530
+ }
27531
+ function extractTypeNames(typeNode) {
27532
+ if (typeNode.getKind() === SyntaxKind5.UnionType) {
27533
+ const unionType = typeNode.asKindOrThrow(SyntaxKind5.UnionType);
27534
+ return unionType.getTypeNodes().map((t) => t.getText());
27535
+ }
27536
+ return [typeNode.getText()];
27537
+ }
27538
+ function evaluateFromGenericArgRule(rule, classDecl) {
27539
+ const { interface: interfaceName, position, transform: transform2 } = rule.fromGenericArg;
27540
+ const sourceFile = classDecl.getSourceFile();
27541
+ const location = {
27542
+ filePath: sourceFile.getFilePath(),
27543
+ line: classDecl.getStartLineNumber()
27544
+ };
27545
+ const typeArgs = getInterfaceTypeArgs(classDecl, interfaceName);
27546
+ if (typeArgs === void 0) {
27547
+ throw new ExtractionError(`Class '${classDecl.getName() ?? "anonymous"}' does not implement interface '${interfaceName}'`, location.filePath, location.line);
27548
+ }
27549
+ const typeArg = typeArgs[position];
27550
+ if (typeArg === void 0) {
27551
+ throw new ExtractionError(`Position ${position} out of bounds. Interface has ${typeArgs.length} type argument(s)`, location.filePath, location.line);
27552
+ }
27553
+ if (typeArg.getKind() === SyntaxKind5.TypeReference) {
27554
+ const typeRef = typeArg.asKindOrThrow(SyntaxKind5.TypeReference);
27555
+ const typeName = typeRef.getTypeName();
27556
+ if (typeName.getKind() === SyntaxKind5.Identifier) {
27557
+ const classTypeParams = classDecl.getTypeParameters();
27558
+ const paramName = typeName.getText();
27559
+ const isTypeParam = classTypeParams.some((p) => p.getName() === paramName);
27560
+ if (isTypeParam) {
27561
+ throw new ExtractionError(`Generic argument at position ${position} is type parameter '${paramName}', expected concrete type`, location.filePath, location.line);
27562
+ }
27563
+ }
27564
+ }
27565
+ const typeNames = extractTypeNames(typeArg);
27566
+ if (transform2 === void 0) {
27567
+ return new ExtractionResult({ value: typeNames });
27568
+ }
27569
+ return new ExtractionResult({ value: typeNames.map((name) => applyTransforms(name, transform2)) });
27570
+ }
27571
+
27572
+ // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/evaluate-extraction-rule.js
27573
+ import { SyntaxKind as SyntaxKind6 } from "ts-morph";
27574
+ function literal2(value) {
27575
+ return new ExtractionResult({ value });
27576
+ }
27577
+ function evaluateLiteralRule(rule) {
27578
+ return literal2(rule.literal);
27579
+ }
27580
+ function evaluateFromClassNameRule(rule, classDecl) {
27581
+ const className = classDecl.getName();
27582
+ if (!className) {
27583
+ const filePath = classDecl.getSourceFile().getFilePath();
27584
+ const lineNumber = classDecl.getStartLineNumber();
27585
+ throw new ExtractionError("Expected class name, got undefined", filePath, lineNumber);
27586
+ }
27587
+ if (rule.fromClassName === true) {
27588
+ return new ExtractionResult({ value: className });
27589
+ }
27590
+ const transform2 = rule.fromClassName.transform;
27591
+ if (transform2 === void 0) {
27592
+ return new ExtractionResult({ value: className });
27593
+ }
27594
+ return new ExtractionResult({ value: applyTransforms(className, transform2) });
27595
+ }
27596
+ function evaluateFromMethodNameRule(rule, methodDecl) {
27597
+ const methodName = methodDecl.getName();
27598
+ if (rule.fromMethodName === true) {
27599
+ return new ExtractionResult({ value: methodName });
27600
+ }
27601
+ const transform2 = rule.fromMethodName.transform;
27602
+ if (transform2 === void 0) {
27603
+ return new ExtractionResult({ value: methodName });
27604
+ }
27605
+ return new ExtractionResult({ value: applyTransforms(methodName, transform2) });
27606
+ }
27607
+ function evaluateFromFilePathRule(rule, filePath) {
27608
+ const pattern = rule.fromFilePath.pattern;
27609
+ const capture = rule.fromFilePath.capture;
27610
+ const transform2 = rule.fromFilePath.transform;
27611
+ const regex = new RegExp(pattern);
27612
+ const match = regex.exec(filePath);
27613
+ if (match === null) {
27614
+ throw new ExtractionError(`Pattern '${pattern}' did not match file path '${filePath}'`, filePath, 0);
27615
+ }
27616
+ const capturedValue = match[capture];
27617
+ if (capturedValue === void 0) {
27618
+ throw new ExtractionError(`Capture group ${capture} out of bounds. Pattern has ${match.length - 1} capture groups`, filePath, 0);
27619
+ }
27620
+ if (transform2 === void 0) {
27621
+ return new ExtractionResult({ value: capturedValue });
27622
+ }
27623
+ return new ExtractionResult({ value: applyTransforms(capturedValue, transform2) });
27624
+ }
27625
+ function findPropertyInHierarchy(classDecl, propertyName, isStatic) {
27626
+ const properties = isStatic ? classDecl.getStaticProperties() : classDecl.getInstanceProperties();
27627
+ const property = properties.find((p) => p.getName() === propertyName);
27628
+ if (property !== void 0 && "getInitializer" in property) {
27629
+ const sourceFile = classDecl.getSourceFile();
27630
+ return {
27631
+ initializer: property.getInitializer(),
27632
+ filePath: sourceFile.getFilePath(),
27633
+ line: property.getStartLineNumber()
27634
+ };
27635
+ }
27636
+ if (classDecl.getExtends() === void 0) {
27637
+ return void 0;
27638
+ }
27639
+ const baseClass = classDecl.getBaseClass();
27640
+ if (baseClass === void 0)
27641
+ return void 0;
27642
+ return findPropertyInHierarchy(baseClass, propertyName, isStatic);
27643
+ }
27644
+ function evaluateFromPropertyRule(rule, classDecl) {
27645
+ const name = rule.fromProperty.name;
27646
+ const kind = rule.fromProperty.kind;
27647
+ const transform2 = rule.fromProperty.transform;
27648
+ const isStatic = kind === "static";
27649
+ const propertyInfo = findPropertyInHierarchy(classDecl, name, isStatic);
27650
+ if (propertyInfo === void 0) {
27651
+ const sourceFile = classDecl.getSourceFile();
27652
+ throw new ExtractionError(`Property '${name}' not found on class '${classDecl.getName() ?? "anonymous"}'`, sourceFile.getFilePath(), classDecl.getStartLineNumber());
27653
+ }
27654
+ const literalResult = extractLiteralValue(propertyInfo.initializer, propertyInfo.filePath, propertyInfo.line);
27655
+ if (transform2 === void 0) {
27656
+ return new ExtractionResult({ value: literalResult.value });
27657
+ }
27658
+ if (typeof literalResult.value !== "string") {
27659
+ return new ExtractionResult({ value: literalResult.value });
27660
+ }
27661
+ return new ExtractionResult({ value: applyTransforms(literalResult.value, transform2) });
27662
+ }
27663
+ function getDecoratorLocation(decorator) {
27664
+ const sourceFile = decorator.getSourceFile();
27665
+ return {
27666
+ filePath: sourceFile.getFilePath(),
27667
+ line: decorator.getStartLineNumber()
27668
+ };
27669
+ }
27670
+ function extractPositionalArg(decorator, position) {
27671
+ const args = decorator.getArguments();
27672
+ const location = getDecoratorLocation(decorator);
27673
+ if (args.length === 0) {
27674
+ throw new ExtractionError(`Decorator '@${decorator.getName()}' has no arguments`, location.filePath, location.line);
27675
+ }
27676
+ const arg = args[position];
27677
+ if (arg === void 0) {
27678
+ throw new ExtractionError(`Argument position ${position} out of bounds. Decorator has ${args.length} argument(s)`, location.filePath, location.line);
27679
+ }
27680
+ if (arg.getKind() !== SyntaxKind6.StringLiteral) {
27681
+ throw new ExtractionError(`Expected string literal at position ${position}, got ${arg.getKindName()}`, location.filePath, location.line);
27682
+ }
27683
+ return arg.asKindOrThrow(SyntaxKind6.StringLiteral).getLiteralValue();
27684
+ }
27685
+ function throwNoArguments(decorator, location) {
27686
+ throw new ExtractionError(`Decorator '@${decorator.getName()}' has no arguments`, location.filePath, location.line);
29026
27687
  }
29027
- function deduplicateCrossStrategy(links) {
29028
- const seen = /* @__PURE__ */ new Map();
29029
- for (const link of links) {
29030
- const key = `${link.source}|${link.target}|${link.type}`;
29031
- const existing = seen.get(key);
29032
- if (existing !== void 0) {
29033
- if (existing._uncertain !== void 0 && link._uncertain === void 0) {
29034
- seen.set(key, link);
29035
- }
29036
- continue;
29037
- }
29038
- seen.set(key, link);
27688
+ function getFirstArgument(decorator, location) {
27689
+ const args = decorator.getArguments();
27690
+ const firstArg = args[0];
27691
+ if (firstArg === void 0) {
27692
+ throwNoArguments(decorator, location);
29039
27693
  }
29040
- return [...seen.values()];
27694
+ return firstArg;
29041
27695
  }
29042
- function detectPerModuleConnections(project, components, options, globMatcher) {
29043
- const setupStart = performance.now();
29044
- const visibleComponents = options.allComponents ?? components;
29045
- const componentIndex = new ComponentIndex(visibleComponents);
29046
- const sourceFilePaths = computeFilteredFilePaths(project, options.moduleGlobs, globMatcher);
29047
- const setupMs = performance.now() - setupStart;
29048
- const strict = options.allowIncomplete !== true;
29049
- const repository = options.repository;
29050
- const callGraphStart = performance.now();
29051
- const syncLinks = buildCallGraph(project, components, componentIndex, {
29052
- strict,
29053
- sourceFilePaths,
29054
- repository
29055
- });
29056
- const callGraphMs = performance.now() - callGraphStart;
29057
- const httpLinkConfigs = options.httpLinks ?? [];
29058
- const resolved = resolveHttpLinks(syncLinks, visibleComponents, httpLinkConfigs);
29059
- return {
29060
- links: resolved.links,
29061
- externalLinks: resolved.externalLinks,
29062
- timings: {
29063
- callGraphMs,
29064
- setupMs
27696
+ function extractNamedArg(decorator, name) {
27697
+ const location = getDecoratorLocation(decorator);
27698
+ const firstArg = getFirstArgument(decorator, location);
27699
+ if (firstArg.getKind() !== SyntaxKind6.ObjectLiteralExpression) {
27700
+ throw new ExtractionError(`Expected object literal argument, got ${firstArg.getKindName()}`, location.filePath, location.line);
27701
+ }
27702
+ const objectLiteral = firstArg.asKindOrThrow(SyntaxKind6.ObjectLiteralExpression);
27703
+ const property = objectLiteral.getProperty(name);
27704
+ if (property === void 0) {
27705
+ throw new ExtractionError(`Property '${name}' not found in decorator argument`, location.filePath, location.line);
27706
+ }
27707
+ if (!("getInitializer" in property)) {
27708
+ throw new ExtractionError(`Property '${name}' has no initializer`, location.filePath, location.line);
27709
+ }
27710
+ const initializer3 = property.getInitializer();
27711
+ if (initializer3?.getKind() !== SyntaxKind6.StringLiteral) {
27712
+ throw new ExtractionError(`Expected string literal for property '${name}'`, location.filePath, location.line);
27713
+ }
27714
+ return initializer3.asKindOrThrow(SyntaxKind6.StringLiteral).getLiteralValue();
27715
+ }
27716
+ function evaluateFromDecoratorArgRule(rule, decorator) {
27717
+ const decoratorName = rule.fromDecoratorArg.decorator;
27718
+ const position = rule.fromDecoratorArg.position;
27719
+ const name = rule.fromDecoratorArg.name;
27720
+ const transform2 = rule.fromDecoratorArg.transform;
27721
+ if (decoratorName !== void 0 && decorator.getName() !== decoratorName) {
27722
+ const location = getDecoratorLocation(decorator);
27723
+ throw new ExtractionError(`Expected decorator '@${decoratorName}', got '@${decorator.getName()}'`, location.filePath, location.line);
27724
+ }
27725
+ const extractValue = () => {
27726
+ if (position !== void 0) {
27727
+ return extractPositionalArg(decorator, position);
27728
+ }
27729
+ if (!name) {
27730
+ const location = getDecoratorLocation(decorator);
27731
+ throw new ExtractionError("Expected name parameter when position is undefined", location.filePath, location.line);
29065
27732
  }
27733
+ return extractNamedArg(decorator, name);
29066
27734
  };
27735
+ const value = extractValue();
27736
+ if (transform2 === void 0) {
27737
+ return new ExtractionResult({ value });
27738
+ }
27739
+ return new ExtractionResult({ value: applyTransforms(value, transform2) });
29067
27740
  }
29068
- function detectCrossModuleConnections(allComponents, options) {
29069
- const strict = options.allowIncomplete !== true;
29070
- const repository = options.repository;
29071
- const asyncOptions = {
29072
- strict,
29073
- repository
29074
- };
29075
- const asyncStart = performance.now();
29076
- const publishLinks = detectEventPublisherConnections(allComponents, options.eventPublishers ?? [], asyncOptions);
29077
- const subscribeLinks = detectSubscribeConnections(allComponents, asyncOptions);
29078
- const asyncDetectionMs = performance.now() - asyncStart;
29079
- return {
29080
- links: [...publishLinks, ...subscribeLinks],
29081
- timings: { asyncDetectionMs }
27741
+ function evaluateFromClassDecoratorArgRule(rule, methodDecl) {
27742
+ const classDecl = methodDecl.getParentIfKind(SyntaxKind6.ClassDeclaration);
27743
+ if (classDecl === void 0) {
27744
+ const sourceFile = methodDecl.getSourceFile();
27745
+ throw new ExtractionError(`Expected method '${methodDecl.getName()}' to be declared inside a class`, sourceFile.getFilePath(), methodDecl.getStartLineNumber());
27746
+ }
27747
+ const classDecorator = classDecl.getDecorators().find((decorator) => decorator.getName() === rule.fromClassDecoratorArg.decorator);
27748
+ if (classDecorator === void 0) {
27749
+ const sourceFile = classDecl.getSourceFile();
27750
+ throw new ExtractionError(`Decorator '@${rule.fromClassDecoratorArg.decorator}' not found on containing class '${classDecl.getName() ?? "anonymous"}'`, sourceFile.getFilePath(), classDecl.getStartLineNumber());
27751
+ }
27752
+ const fromClassDecoratorArg = rule.fromClassDecoratorArg;
27753
+ const fromDecoratorArgRule = {
27754
+ decorator: fromClassDecoratorArg.decorator,
27755
+ ...fromClassDecoratorArg.position === void 0 ? {} : { position: fromClassDecoratorArg.position },
27756
+ ...fromClassDecoratorArg.name === void 0 ? {} : { name: fromClassDecoratorArg.name },
27757
+ ...fromClassDecoratorArg.transform === void 0 ? {} : { transform: fromClassDecoratorArg.transform }
29082
27758
  };
27759
+ return evaluateFromDecoratorArgRule({ fromDecoratorArg: fromDecoratorArgRule }, classDecorator);
27760
+ }
27761
+ function evaluateFromDecoratorNameRule(rule, decorator) {
27762
+ const decoratorName = decorator.getName();
27763
+ if (rule.fromDecoratorName === true) {
27764
+ return new ExtractionResult({ value: decoratorName });
27765
+ }
27766
+ const mapping = rule.fromDecoratorName.mapping;
27767
+ const transform2 = rule.fromDecoratorName.transform;
27768
+ const mappedValue = mapping?.[decoratorName] ?? decoratorName;
27769
+ if (transform2 === void 0) {
27770
+ return new ExtractionResult({ value: mappedValue });
27771
+ }
27772
+ return new ExtractionResult({ value: applyTransforms(mappedValue, transform2) });
29083
27773
  }
29084
27774
 
29085
27775
  // ../riviere-extract-ts/dist/features/extraction/domain/value-extraction/enrich-components.js
29086
- import { posix as posix2 } from "node:path";
29087
- function findMatchingModule2(filePath, modules, globMatcher, configDir) {
29088
- const normalized = filePath.replaceAll(/\\+/g, "/");
29089
- const pathToMatch = posix2.relative(configDir.replaceAll(/\\+/g, "/"), normalized);
29090
- return modules.find((m) => globMatcher(pathToMatch, posix2.join(m.path, m.glob)));
29091
- }
29092
27776
  function getBuiltInRule(module, componentType) {
29093
27777
  const ruleMap = {
29094
27778
  api: module.api,
@@ -29223,9 +27907,9 @@ function evaluateMethodRule(rule, draft, project) {
29223
27907
  const typeName = param.getTypeNode()?.getText() ?? "unknown";
29224
27908
  const transform2 = rule.fromParameterType.transform;
29225
27909
  if (transform2 === void 0) {
29226
- return { value: typeName };
27910
+ return new ExtractionResult({ value: typeName });
29227
27911
  }
29228
- return { value: applyTransforms(typeName, transform2) };
27912
+ return new ExtractionResult({ value: applyTransforms(typeName, transform2) });
29229
27913
  }
29230
27914
  return void 0;
29231
27915
  }
@@ -29253,10 +27937,15 @@ function evaluateRule(rule, draft, project) {
29253
27937
  }
29254
27938
  function componentWithEmptyMetadata(draft) {
29255
27939
  return {
29256
- enriched: {
29257
- ...draft,
29258
- metadata: {}
29259
- },
27940
+ enriched: new EnrichedComponent({
27941
+ type: draft.type,
27942
+ name: draft.name,
27943
+ location: draft.location,
27944
+ domain: draft.domain,
27945
+ module: draft.module,
27946
+ metadata: {},
27947
+ _missing: void 0
27948
+ }),
29260
27949
  failures: []
29261
27950
  };
29262
27951
  }
@@ -29275,11 +27964,11 @@ function extractMetadataFields(extractBlock, draft, project) {
29275
27964
  if (shouldIgnoreMissingMetadataField(draft, fieldName, extractionRule, errorMessage)) {
29276
27965
  continue;
29277
27966
  }
29278
- failures.push({
27967
+ failures.push(new EnrichmentFailure({
29279
27968
  component: draft,
29280
27969
  field: fieldName,
29281
27970
  error: errorMessage
29282
- });
27971
+ }));
29283
27972
  missing.push(fieldName);
29284
27973
  }
29285
27974
  }
@@ -29289,40 +27978,38 @@ function extractMetadataFields(extractBlock, draft, project) {
29289
27978
  failures
29290
27979
  };
29291
27980
  }
29292
- function enrichSingleComponent(draft, config2, project, globMatcher, configDir) {
29293
- const module = findMatchingModule2(draft.location.file, config2.modules, globMatcher, configDir);
29294
- if (module === void 0) {
29295
- return componentWithEmptyMetadata(draft);
29296
- }
27981
+ function enrichSingleComponent(draft, module, project) {
29297
27982
  const detectionRule = findDetectionRule(module, draft.type);
29298
27983
  if (detectionRule?.extract === void 0) {
29299
27984
  return componentWithEmptyMetadata(draft);
29300
27985
  }
29301
27986
  const extracted = extractMetadataFields(detectionRule.extract, draft, project);
29302
- const enriched = {
29303
- ...draft,
29304
- metadata: extracted.metadata
29305
- };
29306
- if (extracted.missing.length > 0) {
29307
- enriched._missing = extracted.missing;
29308
- }
27987
+ const enriched = new EnrichedComponent({
27988
+ type: draft.type,
27989
+ name: draft.name,
27990
+ location: draft.location,
27991
+ domain: draft.domain,
27992
+ module: draft.module,
27993
+ metadata: extracted.metadata,
27994
+ _missing: extracted.missing.length > 0 ? extracted.missing : void 0
27995
+ });
29309
27996
  return {
29310
27997
  enriched,
29311
27998
  failures: extracted.failures
29312
27999
  };
29313
28000
  }
29314
- function enrichComponents(draftComponents, config2, project, globMatcher, configDir) {
28001
+ function enrichComponents(draftComponents, module, project) {
29315
28002
  const allComponents = [];
29316
28003
  const allFailures = [];
29317
28004
  for (const draft of draftComponents) {
29318
- const result = enrichSingleComponent(draft, config2, project, globMatcher, configDir);
28005
+ const result = enrichSingleComponent(draft, module, project);
29319
28006
  allComponents.push(result.enriched);
29320
28007
  allFailures.push(...result.failures);
29321
28008
  }
29322
- return {
28009
+ return new EnrichmentResult({
29323
28010
  components: allComponents,
29324
28011
  failures: allFailures
29325
- };
28012
+ });
29326
28013
  }
29327
28014
 
29328
28015
  // ../riviere-extract-config/dist/validation.js
@@ -30499,7 +29186,6 @@ function loadDraftComponentsFromFile(filePath) {
30499
29186
  }
30500
29187
 
30501
29188
  // src/features/extract/domain/extraction-project.ts
30502
- import { posix as posix3 } from "node:path";
30503
29189
  var OrphanedDraftComponentError = class extends Error {
30504
29190
  constructor(orphanedModules, knownModules) {
30505
29191
  super(
@@ -30509,8 +29195,7 @@ var OrphanedDraftComponentError = class extends Error {
30509
29195
  }
30510
29196
  };
30511
29197
  var ExtractionProject = class {
30512
- constructor(configDir, moduleContexts, resolvedConfig, repositoryName, draftComponents = []) {
30513
- this.configDir = configDir;
29198
+ constructor(moduleContexts, resolvedConfig, repositoryName, draftComponents = []) {
30514
29199
  this.moduleContexts = moduleContexts;
30515
29200
  this.resolvedConfig = resolvedConfig;
30516
29201
  this.repositoryName = repositoryName;
@@ -30518,13 +29203,7 @@ var ExtractionProject = class {
30518
29203
  }
30519
29204
  extractDraftComponents(options) {
30520
29205
  const draftComponents = this.moduleContexts.flatMap(
30521
- (moduleContext) => extractComponents(
30522
- moduleContext.project,
30523
- moduleContext.files,
30524
- this.resolvedConfig,
30525
- matchesGlob,
30526
- this.configDir
30527
- )
29206
+ (moduleContext) => extractComponents(moduleContext.project, moduleContext.files, moduleContext.module)
30528
29207
  );
30529
29208
  if (!options.includeConnections) {
30530
29209
  return {
@@ -30597,18 +29276,13 @@ var ExtractionProject = class {
30597
29276
  if (moduleComponents.length === 0) {
30598
29277
  continue;
30599
29278
  }
30600
- const result = detectPerModuleConnections(
30601
- moduleContext.project,
30602
- moduleComponents,
30603
- {
30604
- allComponents: enrichedComponents,
30605
- allowIncomplete,
30606
- moduleGlobs: [posix3.join(moduleContext.module.path, moduleContext.module.glob)],
30607
- httpLinks,
30608
- repository: this.repositoryName
30609
- },
30610
- matchesGlob
30611
- );
29279
+ const result = detectPerModuleConnections(moduleContext.project, moduleComponents, {
29280
+ allComponents: enrichedComponents,
29281
+ allowIncomplete,
29282
+ httpLinks,
29283
+ repository: this.repositoryName,
29284
+ sourceFilePaths: moduleContext.files
29285
+ });
30612
29286
  links.push(...result.links);
30613
29287
  externalLinks.push(...result.externalLinks);
30614
29288
  timings.push({
@@ -30647,13 +29321,7 @@ var ExtractionProject = class {
30647
29321
  if (moduleDrafts.length === 0) {
30648
29322
  continue;
30649
29323
  }
30650
- const result = enrichComponents(
30651
- moduleDrafts,
30652
- this.resolvedConfig,
30653
- moduleContext.project,
30654
- matchesGlob,
30655
- this.configDir
30656
- );
29324
+ const result = enrichComponents(moduleDrafts, moduleContext.module, moduleContext.project);
30657
29325
  components.push(...result.components);
30658
29326
  for (const failure14 of result.failures) {
30659
29327
  failedFieldSet.add(failure14.field);
@@ -30692,42 +29360,17 @@ function groupDraftsByModule(drafts) {
30692
29360
  return grouped;
30693
29361
  }
30694
29362
 
30695
- // src/features/extract/infra/external-clients/ts-morph/create-configured-project.ts
30696
- import { existsSync as existsSync2 } from "node:fs";
30697
- import { resolve as resolve2 } from "node:path";
30698
- import { Project as Project2 } from "ts-morph";
30699
- function createConfiguredProject(configDir, skipTsConfig) {
30700
- if (skipTsConfig) {
30701
- return new Project2();
30702
- }
30703
- const tsConfigPath = resolve2(configDir, "tsconfig.json");
30704
- if (!existsSync2(tsConfigPath)) {
30705
- return new Project2();
30706
- }
30707
- return new Project2({
30708
- tsConfigFilePath: tsConfigPath,
30709
- skipAddingFilesFromTsConfig: true
30710
- });
30711
- }
30712
-
30713
- // src/features/extract/infra/external-clients/ts-morph/find-module-tsconfig-dir.ts
30714
- import { existsSync as existsSync3 } from "node:fs";
30715
- import { resolve as resolve3 } from "node:path";
30716
- function findModuleTsConfigDir(configDir, modulePath) {
30717
- const moduleTsConfigPath = resolve3(configDir, modulePath, "tsconfig.json");
30718
- if (existsSync3(moduleTsConfigPath)) {
30719
- return resolve3(configDir, modulePath);
30720
- }
30721
- return configDir;
30722
- }
30723
-
30724
- // src/features/extract/infra/persistence/extraction-project/extraction-project-repository.ts
30725
- var ModuleRefNotFoundError = class extends Error {
30726
- constructor(ref, filePath) {
30727
- super(`Cannot resolve module reference '${ref}'. File not found: ${filePath}`);
30728
- this.name = "ModuleRefNotFoundError";
30729
- }
30730
- };
29363
+ // src/features/extract/infra/external-clients/extraction-config/load-extended-module.ts
29364
+ import {
29365
+ existsSync as existsSync2,
29366
+ readFileSync as readFileSync3
29367
+ } from "node:fs";
29368
+ import { createRequire } from "node:module";
29369
+ import {
29370
+ dirname as dirname2,
29371
+ resolve as resolve2
29372
+ } from "node:path";
29373
+ import { parse as parseYaml } from "yaml";
30731
29374
  var ConfigSchemaValidationError = class extends Error {
30732
29375
  constructor(source, details) {
30733
29376
  super(`Invalid extended config in '${source}': ${details}`);
@@ -30757,6 +29400,121 @@ var ConfigFileNotFoundError = class extends Error {
30757
29400
  }
30758
29401
  };
30759
29402
  var NOT_USED = { notUsed: true };
29403
+ function loadExtendedModule(params) {
29404
+ const filePath = resolveExtendedConfigPath(params.source, params.configDir);
29405
+ if (!existsSync2(filePath)) {
29406
+ throw new ConfigFileNotFoundError(params.source, filePath);
29407
+ }
29408
+ const content = readFileSync3(filePath, "utf-8");
29409
+ return parseExtendedConfigContent(
29410
+ content,
29411
+ params.source,
29412
+ dirname2(filePath),
29413
+ params.resolveConfigWithExtends
29414
+ );
29415
+ }
29416
+ function resolveExtendedConfigPath(source, configDir) {
29417
+ return isPackageReference(source) ? resolvePackagePath(source, configDir) : resolve2(configDir, source);
29418
+ }
29419
+ function isPackageReference(source) {
29420
+ return !source.startsWith(".") && !source.startsWith("/");
29421
+ }
29422
+ function resolvePackagePath(packageName, configDir) {
29423
+ const require2 = createRequire(resolve2(configDir, "package.json"));
29424
+ try {
29425
+ const packageJsonPath = require2.resolve(`${packageName}/package.json`);
29426
+ const packageDir = dirname2(packageJsonPath);
29427
+ const defaultConfigPath = resolve2(packageDir, "src/default-extraction.config.json");
29428
+ if (existsSync2(defaultConfigPath)) {
29429
+ return defaultConfigPath;
29430
+ }
29431
+ throw new PackageResolveError(packageName);
29432
+ } catch {
29433
+ throw new PackageResolveError(packageName);
29434
+ }
29435
+ }
29436
+ function parseExtendedConfigContent(content, source, configDir, resolveConfigWithExtends) {
29437
+ const parsed = parseYaml(content);
29438
+ if (hasModulesArray(parsed)) {
29439
+ return resolveFirstModuleFromConfig(parsed, source, configDir, resolveConfigWithExtends);
29440
+ }
29441
+ if (isTopLevelRulesConfig(parsed)) {
29442
+ return topLevelRulesToModule(parsed);
29443
+ }
29444
+ const preview = JSON.stringify(parsed, null, 2).slice(0, 200);
29445
+ throw new InvalidConfigFormatError(source, preview);
29446
+ }
29447
+ function resolveFirstModuleFromConfig(parsed, source, configDir, resolveConfigWithExtends) {
29448
+ if (parsed.modules.length === 0) {
29449
+ throw new ConfigSchemaValidationError(source, "Config has empty modules array");
29450
+ }
29451
+ try {
29452
+ const config2 = parseExtractionConfig(parsed);
29453
+ const [first] = resolveConfigWithExtends(config2, configDir).modules;
29454
+ if (first === void 0) {
29455
+ throw new ConfigSchemaValidationError(source, "Config has empty modules array");
29456
+ }
29457
+ return first;
29458
+ } catch (error48) {
29459
+ throw new ConfigSchemaValidationError(source, String(error48));
29460
+ }
29461
+ }
29462
+ function hasModulesArray(value) {
29463
+ return typeof value === "object" && value !== null && "modules" in value && Array.isArray(value.modules);
29464
+ }
29465
+ function isTopLevelRulesConfig(value) {
29466
+ return typeof value === "object" && value !== null && !Array.isArray(value) && !("modules" in value);
29467
+ }
29468
+ function topLevelRulesToModule(parsed) {
29469
+ return {
29470
+ name: "extended",
29471
+ path: ".",
29472
+ glob: "**",
29473
+ api: parsed.api ?? NOT_USED,
29474
+ useCase: parsed.useCase ?? NOT_USED,
29475
+ domainOp: parsed.domainOp ?? NOT_USED,
29476
+ event: parsed.event ?? NOT_USED,
29477
+ eventHandler: parsed.eventHandler ?? NOT_USED,
29478
+ ui: parsed.ui ?? NOT_USED
29479
+ };
29480
+ }
29481
+
29482
+ // src/features/extract/infra/external-clients/ts-morph/create-configured-project.ts
29483
+ import { existsSync as existsSync3 } from "node:fs";
29484
+ import { resolve as resolve3 } from "node:path";
29485
+ import { Project as Project2 } from "ts-morph";
29486
+ function createConfiguredProject(configDir, skipTsConfig) {
29487
+ if (skipTsConfig) {
29488
+ return new Project2();
29489
+ }
29490
+ const tsConfigPath = resolve3(configDir, "tsconfig.json");
29491
+ if (!existsSync3(tsConfigPath)) {
29492
+ return new Project2();
29493
+ }
29494
+ return new Project2({
29495
+ tsConfigFilePath: tsConfigPath,
29496
+ skipAddingFilesFromTsConfig: true
29497
+ });
29498
+ }
29499
+
29500
+ // src/features/extract/infra/external-clients/ts-morph/find-module-tsconfig-dir.ts
29501
+ import { existsSync as existsSync4 } from "node:fs";
29502
+ import { resolve as resolve4 } from "node:path";
29503
+ function findModuleTsConfigDir(configDir, modulePath) {
29504
+ const moduleTsConfigPath = resolve4(configDir, modulePath, "tsconfig.json");
29505
+ if (existsSync4(moduleTsConfigPath)) {
29506
+ return resolve4(configDir, modulePath);
29507
+ }
29508
+ return configDir;
29509
+ }
29510
+
29511
+ // src/features/extract/infra/persistence/extraction-project/extraction-project-repository.ts
29512
+ var ModuleRefNotFoundError = class extends Error {
29513
+ constructor(ref, filePath) {
29514
+ super(`Cannot resolve module reference '${ref}'. File not found: ${filePath}`);
29515
+ this.name = "ModuleRefNotFoundError";
29516
+ }
29517
+ };
30760
29518
  var ExtractionProjectRepository = class {
30761
29519
  loadFromChangedProject(params) {
30762
29520
  const parsedConfigState = this.loadParsedConfigState(params.configPath);
@@ -30792,15 +29550,15 @@ var ExtractionProjectRepository = class {
30792
29550
  return this.createExtractionProject(parsedConfigState, sourceFilePaths, params.useTsConfig);
30793
29551
  }
30794
29552
  loadParsedConfigState(configPath) {
30795
- if (!existsSync4(configPath)) {
29553
+ if (!existsSync5(configPath)) {
30796
29554
  throw new ConfigValidationError(
30797
29555
  "CONFIG_NOT_FOUND" /* ConfigNotFound */,
30798
29556
  `Config file not found: ${configPath}`
30799
29557
  );
30800
29558
  }
30801
- const content = readFileSync3(configPath, "utf-8");
29559
+ const content = readFileSync4(configPath, "utf-8");
30802
29560
  const parsed = this.parseConfigFile(content);
30803
- const configDir = dirname2(resolve4(configPath));
29561
+ const configDir = dirname3(resolve5(configPath));
30804
29562
  const expanded = this.expandModuleRefs(parsed, configDir);
30805
29563
  if (!isValidExtractionConfig(expanded)) {
30806
29564
  const validationResult = validateExtractionConfig(expanded);
@@ -30812,12 +29570,12 @@ ${formatValidationErrors2(validationResult.errors)}`
30812
29570
  }
30813
29571
  return {
30814
29572
  configDir,
30815
- resolvedConfig: resolveConfig(expanded, this.createExtendedConfigLoader(configDir))
29573
+ resolvedConfig: this.resolveConfigWithExtends(expanded, configDir)
30816
29574
  };
30817
29575
  }
30818
29576
  parseConfigFile(content) {
30819
29577
  try {
30820
- const parsed = parseYaml(content);
29578
+ const parsed = parseYaml2(content);
30821
29579
  return parsed;
30822
29580
  } catch (error48) {
30823
29581
  throw new ConfigValidationError(
@@ -30846,93 +29604,66 @@ ${formatValidationErrors2(validationResult.errors)}`
30846
29604
  if (!this.isModuleRef(item)) {
30847
29605
  return item;
30848
29606
  }
30849
- const refPath = resolve4(configDir, item.$ref);
30850
- if (!existsSync4(refPath)) {
29607
+ const refPath = resolve5(configDir, item.$ref);
29608
+ if (!existsSync5(refPath)) {
30851
29609
  throw new ModuleRefNotFoundError(item.$ref, refPath);
30852
29610
  }
30853
- const content = readFileSync3(refPath, "utf-8");
30854
- const parsed = parseYaml(content);
29611
+ const content = readFileSync4(refPath, "utf-8");
29612
+ const parsed = parseYaml2(content);
30855
29613
  return parsed;
30856
29614
  }
30857
- createExtendedConfigLoader(configDir) {
30858
- return (source) => {
30859
- const filePath = this.resolveExtendedConfigPath(source, configDir);
30860
- return this.loadExtendedConfigFile(filePath, source);
30861
- };
30862
- }
30863
- resolveExtendedConfigPath(source, configDir) {
30864
- return this.isPackageReference(source) ? this.resolvePackagePath(source, configDir) : resolve4(configDir, source);
30865
- }
30866
- isPackageReference(source) {
30867
- return !source.startsWith(".") && !source.startsWith("/");
29615
+ resolveConfigWithExtends(config2, configDir) {
29616
+ return resolveConfig({
29617
+ ...config2,
29618
+ modules: config2.modules.map(
29619
+ (moduleConfig) => this.resolveModuleConfig(moduleConfig, configDir)
29620
+ )
29621
+ });
30868
29622
  }
30869
- resolvePackagePath(packageName, configDir) {
30870
- const require2 = createRequire(resolve4(configDir, "package.json"));
30871
- try {
30872
- const packageJsonPath = require2.resolve(`${packageName}/package.json`);
30873
- const packageDir = dirname2(packageJsonPath);
30874
- const defaultConfigPath = resolve4(packageDir, "src/default-extraction.config.json");
30875
- if (existsSync4(defaultConfigPath)) {
30876
- return defaultConfigPath;
29623
+ resolveModuleConfig(moduleConfig, configDir) {
29624
+ const extendsSource = moduleConfig.extends;
29625
+ if (extendsSource === void 0) {
29626
+ const [resolvedModule] = resolveConfig({ modules: [moduleConfig] }).modules;
29627
+ if (resolvedModule === void 0) {
29628
+ throw new TypeError(`Expected resolved module for '${moduleConfig.name}'`);
30877
29629
  }
30878
- throw new PackageResolveError(packageName);
30879
- } catch {
30880
- throw new PackageResolveError(packageName);
30881
- }
30882
- }
30883
- loadExtendedConfigFile(filePath, source) {
30884
- if (!existsSync4(filePath)) {
30885
- throw new ConfigFileNotFoundError(source, filePath);
30886
- }
30887
- const content = readFileSync3(filePath, "utf-8");
30888
- return this.parseExtendedConfigContent(content, source);
30889
- }
30890
- parseExtendedConfigContent(content, source) {
30891
- const parsed = parseYaml(content);
30892
- if (this.hasModulesArray(parsed)) {
30893
- return this.resolveFirstModuleFromConfig(parsed, source);
29630
+ return resolvedModule;
30894
29631
  }
30895
- if (this.isTopLevelRulesConfig(parsed)) {
30896
- return this.topLevelRulesToModule(parsed);
30897
- }
30898
- const preview = JSON.stringify(parsed, null, 2).slice(0, 200);
30899
- throw new InvalidConfigFormatError(source, preview);
29632
+ const baseModule = loadExtendedModule({
29633
+ configDir,
29634
+ source: extendsSource,
29635
+ resolveConfigWithExtends: (config2, nextConfigDir) => this.resolveConfigWithExtends(config2, nextConfigDir)
29636
+ });
29637
+ const mergedCustomTypes = this.mergeCustomTypes(
29638
+ baseModule.customTypes,
29639
+ moduleConfig.customTypes
29640
+ );
29641
+ return {
29642
+ name: moduleConfig.name,
29643
+ domain: moduleConfig.domain,
29644
+ path: moduleConfig.path,
29645
+ glob: moduleConfig.glob,
29646
+ ...moduleConfig.modules !== void 0 && { modules: moduleConfig.modules },
29647
+ api: moduleConfig.api ?? baseModule.api,
29648
+ useCase: moduleConfig.useCase ?? baseModule.useCase,
29649
+ domainOp: moduleConfig.domainOp ?? baseModule.domainOp,
29650
+ event: moduleConfig.event ?? baseModule.event,
29651
+ eventHandler: moduleConfig.eventHandler ?? baseModule.eventHandler,
29652
+ ui: moduleConfig.ui ?? baseModule.ui,
29653
+ ...mergedCustomTypes !== void 0 && { customTypes: mergedCustomTypes }
29654
+ };
30900
29655
  }
30901
- resolveFirstModuleFromConfig(parsed, source) {
30902
- if (parsed.modules.length === 0) {
30903
- throw new ConfigSchemaValidationError(source, "Config has empty modules array");
30904
- }
30905
- try {
30906
- const config2 = parseExtractionConfig(parsed);
30907
- const [first] = resolveConfig(config2).modules;
30908
- if (first === void 0) {
30909
- throw new ConfigSchemaValidationError(source, "Config has empty modules array");
30910
- }
30911
- return first;
30912
- } catch (error48) {
30913
- const message = error48 instanceof Error ? error48.message : String(error48);
30914
- throw new ConfigSchemaValidationError(source, message);
29656
+ mergeCustomTypes(base, local) {
29657
+ if (base === void 0 && local === void 0) {
29658
+ return void 0;
30915
29659
  }
30916
- }
30917
- isTopLevelRulesConfig(value) {
30918
- return typeof value === "object" && value !== null && !Array.isArray(value) && !("modules" in value);
30919
- }
30920
- topLevelRulesToModule(parsed) {
30921
29660
  return {
30922
- name: "extended",
30923
- path: ".",
30924
- glob: "**",
30925
- api: parsed.api ?? NOT_USED,
30926
- useCase: parsed.useCase ?? NOT_USED,
30927
- domainOp: parsed.domainOp ?? NOT_USED,
30928
- event: parsed.event ?? NOT_USED,
30929
- eventHandler: parsed.eventHandler ?? NOT_USED,
30930
- ui: parsed.ui ?? NOT_USED
29661
+ ...base,
29662
+ ...local
30931
29663
  };
30932
29664
  }
30933
29665
  createExtractionProject(parsedConfigState, sourceFilePaths, useTsConfig, draftComponents = []) {
30934
29666
  return new ExtractionProject(
30935
- parsedConfigState.configDir,
30936
29667
  this.createModuleContexts(
30937
29668
  parsedConfigState.configDir,
30938
29669
  parsedConfigState.resolvedConfig,
@@ -30946,10 +29677,10 @@ ${formatValidationErrors2(validationResult.errors)}`
30946
29677
  }
30947
29678
  resolveSourceFilePaths(parsedConfigState) {
30948
29679
  const sourceFilePaths = parsedConfigState.resolvedConfig.modules.flatMap(
30949
- (module) => globSync(posix4.join(module.path, module.glob), { cwd: parsedConfigState.configDir })
30950
- ).map((filePath) => resolve4(parsedConfigState.configDir, filePath));
29680
+ (module) => globSync(posix.join(module.path, module.glob), { cwd: parsedConfigState.configDir })
29681
+ ).map((filePath) => resolve5(parsedConfigState.configDir, filePath));
30951
29682
  if (sourceFilePaths.length === 0) {
30952
- const patterns = parsedConfigState.resolvedConfig.modules.map((module) => posix4.join(module.path, module.glob)).join(", ");
29683
+ const patterns = parsedConfigState.resolvedConfig.modules.map((module) => posix.join(module.path, module.glob)).join(", ");
30953
29684
  throw new ConfigValidationError(
30954
29685
  "VALIDATION_ERROR" /* ValidationError */,
30955
29686
  `No files matched extraction patterns: ${patterns}
@@ -30964,25 +29695,25 @@ Config directory: ${parsedConfigState.configDir}`
30964
29695
  for (const warning of result.warnings) {
30965
29696
  console.error(warning);
30966
29697
  }
30967
- const changedAbsolute = new Set(result.files.map((filePath) => resolve4(filePath)));
29698
+ const changedAbsolute = new Set(result.files.map((filePath) => resolve5(filePath)));
30968
29699
  return allSourceFiles.filter((filePath) => changedAbsolute.has(filePath));
30969
29700
  }
30970
29701
  resolveSelectedSourceFilePaths(allSourceFiles, requestedFiles) {
30971
- const missingFiles = requestedFiles.filter((filePath) => !existsSync4(resolve4(filePath)));
29702
+ const missingFiles = requestedFiles.filter((filePath) => !existsSync5(resolve5(filePath)));
30972
29703
  if (missingFiles.length > 0) {
30973
29704
  throw new ConfigValidationError(
30974
29705
  "VALIDATION_ERROR" /* ValidationError */,
30975
29706
  `Files not found: ${missingFiles.join(", ")}`
30976
29707
  );
30977
29708
  }
30978
- const requestedAbsolute = new Set(requestedFiles.map((filePath) => resolve4(filePath)));
29709
+ const requestedAbsolute = new Set(requestedFiles.map((filePath) => resolve5(filePath)));
30979
29710
  return allSourceFiles.filter((filePath) => requestedAbsolute.has(filePath));
30980
29711
  }
30981
29712
  createModuleContexts(configDir, resolvedConfig, sourceFilePaths, useTsConfig) {
30982
29713
  const sourceFileSet = new Set(sourceFilePaths);
30983
29714
  return resolvedConfig.modules.map((module) => {
30984
- const allModuleFiles = globSync(posix4.join(module.path, module.glob), { cwd: configDir }).map(
30985
- (filePath) => resolve4(configDir, filePath)
29715
+ const allModuleFiles = globSync(posix.join(module.path, module.glob), { cwd: configDir }).map(
29716
+ (filePath) => resolve5(configDir, filePath)
30986
29717
  );
30987
29718
  const moduleFiles = allModuleFiles.filter((filePath) => sourceFileSet.has(filePath));
30988
29719
  const moduleConfigDir = findModuleTsConfigDir(configDir, module.path);
@@ -31363,7 +30094,7 @@ function createExtractCommand(extractDraftComponents, enrichDraftComponents) {
31363
30094
  }
31364
30095
 
31365
30096
  // src/features/query/infra/persistence/riviere-query-repository.ts
31366
- import { readFileSync as readFileSync4 } from "node:fs";
30097
+ import { readFileSync as readFileSync5 } from "node:fs";
31367
30098
  import { join as join2 } from "node:path";
31368
30099
  var DEFAULT_GRAPH_PATH3 = ".riviere/graph.json";
31369
30100
  var RiviereQueryRepository = class {
@@ -31372,7 +30103,7 @@ var RiviereQueryRepository = class {
31372
30103
  if (!fileExists(graphPath)) {
31373
30104
  throw new GraphNotFoundError(graphPath);
31374
30105
  }
31375
- const content = readFileSync4(graphPath, "utf-8");
30106
+ const content = readFileSync5(graphPath, "utf-8");
31376
30107
  try {
31377
30108
  const parsed = JSON.parse(content);
31378
30109
  return RiviereQuery.fromJSON(parsed);
@@ -31466,7 +30197,7 @@ var TraceFlow = class {
31466
30197
  return {
31467
30198
  message: error48.message,
31468
30199
  success: false,
31469
- suggestions: matches.map((match2) => match2.component.id)
30200
+ suggestions: matches.map((match) => match.component.id)
31470
30201
  };
31471
30202
  }
31472
30203
  }
@@ -31749,8 +30480,8 @@ export {
31749
30480
  /* istanbul ignore next -- @preserve: Methods in object literals have non-class parents; predicate correctly returns false */
31750
30481
  /* istanbul ignore else -- @preserve: false branch is unreachable; FindTarget is exhaustive */
31751
30482
  /* istanbul ignore next -- @preserve: unreachable with valid FindTarget type; defensive fallback */
31752
- /* v8 ignore next -- @preserve: getExtends() !== undefined guarantees getBaseClass() returns a value */
31753
30483
  /* istanbul ignore next -- @preserve: defensive guard; resolvedCustomTypes.has guarantees config exists */
30484
+ /* v8 ignore next -- @preserve: getExtends() !== undefined guarantees getBaseClass() returns a value */
31754
30485
  /* v8 ignore next -- @preserve: decorators.length > 0 guarantees first decorator exists */
31755
30486
  /* istanbul ignore next -- @preserve: catch always receives Error instances from ExtractionError */
31756
30487
  /* v8 ignore start -- @preserve: default executor delegates to execFileSync; tested via CLI integration */