@seedprotocol/mapping 0.6.0 → 0.6.2
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 +11 -0
- package/README.md +43 -32
- package/dist/applyMapping.d.ts +13 -7
- 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.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -47
- package/dist/react/FieldMapper.d.ts +14 -2
- package/dist/react/FieldMapper.d.ts.map +1 -1
- package/dist/react/FieldMapperWires.d.ts +3 -2
- package/dist/react/FieldMapperWires.d.ts.map +1 -1
- package/dist/react/LookupEditor.d.ts +5 -9
- package/dist/react/LookupEditor.d.ts.map +1 -1
- package/dist/react/PropertyRows.d.ts +3 -2
- package/dist/react/PropertyRows.d.ts.map +1 -1
- package/dist/react/SourceRows.d.ts +3 -2
- package/dist/react/SourceRows.d.ts.map +1 -1
- package/dist/react/fieldMapperCore.d.ts +6 -2
- package/dist/react/fieldMapperCore.d.ts.map +1 -1
- package/dist/react/fieldMapperTypes.d.ts +16 -2
- package/dist/react/fieldMapperTypes.d.ts.map +1 -1
- package/dist/react/useFieldMapper.d.ts.map +1 -1
- package/dist/react.d.ts +1 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +719 -646
- package/dist/react.js.map +1 -1
- package/dist/relationLookup.d.ts +21 -1
- package/dist/relationLookup.d.ts.map +1 -1
- package/dist/types.d.ts +19 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
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
|
+
|
|
3
14
|
## 0.6.1
|
|
4
15
|
|
|
5
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'`).
|
package/README.md
CHANGED
|
@@ -7,12 +7,12 @@ Use this package to:
|
|
|
7
7
|
1. Parse markdown or RSS/Atom into `SourceNode[]`
|
|
8
8
|
2. Optionally expand URL sources with `buildResolvedSourceNodes` (extract / file candidates)
|
|
9
9
|
3. Author `FieldMapping` edges (manually, via `autoMap`, or via `FieldMapper`)
|
|
10
|
-
4. `applyMapping` (sync copy) or `applyMappingAsync` (host
|
|
10
|
+
4. `applyMapping` (sync copy + stored lookup) or `applyMappingAsync` (host extract/file callback) → property bag
|
|
11
11
|
|
|
12
12
|
Mappings are an edge list: one source may fan out to multiple properties (e.g. RSS
|
|
13
13
|
`link` → `importUrl` and `canonicalUrl`). Each property is exclusive — at most one
|
|
14
|
-
source may map to it.
|
|
15
|
-
|
|
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
16
|
fetches, runs Readability, or loads Seed Identity items.
|
|
17
17
|
|
|
18
18
|
## Install
|
|
@@ -74,7 +74,7 @@ const mappings = autoMap(itemSources, postTargets)
|
|
|
74
74
|
// link → importUrl/canonicalUrl (copy); missing body → link extract→html;
|
|
75
75
|
// image URLs → featureImage with resolve:'file'
|
|
76
76
|
|
|
77
|
-
// Sync preview
|
|
77
|
+
// Sync preview applies lookup entries; extract/file stay pending:
|
|
78
78
|
const preview = applyMapping(itemSources, mappings, postTargets)
|
|
79
79
|
|
|
80
80
|
// Publish path — host owns HTTP / extract / store:
|
|
@@ -95,7 +95,8 @@ const { properties, errors } = await applyMappingAsync(
|
|
|
95
95
|
### Relation lookup (`resolve: 'lookup'`)
|
|
96
96
|
|
|
97
97
|
Map a string source (e.g. RSS `author`) onto a Relation or List-of-Relation
|
|
98
|
-
target (e.g. `authors` → Identity) via
|
|
98
|
+
target (e.g. `authors` → Identity) via **stored entries on the edge**. Use Seed
|
|
99
|
+
model vocabulary — not a `multiple` flag:
|
|
99
100
|
|
|
100
101
|
```ts
|
|
101
102
|
const postTargets: TargetProperty[] = [
|
|
@@ -108,36 +109,40 @@ const postTargets: TargetProperty[] = [
|
|
|
108
109
|
]
|
|
109
110
|
|
|
110
111
|
const mappings = [
|
|
111
|
-
{
|
|
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
|
+
},
|
|
112
120
|
]
|
|
113
121
|
|
|
114
122
|
const doc: MappingDocument = {
|
|
115
123
|
version: 1,
|
|
116
124
|
sourceKind: 'rss',
|
|
117
125
|
mappings,
|
|
118
|
-
lookups: {
|
|
119
|
-
authors: { 'Jane Doe': 'identity-seed-uid' },
|
|
120
|
-
},
|
|
121
126
|
}
|
|
122
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
|
+
|
|
123
132
|
const { properties, errors } = await applyMappingAsync(
|
|
124
133
|
itemSources,
|
|
125
134
|
mappings,
|
|
126
135
|
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
|
)
|
|
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.
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
`autoMap`
|
|
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`.
|
|
141
146
|
|
|
142
147
|
`classifyUrl({ url, contentType? })` is a pure MIME/extension classifier
|
|
143
148
|
(`html` | `image` | `audio` | `video` | `unknown`). Enclosure nodes expose
|
|
@@ -171,7 +176,6 @@ import {
|
|
|
171
176
|
rssItemToSources,
|
|
172
177
|
applyMappingAsync,
|
|
173
178
|
type FieldMapping,
|
|
174
|
-
type MappingLookups,
|
|
175
179
|
} from '@seedprotocol/mapping'
|
|
176
180
|
import { FieldMapper, useFieldMapper } from '@seedprotocol/mapping/react'
|
|
177
181
|
|
|
@@ -182,13 +186,19 @@ import { FieldMapper, useFieldMapper } from '@seedprotocol/mapping/react'
|
|
|
182
186
|
targets={postTargets} // e.g. { name: 'html', dataType: 'Html', required: true }
|
|
183
187
|
mappings={mappings}
|
|
184
188
|
onChange={setMappings}
|
|
185
|
-
|
|
186
|
-
onLookupsChange={setLookups}
|
|
189
|
+
slots={{ lookups: 'row', preview: 'row' }}
|
|
187
190
|
renderRowAccessory={(row) =>
|
|
188
191
|
row.mapping?.resolve === 'extract' || row.mapping?.resolve === 'file'
|
|
189
192
|
? <button type="button">Preview</button>
|
|
190
193
|
: null
|
|
191
194
|
}
|
|
195
|
+
renderLookup={(row) => (
|
|
196
|
+
<IdentityLookup
|
|
197
|
+
sampleValue={row.sampleValue}
|
|
198
|
+
entries={row.mapping?.lookup?.entries ?? []}
|
|
199
|
+
onChange={row.onLookupChange}
|
|
200
|
+
/>
|
|
201
|
+
)}
|
|
192
202
|
/>
|
|
193
203
|
|
|
194
204
|
// Rows — source-keyed
|
|
@@ -218,13 +228,13 @@ const mapper = useFieldMapper({
|
|
|
218
228
|
// mapper.rows, mapper.coverage, mapper.setSource, mapper.setTransform, …
|
|
219
229
|
```
|
|
220
230
|
|
|
221
|
-
Connecting a source to a Relation / List-of-Relation target sets `resolve: 'lookup'
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
`
|
|
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.
|
|
225
235
|
|
|
226
|
-
Row and JSON previews match sync `applyMapping` output
|
|
227
|
-
under `_pendingResolve
|
|
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.
|
|
228
238
|
|
|
229
239
|
**Theming**
|
|
230
240
|
|
|
@@ -238,6 +248,7 @@ under `_pendingResolve`; JSON sits behind a disclosure).
|
|
|
238
248
|
| `components` | Optional host `Select` / `Button` / `Pill` (defaults are native controls) |
|
|
239
249
|
| `slots` | Toggle chrome: `autoMap`, `filter`, `inspector`, `preview` (`'row' \| 'json' \| 'both' \| false`), `lookups` (`'row' \| 'section' \| false`; rows layout defaults to `'row'`, wires to `'section'`) |
|
|
240
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. |
|
|
241
252
|
| `showPreview` | **Deprecated** — prefer `slots.preview` |
|
|
242
253
|
| `connectionColors` | **Deprecated** optional stroke palette for wires; prefer `--sfm-map-*` / `--fm-map-*` / `--map-*` |
|
|
243
254
|
| `layout="wires"` | **Deprecated** — prefer `layout="rows"` (now the default) |
|
|
@@ -247,9 +258,9 @@ under `_pendingResolve`; JSON sits behind a disclosure).
|
|
|
247
258
|
**DOM hooks for host CSS**
|
|
248
259
|
|
|
249
260
|
- 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`.
|
|
261
|
+
- Rows: `data-state="empty|mapped|needsResolve|needsLookup|conflict"`, `data-property-name`, `data-resolve`, `data-required`, `data-source-kind`.
|
|
251
262
|
|
|
252
|
-
Sync `applyMapping` preview lists pending
|
|
263
|
+
Sync `applyMapping` preview lists pending **extract/file** edges under `_pendingResolve`. Lookup refs from stored entries appear in the bag.
|
|
253
264
|
|
|
254
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).
|
|
255
266
|
|
|
@@ -257,7 +268,7 @@ See [FIELD_MAPPER_REDESIGN.md](../../docs/FIELD_MAPPER_REDESIGN.md) for the row-
|
|
|
257
268
|
|
|
258
269
|
| Type | Package | Meaning |
|
|
259
270
|
|------|---------|---------|
|
|
260
|
-
| `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** (1→N edges; optional `resolve`; optional `
|
|
271
|
+
| `FieldMapping` / `MappingDocument` | `@seedprotocol/mapping` | Source id → **model property name** (1→N edges; optional `resolve`; optional `lookup.entries`) |
|
|
261
272
|
| `FeedFieldManifest` | `@seedprotocol/sdk` | Property/key → **role** (`image` / `audio` / `video` / `file` / `html` / `text`) for display |
|
|
262
273
|
|
|
263
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.
|
package/dist/applyMapping.d.ts
CHANGED
|
@@ -6,19 +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
|
-
*
|
|
9
|
+
* `resolve: 'extract' | 'file'` edges are skipped — use `applyMappingAsync`.
|
|
10
|
+
* `resolve: 'lookup'` is applied from stored entries (or deprecated document lookups).
|
|
10
11
|
*/
|
|
11
|
-
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;
|
|
12
15
|
export type ApplyMappingAsyncOptions = {
|
|
13
|
-
/** Required for extract/file edges
|
|
16
|
+
/** Required for extract/file edges. Not called for lookup. */
|
|
14
17
|
resolve?: ResolveCallback;
|
|
15
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* String → seed uid dictionaries keyed by property name.
|
|
20
|
+
* @deprecated Prefer `FieldMapping.lookup.entries`. Read as a fallback only.
|
|
21
|
+
*/
|
|
16
22
|
lookups?: MappingLookups;
|
|
17
23
|
};
|
|
18
24
|
/**
|
|
19
|
-
* Async apply: copy+coerce plain edges;
|
|
20
|
-
*
|
|
21
|
-
*
|
|
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`.
|
|
22
28
|
*/
|
|
23
29
|
export declare function applyMappingAsync(sources: SourceNode[], mappings: FieldMapping[], targets: TargetProperty[], options?: ApplyMappingAsyncOptions): Promise<ApplyMappingAsyncResult>;
|
|
24
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"}
|