@memberjunction/global 5.41.0 → 5.43.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 (56) hide show
  1. package/README.md +89 -0
  2. package/dist/KeyedSerialTaskQueue.d.ts +60 -0
  3. package/dist/KeyedSerialTaskQueue.d.ts.map +1 -0
  4. package/dist/KeyedSerialTaskQueue.js +76 -0
  5. package/dist/KeyedSerialTaskQueue.js.map +1 -0
  6. package/dist/SafeExpressionEvaluator.d.ts +5 -0
  7. package/dist/SafeExpressionEvaluator.d.ts.map +1 -1
  8. package/dist/SafeExpressionEvaluator.js +26 -11
  9. package/dist/SafeExpressionEvaluator.js.map +1 -1
  10. package/dist/__tests__/FieldRulesEvaluator.test.d.ts +2 -0
  11. package/dist/__tests__/FieldRulesEvaluator.test.d.ts.map +1 -0
  12. package/dist/__tests__/FieldRulesEvaluator.test.js +167 -0
  13. package/dist/__tests__/FieldRulesEvaluator.test.js.map +1 -0
  14. package/dist/__tests__/KeyedSerialTaskQueue.test.d.ts +2 -0
  15. package/dist/__tests__/KeyedSerialTaskQueue.test.d.ts.map +1 -0
  16. package/dist/__tests__/KeyedSerialTaskQueue.test.js +91 -0
  17. package/dist/__tests__/KeyedSerialTaskQueue.test.js.map +1 -0
  18. package/dist/__tests__/UUIDCompliance.test.js +2 -0
  19. package/dist/__tests__/UUIDCompliance.test.js.map +1 -1
  20. package/dist/__tests__/valueMapping.test.d.ts +6 -0
  21. package/dist/__tests__/valueMapping.test.d.ts.map +1 -0
  22. package/dist/__tests__/valueMapping.test.js +68 -0
  23. package/dist/__tests__/valueMapping.test.js.map +1 -0
  24. package/dist/fieldRules/FieldRulesEvaluator.d.ts +34 -0
  25. package/dist/fieldRules/FieldRulesEvaluator.d.ts.map +1 -0
  26. package/dist/fieldRules/FieldRulesEvaluator.js +130 -0
  27. package/dist/fieldRules/FieldRulesEvaluator.js.map +1 -0
  28. package/dist/fieldRules/FieldTransformEngine.d.ts +44 -0
  29. package/dist/fieldRules/FieldTransformEngine.d.ts.map +1 -0
  30. package/dist/fieldRules/FieldTransformEngine.js +189 -0
  31. package/dist/fieldRules/FieldTransformEngine.js.map +1 -0
  32. package/dist/fieldRules/index.d.ts +6 -0
  33. package/dist/fieldRules/index.d.ts.map +1 -0
  34. package/dist/fieldRules/index.js +6 -0
  35. package/dist/fieldRules/index.js.map +1 -0
  36. package/dist/fieldRules/rules.d.ts +135 -0
  37. package/dist/fieldRules/rules.d.ts.map +1 -0
  38. package/dist/fieldRules/rules.js +2 -0
  39. package/dist/fieldRules/rules.js.map +1 -0
  40. package/dist/fieldRules/transformRegistry.d.ts +22 -0
  41. package/dist/fieldRules/transformRegistry.d.ts.map +1 -0
  42. package/dist/fieldRules/transformRegistry.js +33 -0
  43. package/dist/fieldRules/transformRegistry.js.map +1 -0
  44. package/dist/fieldRules/transforms.d.ts +102 -0
  45. package/dist/fieldRules/transforms.d.ts.map +1 -0
  46. package/dist/fieldRules/transforms.js +8 -0
  47. package/dist/fieldRules/transforms.js.map +1 -0
  48. package/dist/index.d.ts +3 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +3 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/valueMapping.d.ts +33 -0
  53. package/dist/valueMapping.d.ts.map +1 -0
  54. package/dist/valueMapping.js +104 -0
  55. package/dist/valueMapping.js.map +1 -0
  56. package/package.json +1 -1
@@ -0,0 +1,189 @@
1
+ import { MJLruCache } from '../MJLruCache.js';
2
+ import { GetFieldTransform } from './transformRegistry.js';
3
+ /**
4
+ * Framework-agnostic engine that runs a field-value transform pipeline over a single `(value, fields)`
5
+ * pair. Lifted from the MemberJunction integration field-mapping engine so the integration sync AND the
6
+ * rules-based bulk-update processor share one implementation of every transform type.
7
+ *
8
+ * Holds an LRU cache of compiled custom/formula expressions (an identical expression compiles once, not
9
+ * once per record). A failed compile is cached as the `Error` it threw and re-thrown from cache, so a
10
+ * malformed expression is compiled exactly once across a whole batch.
11
+ */
12
+ export class FieldTransformEngine {
13
+ constructor() {
14
+ this.compiledExpressionCache = new MJLruCache();
15
+ }
16
+ /**
17
+ * Runs `value` through every step of `steps`, returning the final value (or `Skipped` when an
18
+ * OnError='Skip' step drops the field). `fields` is the full record, available to combine/custom steps.
19
+ */
20
+ ExecutePipeline(value, fields, steps) {
21
+ let current = value;
22
+ for (const step of steps) {
23
+ const result = this.ExecuteStep(step, current, fields);
24
+ if (result.Skipped) {
25
+ return result;
26
+ }
27
+ current = result.Value;
28
+ }
29
+ return { Value: current, Skipped: false };
30
+ }
31
+ /**
32
+ * Executes a single transform step, applying the configured transformation and handling errors
33
+ * according to the step's OnError strategy (default 'Null' — grace: null the field, keep going).
34
+ */
35
+ ExecuteStep(step, value, fields) {
36
+ const onError = step.OnError ?? 'Null';
37
+ try {
38
+ return { Value: this.dispatch(step, value, fields), Skipped: false };
39
+ }
40
+ catch (err) {
41
+ return this.handleError(onError, err);
42
+ }
43
+ }
44
+ /**
45
+ * Evaluates a value-producing expression against the record. Reuses the compiled-expression cache.
46
+ * The expression sees the current field value as `value` and all record fields as `fields`
47
+ * (e.g. `fields.FirstName + ' ' + fields.LastName`).
48
+ */
49
+ Evaluate(expression, value, fields) {
50
+ return this.getCompiled(expression)(value, fields);
51
+ }
52
+ dispatch(step, value, fields) {
53
+ switch (step.Type) {
54
+ case 'direct':
55
+ return this.applyDirect(value, step.Config);
56
+ case 'regex':
57
+ return this.applyRegex(value, step.Config);
58
+ case 'split':
59
+ return this.applySplit(value, step.Config);
60
+ case 'combine':
61
+ return this.applyCombine(fields, step.Config);
62
+ case 'lookup':
63
+ return this.applyLookup(value, step.Config);
64
+ case 'format':
65
+ return this.applyFormat(value, step.Config);
66
+ case 'coerce':
67
+ return this.applyCoerce(value, step.Config);
68
+ case 'substring':
69
+ return this.applySubstring(value, step.Config);
70
+ case 'custom':
71
+ try {
72
+ return this.Evaluate(step.Config.Expression, value, fields);
73
+ }
74
+ catch (err) {
75
+ throw new Error(`Custom transform expression failed: ${err instanceof Error ? err.message : String(err)}`);
76
+ }
77
+ default: {
78
+ // Not a built-in — dispatch to a registered plugin (e.g. 'jsonpath' / 'xpath', whose
79
+ // libraries must not be deps of this package). See {@link RegisterFieldTransform}.
80
+ const plugin = GetFieldTransform(step.Type);
81
+ if (plugin) {
82
+ return plugin(value, fields, step.Config);
83
+ }
84
+ throw new Error(`Unknown transform type '${step.Type}'. If it is a plugin transform (e.g. 'jsonpath'/'xpath'), import the package that registers it before running.`);
85
+ }
86
+ }
87
+ }
88
+ handleError(onError, err) {
89
+ switch (onError) {
90
+ case 'Skip':
91
+ return { Value: undefined, Skipped: true };
92
+ case 'Null':
93
+ return { Value: null, Skipped: false };
94
+ case 'Fail':
95
+ throw err;
96
+ }
97
+ }
98
+ applyDirect(value, config) {
99
+ return value == null && config.DefaultValue !== undefined ? config.DefaultValue : value;
100
+ }
101
+ applyRegex(value, config) {
102
+ return String(value ?? '').replace(new RegExp(config.Pattern, config.Flags ?? ''), config.Replacement);
103
+ }
104
+ applySplit(value, config) {
105
+ return String(value ?? '').split(config.Delimiter)[config.Index] ?? null;
106
+ }
107
+ applyCombine(fields, config) {
108
+ return config.SourceFields.map((f) => String(fields[f] ?? '')).join(config.Separator);
109
+ }
110
+ applyLookup(value, config) {
111
+ const lowerKey = String(value ?? '').toLowerCase();
112
+ const entry = Object.entries(config.Map).find(([key]) => key.toLowerCase() === lowerKey);
113
+ return entry ? entry[1] : (config.Default ?? null);
114
+ }
115
+ applyFormat(value, config) {
116
+ if (config.FormatType === 'date') {
117
+ const dateVal = value instanceof Date ? value : new Date(String(value));
118
+ if (isNaN(dateVal.getTime())) {
119
+ throw new Error(`Cannot format "${String(value)}" as a date`);
120
+ }
121
+ return config.FormatString.toLowerCase() === 'iso' || config.FormatString === 'ISO8601'
122
+ ? dateVal.toISOString()
123
+ : dateVal.toLocaleDateString('en-US');
124
+ }
125
+ if (config.FormatType === 'number') {
126
+ const numVal = Number(value);
127
+ if (!Number.isFinite(numVal)) {
128
+ throw new Error(`Cannot format "${String(value)}" as a number`);
129
+ }
130
+ return numVal.toFixed(Number(config.FormatString) || 0);
131
+ }
132
+ return String(value ?? '');
133
+ }
134
+ applyCoerce(value, config) {
135
+ switch (config.TargetType) {
136
+ case 'string':
137
+ return String(value ?? '');
138
+ case 'number': {
139
+ const num = Number(value);
140
+ if (isNaN(num)) {
141
+ throw new Error(`Cannot coerce "${String(value)}" to number`);
142
+ }
143
+ return num;
144
+ }
145
+ case 'boolean': {
146
+ if (typeof value === 'boolean')
147
+ return value;
148
+ if (typeof value === 'number')
149
+ return value !== 0;
150
+ const s = String(value).toLowerCase().trim();
151
+ return s === 'true' || s === '1' || s === 'yes';
152
+ }
153
+ case 'date': {
154
+ const d = new Date(String(value));
155
+ if (isNaN(d.getTime())) {
156
+ throw new Error(`Cannot coerce "${String(value)}" to date`);
157
+ }
158
+ return d;
159
+ }
160
+ default:
161
+ throw new Error(`Unknown coerce target type: ${config.TargetType}`);
162
+ }
163
+ }
164
+ applySubstring(value, config) {
165
+ const s = String(value ?? '');
166
+ return config.Length !== undefined ? s.substring(config.Start, config.Start + config.Length) : s.substring(config.Start);
167
+ }
168
+ getCompiled(expression) {
169
+ let cached = this.compiledExpressionCache.Get(expression);
170
+ if (cached === undefined) {
171
+ cached = this.compile(expression);
172
+ this.compiledExpressionCache.Set(expression, cached);
173
+ }
174
+ if (cached instanceof Error) {
175
+ throw cached;
176
+ }
177
+ return cached;
178
+ }
179
+ compile(expression) {
180
+ try {
181
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
182
+ return new Function('value', 'fields', `return (${expression});`);
183
+ }
184
+ catch (err) {
185
+ return err instanceof Error ? err : new Error(String(err));
186
+ }
187
+ }
188
+ }
189
+ //# sourceMappingURL=FieldTransformEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldTransformEngine.js","sourceRoot":"","sources":["../../src/fieldRules/FieldTransformEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export * from './transforms.js';
2
+ export * from './transformRegistry.js';
3
+ export * from './FieldTransformEngine.js';
4
+ export * from './rules.js';
5
+ export * from './FieldRulesEvaluator.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fieldRules/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export * from './transforms.js';
2
+ export * from './transformRegistry.js';
3
+ export * from './FieldTransformEngine.js';
4
+ export * from './rules.js';
5
+ export * from './FieldRulesEvaluator.js';
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fieldRules/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,wBAAwB,CAAC;AACvC,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,135 @@
1
+ import type { TransformStep } from './transforms.js';
2
+ /**
3
+ * How a field rule produces its base value (before any transform pipeline runs):
4
+ * - `static` — a literal constant
5
+ * - `field` — copy another field's current value
6
+ * - `formula` — a JS value expression over the record (`fields.X`), e.g. `fields.FirstName + ' ' + fields.LastName`
7
+ * - `lookup` — resolve a value from another entity by matching a key (requires a LookupResolver)
8
+ * - `prompt` — run an AI prompt over the record and use its output (requires a PromptResolver). By
9
+ * default the WHOLE record is passed as the prompt's data; supply `Data` to send a narrower / shaped
10
+ * context (e.g. a rendered entity-document of the record). Powerful but one model call PER record —
11
+ * use the dry-run preview + bounded concurrency, and prefer it for enrichment/summarization fields.
12
+ */
13
+ export type FieldRuleValueSource = {
14
+ Kind: 'static';
15
+ Value: unknown;
16
+ } | {
17
+ Kind: 'field';
18
+ Field: string;
19
+ } | {
20
+ Kind: 'formula';
21
+ Expression: string;
22
+ } | {
23
+ Kind: 'lookup';
24
+ Lookup: FieldRuleLookup;
25
+ } | {
26
+ Kind: 'prompt';
27
+ Prompt: FieldRulePrompt;
28
+ } | {
29
+ Kind: 'entityDocument';
30
+ EntityDocument?: FieldRuleEntityDocument;
31
+ };
32
+ /**
33
+ * Renders the record as text via an MJ Entity Document template (the same templates used for
34
+ * embeddings/RAG), using the existing rendering infrastructure through an injected
35
+ * {@link EntityDocumentResolver}. Most useful inside a `prompt` source's `Data` — hand the LLM a rich,
36
+ * curated rendering of the record instead of raw fields.
37
+ */
38
+ export interface FieldRuleEntityDocument {
39
+ /** Which Entity Document template to render. Omit to use the entity's default/primary document. */
40
+ EntityDocumentID?: string;
41
+ }
42
+ /** An AI prompt source: run a prompt over the record and use its output as the field value. */
43
+ export interface FieldRulePrompt {
44
+ /** The AI prompt to run (its ID). */
45
+ PromptID: string;
46
+ /**
47
+ * Optional shaping of the data handed to the prompt. Omit to pass the whole record. Each entry's
48
+ * value is computed like any other source (`field` / `formula` / `static`), so you can pass selected
49
+ * fields, derived values, or a pre-rendered entity-document string under named keys.
50
+ */
51
+ Data?: Record<string, FieldRuleValueSource>;
52
+ }
53
+ /** An entity lookup: find a record where MatchField === (computed) MatchValue, return ReturnField. */
54
+ export interface FieldRuleLookup {
55
+ /** Entity to look in (e.g. 'Accounts'). */
56
+ Entity: string;
57
+ /** Field on the lookup entity to match against. */
58
+ MatchField: string;
59
+ /** How to compute the value to match (static / field / formula). */
60
+ MatchValue: FieldRuleValueSource;
61
+ /** Field to return from the matched record. */
62
+ ReturnField: string;
63
+ /** Value to use when no record matches. */
64
+ Default?: unknown;
65
+ }
66
+ /** A single rule: set TargetField from Source (optionally transformed), gated by an optional Condition. */
67
+ export interface FieldRule {
68
+ /** The field on the record to set. */
69
+ TargetField: string;
70
+ /** How to produce the base value. */
71
+ Source: FieldRuleValueSource;
72
+ /** Optional transform pipeline applied to the computed value. */
73
+ Transforms?: TransformStep[];
74
+ /** Optional boolean expression over the record — the rule only applies when it evaluates true. */
75
+ Condition?: string;
76
+ }
77
+ /** An ordered set of field rules applied to each record. */
78
+ export interface FieldRuleSet {
79
+ Rules: FieldRule[];
80
+ }
81
+ /** The computed outcome of one rule for one record — the unit of a dry-run preview. */
82
+ export interface FieldChange {
83
+ /** The target field. */
84
+ Field: string;
85
+ /** The record's current value. */
86
+ OldValue: unknown;
87
+ /** The computed new value (equals OldValue when not Applied). */
88
+ NewValue: unknown;
89
+ /** True when NewValue differs from OldValue. */
90
+ Changed: boolean;
91
+ /** True when the rule produced a value to write (condition passed, no skip/error). */
92
+ Applied: boolean;
93
+ /** Why the rule did not apply (condition false / transform skipped). */
94
+ SkipReason?: string;
95
+ /** Set when computing the value errored (condition or source/transform). */
96
+ Error?: string;
97
+ }
98
+ /** A lookup with its MatchValue already resolved to a concrete value, handed to the LookupResolver. */
99
+ export interface ResolvedLookup {
100
+ Entity: string;
101
+ MatchField: string;
102
+ MatchValue: unknown;
103
+ ReturnField: string;
104
+ }
105
+ /**
106
+ * Resolves an entity lookup to a value. Injected into the evaluator so the engine stays framework-pure
107
+ * (the bulk-update processor supplies a RunView-backed resolver; unit tests supply a stub).
108
+ * Should return the matched record's ReturnField value, or `undefined` when nothing matches.
109
+ */
110
+ export type LookupResolver = (lookup: ResolvedLookup) => Promise<unknown>;
111
+ /** A prompt source with its data already resolved to concrete values, handed to the PromptResolver. */
112
+ export interface ResolvedPrompt {
113
+ PromptID: string;
114
+ /** The data context for the prompt run (the whole record by default, or the shaped `Data` map). */
115
+ Data: Record<string, unknown>;
116
+ }
117
+ /**
118
+ * Runs an AI prompt and returns its output value. Injected into the evaluator so the engine itself never
119
+ * depends on the AI stack — the bulk-update processor supplies a real `AIPromptRunner`-backed resolver;
120
+ * unit tests supply a stub. This is the same dependency-inversion seam as {@link LookupResolver}.
121
+ */
122
+ export type PromptResolver = (prompt: ResolvedPrompt) => Promise<unknown>;
123
+ /** An entity-document source with its record handed to the {@link EntityDocumentResolver} to render. */
124
+ export interface ResolvedEntityDocument {
125
+ EntityDocumentID?: string;
126
+ /** The record's field values, to render through the Entity Document template. */
127
+ Record: Record<string, unknown>;
128
+ }
129
+ /**
130
+ * Renders a record to text via the existing Entity Document / Template infrastructure. Injected so the
131
+ * engine never depends on `@memberjunction/templates` or the AI/vector stack — the bulk-update processor
132
+ * supplies a resolver backed by the real render infra. Same dependency-inversion seam as the others.
133
+ */
134
+ export type EntityDocumentResolver = (doc: ResolvedEntityDocument) => Promise<string>;
135
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/fieldRules/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/fieldRules/rules.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * A pluggable transform handler: `(value, fields, config) => result`. Same call shape as the built-in
3
+ * transforms, so a plugin is indistinguishable from a built-in at the call site.
4
+ */
5
+ export type FieldTransformPlugin = (value: unknown, fields: Record<string, unknown>, config: unknown) => unknown;
6
+ /**
7
+ * Registers a transform plugin by type name so the {@link FieldTransformEngine} can dispatch a
8
+ * non-built-in transform to it.
9
+ *
10
+ * This is how heavier transforms (e.g. `jsonpath`, `xpath`) are added WITHOUT making their libraries
11
+ * (jsonpath-plus, xpath, @xmldom/xmldom, …) dependencies of this foundational package: a separate
12
+ * package owns the libs, implements the handler, and calls this at module-load to register it. Any
13
+ * `FieldTransformEngine` in the process (integration sync, rules-based bulk update, …) then supports the
14
+ * transform — the engine stays lib-free, the plugin owns the deps. Idempotent per type (last wins).
15
+ *
16
+ * @param type - The transform `Type` string (case-insensitive), e.g. `'jsonpath'`.
17
+ * @param plugin - The handler.
18
+ */
19
+ export declare function RegisterFieldTransform(type: string, plugin: FieldTransformPlugin): void;
20
+ /** Returns the registered plugin for a transform type, or `undefined` if none is registered. */
21
+ export declare function GetFieldTransform(type: string): FieldTransformPlugin | undefined;
22
+ //# sourceMappingURL=transformRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformRegistry.d.ts","sourceRoot":"","sources":["../../src/fieldRules/transformRegistry.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;AAejH;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,IAAI,CAEvF;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAEhF"}
@@ -0,0 +1,33 @@
1
+ import { GetGlobalObjectStore } from '../util.js';
2
+ /** Global-object-store key so registrations survive bundlers that duplicate this module. */
3
+ const STORE_KEY = '__mj_FieldTransformPlugins__';
4
+ function registry() {
5
+ const store = (GetGlobalObjectStore() ?? globalThis);
6
+ let map = store[STORE_KEY];
7
+ if (!map) {
8
+ map = new Map();
9
+ store[STORE_KEY] = map;
10
+ }
11
+ return map;
12
+ }
13
+ /**
14
+ * Registers a transform plugin by type name so the {@link FieldTransformEngine} can dispatch a
15
+ * non-built-in transform to it.
16
+ *
17
+ * This is how heavier transforms (e.g. `jsonpath`, `xpath`) are added WITHOUT making their libraries
18
+ * (jsonpath-plus, xpath, @xmldom/xmldom, …) dependencies of this foundational package: a separate
19
+ * package owns the libs, implements the handler, and calls this at module-load to register it. Any
20
+ * `FieldTransformEngine` in the process (integration sync, rules-based bulk update, …) then supports the
21
+ * transform — the engine stays lib-free, the plugin owns the deps. Idempotent per type (last wins).
22
+ *
23
+ * @param type - The transform `Type` string (case-insensitive), e.g. `'jsonpath'`.
24
+ * @param plugin - The handler.
25
+ */
26
+ export function RegisterFieldTransform(type, plugin) {
27
+ registry().set(type.trim().toLowerCase(), plugin);
28
+ }
29
+ /** Returns the registered plugin for a transform type, or `undefined` if none is registered. */
30
+ export function GetFieldTransform(type) {
31
+ return registry().get(type.trim().toLowerCase());
32
+ }
33
+ //# sourceMappingURL=transformRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformRegistry.js","sourceRoot":"","sources":["../../src/fieldRules/transformRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAQ/C,4FAA4F;AAC5F,MAAM,SAAS,GAAG,8BAA8B,CAAC;AAEjD,SAAS,QAAQ;IACb,MAAM,KAAK,GAAG,CAAC,oBAAoB,EAAE,IAAK,UAAiD,CAA4B,CAAC;IACxH,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,CAAkD,CAAC;IAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,GAAG,GAAG,IAAI,GAAG,EAAgC,CAAC;QAC9C,KAAK,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC;IAC3B,CAAC;IACD,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,MAA4B;IAC7E,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC1C,OAAO,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Field-value transform pipeline types.
3
+ *
4
+ * This package is the canonical home for these types. The MemberJunction integration field-mapping
5
+ * engine and the rules-based bulk-update processor both consume them — author once, reuse everywhere.
6
+ */
7
+ /** Supported transform types for field value transformation */
8
+ export type TransformType = 'direct' | 'regex' | 'split' | 'combine' | 'lookup' | 'format' | 'coerce' | 'substring' | 'custom' | 'jsonpath' | 'xpath';
9
+ /** What to do when a transform step encounters an error */
10
+ export type TransformOnError = 'Skip' | 'Null' | 'Fail';
11
+ /** A single step in a field value transformation pipeline */
12
+ export interface TransformStep {
13
+ /** The type of transform to apply */
14
+ Type: TransformType;
15
+ /** Configuration for the transform step */
16
+ Config: TransformConfig;
17
+ /** Error handling strategy for this step. Defaults to 'Null' (grace — null the field, keep going). */
18
+ OnError?: TransformOnError;
19
+ }
20
+ /** Configuration for extracting value(s) from JSON via a JSONPath expression. */
21
+ export interface JsonPathConfig {
22
+ /** JSONPath expression, e.g. `$.store.book[0].title` or `$..author`. */
23
+ Path: string;
24
+ /** Return only the first match (default). When false, returns the full array of matches. */
25
+ First?: boolean;
26
+ }
27
+ /** Configuration for extracting value(s) from XML via an XPath expression. */
28
+ export interface XPathConfig {
29
+ /** XPath expression, e.g. `/catalog/book[1]/title/text()` or `//author`. */
30
+ Path: string;
31
+ /** Return only the first match (default). When false, returns the full array of matches. */
32
+ First?: boolean;
33
+ }
34
+ /** Union of all transform configuration types */
35
+ export type TransformConfig = DirectConfig | RegexConfig | SplitConfig | CombineConfig | LookupConfig | FormatConfig | JsonPathConfig | XPathConfig | CoerceConfig | SubstringConfig | CustomConfig;
36
+ /** Configuration for direct pass-through (no transformation) */
37
+ export interface DirectConfig {
38
+ /** Optional default value if source is null/undefined */
39
+ DefaultValue?: unknown;
40
+ }
41
+ /** Configuration for regex-based string transformation */
42
+ export interface RegexConfig {
43
+ /** Regular expression pattern to match */
44
+ Pattern: string;
45
+ /** Replacement string (supports $1, $2, etc. for capture groups) */
46
+ Replacement: string;
47
+ /** Regex flags (e.g., 'gi' for global, case-insensitive) */
48
+ Flags?: string;
49
+ }
50
+ /** Configuration for splitting a string value and extracting a portion */
51
+ export interface SplitConfig {
52
+ /** Delimiter to split on */
53
+ Delimiter: string;
54
+ /** Zero-based index of the part to extract */
55
+ Index: number;
56
+ }
57
+ /** Configuration for combining multiple source field values */
58
+ export interface CombineConfig {
59
+ /** Names of source fields to combine */
60
+ SourceFields: string[];
61
+ /** Separator to place between combined values */
62
+ Separator: string;
63
+ }
64
+ /** Configuration for value lookup/mapping (in-memory translation table — not an entity lookup) */
65
+ export interface LookupConfig {
66
+ /** Map of source values to destination values. Keys are matched case-insensitively */
67
+ Map: Record<string, unknown>;
68
+ /** Value to use when the source value is not found in the map */
69
+ Default?: unknown;
70
+ }
71
+ /** Configuration for date/number formatting */
72
+ export interface FormatConfig {
73
+ /** The target format string. For dates: ISO8601 locale format specifiers */
74
+ FormatString: string;
75
+ /** The type of formatting to apply */
76
+ FormatType: 'date' | 'number' | 'string';
77
+ }
78
+ /** Configuration for type coercion */
79
+ export interface CoerceConfig {
80
+ /** Target type to coerce the value into */
81
+ TargetType: 'string' | 'number' | 'boolean' | 'date';
82
+ }
83
+ /** Configuration for extracting a substring */
84
+ export interface SubstringConfig {
85
+ /** Start index (zero-based) */
86
+ Start: number;
87
+ /** Number of characters to extract. If omitted, extracts to end */
88
+ Length?: number;
89
+ }
90
+ /** Configuration for custom JavaScript expression evaluation */
91
+ export interface CustomConfig {
92
+ /** JavaScript expression to evaluate. The source value is available as 'value' and all fields as 'fields' */
93
+ Expression: string;
94
+ }
95
+ /** Result of running a transform step or pipeline. */
96
+ export interface TransformStepResult {
97
+ /** The resulting value (undefined when Skipped). */
98
+ Value: unknown;
99
+ /** True when an OnError='Skip' step asked to drop the field entirely. */
100
+ Skipped: boolean;
101
+ }
102
+ //# sourceMappingURL=transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../src/fieldRules/transforms.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GACnB,QAAQ,GACR,OAAO,GACP,OAAO,GACP,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,UAAU,GACV,OAAO,CAAC;AAEd,2DAA2D;AAC3D,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAExD,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC1B,qCAAqC;IACrC,IAAI,EAAE,aAAa,CAAC;IACpB,2CAA2C;IAC3C,MAAM,EAAE,eAAe,CAAC;IACxB,sGAAsG;IACtG,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC3B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,8EAA8E;AAC9E,MAAM,WAAW,WAAW;IACxB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,4FAA4F;IAC5F,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,iDAAiD;AACjD,MAAM,MAAM,eAAe,GACrB,YAAY,GACZ,WAAW,GACX,WAAW,GACX,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,cAAc,GACd,WAAW,GACX,YAAY,GACZ,eAAe,GACf,YAAY,CAAC;AAEnB,gEAAgE;AAChE,MAAM,WAAW,YAAY;IACzB,yDAAyD;IACzD,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IACxB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IACxB,4BAA4B;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,+DAA+D;AAC/D,MAAM,WAAW,aAAa;IAC1B,wCAAwC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,kGAAkG;AAClG,MAAM,WAAW,YAAY;IACzB,sFAAsF;IACtF,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,+CAA+C;AAC/C,MAAM,WAAW,YAAY;IACzB,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;CAC5C;AAED,sCAAsC;AACtC,MAAM,WAAW,YAAY;IACzB,2CAA2C;IAC3C,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;CACxD;AAED,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC5B,+BAA+B;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,gEAAgE;AAChE,MAAM,WAAW,YAAY;IACzB,6GAA6G;IAC7G,UAAU,EAAE,MAAM,CAAC;CACtB;AAED,sDAAsD;AACtD,MAAM,WAAW,mBAAmB;IAChC,oDAAoD;IACpD,KAAK,EAAE,OAAO,CAAC;IACf,yEAAyE;IACzE,OAAO,EAAE,OAAO,CAAC;CACpB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Field-value transform pipeline types.
3
+ *
4
+ * This package is the canonical home for these types. The MemberJunction integration field-mapping
5
+ * engine and the rules-based bulk-update processor both consume them — author once, reuse everywhere.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=transforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.js","sourceRoot":"","sources":["../../src/fieldRules/transforms.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { ClassFactory, ClassRegistration } from './ClassFactory.js';
2
2
  export * from './interface.js';
3
3
  export * from './util.js';
4
+ export * from './valueMapping.js';
4
5
  export * from './ObjectCache.js';
5
6
  export * from './MJLruCache.js';
6
7
  export * from './BaseSingleton.js';
@@ -13,9 +14,11 @@ export * from './util/SerializationUtils.js';
13
14
  export * from './ValidationTypes.js';
14
15
  export * from './JSONValidator.js';
15
16
  export * from './SafeExpressionEvaluator.js';
17
+ export * from './fieldRules/index.js';
16
18
  export * from './SQLExpressionValidator.js';
17
19
  export * from './warningManager.js';
18
20
  export * from './EncryptionUtils.js';
21
+ export * from './KeyedSerialTaskQueue.js';
19
22
  export * from './Global.js';
20
23
  export * from './RegisterClass.js';
21
24
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AAMjC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AAMtC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  export { ClassFactory, ClassRegistration } from './ClassFactory.js';
3
3
  export * from './interface.js';
4
4
  export * from './util.js';
5
+ export * from './valueMapping.js';
5
6
  export * from './ObjectCache.js';
6
7
  export * from './MJLruCache.js';
7
8
  export * from './BaseSingleton.js';
@@ -14,9 +15,11 @@ export * from './util/SerializationUtils.js';
14
15
  export * from './ValidationTypes.js';
15
16
  export * from './JSONValidator.js';
16
17
  export * from './SafeExpressionEvaluator.js';
18
+ export * from './fieldRules/index.js';
17
19
  export * from './SQLExpressionValidator.js';
18
20
  export * from './warningManager.js';
19
21
  export * from './EncryptionUtils.js';
22
+ export * from './KeyedSerialTaskQueue.js';
20
23
  // NOTE: TelemetryManager has moved to @memberjunction/core
21
24
  // Import from there instead of here
22
25
  // Export the main classes
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AAEjC,2DAA2D;AAC3D,oCAAoC;AAEpC,0BAA0B;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAE/B,6DAA6D;AAC7D,oCAAoC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,gBAAgB,CAAA;AAC9B,cAAc,eAAe,CAAA;AAC7B,cAAc,cAAc,CAAA;AAC5B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,cAAc,CAAA;AAC5B,cAAc,0BAA0B,CAAA;AACxC,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,wBAAwB,CAAA;AAEtC,2DAA2D;AAC3D,oCAAoC;AAEpC,0BAA0B;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA;AAE/B,6DAA6D;AAC7D,oCAAoC"}