@cmflow/atlas 3.7.0 → 3.8.0

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.
@@ -4,13 +4,13 @@ const __filename = __atlasFileURLToPath(import.meta.url);
4
4
  import { n as __require, r as __toESM, t as __commonJSMin } from "../rolldown-runtime-CGR6nZuH.mjs";
5
5
  import { a as isCancel, c as userConfig$1, i as select, n as atlasLogger, o as getUserConfig, r as progress, s as setUserConfig, t as taskProgressService } from "../taskProgressService-DAEpEqsT.mjs";
6
6
  import { a as resolveModulePath, c as filterAnalysisFiles, d as globby, i as matchesRouteSelector, l as shouldKeepAnalysisFile, n as generateBackendTopologyArtifactsInWorkers, o as inferBackendNameFromFile, s as isKnownBackendType, u as normalizeFilePath } from "../routeBackendTopologyService-_-yZSfG8.mjs";
7
- import { a as loadOpenApiDocument, i as extractOpenApiOutputProperties, r as extractOpenApiInputProperties, t as require_dist$1 } from "../dist-D8VumL0r.mjs";
7
+ import { c as loadOpenApiDocument, i as extractOpenApiOutputProperties, o as transformTypeFrom, r as extractOpenApiInputProperties, s as pickPropertyMetadata, t as require_dist$1 } from "../dist-DIU2ATkt.mjs";
8
8
  import { n as require_auth_errors, r as require_token_error, t as require_token_util } from "../token-util-Dnzm6rU4.mjs";
9
9
  import { readFileSync } from "node:fs";
10
10
  import path, { resolve } from "node:path";
11
11
  import { Node, Project, SyntaxKind } from "ts-morph";
12
12
  import fsPromises from "node:fs/promises";
13
- import { createHash } from "node:crypto";
13
+ import { createHash, randomUUID } from "node:crypto";
14
14
 
15
15
  //#region node_modules/commander/lib/error.js
16
16
  var require_error = /* @__PURE__ */ __commonJSMin(((exports) => {
@@ -2948,18 +2948,12 @@ async function createClient() {
2948
2948
  //#region src/services/directus/queries/deleteOrphanedPropertyLinks.ts
2949
2949
  const DIRECTUS_DELETE_WORKERS = 2;
2950
2950
  async function deleteOrphanedPropertyLinks(client, orphanedLinks) {
2951
- const links = [...orphanedLinks.input.map((link) => ({
2952
- collection: "route_input_properties_backend_properties",
2953
- id: link.id
2954
- })), ...orphanedLinks.output.map((link) => ({
2955
- collection: "route_output_properties_backend_properties",
2956
- id: link.id
2957
- }))];
2951
+ const links = orphanedLinks.links;
2958
2952
  let nextIndex = 0;
2959
2953
  await Promise.all(Array.from({ length: Math.min(DIRECTUS_DELETE_WORKERS, links.length) }, async () => {
2960
2954
  while (nextIndex < links.length) {
2961
2955
  const link = links[nextIndex++];
2962
- await client.request(r$1(link.collection, link.id));
2956
+ await client.request(r$1("route_properties_backend_properties", link.id));
2963
2957
  }
2964
2958
  }));
2965
2959
  return links.length;
@@ -2968,12 +2962,8 @@ async function deleteOrphanedPropertyLinks(client, orphanedLinks) {
2968
2962
  //#endregion
2969
2963
  //#region src/services/directus/queries/findOrphanedPropertyLinks.ts
2970
2964
  async function findOrphanedPropertyLinks(client) {
2971
- const [inputProperties, outputProperties, backendProperties, inputLinks, outputLinks] = await Promise.all([
2972
- client.request(n$1("route_input_properties", {
2973
- fields: ["id"],
2974
- limit: -1
2975
- })),
2976
- client.request(n$1("route_output_properties", {
2965
+ const [routeProperties, backendProperties, links] = await Promise.all([
2966
+ client.request(n$1("route_properties", {
2977
2967
  fields: ["id"],
2978
2968
  limit: -1
2979
2969
  })),
@@ -2981,31 +2971,19 @@ async function findOrphanedPropertyLinks(client) {
2981
2971
  fields: ["id"],
2982
2972
  limit: -1
2983
2973
  })),
2984
- client.request(n$1("route_input_properties_backend_properties", {
2985
- fields: [
2986
- "id",
2987
- "route_input_properties_id",
2988
- "backend_properties_id"
2989
- ],
2990
- limit: -1
2991
- })),
2992
- client.request(n$1("route_output_properties_backend_properties", {
2974
+ client.request(n$1("route_properties_backend_properties", {
2993
2975
  fields: [
2994
2976
  "id",
2995
- "route_output_properties_id",
2977
+ "route_properties_id",
2996
2978
  "backend_properties_id"
2997
2979
  ],
2998
2980
  limit: -1
2999
2981
  }))
3000
2982
  ]);
3001
2983
  const ids = (items) => new Set(items.map((item) => String(item.id)));
3002
- const inputIds = ids(inputProperties);
3003
- const outputIds = ids(outputProperties);
2984
+ const routePropertyIds = ids(routeProperties);
3004
2985
  const backendIds = ids(backendProperties);
3005
- return {
3006
- input: inputLinks.filter((link) => !inputIds.has(String(link.route_input_properties_id)) || !backendIds.has(String(link.backend_properties_id))),
3007
- output: outputLinks.filter((link) => !outputIds.has(String(link.route_output_properties_id)) || !backendIds.has(String(link.backend_properties_id)))
3008
- };
2986
+ return { links: links.filter((link) => !routePropertyIds.has(String(link.route_properties_id)) || !backendIds.has(String(link.backend_properties_id))) };
3009
2987
  }
3010
2988
 
3011
2989
  //#endregion
@@ -3015,7 +2993,7 @@ async function cleanDirectusOrphanedPropertyLinks(options) {
3015
2993
  const client = await createClient();
3016
2994
  taskProgressService.report("Finding orphaned property links");
3017
2995
  const orphanedLinks = await findOrphanedPropertyLinks(client);
3018
- const orphanedCount = orphanedLinks.input.length + orphanedLinks.output.length;
2996
+ const orphanedCount = orphanedLinks.links.length;
3019
2997
  if (options.dryRun) {
3020
2998
  taskProgressService.report(`${orphanedCount} orphaned property links found (dry-run)`);
3021
2999
  return {
@@ -3050,17 +3028,17 @@ async function cleanupOrphanedPropertyLinks(client) {
3050
3028
  //#endregion
3051
3029
  //#region src/services/directus/queries/ensureInputLink.ts
3052
3030
  async function ensureInputLink(client, inputPropertyId, backendPropertyId) {
3053
- const [existing] = await client.request(n$1("route_input_properties_backend_properties", {
3031
+ const [existing] = await client.request(n$1("route_properties_backend_properties", {
3054
3032
  filter: {
3055
- route_input_properties_id: { _eq: inputPropertyId },
3033
+ route_properties_id: { _eq: inputPropertyId },
3056
3034
  backend_properties_id: { _eq: backendPropertyId }
3057
3035
  },
3058
3036
  fields: ["id"],
3059
3037
  limit: 1
3060
3038
  }));
3061
3039
  if (existing) return false;
3062
- await client.request(n$2("route_input_properties_backend_properties", {
3063
- route_input_properties_id: inputPropertyId,
3040
+ await client.request(n$2("route_properties_backend_properties", {
3041
+ route_properties_id: inputPropertyId,
3064
3042
  backend_properties_id: backendPropertyId
3065
3043
  }));
3066
3044
  return true;
@@ -3069,17 +3047,17 @@ async function ensureInputLink(client, inputPropertyId, backendPropertyId) {
3069
3047
  //#endregion
3070
3048
  //#region src/services/directus/queries/ensureOutputLink.ts
3071
3049
  async function ensureOutputLink(client, outputPropertyId, backendPropertyId) {
3072
- const [existing] = await client.request(n$1("route_output_properties_backend_properties", {
3050
+ const [existing] = await client.request(n$1("route_properties_backend_properties", {
3073
3051
  filter: {
3074
- route_output_properties_id: { _eq: outputPropertyId },
3052
+ route_properties_id: { _eq: outputPropertyId },
3075
3053
  backend_properties_id: { _eq: backendPropertyId }
3076
3054
  },
3077
3055
  fields: ["id"],
3078
3056
  limit: 1
3079
3057
  }));
3080
3058
  if (existing) return false;
3081
- await client.request(n$2("route_output_properties_backend_properties", {
3082
- route_output_properties_id: outputPropertyId,
3059
+ await client.request(n$2("route_properties_backend_properties", {
3060
+ route_properties_id: outputPropertyId,
3083
3061
  backend_properties_id: backendPropertyId
3084
3062
  }));
3085
3063
  return true;
@@ -3092,7 +3070,8 @@ async function loadDirectusReferenceData(client) {
3092
3070
  filter: { type: { _in: [
3093
3071
  "backend",
3094
3072
  "in_type",
3095
- "out_type"
3073
+ "out_type",
3074
+ "data_type"
3096
3075
  ] } },
3097
3076
  fields: [
3098
3077
  "id",
@@ -3113,9 +3092,10 @@ async function loadDirectusReferenceData(client) {
3113
3092
  const inTypeIds = /* @__PURE__ */ new Map();
3114
3093
  const outTypeIds = /* @__PURE__ */ new Map();
3115
3094
  const documentIds = /* @__PURE__ */ new Map();
3095
+ const dataTypeIds = /* @__PURE__ */ new Map();
3116
3096
  for (const value of values) {
3117
3097
  const normalizedKeys = [normalizeLookupKey(value.id), normalizeLookupKey(value.label)];
3118
- const target = value.type === "backend" ? backendIds : value.type === "in_type" ? inTypeIds : outTypeIds;
3098
+ const target = value.type === "backend" ? backendIds : value.type === "in_type" ? inTypeIds : value.type === "out_type" ? outTypeIds : dataTypeIds;
3119
3099
  for (const key of normalizedKeys) target.set(key, value.id);
3120
3100
  }
3121
3101
  for (const value of documentValues) {
@@ -3126,7 +3106,8 @@ async function loadDirectusReferenceData(client) {
3126
3106
  backendIds,
3127
3107
  inTypeIds,
3128
3108
  outTypeIds,
3129
- documentIds
3109
+ documentIds,
3110
+ dataTypeIds
3130
3111
  };
3131
3112
  }
3132
3113
 
@@ -3354,6 +3335,13 @@ function dedupeByKey(items, keyFn) {
3354
3335
  return [...map.values()];
3355
3336
  }
3356
3337
 
3338
+ //#endregion
3339
+ //#region src/utils/path/isArrayPath.ts
3340
+ /** Whether a property path denotes an array element (e.g. `offers[].id`). */
3341
+ function isArrayPath(path) {
3342
+ return path.includes("[]");
3343
+ }
3344
+
3357
3345
  //#endregion
3358
3346
  //#region src/services/codeAnalysisService.ts
3359
3347
  const userConfig = new Proxy({}, { get: (_target, property) => Reflect.get(getUserConfig(), property) });
@@ -4457,15 +4445,26 @@ function resolveApiPropertySource(document, property, direction, matches = []) {
4457
4445
  return match ? `${match.sourceFile}:${match.line}` : matches[0] ? backendFieldSource(matches[0]) : document.routeFile || null;
4458
4446
  }
4459
4447
  function ensureBackendRouteRecord(backendRoutesByKey, document, candidate) {
4460
- const key = stableKey(document.key, candidate.backend, candidate.route);
4448
+ const isDocument = "document" in candidate;
4449
+ const sourceId = isDocument ? candidate.document : candidate.route;
4450
+ const key = stableKey(document.key, candidate.backend, sourceId);
4461
4451
  const existing = backendRoutesByKey.get(key);
4462
4452
  if (existing) return existing;
4463
- const created = {
4453
+ const created = isDocument ? {
4454
+ key,
4455
+ backend: candidate.backend,
4456
+ route_key: document.key,
4457
+ resource_type: "document",
4458
+ document: candidate.document,
4459
+ source_file: candidate.sourceFile,
4460
+ provenance: "code_analysis"
4461
+ } : {
4464
4462
  key,
4465
4463
  backend: candidate.backend,
4466
4464
  route_key: document.key,
4467
4465
  resource_type: "http",
4468
- route: `${candidate.method || "CALL"} ${candidate.route}`,
4466
+ method: candidate.method || void 0,
4467
+ route: candidate.route,
4469
4468
  source_file: candidate.sourceFile,
4470
4469
  provenance: "code_analysis"
4471
4470
  };
@@ -4483,6 +4482,7 @@ function toBackendMapping(document, match) {
4483
4482
  document: resolved.document,
4484
4483
  field: resolved.field,
4485
4484
  description: resolved.description,
4485
+ ...pickPropertyMetadata(resolved),
4486
4486
  source_file: backendFieldSource(match),
4487
4487
  confidence: match.confidence,
4488
4488
  mapper_type: match.mapperType,
@@ -4492,15 +4492,20 @@ function toBackendMapping(document, match) {
4492
4492
  return {
4493
4493
  backend: match.backend,
4494
4494
  method: backendRouteCandidate?.method || null,
4495
- route: backendRouteCandidate?.route || "unknown",
4495
+ route: backendRouteCandidate?.route || "",
4496
4496
  field: resolved?.field || match.backendField,
4497
4497
  description: resolved?.description,
4498
+ ...pickPropertyMetadata(resolved),
4498
4499
  source_file: backendFieldSource(match),
4499
4500
  confidence: match.confidence,
4500
4501
  mapper_type: match.mapperType,
4501
4502
  reason: match.reviewReason
4502
4503
  };
4503
4504
  }
4505
+ function toApiPropertyDataType(property) {
4506
+ if (!property.data_type || property.data_type === "unknow" || property.data_type.endsWith("[]")) return property.data_type;
4507
+ return isArrayPath(property.path) ? `${property.data_type}[]` : property.data_type;
4508
+ }
4504
4509
  async function buildCatalogue(documents) {
4505
4510
  const routes = documents.map((document) => ({
4506
4511
  key: document.key,
@@ -4550,6 +4555,8 @@ async function buildCatalogue(documents) {
4550
4555
  field: property.path,
4551
4556
  domain_field: apiSource?.domainField,
4552
4557
  transversal: isTransversalInput(property) || void 0,
4558
+ ...pickPropertyMetadata(property),
4559
+ data_type: toApiPropertyDataType(property),
4553
4560
  backend_names: backendNames,
4554
4561
  backend_mappings: backendMappings,
4555
4562
  description: normalizeDescription(property.description),
@@ -4568,9 +4575,14 @@ async function buildCatalogue(documents) {
4568
4575
  source_file: document.routeFile || null
4569
4576
  });
4570
4577
  for (const match of matches) {
4571
- const backendRouteKey = ensureBackendRouteRecord(backendRoutesByKey, document, resolveBackendRouteCandidate(document, match) || {
4578
+ const resolvedDocument = match.resolvedProperty && "document" in match.resolvedProperty ? match.resolvedProperty.document : void 0;
4579
+ const backendRouteKey = ensureBackendRouteRecord(backendRoutesByKey, document, resolvedDocument ? {
4572
4580
  backend: match.backend,
4573
- route: "unknown",
4581
+ document: resolvedDocument,
4582
+ sourceFile: match.sourceFile
4583
+ } : resolveBackendRouteCandidate(document, match) || {
4584
+ backend: match.backend,
4585
+ route: "",
4574
4586
  sourceFile: match.sourceFile
4575
4587
  }).key;
4576
4588
  const backendPropertyKey = stableKey(backendRouteKey, "input", match.resolvedProperty?.field || match.backendField);
@@ -4581,6 +4593,7 @@ async function buildCatalogue(documents) {
4581
4593
  field: match.resolvedProperty?.field || match.backendField,
4582
4594
  document: match.resolvedProperty && "document" in match.resolvedProperty ? match.resolvedProperty.document : void 0,
4583
4595
  description: match.resolvedProperty?.description,
4596
+ ...pickPropertyMetadata(match.resolvedProperty),
4584
4597
  direction: "input",
4585
4598
  source_file: backendFieldSource(match),
4586
4599
  provenance: "code_analysis"
@@ -4611,6 +4624,8 @@ async function buildCatalogue(documents) {
4611
4624
  direction: "output",
4612
4625
  field: property.path,
4613
4626
  domain_field: apiSource?.domainField,
4627
+ ...pickPropertyMetadata(property),
4628
+ data_type: toApiPropertyDataType(property),
4614
4629
  backend_names: backendNames,
4615
4630
  backend_mappings: backendMappings,
4616
4631
  description: normalizeDescription(property.description),
@@ -4630,9 +4645,14 @@ async function buildCatalogue(documents) {
4630
4645
  source_file: document.routeFile || null
4631
4646
  });
4632
4647
  for (const match of matches) {
4633
- const backendRouteKey = ensureBackendRouteRecord(backendRoutesByKey, document, resolveBackendRouteCandidate(document, match) || {
4648
+ const resolvedDocument = match.resolvedProperty && "document" in match.resolvedProperty ? match.resolvedProperty.document : void 0;
4649
+ const backendRouteKey = ensureBackendRouteRecord(backendRoutesByKey, document, resolvedDocument ? {
4650
+ backend: match.backend,
4651
+ document: resolvedDocument,
4652
+ sourceFile: match.sourceFile
4653
+ } : resolveBackendRouteCandidate(document, match) || {
4634
4654
  backend: match.backend,
4635
- route: "unknown",
4655
+ route: "",
4636
4656
  sourceFile: match.sourceFile
4637
4657
  }).key;
4638
4658
  const backendPropertyKey = stableKey(backendRouteKey, "output", match.resolvedProperty?.field || match.backendField);
@@ -4643,6 +4663,7 @@ async function buildCatalogue(documents) {
4643
4663
  field: match.resolvedProperty?.field || match.backendField,
4644
4664
  document: match.resolvedProperty && "document" in match.resolvedProperty ? match.resolvedProperty.document : void 0,
4645
4665
  description: match.resolvedProperty?.description,
4666
+ ...pickPropertyMetadata(match.resolvedProperty),
4646
4667
  direction: "output",
4647
4668
  source_file: backendFieldSource(match),
4648
4669
  provenance: "code_analysis"
@@ -4692,6 +4713,20 @@ function toPascalCase(value) {
4692
4713
  return value.toLowerCase().replace(/(^|[^a-z0-9]+)([a-z0-9])/g, (_match, _separator, character) => character.toUpperCase());
4693
4714
  }
4694
4715
 
4716
+ //#endregion
4717
+ //#region src/services/directus/queries/createPredefinedValue.ts
4718
+ /**
4719
+ * Creates a Directus predefined value while retaining the attempted identity in
4720
+ * any error reported by the push command.
4721
+ */
4722
+ async function createPredefinedValue(client, payload) {
4723
+ try {
4724
+ return await client.request(n$2("predefined_values", payload));
4725
+ } catch (error) {
4726
+ throw new Error(`Unable to create predefined_values entry (type=${JSON.stringify(payload.type)}, id=${JSON.stringify(payload.id)}, label=${JSON.stringify(payload.label)})`, { cause: error });
4727
+ }
4728
+ }
4729
+
4695
4730
  //#endregion
4696
4731
  //#region src/services/directus/queries/resolveBackendReference.ts
4697
4732
  async function resolveBackendReference(client, references, backend) {
@@ -4702,11 +4737,11 @@ async function resolveBackendReference(client, references, backend) {
4702
4737
  created: false
4703
4738
  };
4704
4739
  if (!isKnownBackendType(backend)) return { created: false };
4705
- const created = await client.request(n$2("predefined_values", {
4740
+ const created = await createPredefinedValue(client, {
4706
4741
  id: backend,
4707
4742
  label: toPascalCase(backend),
4708
4743
  type: "backend"
4709
- }));
4744
+ });
4710
4745
  const id = typeof created === "string" ? created : created.id;
4711
4746
  references.backendIds.set(lookupKey, id);
4712
4747
  return {
@@ -4715,15 +4750,56 @@ async function resolveBackendReference(client, references, backend) {
4715
4750
  };
4716
4751
  }
4717
4752
 
4753
+ //#endregion
4754
+ //#region src/services/directus/queries/resolveDataTypeReference.ts
4755
+ async function resolveDataTypeReference(client, references, dataType) {
4756
+ const { id, label } = transformTypeFrom(dataType);
4757
+ const lookupKey = normalizeLookupKey(id);
4758
+ const existingId = references.dataTypeIds.get(lookupKey);
4759
+ if (existingId) return {
4760
+ id: existingId,
4761
+ created: false
4762
+ };
4763
+ const created = await createPredefinedValue(client, {
4764
+ id,
4765
+ label,
4766
+ type: "data_type"
4767
+ });
4768
+ const createdId = typeof created === "string" ? created : created.id;
4769
+ references.dataTypeIds.set(lookupKey, createdId);
4770
+ return {
4771
+ id: createdId,
4772
+ created: true
4773
+ };
4774
+ }
4775
+
4718
4776
  //#endregion
4719
4777
  //#region src/services/directus/utils/normalizeDirectusPath.ts
4720
4778
  function normalizeDirectusPath(value) {
4721
4779
  return value.replace(/\?\.\[/g, "[").replace(/\?\./g, ".");
4722
4780
  }
4723
4781
 
4782
+ //#endregion
4783
+ //#region src/services/directus/utils/toDirectusPropertyMetadata.ts
4784
+ /**
4785
+ * Converts Atlas' property metadata to the nullable shape expected by Directus.
4786
+ * The data type relation is deliberately excluded: it is resolved separately as
4787
+ * a predefined-value id before a property is upserted.
4788
+ */
4789
+ function toDirectusPropertyMetadata(property) {
4790
+ return {
4791
+ original_type: property.original_type ?? null,
4792
+ format: property.format ?? null,
4793
+ pattern: property.pattern ?? null,
4794
+ is_nullable: property.is_nullable ?? null,
4795
+ enum_values: property.enum_values?.length ? property.enum_values : null,
4796
+ description: property.description ?? null
4797
+ };
4798
+ }
4799
+
4724
4800
  //#endregion
4725
4801
  //#region src/services/directus/queries/upsertBackendProperty.ts
4726
- async function upsertBackendProperty(client, property, backendRouteId, typeId) {
4802
+ async function upsertBackendProperty(client, property, backendRouteId, typeId, dataTypeId) {
4727
4803
  const path = normalizeDirectusPath(property.field);
4728
4804
  const [existing] = await client.request(n$1("backend_properties", {
4729
4805
  filter: {
@@ -4734,16 +4810,21 @@ async function upsertBackendProperty(client, property, backendRouteId, typeId) {
4734
4810
  fields: ["id"],
4735
4811
  limit: 1
4736
4812
  }));
4737
- if (existing) return existing.id;
4738
- const created = await client.request(n$2("backend_properties", {
4813
+ const payload = {
4739
4814
  backend: backendRouteId,
4740
4815
  path: path || null,
4741
4816
  type: typeId,
4817
+ data_type: dataTypeId ?? null,
4818
+ ...toDirectusPropertyMetadata(property),
4742
4819
  source_file: property.source_file || null,
4743
4820
  provenance: property.provenance,
4744
- comments: property.provenance === "ai" ? "Inferred with AI" : null,
4745
- content_name: null
4746
- }));
4821
+ comments: property.provenance === "ai" ? "Inferred with AI" : null
4822
+ };
4823
+ if (existing) {
4824
+ await client.request(i("backend_properties", existing.id, payload));
4825
+ return existing.id;
4826
+ }
4827
+ const created = await client.request(n$2("backend_properties", payload));
4747
4828
  return typeof created === "string" ? created : created.id;
4748
4829
  }
4749
4830
 
@@ -4754,10 +4835,12 @@ async function upsertBackendSource(client, backendRoute, backendValueId, refs) {
4754
4835
  let documentId = isDocument ? refs.documentIds.get(normalizeLookupKey(backendRoute.document || "")) : void 0;
4755
4836
  if (isDocument && !documentId && backendRoute.document) {
4756
4837
  const type = `document_${backendRoute.backend.toLowerCase()}`;
4757
- const created = await client.request(n$2("predefined_values", {
4838
+ const id = `${type}_${backendRoute.document}`.toUpperCase().replace(/[^A-Z0-9]+/g, "_");
4839
+ const created = await createPredefinedValue(client, {
4840
+ id,
4758
4841
  label: backendRoute.document,
4759
4842
  type
4760
- }));
4843
+ });
4761
4844
  documentId = typeof created === "string" ? created : created.id;
4762
4845
  refs.documentIds.set(normalizeLookupKey(backendRoute.document), documentId);
4763
4846
  }
@@ -4780,6 +4863,8 @@ async function upsertBackendSource(client, backendRoute, backendValueId, refs) {
4780
4863
  const payload = isDocument ? {
4781
4864
  backend: backendValueId,
4782
4865
  resource_type: "document",
4866
+ method: null,
4867
+ route: null,
4783
4868
  document: documentId ?? null,
4784
4869
  source_file: backendRoute.source_file || null,
4785
4870
  provenance: backendRoute.provenance
@@ -4788,26 +4873,29 @@ async function upsertBackendSource(client, backendRoute, backendValueId, refs) {
4788
4873
  resource_type: "http",
4789
4874
  method: backendRoute.method ?? null,
4790
4875
  route: backendRoute.route ?? null,
4876
+ document: null,
4791
4877
  source_file: backendRoute.source_file || null,
4792
4878
  provenance: backendRoute.provenance
4793
4879
  };
4794
- const created = await client.request(n$2("backend_sources", payload));
4880
+ const created = await client.request(n$2("backend_sources", {
4881
+ id: randomUUID(),
4882
+ ...payload
4883
+ }));
4795
4884
  return typeof created === "string" ? created : created.id;
4796
4885
  }
4797
4886
 
4798
4887
  //#endregion
4799
4888
  //#region src/services/directus/queries/upsertMappingEvidence.ts
4800
4889
  async function upsertMappingEvidence(client, evidence, params) {
4801
- const [existing] = await client.request(n$1("mapping_evidence", {
4890
+ const [existing] = await client.request(n$1("mapping_evidences", {
4802
4891
  filter: { atlas_key: { _eq: evidence.key } },
4803
4892
  fields: ["id"],
4804
4893
  limit: 1
4805
4894
  }));
4806
4895
  const payload = {
4807
4896
  atlas_key: evidence.key,
4808
- input_property_id: params.inputPropertyId ?? null,
4809
- output_property_id: params.outputPropertyId ?? null,
4810
- backend_property_id: params.backendPropertyId,
4897
+ route_property_id: params.routePropertyId ?? null,
4898
+ backend_property_id: params.backendPropertyId ?? null,
4811
4899
  evidence_type: evidence.evidence_type,
4812
4900
  status: evidence.status,
4813
4901
  confidence_score: evidence.confidence_score,
@@ -4816,70 +4904,57 @@ async function upsertMappingEvidence(client, evidence, params) {
4816
4904
  last_seen_at: (/* @__PURE__ */ new Date()).toISOString()
4817
4905
  };
4818
4906
  if (existing) {
4819
- await client.request(i("mapping_evidence", existing.id, payload));
4907
+ await client.request(i("mapping_evidences", existing.id, payload));
4820
4908
  return false;
4821
4909
  }
4822
- await client.request(n$2("mapping_evidence", payload));
4910
+ await client.request(n$2("mapping_evidences", {
4911
+ id: randomUUID(),
4912
+ ...payload
4913
+ }));
4823
4914
  return true;
4824
4915
  }
4825
4916
 
4826
4917
  //#endregion
4827
- //#region src/services/directus/queries/upsertInputProperty.ts
4828
- async function upsertInputProperty(client, property, routeId, inType) {
4829
- const field = normalizeDirectusPath(property.field);
4830
- const [existing] = await client.request(n$1("route_input_properties", {
4918
+ //#region src/services/directus/queries/upsertRouteProperty.ts
4919
+ async function upsertRouteProperty(client, property, routeId, type, dataTypeId) {
4920
+ const path = normalizeDirectusPath(property.field);
4921
+ const [existing] = await client.request(n$1("route_properties", {
4831
4922
  filter: {
4832
4923
  route_id: { _eq: routeId },
4833
- path: { _eq: field },
4834
- in_type: { _eq: inType }
4924
+ path: { _eq: path },
4925
+ type: { _eq: type }
4835
4926
  },
4836
4927
  fields: ["id"],
4837
4928
  limit: 1
4838
4929
  }));
4839
4930
  const payload = {
4840
4931
  route_id: routeId,
4841
- path: field,
4842
- in_type: inType,
4843
- description: property.description || null,
4932
+ path,
4933
+ type,
4934
+ data_type: dataTypeId ?? null,
4935
+ ...toDirectusPropertyMetadata(property),
4844
4936
  source_file: property.source_file || null,
4845
- deprecated: false
4937
+ deprecated: false,
4938
+ is_dynamic: isArrayPath(path) || path.includes("{")
4846
4939
  };
4847
4940
  if (!existing) {
4848
- const created = await client.request(n$2("route_input_properties", payload));
4941
+ const created = await client.request(n$2("route_properties", payload));
4849
4942
  return typeof created === "string" ? created : created.id;
4850
4943
  }
4851
- await client.request(i("route_input_properties", existing.id, payload));
4944
+ await client.request(i("route_properties", existing.id, payload));
4852
4945
  return existing.id;
4853
4946
  }
4854
4947
 
4948
+ //#endregion
4949
+ //#region src/services/directus/queries/upsertInputProperty.ts
4950
+ async function upsertInputProperty(client, property, routeId, inType, dataTypeId) {
4951
+ return upsertRouteProperty(client, property, routeId, inType, dataTypeId);
4952
+ }
4953
+
4855
4954
  //#endregion
4856
4955
  //#region src/services/directus/queries/upsertOutputProperty.ts
4857
- async function upsertOutputProperty(client, property, routeId, outType) {
4858
- const field = normalizeDirectusPath(property.field);
4859
- const [existing] = await client.request(n$1("route_output_properties", {
4860
- filter: {
4861
- route_id: { _eq: routeId },
4862
- path: { _eq: field },
4863
- out_type: { _eq: outType }
4864
- },
4865
- fields: ["id"],
4866
- limit: 1
4867
- }));
4868
- const payload = {
4869
- route_id: routeId,
4870
- path: field,
4871
- out_type: outType,
4872
- description: property.description || null,
4873
- source_file: property.source_file || null,
4874
- deprecated: false,
4875
- is_dynamic: field.includes("[]") || field.includes("{")
4876
- };
4877
- if (!existing) {
4878
- const created = await client.request(n$2("route_output_properties", payload));
4879
- return typeof created === "string" ? created : created.id;
4880
- }
4881
- await client.request(i("route_output_properties", existing.id, payload));
4882
- return existing.id;
4956
+ async function upsertOutputProperty(client, property, routeId, outType, dataTypeId) {
4957
+ return upsertRouteProperty(client, property, routeId, outType, dataTypeId);
4883
4958
  }
4884
4959
 
4885
4960
  //#endregion
@@ -4930,7 +5005,7 @@ async function upsertRoute(client, route) {
4930
5005
  function groupBackendRoutesForDirectusSync(backendRoutes) {
4931
5006
  const groups = /* @__PURE__ */ new Map();
4932
5007
  for (const backendRoute of backendRoutes) {
4933
- const key = backendRoute.resource_type === "document" ? `${backendRoute.backend}\0document\0${backendRoute.document || ""}` : `${backendRoute.backend}\0http\0${backendRoute.method || ""}\0${backendRoute.route || ""}`;
5008
+ const key = backendRoute.resource_type === "document" ? `${backendRoute.route_key}\0${backendRoute.backend}\0document\0${backendRoute.document || ""}` : `${backendRoute.route_key}\0${backendRoute.backend}\0http\0${backendRoute.method || ""}\0${backendRoute.route || ""}`;
4934
5009
  const group = groups.get(key);
4935
5010
  if (group) group.keys.push(backendRoute.key);
4936
5011
  else groups.set(key, {
@@ -4963,7 +5038,6 @@ function selectCatalogueForDirectusPush(catalogue, routeSelector) {
4963
5038
  const backendRouteKeys = new Set(backendRoutes.map((route) => route.key));
4964
5039
  const backendProperties = catalogue.backend_properties.filter((property) => backendRouteKeys.has(property.backend_route_key));
4965
5040
  const apiPropertyKeys = new Set([...routeInputProperties, ...routeOutputProperties].map((property) => property.key));
4966
- const backendPropertyKeys = new Set(backendProperties.map((property) => property.key));
4967
5041
  return {
4968
5042
  ...catalogue,
4969
5043
  routes,
@@ -4971,7 +5045,7 @@ function selectCatalogueForDirectusPush(catalogue, routeSelector) {
4971
5045
  route_output_properties: routeOutputProperties,
4972
5046
  backend_routes: backendRoutes,
4973
5047
  backend_properties: backendProperties,
4974
- mapping_evidence: catalogue.mapping_evidence.filter((evidence) => backendPropertyKeys.has(evidence.backend_property_key) && (apiPropertyKeys.has(evidence.input_property_key || "") || apiPropertyKeys.has(evidence.output_property_key || ""))),
5048
+ mapping_evidence: catalogue.mapping_evidence.filter((evidence) => apiPropertyKeys.has(evidence.input_property_key || "") || apiPropertyKeys.has(evidence.output_property_key || "")),
4975
5049
  rules: catalogue.rules.filter((rule) => routeKeys.has(rule.route_key)),
4976
5050
  aggregations: catalogue.aggregations.filter((aggregation) => routeKeys.has(aggregation.route_key))
4977
5051
  };
@@ -4983,13 +5057,11 @@ async function pushCatalogueToDirectus(catalogue, options) {
4983
5057
  const pushedCollections = [
4984
5058
  "predefined_values",
4985
5059
  "routes",
4986
- "route_input_properties",
4987
- "route_output_properties",
5060
+ "route_properties",
4988
5061
  "backend_sources",
4989
5062
  "backend_properties",
4990
- "mapping_evidence",
4991
- "route_input_properties_backend_properties",
4992
- "route_output_properties_backend_properties"
5063
+ "mapping_evidences",
5064
+ "route_properties_backend_properties"
4993
5065
  ];
4994
5066
  const skippedCollections = [];
4995
5067
  const catalogueToPush = selectCatalogueForDirectusPush(catalogue, options.routeSelector);
@@ -5055,7 +5127,13 @@ async function pushCatalogueToDirectus(catalogue, options) {
5055
5127
  warnings.add(`UNKNOWN_BACKEND_PROPERTY_TYPE: ${backendProperty.direction} ${backendProperty.field}`);
5056
5128
  continue;
5057
5129
  }
5058
- const backendPropertyId = await upsertBackendProperty(client, backendProperty, backendRouteId, typeId);
5130
+ let dataTypeId;
5131
+ if (backendProperty.data_type) {
5132
+ const dataTypeReference = await resolveDataTypeReference(client, refs, backendProperty.data_type);
5133
+ dataTypeId = dataTypeReference.id;
5134
+ if (dataTypeReference.created) pushedItems += 1;
5135
+ }
5136
+ const backendPropertyId = await upsertBackendProperty(client, backendProperty, backendRouteId, typeId, dataTypeId);
5059
5137
  backendPropertyIds.set(backendProperty.key, backendPropertyId);
5060
5138
  pushedItems += 1;
5061
5139
  }
@@ -5067,18 +5145,18 @@ async function pushCatalogueToDirectus(catalogue, options) {
5067
5145
  warnings.add(`UNKNOWN_IN_TYPE: ${property.field}`);
5068
5146
  continue;
5069
5147
  }
5070
- const inputPropertyId = await upsertInputProperty(client, property, routeId, inType);
5148
+ const dataTypeReference = property.data_type ? await resolveDataTypeReference(client, refs, property.data_type) : void 0;
5149
+ if (dataTypeReference?.created) pushedItems += 1;
5150
+ const inputPropertyId = await upsertInputProperty(client, property, routeId, inType, dataTypeReference?.id);
5071
5151
  pushedItems += 1;
5072
5152
  for (const evidence of catalogueToPush.mapping_evidence.filter((item) => item.input_property_key === property.key)) {
5073
5153
  const backendPropertyId = backendPropertyIds.get(evidence.backend_property_key);
5074
- if (backendPropertyId) {
5075
- if (await ensureInputLink(client, inputPropertyId, backendPropertyId)) pushedItems += 1;
5076
- await upsertMappingEvidence(client, evidence, {
5077
- inputPropertyId,
5078
- backendPropertyId
5079
- });
5080
- pushedItems += 1;
5081
- }
5154
+ if (backendPropertyId && await ensureInputLink(client, inputPropertyId, backendPropertyId)) pushedItems += 1;
5155
+ await upsertMappingEvidence(client, evidence, {
5156
+ routePropertyId: inputPropertyId,
5157
+ backendPropertyId
5158
+ });
5159
+ pushedItems += 1;
5082
5160
  }
5083
5161
  }
5084
5162
  const routeOutputProperties = catalogueToPush.route_output_properties.filter((property) => property.route_key === route.key);
@@ -5089,18 +5167,18 @@ async function pushCatalogueToDirectus(catalogue, options) {
5089
5167
  warnings.add("UNKNOWN_OUT_TYPE: RESPONSE_BODY");
5090
5168
  continue;
5091
5169
  }
5092
- const outputPropertyId = await upsertOutputProperty(client, property, routeId, outType);
5170
+ const dataTypeReference = property.data_type ? await resolveDataTypeReference(client, refs, property.data_type) : void 0;
5171
+ if (dataTypeReference?.created) pushedItems += 1;
5172
+ const outputPropertyId = await upsertOutputProperty(client, property, routeId, outType, dataTypeReference?.id);
5093
5173
  pushedItems += 1;
5094
5174
  for (const evidence of catalogueToPush.mapping_evidence.filter((item) => item.output_property_key === property.key)) {
5095
5175
  const backendPropertyId = backendPropertyIds.get(evidence.backend_property_key);
5096
- if (backendPropertyId) {
5097
- if (await ensureOutputLink(client, outputPropertyId, backendPropertyId)) pushedItems += 1;
5098
- await upsertMappingEvidence(client, evidence, {
5099
- outputPropertyId,
5100
- backendPropertyId
5101
- });
5102
- pushedItems += 1;
5103
- }
5176
+ if (backendPropertyId && await ensureOutputLink(client, outputPropertyId, backendPropertyId)) pushedItems += 1;
5177
+ await upsertMappingEvidence(client, evidence, {
5178
+ routePropertyId: outputPropertyId,
5179
+ backendPropertyId
5180
+ });
5181
+ pushedItems += 1;
5104
5182
  }
5105
5183
  }
5106
5184
  }
@@ -5141,12 +5219,11 @@ function buildRouteReviewRelativePath(method, routePath) {
5141
5219
  ];
5142
5220
  return path.join(resourceDir, versionDir, `${fileNameParts.join("_")}.yaml`);
5143
5221
  }
5144
- function parseBackendRoute(route) {
5145
- const match = route.match(/^(GET|POST|PUT|PATCH|DELETE|HEAD|CALL)\s+(.+)$/);
5146
- if (!match || match[1] === "CALL" && match[2] === "unknown") return;
5222
+ function toHttpOperation(backendRoute) {
5223
+ if (!backendRoute.route) return;
5147
5224
  return {
5148
- method: match[1] === "CALL" ? null : match[1],
5149
- route: match[2]
5225
+ method: backendRoute.method || null,
5226
+ route: backendRoute.route
5150
5227
  };
5151
5228
  }
5152
5229
  function buildReviewProperty(property) {
@@ -5155,6 +5232,7 @@ function buildReviewProperty(property) {
5155
5232
  field: mapping.field,
5156
5233
  document: mapping.document,
5157
5234
  description: mapping.description,
5235
+ ...pickPropertyMetadata(mapping),
5158
5236
  source: mapping.source_file,
5159
5237
  ...mapping.route && (mapping.route !== "unknown" || mapping.method) ? { operation: {
5160
5238
  method: mapping.method || null,
@@ -5195,6 +5273,7 @@ function buildReviewProperty(property) {
5195
5273
  source: property.source_file,
5196
5274
  evidence_status: property.evidence_status,
5197
5275
  transversal: property.transversal,
5276
+ ...pickPropertyMetadata(property),
5198
5277
  ...hasMapping ? { mapping } : {},
5199
5278
  ...suggestions?.length || unresolvedBackendCandidates?.length ? { review: {
5200
5279
  ...suggestions?.length ? { suggestions } : {},
@@ -5211,7 +5290,7 @@ function buildRouteReviewDocument(catalogue, routeKey) {
5211
5290
  const datasources = backendRoutes.map((backendRoute) => ({
5212
5291
  type: backendRoute.backend,
5213
5292
  source: backendRoute.source_file,
5214
- ...parseBackendRoute(backendRoute.route ?? "") ? { operation: parseBackendRoute(backendRoute.route ?? "") } : {},
5293
+ ...backendRoute.resource_type === "document" ? { document: backendRoute.document } : toHttpOperation(backendRoute) ? { operation: toHttpOperation(backendRoute) } : {},
5215
5294
  ...backendRoute.provenance === "ai" ? { provenance: backendRoute.provenance } : {}
5216
5295
  }));
5217
5296
  for (const backend of route.backends) if (!datasources.some((datasource) => datasource.type === backend) && !mappedBackendTypes.has(backend)) datasources.push({
@@ -5327,14 +5406,16 @@ async function writeCatalogueArtifacts(catalogue, outputDir, repoRoot = process.
5327
5406
  };
5328
5407
  }
5329
5408
  function addBackendMapping(routeKey, direction, apiPropertyKey, mapping, backendRoutesByKey, backendPropertiesByKey, mappingEvidence) {
5330
- const backendRoute = mapping.route || (mapping.document ? `DOCUMENT ${mapping.document}` : "unknown");
5331
- const backendRouteKey = stableKey(routeKey, mapping.backend, backendRoute);
5409
+ const backendSourceId = mapping.document || mapping.route || "";
5410
+ const backendRouteKey = stableKey(routeKey, mapping.backend, backendSourceId);
5332
5411
  const backendRouteRecord = backendRoutesByKey.get(backendRouteKey) || {
5333
5412
  key: backendRouteKey,
5334
5413
  backend: mapping.backend,
5335
5414
  route_key: routeKey,
5336
- resource_type: "http",
5337
- route: `${mapping.method || "CALL"} ${backendRoute}`,
5415
+ resource_type: mapping.document ? "document" : "http",
5416
+ method: mapping.document ? void 0 : mapping.method || void 0,
5417
+ route: mapping.document ? void 0 : mapping.route || void 0,
5418
+ document: mapping.document || void 0,
5338
5419
  source_file: mapping.source_file,
5339
5420
  provenance: "code_analysis"
5340
5421
  };
@@ -5345,6 +5426,8 @@ function addBackendMapping(routeKey, direction, apiPropertyKey, mapping, backend
5345
5426
  backend_route_key: backendRouteKey,
5346
5427
  backend: mapping.backend,
5347
5428
  field: mapping.field,
5429
+ description: mapping.description,
5430
+ ...pickPropertyMetadata(mapping),
5348
5431
  direction,
5349
5432
  source_file: mapping.source_file,
5350
5433
  provenance: mapping.provenance || "code_analysis"
@@ -5368,6 +5451,7 @@ function toCatalogueBackendMapping(mapping) {
5368
5451
  field: mapping.field,
5369
5452
  document: mapping.document,
5370
5453
  description: mapping.description,
5454
+ ...pickPropertyMetadata(mapping),
5371
5455
  source_file: mapping.source,
5372
5456
  confidence: mapping.confidence,
5373
5457
  mapper_type: mapping.mapper_type,
@@ -5376,14 +5460,25 @@ function toCatalogueBackendMapping(mapping) {
5376
5460
  };
5377
5461
  }
5378
5462
  function addDatasourceRoute(routeKey, datasource, backendRoutesByKey) {
5379
- const backendRoute = datasource.operation?.route || "unknown";
5380
- const backendRouteKey = stableKey(routeKey, datasource.type, backendRoute);
5381
- backendRoutesByKey.set(backendRouteKey, {
5463
+ const isDocument = datasource.document !== void 0;
5464
+ if (!isDocument && !datasource.operation) return;
5465
+ const sourceId = isDocument ? datasource.document : datasource.operation?.route || "";
5466
+ const backendRouteKey = stableKey(routeKey, datasource.type, sourceId);
5467
+ backendRoutesByKey.set(backendRouteKey, isDocument ? {
5468
+ key: backendRouteKey,
5469
+ backend: datasource.type,
5470
+ route_key: routeKey,
5471
+ resource_type: "document",
5472
+ document: datasource.document,
5473
+ source_file: datasource.source,
5474
+ provenance: datasource.provenance || "code_analysis"
5475
+ } : {
5382
5476
  key: backendRouteKey,
5383
5477
  backend: datasource.type,
5384
5478
  route_key: routeKey,
5385
5479
  resource_type: "http",
5386
- route: `${datasource.operation?.method || "CALL"} ${backendRoute}`,
5480
+ method: datasource.operation?.method || void 0,
5481
+ route: datasource.operation?.route || void 0,
5387
5482
  source_file: datasource.source,
5388
5483
  provenance: datasource.provenance || "code_analysis"
5389
5484
  });
@@ -5422,12 +5517,13 @@ function mergeRouteReviewDocuments(documents) {
5422
5517
  field: property.field,
5423
5518
  domain_field: property.mapping?.domain?.field,
5424
5519
  transversal: property.transversal,
5520
+ ...pickPropertyMetadata(property),
5425
5521
  backend_names: [...new Set(backendMappings.map((mapping) => mapping.backend))],
5426
5522
  backend_mappings: backendMappings,
5427
5523
  inference_suggestions: property.review?.suggestions?.map((suggestion) => ({
5428
5524
  backend: suggestion.type,
5429
5525
  method: suggestion.operation?.method || null,
5430
- route: suggestion.operation?.route || "unknown",
5526
+ route: suggestion.operation?.route || "",
5431
5527
  field: suggestion.field,
5432
5528
  source_file: suggestion.source,
5433
5529
  confidence: suggestion.confidence,
@@ -5550,7 +5646,10 @@ function parseRouteSelector(value) {
5550
5646
  //#endregion
5551
5647
  //#region src/commands/push.ts
5552
5648
  function formatPushError(error) {
5553
- if (error instanceof Error) return error.message;
5649
+ if (error instanceof Error) {
5650
+ const cause = isRecord$1(error) ? error.cause : void 0;
5651
+ return cause === void 0 ? error.message : `${error.message}; ${formatPushError(cause)}`;
5652
+ }
5554
5653
  if (!isRecord$1(error)) return String(error);
5555
5654
  const details = (Array.isArray(error.errors) ? error.errors : []).flatMap((item) => {
5556
5655
  if (!isRecord$1(item) || typeof item.message !== "string") return [];
@@ -23166,16 +23265,20 @@ function findBackendRoute(document, suggestion) {
23166
23265
  }
23167
23266
  function ensureBackendRoute(catalogue, document, suggestion) {
23168
23267
  const candidate = findBackendRoute(document, suggestion);
23169
- const backendRoutePath = candidate?.route || "unknown";
23170
- const key = stableKey(document.key, suggestion.candidate.backend, backendRoutePath);
23268
+ const resolvedProp = suggestion.candidate.resolvedProperty;
23269
+ const isDocument = resolvedProp !== void 0 && "document" in resolvedProp;
23270
+ const sourceId = isDocument ? resolvedProp.document : candidate?.route || "";
23271
+ const key = stableKey(document.key, suggestion.candidate.backend, sourceId);
23171
23272
  const existing = catalogue.backend_routes.find((route) => route.key === key);
23172
23273
  if (existing) return existing;
23173
23274
  const created = {
23174
23275
  key,
23175
23276
  backend: suggestion.candidate.backend,
23176
23277
  route_key: document.key,
23177
- resource_type: "http",
23178
- route: `${candidate?.method || "CALL"} ${backendRoutePath}`,
23278
+ resource_type: isDocument ? "document" : "http",
23279
+ method: isDocument ? void 0 : candidate?.method || void 0,
23280
+ route: isDocument ? void 0 : candidate?.route || void 0,
23281
+ document: isDocument ? resolvedProp.document : void 0,
23179
23282
  source_file: candidate?.sourceFile || suggestion.candidate.sourceFile,
23180
23283
  provenance: "ai"
23181
23284
  };
@@ -23207,20 +23310,28 @@ function applySuggestion(catalogue, document, property, suggestion) {
23207
23310
  const backendRouteCandidate = findBackendRoute(document, suggestion);
23208
23311
  const backendRoute = ensureBackendRoute(catalogue, document, suggestion);
23209
23312
  const backendPropertyKey = stableKey(backendRoute.key, property.direction, suggestion.candidate.backendField);
23313
+ const resolvedProp = suggestion.candidate.resolvedProperty;
23314
+ const resolvedDocument = resolvedProp && "document" in resolvedProp ? resolvedProp.document : void 0;
23210
23315
  if (!catalogue.backend_properties.some((item) => item.key === backendPropertyKey)) catalogue.backend_properties.push({
23211
23316
  key: backendPropertyKey,
23212
23317
  backend_route_key: backendRoute.key,
23213
23318
  backend: suggestion.candidate.backend,
23214
23319
  field: suggestion.candidate.backendField,
23320
+ description: resolvedProp?.description,
23321
+ ...pickPropertyMetadata(resolvedProp),
23215
23322
  direction: property.direction,
23216
23323
  source_file: candidateSource(suggestion.candidate),
23217
23324
  provenance: "ai"
23218
23325
  });
23219
23326
  if (!property.backend_mappings.some((mapping) => mapping.backend === suggestion.candidate.backend && mapping.field === suggestion.candidate.backendField)) property.backend_mappings.push({
23220
23327
  backend: suggestion.candidate.backend,
23221
- method: backendRouteCandidate?.method || null,
23222
- route: backendRouteCandidate?.route || "unknown",
23328
+ ...resolvedDocument ? { document: resolvedDocument } : {
23329
+ method: backendRouteCandidate?.method || null,
23330
+ route: backendRouteCandidate?.route || ""
23331
+ },
23223
23332
  field: suggestion.candidate.backendField,
23333
+ description: resolvedProp?.description,
23334
+ ...pickPropertyMetadata(resolvedProp),
23224
23335
  source_file: candidateSource(suggestion.candidate),
23225
23336
  confidence: suggestion.confidence,
23226
23337
  mapper_type: suggestion.candidate.mapperType,
@@ -23247,7 +23358,7 @@ function recordReviewSuggestion(document, property, suggestion) {
23247
23358
  property.inference_suggestions.push({
23248
23359
  backend: suggestion.candidate.backend,
23249
23360
  method: backendRouteCandidate?.method || null,
23250
- route: backendRouteCandidate?.route || "unknown",
23361
+ route: backendRouteCandidate?.route || "",
23251
23362
  field: suggestion.candidate.backendField,
23252
23363
  source_file: candidateSource(suggestion.candidate),
23253
23364
  confidence: suggestion.confidence,
@@ -23379,11 +23490,13 @@ async function inferCatalogueDirectory(params) {
23379
23490
  input: catalogue.route_input_properties.filter((property) => property.route_key === routeKey).map((property) => ({
23380
23491
  path: property.field,
23381
23492
  description: property.description,
23493
+ type: property.data_type,
23382
23494
  location: "body"
23383
23495
  })),
23384
23496
  output: catalogue.route_output_properties.filter((property) => property.route_key === routeKey).map((property) => ({
23385
23497
  path: property.field,
23386
23498
  description: property.description,
23499
+ type: property.data_type,
23387
23500
  location: "body"
23388
23501
  }))
23389
23502
  }]]);