@seedprotocol/mapping 0.5.3 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +202 -36
  3. package/dist/adapters/rss.d.ts +2 -1
  4. package/dist/adapters/rss.d.ts.map +1 -1
  5. package/dist/applyMapping.d.ts +14 -1
  6. package/dist/applyMapping.d.ts.map +1 -1
  7. package/dist/autoMap-PTFd4l-9.js +534 -0
  8. package/dist/autoMap-PTFd4l-9.js.map +1 -0
  9. package/dist/autoMap.d.ts +3 -3
  10. package/dist/autoMap.d.ts.map +1 -1
  11. package/dist/classifyUrl.d.ts +14 -0
  12. package/dist/classifyUrl.d.ts.map +1 -0
  13. package/dist/index.d.ts +7 -3
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +91 -402
  16. package/dist/index.js.map +1 -1
  17. package/dist/react/FieldMapper.d.ts +65 -5
  18. package/dist/react/FieldMapper.d.ts.map +1 -1
  19. package/dist/react/FieldMapperWires.d.ts +19 -0
  20. package/dist/react/FieldMapperWires.d.ts.map +1 -0
  21. package/dist/react/LookupEditor.d.ts +24 -0
  22. package/dist/react/LookupEditor.d.ts.map +1 -0
  23. package/dist/react/PropertyRows.d.ts +19 -0
  24. package/dist/react/PropertyRows.d.ts.map +1 -0
  25. package/dist/react/SourceRows.d.ts +18 -0
  26. package/dist/react/SourceRows.d.ts.map +1 -0
  27. package/dist/react/fieldMapperControls.d.ts +9 -0
  28. package/dist/react/fieldMapperControls.d.ts.map +1 -0
  29. package/dist/react/fieldMapperCore.d.ts +79 -0
  30. package/dist/react/fieldMapperCore.d.ts.map +1 -0
  31. package/dist/react/fieldMapperSlots.d.ts +69 -0
  32. package/dist/react/fieldMapperSlots.d.ts.map +1 -0
  33. package/dist/react/fieldMapperTheme.d.ts +34 -0
  34. package/dist/react/fieldMapperTheme.d.ts.map +1 -0
  35. package/dist/react/fieldMapperTypes.d.ts +63 -0
  36. package/dist/react/fieldMapperTypes.d.ts.map +1 -0
  37. package/dist/react/useFieldMapper.d.ts +8 -0
  38. package/dist/react/useFieldMapper.d.ts.map +1 -0
  39. package/dist/react.d.ts +10 -0
  40. package/dist/react.d.ts.map +1 -0
  41. package/dist/react.js +1617 -0
  42. package/dist/react.js.map +1 -0
  43. package/dist/relationLookup.d.ts +14 -0
  44. package/dist/relationLookup.d.ts.map +1 -0
  45. package/dist/resolvedSources.d.ts +32 -0
  46. package/dist/resolvedSources.d.ts.map +1 -0
  47. package/dist/types.d.ts +57 -2
  48. package/dist/types.d.ts.map +1 -1
  49. package/package.json +19 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.1
4
+
5
+ - `FieldMapper` `renderRowAccessory?: (row: FieldMapperRow) => ReactNode` — host chrome slot on each rows-layout row (`.fm-row-accessory` / `classNames.rowAccessory`), after the transform control and before remove. Package does not fetch or preview; hosts return `null` when idle (e.g. show **Preview** only for `resolve: 'extract' | 'file'`).
6
+ - Optional `SourceNode.subtitle` for a secondary display line (inspector, wires card, source option labels). Prefer this over stuffing origin into `label`. Display-only — not part of `MappingDocument`.
7
+
8
+ ## 0.6.0
9
+
10
+ - `FieldMapper` Phase 5: `layout` defaults to `'rows'`; `'wires'` is deprecated but still supported.
11
+ - `FieldMapper` Phase 4: per-row lookup editors (`slots.lookups: 'row'`), row/JSON preview parity with sync `applyMapping` (+ `_pendingResolve`), JSON behind a `<details>` disclosure. Rows layout defaults `lookups` to `'row'`; wires keep `'section'`.
12
+ - Shared `LookupEditor` + `buildSyncPreviewBag` / upgraded `previewForEdge` (lookup table hits, coerced copy values).
13
+ - `FieldMapper` Phase 3 theming contract: `--sfm-*` tokens (with `--fm-*` aliases), `theme="default" | "structural" | "none"` (`unstyled` shim), `classNames` / `components` / `slots`, `@layer seed-field-mapper`, document-once CSS injection, row `data-source-kind`.
14
+ - Deprecated (still work): `layout="wires"`, `theme="unstyled"`, `showPreview`, `connectionColors` — prefer `layout="rows"`, `theme="none"`, `slots.preview`, and CSS map tokens.
15
+ - `FieldMapper` row layout (Phase 1–2 of the redesign): `layout="rows" | "wires"`, `rowKey="property" | "source"`, `defaultRows`, optional `TargetProperty.required` for coverage.
16
+ - Headless `useFieldMapper` hook + shared core (`setSource` / `setTransform` / coverage / conflicts); wires UI refactored to consume the hook.
17
+ - Rows UI: transform control on the edge (no `buildResolvedSourceNodes` in the rows path), coverage toolbar, mapped+required filter, add-mapping flow, source inspector; source mode conflict + coverage banners.
18
+ - **Breaking:** `FieldMapper` and related UI exports moved to `@seedprotocol/mapping/react`. The default entry is headless-only (no React import or required peer) so Node sidecars can load without React. Install `react` / `react-dom` only when using `/react`.
19
+ - **Breaking:** `FieldMapper` `layout` default flipped from `'wires'` to `'rows'`. Pass `layout="wires"` explicitly if you still need the two-pane connector UI. For rows, pass origin sources only (not `buildResolvedSourceNodes`).
20
+ - `resolve: 'lookup'` for Relation / List-of-Relation targets: persistable `MappingDocument.lookups` (string → seed uid), `applyMappingAsync` table hit + optional host callback on miss; sync apply skips lookup edges.
21
+ - `TargetProperty.ref` / `refValueType`; `isRelationLookupTarget` helper; `autoMap` never plain-copies onto lookup-capable targets (author → authors no longer writes a string into a relation list).
22
+ - `FieldMapper`: connecting to a lookup-capable target sets `resolve: 'lookup'`; optional `lookups` / `onLookupsChange` panel edits string → uid maps (comma-separated for multi).
23
+ - `FieldMapper`: `theme="default" | "unstyled"`, CSS-var connector strokes (`--fm-map-1…8` / `--map-1…8`), optional `connectionColors`, `data-mapping-index` / `data-pair` on wells and paths; pending `.active` only on the selected source.
24
+ - `FieldMapping.resolve?: 'extract' | 'file' | 'lookup'`; sync `applyMapping` skips resolve edges; new `applyMappingAsync` with host callback.
25
+ - `classifyUrl`, `buildResolvedSourceNodes`, `normalizeMappingFromSourceId` for package-owned extract/file candidates.
26
+ - RSS adapter exposes enclosure / media:content as `url` + `contentType` in `meta` (stable `rss-enclosure-N` ids).
27
+ - `autoMap` never maps a raw URL onto html/Image/File without `resolve`; prefers full-text → html, then extract, then file jobs.
28
+ - Allow one source to map to multiple properties (edge-list fan-out); each property remains exclusive.
29
+ - `autoMap` fans `link` / `url` sources out to matching URL-ish targets (`importUrl`, `canonicalUrl`, `url`, `link`, `permalink`).
30
+ - `FieldMapper` supports attaching multiple properties from an active source without clearing prior edges; normalizes `@extract`/`@file` nodes to `resolve` on persist.
31
+
3
32
  ## 0.5.1
4
33
 
5
34
  - Initial Phase 1 release: headless mapping core, markdown + RSS adapters, `FieldMapper` UI.
package/README.md CHANGED
@@ -5,8 +5,15 @@ Source → Seed model property mapping helpers and a props-driven React UI.
5
5
  Use this package to:
6
6
 
7
7
  1. Parse markdown or RSS/Atom into `SourceNode[]`
8
- 2. Author 1:1 `FieldMapping`s (manually, via `autoMap`, or via `FieldMapper`)
9
- 3. `applyMapping` to a coerced property bag for `createItem` / publish
8
+ 2. Optionally expand URL sources with `buildResolvedSourceNodes` (extract / file candidates)
9
+ 3. Author `FieldMapping` edges (manually, via `autoMap`, or via `FieldMapper`)
10
+ 4. `applyMapping` (sync copy) or `applyMappingAsync` (host resolve callback) → property bag
11
+
12
+ Mappings are an edge list: one source may fan out to multiple properties (e.g. RSS
13
+ `link` → `importUrl` and `canonicalUrl`). Each property is exclusive — at most one
14
+ source may map to it. Optional `resolve: 'extract' | 'file' | 'lookup'` marks
15
+ transforms the **host** (or a persisted value map) performs; the package never
16
+ fetches, runs Readability, or loads Seed Identity items.
10
17
 
11
18
  ## Install
12
19
 
@@ -14,7 +21,11 @@ Use this package to:
14
21
  bun add @seedprotocol/mapping
15
22
  ```
16
23
 
17
- Peers: `react`, `react-dom`. RSS parsing uses `rss-parser` with the same custom fields as `@seedprotocol/feed` `parseRssString` (aligned, no hard dependency on the feed package barrel).
24
+ The default entry (`@seedprotocol/mapping`) is headless — no React peer required.
25
+ For `FieldMapper`, also install React peers and import from `@seedprotocol/mapping/react`.
26
+
27
+ RSS parsing uses `rss-parser` with the same custom fields as `@seedprotocol/feed`
28
+ `parseRssString` (aligned, no hard dependency on the feed package barrel).
18
29
 
19
30
  ## Headless API
20
31
 
@@ -24,6 +35,9 @@ import {
24
35
  rssXmlToSources,
25
36
  autoMap,
26
37
  applyMapping,
38
+ applyMappingAsync,
39
+ buildResolvedSourceNodes,
40
+ classifyUrl,
27
41
  type TargetProperty,
28
42
  type MappingDocument,
29
43
  } from '@seedprotocol/mapping'
@@ -43,63 +57,215 @@ const doc: MappingDocument = {
43
57
  }
44
58
  ```
45
59
 
46
- RSS:
60
+ RSS with resolve jobs:
47
61
 
48
62
  ```ts
49
- const { channel, items } = await rssXmlToSources(xml)
63
+ const { items } = await rssXmlToSources(xml)
50
64
  const itemSources = items[0]!
65
+ const expanded = buildResolvedSourceNodes(itemSources)
66
+ const postTargets: TargetProperty[] = [
67
+ { name: 'importUrl', dataType: 'String' },
68
+ { name: 'canonicalUrl', dataType: 'String' },
69
+ { name: 'html', dataType: 'Html' },
70
+ { name: 'featureImage', dataType: 'Image' },
71
+ { name: 'title', dataType: 'String' },
72
+ ]
51
73
  const mappings = autoMap(itemSources, postTargets)
52
- const properties = applyMapping(itemSources, mappings, postTargets)
74
+ // link → importUrl/canonicalUrl (copy); missing body → link extract→html;
75
+ // image URLs → featureImage with resolve:'file'
76
+
77
+ // Sync preview skips resolve edges:
78
+ const preview = applyMapping(itemSources, mappings, postTargets)
79
+
80
+ // Publish path — host owns HTTP / extract / store:
81
+ const { properties, errors } = await applyMappingAsync(
82
+ itemSources,
83
+ mappings,
84
+ postTargets,
85
+ {
86
+ resolve: async ({ job, url, contentType, rawValue }) => {
87
+ if (job === 'extract') return await hostExtractHtml(url!)
88
+ if (job === 'lookup') return await hostLookupIdentity(rawValue!)
89
+ return await hostFetchAndStoreFile(url!, contentType)
90
+ },
91
+ },
92
+ )
93
+ ```
94
+
95
+ ### Relation lookup (`resolve: 'lookup'`)
96
+
97
+ Map a string source (e.g. RSS `author`) onto a Relation or List-of-Relation
98
+ target (e.g. `authors` → Identity) via a persisted dictionary and/or host callback:
99
+
100
+ ```ts
101
+ const postTargets: TargetProperty[] = [
102
+ {
103
+ name: 'authors',
104
+ dataType: 'List',
105
+ refValueType: 'Relation',
106
+ ref: 'Identity',
107
+ },
108
+ ]
109
+
110
+ const mappings = [
111
+ { sourceId: 'rss-author', propertyName: 'authors', resolve: 'lookup' as const },
112
+ ]
113
+
114
+ const doc: MappingDocument = {
115
+ version: 1,
116
+ sourceKind: 'rss',
117
+ mappings,
118
+ lookups: {
119
+ authors: { 'Jane Doe': 'identity-seed-uid' },
120
+ },
121
+ }
122
+
123
+ const { properties, errors } = await applyMappingAsync(
124
+ itemSources,
125
+ mappings,
126
+ postTargets,
127
+ {
128
+ lookups: doc.lookups,
129
+ // Optional: called only when the table has no entry for the trimmed source value
130
+ resolve: async ({ job, rawValue }) => {
131
+ if (job === 'lookup') return await findOrCreateIdentity(rawValue!)
132
+ throw new Error(`unexpected job ${job}`)
133
+ },
134
+ },
135
+ )
136
+ // properties.authors === ['identity-seed-uid']
53
137
  ```
54
138
 
139
+ `autoMap` never wires a plain string onto Relation / List-of-Relation targets —
140
+ author those edges in FieldMapper or programmatically.
141
+
142
+ `classifyUrl({ url, contentType? })` is a pure MIME/extension classifier
143
+ (`html` | `image` | `audio` | `video` | `unknown`). Enclosure nodes expose
144
+ `meta.url`, `meta.contentType`, and `meta.class` (not a stringified object).
145
+
55
146
  ## FieldMapper UI
56
147
 
57
- Props-driven only — no Seed hooks or routing. The host app supplies sources/targets and handles create/navigate.
148
+ Props-driven only — no Seed hooks or routing. Import from `@seedprotocol/mapping/react`.
149
+
150
+ Two layouts share the same persisted `FieldMapping[]`. **`layout` defaults to `"rows"`.**
151
+
152
+ | `layout` | Behavior |
153
+ |----------|----------|
154
+ | `"rows"` (default) | Row-based authoring. Pass **origin** sources only — transforms are chosen per row (no `@extract`/`@file` cards). |
155
+ | `"wires"` (**deprecated**) | Two-pane click-to-connect with SVG connectors. Pass `buildResolvedSourceNodes(sources)` so extract/file candidates appear as source cards. Still supported for one minor. |
156
+
157
+ When `layout="rows"`, `rowKey` picks orientation:
158
+
159
+ | `rowKey` | Behavior |
160
+ |----------|----------|
161
+ | `"property"` (default) | One row per target property; source + transform inside the row. Structurally property-exclusive. |
162
+ | `"source"` | One row per edge (insertion order); conflict banner when two rows claim one property; coverage banner for missing `required` targets. |
163
+
164
+ Mark targets with `required: true` so coverage / default filters surface missing fields. Default visible set for property mode is mapped + required (`defaultRows="requiredAndMapped"`).
58
165
 
59
166
  ```tsx
60
167
  import { useState } from 'react'
61
168
  import {
62
- FieldMapper,
169
+ buildResolvedSourceNodes,
63
170
  markdownToSources,
64
- applyMapping,
171
+ rssItemToSources,
172
+ applyMappingAsync,
65
173
  type FieldMapping,
174
+ type MappingLookups,
66
175
  } from '@seedprotocol/mapping'
176
+ import { FieldMapper, useFieldMapper } from '@seedprotocol/mapping/react'
67
177
 
68
- function ImportMap({ markdown, targets, onSubmit }) {
69
- const sources = markdownToSources(markdown)
70
- const [mappings, setMappings] = useState<FieldMapping[]>([])
71
-
72
- return (
73
- <>
74
- <FieldMapper
75
- sources={sources}
76
- targets={targets}
77
- mappings={mappings}
78
- onChange={setMappings}
79
- />
80
- <button
81
- onClick={() => onSubmit(applyMapping(sources, mappings, targets))}
82
- >
83
- Create
84
- </button>
85
- </>
86
- )
87
- }
178
+ // Rows — property-keyed (default layout; recommended)
179
+ <FieldMapper
180
+ rowKey="property"
181
+ sources={rssItemToSources(item)} // origin sources; no buildResolvedSourceNodes
182
+ targets={postTargets} // e.g. { name: 'html', dataType: 'Html', required: true }
183
+ mappings={mappings}
184
+ onChange={setMappings}
185
+ lookups={lookups}
186
+ onLookupsChange={setLookups}
187
+ renderRowAccessory={(row) =>
188
+ row.mapping?.resolve === 'extract' || row.mapping?.resolve === 'file'
189
+ ? <button type="button">Preview</button>
190
+ : null
191
+ }
192
+ />
193
+
194
+ // Rows — source-keyed
195
+ <FieldMapper rowKey="source" sources={itemSources} targets={targets} mappings={mappings} onChange={setMappings} />
196
+
197
+ // Wires (deprecated — opt in explicitly)
198
+ <FieldMapper
199
+ layout="wires"
200
+ sources={buildResolvedSourceNodes(markdownToSources(markdown))}
201
+ targets={targets}
202
+ mappings={mappings}
203
+ onChange={setMappings}
204
+ theme="none"
205
+ />
88
206
  ```
89
207
 
208
+ Headless mechanics (same package):
209
+
210
+ ```tsx
211
+ const mapper = useFieldMapper({
212
+ sources,
213
+ targets,
214
+ mappings,
215
+ onChange: setMappings,
216
+ rowKey: 'property',
217
+ })
218
+ // mapper.rows, mapper.coverage, mapper.setSource, mapper.setTransform, …
219
+ ```
220
+
221
+ Connecting a source to a Relation / List-of-Relation target sets `resolve: 'lookup'`
222
+ and (when `onLookupsChange` is provided) shows a string → seed uid editor — per-row
223
+ when `layout="rows"` (default `slots.lookups: 'row'`), or as a section when
224
+ `layout="wires"` / `slots.lookups: 'section'`.
225
+
226
+ Row and JSON previews match sync `applyMapping` output (pending resolve edges listed
227
+ under `_pendingResolve`; JSON sits behind a disclosure).
228
+
229
+ **Theming**
230
+
231
+ | Prop | Behavior |
232
+ |------|----------|
233
+ | `theme="default"` (default) | Injects structural + paint CSS once into `document.head` (`@layer seed-field-mapper`) with `--sfm-*` tokens (`--fm-*` aliases kept for one minor) |
234
+ | `theme="structural"` | Layout / spacing only — no color paint; inherits host colors |
235
+ | `theme="none"` | No injection — structural classes only (`fm-card`, `fm-row`, `fm-grid`, …); keeps `seed-field-mapper--unstyled` |
236
+ | `theme="unstyled"` | **Deprecated** shim for `none` |
237
+ | `classNames` | Per-slot host classes merged with package classes (`root`, `toolbar`, `row`, `rowAccessory`, …) |
238
+ | `components` | Optional host `Select` / `Button` / `Pill` (defaults are native controls) |
239
+ | `slots` | Toggle chrome: `autoMap`, `filter`, `inspector`, `preview` (`'row' \| 'json' \| 'both' \| false`), `lookups` (`'row' \| 'section' \| false`; rows layout defaults to `'row'`, wires to `'section'`) |
240
+ | `renderRowAccessory` | Optional `(row: FieldMapperRow) => ReactNode` for host chrome (e.g. extract/file **Preview**) in `.fm-row-accessory`. Unrelated to `slots.preview`. Package does not fetch. |
241
+ | `showPreview` | **Deprecated** — prefer `slots.preview` |
242
+ | `connectionColors` | **Deprecated** optional stroke palette for wires; prefer `--sfm-map-*` / `--fm-map-*` / `--map-*` |
243
+ | `layout="wires"` | **Deprecated** — prefer `layout="rows"` (now the default) |
244
+
245
+ `SourceNode` may include optional `subtitle` (display-only). Prefer `subtitle` over stuffing a secondary fact into `label` (e.g. origin field name on a resolved well).
246
+
247
+ **DOM hooks for host CSS**
248
+
249
+ - Wires: mapped wells expose `data-mapping-index` / `data-pair={index % 8}` (kept for host CSS); pending `.active` only on the selected source.
250
+ - Rows: `data-state="empty|mapped|needsResolve|conflict"`, `data-property-name`, `data-resolve`, `data-required`, `data-source-kind`.
251
+
252
+ Sync `applyMapping` preview lists pending resolve edges under `_pendingResolve`.
253
+
254
+ See [FIELD_MAPPER_REDESIGN.md](../../docs/FIELD_MAPPER_REDESIGN.md) for the row-layout design study (Phases 1–5 shipped). PermaPress: [FIELD_MAPPER_PERMAPRESS_HANDOFF.md](../../docs/FIELD_MAPPER_PERMAPRESS_HANDOFF.md).
255
+
90
256
  ## Relationship to `FeedFieldManifest`
91
257
 
92
258
  | Type | Package | Meaning |
93
259
  |------|---------|---------|
94
- | `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** |
95
- | `FeedFieldManifest` | `@seedprotocol/sdk` | Property/key → **role** (`image` / `html` / `text`) for `normalizeFeedItemFields` |
260
+ | `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** (1→N edges; optional `resolve`; optional `lookups`) |
261
+ | `FeedFieldManifest` | `@seedprotocol/sdk` | Property/key → **role** (`image` / `audio` / `video` / `file` / `html` / `text`) for display |
96
262
 
97
- Compose them: map external fields into a plain item, then optionally normalize roles for media/HTML display.
263
+ Compose them: map + resolve into a plain item, then optionally normalize roles for media/HTML display. Storage stays `Image` / `File` schema types — no separate Audio/Video dataTypes.
98
264
 
99
- ## Phase 1 limits
265
+ ## Limits
100
266
 
101
267
  - Markdown: flat YAML frontmatter; `#` / `##` sections only
102
- - RSS: top-level item fields via `parseRssString` (no general XPath)
103
- - UI: self-contained dark theme; no desktop/Tailwind coupling
268
+ - RSS: top-level item fields via `parseRssString` (no general XPath); structured enclosure / media:content
269
+ - UI: self-contained dark theme (or `theme="none"` / `"structural"` for host paint); `layout` defaults to `rows` (`wires` deprecated); no desktop/Tailwind coupling; no media preview player
104
270
 
105
- See [MAPPING_PHASE2.md](../../docs/MAPPING_PHASE2.md) for consumer migration and hardening.
271
+ See [MAPPING_PHASE2.md](../../docs/MAPPING_PHASE2.md) for remaining consumer work (desktop migration, npm publish), [FIELD_MAPPER_REDESIGN.md](../../docs/FIELD_MAPPER_REDESIGN.md) for the row-layout study, and [FIELD_MAPPER_PERMAPRESS_HANDOFF.md](../../docs/FIELD_MAPPER_PERMAPRESS_HANDOFF.md) for PermaPress.
@@ -8,7 +8,8 @@ export type ParsedRssChannel = {
8
8
  };
9
9
  /**
10
10
  * Flatten a parsed RSS/Atom item into SourceNodes (one per string-coercible key).
11
- * Stable ids: `rss-{key}`.
11
+ * Enclosure / media:content become url + type in `meta` (not stringified objects).
12
+ * Stable ids: `rss-{key}`, `rss-enclosure-0`, …
12
13
  */
13
14
  export declare function rssItemToSources(item: Record<string, unknown>): SourceNode[];
14
15
  export type RssXmlSourcesResult = {
@@ -1 +1 @@
1
- {"version":3,"file":"rss.d.ts","sourceRoot":"","sources":["../../src/adapters/rss.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CACjC,CAAA;AAiED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,EAAE,CAoB5E;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,0DAA0D;IAC1D,KAAK,EAAE,UAAU,EAAE,EAAE,CAAA;CACtB,CAAA;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,CAAC,CAU9B"}
1
+ {"version":3,"file":"rss.d.ts","sourceRoot":"","sources":["../../src/adapters/rss.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,kEAAkE;IAClE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAA;CACjC,CAAA;AA8JD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,EAAE,CAoD5E;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,WAAW,CAAC,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,0DAA0D;IAC1D,KAAK,EAAE,UAAU,EAAE,EAAE,CAAA;CACtB,CAAA;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,CAAC,CAU9B"}
@@ -1,4 +1,4 @@
1
- import type { FieldMapping, PropertyBag, SourceNode, TargetProperty } from './types';
1
+ import type { ApplyMappingAsyncResult, FieldMapping, MappingLookups, PropertyBag, ResolveCallback, SourceNode, TargetProperty } from './types';
2
2
  /**
3
3
  * Coerce a raw string value to the Seed model property dataType.
4
4
  */
@@ -6,6 +6,19 @@ export declare function coerceValue(rawValue: string, dataType: string): unknown
6
6
  /**
7
7
  * Apply field mappings to produce a property bag for createItem / publish.
8
8
  * Missing sources or unknown target properties are skipped (no throw).
9
+ * Mappings with `resolve` are skipped — use `applyMappingAsync` with a host callback.
9
10
  */
10
11
  export declare function applyMapping(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[]): PropertyBag;
12
+ export type ApplyMappingAsyncOptions = {
13
+ /** Required for extract/file edges and lookup misses. */
14
+ resolve?: ResolveCallback;
15
+ /** String → seed uid dictionaries keyed by property name. */
16
+ lookups?: MappingLookups;
17
+ };
18
+ /**
19
+ * Async apply: copy+coerce plain edges; for `resolve` edges call the host
20
+ * callback (or apply lookups for `lookup`) then coerce. Partial success —
21
+ * failed resolve edges are listed in `errors` and omitted from `properties`.
22
+ */
23
+ export declare function applyMappingAsync(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[], options?: ApplyMappingAsyncOptions): Promise<ApplyMappingAsyncResult>;
11
24
  //# sourceMappingURL=applyMapping.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"applyMapping.d.ts","sourceRoot":"","sources":["../src/applyMapping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACf,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuBvE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,cAAc,EAAE,GACxB,WAAW,CAeb"}
1
+ {"version":3,"file":"applyMapping.d.ts","sourceRoot":"","sources":["../src/applyMapping.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,uBAAuB,EACvB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,eAAe,EAEf,UAAU,EACV,cAAc,EAEf,MAAM,SAAS,CAAA;AAEhB;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuBvE;AA8DD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,cAAc,EAAE,GACxB,WAAW,CAmBb;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,yDAAyD;IACzD,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB,CAAA;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CAwIlC"}