@inkindcards/semantic-layer 2.0.0 → 2.1.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.
@@ -1,6 +1,6 @@
1
1
  import { useMetrics, useAuth, useAdminFields, useAdminRoles, useAdminUsers } from './chunk-3OR3QCN6.js';
2
- import { useState, useMemo, useCallback } from 'react';
3
- import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { createContext, useState, useMemo, useCallback, useContext, useId, useRef, useEffect } from 'react';
3
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
 
5
5
  var containerStyle = {
6
6
  fontFamily: "system-ui, -apple-system, sans-serif",
@@ -803,7 +803,549 @@ function AdminDashboard({ className }) {
803
803
  tab === "users" && /* @__PURE__ */ jsx(UsersTab, {})
804
804
  ] });
805
805
  }
806
+ var InspectableRegistryContext = createContext(null);
807
+ function InspectableRegistry({ children }) {
808
+ const [entries, setEntries] = useState(/* @__PURE__ */ new Map());
809
+ const [inspectActive, setInspectActive] = useState(false);
810
+ const [selectedId, setSelectedId] = useState(null);
811
+ const register = useCallback((entry) => {
812
+ setEntries((prev) => {
813
+ const next = new Map(prev);
814
+ next.set(entry.id, entry);
815
+ return next;
816
+ });
817
+ }, []);
818
+ const unregister = useCallback((id) => {
819
+ setEntries((prev) => {
820
+ const next = new Map(prev);
821
+ next.delete(id);
822
+ return next;
823
+ });
824
+ setSelectedId((prev) => prev === id ? null : prev);
825
+ }, []);
826
+ const value = {
827
+ entries,
828
+ register,
829
+ unregister,
830
+ inspectActive,
831
+ setInspectActive,
832
+ selectedId,
833
+ setSelectedId
834
+ };
835
+ return /* @__PURE__ */ jsx(InspectableRegistryContext.Provider, { value, children });
836
+ }
837
+ function Inspectable({
838
+ label,
839
+ currentSource = "unknown",
840
+ data,
841
+ columns,
842
+ children
843
+ }) {
844
+ const registry = useContext(InspectableRegistryContext);
845
+ const id = useId();
846
+ const ref = useRef(null);
847
+ const inferredColumns = columns ?? (data?.[0] ? Object.keys(data[0]) : []);
848
+ const sampleValues = data?.slice(0, 3) ?? [];
849
+ useEffect(() => {
850
+ if (!registry) return;
851
+ registry.register({
852
+ id,
853
+ label,
854
+ currentSource,
855
+ columns: inferredColumns,
856
+ sampleValues,
857
+ element: ref.current
858
+ });
859
+ return () => registry.unregister(id);
860
+ }, [id, label, currentSource, inferredColumns.join(","), registry]);
861
+ if (!registry) {
862
+ return /* @__PURE__ */ jsx(Fragment, { children });
863
+ }
864
+ const isSelected = registry.selectedId === id;
865
+ const showOutline = registry.inspectActive;
866
+ const handleClick = (e) => {
867
+ if (!registry.inspectActive) return;
868
+ e.stopPropagation();
869
+ registry.setSelectedId(isSelected ? null : id);
870
+ };
871
+ return /* @__PURE__ */ jsxs(
872
+ "div",
873
+ {
874
+ ref,
875
+ onClick: handleClick,
876
+ style: {
877
+ position: "relative",
878
+ outline: showOutline ? isSelected ? "2px solid #3b82f6" : "2px dashed #93c5fd" : "none",
879
+ outlineOffset: 2,
880
+ borderRadius: 4,
881
+ cursor: showOutline ? "pointer" : "inherit",
882
+ transition: "outline 0.15s ease"
883
+ },
884
+ children: [
885
+ showOutline && /* @__PURE__ */ jsx(
886
+ "div",
887
+ {
888
+ style: {
889
+ position: "absolute",
890
+ top: -10,
891
+ left: 4,
892
+ fontSize: 10,
893
+ fontWeight: 600,
894
+ fontFamily: "system-ui, -apple-system, sans-serif",
895
+ color: "#fff",
896
+ backgroundColor: isSelected ? "#3b82f6" : "#93c5fd",
897
+ padding: "1px 6px",
898
+ borderRadius: 3,
899
+ zIndex: 1e4,
900
+ pointerEvents: "none",
901
+ whiteSpace: "nowrap"
902
+ },
903
+ children: label
904
+ }
905
+ ),
906
+ children
907
+ ]
908
+ }
909
+ );
910
+ }
911
+
912
+ // src/components/field-matcher.ts
913
+ var AGG_PREFIXES = ["total_", "sum_", "avg_", "count_", "min_", "max_", "num_"];
914
+ var NOISE_SUFFIXES = ["_name", "_id", "_value", "_val", "_amt", "_amount"];
915
+ function camelToSnake(s) {
916
+ return s.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase();
917
+ }
918
+ function normalize(s) {
919
+ let result = camelToSnake(s).toLowerCase().trim();
920
+ for (const prefix of AGG_PREFIXES) {
921
+ if (result.startsWith(prefix) && result.length > prefix.length) {
922
+ result = result.slice(prefix.length);
923
+ break;
924
+ }
925
+ }
926
+ for (const suffix of NOISE_SUFFIXES) {
927
+ if (result.endsWith(suffix) && result.length > suffix.length) {
928
+ result = result.slice(0, -suffix.length);
929
+ break;
930
+ }
931
+ }
932
+ return result;
933
+ }
934
+ function matchExact(column, catalog) {
935
+ const lower = column.toLowerCase();
936
+ return catalog.find((f) => f.name.toLowerCase() === lower) ?? null;
937
+ }
938
+ function matchNormalized(column, catalog) {
939
+ const norm = normalize(column);
940
+ return catalog.find((f) => normalize(f.name) === norm) ?? null;
941
+ }
942
+ function matchDisplayName(column, catalog) {
943
+ const lower = normalize(column).replace(/_/g, " ");
944
+ if (lower.length < 3) return null;
945
+ return catalog.find((f) => f.displayName.toLowerCase().includes(lower)) ?? catalog.find((f) => f.description.toLowerCase().includes(lower)) ?? null;
946
+ }
947
+ function matchFields(columns, catalog) {
948
+ return columns.map((column) => {
949
+ const exact = matchExact(column, catalog);
950
+ if (exact) return { column, suggestedField: exact, confidence: "exact" };
951
+ const normalized = matchNormalized(column, catalog);
952
+ if (normalized) return { column, suggestedField: normalized, confidence: "fuzzy" };
953
+ const display = matchDisplayName(column, catalog);
954
+ if (display) return { column, suggestedField: display, confidence: "fuzzy" };
955
+ return { column, suggestedField: null, confidence: "manual" };
956
+ });
957
+ }
958
+
959
+ // src/components/prompt-generator.ts
960
+ function generateMigrationPrompt(componentLabel, mappings) {
961
+ const resolved = mappings.filter((m) => m.field !== null);
962
+ if (resolved.length === 0) {
963
+ return `Replace the sample/hardcoded data in the "${componentLabel}" component with live data from the semantic layer using useSemanticQuery. Use the DataCatalog to find the right field names.`;
964
+ }
965
+ const metrics = resolved.filter((m) => m.field.type === "metric").map((m) => m.field.name);
966
+ const timeDims = resolved.filter((m) => m.field.type === "time_dimension").map((m) => m.field.name);
967
+ const dims = resolved.filter((m) => m.field.type === "dimension").map((m) => m.field.name);
968
+ const groupBy = [...timeDims, ...dims];
969
+ const parts = [
970
+ `Replace the sample/hardcoded data in the "${componentLabel}" component with a useSemanticQuery call using:`
971
+ ];
972
+ if (metrics.length > 0) {
973
+ parts.push(` metrics: [${metrics.map((n) => `'${n}'`).join(", ")}]`);
974
+ }
975
+ if (groupBy.length > 0) {
976
+ parts.push(` groupBy: [${groupBy.map((n) => `'${n}'`).join(", ")}]`);
977
+ }
978
+ if (timeDims.length > 0) {
979
+ parts.push(` grain: 'month'`);
980
+ }
981
+ parts.push("");
982
+ parts.push("Map the query result columns to the component's props:");
983
+ for (const m of resolved) {
984
+ parts.push(` "${m.column}" \u2192 data column "${m.field.name}"`);
985
+ }
986
+ parts.push("");
987
+ parts.push(
988
+ "Remove the old hardcoded/sample data and any fetch logic it used. Use the data, isLoading, and error values from useSemanticQuery to render the component."
989
+ );
990
+ return parts.join("\n");
991
+ }
992
+ function DataInspector({ children }) {
993
+ return /* @__PURE__ */ jsxs(InspectableRegistry, { children: [
994
+ /* @__PURE__ */ jsx(InspectorOverlay, {}),
995
+ children
996
+ ] });
997
+ }
998
+ function InspectorOverlay() {
999
+ const registry = useContext(InspectableRegistryContext);
1000
+ if (!registry) return null;
1001
+ const { inspectActive, setInspectActive, selectedId, setSelectedId, entries } = registry;
1002
+ useEffect(() => {
1003
+ function handleKeyDown(e) {
1004
+ if (e.ctrlKey && e.shiftKey && e.key === "I") {
1005
+ e.preventDefault();
1006
+ setInspectActive(!inspectActive);
1007
+ }
1008
+ }
1009
+ window.addEventListener("keydown", handleKeyDown);
1010
+ return () => window.removeEventListener("keydown", handleKeyDown);
1011
+ }, [inspectActive, setInspectActive]);
1012
+ const selectedEntry = selectedId ? entries.get(selectedId) ?? null : null;
1013
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1014
+ /* @__PURE__ */ jsx(
1015
+ ToggleButton,
1016
+ {
1017
+ active: inspectActive,
1018
+ count: entries.size,
1019
+ onToggle: () => {
1020
+ setInspectActive(!inspectActive);
1021
+ if (inspectActive) setSelectedId(null);
1022
+ }
1023
+ }
1024
+ ),
1025
+ selectedEntry && /* @__PURE__ */ jsx(
1026
+ InspectorModal,
1027
+ {
1028
+ entry: selectedEntry,
1029
+ onClose: () => setSelectedId(null)
1030
+ }
1031
+ )
1032
+ ] });
1033
+ }
1034
+ function ToggleButton({
1035
+ active,
1036
+ count,
1037
+ onToggle
1038
+ }) {
1039
+ return /* @__PURE__ */ jsxs(
1040
+ "button",
1041
+ {
1042
+ onClick: onToggle,
1043
+ title: active ? "Exit inspect mode (Ctrl+Shift+I)" : "Enter inspect mode (Ctrl+Shift+I)",
1044
+ style: {
1045
+ position: "fixed",
1046
+ bottom: 20,
1047
+ right: 20,
1048
+ zIndex: 99999,
1049
+ display: "flex",
1050
+ alignItems: "center",
1051
+ gap: 6,
1052
+ padding: "8px 16px",
1053
+ fontSize: 13,
1054
+ fontWeight: 600,
1055
+ fontFamily: "system-ui, -apple-system, sans-serif",
1056
+ color: active ? "#fff" : "#374151",
1057
+ backgroundColor: active ? "#3b82f6" : "#fff",
1058
+ border: `1px solid ${active ? "#2563eb" : "#d1d5db"}`,
1059
+ borderRadius: 999,
1060
+ cursor: "pointer",
1061
+ boxShadow: "0 2px 8px rgba(0,0,0,0.12)",
1062
+ transition: "all 0.15s ease"
1063
+ },
1064
+ children: [
1065
+ /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
1066
+ /* @__PURE__ */ jsx("circle", { cx: "11", cy: "11", r: "8" }),
1067
+ /* @__PURE__ */ jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
1068
+ ] }),
1069
+ active ? "Inspecting" : "Inspect Data",
1070
+ count > 0 && /* @__PURE__ */ jsx(
1071
+ "span",
1072
+ {
1073
+ style: {
1074
+ display: "inline-flex",
1075
+ alignItems: "center",
1076
+ justifyContent: "center",
1077
+ minWidth: 18,
1078
+ height: 18,
1079
+ fontSize: 11,
1080
+ fontWeight: 700,
1081
+ borderRadius: 999,
1082
+ backgroundColor: active ? "rgba(255,255,255,0.25)" : "#e5e7eb",
1083
+ color: active ? "#fff" : "#6b7280",
1084
+ padding: "0 5px"
1085
+ },
1086
+ children: count
1087
+ }
1088
+ )
1089
+ ]
1090
+ }
1091
+ );
1092
+ }
1093
+ function InspectorModal({
1094
+ entry,
1095
+ onClose
1096
+ }) {
1097
+ const { fields: catalog } = useMetrics();
1098
+ const initialMatches = useMemo(
1099
+ () => matchFields(entry.columns, catalog),
1100
+ [entry.columns, catalog]
1101
+ );
1102
+ const [mappings, setMappings] = useState(
1103
+ () => new Map(initialMatches.map((m) => [m.column, m.suggestedField]))
1104
+ );
1105
+ useEffect(() => {
1106
+ setMappings(new Map(initialMatches.map((m) => [m.column, m.suggestedField])));
1107
+ }, [initialMatches]);
1108
+ const [copied, setCopied] = useState(false);
1109
+ const handleFieldChange = useCallback((column, field) => {
1110
+ setMappings((prev) => {
1111
+ const next = new Map(prev);
1112
+ next.set(column, field);
1113
+ return next;
1114
+ });
1115
+ }, []);
1116
+ const handleGenerate = useCallback(async () => {
1117
+ const fieldMappings = entry.columns.map((col) => ({
1118
+ column: col,
1119
+ field: mappings.get(col) ?? null
1120
+ }));
1121
+ const prompt = generateMigrationPrompt(entry.label, fieldMappings);
1122
+ try {
1123
+ await navigator.clipboard.writeText(prompt);
1124
+ setCopied(true);
1125
+ setTimeout(() => setCopied(false), 2e3);
1126
+ } catch {
1127
+ const ta = document.createElement("textarea");
1128
+ ta.value = prompt;
1129
+ document.body.appendChild(ta);
1130
+ ta.select();
1131
+ document.execCommand("copy");
1132
+ document.body.removeChild(ta);
1133
+ setCopied(true);
1134
+ setTimeout(() => setCopied(false), 2e3);
1135
+ }
1136
+ }, [entry, mappings]);
1137
+ const confidenceMap = useMemo(() => {
1138
+ const map = /* @__PURE__ */ new Map();
1139
+ for (const m of initialMatches) map.set(m.column, m.confidence);
1140
+ return map;
1141
+ }, [initialMatches]);
1142
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1143
+ /* @__PURE__ */ jsx("div", { onClick: onClose, style: backdropStyle }),
1144
+ /* @__PURE__ */ jsxs("div", { style: modalStyle, children: [
1145
+ /* @__PURE__ */ jsxs("div", { style: modalHeaderStyle, children: [
1146
+ /* @__PURE__ */ jsxs("div", { children: [
1147
+ /* @__PURE__ */ jsx("div", { style: { fontSize: 16, fontWeight: 700, color: "#111827" }, children: entry.label }),
1148
+ /* @__PURE__ */ jsxs("div", { style: { fontSize: 12, color: "#6b7280", marginTop: 2 }, children: [
1149
+ "Source: ",
1150
+ entry.currentSource
1151
+ ] })
1152
+ ] }),
1153
+ /* @__PURE__ */ jsx("button", { onClick: onClose, style: closeBtnStyle, children: "\xD7" })
1154
+ ] }),
1155
+ entry.sampleValues.length > 0 && /* @__PURE__ */ jsxs("div", { style: sectionStyle, children: [
1156
+ /* @__PURE__ */ jsx("div", { style: sectionTitleStyle, children: "Current Data Preview" }),
1157
+ /* @__PURE__ */ jsx("div", { style: { overflow: "auto" }, children: /* @__PURE__ */ jsxs("table", { style: previewTableStyle, children: [
1158
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: entry.columns.map((col) => /* @__PURE__ */ jsx("th", { style: previewThStyle, children: col }, col)) }) }),
1159
+ /* @__PURE__ */ jsx("tbody", { children: entry.sampleValues.map((row, i) => /* @__PURE__ */ jsx("tr", { children: entry.columns.map((col) => /* @__PURE__ */ jsx("td", { style: previewTdStyle, children: row[col] === null || row[col] === void 0 ? "\u2014" : String(row[col]) }, col)) }, i)) })
1160
+ ] }) })
1161
+ ] }),
1162
+ /* @__PURE__ */ jsxs("div", { style: sectionStyle, children: [
1163
+ /* @__PURE__ */ jsx("div", { style: sectionTitleStyle, children: "Field Mapping" }),
1164
+ /* @__PURE__ */ jsxs("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: 13 }, children: [
1165
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1166
+ /* @__PURE__ */ jsx("th", { style: mappingThStyle, children: "Current Column" }),
1167
+ /* @__PURE__ */ jsx("th", { style: mappingThStyle, children: "Confidence" }),
1168
+ /* @__PURE__ */ jsx("th", { style: mappingThStyle, children: "Semantic Layer Field" })
1169
+ ] }) }),
1170
+ /* @__PURE__ */ jsx("tbody", { children: entry.columns.map((col) => /* @__PURE__ */ jsx(
1171
+ MappingRow,
1172
+ {
1173
+ column: col,
1174
+ confidence: confidenceMap.get(col) ?? "manual",
1175
+ selectedField: mappings.get(col) ?? null,
1176
+ catalog,
1177
+ onChange: (field) => handleFieldChange(col, field)
1178
+ },
1179
+ col
1180
+ )) })
1181
+ ] }),
1182
+ catalog.length === 0 && /* @__PURE__ */ jsx("div", { style: { fontSize: 12, color: "#9ca3af", marginTop: 8, textAlign: "center" }, children: "No semantic layer catalog available. Connect to the gateway to enable smart matching." })
1183
+ ] }),
1184
+ /* @__PURE__ */ jsx("div", { style: { padding: "12px 20px", borderTop: "1px solid #e5e7eb" }, children: /* @__PURE__ */ jsx("button", { onClick: handleGenerate, style: generateBtnStyle, children: copied ? "Copied to clipboard!" : "Generate Migration Prompt" }) })
1185
+ ] })
1186
+ ] });
1187
+ }
1188
+ function MappingRow({
1189
+ column,
1190
+ confidence,
1191
+ selectedField,
1192
+ catalog,
1193
+ onChange
1194
+ }) {
1195
+ const badgeColors = {
1196
+ exact: { bg: "#dcfce7", color: "#15803d" },
1197
+ fuzzy: { bg: "#fef9c3", color: "#a16207" },
1198
+ manual: { bg: "#fee2e2", color: "#dc2626" }
1199
+ };
1200
+ const badge = badgeColors[confidence] ?? badgeColors.manual;
1201
+ return /* @__PURE__ */ jsxs("tr", { children: [
1202
+ /* @__PURE__ */ jsx("td", { style: mappingTdStyle, children: /* @__PURE__ */ jsx("code", { style: { fontSize: 12, color: "#6366f1", fontFamily: "monospace" }, children: column }) }),
1203
+ /* @__PURE__ */ jsx("td", { style: { ...mappingTdStyle, textAlign: "center" }, children: /* @__PURE__ */ jsx(
1204
+ "span",
1205
+ {
1206
+ style: {
1207
+ display: "inline-block",
1208
+ padding: "1px 6px",
1209
+ fontSize: 10,
1210
+ fontWeight: 600,
1211
+ borderRadius: 4,
1212
+ backgroundColor: badge.bg,
1213
+ color: badge.color
1214
+ },
1215
+ children: confidence
1216
+ }
1217
+ ) }),
1218
+ /* @__PURE__ */ jsx("td", { style: mappingTdStyle, children: catalog.length > 0 ? /* @__PURE__ */ jsxs(
1219
+ "select",
1220
+ {
1221
+ value: selectedField?.name ?? "",
1222
+ onChange: (e) => {
1223
+ const field = catalog.find((f) => f.name === e.target.value) ?? null;
1224
+ onChange(field);
1225
+ },
1226
+ style: selectStyle2,
1227
+ children: [
1228
+ /* @__PURE__ */ jsx("option", { value: "", children: "-- none --" }),
1229
+ catalog.map((f) => /* @__PURE__ */ jsxs("option", { value: f.name, children: [
1230
+ f.displayName,
1231
+ " (",
1232
+ f.type,
1233
+ ") \u2014 ",
1234
+ f.name
1235
+ ] }, f.name))
1236
+ ]
1237
+ }
1238
+ ) : /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: "#9ca3af" }, children: selectedField ? selectedField.name : "No catalog" }) })
1239
+ ] });
1240
+ }
1241
+ var backdropStyle = {
1242
+ position: "fixed",
1243
+ inset: 0,
1244
+ backgroundColor: "rgba(0,0,0,0.3)",
1245
+ zIndex: 1e5
1246
+ };
1247
+ var modalStyle = {
1248
+ position: "fixed",
1249
+ top: "50%",
1250
+ left: "50%",
1251
+ transform: "translate(-50%, -50%)",
1252
+ zIndex: 100001,
1253
+ width: "min(640px, 90vw)",
1254
+ maxHeight: "80vh",
1255
+ backgroundColor: "#fff",
1256
+ borderRadius: 12,
1257
+ boxShadow: "0 8px 30px rgba(0,0,0,0.2)",
1258
+ display: "flex",
1259
+ flexDirection: "column",
1260
+ overflow: "hidden",
1261
+ fontFamily: "system-ui, -apple-system, sans-serif"
1262
+ };
1263
+ var modalHeaderStyle = {
1264
+ display: "flex",
1265
+ justifyContent: "space-between",
1266
+ alignItems: "flex-start",
1267
+ padding: "16px 20px",
1268
+ borderBottom: "1px solid #e5e7eb"
1269
+ };
1270
+ var closeBtnStyle = {
1271
+ background: "none",
1272
+ border: "none",
1273
+ fontSize: 22,
1274
+ color: "#6b7280",
1275
+ cursor: "pointer",
1276
+ padding: "0 4px",
1277
+ lineHeight: 1
1278
+ };
1279
+ var sectionStyle = {
1280
+ padding: "12px 20px",
1281
+ overflow: "auto",
1282
+ flex: 1
1283
+ };
1284
+ var sectionTitleStyle = {
1285
+ fontSize: 11,
1286
+ fontWeight: 700,
1287
+ textTransform: "uppercase",
1288
+ letterSpacing: "0.05em",
1289
+ color: "#6b7280",
1290
+ marginBottom: 8
1291
+ };
1292
+ var previewTableStyle = {
1293
+ width: "100%",
1294
+ borderCollapse: "collapse",
1295
+ fontSize: 12
1296
+ };
1297
+ var previewThStyle = {
1298
+ padding: "4px 8px",
1299
+ textAlign: "left",
1300
+ fontWeight: 600,
1301
+ color: "#374151",
1302
+ backgroundColor: "#f9fafb",
1303
+ borderBottom: "1px solid #e5e7eb",
1304
+ whiteSpace: "nowrap"
1305
+ };
1306
+ var previewTdStyle = {
1307
+ padding: "4px 8px",
1308
+ color: "#6b7280",
1309
+ borderBottom: "1px solid #f3f4f6",
1310
+ whiteSpace: "nowrap",
1311
+ maxWidth: 150,
1312
+ overflow: "hidden",
1313
+ textOverflow: "ellipsis"
1314
+ };
1315
+ var mappingThStyle = {
1316
+ padding: "6px 8px",
1317
+ textAlign: "left",
1318
+ fontWeight: 600,
1319
+ fontSize: 11,
1320
+ color: "#6b7280",
1321
+ borderBottom: "1px solid #e5e7eb"
1322
+ };
1323
+ var mappingTdStyle = {
1324
+ padding: "6px 8px",
1325
+ borderBottom: "1px solid #f3f4f6",
1326
+ verticalAlign: "middle"
1327
+ };
1328
+ var selectStyle2 = {
1329
+ width: "100%",
1330
+ padding: "4px 6px",
1331
+ fontSize: 12,
1332
+ border: "1px solid #d1d5db",
1333
+ borderRadius: 4,
1334
+ backgroundColor: "#fff",
1335
+ color: "#111827"
1336
+ };
1337
+ var generateBtnStyle = {
1338
+ width: "100%",
1339
+ padding: "10px 16px",
1340
+ fontSize: 14,
1341
+ fontWeight: 600,
1342
+ color: "#fff",
1343
+ backgroundColor: "#3b82f6",
1344
+ border: "none",
1345
+ borderRadius: 8,
1346
+ cursor: "pointer"
1347
+ };
806
1348
 
807
- export { AdminDashboard, DataCatalog, MetricPicker, ResultsTable };
1349
+ export { AdminDashboard, DataCatalog, DataInspector, Inspectable, MetricPicker, ResultsTable, generateMigrationPrompt, matchFields };
808
1350
  //# sourceMappingURL=components.js.map
809
1351
  //# sourceMappingURL=components.js.map