@seedprotocol/mapping 0.5.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +213 -36
- package/dist/adapters/rss.d.ts +2 -1
- package/dist/adapters/rss.d.ts.map +1 -1
- package/dist/applyMapping.d.ts +21 -2
- package/dist/applyMapping.d.ts.map +1 -1
- package/dist/autoMap-OMvtOG0S.js +549 -0
- package/dist/autoMap-OMvtOG0S.js.map +1 -0
- package/dist/autoMap-PTFd4l-9.js +534 -0
- package/dist/autoMap-PTFd4l-9.js.map +1 -0
- package/dist/autoMap.d.ts +3 -3
- package/dist/autoMap.d.ts.map +1 -1
- package/dist/classifyUrl.d.ts +14 -0
- package/dist/classifyUrl.d.ts.map +1 -0
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -402
- package/dist/index.js.map +1 -1
- package/dist/react/FieldMapper.d.ts +77 -5
- package/dist/react/FieldMapper.d.ts.map +1 -1
- package/dist/react/FieldMapperWires.d.ts +20 -0
- package/dist/react/FieldMapperWires.d.ts.map +1 -0
- package/dist/react/LookupEditor.d.ts +20 -0
- package/dist/react/LookupEditor.d.ts.map +1 -0
- package/dist/react/PropertyRows.d.ts +20 -0
- package/dist/react/PropertyRows.d.ts.map +1 -0
- package/dist/react/SourceRows.d.ts +19 -0
- package/dist/react/SourceRows.d.ts.map +1 -0
- package/dist/react/fieldMapperControls.d.ts +9 -0
- package/dist/react/fieldMapperControls.d.ts.map +1 -0
- package/dist/react/fieldMapperCore.d.ts +83 -0
- package/dist/react/fieldMapperCore.d.ts.map +1 -0
- package/dist/react/fieldMapperSlots.d.ts +69 -0
- package/dist/react/fieldMapperSlots.d.ts.map +1 -0
- package/dist/react/fieldMapperTheme.d.ts +34 -0
- package/dist/react/fieldMapperTheme.d.ts.map +1 -0
- package/dist/react/fieldMapperTypes.d.ts +77 -0
- package/dist/react/fieldMapperTypes.d.ts.map +1 -0
- package/dist/react/useFieldMapper.d.ts +8 -0
- package/dist/react/useFieldMapper.d.ts.map +1 -0
- package/dist/react.d.ts +10 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +1690 -0
- package/dist/react.js.map +1 -0
- package/dist/relationLookup.d.ts +34 -0
- package/dist/relationLookup.d.ts.map +1 -0
- package/dist/resolvedSources.d.ts +32 -0
- package/dist/resolvedSources.d.ts.map +1 -0
- package/dist/types.d.ts +74 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +19 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
- Relation lookup is an edge-local stored intent: `FieldMapping.lookup.entries` as `{ value, ref }[]`. `ref` is opaque (`seedLocalId` or `seedUid`). Empty entries are a valid unassigned map.
|
|
6
|
+
- `applyMapping` (sync) applies lookup entries and emits refs. Unmatched values are omitted. `applyMappingAsync` reports unmatched on `errors[]` and no longer calls the host `resolve` callback for lookup.
|
|
7
|
+
- `autoMap` pairs alias matches such as `author` → List-of-Relation `authors` with `resolve: 'lookup'` and no invented refs.
|
|
8
|
+
- `FieldMapper` `renderLookup?: (row: FieldMapperLookupRow) => ReactNode` — host picker on lookup rows (same split as `renderRowAccessory`). Package uid editor is a fallback only.
|
|
9
|
+
- `useFieldMapper.setLookupEntries`. Row `sampleValue` and `data-state="needsLookup"` when the current sample has no matching entry.
|
|
10
|
+
- `TargetProperty` stays Seed-accurate (`List` + `refValueType: 'Relation'` + `ref`). No `multiple` flag.
|
|
11
|
+
- `MappingDocument.lookups` / `lookups` + `onLookupsChange` are deprecated read/write fallbacks for 0.6.0 documents.
|
|
12
|
+
- `_pendingResolve` is extract/file only; lookup hits appear in the preview bag.
|
|
13
|
+
|
|
14
|
+
## 0.6.1
|
|
15
|
+
|
|
16
|
+
- `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'`).
|
|
17
|
+
- 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`.
|
|
18
|
+
|
|
19
|
+
## 0.6.0
|
|
20
|
+
|
|
21
|
+
- `FieldMapper` Phase 5: `layout` defaults to `'rows'`; `'wires'` is deprecated but still supported.
|
|
22
|
+
- `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'`.
|
|
23
|
+
- Shared `LookupEditor` + `buildSyncPreviewBag` / upgraded `previewForEdge` (lookup table hits, coerced copy values).
|
|
24
|
+
- `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`.
|
|
25
|
+
- Deprecated (still work): `layout="wires"`, `theme="unstyled"`, `showPreview`, `connectionColors` — prefer `layout="rows"`, `theme="none"`, `slots.preview`, and CSS map tokens.
|
|
26
|
+
- `FieldMapper` row layout (Phase 1–2 of the redesign): `layout="rows" | "wires"`, `rowKey="property" | "source"`, `defaultRows`, optional `TargetProperty.required` for coverage.
|
|
27
|
+
- Headless `useFieldMapper` hook + shared core (`setSource` / `setTransform` / coverage / conflicts); wires UI refactored to consume the hook.
|
|
28
|
+
- 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.
|
|
29
|
+
- **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`.
|
|
30
|
+
- **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`).
|
|
31
|
+
- `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.
|
|
32
|
+
- `TargetProperty.ref` / `refValueType`; `isRelationLookupTarget` helper; `autoMap` never plain-copies onto lookup-capable targets (author → authors no longer writes a string into a relation list).
|
|
33
|
+
- `FieldMapper`: connecting to a lookup-capable target sets `resolve: 'lookup'`; optional `lookups` / `onLookupsChange` panel edits string → uid maps (comma-separated for multi).
|
|
34
|
+
- `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.
|
|
35
|
+
- `FieldMapping.resolve?: 'extract' | 'file' | 'lookup'`; sync `applyMapping` skips resolve edges; new `applyMappingAsync` with host callback.
|
|
36
|
+
- `classifyUrl`, `buildResolvedSourceNodes`, `normalizeMappingFromSourceId` for package-owned extract/file candidates.
|
|
37
|
+
- RSS adapter exposes enclosure / media:content as `url` + `contentType` in `meta` (stable `rss-enclosure-N` ids).
|
|
38
|
+
- `autoMap` never maps a raw URL onto html/Image/File without `resolve`; prefers full-text → html, then extract, then file jobs.
|
|
39
|
+
- Allow one source to map to multiple properties (edge-list fan-out); each property remains exclusive.
|
|
40
|
+
- `autoMap` fans `link` / `url` sources out to matching URL-ish targets (`importUrl`, `canonicalUrl`, `url`, `link`, `permalink`).
|
|
41
|
+
- `FieldMapper` supports attaching multiple properties from an active source without clearing prior edges; normalizes `@extract`/`@file` nodes to `resolve` on persist.
|
|
42
|
+
|
|
3
43
|
## 0.5.1
|
|
4
44
|
|
|
5
45
|
- 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.
|
|
9
|
-
3. `
|
|
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 + stored lookup) or `applyMappingAsync` (host extract/file 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. `resolve: 'extract' | 'file'` is applied by the host callback.
|
|
15
|
+
`resolve: 'lookup'` is a stored string → ref table on the edge — 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
|
-
|
|
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,226 @@ const doc: MappingDocument = {
|
|
|
43
57
|
}
|
|
44
58
|
```
|
|
45
59
|
|
|
46
|
-
RSS:
|
|
60
|
+
RSS with resolve jobs:
|
|
47
61
|
|
|
48
62
|
```ts
|
|
49
|
-
const {
|
|
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
|
-
|
|
74
|
+
// link → importUrl/canonicalUrl (copy); missing body → link extract→html;
|
|
75
|
+
// image URLs → featureImage with resolve:'file'
|
|
76
|
+
|
|
77
|
+
// Sync preview applies lookup entries; extract/file stay pending:
|
|
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
|
+
)
|
|
53
93
|
```
|
|
54
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 **stored entries on the edge**. Use Seed
|
|
99
|
+
model vocabulary — not a `multiple` flag:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const postTargets: TargetProperty[] = [
|
|
103
|
+
{
|
|
104
|
+
name: 'authors',
|
|
105
|
+
dataType: 'List',
|
|
106
|
+
refValueType: 'Relation',
|
|
107
|
+
ref: 'Identity',
|
|
108
|
+
},
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
const mappings = [
|
|
112
|
+
{
|
|
113
|
+
sourceId: 'rss-author',
|
|
114
|
+
propertyName: 'authors',
|
|
115
|
+
resolve: 'lookup' as const,
|
|
116
|
+
lookup: {
|
|
117
|
+
entries: [{ value: 'Jane Doe', ref: 'identity-seed-uid' }],
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
const doc: MappingDocument = {
|
|
123
|
+
version: 1,
|
|
124
|
+
sourceKind: 'rss',
|
|
125
|
+
mappings,
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Sync apply emits refs from stored entries (extract/file still skipped):
|
|
129
|
+
const bag = applyMapping(itemSources, mappings, postTargets)
|
|
130
|
+
// bag.authors === ['identity-seed-uid']
|
|
131
|
+
|
|
132
|
+
const { properties, errors } = await applyMappingAsync(
|
|
133
|
+
itemSources,
|
|
134
|
+
mappings,
|
|
135
|
+
postTargets,
|
|
136
|
+
)
|
|
137
|
+
// Unmatched values are omitted from the bag and listed in errors[].
|
|
138
|
+
// Do not fetch identities inside apply — persist the assignment, then apply.
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`autoMap` pairs alias matches such as `author` → `authors` with
|
|
142
|
+
`resolve: 'lookup'` and **empty** entries. It never invents refs.
|
|
143
|
+
|
|
144
|
+
`MappingDocument.lookups` / `applyMappingAsync({ lookups })` remain a read-only
|
|
145
|
+
fallback for 0.6.0 documents. Prefer `FieldMapping.lookup.entries`.
|
|
146
|
+
|
|
147
|
+
`classifyUrl({ url, contentType? })` is a pure MIME/extension classifier
|
|
148
|
+
(`html` | `image` | `audio` | `video` | `unknown`). Enclosure nodes expose
|
|
149
|
+
`meta.url`, `meta.contentType`, and `meta.class` (not a stringified object).
|
|
150
|
+
|
|
55
151
|
## FieldMapper UI
|
|
56
152
|
|
|
57
|
-
Props-driven only — no Seed hooks or routing.
|
|
153
|
+
Props-driven only — no Seed hooks or routing. Import from `@seedprotocol/mapping/react`.
|
|
154
|
+
|
|
155
|
+
Two layouts share the same persisted `FieldMapping[]`. **`layout` defaults to `"rows"`.**
|
|
156
|
+
|
|
157
|
+
| `layout` | Behavior |
|
|
158
|
+
|----------|----------|
|
|
159
|
+
| `"rows"` (default) | Row-based authoring. Pass **origin** sources only — transforms are chosen per row (no `@extract`/`@file` cards). |
|
|
160
|
+
| `"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. |
|
|
161
|
+
|
|
162
|
+
When `layout="rows"`, `rowKey` picks orientation:
|
|
163
|
+
|
|
164
|
+
| `rowKey` | Behavior |
|
|
165
|
+
|----------|----------|
|
|
166
|
+
| `"property"` (default) | One row per target property; source + transform inside the row. Structurally property-exclusive. |
|
|
167
|
+
| `"source"` | One row per edge (insertion order); conflict banner when two rows claim one property; coverage banner for missing `required` targets. |
|
|
168
|
+
|
|
169
|
+
Mark targets with `required: true` so coverage / default filters surface missing fields. Default visible set for property mode is mapped + required (`defaultRows="requiredAndMapped"`).
|
|
58
170
|
|
|
59
171
|
```tsx
|
|
60
172
|
import { useState } from 'react'
|
|
61
173
|
import {
|
|
62
|
-
|
|
174
|
+
buildResolvedSourceNodes,
|
|
63
175
|
markdownToSources,
|
|
64
|
-
|
|
176
|
+
rssItemToSources,
|
|
177
|
+
applyMappingAsync,
|
|
65
178
|
type FieldMapping,
|
|
66
179
|
} from '@seedprotocol/mapping'
|
|
180
|
+
import { FieldMapper, useFieldMapper } from '@seedprotocol/mapping/react'
|
|
67
181
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
182
|
+
// Rows — property-keyed (default layout; recommended)
|
|
183
|
+
<FieldMapper
|
|
184
|
+
rowKey="property"
|
|
185
|
+
sources={rssItemToSources(item)} // origin sources; no buildResolvedSourceNodes
|
|
186
|
+
targets={postTargets} // e.g. { name: 'html', dataType: 'Html', required: true }
|
|
187
|
+
mappings={mappings}
|
|
188
|
+
onChange={setMappings}
|
|
189
|
+
slots={{ lookups: 'row', preview: 'row' }}
|
|
190
|
+
renderRowAccessory={(row) =>
|
|
191
|
+
row.mapping?.resolve === 'extract' || row.mapping?.resolve === 'file'
|
|
192
|
+
? <button type="button">Preview</button>
|
|
193
|
+
: null
|
|
194
|
+
}
|
|
195
|
+
renderLookup={(row) => (
|
|
196
|
+
<IdentityLookup
|
|
197
|
+
sampleValue={row.sampleValue}
|
|
198
|
+
entries={row.mapping?.lookup?.entries ?? []}
|
|
199
|
+
onChange={row.onLookupChange}
|
|
200
|
+
/>
|
|
201
|
+
)}
|
|
202
|
+
/>
|
|
203
|
+
|
|
204
|
+
// Rows — source-keyed
|
|
205
|
+
<FieldMapper rowKey="source" sources={itemSources} targets={targets} mappings={mappings} onChange={setMappings} />
|
|
206
|
+
|
|
207
|
+
// Wires (deprecated — opt in explicitly)
|
|
208
|
+
<FieldMapper
|
|
209
|
+
layout="wires"
|
|
210
|
+
sources={buildResolvedSourceNodes(markdownToSources(markdown))}
|
|
211
|
+
targets={targets}
|
|
212
|
+
mappings={mappings}
|
|
213
|
+
onChange={setMappings}
|
|
214
|
+
theme="none"
|
|
215
|
+
/>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Headless mechanics (same package):
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
const mapper = useFieldMapper({
|
|
222
|
+
sources,
|
|
223
|
+
targets,
|
|
224
|
+
mappings,
|
|
225
|
+
onChange: setMappings,
|
|
226
|
+
rowKey: 'property',
|
|
227
|
+
})
|
|
228
|
+
// mapper.rows, mapper.coverage, mapper.setSource, mapper.setTransform, …
|
|
88
229
|
```
|
|
89
230
|
|
|
231
|
+
Connecting a source to a Relation / List-of-Relation target sets `resolve: 'lookup'`.
|
|
232
|
+
Pass `renderLookup` to paint the host picker (Identity, etc.) on that row. Without
|
|
233
|
+
`renderLookup`, `onLookupsChange` still enables the package uid-text fallback.
|
|
234
|
+
`lookups` / `onLookupsChange` are deprecated — persist `lookup.entries` on the edge.
|
|
235
|
+
|
|
236
|
+
Row and JSON previews match sync `applyMapping` output. Lookup hits appear in the
|
|
237
|
+
bag; only extract/file stay under `_pendingResolve`. JSON sits behind a disclosure.
|
|
238
|
+
|
|
239
|
+
**Theming**
|
|
240
|
+
|
|
241
|
+
| Prop | Behavior |
|
|
242
|
+
|------|----------|
|
|
243
|
+
| `theme="default"` (default) | Injects structural + paint CSS once into `document.head` (`@layer seed-field-mapper`) with `--sfm-*` tokens (`--fm-*` aliases kept for one minor) |
|
|
244
|
+
| `theme="structural"` | Layout / spacing only — no color paint; inherits host colors |
|
|
245
|
+
| `theme="none"` | No injection — structural classes only (`fm-card`, `fm-row`, `fm-grid`, …); keeps `seed-field-mapper--unstyled` |
|
|
246
|
+
| `theme="unstyled"` | **Deprecated** shim for `none` |
|
|
247
|
+
| `classNames` | Per-slot host classes merged with package classes (`root`, `toolbar`, `row`, `rowAccessory`, …) |
|
|
248
|
+
| `components` | Optional host `Select` / `Button` / `Pill` (defaults are native controls) |
|
|
249
|
+
| `slots` | Toggle chrome: `autoMap`, `filter`, `inspector`, `preview` (`'row' \| 'json' \| 'both' \| false`), `lookups` (`'row' \| 'section' \| false`; rows layout defaults to `'row'`, wires to `'section'`) |
|
|
250
|
+
| `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. |
|
|
251
|
+
| `renderLookup` | Optional `(row: FieldMapperLookupRow) => ReactNode` for host lookup chrome on `resolve: 'lookup'` rows. Package does not fetch or list identities. |
|
|
252
|
+
| `showPreview` | **Deprecated** — prefer `slots.preview` |
|
|
253
|
+
| `connectionColors` | **Deprecated** optional stroke palette for wires; prefer `--sfm-map-*` / `--fm-map-*` / `--map-*` |
|
|
254
|
+
| `layout="wires"` | **Deprecated** — prefer `layout="rows"` (now the default) |
|
|
255
|
+
|
|
256
|
+
`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).
|
|
257
|
+
|
|
258
|
+
**DOM hooks for host CSS**
|
|
259
|
+
|
|
260
|
+
- Wires: mapped wells expose `data-mapping-index` / `data-pair={index % 8}` (kept for host CSS); pending `.active` only on the selected source.
|
|
261
|
+
- Rows: `data-state="empty|mapped|needsResolve|needsLookup|conflict"`, `data-property-name`, `data-resolve`, `data-required`, `data-source-kind`.
|
|
262
|
+
|
|
263
|
+
Sync `applyMapping` preview lists pending **extract/file** edges under `_pendingResolve`. Lookup refs from stored entries appear in the bag.
|
|
264
|
+
|
|
265
|
+
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).
|
|
266
|
+
|
|
90
267
|
## Relationship to `FeedFieldManifest`
|
|
91
268
|
|
|
92
269
|
| Type | Package | Meaning |
|
|
93
270
|
|------|---------|---------|
|
|
94
|
-
| `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** |
|
|
95
|
-
| `FeedFieldManifest` | `@seedprotocol/sdk` | Property/key → **role** (`image` / `html` / `text`) for
|
|
271
|
+
| `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** (1→N edges; optional `resolve`; optional `lookup.entries`) |
|
|
272
|
+
| `FeedFieldManifest` | `@seedprotocol/sdk` | Property/key → **role** (`image` / `audio` / `video` / `file` / `html` / `text`) for display |
|
|
96
273
|
|
|
97
|
-
Compose them: map
|
|
274
|
+
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
275
|
|
|
99
|
-
##
|
|
276
|
+
## Limits
|
|
100
277
|
|
|
101
278
|
- 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
|
|
279
|
+
- RSS: top-level item fields via `parseRssString` (no general XPath); structured enclosure / media:content
|
|
280
|
+
- 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
281
|
|
|
105
|
-
See [MAPPING_PHASE2.md](../../docs/MAPPING_PHASE2.md) for consumer migration and
|
|
282
|
+
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.
|
package/dist/adapters/rss.d.ts
CHANGED
|
@@ -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
|
-
*
|
|
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":"
|
|
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"}
|
package/dist/applyMapping.d.ts
CHANGED
|
@@ -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,25 @@ 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
|
+
* `resolve: 'extract' | 'file'` edges are skipped — use `applyMappingAsync`.
|
|
10
|
+
* `resolve: 'lookup'` is applied from stored entries (or deprecated document lookups).
|
|
9
11
|
*/
|
|
10
|
-
export declare function applyMapping(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[]
|
|
12
|
+
export declare function applyMapping(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[], options?: {
|
|
13
|
+
lookups?: MappingLookups;
|
|
14
|
+
}): PropertyBag;
|
|
15
|
+
export type ApplyMappingAsyncOptions = {
|
|
16
|
+
/** Required for extract/file edges. Not called for lookup. */
|
|
17
|
+
resolve?: ResolveCallback;
|
|
18
|
+
/**
|
|
19
|
+
* String → seed uid dictionaries keyed by property name.
|
|
20
|
+
* @deprecated Prefer `FieldMapping.lookup.entries`. Read as a fallback only.
|
|
21
|
+
*/
|
|
22
|
+
lookups?: MappingLookups;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Async apply: copy+coerce plain edges; apply lookup entries; for extract/file
|
|
26
|
+
* call the host callback then coerce. Partial success — failed resolve edges
|
|
27
|
+
* are listed in `errors` and omitted from `properties`.
|
|
28
|
+
*/
|
|
29
|
+
export declare function applyMappingAsync(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[], options?: ApplyMappingAsyncOptions): Promise<ApplyMappingAsyncResult>;
|
|
11
30
|
//# sourceMappingURL=applyMapping.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applyMapping.d.ts","sourceRoot":"","sources":["../src/applyMapping.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"applyMapping.d.ts","sourceRoot":"","sources":["../src/applyMapping.ts"],"names":[],"mappings":"AAOA,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;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,UAAU,EAAE,EACrB,QAAQ,EAAE,YAAY,EAAE,EACxB,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,cAAc,CAAA;CAAE,GACrC,WAAW,CA4Bb;AAED,MAAM,MAAM,wBAAwB,GAAG;IACrC,8DAA8D;IAC9D,OAAO,CAAC,EAAE,eAAe,CAAA;IACzB;;;OAGG;IACH,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,CAwFlC"}
|