displayLabel: sanitizeText()

in packages/graph-explorer/src/connector/openCypher/fetchSchema/index.ts [140:257]


            displayLabel: sanitizeText(name),
            dataType: typeof value === "string" ? "String" : "Number",
          };
        }),
      };
      return vertexSchema;
    })
    .filter(vertexSchema => vertexSchema != null);

  remoteLogger.info(
    `[openCypher Explorer] Found ${vertices.flatMap(v => v.attributes).length} vertex attributes across ${vertices.length} vertex types.`
  );

  return vertices;
};

// Fetches schema for all vertices
const fetchVerticesSchema = async (
  openCypherFetch: OpenCypherFetch,
  remoteLogger: LoggerConnector
): Promise<SchemaResponse["vertices"]> => {
  const countsByLabel = await fetchVertexLabels(openCypherFetch, remoteLogger);
  const labels = Object.keys(countsByLabel);

  return fetchVerticesAttributes(
    openCypherFetch,
    remoteLogger,
    labels,
    countsByLabel
  );
};

// Fetches all edge labels and their counts
const fetchEdgeLabels = async (
  openCypherFetch: OpenCypherFetch,
  remoteLogger: LoggerConnector
): Promise<Record<string, number>> => {
  const labelsTemplate = edgeLabelsTemplate();
  remoteLogger.info(
    "[openCypher Explorer] Fetching edge labels with counts..."
  );
  const data = await openCypherFetch<RawEdgeLabelsResponse>(labelsTemplate);

  const values = data.results;
  const labelsWithCounts: Record<string, number> = {};

  if (!values) {
    return labelsWithCounts;
  }

  for (let i = 0; i < values.length; i += 1) {
    const edge = values[i];
    if (!edge) {
      continue;
    }

    const label = Array.isArray(edge.label) ? edge.label[0] : edge.label;

    if (!label) {
      continue;
    }

    labelsWithCounts[label] = edge.count;
  }

  remoteLogger.info(
    `[openCypher Explorer] Found ${Object.keys(labelsWithCounts).length} edge labels.`
  );

  return labelsWithCounts;
};

// Fetches attributes for all edges with the given labels
const fetchEdgesAttributes = async (
  openCypherFetch: OpenCypherFetch,
  remoteLogger: LoggerConnector,
  labels: Array<string>,
  countsByLabel: Record<string, number>
): Promise<SchemaResponse["edges"]> => {
  if (labels.length === 0) {
    return [];
  }

  remoteLogger.info("[openCypher Explorer] Fetching edges attributes...");
  const responses = await batchPromisesSerially(
    labels,
    DEFAULT_CONCURRENT_REQUESTS_LIMIT,
    async label => {
      const edgesTemplate = edgesSchemaTemplate({
        type: label,
      });

      const response =
        await openCypherFetch<RawEdgesSchemaResponse>(edgesTemplate);

      return {
        edge: response.results ? response.results[0]?.object : null,
        label,
      };
    }
  );

  const edges = responses
    .map(({ edge, label }) => {
      // verify response has the info we need
      if (!edge || !edge["~entityType"] || !edge["~type"]) {
        return null;
      }

      const type = edge["~type"];
      const properties = edge["~properties"];
      const edgeSchema: EdgeSchemaResponse = {
        type: type,
        displayLabel: sanitizeText(type),
        total: countsByLabel[label],
        attributes: Object.entries(properties || {}).map(([name, prop]) => {
          const value = prop;
          return {