@octaviaflow/flow-rules 0.15.0 → 0.16.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.
@@ -26,6 +26,19 @@ export interface FieldMapping {
26
26
  depth?: number;
27
27
  /** With `groupBy`: this field goes into each line of the record's list, not the record (DEV-478). Root level only. */
28
28
  lineField?: boolean;
29
+ /**
30
+ * "Find by" (DEV-480): the mapped value names a record in the target app —
31
+ * the write uses the id of the `object` record whose `matchField` equals it.
32
+ * Root level only; on a line field it applies to each line. Odoo today.
33
+ */
34
+ lookup?: TransformLookup;
35
+ }
36
+ /** A record in the target app, found by one of its fields (DEV-480). */
37
+ export interface TransformLookup {
38
+ /** The target app's object (Odoo model): res.partner, product.product. */
39
+ object: string;
40
+ /** The field the mapped value is matched against: email, default_code. Must be unique. */
41
+ matchField: string;
29
42
  }
30
43
  /**
31
44
  * One record per key (DEV-478): rows whose `key` resolves to the same value
package/dist/index.cjs CHANGED
@@ -3774,7 +3774,7 @@ var TransformConfig = {
3774
3774
  mappings: {
3775
3775
  type: "array",
3776
3776
  required: false,
3777
- description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line."
3777
+ description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo only for now."
3778
3778
  },
3779
3779
  groupBy: {
3780
3780
  type: "json",
@@ -3818,6 +3818,10 @@ var TransformConfig = {
3818
3818
  if (!mapping.targetField) {
3819
3819
  errors.push(`Mapping ${index + 1}: Target field is required`);
3820
3820
  }
3821
+ const lookup = mapping.lookup;
3822
+ if (lookup && (!lookup.object || !lookup.matchField)) {
3823
+ errors.push(`Mapping ${index + 1}: Find by needs both the object and the field to match (lookup.object, lookup.matchField)`);
3824
+ }
3821
3825
  });
3822
3826
  }
3823
3827
  }
package/dist/index.d.ts CHANGED
@@ -36,7 +36,7 @@ export { EmailConfig, } from "./catalog/communication/email-send/config";
36
36
  export { queryDefinition, } from "./catalog/general/query/index";
37
37
  export { isQueryableConnector, } from "./catalog/general/query/config";
38
38
  export { AggregateFunction, type BuildQueryConfig, type ColumnSchema, type ConnectorSchema, JoinType, LogicalOperator, type QueryExecutionResult, type QueryField, type QueryFilter, type QueryFilterGroup, type QueryJoin, type QuerySort, SortDirection, type VisualQueryConfig, } from "./catalog/general/query/types";
39
- export { DATABASE_CONNECTOR_IDS, type FieldMapping, TRANSFORM_MODES, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformGroupBy, type TransformOperation, } from "./catalog/general/transform/config";
39
+ export { DATABASE_CONNECTOR_IDS, type FieldMapping, TRANSFORM_MODES, TRANSFORM_OPERATIONS, TransformConfig, type TransformConfigType, type TransformGroupBy, type TransformLookup, type TransformOperation, } from "./catalog/general/transform/config";
40
40
  export { AGGREGATE_FUNCTIONS, AGGREGATE_FUNCTION_DESCRIPTIONS, AggregateConfig, type AggregateConfigType, type AggregateFn, type AggregateMetric, type AggregateSchemaNode, groupKeyName, } from "./catalog/general/aggregate/config";
41
41
  export { detectRecordFields, resolveRecordSchema, type RecordSchemaLike, } from "./catalog/logic/for-each/recordSchema";
42
42
  export { STORAGE_CONNECTOR_IDS, type StorageExtraField, type StoragePathField, getStorageProvider, storageConfigKeys, } from "./catalog/storage/storageCapabilities";
package/dist/index.js CHANGED
@@ -3616,7 +3616,7 @@ var TransformConfig = {
3616
3616
  mappings: {
3617
3617
  type: "array",
3618
3618
  required: false,
3619
- description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line."
3619
+ description: "Field mappings: [{ id, sourceField, targetField, targetType, transform? }]. sourceField is a token like {{orders[].email}}; " + "an index picks one list element ({{products[].variants[0].price}}). With groupBy, set lineField: true on the mappings that make each line. " + 'When the target field holds a record id but you have a reference (an email, SHOP-123), add lookup: { "object": "product.product", "matchField": "default_code" } — ' + "the write uses the id of the one record whose matchField equals the value; no match, or more than one, fails that row. Odoo only for now."
3620
3620
  },
3621
3621
  groupBy: {
3622
3622
  type: "json",
@@ -3660,6 +3660,10 @@ var TransformConfig = {
3660
3660
  if (!mapping.targetField) {
3661
3661
  errors.push(`Mapping ${index + 1}: Target field is required`);
3662
3662
  }
3663
+ const lookup = mapping.lookup;
3664
+ if (lookup && (!lookup.object || !lookup.matchField)) {
3665
+ errors.push(`Mapping ${index + 1}: Find by needs both the object and the field to match (lookup.object, lookup.matchField)`);
3666
+ }
3663
3667
  });
3664
3668
  }
3665
3669
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@octaviaflow/flow-rules",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "The flow action catalog and the rules engine behind Flow Doctor — one definition of what a step accepts and what makes a flow valid, shared by the editor and the server",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",