@workbench-kit/field-remap 0.0.2-prototype.0.2.30 → 0.0.2-prototype.0.2.31
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
|
@@ -16,8 +16,13 @@ import type {
|
|
|
16
16
|
ValueTransformRegistry,
|
|
17
17
|
} from '../types.js';
|
|
18
18
|
import { applyTransformChain } from '../../registry/createValueTransformRegistry.js';
|
|
19
|
-
import {
|
|
20
|
-
|
|
19
|
+
import {
|
|
20
|
+
findSourceField,
|
|
21
|
+
findTargetSlot,
|
|
22
|
+
readSourceFieldValue,
|
|
23
|
+
resolveTargetSlotOutputPath,
|
|
24
|
+
} from './resolveMappedValue.js';
|
|
25
|
+
import { isPlainObject, writeObjectPath } from './pathUtils.js';
|
|
21
26
|
|
|
22
27
|
/** Max inputs on a combine operator. */
|
|
23
28
|
export const MAX_MAPPING_FAN_IN = 8;
|
|
@@ -68,45 +73,6 @@ function leafKey(field: {
|
|
|
68
73
|
return idParts[idParts.length - 1] ?? field.label;
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
function outputPathForTarget(slot: TargetSlot): string {
|
|
72
|
-
const path = slot.path?.trim();
|
|
73
|
-
if (path) {
|
|
74
|
-
return path;
|
|
75
|
-
}
|
|
76
|
-
const id = slot.id.trim();
|
|
77
|
-
if (id.includes('.')) {
|
|
78
|
-
const parts = id.split('.').filter(Boolean);
|
|
79
|
-
if (parts.length >= 2) {
|
|
80
|
-
return parts.slice(1).join('.');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return slot.label.trim() || id;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function readFieldValue(field: SourceField, inputs: Readonly<Record<string, unknown>>): unknown {
|
|
87
|
-
const shapeId = field.shapeId?.trim();
|
|
88
|
-
const bag =
|
|
89
|
-
shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)
|
|
90
|
-
? inputs[shapeId]
|
|
91
|
-
: Object.keys(inputs).length === 1
|
|
92
|
-
? inputs[Object.keys(inputs)[0]!]
|
|
93
|
-
: inputs;
|
|
94
|
-
|
|
95
|
-
const path = field.path?.trim();
|
|
96
|
-
if (path) {
|
|
97
|
-
if (shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)) {
|
|
98
|
-
return readObjectPath(bag, path);
|
|
99
|
-
}
|
|
100
|
-
const fromBag = readObjectPath(bag, path);
|
|
101
|
-
if (fromBag !== undefined) {
|
|
102
|
-
return fromBag;
|
|
103
|
-
}
|
|
104
|
-
return readObjectPath(inputs, path);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return field.sampleValue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
76
|
function sanitizeOperatorTransformIds(ids: readonly string[] | undefined): string[] | undefined {
|
|
111
77
|
const cleaned = ids
|
|
112
78
|
?.map((id) => id.trim())
|
|
@@ -234,7 +200,7 @@ export async function applyMappingOperators(
|
|
|
234
200
|
if (!field) {
|
|
235
201
|
throw new MappingOperatorError(operator.id, `Unknown source field "${fieldId}".`);
|
|
236
202
|
}
|
|
237
|
-
bag[leafKey(field)] =
|
|
203
|
+
bag[leafKey(field)] = readSourceFieldValue(field, input.inputs);
|
|
238
204
|
}
|
|
239
205
|
|
|
240
206
|
const target = findTargetSlot(input.targets, operator.outputSlotId);
|
|
@@ -251,7 +217,7 @@ export async function applyMappingOperators(
|
|
|
251
217
|
bag,
|
|
252
218
|
context,
|
|
253
219
|
);
|
|
254
|
-
output = writeObjectPath(output,
|
|
220
|
+
output = writeObjectPath(output, resolveTargetSlotOutputPath(target), value);
|
|
255
221
|
continue;
|
|
256
222
|
}
|
|
257
223
|
|
|
@@ -264,7 +230,7 @@ export async function applyMappingOperators(
|
|
|
264
230
|
);
|
|
265
231
|
}
|
|
266
232
|
|
|
267
|
-
let current =
|
|
233
|
+
let current = readSourceFieldValue(source, input.inputs);
|
|
268
234
|
current = await applyTransformChain(
|
|
269
235
|
input.transforms,
|
|
270
236
|
operator.transformIds ?? [],
|
|
@@ -285,7 +251,7 @@ export async function applyMappingOperators(
|
|
|
285
251
|
throw new MappingOperatorError(operator.id, `Unknown target slot "${slotId}".`);
|
|
286
252
|
}
|
|
287
253
|
const key = leafKey(target);
|
|
288
|
-
output = writeObjectPath(output,
|
|
254
|
+
output = writeObjectPath(output, resolveTargetSlotOutputPath(target), current[key]);
|
|
289
255
|
}
|
|
290
256
|
}
|
|
291
257
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
MappingEdge,
|
|
3
3
|
SourceField,
|
|
4
|
+
TargetSlot,
|
|
4
5
|
TransformContext,
|
|
5
6
|
ValueTransformRegistry,
|
|
6
7
|
} from '../types.js';
|
|
7
8
|
import { edgeItemTransformIds, edgeTransformIds } from '../document/mappingEdge.js';
|
|
8
|
-
import { projectCollectionItems } from './pathUtils.js';
|
|
9
|
+
import { projectCollectionItems, readObjectPath } from './pathUtils.js';
|
|
9
10
|
import { applyTransformChain } from '../../registry/createValueTransformRegistry.js';
|
|
10
11
|
import { BUILTIN_TRANSFORM_IDS } from '../../registry/builtinTransforms.js';
|
|
11
12
|
import { resolveOptionSteps } from './transformOptions.js';
|
|
@@ -22,6 +23,44 @@ export function findSourceField(
|
|
|
22
23
|
return flattenSourceFields(fields).find((field) => field.id === fieldId);
|
|
23
24
|
}
|
|
24
25
|
|
|
26
|
+
export function readSourceFieldValue(
|
|
27
|
+
field: SourceField,
|
|
28
|
+
inputs: Readonly<Record<string, unknown>>,
|
|
29
|
+
): unknown {
|
|
30
|
+
const shapeId = field.shapeId?.trim();
|
|
31
|
+
const bag =
|
|
32
|
+
shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)
|
|
33
|
+
? inputs[shapeId]
|
|
34
|
+
: Object.keys(inputs).length === 1
|
|
35
|
+
? inputs[Object.keys(inputs)[0]!]
|
|
36
|
+
: inputs;
|
|
37
|
+
|
|
38
|
+
const path = field.path?.trim();
|
|
39
|
+
if (!path) {
|
|
40
|
+
return field.sampleValue;
|
|
41
|
+
}
|
|
42
|
+
if (shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)) {
|
|
43
|
+
return readObjectPath(bag, path);
|
|
44
|
+
}
|
|
45
|
+
const fromBag = readObjectPath(bag, path);
|
|
46
|
+
return fromBag === undefined ? readObjectPath(inputs, path) : fromBag;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function resolveTargetSlotOutputPath(slot: TargetSlot): string {
|
|
50
|
+
const path = slot.path?.trim();
|
|
51
|
+
if (path) {
|
|
52
|
+
return path;
|
|
53
|
+
}
|
|
54
|
+
const id = slot.id.trim();
|
|
55
|
+
if (id.includes('.')) {
|
|
56
|
+
const parts = id.split('.').filter(Boolean);
|
|
57
|
+
if (parts.length >= 2) {
|
|
58
|
+
return parts.slice(1).join('.');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return slot.label.trim() || id;
|
|
62
|
+
}
|
|
63
|
+
|
|
25
64
|
/**
|
|
26
65
|
* Resolve an edge against a live / sample source value.
|
|
27
66
|
*
|
|
@@ -7,15 +7,15 @@ import {
|
|
|
7
7
|
type DataShapeRegistry,
|
|
8
8
|
} from './dataShape.js';
|
|
9
9
|
import { convertArrayWithItemEdges } from '../mapping/convertItemEdges.js';
|
|
10
|
-
import { isPlainObject,
|
|
11
|
-
import {
|
|
10
|
+
import { isPlainObject, writeObjectPath } from '../mapping/pathUtils.js';
|
|
11
|
+
import {
|
|
12
|
+
findSourceField,
|
|
13
|
+
readSourceFieldValue,
|
|
14
|
+
resolveMappedValue,
|
|
15
|
+
resolveTargetSlotOutputPath,
|
|
16
|
+
} from '../mapping/resolveMappedValue.js';
|
|
12
17
|
import { findTargetSlot, flattenTargetSlots } from '../mapping/treeUtils.js';
|
|
13
|
-
import type {
|
|
14
|
-
SourceField,
|
|
15
|
-
TargetSlot,
|
|
16
|
-
TransformContext,
|
|
17
|
-
ValueTransformRegistry,
|
|
18
|
-
} from '../types.js';
|
|
18
|
+
import type { TransformContext, ValueTransformRegistry } from '../types.js';
|
|
19
19
|
|
|
20
20
|
export interface ConvertToShapeInput {
|
|
21
21
|
readonly conversion: ConversionDefinition;
|
|
@@ -66,54 +66,6 @@ function resolveShape(
|
|
|
66
66
|
return shapes.find((shape) => shape.id === id);
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
function outputPathForTarget(slot: TargetSlot): string {
|
|
70
|
-
const path = slot.path?.trim();
|
|
71
|
-
if (path) {
|
|
72
|
-
return path;
|
|
73
|
-
}
|
|
74
|
-
// Prefer last id segment when hosts use dotted ids (`slot.display.timeText`).
|
|
75
|
-
const id = slot.id.trim();
|
|
76
|
-
if (id.includes('.')) {
|
|
77
|
-
const parts = id.split('.').filter(Boolean);
|
|
78
|
-
// Drop a leading registry prefix like `slot` when present with 3+ segments.
|
|
79
|
-
if (parts.length >= 3 && (parts[0] === 'slot' || parts[0] === 'tgt')) {
|
|
80
|
-
return parts.slice(1).join('.');
|
|
81
|
-
}
|
|
82
|
-
if (parts.length >= 2) {
|
|
83
|
-
return parts.slice(1).join('.');
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return slot.label.trim() || id;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function readFieldValue(field: SourceField, inputs: Readonly<Record<string, unknown>>): unknown {
|
|
90
|
-
const shapeId = field.shapeId?.trim();
|
|
91
|
-
const bag =
|
|
92
|
-
shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)
|
|
93
|
-
? inputs[shapeId]
|
|
94
|
-
: // Single-bag fallback: use the only input, or the whole inputs record.
|
|
95
|
-
Object.keys(inputs).length === 1
|
|
96
|
-
? inputs[Object.keys(inputs)[0]!]
|
|
97
|
-
: inputs;
|
|
98
|
-
|
|
99
|
-
const path = field.path?.trim();
|
|
100
|
-
if (path) {
|
|
101
|
-
// When bags are per-shape, paths are relative to that bag.
|
|
102
|
-
// When falling back to the whole inputs record, absolute paths still work.
|
|
103
|
-
if (shapeId && Object.prototype.hasOwnProperty.call(inputs, shapeId)) {
|
|
104
|
-
return readObjectPath(bag, path);
|
|
105
|
-
}
|
|
106
|
-
const fromBag = readObjectPath(bag, path);
|
|
107
|
-
if (fromBag !== undefined) {
|
|
108
|
-
return fromBag;
|
|
109
|
-
}
|
|
110
|
-
// Absolute path into combined inputs (e.g. `order.totalCents`).
|
|
111
|
-
return readObjectPath(inputs, path);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return field.sampleValue;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
69
|
/**
|
|
118
70
|
* Apply a conversion to named input bags and build target-shaped JSON.
|
|
119
71
|
*
|
|
@@ -170,7 +122,7 @@ export async function convertToShape(input: ConvertToShapeInput): Promise<Conver
|
|
|
170
122
|
continue;
|
|
171
123
|
}
|
|
172
124
|
|
|
173
|
-
const sourceValue =
|
|
125
|
+
const sourceValue = readSourceFieldValue(sourceField, input.inputs);
|
|
174
126
|
const value =
|
|
175
127
|
edge.itemEdges && edge.itemEdges.length > 0
|
|
176
128
|
? await convertArrayWithItemEdges({
|
|
@@ -191,7 +143,7 @@ export async function convertToShape(input: ConvertToShapeInput): Promise<Conver
|
|
|
191
143
|
: undefined,
|
|
192
144
|
});
|
|
193
145
|
|
|
194
|
-
const path =
|
|
146
|
+
const path = resolveTargetSlotOutputPath(targetSlot);
|
|
195
147
|
output = writeObjectPath(output, path, value);
|
|
196
148
|
slots.push({
|
|
197
149
|
edgeId: edge.id,
|