clivly 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -3
- package/adapter-nLfZpgIG.d.cts +40 -0
- package/adapter-xs04z0KX.d.mts +40 -0
- package/auth-adapter-CBOKDhlc.cjs +11 -0
- package/auth-adapter-FEOR1nx-.d.mts +30 -0
- package/auth-adapter-wqnnEjo3.mjs +6 -0
- package/auth-adapter-wvfGKsOJ.d.cts +30 -0
- package/auth-better-auth.cjs +28 -0
- package/auth-better-auth.d.cts +33 -0
- package/auth-better-auth.d.mts +33 -0
- package/auth-better-auth.mjs +26 -0
- package/auth-clerk.cjs +34 -0
- package/auth-clerk.d.cts +32 -0
- package/auth-clerk.d.mts +32 -0
- package/auth-clerk.mjs +32 -0
- package/auth-workos.cjs +47 -0
- package/auth-workos.d.cts +30 -0
- package/auth-workos.d.mts +30 -0
- package/auth-workos.mjs +45 -0
- package/core-adapter.cjs +0 -0
- package/core-adapter.d.cts +2 -0
- package/core-adapter.d.mts +2 -0
- package/core-adapter.mjs +1 -0
- package/core-auth-adapter.cjs +3 -0
- package/core-auth-adapter.d.cts +2 -0
- package/core-auth-adapter.d.mts +2 -0
- package/core-auth-adapter.mjs +2 -0
- package/core-drizzle.cjs +32 -0
- package/core-drizzle.d.cts +21 -0
- package/core-drizzle.d.mts +21 -0
- package/core-drizzle.mjs +31 -0
- package/core-entity-config.cjs +13 -0
- package/core-entity-config.d.cts +2 -0
- package/core-entity-config.d.mts +2 -0
- package/core-entity-config.mjs +2 -0
- package/core-entity-heuristics.cjs +442 -0
- package/core-entity-heuristics.d.cts +68 -0
- package/core-entity-heuristics.d.mts +68 -0
- package/core-entity-heuristics.mjs +431 -0
- package/core-mapping-form.cjs +5 -0
- package/core-mapping-form.d.cts +2 -0
- package/core-mapping-form.d.mts +2 -0
- package/core-mapping-form.mjs +2 -0
- package/core-mapping-score.cjs +12 -0
- package/core-mapping-score.d.cts +2 -0
- package/core-mapping-score.d.mts +2 -0
- package/core-mapping-score.mjs +2 -0
- package/core-mappings-config.cjs +3 -0
- package/core-mappings-config.d.cts +2 -0
- package/core-mappings-config.d.mts +2 -0
- package/core-mappings-config.mjs +2 -0
- package/core-sync-engine.cjs +6 -0
- package/core-sync-engine.d.cts +2 -0
- package/core-sync-engine.d.mts +2 -0
- package/core-sync-engine.mjs +2 -0
- package/core-types.cjs +0 -0
- package/core-types.d.cts +2 -0
- package/core-types.d.mts +2 -0
- package/core-types.mjs +1 -0
- package/core-view-compiler.cjs +5 -0
- package/core-view-compiler.d.cts +2 -0
- package/core-view-compiler.d.mts +2 -0
- package/core-view-compiler.mjs +2 -0
- package/core.cjs +27 -0
- package/core.d.cts +9 -0
- package/core.d.mts +9 -0
- package/core.mjs +7 -0
- package/drizzle-meta-BGn0BqGb.cjs +9 -0
- package/drizzle-meta-CnC336L-.mjs +4 -0
- package/drizzle.cjs +107 -0
- package/drizzle.d.cts +28 -0
- package/drizzle.d.mts +28 -0
- package/drizzle.mjs +105 -0
- package/entity-config-Cvjo1cpv.cjs +4598 -0
- package/entity-config-D1DFyeUp.d.mts +2403 -0
- package/entity-config-DoR0khce.mjs +4533 -0
- package/entity-config-GczjD3y8.d.cts +2403 -0
- package/index.cjs +926 -0
- package/index.d.cts +56 -0
- package/index.d.mts +56 -0
- package/{dist/index.mjs → index.mjs} +430 -47
- package/mapping-form-BHtPexzI.mjs +47 -0
- package/mapping-form-CUlFVfG8.d.cts +35 -0
- package/mapping-form-DdmDebC3.cjs +64 -0
- package/mapping-form-kjSiJaCX.d.mts +35 -0
- package/mapping-score-A2lRnlpk.d.mts +49 -0
- package/mapping-score-BJNe0lFn.mjs +87 -0
- package/mapping-score-BcjC0ZQs.d.cts +49 -0
- package/mapping-score-D9gfhtRu.cjs +146 -0
- package/mappings-config-CYPrzB3K.mjs +99 -0
- package/mappings-config-DTu_2cyx.cjs +104 -0
- package/mappings-config-DjRLCb2Q.d.cts +42 -0
- package/mappings-config-GxiYsSBQ.d.mts +42 -0
- package/namespace-probe-BtS0nXcr.d.cts +299 -0
- package/namespace-probe-CYMie-BI.d.mts +299 -0
- package/package.json +223 -26
- package/sdk-BZUn6wzs.mjs +764 -0
- package/sdk-CP_mYZa5.cjs +793 -0
- package/sdk.cjs +7 -0
- package/sdk.d.cts +33 -0
- package/sdk.d.mts +33 -0
- package/sdk.mjs +2 -0
- package/sync-engine-DUc0qWgo.cjs +230 -0
- package/sync-engine-DWnQPjV3.d.mts +183 -0
- package/sync-engine-DedXngop.mjs +207 -0
- package/sync-engine-uhfzKM-e.d.cts +183 -0
- package/types-C4POUcvk.d.mts +158 -0
- package/types-LJTBhkcN.d.cts +158 -0
- package/view-compiler-B4UYTvRM.d.cts +71 -0
- package/view-compiler-BHzbI9b7.cjs +202 -0
- package/view-compiler-CosFGar8.mjs +185 -0
- package/view-compiler-i_xFf-L0.d.mts +71 -0
- package/vite.cjs +38 -0
- package/vite.d.cts +23 -0
- package/vite.d.mts +23 -0
- package/vite.mjs +37 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { a as Scored } from "./mapping-score-A2lRnlpk.mjs";
|
|
2
|
+
|
|
3
|
+
//#region ../core/src/entity-heuristics.d.ts
|
|
4
|
+
declare const TARGET_CONCEPTS: readonly ["contact", "company", "deal", "activity", "conversation", "note"];
|
|
5
|
+
type TargetConcept = (typeof TARGET_CONCEPTS)[number];
|
|
6
|
+
declare function suggestCursorField(columnKeys: string[]): string | null;
|
|
7
|
+
declare function matchesConcept(tableName: string, concept: TargetConcept): {
|
|
8
|
+
exact: boolean;
|
|
9
|
+
} | null;
|
|
10
|
+
interface DiscoveredColumnMeta {
|
|
11
|
+
isForeignKey?: boolean;
|
|
12
|
+
isPrimaryKey?: boolean;
|
|
13
|
+
name: string;
|
|
14
|
+
nullable?: boolean;
|
|
15
|
+
references?: {
|
|
16
|
+
table: string;
|
|
17
|
+
column: string;
|
|
18
|
+
};
|
|
19
|
+
type?: string;
|
|
20
|
+
}
|
|
21
|
+
interface ScoredTable {
|
|
22
|
+
columns: string[];
|
|
23
|
+
columnsMeta?: DiscoveredColumnMeta[];
|
|
24
|
+
name: string;
|
|
25
|
+
rowCount?: number;
|
|
26
|
+
}
|
|
27
|
+
declare function scoreConcepts(table: ScoredTable): Scored<TargetConcept>[];
|
|
28
|
+
declare function topConcept(table: ScoredTable): {
|
|
29
|
+
best: Scored<TargetConcept>;
|
|
30
|
+
ambiguous: boolean;
|
|
31
|
+
} | null;
|
|
32
|
+
declare function requiredFieldsFor(concept: TargetConcept | "custom"): string[];
|
|
33
|
+
declare function validateMapping(requiredFields: string[], fieldMap: Record<string, string>): {
|
|
34
|
+
valid: boolean;
|
|
35
|
+
missing: string[];
|
|
36
|
+
};
|
|
37
|
+
declare function suggestDiscriminatorColumns(columns: string[]): string[];
|
|
38
|
+
type SuggestedVia = {
|
|
39
|
+
fkOn: "company" | "contact";
|
|
40
|
+
column: string;
|
|
41
|
+
} | {
|
|
42
|
+
through: string;
|
|
43
|
+
localKey: string;
|
|
44
|
+
foreignKey: string;
|
|
45
|
+
};
|
|
46
|
+
interface RelationshipSuggestion {
|
|
47
|
+
/** The related host table. */
|
|
48
|
+
entityTable: string;
|
|
49
|
+
/** Suggested relationship name (defaults to the related concept). */
|
|
50
|
+
name: string;
|
|
51
|
+
via: SuggestedVia;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Suggest contact→company relationships. When the source table carries FK
|
|
55
|
+
* metadata (`references`), the target table is a *fact*, not a name guess —
|
|
56
|
+
* that scores highest. Without metadata (v1 hosts) we fall back to the legacy
|
|
57
|
+
* FK-name hints at a lower tier.
|
|
58
|
+
*/
|
|
59
|
+
declare function scoreRelationships(source: ScoredTable, allTables: ScoredTable[]): Scored<RelationshipSuggestion>[];
|
|
60
|
+
interface FieldSuggestion {
|
|
61
|
+
column: string;
|
|
62
|
+
field: string;
|
|
63
|
+
required: boolean;
|
|
64
|
+
}
|
|
65
|
+
declare function scoreFieldMap(concept: TargetConcept, table: ScoredTable): Scored<FieldSuggestion>[];
|
|
66
|
+
declare function toFieldMap(scored: Scored<FieldSuggestion>[]): Record<string, string>;
|
|
67
|
+
//#endregion
|
|
68
|
+
export { DiscoveredColumnMeta, FieldSuggestion, RelationshipSuggestion, ScoredTable, SuggestedVia, TARGET_CONCEPTS, TargetConcept, matchesConcept, requiredFieldsFor, scoreConcepts, scoreFieldMap, scoreRelationships, suggestCursorField, suggestDiscriminatorColumns, toFieldMap, topConcept, validateMapping };
|
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
import { a as MATERIALIZING_CONCEPTS } from "./entity-config-DoR0khce.mjs";
|
|
2
|
+
import { a as W, c as isTextLike, i as RELATIONSHIP_TIERS, l as isTimestampLike, n as CONCEPT_TIERS, o as isAmbiguous, r as FIELD_TIERS, s as isNumericLike, u as tierFor } from "./mapping-score-BJNe0lFn.mjs";
|
|
3
|
+
//#region ../core/src/entity-heuristics.ts
|
|
4
|
+
const TARGET_CONCEPTS = [
|
|
5
|
+
"contact",
|
|
6
|
+
"company",
|
|
7
|
+
"deal",
|
|
8
|
+
"activity",
|
|
9
|
+
"conversation",
|
|
10
|
+
"note"
|
|
11
|
+
];
|
|
12
|
+
const TABLE_PATTERNS = [
|
|
13
|
+
{
|
|
14
|
+
concept: "contact",
|
|
15
|
+
names: [
|
|
16
|
+
"users",
|
|
17
|
+
"customers",
|
|
18
|
+
"clients",
|
|
19
|
+
"accounts",
|
|
20
|
+
"participants",
|
|
21
|
+
"attendees",
|
|
22
|
+
"people",
|
|
23
|
+
"members",
|
|
24
|
+
"contacts"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
concept: "company",
|
|
29
|
+
names: [
|
|
30
|
+
"companies",
|
|
31
|
+
"organizations",
|
|
32
|
+
"organisations",
|
|
33
|
+
"orgs",
|
|
34
|
+
"teams",
|
|
35
|
+
"businesses",
|
|
36
|
+
"accounts"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
concept: "deal",
|
|
41
|
+
names: [
|
|
42
|
+
"deals",
|
|
43
|
+
"opportunities",
|
|
44
|
+
"subscriptions",
|
|
45
|
+
"orders",
|
|
46
|
+
"invoices",
|
|
47
|
+
"sales"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
concept: "conversation",
|
|
52
|
+
names: [
|
|
53
|
+
"conversations",
|
|
54
|
+
"messages",
|
|
55
|
+
"tickets",
|
|
56
|
+
"threads",
|
|
57
|
+
"chats",
|
|
58
|
+
"inbox"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
concept: "activity",
|
|
63
|
+
names: [
|
|
64
|
+
"events",
|
|
65
|
+
"activities",
|
|
66
|
+
"jobs",
|
|
67
|
+
"logs",
|
|
68
|
+
"audit",
|
|
69
|
+
"shifts",
|
|
70
|
+
"scans",
|
|
71
|
+
"sessions"
|
|
72
|
+
]
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
concept: "note",
|
|
76
|
+
names: [
|
|
77
|
+
"notes",
|
|
78
|
+
"comments",
|
|
79
|
+
"annotations"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
];
|
|
83
|
+
const CONCEPT_FIELDS = {
|
|
84
|
+
contact: [{
|
|
85
|
+
field: "name",
|
|
86
|
+
candidates: [
|
|
87
|
+
"name",
|
|
88
|
+
"full_name",
|
|
89
|
+
"fullname",
|
|
90
|
+
"display_name"
|
|
91
|
+
],
|
|
92
|
+
required: false
|
|
93
|
+
}, {
|
|
94
|
+
field: "email",
|
|
95
|
+
candidates: ["email", "email_address"],
|
|
96
|
+
required: true
|
|
97
|
+
}],
|
|
98
|
+
company: [{
|
|
99
|
+
field: "name",
|
|
100
|
+
candidates: [
|
|
101
|
+
"name",
|
|
102
|
+
"company_name",
|
|
103
|
+
"legal_name",
|
|
104
|
+
"title"
|
|
105
|
+
],
|
|
106
|
+
required: true
|
|
107
|
+
}, {
|
|
108
|
+
field: "domain",
|
|
109
|
+
candidates: [
|
|
110
|
+
"domain",
|
|
111
|
+
"website",
|
|
112
|
+
"url"
|
|
113
|
+
],
|
|
114
|
+
required: false
|
|
115
|
+
}],
|
|
116
|
+
deal: [
|
|
117
|
+
{
|
|
118
|
+
field: "name",
|
|
119
|
+
candidates: ["name", "title"],
|
|
120
|
+
required: true
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
field: "value",
|
|
124
|
+
candidates: [
|
|
125
|
+
"value",
|
|
126
|
+
"amount",
|
|
127
|
+
"total",
|
|
128
|
+
"price"
|
|
129
|
+
],
|
|
130
|
+
required: false
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
field: "stage",
|
|
134
|
+
candidates: [
|
|
135
|
+
"stage",
|
|
136
|
+
"status",
|
|
137
|
+
"state"
|
|
138
|
+
],
|
|
139
|
+
required: false
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
activity: [
|
|
143
|
+
{
|
|
144
|
+
field: "type",
|
|
145
|
+
candidates: [
|
|
146
|
+
"type",
|
|
147
|
+
"kind",
|
|
148
|
+
"event_type"
|
|
149
|
+
],
|
|
150
|
+
required: false
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
field: "summary",
|
|
154
|
+
candidates: [
|
|
155
|
+
"summary",
|
|
156
|
+
"description",
|
|
157
|
+
"message",
|
|
158
|
+
"title"
|
|
159
|
+
],
|
|
160
|
+
required: false
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
field: "createdAt",
|
|
164
|
+
candidates: [
|
|
165
|
+
"created_at",
|
|
166
|
+
"createdat",
|
|
167
|
+
"timestamp"
|
|
168
|
+
],
|
|
169
|
+
required: false
|
|
170
|
+
}
|
|
171
|
+
],
|
|
172
|
+
conversation: [{
|
|
173
|
+
field: "status",
|
|
174
|
+
candidates: ["status", "state"],
|
|
175
|
+
required: false
|
|
176
|
+
}, {
|
|
177
|
+
field: "subject",
|
|
178
|
+
candidates: [
|
|
179
|
+
"subject",
|
|
180
|
+
"title",
|
|
181
|
+
"preview"
|
|
182
|
+
],
|
|
183
|
+
required: false
|
|
184
|
+
}],
|
|
185
|
+
note: [{
|
|
186
|
+
field: "body",
|
|
187
|
+
candidates: [
|
|
188
|
+
"body",
|
|
189
|
+
"content",
|
|
190
|
+
"text",
|
|
191
|
+
"note"
|
|
192
|
+
],
|
|
193
|
+
required: true
|
|
194
|
+
}]
|
|
195
|
+
};
|
|
196
|
+
const CURSOR_CANDIDATES = [
|
|
197
|
+
"updatedat",
|
|
198
|
+
"updated_at",
|
|
199
|
+
"modifiedat",
|
|
200
|
+
"modified_at",
|
|
201
|
+
"createdat",
|
|
202
|
+
"created_at"
|
|
203
|
+
];
|
|
204
|
+
function suggestCursorField(columnKeys) {
|
|
205
|
+
const lowerToActual = new Map(columnKeys.map((c) => [c.toLowerCase(), c]));
|
|
206
|
+
for (const candidate of CURSOR_CANDIDATES) {
|
|
207
|
+
const match = lowerToActual.get(candidate);
|
|
208
|
+
if (match) return match;
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const MATERIALIZING = new Set(MATERIALIZING_CONCEPTS);
|
|
213
|
+
function matchesConcept(tableName, concept) {
|
|
214
|
+
const normalized = tableName.toLowerCase();
|
|
215
|
+
const entry = TABLE_PATTERNS.find((p) => p.concept === concept);
|
|
216
|
+
if (!entry) return null;
|
|
217
|
+
if (entry.names.includes(normalized)) return { exact: true };
|
|
218
|
+
if (entry.names.some((name) => normalized.includes(name))) return { exact: false };
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
function metaFor(table, column) {
|
|
222
|
+
return table.columnsMeta?.find((c) => c.name === column);
|
|
223
|
+
}
|
|
224
|
+
function hasDefiningColumn(concept, columns) {
|
|
225
|
+
const lower = new Set(columns.map((c) => c.toLowerCase()));
|
|
226
|
+
const required = CONCEPT_FIELDS[concept].filter((f) => f.required);
|
|
227
|
+
return required.length > 0 && required.every((f) => f.candidates.some((c) => lower.has(c)));
|
|
228
|
+
}
|
|
229
|
+
function scoreConcepts(table) {
|
|
230
|
+
const out = [];
|
|
231
|
+
for (const concept of TARGET_CONCEPTS) {
|
|
232
|
+
if (!MATERIALIZING.has(concept)) continue;
|
|
233
|
+
const nameMatch = matchesConcept(table.name, concept);
|
|
234
|
+
if (!nameMatch) continue;
|
|
235
|
+
let score = 0;
|
|
236
|
+
const reasons = [];
|
|
237
|
+
if (nameMatch.exact) {
|
|
238
|
+
score += W.nameExact;
|
|
239
|
+
reasons.push(`name matches "${table.name}"`);
|
|
240
|
+
} else {
|
|
241
|
+
score += W.nameSubstring;
|
|
242
|
+
reasons.push(`name looks like ${concept}`);
|
|
243
|
+
}
|
|
244
|
+
if (hasDefiningColumn(concept, table.columns)) {
|
|
245
|
+
score += W.definingColumn;
|
|
246
|
+
reasons.push(`has the columns a ${concept} needs`);
|
|
247
|
+
}
|
|
248
|
+
if (table.columnsMeta?.some((c) => c.isPrimaryKey)) {
|
|
249
|
+
score += W.hasPrimaryKey;
|
|
250
|
+
reasons.push("has primary key");
|
|
251
|
+
}
|
|
252
|
+
if (table.rowCount !== void 0) if (table.rowCount === 0) {
|
|
253
|
+
score += W.emptyTable;
|
|
254
|
+
reasons.push("table is empty");
|
|
255
|
+
} else {
|
|
256
|
+
score += W.hasRows;
|
|
257
|
+
reasons.push(`${table.rowCount.toLocaleString("en-US")} rows`);
|
|
258
|
+
}
|
|
259
|
+
out.push({
|
|
260
|
+
value: concept,
|
|
261
|
+
score,
|
|
262
|
+
tier: tierFor(score, CONCEPT_TIERS),
|
|
263
|
+
reasons
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return out.sort((a, b) => b.score - a.score);
|
|
267
|
+
}
|
|
268
|
+
function topConcept(table) {
|
|
269
|
+
const ranked = scoreConcepts(table);
|
|
270
|
+
const best = ranked[0];
|
|
271
|
+
if (!best) return null;
|
|
272
|
+
return {
|
|
273
|
+
best,
|
|
274
|
+
ambiguous: isAmbiguous(ranked)
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
function requiredFieldsFor(concept) {
|
|
278
|
+
if (concept === "custom") return [];
|
|
279
|
+
return CONCEPT_FIELDS[concept].filter((f) => f.required).map((f) => f.field);
|
|
280
|
+
}
|
|
281
|
+
function validateMapping(requiredFields, fieldMap) {
|
|
282
|
+
const missing = requiredFields.filter((field) => !fieldMap[field]);
|
|
283
|
+
return {
|
|
284
|
+
valid: missing.length === 0,
|
|
285
|
+
missing
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
const DISCRIMINATOR_COLUMNS = [
|
|
289
|
+
"role",
|
|
290
|
+
"type",
|
|
291
|
+
"kind",
|
|
292
|
+
"status",
|
|
293
|
+
"state",
|
|
294
|
+
"category",
|
|
295
|
+
"tier"
|
|
296
|
+
];
|
|
297
|
+
function suggestDiscriminatorColumns(columns) {
|
|
298
|
+
const lowerToActual = new Map(columns.map((c) => [c.toLowerCase(), c]));
|
|
299
|
+
const out = [];
|
|
300
|
+
for (const name of DISCRIMINATOR_COLUMNS) {
|
|
301
|
+
const match = lowerToActual.get(name);
|
|
302
|
+
if (match) out.push(match);
|
|
303
|
+
}
|
|
304
|
+
return out;
|
|
305
|
+
}
|
|
306
|
+
const COMPANY_FK_HINTS = [
|
|
307
|
+
"organization_id",
|
|
308
|
+
"organisation_id",
|
|
309
|
+
"org_id",
|
|
310
|
+
"company_id",
|
|
311
|
+
"account_id",
|
|
312
|
+
"team_id"
|
|
313
|
+
];
|
|
314
|
+
function firstMatchingColumn(columns, hints) {
|
|
315
|
+
const lowerToActual = new Map(columns.map((c) => [c.toLowerCase(), c]));
|
|
316
|
+
for (const hint of hints) {
|
|
317
|
+
const match = lowerToActual.get(hint);
|
|
318
|
+
if (match) return match;
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Suggest contact→company relationships. When the source table carries FK
|
|
324
|
+
* metadata (`references`), the target table is a *fact*, not a name guess —
|
|
325
|
+
* that scores highest. Without metadata (v1 hosts) we fall back to the legacy
|
|
326
|
+
* FK-name hints at a lower tier.
|
|
327
|
+
*/
|
|
328
|
+
function scoreRelationships(source, allTables) {
|
|
329
|
+
const companyTables = allTables.filter((t) => t.name !== source.name && topConcept(t)?.best.value === "company");
|
|
330
|
+
if (companyTables.length === 0) return [];
|
|
331
|
+
const companyNames = new Set(companyTables.map((t) => t.name.toLowerCase()));
|
|
332
|
+
const out = [];
|
|
333
|
+
const seenTargets = /* @__PURE__ */ new Set();
|
|
334
|
+
for (const col of source.columnsMeta ?? []) {
|
|
335
|
+
const ref = col.references;
|
|
336
|
+
if (!(ref && companyNames.has(ref.table.toLowerCase()))) continue;
|
|
337
|
+
if (seenTargets.has(ref.table.toLowerCase())) continue;
|
|
338
|
+
seenTargets.add(ref.table.toLowerCase());
|
|
339
|
+
out.push({
|
|
340
|
+
value: {
|
|
341
|
+
name: "company",
|
|
342
|
+
entityTable: ref.table,
|
|
343
|
+
via: {
|
|
344
|
+
fkOn: "contact",
|
|
345
|
+
column: `${source.name}.${col.name}`
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
score: W.fkResolved,
|
|
349
|
+
tier: tierFor(W.fkResolved, RELATIONSHIP_TIERS),
|
|
350
|
+
reasons: [`foreign key → ${ref.table}.${ref.column}`]
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
if (source.columnsMeta?.length) return out.sort((a, b) => b.score - a.score);
|
|
354
|
+
const contactFk = firstMatchingColumn(source.columns, COMPANY_FK_HINTS);
|
|
355
|
+
if (contactFk) out.push({
|
|
356
|
+
value: {
|
|
357
|
+
name: "company",
|
|
358
|
+
entityTable: companyTables[0]?.name ?? "",
|
|
359
|
+
via: {
|
|
360
|
+
fkOn: "contact",
|
|
361
|
+
column: `${source.name}.${contactFk}`
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
score: W.fkNameHint,
|
|
365
|
+
tier: tierFor(W.fkNameHint, RELATIONSHIP_TIERS),
|
|
366
|
+
reasons: [`column "${contactFk}" looks like a company link`]
|
|
367
|
+
});
|
|
368
|
+
return out.sort((a, b) => b.score - a.score);
|
|
369
|
+
}
|
|
370
|
+
const FIELD_TYPE_EXPECTATION = {
|
|
371
|
+
name: "text",
|
|
372
|
+
email: "text",
|
|
373
|
+
domain: "text",
|
|
374
|
+
stage: "text",
|
|
375
|
+
status: "text",
|
|
376
|
+
subject: "text",
|
|
377
|
+
body: "text",
|
|
378
|
+
summary: "text",
|
|
379
|
+
type: "text",
|
|
380
|
+
value: "numeric",
|
|
381
|
+
createdAt: "timestamp"
|
|
382
|
+
};
|
|
383
|
+
function typeFits(field, type) {
|
|
384
|
+
const expectation = FIELD_TYPE_EXPECTATION[field];
|
|
385
|
+
if (!(expectation && type)) return null;
|
|
386
|
+
if (expectation === "text") return isTextLike(type);
|
|
387
|
+
if (expectation === "numeric") return isNumericLike(type);
|
|
388
|
+
return isTimestampLike(type);
|
|
389
|
+
}
|
|
390
|
+
function scoreFieldMap(concept, table) {
|
|
391
|
+
const lowerToActual = new Map(table.columns.map((c) => [c.toLowerCase(), c]));
|
|
392
|
+
const out = [];
|
|
393
|
+
for (const { field, candidates, required } of CONCEPT_FIELDS[concept]) for (const candidate of candidates) {
|
|
394
|
+
const column = lowerToActual.get(candidate);
|
|
395
|
+
if (!column) continue;
|
|
396
|
+
let score = W.fieldNameMatch;
|
|
397
|
+
const reasons = [`name matches "${column}"`];
|
|
398
|
+
const meta = metaFor(table, column);
|
|
399
|
+
const fits = typeFits(field, meta?.type);
|
|
400
|
+
if (fits === true) {
|
|
401
|
+
score += W.typeCompatible;
|
|
402
|
+
reasons.push(`type ${meta?.type}`);
|
|
403
|
+
} else if (fits === false) {
|
|
404
|
+
score += W.typeMismatch;
|
|
405
|
+
reasons.push(`type ${meta?.type} does not fit ${field}`);
|
|
406
|
+
}
|
|
407
|
+
if (required && meta?.nullable === false) {
|
|
408
|
+
score += W.requiredNotNull;
|
|
409
|
+
reasons.push("not null");
|
|
410
|
+
}
|
|
411
|
+
out.push({
|
|
412
|
+
value: {
|
|
413
|
+
field,
|
|
414
|
+
column,
|
|
415
|
+
required
|
|
416
|
+
},
|
|
417
|
+
score,
|
|
418
|
+
tier: tierFor(score, FIELD_TIERS),
|
|
419
|
+
reasons
|
|
420
|
+
});
|
|
421
|
+
break;
|
|
422
|
+
}
|
|
423
|
+
return out;
|
|
424
|
+
}
|
|
425
|
+
function toFieldMap(scored) {
|
|
426
|
+
const map = {};
|
|
427
|
+
for (const { value } of scored) map[value.field] = value.column;
|
|
428
|
+
return map;
|
|
429
|
+
}
|
|
430
|
+
//#endregion
|
|
431
|
+
export { TARGET_CONCEPTS, matchesConcept, requiredFieldsFor, scoreConcepts, scoreFieldMap, scoreRelationships, suggestCursorField, suggestDiscriminatorColumns, toFieldMap, topConcept, validateMapping };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_mapping_form = require("./mapping-form-DdmDebC3.cjs");
|
|
3
|
+
exports.buildFilterFromDiscriminator = require_mapping_form.buildFilterFromDiscriminator;
|
|
4
|
+
exports.buildRelationships = require_mapping_form.buildRelationships;
|
|
5
|
+
exports.relationshipViaSignature = require_mapping_form.relationshipViaSignature;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_mapping_score = require("./mapping-score-D9gfhtRu.cjs");
|
|
3
|
+
exports.AMBIGUITY_MARGIN = require_mapping_score.AMBIGUITY_MARGIN;
|
|
4
|
+
exports.CONCEPT_TIERS = require_mapping_score.CONCEPT_TIERS;
|
|
5
|
+
exports.FIELD_TIERS = require_mapping_score.FIELD_TIERS;
|
|
6
|
+
exports.RELATIONSHIP_TIERS = require_mapping_score.RELATIONSHIP_TIERS;
|
|
7
|
+
exports.W = require_mapping_score.W;
|
|
8
|
+
exports.isAmbiguous = require_mapping_score.isAmbiguous;
|
|
9
|
+
exports.isNumericLike = require_mapping_score.isNumericLike;
|
|
10
|
+
exports.isTextLike = require_mapping_score.isTextLike;
|
|
11
|
+
exports.isTimestampLike = require_mapping_score.isTimestampLike;
|
|
12
|
+
exports.tierFor = require_mapping_score.tierFor;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as Scored, c as W, d as isTextLike, f as isTimestampLike, i as RELATIONSHIP_TIERS, l as isAmbiguous, n as CONCEPT_TIERS, o as Thresholds, p as tierFor, r as FIELD_TIERS, s as Tier, t as AMBIGUITY_MARGIN, u as isNumericLike } from "./mapping-score-BcjC0ZQs.cjs";
|
|
2
|
+
export { AMBIGUITY_MARGIN, CONCEPT_TIERS, FIELD_TIERS, RELATIONSHIP_TIERS, Scored, Thresholds, Tier, W, isAmbiguous, isNumericLike, isTextLike, isTimestampLike, tierFor };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as Scored, c as W, d as isTextLike, f as isTimestampLike, i as RELATIONSHIP_TIERS, l as isAmbiguous, n as CONCEPT_TIERS, o as Thresholds, p as tierFor, r as FIELD_TIERS, s as Tier, t as AMBIGUITY_MARGIN, u as isNumericLike } from "./mapping-score-A2lRnlpk.mjs";
|
|
2
|
+
export { AMBIGUITY_MARGIN, CONCEPT_TIERS, FIELD_TIERS, RELATIONSHIP_TIERS, Scored, Thresholds, Tier, W, isAmbiguous, isNumericLike, isTextLike, isTimestampLike, tierFor };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as W, c as isTextLike, i as RELATIONSHIP_TIERS, l as isTimestampLike, n as CONCEPT_TIERS, o as isAmbiguous, r as FIELD_TIERS, s as isNumericLike, t as AMBIGUITY_MARGIN, u as tierFor } from "./mapping-score-BJNe0lFn.mjs";
|
|
2
|
+
export { AMBIGUITY_MARGIN, CONCEPT_TIERS, FIELD_TIERS, RELATIONSHIP_TIERS, W, isAmbiguous, isNumericLike, isTextLike, isTimestampLike, tierFor };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_sync_engine = require("./sync-engine-DUc0qWgo.cjs");
|
|
3
|
+
exports.computeSampleWarnings = require_sync_engine.computeSampleWarnings;
|
|
4
|
+
exports.previewSync = require_sync_engine.previewSync;
|
|
5
|
+
exports.reconcile = require_sync_engine.reconcile;
|
|
6
|
+
exports.runSync = require_sync_engine.runSync;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as PreviewWarning, c as SyncResult, d as previewSync, f as reconcile, i as PreviewResult, l as SyncStore, n as MirrorRecord, o as SourceRow, p as runSync, r as PersistAction, s as SyncAction, t as EntitySyncResult, u as computeSampleWarnings } from "./sync-engine-uhfzKM-e.cjs";
|
|
2
|
+
export { EntitySyncResult, MirrorRecord, PersistAction, PreviewResult, PreviewWarning, SourceRow, SyncAction, SyncResult, SyncStore, computeSampleWarnings, previewSync, reconcile, runSync };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as PreviewWarning, c as SyncResult, d as previewSync, f as reconcile, i as PreviewResult, l as SyncStore, n as MirrorRecord, o as SourceRow, p as runSync, r as PersistAction, s as SyncAction, t as EntitySyncResult, u as computeSampleWarnings } from "./sync-engine-DWnQPjV3.mjs";
|
|
2
|
+
export { EntitySyncResult, MirrorRecord, PersistAction, PreviewResult, PreviewWarning, SourceRow, SyncAction, SyncResult, SyncStore, computeSampleWarnings, previewSync, reconcile, runSync };
|
package/core-types.cjs
ADDED
|
File without changes
|
package/core-types.d.cts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-LJTBhkcN.cjs";
|
|
2
|
+
export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
|
package/core-types.d.mts
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-C4POUcvk.mjs";
|
|
2
|
+
export { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmRole, Deal, DealStage, Note, RecordSource, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput };
|
package/core-types.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_view_compiler = require("./view-compiler-BHzbI9b7.cjs");
|
|
3
|
+
exports.compileEntityView = require_view_compiler.compileEntityView;
|
|
4
|
+
exports.compileEntityViews = require_view_compiler.compileEntityViews;
|
|
5
|
+
exports.explainEntitiesConfig = require_view_compiler.explainEntitiesConfig;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as compileEntityViews, i as compileEntityView, n as CompiledView, o as explainEntitiesConfig, r as ExplainResult, t as CompileOptions } from "./view-compiler-B4UYTvRM.cjs";
|
|
2
|
+
export { CompileOptions, CompiledView, ExplainResult, compileEntityView, compileEntityViews, explainEntitiesConfig };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as compileEntityViews, i as compileEntityView, n as CompiledView, o as explainEntitiesConfig, r as ExplainResult, t as CompileOptions } from "./view-compiler-i_xFf-L0.mjs";
|
|
2
|
+
export { CompileOptions, CompiledView, ExplainResult, compileEntityView, compileEntityViews, explainEntitiesConfig };
|
package/core.cjs
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_entity_config = require("./entity-config-Cvjo1cpv.cjs");
|
|
3
|
+
const require_auth_adapter = require("./auth-adapter-CBOKDhlc.cjs");
|
|
4
|
+
const require_mapping_form = require("./mapping-form-DdmDebC3.cjs");
|
|
5
|
+
const require_mappings_config = require("./mappings-config-DTu_2cyx.cjs");
|
|
6
|
+
const require_view_compiler = require("./view-compiler-BHzbI9b7.cjs");
|
|
7
|
+
const require_sync_engine = require("./sync-engine-DUc0qWgo.cjs");
|
|
8
|
+
exports.CANONICAL_FIELDS = require_entity_config.CANONICAL_FIELDS;
|
|
9
|
+
exports.CRM_CONCEPTS = require_entity_config.CRM_CONCEPTS;
|
|
10
|
+
exports.ClivlyConfigError = require_entity_config.ClivlyConfigError;
|
|
11
|
+
exports.MATERIALIZING_CONCEPTS = require_entity_config.MATERIALIZING_CONCEPTS;
|
|
12
|
+
exports.authCustom = require_auth_adapter.authCustom;
|
|
13
|
+
exports.buildFilterFromDiscriminator = require_mapping_form.buildFilterFromDiscriminator;
|
|
14
|
+
exports.buildRelationships = require_mapping_form.buildRelationships;
|
|
15
|
+
exports.compileEntityView = require_view_compiler.compileEntityView;
|
|
16
|
+
exports.compileEntityViews = require_view_compiler.compileEntityViews;
|
|
17
|
+
exports.defineClivlyConfig = require_entity_config.defineClivlyConfig;
|
|
18
|
+
exports.entitiesConfigSchema = require_entity_config.entitiesConfigSchema;
|
|
19
|
+
exports.explainEntitiesConfig = require_view_compiler.explainEntitiesConfig;
|
|
20
|
+
exports.filterSchema = require_entity_config.filterSchema;
|
|
21
|
+
exports.mappingsToEntitiesConfig = require_mappings_config.mappingsToEntitiesConfig;
|
|
22
|
+
exports.reconcile = require_sync_engine.reconcile;
|
|
23
|
+
exports.relationshipSchema = require_entity_config.relationshipSchema;
|
|
24
|
+
exports.relationshipViaSignature = require_mapping_form.relationshipViaSignature;
|
|
25
|
+
exports.relationshipsSchema = require_entity_config.relationshipsSchema;
|
|
26
|
+
exports.runSync = require_sync_engine.runSync;
|
|
27
|
+
exports.validateEntitiesConfig = require_entity_config.validateEntitiesConfig;
|
package/core.d.cts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { C as UpdateDealInput, S as UpdateContactInput, _ as Task, a as ContactFilters, b as TaskPriority, c as CreateCompanyInput, d as CreateTaskInput, f as CrmRole, g as RecordSource, h as Note, i as Contact, l as CreateContactInput, m as DealStage, n as ActivityType, o as ContactStatus, p as Deal, r as Company, s as CreateActivityInput, t as Activity, u as CreateDealInput, v as TaskEntityType, w as UpdateTaskInput, x as TaskStatus, y as TaskFilters } from "./types-LJTBhkcN.cjs";
|
|
2
|
+
import { a as authCustom, i as MembershipResolver, n as ClivlyUser, r as CrmMembership, t as ClivlyAuthAdapter } from "./auth-adapter-wvfGKsOJ.cjs";
|
|
3
|
+
import { t as CRMAdapter } from "./adapter-nLfZpgIG.cjs";
|
|
4
|
+
import { C as validateEntitiesConfig, S as relationshipsSchema, _ as RelationshipsMap, a as ClivlyEntitiesConfig, b as filterSchema, c as ConfigValidationResult, d as FilterExpr, f as FilterValue, g as RelationshipVia, h as RelationshipSpec, i as ClivlyConfigError, l as CrmConcept, m as MaterializingConcept, n as CRM_CONCEPTS, o as ClivlyEntityConfig, p as MATERIALIZING_CONCEPTS, s as ConfigValidationError, t as CANONICAL_FIELDS, u as DiscoveredSchemaTable, v as defineClivlyConfig, x as relationshipSchema, y as entitiesConfigSchema } from "./entity-config-GczjD3y8.cjs";
|
|
5
|
+
import { i as relationshipViaSignature, n as buildFilterFromDiscriminator, r as buildRelationships, t as RelationshipCandidate } from "./mapping-form-CUlFVfG8.cjs";
|
|
6
|
+
import { n as mappingsToEntitiesConfig, t as EntityMappingRow } from "./mappings-config-DjRLCb2Q.cjs";
|
|
7
|
+
import { a as compileEntityViews, i as compileEntityView, n as CompiledView, o as explainEntitiesConfig, r as ExplainResult, t as CompileOptions } from "./view-compiler-B4UYTvRM.cjs";
|
|
8
|
+
import { c as SyncResult, f as reconcile, l as SyncStore, n as MirrorRecord, o as SourceRow, p as runSync, r as PersistAction, s as SyncAction, t as EntitySyncResult } from "./sync-engine-uhfzKM-e.cjs";
|
|
9
|
+
export { Activity, ActivityType, CANONICAL_FIELDS, CRMAdapter, CRM_CONCEPTS, ClivlyAuthAdapter, ClivlyConfigError, ClivlyEntitiesConfig, ClivlyEntityConfig, ClivlyUser, Company, CompileOptions, CompiledView, ConfigValidationError, ConfigValidationResult, Contact, ContactFilters, ContactStatus, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, CrmConcept, CrmMembership, CrmRole, Deal, DealStage, DiscoveredSchemaTable, EntityMappingRow, EntitySyncResult, ExplainResult, FilterExpr, FilterValue, MATERIALIZING_CONCEPTS, MaterializingConcept, MembershipResolver, MirrorRecord, Note, PersistAction, RecordSource, RelationshipCandidate, RelationshipSpec, RelationshipVia, RelationshipsMap, SourceRow, SyncAction, SyncResult, SyncStore, Task, TaskEntityType, TaskFilters, TaskPriority, TaskStatus, UpdateContactInput, UpdateDealInput, UpdateTaskInput, authCustom, buildFilterFromDiscriminator, buildRelationships, compileEntityView, compileEntityViews, defineClivlyConfig, entitiesConfigSchema, explainEntitiesConfig, filterSchema, mappingsToEntitiesConfig, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, validateEntitiesConfig };
|