@seedprotocol/mapping 0.7.1 → 0.7.2-next.593.gd5bd4ea
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seedprotocol/mapping",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2-next.593.gd5bd4ea",
|
|
4
4
|
"description": "Source-to-model-property field mapping helpers and UI for Seed Protocol",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -63,6 +63,11 @@
|
|
|
63
63
|
},
|
|
64
64
|
"author": "Keith Axline <keith@journodao.xyz>",
|
|
65
65
|
"license": "MIT",
|
|
66
|
+
"repository": {
|
|
67
|
+
"type": "git",
|
|
68
|
+
"url": "git+https://github.com/JournoLabs/seed-protocol-sdk.git",
|
|
69
|
+
"directory": "packages/mapping"
|
|
70
|
+
},
|
|
66
71
|
"publishConfig": {
|
|
67
72
|
"access": "public"
|
|
68
73
|
}
|
package/dist/autoMap-OMvtOG0S.js
DELETED
|
@@ -1,549 +0,0 @@
|
|
|
1
|
-
//#region src/relationLookup.ts
|
|
2
|
-
function e(e) {
|
|
3
|
-
return e.dataType === "Relation" ? !0 : e.dataType === "List" ? e.refValueType === "Relation" || !!e.ref : !1;
|
|
4
|
-
}
|
|
5
|
-
function t(e) {
|
|
6
|
-
return e.replace(/\s+/g, " ").trim();
|
|
7
|
-
}
|
|
8
|
-
function n(e) {
|
|
9
|
-
return e ? t(e.value || e.label) : "";
|
|
10
|
-
}
|
|
11
|
-
function r(e, t) {
|
|
12
|
-
if (t.dataType === "List") {
|
|
13
|
-
if (Array.isArray(e)) return e.map((e) => String(e).trim()).filter(Boolean);
|
|
14
|
-
let t = String(e).trim();
|
|
15
|
-
return t ? [t] : [];
|
|
16
|
-
}
|
|
17
|
-
return Array.isArray(e) ? String(e[0] ?? "").trim() : String(e).trim();
|
|
18
|
-
}
|
|
19
|
-
function i(e) {
|
|
20
|
-
return e?.lookup?.entries ?? [];
|
|
21
|
-
}
|
|
22
|
-
function a(e, n) {
|
|
23
|
-
let r = t(n);
|
|
24
|
-
if (r && e?.length) for (let n of e) {
|
|
25
|
-
if (t(n.value) !== r) continue;
|
|
26
|
-
let e = String(n.ref ?? "").trim();
|
|
27
|
-
if (e) return e;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function o(e, t, n) {
|
|
31
|
-
if (!e) return;
|
|
32
|
-
let r = e[t];
|
|
33
|
-
if (r && Object.prototype.hasOwnProperty.call(r, n)) return r[n];
|
|
34
|
-
}
|
|
35
|
-
function s(e, n, r) {
|
|
36
|
-
let i = t(n), s = a(e.lookup?.entries, i);
|
|
37
|
-
return s === void 0 ? o(r, e.propertyName, i) : s;
|
|
38
|
-
}
|
|
39
|
-
function c(e, t) {
|
|
40
|
-
if (t.length === 0) {
|
|
41
|
-
if (!e.lookup) return e;
|
|
42
|
-
let { lookup: t, ...n } = e;
|
|
43
|
-
return n;
|
|
44
|
-
}
|
|
45
|
-
return {
|
|
46
|
-
...e,
|
|
47
|
-
lookup: { entries: t }
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
function l(e) {
|
|
51
|
-
if (!e.lookup) return e;
|
|
52
|
-
let { lookup: t, ...n } = e;
|
|
53
|
-
return n;
|
|
54
|
-
}
|
|
55
|
-
//#endregion
|
|
56
|
-
//#region src/classifyUrl.ts
|
|
57
|
-
function u(e) {
|
|
58
|
-
return e.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
59
|
-
}
|
|
60
|
-
function d(e) {
|
|
61
|
-
return e ? e.startsWith("image/") ? "image" : e.startsWith("audio/") ? "audio" : e.startsWith("video/") ? "video" : e === "text/html" || e === "application/xhtml+xml" || e === "application/xhtml" ? "html" : null : null;
|
|
62
|
-
}
|
|
63
|
-
function f(e) {
|
|
64
|
-
let t = e.trim();
|
|
65
|
-
try {
|
|
66
|
-
return new URL(t).pathname.toLowerCase();
|
|
67
|
-
} catch {
|
|
68
|
-
return (t.split("?")[0]?.split("#")[0] ?? t).toLowerCase();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
function p(e) {
|
|
72
|
-
return /\.(html?|xhtml|php|asp|aspx|jsp)$/i.test(e) ? "html" : /\.(jpe?g|png|gif|webp|avif|svg|bmp|ico|tiff?)$/i.test(e) ? "image" : /\.(mp3|m4a|aac|ogg|oga|opus|wav|flac|aiff?)$/i.test(e) ? "audio" : /\.(mp4|m4v|webm|ogv|mov|avi|mkv)$/i.test(e) ? "video" : "unknown";
|
|
73
|
-
}
|
|
74
|
-
function m(e) {
|
|
75
|
-
let t = typeof e.url == "string" ? e.url.trim() : "";
|
|
76
|
-
if (!t) return "unknown";
|
|
77
|
-
if (e.contentType) {
|
|
78
|
-
let t = d(u(String(e.contentType)));
|
|
79
|
-
if (t) return t;
|
|
80
|
-
}
|
|
81
|
-
return p(f(t));
|
|
82
|
-
}
|
|
83
|
-
function h(e) {
|
|
84
|
-
let t = e.trim().toLowerCase();
|
|
85
|
-
return t.startsWith("http://") || t.startsWith("https://") || t.startsWith("blob:") || t.startsWith("data:");
|
|
86
|
-
}
|
|
87
|
-
//#endregion
|
|
88
|
-
//#region src/resolvedSources.ts
|
|
89
|
-
var g = "@extract", _ = "@file";
|
|
90
|
-
function v(e) {
|
|
91
|
-
if (!e) return;
|
|
92
|
-
let t = e.contentType ?? e.type;
|
|
93
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
94
|
-
}
|
|
95
|
-
function y(e) {
|
|
96
|
-
let t = e.meta?.class;
|
|
97
|
-
return t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown" ? t : m({
|
|
98
|
-
url: typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value,
|
|
99
|
-
contentType: v(e.meta)
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
function b(e) {
|
|
103
|
-
return e.kind === "resolved" || e.kind === "full" || e.kind === "section" ? !1 : h(typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value);
|
|
104
|
-
}
|
|
105
|
-
function x(e) {
|
|
106
|
-
return e.endsWith("@extract") ? {
|
|
107
|
-
originId: e.slice(0, -8),
|
|
108
|
-
resolve: "extract"
|
|
109
|
-
} : e.endsWith("@file") ? {
|
|
110
|
-
originId: e.slice(0, -5),
|
|
111
|
-
resolve: "file"
|
|
112
|
-
} : null;
|
|
113
|
-
}
|
|
114
|
-
function S(e, t) {
|
|
115
|
-
let n = x(e);
|
|
116
|
-
return n ? {
|
|
117
|
-
sourceId: n.originId,
|
|
118
|
-
propertyName: t,
|
|
119
|
-
resolve: n.resolve
|
|
120
|
-
} : {
|
|
121
|
-
sourceId: e,
|
|
122
|
-
propertyName: t
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
function C(e, t) {
|
|
126
|
-
return t === "extract" ? `${e}${g}` : `${e}${_}`;
|
|
127
|
-
}
|
|
128
|
-
function w(e) {
|
|
129
|
-
let t = [...e], n = new Set(e.map((e) => e.id));
|
|
130
|
-
for (let r of e) {
|
|
131
|
-
if (!b(r)) continue;
|
|
132
|
-
let e = typeof r.meta?.url == "string" && r.meta.url.trim() ? r.meta.url.trim() : r.value.trim(), i = v(r.meta), a = y(r), o = C(r.id, "extract");
|
|
133
|
-
n.has(o) || (t.push({
|
|
134
|
-
id: o,
|
|
135
|
-
label: `${r.label} → extract HTML`,
|
|
136
|
-
kind: "resolved",
|
|
137
|
-
value: e,
|
|
138
|
-
meta: {
|
|
139
|
-
originId: r.id,
|
|
140
|
-
resolve: "extract",
|
|
141
|
-
class: "html",
|
|
142
|
-
contentType: i,
|
|
143
|
-
url: e
|
|
144
|
-
}
|
|
145
|
-
}), n.add(o));
|
|
146
|
-
let s = C(r.id, "file");
|
|
147
|
-
n.has(s) || (t.push({
|
|
148
|
-
id: s,
|
|
149
|
-
label: `${r.label} → file`,
|
|
150
|
-
kind: "resolved",
|
|
151
|
-
value: e,
|
|
152
|
-
meta: {
|
|
153
|
-
originId: r.id,
|
|
154
|
-
resolve: "file",
|
|
155
|
-
class: a,
|
|
156
|
-
contentType: i,
|
|
157
|
-
url: e
|
|
158
|
-
}
|
|
159
|
-
}), n.add(s));
|
|
160
|
-
}
|
|
161
|
-
return t;
|
|
162
|
-
}
|
|
163
|
-
function T(e, t) {
|
|
164
|
-
let n = new Map(e.map((e) => [e.id, e])), r = n.get(t.sourceId);
|
|
165
|
-
if (r) return r;
|
|
166
|
-
if (t.resolve) {
|
|
167
|
-
let e = n.get(C(t.sourceId, t.resolve));
|
|
168
|
-
if (e) return e;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
//#endregion
|
|
172
|
-
//#region src/applyMapping.ts
|
|
173
|
-
function E(e, t) {
|
|
174
|
-
if (t === "Number") return parseFloat(String(e)) || 0;
|
|
175
|
-
if (t === "Boolean") return e === "true" || e === "1" || String(e).toLowerCase() === "yes";
|
|
176
|
-
if (t === "Json") try {
|
|
177
|
-
return JSON.parse(e);
|
|
178
|
-
} catch {
|
|
179
|
-
return e;
|
|
180
|
-
}
|
|
181
|
-
if (t === "Date") {
|
|
182
|
-
let t = new Date(String(e));
|
|
183
|
-
return Number.isNaN(t.getTime()) ? e : t.getTime();
|
|
184
|
-
}
|
|
185
|
-
return String(e ?? "");
|
|
186
|
-
}
|
|
187
|
-
function D(e, t) {
|
|
188
|
-
return typeof e == "string" ? E(e, t) : e == null ? E("", t) : t === "Image" || t === "File" || t === "Relation" || t === "List" || t === "Json" ? e : E(String(e), t);
|
|
189
|
-
}
|
|
190
|
-
function O(e) {
|
|
191
|
-
return typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : (e.value || e.label).trim();
|
|
192
|
-
}
|
|
193
|
-
function k(e) {
|
|
194
|
-
let t = e.meta?.contentType ?? e.meta?.type;
|
|
195
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
196
|
-
}
|
|
197
|
-
function A(e) {
|
|
198
|
-
let t = e.meta?.class;
|
|
199
|
-
if (t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown") return t;
|
|
200
|
-
}
|
|
201
|
-
function j(e, n, i, a) {
|
|
202
|
-
let o = t(n.value || n.label), c = s(e, o, a);
|
|
203
|
-
return c === void 0 ? { unmatched: o } : { value: r(c, i) };
|
|
204
|
-
}
|
|
205
|
-
function M(t, n, r, i) {
|
|
206
|
-
let a = new Map(t.map((e) => [e.id, e])), o = new Map(r.map((e) => [e.name, e])), s = {};
|
|
207
|
-
for (let t of n) {
|
|
208
|
-
if (t.resolve && t.resolve !== "lookup") continue;
|
|
209
|
-
let n = a.get(t.sourceId), r = o.get(t.propertyName);
|
|
210
|
-
if (!n || !r) continue;
|
|
211
|
-
if (t.resolve === "lookup") {
|
|
212
|
-
let e = j(t, n, r, i?.lookups);
|
|
213
|
-
"value" in e && (s[t.propertyName] = e.value);
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
if (e(r)) continue;
|
|
217
|
-
let c = n.value || n.label;
|
|
218
|
-
s[t.propertyName] = E(c, r.dataType);
|
|
219
|
-
}
|
|
220
|
-
return s;
|
|
221
|
-
}
|
|
222
|
-
async function N(t, n, r, i = {}) {
|
|
223
|
-
let a = new Map(r.map((e) => [e.name, e])), o = {}, s = [];
|
|
224
|
-
for (let r of n) {
|
|
225
|
-
let n = a.get(r.propertyName);
|
|
226
|
-
if (!n) continue;
|
|
227
|
-
if (!r.resolve) {
|
|
228
|
-
let i = t.find((e) => e.id === r.sourceId);
|
|
229
|
-
if (!i || e(n)) continue;
|
|
230
|
-
let a = i.value || i.label;
|
|
231
|
-
o[r.propertyName] = E(a, n.dataType);
|
|
232
|
-
continue;
|
|
233
|
-
}
|
|
234
|
-
if (r.resolve === "lookup") {
|
|
235
|
-
let e = t.find((e) => e.id === r.sourceId);
|
|
236
|
-
if (!e) {
|
|
237
|
-
s.push({
|
|
238
|
-
sourceId: r.sourceId,
|
|
239
|
-
propertyName: r.propertyName,
|
|
240
|
-
resolve: "lookup",
|
|
241
|
-
message: `Source not found: ${r.sourceId}`
|
|
242
|
-
});
|
|
243
|
-
continue;
|
|
244
|
-
}
|
|
245
|
-
let a = j(r, e, n, i.lookups);
|
|
246
|
-
"value" in a ? o[r.propertyName] = a.value : s.push({
|
|
247
|
-
sourceId: r.sourceId,
|
|
248
|
-
propertyName: r.propertyName,
|
|
249
|
-
resolve: "lookup",
|
|
250
|
-
message: `No lookup entry for "${a.unmatched}"`
|
|
251
|
-
});
|
|
252
|
-
continue;
|
|
253
|
-
}
|
|
254
|
-
let c = T(t, r);
|
|
255
|
-
if (!c) {
|
|
256
|
-
s.push({
|
|
257
|
-
sourceId: r.sourceId,
|
|
258
|
-
propertyName: r.propertyName,
|
|
259
|
-
resolve: r.resolve,
|
|
260
|
-
message: `Source not found: ${r.sourceId}`
|
|
261
|
-
});
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
if (!i.resolve) {
|
|
265
|
-
s.push({
|
|
266
|
-
sourceId: r.sourceId,
|
|
267
|
-
propertyName: r.propertyName,
|
|
268
|
-
resolve: r.resolve,
|
|
269
|
-
message: `No resolve callback for ${r.resolve}`
|
|
270
|
-
});
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
let l = {
|
|
274
|
-
job: r.resolve,
|
|
275
|
-
url: O(c),
|
|
276
|
-
source: c,
|
|
277
|
-
target: n,
|
|
278
|
-
contentType: k(c),
|
|
279
|
-
class: A(c)
|
|
280
|
-
};
|
|
281
|
-
try {
|
|
282
|
-
let e = await i.resolve(l);
|
|
283
|
-
o[r.propertyName] = D(e, n.dataType);
|
|
284
|
-
} catch (e) {
|
|
285
|
-
s.push({
|
|
286
|
-
sourceId: r.sourceId,
|
|
287
|
-
propertyName: r.propertyName,
|
|
288
|
-
resolve: r.resolve,
|
|
289
|
-
message: e instanceof Error ? e.message : String(e)
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return {
|
|
294
|
-
properties: o,
|
|
295
|
-
errors: s
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
//#endregion
|
|
299
|
-
//#region src/autoMap.ts
|
|
300
|
-
var P = [
|
|
301
|
-
"text",
|
|
302
|
-
"content",
|
|
303
|
-
"body",
|
|
304
|
-
"fulltext",
|
|
305
|
-
"markdown"
|
|
306
|
-
], F = [
|
|
307
|
-
"html",
|
|
308
|
-
"content",
|
|
309
|
-
"body",
|
|
310
|
-
"text"
|
|
311
|
-
], I = [
|
|
312
|
-
"featureimage",
|
|
313
|
-
"feature_image",
|
|
314
|
-
"image",
|
|
315
|
-
"cover",
|
|
316
|
-
"coverimage"
|
|
317
|
-
], L = [
|
|
318
|
-
"file",
|
|
319
|
-
"audio",
|
|
320
|
-
"video",
|
|
321
|
-
"enclosure",
|
|
322
|
-
"attachment",
|
|
323
|
-
"media"
|
|
324
|
-
], R = [
|
|
325
|
-
"importurl",
|
|
326
|
-
"canonicalurl",
|
|
327
|
-
"url",
|
|
328
|
-
"link",
|
|
329
|
-
"permalink"
|
|
330
|
-
];
|
|
331
|
-
function z(e) {
|
|
332
|
-
return e.toLowerCase().replace(/\s+/g, "").replace(/[:_-]/g, "");
|
|
333
|
-
}
|
|
334
|
-
function B(e, t) {
|
|
335
|
-
let n = z(e), r = z(t);
|
|
336
|
-
return n === r || n.includes(r) || r.includes(n);
|
|
337
|
-
}
|
|
338
|
-
var V = {
|
|
339
|
-
link: R,
|
|
340
|
-
url: R
|
|
341
|
-
};
|
|
342
|
-
function H(e) {
|
|
343
|
-
if (e.kind === "resolved") return;
|
|
344
|
-
let t = z(e.label), n = z(e.id.replace(/^rss-/, "").replace(/^fm-/, ""));
|
|
345
|
-
return V[t] ?? V[n];
|
|
346
|
-
}
|
|
347
|
-
function U(e) {
|
|
348
|
-
if (!e) return;
|
|
349
|
-
let t = e.contentType ?? e.type;
|
|
350
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
351
|
-
}
|
|
352
|
-
function W(e) {
|
|
353
|
-
let t = e.meta?.class;
|
|
354
|
-
return t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown" ? t : m({
|
|
355
|
-
url: typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value,
|
|
356
|
-
contentType: U(e.meta)
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
function G(e) {
|
|
360
|
-
if (e.kind === "resolved" || e.kind === "full" || e.kind === "section") return !1;
|
|
361
|
-
let t = z(e.label);
|
|
362
|
-
if (t === "contentencoded" || t === "content" || t === "description" || t === "summary" || t === "title") return !1;
|
|
363
|
-
let n = typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value;
|
|
364
|
-
return h(n) && !n.trim().includes("<");
|
|
365
|
-
}
|
|
366
|
-
function K(e) {
|
|
367
|
-
let t = z(e.name);
|
|
368
|
-
return F.some((e) => B(t, e)) || e.dataType === "Html" || e.dataType === "Text";
|
|
369
|
-
}
|
|
370
|
-
function q(e) {
|
|
371
|
-
let t = z(e.name);
|
|
372
|
-
return e.dataType === "Image" || e.dataType === "File" || e.dataType === "Relation" ? I.some((e) => B(t, e)) || L.some((e) => B(t, e)) || e.dataType === "Image" || e.dataType === "File" : I.some((e) => B(t, e)) || L.some((e) => B(t, e));
|
|
373
|
-
}
|
|
374
|
-
function J(e) {
|
|
375
|
-
let t = z(e.name);
|
|
376
|
-
return R.some((e) => B(t, e));
|
|
377
|
-
}
|
|
378
|
-
function Y(e, t) {
|
|
379
|
-
return e.find((e) => {
|
|
380
|
-
if (t.has(e.name)) return !1;
|
|
381
|
-
let n = z(e.name);
|
|
382
|
-
return e.dataType === "Image" || I.some((e) => B(n, e));
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
function X(e, t, n) {
|
|
386
|
-
return e.find((e) => {
|
|
387
|
-
if (t.has(e.name)) return !1;
|
|
388
|
-
let r = z(e.name);
|
|
389
|
-
return n === "audio" && B(r, "audio") || n === "video" && B(r, "video") ? !0 : e.dataType === "File" || L.some((e) => B(r, e));
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
function Z(e, t) {
|
|
393
|
-
return e.find((e) => {
|
|
394
|
-
if (t.has(e.name)) return !1;
|
|
395
|
-
let n = z(e.name);
|
|
396
|
-
return e.dataType === "Html" || F.some((e) => B(n, e));
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
function Q(t, n) {
|
|
400
|
-
let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = t.filter((e) => e.kind !== "resolved"), s = o.find((e) => e.kind === "full");
|
|
401
|
-
if (s) {
|
|
402
|
-
let e = n.find((e) => P.includes(e.name.toLowerCase()));
|
|
403
|
-
e && (r.push({
|
|
404
|
-
sourceId: s.id,
|
|
405
|
-
propertyName: e.name
|
|
406
|
-
}), i.add(e.name), a.add(s.id));
|
|
407
|
-
}
|
|
408
|
-
let c = {
|
|
409
|
-
title: [
|
|
410
|
-
"title",
|
|
411
|
-
"name",
|
|
412
|
-
"headline"
|
|
413
|
-
],
|
|
414
|
-
"content:encoded": [
|
|
415
|
-
"html",
|
|
416
|
-
"content",
|
|
417
|
-
"body",
|
|
418
|
-
"text"
|
|
419
|
-
],
|
|
420
|
-
content: [
|
|
421
|
-
"html",
|
|
422
|
-
"content",
|
|
423
|
-
"body",
|
|
424
|
-
"text"
|
|
425
|
-
],
|
|
426
|
-
description: [
|
|
427
|
-
"summary",
|
|
428
|
-
"description",
|
|
429
|
-
"excerpt"
|
|
430
|
-
],
|
|
431
|
-
summary: [
|
|
432
|
-
"summary",
|
|
433
|
-
"description",
|
|
434
|
-
"excerpt"
|
|
435
|
-
],
|
|
436
|
-
featureimage: [
|
|
437
|
-
"featureimage",
|
|
438
|
-
"feature_image",
|
|
439
|
-
"image",
|
|
440
|
-
"cover"
|
|
441
|
-
],
|
|
442
|
-
feature_image: [
|
|
443
|
-
"featureimage",
|
|
444
|
-
"feature_image",
|
|
445
|
-
"image",
|
|
446
|
-
"cover"
|
|
447
|
-
],
|
|
448
|
-
link: [
|
|
449
|
-
"url",
|
|
450
|
-
"link",
|
|
451
|
-
"permalink"
|
|
452
|
-
],
|
|
453
|
-
creator: [
|
|
454
|
-
"author",
|
|
455
|
-
"authors",
|
|
456
|
-
"creator",
|
|
457
|
-
"byline"
|
|
458
|
-
],
|
|
459
|
-
author: [
|
|
460
|
-
"author",
|
|
461
|
-
"authors",
|
|
462
|
-
"creator",
|
|
463
|
-
"byline"
|
|
464
|
-
]
|
|
465
|
-
};
|
|
466
|
-
for (let e of o) {
|
|
467
|
-
if (a.has(e.id)) continue;
|
|
468
|
-
let t = z(e.label), o = e.id.replace(/^rss-/, "").replace(/^fm-/, "");
|
|
469
|
-
if (t === "contentencoded" || z(o) === "contentencoded" || t === "content" && e.value.includes("<")) {
|
|
470
|
-
let t = Z(n, i);
|
|
471
|
-
t && (r.push({
|
|
472
|
-
sourceId: e.id,
|
|
473
|
-
propertyName: t.name
|
|
474
|
-
}), i.add(t.name), a.add(e.id));
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
for (let t of o) {
|
|
478
|
-
if (a.has(t.id)) continue;
|
|
479
|
-
let o = H(t);
|
|
480
|
-
if (o) {
|
|
481
|
-
for (let e of n) i.has(e.name) || (!q(e) || J(e)) && (!K(e) || J(e) || z(e.name) !== "html" && e.dataType !== "Html") && o.some((t) => B(e.name, t)) && (r.push({
|
|
482
|
-
sourceId: t.id,
|
|
483
|
-
propertyName: e.name
|
|
484
|
-
}), i.add(e.name));
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
if (G(t)) {
|
|
488
|
-
let e = W(t);
|
|
489
|
-
if (e === "image") {
|
|
490
|
-
let e = Y(n, i);
|
|
491
|
-
if (e) {
|
|
492
|
-
r.push({
|
|
493
|
-
sourceId: t.id,
|
|
494
|
-
propertyName: e.name,
|
|
495
|
-
resolve: "file"
|
|
496
|
-
}), i.add(e.name), a.add(t.id);
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
if (e === "audio" || e === "video") {
|
|
501
|
-
let o = X(n, i, e);
|
|
502
|
-
if (o) {
|
|
503
|
-
r.push({
|
|
504
|
-
sourceId: t.id,
|
|
505
|
-
propertyName: o.name,
|
|
506
|
-
resolve: "file"
|
|
507
|
-
}), i.add(o.name), a.add(t.id);
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
let s = z(t.label), l = t.id.replace(/^rss-/, "").replace(/^fm-/, ""), u = [
|
|
513
|
-
...c[t.label] ?? [],
|
|
514
|
-
...c[l] ?? [],
|
|
515
|
-
...c[s] ?? []
|
|
516
|
-
], d;
|
|
517
|
-
for (let e of u) if (d = n.find((t) => !i.has(t.name) && B(t.name, e)), d) break;
|
|
518
|
-
d ||= n.find((e) => !i.has(e.name) && (B(e.name, t.label) || B(e.name, l))), d && (G(t) && (K(d) || q(d)) && !J(d) || (G(t) && W(t) === "image" && q(d) ? (r.push({
|
|
519
|
-
sourceId: t.id,
|
|
520
|
-
propertyName: d.name,
|
|
521
|
-
resolve: "file"
|
|
522
|
-
}), i.add(d.name), a.add(t.id)) : e(d) ? (r.push({
|
|
523
|
-
sourceId: t.id,
|
|
524
|
-
propertyName: d.name,
|
|
525
|
-
resolve: "lookup"
|
|
526
|
-
}), i.add(d.name), a.add(t.id)) : (r.push({
|
|
527
|
-
sourceId: t.id,
|
|
528
|
-
propertyName: d.name
|
|
529
|
-
}), i.add(d.name), a.add(t.id))));
|
|
530
|
-
}
|
|
531
|
-
let l = Z(n, i);
|
|
532
|
-
if (l) {
|
|
533
|
-
let e = o.find((e) => {
|
|
534
|
-
if (a.has(e.id) && !H(e)) return !1;
|
|
535
|
-
let t = z(e.label), n = z(e.id.replace(/^rss-/, "").replace(/^fm-/, ""));
|
|
536
|
-
return (t === "link" || t === "url" || n === "link" || n === "url" || t === "permalink") && h(e.value);
|
|
537
|
-
});
|
|
538
|
-
e && (r.push({
|
|
539
|
-
sourceId: e.id,
|
|
540
|
-
propertyName: l.name,
|
|
541
|
-
resolve: "extract"
|
|
542
|
-
}), i.add(l.name));
|
|
543
|
-
}
|
|
544
|
-
return r;
|
|
545
|
-
}
|
|
546
|
-
//#endregion
|
|
547
|
-
export { c as S, t as _, g as a, r as b, S as c, C as d, m as f, a as g, i as h, E as i, x as l, e as m, M as n, _ as o, h as p, N as r, w as s, Q as t, T as u, s as v, l as x, n as y };
|
|
548
|
-
|
|
549
|
-
//# sourceMappingURL=autoMap-OMvtOG0S.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"autoMap-OMvtOG0S.js","names":[],"sources":["../src/relationLookup.ts","../src/classifyUrl.ts","../src/resolvedSources.ts","../src/applyMapping.ts","../src/autoMap.ts"],"sourcesContent":["import type {\n FieldMapping,\n LookupEntry,\n MappingLookups,\n SourceNode,\n TargetProperty,\n} from './types'\n\n/**\n * True when the target expects a Seed relation uid (or list of uids)\n * rather than a copied scalar string.\n */\nexport function isRelationLookupTarget(target: TargetProperty): boolean {\n if (target.dataType === 'Relation') return true\n if (target.dataType === 'List') {\n return target.refValueType === 'Relation' || Boolean(target.ref)\n }\n return false\n}\n\n/** Trim and collapse internal whitespace for lookup dictionary keys. */\nexport function normalizeLookupKey(raw: string): string {\n return raw.replace(/\\s+/g, ' ').trim()\n}\n\n/** Normalized sample string for a source node (value, then label). */\nexport function sampleValueFromSource(source: SourceNode | undefined): string {\n if (!source) return ''\n return normalizeLookupKey(source.value || source.label)\n}\n\n/**\n * Shape a looked-up uid value for the target dataType.\n * Relation → single string; List → string[].\n */\nexport function shapeLookupValue(\n mapped: string | string[],\n target: TargetProperty,\n): string | string[] {\n if (target.dataType === 'List') {\n if (Array.isArray(mapped)) {\n return mapped.map((u) => String(u).trim()).filter(Boolean)\n }\n const one = String(mapped).trim()\n return one ? [one] : []\n }\n // Relation (or any non-List lookup target): single uid\n if (Array.isArray(mapped)) {\n return String(mapped[0] ?? '').trim()\n }\n return String(mapped).trim()\n}\n\n/** Entries stored on a lookup edge. Missing `lookup` is an empty assignment. */\nexport function lookupEntriesFromMapping(\n mapping: FieldMapping | undefined,\n): LookupEntry[] {\n return mapping?.lookup?.entries ?? []\n}\n\n/**\n * First entry whose normalized `value` matches `rawValue`.\n * Empty / whitespace-only refs are ignored.\n */\nexport function lookupRefFromEntries(\n entries: LookupEntry[] | undefined,\n rawValue: string,\n): string | undefined {\n const key = normalizeLookupKey(rawValue)\n if (!key || !entries?.length) return undefined\n for (const entry of entries) {\n if (normalizeLookupKey(entry.value) !== key) continue\n const ref = String(entry.ref ?? '').trim()\n if (ref) return ref\n }\n return undefined\n}\n\n/**\n * @deprecated Document-level table. Prefer `lookupRefFromEntries`.\n */\nexport function lookupRefFromTable(\n lookups: MappingLookups | undefined,\n propertyName: string,\n rawKey: string,\n): string | string[] | undefined {\n if (!lookups) return undefined\n const table = lookups[propertyName]\n if (!table) return undefined\n if (Object.prototype.hasOwnProperty.call(table, rawKey)) {\n return table[rawKey]\n }\n return undefined\n}\n\n/**\n * Resolve a lookup ref: edge entries first, then deprecated document table.\n */\nexport function resolveLookupMapped(\n mapping: FieldMapping,\n rawValue: string,\n lookups?: MappingLookups,\n): string | string[] | undefined {\n const key = normalizeLookupKey(rawValue)\n const fromEntries = lookupRefFromEntries(mapping.lookup?.entries, key)\n if (fromEntries !== undefined) return fromEntries\n return lookupRefFromTable(lookups, mapping.propertyName, key)\n}\n\nexport function withLookupEntries(\n edge: FieldMapping,\n entries: LookupEntry[],\n): FieldMapping {\n if (entries.length === 0) {\n if (!edge.lookup) return edge\n const { lookup: _lookup, ...rest } = edge\n return rest\n }\n return { ...edge, lookup: { entries } }\n}\n\n/** Drop `lookup` when the edge is no longer a lookup job. */\nexport function stripLookup(edge: FieldMapping): FieldMapping {\n if (!edge.lookup) return edge\n const { lookup: _lookup, ...rest } = edge\n return rest\n}\n","import type { UrlMediaClass } from './types'\n\nexport type ClassifyUrlInput = {\n url: string\n contentType?: string | null\n}\n\nfunction normalizeMime(contentType: string): string {\n return contentType.split(';')[0]?.trim().toLowerCase() ?? ''\n}\n\nfunction classFromMime(mime: string): UrlMediaClass | null {\n if (!mime) return null\n if (mime.startsWith('image/')) return 'image'\n if (mime.startsWith('audio/')) return 'audio'\n if (mime.startsWith('video/')) return 'video'\n if (\n mime === 'text/html' ||\n mime === 'application/xhtml+xml' ||\n mime === 'application/xhtml'\n ) {\n return 'html'\n }\n return null\n}\n\nfunction pathFromUrl(url: string): string {\n const trimmed = url.trim()\n try {\n const u = new URL(trimmed)\n return u.pathname.toLowerCase()\n } catch {\n const noQuery = trimmed.split('?')[0]?.split('#')[0] ?? trimmed\n return noQuery.toLowerCase()\n }\n}\n\nfunction classFromPath(pathname: string): UrlMediaClass {\n if (/\\.(html?|xhtml|php|asp|aspx|jsp)$/i.test(pathname)) return 'html'\n if (/\\.(jpe?g|png|gif|webp|avif|svg|bmp|ico|tiff?)$/i.test(pathname)) {\n return 'image'\n }\n if (/\\.(mp3|m4a|aac|ogg|oga|opus|wav|flac|aiff?)$/i.test(pathname)) {\n return 'audio'\n }\n if (/\\.(mp4|m4v|webm|ogv|mov|avi|mkv)$/i.test(pathname)) return 'video'\n return 'unknown'\n}\n\n/**\n * Pure MIME / URL-shape classifier for import mapping.\n * Prefer `contentType` when present; fall back to path extension.\n * No I/O. Distinct from `@seedprotocol/sdk` `classifyMediaRef` (Seed ref identity).\n */\nexport function classifyUrl(input: ClassifyUrlInput): UrlMediaClass {\n const url = typeof input.url === 'string' ? input.url.trim() : ''\n if (!url) return 'unknown'\n\n if (input.contentType) {\n const fromMime = classFromMime(normalizeMime(String(input.contentType)))\n if (fromMime) return fromMime\n }\n\n return classFromPath(pathFromUrl(url))\n}\n\n/** True when the string looks like an absolute http(s) / blob / data URL. */\nexport function looksLikeUrl(value: string): boolean {\n const v = value.trim().toLowerCase()\n return (\n v.startsWith('http://') ||\n v.startsWith('https://') ||\n v.startsWith('blob:') ||\n v.startsWith('data:')\n )\n}\n","import { classifyUrl, looksLikeUrl } from './classifyUrl'\nimport type {\n FieldMapping,\n ResolveJob,\n SourceNode,\n UrlMediaClass,\n} from './types'\n\nexport const RESOLVE_EXTRACT_SUFFIX = '@extract'\nexport const RESOLVE_FILE_SUFFIX = '@file'\n\nfunction contentTypeFromMeta(meta?: Record<string, unknown>): string | undefined {\n if (!meta) return undefined\n const ct = meta.contentType ?? meta.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction mediaClassFromSource(source: SourceNode): UrlMediaClass {\n const metaClass = source.meta?.class\n if (\n metaClass === 'html' ||\n metaClass === 'image' ||\n metaClass === 'audio' ||\n metaClass === 'video' ||\n metaClass === 'unknown'\n ) {\n return metaClass\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return classifyUrl({\n url,\n contentType: contentTypeFromMeta(source.meta),\n })\n}\n\nfunction isUrlCandidate(source: SourceNode): boolean {\n if (source.kind === 'resolved') return false\n if (source.kind === 'full' || source.kind === 'section') return false\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return looksLikeUrl(url)\n}\n\n/**\n * Parse a package-owned derived source id (`origin@extract` / `origin@file`).\n */\nexport function parseResolvedSourceId(\n sourceId: string,\n): { originId: string; resolve: ResolveJob } | null {\n if (sourceId.endsWith(RESOLVE_EXTRACT_SUFFIX)) {\n return {\n originId: sourceId.slice(0, -RESOLVE_EXTRACT_SUFFIX.length),\n resolve: 'extract',\n }\n }\n if (sourceId.endsWith(RESOLVE_FILE_SUFFIX)) {\n return {\n originId: sourceId.slice(0, -RESOLVE_FILE_SUFFIX.length),\n resolve: 'file',\n }\n }\n return null\n}\n\n/**\n * Normalize a UI selection (possibly a derived `@extract` / `@file` node)\n * into a persistable FieldMapping with `resolve` on the origin source.\n */\nexport function normalizeMappingFromSourceId(\n sourceId: string,\n propertyName: string,\n): FieldMapping {\n const parsed = parseResolvedSourceId(sourceId)\n if (!parsed) {\n return { sourceId, propertyName }\n }\n return {\n sourceId: parsed.originId,\n propertyName,\n resolve: parsed.resolve,\n }\n}\n\n/**\n * Stable display id for a derived resolve candidate.\n */\nexport function resolvedSourceId(originId: string, job: ResolveJob): string {\n return job === 'extract'\n ? `${originId}${RESOLVE_EXTRACT_SUFFIX}`\n : `${originId}${RESOLVE_FILE_SUFFIX}`\n}\n\n/**\n * Expand URL-classifiable sources with package-owned extract/file candidates\n * for FieldMapper / autoMap. Original nodes are preserved.\n *\n * Prefer mapping derived nodes in the UI; persist via\n * `normalizeMappingFromSourceId` so documents store origin + `resolve`.\n */\nexport function buildResolvedSourceNodes(sources: SourceNode[]): SourceNode[] {\n const out: SourceNode[] = [...sources]\n const existing = new Set(sources.map((s) => s.id))\n\n for (const source of sources) {\n if (!isUrlCandidate(source)) continue\n\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value.trim()\n const contentType = contentTypeFromMeta(source.meta)\n const mediaClass = mediaClassFromSource(source)\n\n const extractId = resolvedSourceId(source.id, 'extract')\n if (!existing.has(extractId)) {\n out.push({\n id: extractId,\n label: `${source.label} → extract HTML`,\n kind: 'resolved',\n value: url,\n meta: {\n originId: source.id,\n resolve: 'extract' satisfies ResolveJob,\n class: 'html' satisfies UrlMediaClass,\n contentType,\n url,\n },\n })\n existing.add(extractId)\n }\n\n const fileId = resolvedSourceId(source.id, 'file')\n if (!existing.has(fileId)) {\n out.push({\n id: fileId,\n label: `${source.label} → file`,\n kind: 'resolved',\n value: url,\n meta: {\n originId: source.id,\n resolve: 'file' satisfies ResolveJob,\n class: mediaClass,\n contentType,\n url,\n },\n })\n existing.add(fileId)\n }\n }\n\n return out\n}\n\n/**\n * Look up the origin source for a mapping (handles resolve edges).\n */\nexport function resolveMappingSource(\n sources: SourceNode[],\n mapping: FieldMapping,\n): SourceNode | undefined {\n const byId = new Map(sources.map((s) => [s.id, s]))\n const direct = byId.get(mapping.sourceId)\n if (direct) return direct\n if (mapping.resolve) {\n const derived = byId.get(resolvedSourceId(mapping.sourceId, mapping.resolve))\n if (derived) return derived\n }\n return undefined\n}\n","import {\n isRelationLookupTarget,\n normalizeLookupKey,\n resolveLookupMapped,\n shapeLookupValue,\n} from './relationLookup'\nimport { resolveMappingSource } from './resolvedSources'\nimport type {\n ApplyMappingAsyncResult,\n FieldMapping,\n MappingLookups,\n PropertyBag,\n ResolveCallback,\n ResolveContext,\n SourceNode,\n TargetProperty,\n UrlMediaClass,\n} from './types'\n\n/**\n * Coerce a raw string value to the Seed model property dataType.\n */\nexport function coerceValue(rawValue: string, dataType: string): unknown {\n if (dataType === 'Number') {\n return parseFloat(String(rawValue)) || 0\n }\n if (dataType === 'Boolean') {\n return (\n rawValue === 'true' ||\n rawValue === '1' ||\n String(rawValue).toLowerCase() === 'yes'\n )\n }\n if (dataType === 'Json') {\n try {\n return JSON.parse(rawValue)\n } catch {\n return rawValue\n }\n }\n if (dataType === 'Date') {\n const d = new Date(String(rawValue))\n return Number.isNaN(d.getTime()) ? rawValue : d.getTime()\n }\n return String(rawValue ?? '')\n}\n\nfunction coerceResolved(raw: unknown, dataType: string): unknown {\n if (typeof raw === 'string') {\n return coerceValue(raw, dataType)\n }\n if (raw == null) {\n return coerceValue('', dataType)\n }\n // Host may return seed refs, blobs, or already-shaped values for File/Image.\n if (\n dataType === 'Image' ||\n dataType === 'File' ||\n dataType === 'Relation' ||\n dataType === 'List' ||\n dataType === 'Json'\n ) {\n return raw\n }\n return coerceValue(String(raw), dataType)\n}\n\nfunction urlFromSource(source: SourceNode): string {\n if (typeof source.meta?.url === 'string' && source.meta.url.trim()) {\n return source.meta.url.trim()\n }\n return (source.value || source.label).trim()\n}\n\nfunction contentTypeFromSource(source: SourceNode): string | undefined {\n const ct = source.meta?.contentType ?? source.meta?.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction classFromSource(source: SourceNode): UrlMediaClass | undefined {\n const c = source.meta?.class\n if (\n c === 'html' ||\n c === 'image' ||\n c === 'audio' ||\n c === 'video' ||\n c === 'unknown'\n ) {\n return c\n }\n return undefined\n}\n\nfunction applyLookupEdge(\n mapping: FieldMapping,\n source: SourceNode,\n target: TargetProperty,\n lookups: MappingLookups | undefined,\n): { value: string | string[] } | { unmatched: string } {\n const rawValue = normalizeLookupKey(source.value || source.label)\n const mapped = resolveLookupMapped(mapping, rawValue, lookups)\n if (mapped === undefined) {\n return { unmatched: rawValue }\n }\n return { value: shapeLookupValue(mapped, target) }\n}\n\n/**\n * Apply field mappings to produce a property bag for createItem / publish.\n * Missing sources or unknown target properties are skipped (no throw).\n * `resolve: 'extract' | 'file'` edges are skipped — use `applyMappingAsync`.\n * `resolve: 'lookup'` is applied from stored entries (or deprecated document lookups).\n */\nexport function applyMapping(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n options?: { lookups?: MappingLookups },\n): PropertyBag {\n const byId = new Map(sources.map((s) => [s.id, s]))\n const byName = new Map(targets.map((t) => [t.name, t]))\n const properties: PropertyBag = {}\n\n for (const mapping of mappings) {\n if (mapping.resolve && mapping.resolve !== 'lookup') continue\n\n const source = byId.get(mapping.sourceId)\n const target = byName.get(mapping.propertyName)\n if (!source || !target) continue\n\n if (mapping.resolve === 'lookup') {\n const result = applyLookupEdge(mapping, source, target, options?.lookups)\n if ('value' in result) {\n properties[mapping.propertyName] = result.value\n }\n continue\n }\n\n // Never copy a raw string onto relation / list-of-relation targets.\n if (isRelationLookupTarget(target)) continue\n\n const raw = source.value || source.label\n properties[mapping.propertyName] = coerceValue(raw, target.dataType)\n }\n\n return properties\n}\n\nexport type ApplyMappingAsyncOptions = {\n /** Required for extract/file edges. Not called for lookup. */\n resolve?: ResolveCallback\n /**\n * String → seed uid dictionaries keyed by property name.\n * @deprecated Prefer `FieldMapping.lookup.entries`. Read as a fallback only.\n */\n lookups?: MappingLookups\n}\n\n/**\n * Async apply: copy+coerce plain edges; apply lookup entries; for extract/file\n * call the host callback then coerce. Partial success — failed resolve edges\n * are listed in `errors` and omitted from `properties`.\n */\nexport async function applyMappingAsync(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n options: ApplyMappingAsyncOptions = {},\n): Promise<ApplyMappingAsyncResult> {\n const byName = new Map(targets.map((t) => [t.name, t]))\n const properties: PropertyBag = {}\n const errors: ApplyMappingAsyncResult['errors'] = []\n\n for (const mapping of mappings) {\n const target = byName.get(mapping.propertyName)\n if (!target) continue\n\n if (!mapping.resolve) {\n const source = sources.find((s) => s.id === mapping.sourceId)\n if (!source) continue\n if (isRelationLookupTarget(target)) continue\n const raw = source.value || source.label\n properties[mapping.propertyName] = coerceValue(raw, target.dataType)\n continue\n }\n\n if (mapping.resolve === 'lookup') {\n const source = sources.find((s) => s.id === mapping.sourceId)\n if (!source) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: `Source not found: ${mapping.sourceId}`,\n })\n continue\n }\n\n const result = applyLookupEdge(mapping, source, target, options.lookups)\n if ('value' in result) {\n properties[mapping.propertyName] = result.value\n } else {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: `No lookup entry for \"${result.unmatched}\"`,\n })\n }\n continue\n }\n\n const source = resolveMappingSource(sources, mapping)\n if (!source) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: `Source not found: ${mapping.sourceId}`,\n })\n continue\n }\n\n if (!options.resolve) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: `No resolve callback for ${mapping.resolve}`,\n })\n continue\n }\n\n const ctx: ResolveContext = {\n job: mapping.resolve,\n url: urlFromSource(source),\n source,\n target,\n contentType: contentTypeFromSource(source),\n class: classFromSource(source),\n }\n\n try {\n const resolved = await options.resolve(ctx)\n properties[mapping.propertyName] = coerceResolved(resolved, target.dataType)\n } catch (err) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n return { properties, errors }\n}\n","import { classifyUrl, looksLikeUrl } from './classifyUrl'\nimport { isRelationLookupTarget } from './relationLookup'\nimport type { FieldMapping, SourceNode, TargetProperty, UrlMediaClass } from './types'\n\nconst FULL_DOC_PROP_NAMES = ['text', 'content', 'body', 'fulltext', 'markdown']\nconst HTML_PROP_NAMES = ['html', 'content', 'body', 'text']\nconst IMAGE_PROP_ALIASES = [\n 'featureimage',\n 'feature_image',\n 'image',\n 'cover',\n 'coverimage',\n]\nconst FILE_PROP_ALIASES = ['file', 'audio', 'video', 'enclosure', 'attachment', 'media']\nconst URL_PROP_ALIASES = ['importurl', 'canonicalurl', 'url', 'link', 'permalink']\n\nfunction normalizeName(name: string): string {\n return name.toLowerCase().replace(/\\s+/g, '').replace(/[:_-]/g, '')\n}\n\nfunction namesMatch(a: string, b: string): boolean {\n const na = normalizeName(a)\n const nb = normalizeName(b)\n return na === nb || na.includes(nb) || nb.includes(na)\n}\n\n/**\n * Sources that fan out to every unused target matching any alias.\n * Keys are normalized source label/id fragments.\n */\nconst FAN_OUT_ALIASES: Record<string, string[]> = {\n link: URL_PROP_ALIASES,\n url: URL_PROP_ALIASES,\n}\n\nfunction fanOutAliasesForSource(source: SourceNode): string[] | undefined {\n if (source.kind === 'resolved') return undefined\n const labelKey = normalizeName(source.label)\n const idKey = normalizeName(source.id.replace(/^rss-/, '').replace(/^fm-/, ''))\n return FAN_OUT_ALIASES[labelKey] ?? FAN_OUT_ALIASES[idKey]\n}\n\nfunction contentTypeFromMeta(meta?: Record<string, unknown>): string | undefined {\n if (!meta) return undefined\n const ct = meta.contentType ?? meta.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction mediaClassOf(source: SourceNode): UrlMediaClass {\n const metaClass = source.meta?.class\n if (\n metaClass === 'html' ||\n metaClass === 'image' ||\n metaClass === 'audio' ||\n metaClass === 'video' ||\n metaClass === 'unknown'\n ) {\n return metaClass\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return classifyUrl({\n url,\n contentType: contentTypeFromMeta(source.meta),\n })\n}\n\nfunction isRawUrlSource(source: SourceNode): boolean {\n if (source.kind === 'resolved') return false\n if (source.kind === 'full' || source.kind === 'section') return false\n // content:encoded / description HTML bodies are not \"raw URL\" sources\n const labelKey = normalizeName(source.label)\n if (\n labelKey === 'contentencoded' ||\n labelKey === 'content' ||\n labelKey === 'description' ||\n labelKey === 'summary' ||\n labelKey === 'title'\n ) {\n return false\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return looksLikeUrl(url) && !url.trim().includes('<')\n}\n\nfunction isHtmlLikeTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n return (\n HTML_PROP_NAMES.some((p) => namesMatch(n, p)) ||\n target.dataType === 'Html' ||\n target.dataType === 'Text'\n )\n}\n\nfunction isRichMediaTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n if (\n target.dataType === 'Image' ||\n target.dataType === 'File' ||\n target.dataType === 'Relation'\n ) {\n return (\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n FILE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n target.dataType === 'Image' ||\n target.dataType === 'File'\n )\n }\n return (\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n FILE_PROP_ALIASES.some((a) => namesMatch(n, a))\n )\n}\n\nfunction isUrlOnlyTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n return URL_PROP_ALIASES.some((a) => namesMatch(n, a))\n}\n\nfunction findImageTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n return (\n p.dataType === 'Image' ||\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a))\n )\n })\n}\n\nfunction findFileTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n mediaClass: UrlMediaClass,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n if (mediaClass === 'audio' && namesMatch(n, 'audio')) return true\n if (mediaClass === 'video' && namesMatch(n, 'video')) return true\n return p.dataType === 'File' || FILE_PROP_ALIASES.some((a) => namesMatch(n, a))\n })\n}\n\nfunction findHtmlTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n return (\n p.dataType === 'Html' ||\n HTML_PROP_NAMES.some((alias) => namesMatch(n, alias))\n )\n })\n}\n\n/**\n * Heuristic auto-map: full-document / full-text first, then RSS aliases,\n * URL fan-out (copy only), media file/extract jobs, then fuzzy name match.\n * Never maps a raw URL onto html / Image / File without `resolve`.\n */\nexport function autoMap(\n sources: SourceNode[],\n targets: TargetProperty[],\n): FieldMapping[] {\n const mappings: FieldMapping[] = []\n const usedProps = new Set<string>()\n const usedSources = new Set<string>()\n\n // Skip derived resolve nodes in the main pass; we emit resolve jobs from origins.\n const baseSources = sources.filter((s) => s.kind !== 'resolved')\n\n const fullSource = baseSources.find((s) => s.kind === 'full')\n if (fullSource) {\n const fullDocMatch = targets.find((p) =>\n FULL_DOC_PROP_NAMES.includes(p.name.toLowerCase()),\n )\n if (fullDocMatch) {\n mappings.push({\n sourceId: fullSource.id,\n propertyName: fullDocMatch.name,\n })\n usedProps.add(fullDocMatch.name)\n usedSources.add(fullSource.id)\n }\n }\n\n const rssAliases: Record<string, string[]> = {\n title: ['title', 'name', 'headline'],\n 'content:encoded': ['html', 'content', 'body', 'text'],\n content: ['html', 'content', 'body', 'text'],\n description: ['summary', 'description', 'excerpt'],\n summary: ['summary', 'description', 'excerpt'],\n featureimage: ['featureimage', 'feature_image', 'image', 'cover'],\n feature_image: ['featureimage', 'feature_image', 'image', 'cover'],\n link: ['url', 'link', 'permalink'],\n creator: ['author', 'authors', 'creator', 'byline'],\n author: ['author', 'authors', 'creator', 'byline'],\n }\n\n // Prefer full-text RSS → html (copy) before URL extract\n for (const source of baseSources) {\n if (usedSources.has(source.id)) continue\n const labelKey = normalizeName(source.label)\n const idKey = source.id.replace(/^rss-/, '').replace(/^fm-/, '')\n if (\n labelKey === 'contentencoded' ||\n normalizeName(idKey) === 'contentencoded' ||\n (labelKey === 'content' && source.value.includes('<'))\n ) {\n const htmlTarget = findHtmlTarget(targets, usedProps)\n if (htmlTarget) {\n mappings.push({ sourceId: source.id, propertyName: htmlTarget.name })\n usedProps.add(htmlTarget.name)\n usedSources.add(source.id)\n }\n }\n }\n\n for (const source of baseSources) {\n if (usedSources.has(source.id)) continue\n\n const fanOutAliases = fanOutAliasesForSource(source)\n if (fanOutAliases) {\n for (const target of targets) {\n if (usedProps.has(target.name)) continue\n if (isRichMediaTarget(target) && !isUrlOnlyTarget(target)) continue\n if (isHtmlLikeTarget(target) && !isUrlOnlyTarget(target)) {\n // Do not fan raw link into html — handled later as extract if needed\n const n = normalizeName(target.name)\n if (n === 'html' || target.dataType === 'Html') continue\n }\n const matches = fanOutAliases.some((alias) =>\n namesMatch(target.name, alias),\n )\n if (matches) {\n mappings.push({ sourceId: source.id, propertyName: target.name })\n usedProps.add(target.name)\n }\n }\n continue\n }\n\n // Media URL sources → resolve:file onto Image/File targets\n if (isRawUrlSource(source)) {\n const mediaClass = mediaClassOf(source)\n if (mediaClass === 'image') {\n const imageTarget = findImageTarget(targets, usedProps)\n if (imageTarget) {\n mappings.push({\n sourceId: source.id,\n propertyName: imageTarget.name,\n resolve: 'file',\n })\n usedProps.add(imageTarget.name)\n usedSources.add(source.id)\n continue\n }\n }\n if (mediaClass === 'audio' || mediaClass === 'video') {\n const fileTarget = findFileTarget(targets, usedProps, mediaClass)\n if (fileTarget) {\n mappings.push({\n sourceId: source.id,\n propertyName: fileTarget.name,\n resolve: 'file',\n })\n usedProps.add(fileTarget.name)\n usedSources.add(source.id)\n continue\n }\n }\n // Unknown / html-class URLs: do not map onto rich media without resolve\n // (extract handled in a later pass for link-like sources)\n }\n\n const labelKey = normalizeName(source.label)\n const idKey = source.id.replace(/^rss-/, '').replace(/^fm-/, '')\n const aliasKeys = [\n ...(rssAliases[source.label] ?? []),\n ...(rssAliases[idKey] ?? []),\n ...(rssAliases[labelKey] ?? []),\n ]\n\n let match: TargetProperty | undefined\n\n for (const alias of aliasKeys) {\n match = targets.find(\n (p) => !usedProps.has(p.name) && namesMatch(p.name, alias),\n )\n if (match) break\n }\n\n if (!match) {\n match = targets.find(\n (p) =>\n !usedProps.has(p.name) &&\n (namesMatch(p.name, source.label) || namesMatch(p.name, idKey)),\n )\n }\n\n if (match) {\n // Block raw URL → html / image / file without resolve\n if (\n isRawUrlSource(source) &&\n (isHtmlLikeTarget(match) || isRichMediaTarget(match)) &&\n !isUrlOnlyTarget(match)\n ) {\n // skip — extract / file jobs handled separately\n } else if (\n isRawUrlSource(source) &&\n mediaClassOf(source) === 'image' &&\n isRichMediaTarget(match)\n ) {\n mappings.push({\n sourceId: source.id,\n propertyName: match.name,\n resolve: 'file',\n })\n usedProps.add(match.name)\n usedSources.add(source.id)\n } else if (isRelationLookupTarget(match)) {\n mappings.push({\n sourceId: source.id,\n propertyName: match.name,\n resolve: 'lookup',\n })\n usedProps.add(match.name)\n usedSources.add(source.id)\n } else {\n mappings.push({ sourceId: source.id, propertyName: match.name })\n usedProps.add(match.name)\n usedSources.add(source.id)\n }\n }\n }\n\n // If no HTML body filled, prefer extract from link/permalink\n const htmlStillFree = findHtmlTarget(targets, usedProps)\n if (htmlStillFree) {\n const linkSource = baseSources.find((s) => {\n if (usedSources.has(s.id) && !fanOutAliasesForSource(s)) return false\n const labelKey = normalizeName(s.label)\n const idKey = normalizeName(s.id.replace(/^rss-/, '').replace(/^fm-/, ''))\n return (\n (labelKey === 'link' ||\n labelKey === 'url' ||\n idKey === 'link' ||\n idKey === 'url' ||\n labelKey === 'permalink') &&\n looksLikeUrl(s.value)\n )\n })\n if (linkSource) {\n mappings.push({\n sourceId: linkSource.id,\n propertyName: htmlStillFree.name,\n resolve: 'extract',\n })\n usedProps.add(htmlStillFree.name)\n }\n }\n\n return mappings\n}\n"],"mappings":"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"}
|
package/dist/autoMap-PTFd4l-9.js
DELETED
|
@@ -1,534 +0,0 @@
|
|
|
1
|
-
//#region src/relationLookup.ts
|
|
2
|
-
function e(e) {
|
|
3
|
-
return e.dataType === "Relation" ? !0 : e.dataType === "List" ? e.refValueType === "Relation" || !!e.ref : !1;
|
|
4
|
-
}
|
|
5
|
-
function t(e) {
|
|
6
|
-
return e.replace(/\s+/g, " ").trim();
|
|
7
|
-
}
|
|
8
|
-
function n(e, t) {
|
|
9
|
-
if (t.dataType === "List") {
|
|
10
|
-
if (Array.isArray(e)) return e.map((e) => String(e).trim()).filter(Boolean);
|
|
11
|
-
let t = String(e).trim();
|
|
12
|
-
return t ? [t] : [];
|
|
13
|
-
}
|
|
14
|
-
return Array.isArray(e) ? String(e[0] ?? "").trim() : String(e).trim();
|
|
15
|
-
}
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/classifyUrl.ts
|
|
18
|
-
function r(e) {
|
|
19
|
-
return e.split(";")[0]?.trim().toLowerCase() ?? "";
|
|
20
|
-
}
|
|
21
|
-
function i(e) {
|
|
22
|
-
return e ? e.startsWith("image/") ? "image" : e.startsWith("audio/") ? "audio" : e.startsWith("video/") ? "video" : e === "text/html" || e === "application/xhtml+xml" || e === "application/xhtml" ? "html" : null : null;
|
|
23
|
-
}
|
|
24
|
-
function a(e) {
|
|
25
|
-
let t = e.trim();
|
|
26
|
-
try {
|
|
27
|
-
return new URL(t).pathname.toLowerCase();
|
|
28
|
-
} catch {
|
|
29
|
-
return (t.split("?")[0]?.split("#")[0] ?? t).toLowerCase();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function o(e) {
|
|
33
|
-
return /\.(html?|xhtml|php|asp|aspx|jsp)$/i.test(e) ? "html" : /\.(jpe?g|png|gif|webp|avif|svg|bmp|ico|tiff?)$/i.test(e) ? "image" : /\.(mp3|m4a|aac|ogg|oga|opus|wav|flac|aiff?)$/i.test(e) ? "audio" : /\.(mp4|m4v|webm|ogv|mov|avi|mkv)$/i.test(e) ? "video" : "unknown";
|
|
34
|
-
}
|
|
35
|
-
function s(e) {
|
|
36
|
-
let t = typeof e.url == "string" ? e.url.trim() : "";
|
|
37
|
-
if (!t) return "unknown";
|
|
38
|
-
if (e.contentType) {
|
|
39
|
-
let t = i(r(String(e.contentType)));
|
|
40
|
-
if (t) return t;
|
|
41
|
-
}
|
|
42
|
-
return o(a(t));
|
|
43
|
-
}
|
|
44
|
-
function c(e) {
|
|
45
|
-
let t = e.trim().toLowerCase();
|
|
46
|
-
return t.startsWith("http://") || t.startsWith("https://") || t.startsWith("blob:") || t.startsWith("data:");
|
|
47
|
-
}
|
|
48
|
-
//#endregion
|
|
49
|
-
//#region src/resolvedSources.ts
|
|
50
|
-
var l = "@extract", u = "@file";
|
|
51
|
-
function d(e) {
|
|
52
|
-
if (!e) return;
|
|
53
|
-
let t = e.contentType ?? e.type;
|
|
54
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
55
|
-
}
|
|
56
|
-
function f(e) {
|
|
57
|
-
let t = e.meta?.class;
|
|
58
|
-
return t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown" ? t : s({
|
|
59
|
-
url: typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value,
|
|
60
|
-
contentType: d(e.meta)
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
function p(e) {
|
|
64
|
-
return e.kind === "resolved" || e.kind === "full" || e.kind === "section" ? !1 : c(typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value);
|
|
65
|
-
}
|
|
66
|
-
function m(e) {
|
|
67
|
-
return e.endsWith("@extract") ? {
|
|
68
|
-
originId: e.slice(0, -8),
|
|
69
|
-
resolve: "extract"
|
|
70
|
-
} : e.endsWith("@file") ? {
|
|
71
|
-
originId: e.slice(0, -5),
|
|
72
|
-
resolve: "file"
|
|
73
|
-
} : null;
|
|
74
|
-
}
|
|
75
|
-
function h(e, t) {
|
|
76
|
-
let n = m(e);
|
|
77
|
-
return n ? {
|
|
78
|
-
sourceId: n.originId,
|
|
79
|
-
propertyName: t,
|
|
80
|
-
resolve: n.resolve
|
|
81
|
-
} : {
|
|
82
|
-
sourceId: e,
|
|
83
|
-
propertyName: t
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function g(e, t) {
|
|
87
|
-
return t === "extract" ? `${e}${l}` : `${e}${u}`;
|
|
88
|
-
}
|
|
89
|
-
function _(e) {
|
|
90
|
-
let t = [...e], n = new Set(e.map((e) => e.id));
|
|
91
|
-
for (let r of e) {
|
|
92
|
-
if (!p(r)) continue;
|
|
93
|
-
let e = typeof r.meta?.url == "string" && r.meta.url.trim() ? r.meta.url.trim() : r.value.trim(), i = d(r.meta), a = f(r), o = g(r.id, "extract");
|
|
94
|
-
n.has(o) || (t.push({
|
|
95
|
-
id: o,
|
|
96
|
-
label: `${r.label} → extract HTML`,
|
|
97
|
-
kind: "resolved",
|
|
98
|
-
value: e,
|
|
99
|
-
meta: {
|
|
100
|
-
originId: r.id,
|
|
101
|
-
resolve: "extract",
|
|
102
|
-
class: "html",
|
|
103
|
-
contentType: i,
|
|
104
|
-
url: e
|
|
105
|
-
}
|
|
106
|
-
}), n.add(o));
|
|
107
|
-
let s = g(r.id, "file");
|
|
108
|
-
n.has(s) || (t.push({
|
|
109
|
-
id: s,
|
|
110
|
-
label: `${r.label} → file`,
|
|
111
|
-
kind: "resolved",
|
|
112
|
-
value: e,
|
|
113
|
-
meta: {
|
|
114
|
-
originId: r.id,
|
|
115
|
-
resolve: "file",
|
|
116
|
-
class: a,
|
|
117
|
-
contentType: i,
|
|
118
|
-
url: e
|
|
119
|
-
}
|
|
120
|
-
}), n.add(s));
|
|
121
|
-
}
|
|
122
|
-
return t;
|
|
123
|
-
}
|
|
124
|
-
function v(e, t) {
|
|
125
|
-
let n = new Map(e.map((e) => [e.id, e])), r = n.get(t.sourceId);
|
|
126
|
-
if (r) return r;
|
|
127
|
-
if (t.resolve) {
|
|
128
|
-
let e = n.get(g(t.sourceId, t.resolve));
|
|
129
|
-
if (e) return e;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
//#endregion
|
|
133
|
-
//#region src/applyMapping.ts
|
|
134
|
-
function y(e, t) {
|
|
135
|
-
if (t === "Number") return parseFloat(String(e)) || 0;
|
|
136
|
-
if (t === "Boolean") return e === "true" || e === "1" || String(e).toLowerCase() === "yes";
|
|
137
|
-
if (t === "Json") try {
|
|
138
|
-
return JSON.parse(e);
|
|
139
|
-
} catch {
|
|
140
|
-
return e;
|
|
141
|
-
}
|
|
142
|
-
if (t === "Date") {
|
|
143
|
-
let t = new Date(String(e));
|
|
144
|
-
return Number.isNaN(t.getTime()) ? e : t.getTime();
|
|
145
|
-
}
|
|
146
|
-
return String(e ?? "");
|
|
147
|
-
}
|
|
148
|
-
function b(e, t) {
|
|
149
|
-
return typeof e == "string" ? y(e, t) : e == null ? y("", t) : t === "Image" || t === "File" || t === "Relation" || t === "List" || t === "Json" ? e : y(String(e), t);
|
|
150
|
-
}
|
|
151
|
-
function x(e) {
|
|
152
|
-
return typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : (e.value || e.label).trim();
|
|
153
|
-
}
|
|
154
|
-
function S(e) {
|
|
155
|
-
let t = e.meta?.contentType ?? e.meta?.type;
|
|
156
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
157
|
-
}
|
|
158
|
-
function C(e) {
|
|
159
|
-
let t = e.meta?.class;
|
|
160
|
-
if (t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown") return t;
|
|
161
|
-
}
|
|
162
|
-
function w(e, t, n) {
|
|
163
|
-
if (!e) return;
|
|
164
|
-
let r = e[t];
|
|
165
|
-
if (r && Object.prototype.hasOwnProperty.call(r, n)) return r[n];
|
|
166
|
-
}
|
|
167
|
-
function T(t, n, r) {
|
|
168
|
-
let i = new Map(t.map((e) => [e.id, e])), a = new Map(r.map((e) => [e.name, e])), o = {};
|
|
169
|
-
for (let t of n) {
|
|
170
|
-
if (t.resolve) continue;
|
|
171
|
-
let n = i.get(t.sourceId), r = a.get(t.propertyName);
|
|
172
|
-
if (!n || !r || e(r)) continue;
|
|
173
|
-
let s = n.value || n.label;
|
|
174
|
-
o[t.propertyName] = y(s, r.dataType);
|
|
175
|
-
}
|
|
176
|
-
return o;
|
|
177
|
-
}
|
|
178
|
-
async function E(r, i, a, o = {}) {
|
|
179
|
-
let s = new Map(a.map((e) => [e.name, e])), c = {}, l = [];
|
|
180
|
-
for (let a of i) {
|
|
181
|
-
let i = s.get(a.propertyName);
|
|
182
|
-
if (!i) continue;
|
|
183
|
-
if (!a.resolve) {
|
|
184
|
-
let t = r.find((e) => e.id === a.sourceId);
|
|
185
|
-
if (!t || e(i)) continue;
|
|
186
|
-
let n = t.value || t.label;
|
|
187
|
-
c[a.propertyName] = y(n, i.dataType);
|
|
188
|
-
continue;
|
|
189
|
-
}
|
|
190
|
-
if (a.resolve === "lookup") {
|
|
191
|
-
let e = r.find((e) => e.id === a.sourceId);
|
|
192
|
-
if (!e) {
|
|
193
|
-
l.push({
|
|
194
|
-
sourceId: a.sourceId,
|
|
195
|
-
propertyName: a.propertyName,
|
|
196
|
-
resolve: "lookup",
|
|
197
|
-
message: `Source not found: ${a.sourceId}`
|
|
198
|
-
});
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
let s = t(e.value || e.label), u = w(o.lookups, a.propertyName, s);
|
|
202
|
-
if (u !== void 0) {
|
|
203
|
-
c[a.propertyName] = n(u, i);
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
|
-
if (!o.resolve) {
|
|
207
|
-
l.push({
|
|
208
|
-
sourceId: a.sourceId,
|
|
209
|
-
propertyName: a.propertyName,
|
|
210
|
-
resolve: "lookup",
|
|
211
|
-
message: `No lookup entry for "${s}" and no resolve callback`
|
|
212
|
-
});
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
let d = {
|
|
216
|
-
job: "lookup",
|
|
217
|
-
source: e,
|
|
218
|
-
target: i,
|
|
219
|
-
rawValue: s
|
|
220
|
-
};
|
|
221
|
-
try {
|
|
222
|
-
let e = await o.resolve(d);
|
|
223
|
-
if (e == null) {
|
|
224
|
-
l.push({
|
|
225
|
-
sourceId: a.sourceId,
|
|
226
|
-
propertyName: a.propertyName,
|
|
227
|
-
resolve: "lookup",
|
|
228
|
-
message: `Lookup returned empty for "${s}"`
|
|
229
|
-
});
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
typeof e == "string" || Array.isArray(e) ? c[a.propertyName] = n(e, i) : c[a.propertyName] = b(e, i.dataType);
|
|
233
|
-
} catch (e) {
|
|
234
|
-
l.push({
|
|
235
|
-
sourceId: a.sourceId,
|
|
236
|
-
propertyName: a.propertyName,
|
|
237
|
-
resolve: "lookup",
|
|
238
|
-
message: e instanceof Error ? e.message : String(e)
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
continue;
|
|
242
|
-
}
|
|
243
|
-
let u = v(r, a);
|
|
244
|
-
if (!u) {
|
|
245
|
-
l.push({
|
|
246
|
-
sourceId: a.sourceId,
|
|
247
|
-
propertyName: a.propertyName,
|
|
248
|
-
resolve: a.resolve,
|
|
249
|
-
message: `Source not found: ${a.sourceId}`
|
|
250
|
-
});
|
|
251
|
-
continue;
|
|
252
|
-
}
|
|
253
|
-
if (!o.resolve) {
|
|
254
|
-
l.push({
|
|
255
|
-
sourceId: a.sourceId,
|
|
256
|
-
propertyName: a.propertyName,
|
|
257
|
-
resolve: a.resolve,
|
|
258
|
-
message: `No resolve callback for ${a.resolve}`
|
|
259
|
-
});
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
let d = {
|
|
263
|
-
job: a.resolve,
|
|
264
|
-
url: x(u),
|
|
265
|
-
source: u,
|
|
266
|
-
target: i,
|
|
267
|
-
contentType: S(u),
|
|
268
|
-
class: C(u)
|
|
269
|
-
};
|
|
270
|
-
try {
|
|
271
|
-
let e = await o.resolve(d);
|
|
272
|
-
c[a.propertyName] = b(e, i.dataType);
|
|
273
|
-
} catch (e) {
|
|
274
|
-
l.push({
|
|
275
|
-
sourceId: a.sourceId,
|
|
276
|
-
propertyName: a.propertyName,
|
|
277
|
-
resolve: a.resolve,
|
|
278
|
-
message: e instanceof Error ? e.message : String(e)
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
return {
|
|
283
|
-
properties: c,
|
|
284
|
-
errors: l
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
//#endregion
|
|
288
|
-
//#region src/autoMap.ts
|
|
289
|
-
var D = [
|
|
290
|
-
"text",
|
|
291
|
-
"content",
|
|
292
|
-
"body",
|
|
293
|
-
"fulltext",
|
|
294
|
-
"markdown"
|
|
295
|
-
], O = [
|
|
296
|
-
"html",
|
|
297
|
-
"content",
|
|
298
|
-
"body",
|
|
299
|
-
"text"
|
|
300
|
-
], k = [
|
|
301
|
-
"featureimage",
|
|
302
|
-
"feature_image",
|
|
303
|
-
"image",
|
|
304
|
-
"cover",
|
|
305
|
-
"coverimage"
|
|
306
|
-
], A = [
|
|
307
|
-
"file",
|
|
308
|
-
"audio",
|
|
309
|
-
"video",
|
|
310
|
-
"enclosure",
|
|
311
|
-
"attachment",
|
|
312
|
-
"media"
|
|
313
|
-
], j = [
|
|
314
|
-
"importurl",
|
|
315
|
-
"canonicalurl",
|
|
316
|
-
"url",
|
|
317
|
-
"link",
|
|
318
|
-
"permalink"
|
|
319
|
-
];
|
|
320
|
-
function M(e) {
|
|
321
|
-
return e.toLowerCase().replace(/\s+/g, "").replace(/[:_-]/g, "");
|
|
322
|
-
}
|
|
323
|
-
function N(e, t) {
|
|
324
|
-
let n = M(e), r = M(t);
|
|
325
|
-
return n === r || n.includes(r) || r.includes(n);
|
|
326
|
-
}
|
|
327
|
-
var P = {
|
|
328
|
-
link: j,
|
|
329
|
-
url: j
|
|
330
|
-
};
|
|
331
|
-
function F(e) {
|
|
332
|
-
if (e.kind === "resolved") return;
|
|
333
|
-
let t = M(e.label), n = M(e.id.replace(/^rss-/, "").replace(/^fm-/, ""));
|
|
334
|
-
return P[t] ?? P[n];
|
|
335
|
-
}
|
|
336
|
-
function I(e) {
|
|
337
|
-
if (!e) return;
|
|
338
|
-
let t = e.contentType ?? e.type;
|
|
339
|
-
return typeof t == "string" && t.trim() ? t.trim() : void 0;
|
|
340
|
-
}
|
|
341
|
-
function L(e) {
|
|
342
|
-
let t = e.meta?.class;
|
|
343
|
-
return t === "html" || t === "image" || t === "audio" || t === "video" || t === "unknown" ? t : s({
|
|
344
|
-
url: typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value,
|
|
345
|
-
contentType: I(e.meta)
|
|
346
|
-
});
|
|
347
|
-
}
|
|
348
|
-
function R(e) {
|
|
349
|
-
if (e.kind === "resolved" || e.kind === "full" || e.kind === "section") return !1;
|
|
350
|
-
let t = M(e.label);
|
|
351
|
-
if (t === "contentencoded" || t === "content" || t === "description" || t === "summary" || t === "title") return !1;
|
|
352
|
-
let n = typeof e.meta?.url == "string" && e.meta.url.trim() ? e.meta.url.trim() : e.value;
|
|
353
|
-
return c(n) && !n.trim().includes("<");
|
|
354
|
-
}
|
|
355
|
-
function z(e) {
|
|
356
|
-
let t = M(e.name);
|
|
357
|
-
return O.some((e) => N(t, e)) || e.dataType === "Html" || e.dataType === "Text";
|
|
358
|
-
}
|
|
359
|
-
function B(e) {
|
|
360
|
-
let t = M(e.name);
|
|
361
|
-
return e.dataType === "Image" || e.dataType === "File" || e.dataType === "Relation" ? k.some((e) => N(t, e)) || A.some((e) => N(t, e)) || e.dataType === "Image" || e.dataType === "File" : k.some((e) => N(t, e)) || A.some((e) => N(t, e));
|
|
362
|
-
}
|
|
363
|
-
function V(e) {
|
|
364
|
-
let t = M(e.name);
|
|
365
|
-
return j.some((e) => N(t, e));
|
|
366
|
-
}
|
|
367
|
-
function H(e, t) {
|
|
368
|
-
return e.find((e) => {
|
|
369
|
-
if (t.has(e.name)) return !1;
|
|
370
|
-
let n = M(e.name);
|
|
371
|
-
return e.dataType === "Image" || k.some((e) => N(n, e));
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
function U(e, t, n) {
|
|
375
|
-
return e.find((e) => {
|
|
376
|
-
if (t.has(e.name)) return !1;
|
|
377
|
-
let r = M(e.name);
|
|
378
|
-
return n === "audio" && N(r, "audio") || n === "video" && N(r, "video") ? !0 : e.dataType === "File" || A.some((e) => N(r, e));
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
function W(e, t) {
|
|
382
|
-
return e.find((e) => {
|
|
383
|
-
if (t.has(e.name)) return !1;
|
|
384
|
-
let n = M(e.name);
|
|
385
|
-
return e.dataType === "Html" || O.some((e) => N(n, e));
|
|
386
|
-
});
|
|
387
|
-
}
|
|
388
|
-
function G(t, n) {
|
|
389
|
-
let r = [], i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = t.filter((e) => e.kind !== "resolved"), s = o.find((e) => e.kind === "full");
|
|
390
|
-
if (s) {
|
|
391
|
-
let e = n.find((e) => D.includes(e.name.toLowerCase()));
|
|
392
|
-
e && (r.push({
|
|
393
|
-
sourceId: s.id,
|
|
394
|
-
propertyName: e.name
|
|
395
|
-
}), i.add(e.name), a.add(s.id));
|
|
396
|
-
}
|
|
397
|
-
let l = {
|
|
398
|
-
title: [
|
|
399
|
-
"title",
|
|
400
|
-
"name",
|
|
401
|
-
"headline"
|
|
402
|
-
],
|
|
403
|
-
"content:encoded": [
|
|
404
|
-
"html",
|
|
405
|
-
"content",
|
|
406
|
-
"body",
|
|
407
|
-
"text"
|
|
408
|
-
],
|
|
409
|
-
content: [
|
|
410
|
-
"html",
|
|
411
|
-
"content",
|
|
412
|
-
"body",
|
|
413
|
-
"text"
|
|
414
|
-
],
|
|
415
|
-
description: [
|
|
416
|
-
"summary",
|
|
417
|
-
"description",
|
|
418
|
-
"excerpt"
|
|
419
|
-
],
|
|
420
|
-
summary: [
|
|
421
|
-
"summary",
|
|
422
|
-
"description",
|
|
423
|
-
"excerpt"
|
|
424
|
-
],
|
|
425
|
-
featureimage: [
|
|
426
|
-
"featureimage",
|
|
427
|
-
"feature_image",
|
|
428
|
-
"image",
|
|
429
|
-
"cover"
|
|
430
|
-
],
|
|
431
|
-
feature_image: [
|
|
432
|
-
"featureimage",
|
|
433
|
-
"feature_image",
|
|
434
|
-
"image",
|
|
435
|
-
"cover"
|
|
436
|
-
],
|
|
437
|
-
link: [
|
|
438
|
-
"url",
|
|
439
|
-
"link",
|
|
440
|
-
"permalink"
|
|
441
|
-
],
|
|
442
|
-
creator: [
|
|
443
|
-
"author",
|
|
444
|
-
"authors",
|
|
445
|
-
"creator",
|
|
446
|
-
"byline"
|
|
447
|
-
],
|
|
448
|
-
author: [
|
|
449
|
-
"author",
|
|
450
|
-
"authors",
|
|
451
|
-
"creator",
|
|
452
|
-
"byline"
|
|
453
|
-
]
|
|
454
|
-
};
|
|
455
|
-
for (let e of o) {
|
|
456
|
-
if (a.has(e.id)) continue;
|
|
457
|
-
let t = M(e.label), o = e.id.replace(/^rss-/, "").replace(/^fm-/, "");
|
|
458
|
-
if (t === "contentencoded" || M(o) === "contentencoded" || t === "content" && e.value.includes("<")) {
|
|
459
|
-
let t = W(n, i);
|
|
460
|
-
t && (r.push({
|
|
461
|
-
sourceId: e.id,
|
|
462
|
-
propertyName: t.name
|
|
463
|
-
}), i.add(t.name), a.add(e.id));
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
for (let t of o) {
|
|
467
|
-
if (a.has(t.id)) continue;
|
|
468
|
-
let o = F(t);
|
|
469
|
-
if (o) {
|
|
470
|
-
for (let e of n) i.has(e.name) || (!B(e) || V(e)) && (!z(e) || V(e) || M(e.name) !== "html" && e.dataType !== "Html") && o.some((t) => N(e.name, t)) && (r.push({
|
|
471
|
-
sourceId: t.id,
|
|
472
|
-
propertyName: e.name
|
|
473
|
-
}), i.add(e.name));
|
|
474
|
-
continue;
|
|
475
|
-
}
|
|
476
|
-
if (R(t)) {
|
|
477
|
-
let e = L(t);
|
|
478
|
-
if (e === "image") {
|
|
479
|
-
let e = H(n, i);
|
|
480
|
-
if (e) {
|
|
481
|
-
r.push({
|
|
482
|
-
sourceId: t.id,
|
|
483
|
-
propertyName: e.name,
|
|
484
|
-
resolve: "file"
|
|
485
|
-
}), i.add(e.name), a.add(t.id);
|
|
486
|
-
continue;
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
if (e === "audio" || e === "video") {
|
|
490
|
-
let o = U(n, i, e);
|
|
491
|
-
if (o) {
|
|
492
|
-
r.push({
|
|
493
|
-
sourceId: t.id,
|
|
494
|
-
propertyName: o.name,
|
|
495
|
-
resolve: "file"
|
|
496
|
-
}), i.add(o.name), a.add(t.id);
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
let s = M(t.label), c = t.id.replace(/^rss-/, "").replace(/^fm-/, ""), u = [
|
|
502
|
-
...l[t.label] ?? [],
|
|
503
|
-
...l[c] ?? [],
|
|
504
|
-
...l[s] ?? []
|
|
505
|
-
], d;
|
|
506
|
-
for (let t of u) if (d = n.find((n) => !i.has(n.name) && !e(n) && N(n.name, t)), d) break;
|
|
507
|
-
d ||= n.find((n) => !i.has(n.name) && !e(n) && (N(n.name, t.label) || N(n.name, c))), d && (R(t) && (z(d) || B(d)) && !V(d) || (R(t) && L(t) === "image" && B(d) ? (r.push({
|
|
508
|
-
sourceId: t.id,
|
|
509
|
-
propertyName: d.name,
|
|
510
|
-
resolve: "file"
|
|
511
|
-
}), i.add(d.name), a.add(t.id)) : (r.push({
|
|
512
|
-
sourceId: t.id,
|
|
513
|
-
propertyName: d.name
|
|
514
|
-
}), i.add(d.name), a.add(t.id))));
|
|
515
|
-
}
|
|
516
|
-
let u = W(n, i);
|
|
517
|
-
if (u) {
|
|
518
|
-
let e = o.find((e) => {
|
|
519
|
-
if (a.has(e.id) && !F(e)) return !1;
|
|
520
|
-
let t = M(e.label), n = M(e.id.replace(/^rss-/, "").replace(/^fm-/, ""));
|
|
521
|
-
return (t === "link" || t === "url" || n === "link" || n === "url" || t === "permalink") && c(e.value);
|
|
522
|
-
});
|
|
523
|
-
e && (r.push({
|
|
524
|
-
sourceId: e.id,
|
|
525
|
-
propertyName: u.name,
|
|
526
|
-
resolve: "extract"
|
|
527
|
-
}), i.add(u.name));
|
|
528
|
-
}
|
|
529
|
-
return r;
|
|
530
|
-
}
|
|
531
|
-
//#endregion
|
|
532
|
-
export { l as a, h as c, g as d, s as f, n as g, t as h, y as i, m as l, e as m, T as n, u as o, c as p, E as r, _ as s, G as t, v as u };
|
|
533
|
-
|
|
534
|
-
//# sourceMappingURL=autoMap-PTFd4l-9.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"autoMap-PTFd4l-9.js","names":[],"sources":["../src/relationLookup.ts","../src/classifyUrl.ts","../src/resolvedSources.ts","../src/applyMapping.ts","../src/autoMap.ts"],"sourcesContent":["import type { TargetProperty } from './types'\n\n/**\n * True when the target expects a Seed relation uid (or list of uids)\n * rather than a copied scalar string.\n */\nexport function isRelationLookupTarget(target: TargetProperty): boolean {\n if (target.dataType === 'Relation') return true\n if (target.dataType === 'List') {\n return target.refValueType === 'Relation' || Boolean(target.ref)\n }\n return false\n}\n\n/** Trim and collapse internal whitespace for lookup dictionary keys. */\nexport function normalizeLookupKey(raw: string): string {\n return raw.replace(/\\s+/g, ' ').trim()\n}\n\n/**\n * Shape a looked-up uid value for the target dataType.\n * Relation → single string; List → string[].\n */\nexport function shapeLookupValue(\n mapped: string | string[],\n target: TargetProperty,\n): string | string[] {\n if (target.dataType === 'List') {\n if (Array.isArray(mapped)) {\n return mapped.map((u) => String(u).trim()).filter(Boolean)\n }\n const one = String(mapped).trim()\n return one ? [one] : []\n }\n // Relation (or any non-List lookup target): single uid\n if (Array.isArray(mapped)) {\n return String(mapped[0] ?? '').trim()\n }\n return String(mapped).trim()\n}\n","import type { UrlMediaClass } from './types'\n\nexport type ClassifyUrlInput = {\n url: string\n contentType?: string | null\n}\n\nfunction normalizeMime(contentType: string): string {\n return contentType.split(';')[0]?.trim().toLowerCase() ?? ''\n}\n\nfunction classFromMime(mime: string): UrlMediaClass | null {\n if (!mime) return null\n if (mime.startsWith('image/')) return 'image'\n if (mime.startsWith('audio/')) return 'audio'\n if (mime.startsWith('video/')) return 'video'\n if (\n mime === 'text/html' ||\n mime === 'application/xhtml+xml' ||\n mime === 'application/xhtml'\n ) {\n return 'html'\n }\n return null\n}\n\nfunction pathFromUrl(url: string): string {\n const trimmed = url.trim()\n try {\n const u = new URL(trimmed)\n return u.pathname.toLowerCase()\n } catch {\n const noQuery = trimmed.split('?')[0]?.split('#')[0] ?? trimmed\n return noQuery.toLowerCase()\n }\n}\n\nfunction classFromPath(pathname: string): UrlMediaClass {\n if (/\\.(html?|xhtml|php|asp|aspx|jsp)$/i.test(pathname)) return 'html'\n if (/\\.(jpe?g|png|gif|webp|avif|svg|bmp|ico|tiff?)$/i.test(pathname)) {\n return 'image'\n }\n if (/\\.(mp3|m4a|aac|ogg|oga|opus|wav|flac|aiff?)$/i.test(pathname)) {\n return 'audio'\n }\n if (/\\.(mp4|m4v|webm|ogv|mov|avi|mkv)$/i.test(pathname)) return 'video'\n return 'unknown'\n}\n\n/**\n * Pure MIME / URL-shape classifier for import mapping.\n * Prefer `contentType` when present; fall back to path extension.\n * No I/O. Distinct from `@seedprotocol/sdk` `classifyMediaRef` (Seed ref identity).\n */\nexport function classifyUrl(input: ClassifyUrlInput): UrlMediaClass {\n const url = typeof input.url === 'string' ? input.url.trim() : ''\n if (!url) return 'unknown'\n\n if (input.contentType) {\n const fromMime = classFromMime(normalizeMime(String(input.contentType)))\n if (fromMime) return fromMime\n }\n\n return classFromPath(pathFromUrl(url))\n}\n\n/** True when the string looks like an absolute http(s) / blob / data URL. */\nexport function looksLikeUrl(value: string): boolean {\n const v = value.trim().toLowerCase()\n return (\n v.startsWith('http://') ||\n v.startsWith('https://') ||\n v.startsWith('blob:') ||\n v.startsWith('data:')\n )\n}\n","import { classifyUrl, looksLikeUrl } from './classifyUrl'\nimport type {\n FieldMapping,\n ResolveJob,\n SourceNode,\n UrlMediaClass,\n} from './types'\n\nexport const RESOLVE_EXTRACT_SUFFIX = '@extract'\nexport const RESOLVE_FILE_SUFFIX = '@file'\n\nfunction contentTypeFromMeta(meta?: Record<string, unknown>): string | undefined {\n if (!meta) return undefined\n const ct = meta.contentType ?? meta.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction mediaClassFromSource(source: SourceNode): UrlMediaClass {\n const metaClass = source.meta?.class\n if (\n metaClass === 'html' ||\n metaClass === 'image' ||\n metaClass === 'audio' ||\n metaClass === 'video' ||\n metaClass === 'unknown'\n ) {\n return metaClass\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return classifyUrl({\n url,\n contentType: contentTypeFromMeta(source.meta),\n })\n}\n\nfunction isUrlCandidate(source: SourceNode): boolean {\n if (source.kind === 'resolved') return false\n if (source.kind === 'full' || source.kind === 'section') return false\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return looksLikeUrl(url)\n}\n\n/**\n * Parse a package-owned derived source id (`origin@extract` / `origin@file`).\n */\nexport function parseResolvedSourceId(\n sourceId: string,\n): { originId: string; resolve: ResolveJob } | null {\n if (sourceId.endsWith(RESOLVE_EXTRACT_SUFFIX)) {\n return {\n originId: sourceId.slice(0, -RESOLVE_EXTRACT_SUFFIX.length),\n resolve: 'extract',\n }\n }\n if (sourceId.endsWith(RESOLVE_FILE_SUFFIX)) {\n return {\n originId: sourceId.slice(0, -RESOLVE_FILE_SUFFIX.length),\n resolve: 'file',\n }\n }\n return null\n}\n\n/**\n * Normalize a UI selection (possibly a derived `@extract` / `@file` node)\n * into a persistable FieldMapping with `resolve` on the origin source.\n */\nexport function normalizeMappingFromSourceId(\n sourceId: string,\n propertyName: string,\n): FieldMapping {\n const parsed = parseResolvedSourceId(sourceId)\n if (!parsed) {\n return { sourceId, propertyName }\n }\n return {\n sourceId: parsed.originId,\n propertyName,\n resolve: parsed.resolve,\n }\n}\n\n/**\n * Stable display id for a derived resolve candidate.\n */\nexport function resolvedSourceId(originId: string, job: ResolveJob): string {\n return job === 'extract'\n ? `${originId}${RESOLVE_EXTRACT_SUFFIX}`\n : `${originId}${RESOLVE_FILE_SUFFIX}`\n}\n\n/**\n * Expand URL-classifiable sources with package-owned extract/file candidates\n * for FieldMapper / autoMap. Original nodes are preserved.\n *\n * Prefer mapping derived nodes in the UI; persist via\n * `normalizeMappingFromSourceId` so documents store origin + `resolve`.\n */\nexport function buildResolvedSourceNodes(sources: SourceNode[]): SourceNode[] {\n const out: SourceNode[] = [...sources]\n const existing = new Set(sources.map((s) => s.id))\n\n for (const source of sources) {\n if (!isUrlCandidate(source)) continue\n\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value.trim()\n const contentType = contentTypeFromMeta(source.meta)\n const mediaClass = mediaClassFromSource(source)\n\n const extractId = resolvedSourceId(source.id, 'extract')\n if (!existing.has(extractId)) {\n out.push({\n id: extractId,\n label: `${source.label} → extract HTML`,\n kind: 'resolved',\n value: url,\n meta: {\n originId: source.id,\n resolve: 'extract' satisfies ResolveJob,\n class: 'html' satisfies UrlMediaClass,\n contentType,\n url,\n },\n })\n existing.add(extractId)\n }\n\n const fileId = resolvedSourceId(source.id, 'file')\n if (!existing.has(fileId)) {\n out.push({\n id: fileId,\n label: `${source.label} → file`,\n kind: 'resolved',\n value: url,\n meta: {\n originId: source.id,\n resolve: 'file' satisfies ResolveJob,\n class: mediaClass,\n contentType,\n url,\n },\n })\n existing.add(fileId)\n }\n }\n\n return out\n}\n\n/**\n * Look up the origin source for a mapping (handles resolve edges).\n */\nexport function resolveMappingSource(\n sources: SourceNode[],\n mapping: FieldMapping,\n): SourceNode | undefined {\n const byId = new Map(sources.map((s) => [s.id, s]))\n const direct = byId.get(mapping.sourceId)\n if (direct) return direct\n if (mapping.resolve) {\n const derived = byId.get(resolvedSourceId(mapping.sourceId, mapping.resolve))\n if (derived) return derived\n }\n return undefined\n}\n","import {\n isRelationLookupTarget,\n normalizeLookupKey,\n shapeLookupValue,\n} from './relationLookup'\nimport { resolveMappingSource } from './resolvedSources'\nimport type {\n ApplyMappingAsyncResult,\n FieldMapping,\n MappingLookups,\n PropertyBag,\n ResolveCallback,\n ResolveContext,\n SourceNode,\n TargetProperty,\n UrlMediaClass,\n} from './types'\n\n/**\n * Coerce a raw string value to the Seed model property dataType.\n */\nexport function coerceValue(rawValue: string, dataType: string): unknown {\n if (dataType === 'Number') {\n return parseFloat(String(rawValue)) || 0\n }\n if (dataType === 'Boolean') {\n return (\n rawValue === 'true' ||\n rawValue === '1' ||\n String(rawValue).toLowerCase() === 'yes'\n )\n }\n if (dataType === 'Json') {\n try {\n return JSON.parse(rawValue)\n } catch {\n return rawValue\n }\n }\n if (dataType === 'Date') {\n const d = new Date(String(rawValue))\n return Number.isNaN(d.getTime()) ? rawValue : d.getTime()\n }\n return String(rawValue ?? '')\n}\n\nfunction coerceResolved(raw: unknown, dataType: string): unknown {\n if (typeof raw === 'string') {\n return coerceValue(raw, dataType)\n }\n if (raw == null) {\n return coerceValue('', dataType)\n }\n // Host may return seed refs, blobs, or already-shaped values for File/Image.\n if (\n dataType === 'Image' ||\n dataType === 'File' ||\n dataType === 'Relation' ||\n dataType === 'List' ||\n dataType === 'Json'\n ) {\n return raw\n }\n return coerceValue(String(raw), dataType)\n}\n\nfunction urlFromSource(source: SourceNode): string {\n if (typeof source.meta?.url === 'string' && source.meta.url.trim()) {\n return source.meta.url.trim()\n }\n return (source.value || source.label).trim()\n}\n\nfunction contentTypeFromSource(source: SourceNode): string | undefined {\n const ct = source.meta?.contentType ?? source.meta?.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction classFromSource(source: SourceNode): UrlMediaClass | undefined {\n const c = source.meta?.class\n if (\n c === 'html' ||\n c === 'image' ||\n c === 'audio' ||\n c === 'video' ||\n c === 'unknown'\n ) {\n return c\n }\n return undefined\n}\n\nfunction lookupFromTable(\n lookups: MappingLookups | undefined,\n propertyName: string,\n rawKey: string,\n): string | string[] | undefined {\n if (!lookups) return undefined\n const table = lookups[propertyName]\n if (!table) return undefined\n if (Object.prototype.hasOwnProperty.call(table, rawKey)) {\n return table[rawKey]\n }\n return undefined\n}\n\n/**\n * Apply field mappings to produce a property bag for createItem / publish.\n * Missing sources or unknown target properties are skipped (no throw).\n * Mappings with `resolve` are skipped — use `applyMappingAsync` with a host callback.\n */\nexport function applyMapping(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n): PropertyBag {\n const byId = new Map(sources.map((s) => [s.id, s]))\n const byName = new Map(targets.map((t) => [t.name, t]))\n const properties: PropertyBag = {}\n\n for (const mapping of mappings) {\n if (mapping.resolve) continue\n\n const source = byId.get(mapping.sourceId)\n const target = byName.get(mapping.propertyName)\n if (!source || !target) continue\n // Never copy a raw string onto relation / list-of-relation targets.\n if (isRelationLookupTarget(target)) continue\n\n const raw = source.value || source.label\n properties[mapping.propertyName] = coerceValue(raw, target.dataType)\n }\n\n return properties\n}\n\nexport type ApplyMappingAsyncOptions = {\n /** Required for extract/file edges and lookup misses. */\n resolve?: ResolveCallback\n /** String → seed uid dictionaries keyed by property name. */\n lookups?: MappingLookups\n}\n\n/**\n * Async apply: copy+coerce plain edges; for `resolve` edges call the host\n * callback (or apply lookups for `lookup`) then coerce. Partial success —\n * failed resolve edges are listed in `errors` and omitted from `properties`.\n */\nexport async function applyMappingAsync(\n sources: SourceNode[],\n mappings: FieldMapping[],\n targets: TargetProperty[],\n options: ApplyMappingAsyncOptions = {},\n): Promise<ApplyMappingAsyncResult> {\n const byName = new Map(targets.map((t) => [t.name, t]))\n const properties: PropertyBag = {}\n const errors: ApplyMappingAsyncResult['errors'] = []\n\n for (const mapping of mappings) {\n const target = byName.get(mapping.propertyName)\n if (!target) continue\n\n if (!mapping.resolve) {\n const source = sources.find((s) => s.id === mapping.sourceId)\n if (!source) continue\n if (isRelationLookupTarget(target)) continue\n const raw = source.value || source.label\n properties[mapping.propertyName] = coerceValue(raw, target.dataType)\n continue\n }\n\n if (mapping.resolve === 'lookup') {\n const source = sources.find((s) => s.id === mapping.sourceId)\n if (!source) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: `Source not found: ${mapping.sourceId}`,\n })\n continue\n }\n\n const rawValue = normalizeLookupKey(source.value || source.label)\n const fromTable = lookupFromTable(\n options.lookups,\n mapping.propertyName,\n rawValue,\n )\n\n if (fromTable !== undefined) {\n properties[mapping.propertyName] = shapeLookupValue(fromTable, target)\n continue\n }\n\n if (!options.resolve) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: `No lookup entry for \"${rawValue}\" and no resolve callback`,\n })\n continue\n }\n\n const ctx: ResolveContext = {\n job: 'lookup',\n source,\n target,\n rawValue,\n }\n\n try {\n const resolved = await options.resolve(ctx)\n if (resolved == null) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: `Lookup returned empty for \"${rawValue}\"`,\n })\n continue\n }\n if (typeof resolved === 'string' || Array.isArray(resolved)) {\n properties[mapping.propertyName] = shapeLookupValue(\n resolved as string | string[],\n target,\n )\n } else {\n properties[mapping.propertyName] = coerceResolved(\n resolved,\n target.dataType,\n )\n }\n } catch (err) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: 'lookup',\n message: err instanceof Error ? err.message : String(err),\n })\n }\n continue\n }\n\n const source = resolveMappingSource(sources, mapping)\n if (!source) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: `Source not found: ${mapping.sourceId}`,\n })\n continue\n }\n\n if (!options.resolve) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: `No resolve callback for ${mapping.resolve}`,\n })\n continue\n }\n\n const ctx: ResolveContext = {\n job: mapping.resolve,\n url: urlFromSource(source),\n source,\n target,\n contentType: contentTypeFromSource(source),\n class: classFromSource(source),\n }\n\n try {\n const resolved = await options.resolve(ctx)\n properties[mapping.propertyName] = coerceResolved(resolved, target.dataType)\n } catch (err) {\n errors.push({\n sourceId: mapping.sourceId,\n propertyName: mapping.propertyName,\n resolve: mapping.resolve,\n message: err instanceof Error ? err.message : String(err),\n })\n }\n }\n\n return { properties, errors }\n}\n","import { classifyUrl, looksLikeUrl } from './classifyUrl'\nimport { isRelationLookupTarget } from './relationLookup'\nimport type { FieldMapping, SourceNode, TargetProperty, UrlMediaClass } from './types'\n\nconst FULL_DOC_PROP_NAMES = ['text', 'content', 'body', 'fulltext', 'markdown']\nconst HTML_PROP_NAMES = ['html', 'content', 'body', 'text']\nconst IMAGE_PROP_ALIASES = [\n 'featureimage',\n 'feature_image',\n 'image',\n 'cover',\n 'coverimage',\n]\nconst FILE_PROP_ALIASES = ['file', 'audio', 'video', 'enclosure', 'attachment', 'media']\nconst URL_PROP_ALIASES = ['importurl', 'canonicalurl', 'url', 'link', 'permalink']\n\nfunction normalizeName(name: string): string {\n return name.toLowerCase().replace(/\\s+/g, '').replace(/[:_-]/g, '')\n}\n\nfunction namesMatch(a: string, b: string): boolean {\n const na = normalizeName(a)\n const nb = normalizeName(b)\n return na === nb || na.includes(nb) || nb.includes(na)\n}\n\n/**\n * Sources that fan out to every unused target matching any alias.\n * Keys are normalized source label/id fragments.\n */\nconst FAN_OUT_ALIASES: Record<string, string[]> = {\n link: URL_PROP_ALIASES,\n url: URL_PROP_ALIASES,\n}\n\nfunction fanOutAliasesForSource(source: SourceNode): string[] | undefined {\n if (source.kind === 'resolved') return undefined\n const labelKey = normalizeName(source.label)\n const idKey = normalizeName(source.id.replace(/^rss-/, '').replace(/^fm-/, ''))\n return FAN_OUT_ALIASES[labelKey] ?? FAN_OUT_ALIASES[idKey]\n}\n\nfunction contentTypeFromMeta(meta?: Record<string, unknown>): string | undefined {\n if (!meta) return undefined\n const ct = meta.contentType ?? meta.type\n return typeof ct === 'string' && ct.trim() ? ct.trim() : undefined\n}\n\nfunction mediaClassOf(source: SourceNode): UrlMediaClass {\n const metaClass = source.meta?.class\n if (\n metaClass === 'html' ||\n metaClass === 'image' ||\n metaClass === 'audio' ||\n metaClass === 'video' ||\n metaClass === 'unknown'\n ) {\n return metaClass\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return classifyUrl({\n url,\n contentType: contentTypeFromMeta(source.meta),\n })\n}\n\nfunction isRawUrlSource(source: SourceNode): boolean {\n if (source.kind === 'resolved') return false\n if (source.kind === 'full' || source.kind === 'section') return false\n // content:encoded / description HTML bodies are not \"raw URL\" sources\n const labelKey = normalizeName(source.label)\n if (\n labelKey === 'contentencoded' ||\n labelKey === 'content' ||\n labelKey === 'description' ||\n labelKey === 'summary' ||\n labelKey === 'title'\n ) {\n return false\n }\n const url =\n typeof source.meta?.url === 'string' && source.meta.url.trim()\n ? source.meta.url.trim()\n : source.value\n return looksLikeUrl(url) && !url.trim().includes('<')\n}\n\nfunction isHtmlLikeTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n return (\n HTML_PROP_NAMES.some((p) => namesMatch(n, p)) ||\n target.dataType === 'Html' ||\n target.dataType === 'Text'\n )\n}\n\nfunction isRichMediaTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n if (\n target.dataType === 'Image' ||\n target.dataType === 'File' ||\n target.dataType === 'Relation'\n ) {\n return (\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n FILE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n target.dataType === 'Image' ||\n target.dataType === 'File'\n )\n }\n return (\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a)) ||\n FILE_PROP_ALIASES.some((a) => namesMatch(n, a))\n )\n}\n\nfunction isUrlOnlyTarget(target: TargetProperty): boolean {\n const n = normalizeName(target.name)\n return URL_PROP_ALIASES.some((a) => namesMatch(n, a))\n}\n\nfunction findImageTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n return (\n p.dataType === 'Image' ||\n IMAGE_PROP_ALIASES.some((a) => namesMatch(n, a))\n )\n })\n}\n\nfunction findFileTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n mediaClass: UrlMediaClass,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n if (mediaClass === 'audio' && namesMatch(n, 'audio')) return true\n if (mediaClass === 'video' && namesMatch(n, 'video')) return true\n return p.dataType === 'File' || FILE_PROP_ALIASES.some((a) => namesMatch(n, a))\n })\n}\n\nfunction findHtmlTarget(\n targets: TargetProperty[],\n usedProps: Set<string>,\n): TargetProperty | undefined {\n return targets.find((p) => {\n if (usedProps.has(p.name)) return false\n const n = normalizeName(p.name)\n return (\n p.dataType === 'Html' ||\n HTML_PROP_NAMES.some((alias) => namesMatch(n, alias))\n )\n })\n}\n\n/**\n * Heuristic auto-map: full-document / full-text first, then RSS aliases,\n * URL fan-out (copy only), media file/extract jobs, then fuzzy name match.\n * Never maps a raw URL onto html / Image / File without `resolve`.\n */\nexport function autoMap(\n sources: SourceNode[],\n targets: TargetProperty[],\n): FieldMapping[] {\n const mappings: FieldMapping[] = []\n const usedProps = new Set<string>()\n const usedSources = new Set<string>()\n\n // Skip derived resolve nodes in the main pass; we emit resolve jobs from origins.\n const baseSources = sources.filter((s) => s.kind !== 'resolved')\n\n const fullSource = baseSources.find((s) => s.kind === 'full')\n if (fullSource) {\n const fullDocMatch = targets.find((p) =>\n FULL_DOC_PROP_NAMES.includes(p.name.toLowerCase()),\n )\n if (fullDocMatch) {\n mappings.push({\n sourceId: fullSource.id,\n propertyName: fullDocMatch.name,\n })\n usedProps.add(fullDocMatch.name)\n usedSources.add(fullSource.id)\n }\n }\n\n const rssAliases: Record<string, string[]> = {\n title: ['title', 'name', 'headline'],\n 'content:encoded': ['html', 'content', 'body', 'text'],\n content: ['html', 'content', 'body', 'text'],\n description: ['summary', 'description', 'excerpt'],\n summary: ['summary', 'description', 'excerpt'],\n featureimage: ['featureimage', 'feature_image', 'image', 'cover'],\n feature_image: ['featureimage', 'feature_image', 'image', 'cover'],\n link: ['url', 'link', 'permalink'],\n creator: ['author', 'authors', 'creator', 'byline'],\n author: ['author', 'authors', 'creator', 'byline'],\n }\n\n // Prefer full-text RSS → html (copy) before URL extract\n for (const source of baseSources) {\n if (usedSources.has(source.id)) continue\n const labelKey = normalizeName(source.label)\n const idKey = source.id.replace(/^rss-/, '').replace(/^fm-/, '')\n if (\n labelKey === 'contentencoded' ||\n normalizeName(idKey) === 'contentencoded' ||\n (labelKey === 'content' && source.value.includes('<'))\n ) {\n const htmlTarget = findHtmlTarget(targets, usedProps)\n if (htmlTarget) {\n mappings.push({ sourceId: source.id, propertyName: htmlTarget.name })\n usedProps.add(htmlTarget.name)\n usedSources.add(source.id)\n }\n }\n }\n\n for (const source of baseSources) {\n if (usedSources.has(source.id)) continue\n\n const fanOutAliases = fanOutAliasesForSource(source)\n if (fanOutAliases) {\n for (const target of targets) {\n if (usedProps.has(target.name)) continue\n if (isRichMediaTarget(target) && !isUrlOnlyTarget(target)) continue\n if (isHtmlLikeTarget(target) && !isUrlOnlyTarget(target)) {\n // Do not fan raw link into html — handled later as extract if needed\n const n = normalizeName(target.name)\n if (n === 'html' || target.dataType === 'Html') continue\n }\n const matches = fanOutAliases.some((alias) =>\n namesMatch(target.name, alias),\n )\n if (matches) {\n mappings.push({ sourceId: source.id, propertyName: target.name })\n usedProps.add(target.name)\n }\n }\n continue\n }\n\n // Media URL sources → resolve:file onto Image/File targets\n if (isRawUrlSource(source)) {\n const mediaClass = mediaClassOf(source)\n if (mediaClass === 'image') {\n const imageTarget = findImageTarget(targets, usedProps)\n if (imageTarget) {\n mappings.push({\n sourceId: source.id,\n propertyName: imageTarget.name,\n resolve: 'file',\n })\n usedProps.add(imageTarget.name)\n usedSources.add(source.id)\n continue\n }\n }\n if (mediaClass === 'audio' || mediaClass === 'video') {\n const fileTarget = findFileTarget(targets, usedProps, mediaClass)\n if (fileTarget) {\n mappings.push({\n sourceId: source.id,\n propertyName: fileTarget.name,\n resolve: 'file',\n })\n usedProps.add(fileTarget.name)\n usedSources.add(source.id)\n continue\n }\n }\n // Unknown / html-class URLs: do not map onto rich media without resolve\n // (extract handled in a later pass for link-like sources)\n }\n\n const labelKey = normalizeName(source.label)\n const idKey = source.id.replace(/^rss-/, '').replace(/^fm-/, '')\n const aliasKeys = [\n ...(rssAliases[source.label] ?? []),\n ...(rssAliases[idKey] ?? []),\n ...(rssAliases[labelKey] ?? []),\n ]\n\n let match: TargetProperty | undefined\n\n for (const alias of aliasKeys) {\n match = targets.find(\n (p) =>\n !usedProps.has(p.name) &&\n !isRelationLookupTarget(p) &&\n namesMatch(p.name, alias),\n )\n if (match) break\n }\n\n if (!match) {\n match = targets.find(\n (p) =>\n !usedProps.has(p.name) &&\n !isRelationLookupTarget(p) &&\n (namesMatch(p.name, source.label) || namesMatch(p.name, idKey)),\n )\n }\n\n if (match) {\n // Block raw URL → html / image / file without resolve\n if (\n isRawUrlSource(source) &&\n (isHtmlLikeTarget(match) || isRichMediaTarget(match)) &&\n !isUrlOnlyTarget(match)\n ) {\n // skip — extract / file jobs handled separately\n } else if (\n isRawUrlSource(source) &&\n mediaClassOf(source) === 'image' &&\n isRichMediaTarget(match)\n ) {\n mappings.push({\n sourceId: source.id,\n propertyName: match.name,\n resolve: 'file',\n })\n usedProps.add(match.name)\n usedSources.add(source.id)\n } else {\n mappings.push({ sourceId: source.id, propertyName: match.name })\n usedProps.add(match.name)\n usedSources.add(source.id)\n }\n }\n }\n\n // If no HTML body filled, prefer extract from link/permalink\n const htmlStillFree = findHtmlTarget(targets, usedProps)\n if (htmlStillFree) {\n const linkSource = baseSources.find((s) => {\n if (usedSources.has(s.id) && !fanOutAliasesForSource(s)) return false\n const labelKey = normalizeName(s.label)\n const idKey = normalizeName(s.id.replace(/^rss-/, '').replace(/^fm-/, ''))\n return (\n (labelKey === 'link' ||\n labelKey === 'url' ||\n idKey === 'link' ||\n idKey === 'url' ||\n labelKey === 'permalink') &&\n looksLikeUrl(s.value)\n )\n })\n if (linkSource) {\n mappings.push({\n sourceId: linkSource.id,\n propertyName: htmlStillFree.name,\n resolve: 'extract',\n })\n usedProps.add(htmlStillFree.name)\n }\n }\n\n return mappings\n}\n"],"mappings":"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"}
|