@x12i/memorix-resolvers 1.0.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.
package/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # @x12i/memorix-resolvers
2
+
3
+ Pluggable resolver APIs for Memorix. Resolvers normalize join keys, bridge lookups, and domain-specific relationship signals without baking domain knowledge into the engine.
4
+
5
+ ## Design
6
+
7
+ - **Resolver registry** — register built-in and custom resolver types.
8
+ - **Resolver steps** — run one or more resolvers against a source record.
9
+ - **Domain plug-ins** — networking, pharma, marketing, identity, or any future domain implements the same `ResolverDefinition` API.
10
+
11
+ The engine does not branch on resolver type. A CIDR containment resolver, pharma SKU resolver, and marketing campaign resolver are all ordinary plug-ins.
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ import {
17
+ createResolverRegistry,
18
+ builtinResolvers,
19
+ runResolverSteps,
20
+ type ResolverDefinition,
21
+ } from "@x12i/memorix-resolvers";
22
+
23
+ const registry = createResolverRegistry(builtinResolvers);
24
+
25
+ const myResolver: ResolverDefinition<{ outputPath: string }> = {
26
+ type: "my-domain",
27
+ create(config) {
28
+ return {
29
+ async resolve(input) {
30
+ return {
31
+ outputs: [{ path: config.outputPath, values: ["resolved"] }],
32
+ stats: { inputsScanned: 1, valuesParsed: 1, valuesRejected: 0, matchesFound: 1, ambiguousMatches: 0 },
33
+ diagnostics: [],
34
+ };
35
+ },
36
+ };
37
+ },
38
+ };
39
+
40
+ registry.register(myResolver);
41
+
42
+ const result = await runResolverSteps(registry, {
43
+ steps: [{ type: "my-domain", resolverKey: "step-1", config: { outputPath: "data.key" } }],
44
+ record: { data: {} },
45
+ });
46
+ ```
47
+
48
+ ## Built-in resolvers
49
+
50
+ | Type | Purpose |
51
+ |------|---------|
52
+ | `exact-match` | Copy normalized values from source paths to an output path |
53
+ | `multi-value` | Split comma-separated scalars into array fields |
54
+ | `bridge-index` | Map readable keys through a bridge collection to target join keys |
55
+
56
+ ## Related packages
57
+
58
+ - [`@x12i/memorix-associator`](../memorix-associator/) — plans and applies association materialization using resolver output.
59
+ - [Operational design note](../memorix-schema-api/src/operational/memorix-enrichment-processes.md) — original enrichment process specification.
@@ -0,0 +1,26 @@
1
+ import type { ResolverDefinition } from "../types.js";
2
+ export type ExactMatchConfig = {
3
+ sourcePaths: string[];
4
+ outputPath: string;
5
+ };
6
+ export declare const exactMatchResolver: ResolverDefinition<ExactMatchConfig>;
7
+ export type MultiValueConfig = {
8
+ from: string[];
9
+ to: string;
10
+ separators?: string[];
11
+ deduplicate?: boolean;
12
+ };
13
+ export declare const multiValueResolver: ResolverDefinition<MultiValueConfig>;
14
+ export type BridgeIndexConfig = {
15
+ bridge: {
16
+ db: string;
17
+ collection: string;
18
+ sourceJoinPaths: string[];
19
+ targetJoinPath: string;
20
+ };
21
+ sourcePaths: string[];
22
+ outputPath: string;
23
+ };
24
+ export declare const bridgeIndexResolver: ResolverDefinition<BridgeIndexConfig>;
25
+ export declare const builtinResolvers: ResolverDefinition[];
26
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builtins/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAGjE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,CAAC,gBAAgB,CAgCnE,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,kBAAkB,CAAC,gBAAgB,CAqDnE,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,kBAAkB,CAAC,iBAAiB,CAsErE,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,EAIhD,CAAC"}
@@ -0,0 +1,157 @@
1
+ import { getByPath, isPlainObject, normalizeJoinValues } from "../utils.js";
2
+ export const exactMatchResolver = {
3
+ type: "exact-match",
4
+ create(config) {
5
+ const sourcePaths = config.sourcePaths ?? [];
6
+ const outputPath = config.outputPath;
7
+ return {
8
+ async resolve(input) {
9
+ const values = [];
10
+ for (const path of sourcePaths) {
11
+ values.push(...normalizeJoinValues(getByPath(input.record, path)));
12
+ }
13
+ const normalized = normalizeJoinValues(values);
14
+ const outputs = outputPath && normalized.length > 0
15
+ ? [{ path: outputPath, values: normalized }]
16
+ : [];
17
+ return {
18
+ outputs,
19
+ stats: {
20
+ inputsScanned: 1,
21
+ valuesParsed: normalized.length,
22
+ valuesRejected: sourcePaths.length > 0 && normalized.length === 0 ? 1 : 0,
23
+ matchesFound: normalized.length,
24
+ ambiguousMatches: 0,
25
+ },
26
+ diagnostics: [],
27
+ };
28
+ },
29
+ };
30
+ },
31
+ };
32
+ export const multiValueResolver = {
33
+ type: "multi-value",
34
+ create(config) {
35
+ const from = config.from ?? [];
36
+ const to = config.to;
37
+ const separators = config.separators ?? [","];
38
+ const deduplicate = config.deduplicate !== false;
39
+ return {
40
+ async resolve(input) {
41
+ const raw = [];
42
+ for (const path of from) {
43
+ raw.push(...normalizeJoinValues(getByPath(input.record, path)));
44
+ }
45
+ const expanded = [];
46
+ for (const value of raw) {
47
+ if (typeof value === "string" && separators.some((sep) => value.includes(sep))) {
48
+ for (const part of value.split(new RegExp(separators.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|")))) {
49
+ const trimmed = part.trim();
50
+ if (trimmed)
51
+ expanded.push(trimmed);
52
+ }
53
+ }
54
+ else if (value !== undefined && value !== null && value !== "") {
55
+ expanded.push(value);
56
+ }
57
+ }
58
+ let values = expanded;
59
+ if (deduplicate) {
60
+ const seen = new Set();
61
+ values = [];
62
+ for (const item of expanded) {
63
+ const key = JSON.stringify(item);
64
+ if (seen.has(key))
65
+ continue;
66
+ seen.add(key);
67
+ values.push(item);
68
+ }
69
+ }
70
+ return {
71
+ outputs: to ? [{ path: to, values }] : [],
72
+ stats: {
73
+ inputsScanned: 1,
74
+ valuesParsed: values.length,
75
+ valuesRejected: values.length === 0 ? 1 : 0,
76
+ matchesFound: values.length,
77
+ ambiguousMatches: 0,
78
+ },
79
+ diagnostics: [],
80
+ };
81
+ },
82
+ };
83
+ },
84
+ };
85
+ export const bridgeIndexResolver = {
86
+ type: "bridge-index",
87
+ create(config, context) {
88
+ let bridgeCache = null;
89
+ async function loadBridge() {
90
+ if (bridgeCache)
91
+ return bridgeCache;
92
+ bridgeCache = new Map();
93
+ if (!context.scanRecords) {
94
+ return bridgeCache;
95
+ }
96
+ const bridge = config.bridge;
97
+ for await (const doc of context.scanRecords({
98
+ db: bridge.db,
99
+ collection: bridge.collection,
100
+ })) {
101
+ const targetValue = getByPath(doc, bridge.targetJoinPath);
102
+ if (targetValue === undefined || targetValue === null || targetValue === "")
103
+ continue;
104
+ for (const sourcePath of bridge.sourceJoinPaths) {
105
+ for (const sourceValue of normalizeJoinValues(getByPath(doc, sourcePath))) {
106
+ const key = JSON.stringify(sourceValue);
107
+ const bucket = bridgeCache.get(key) ?? [];
108
+ bucket.push(targetValue);
109
+ bridgeCache.set(key, bucket);
110
+ }
111
+ }
112
+ }
113
+ return bridgeCache;
114
+ }
115
+ return {
116
+ async resolve(input) {
117
+ const bridge = await loadBridge();
118
+ const sourceValues = [];
119
+ for (const path of config.sourcePaths) {
120
+ sourceValues.push(...normalizeJoinValues(getByPath(input.record, path)));
121
+ }
122
+ const resolved = [];
123
+ for (const sourceValue of sourceValues) {
124
+ const bridged = bridge.get(JSON.stringify(sourceValue)) ?? [];
125
+ resolved.push(...bridged);
126
+ }
127
+ const values = normalizeJoinValues(resolved);
128
+ return {
129
+ outputs: values.length > 0 ? [{ path: config.outputPath, values }] : [],
130
+ stats: {
131
+ inputsScanned: 1,
132
+ valuesParsed: sourceValues.length,
133
+ valuesRejected: sourceValues.length > 0 && values.length === 0 ? 1 : 0,
134
+ matchesFound: values.length,
135
+ ambiguousMatches: values.length > sourceValues.length ? values.length - sourceValues.length : 0,
136
+ },
137
+ diagnostics: bridge.size === 0
138
+ ? [
139
+ {
140
+ level: "warning",
141
+ code: "BRIDGE_EMPTY",
142
+ message: "Bridge index produced no entries",
143
+ details: { bridge: config.bridge },
144
+ },
145
+ ]
146
+ : [],
147
+ };
148
+ },
149
+ };
150
+ },
151
+ };
152
+ export const builtinResolvers = [
153
+ exactMatchResolver,
154
+ multiValueResolver,
155
+ bridgeIndexResolver,
156
+ ];
157
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/builtins/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAO5E,MAAM,CAAC,MAAM,kBAAkB,GAAyC;IACtE,IAAI,EAAE,aAAa;IACnB,MAAM,CAAC,MAAM;QACb,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAErC,OAAO;YACL,KAAK,CAAC,OAAO,CAAC,KAAK;gBACjB,MAAM,MAAM,GAAgB,EAAE,CAAC;gBAC/B,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;oBAC/B,MAAM,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBACrE,CAAC;gBACD,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBAC/C,MAAM,OAAO,GACX,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;oBACjC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;oBAC5C,CAAC,CAAC,EAAE,CAAC;gBAET,OAAO;oBACL,OAAO;oBACP,KAAK,EAAE;wBACL,aAAa,EAAE,CAAC;wBAChB,YAAY,EAAE,UAAU,CAAC,MAAM;wBAC/B,cAAc,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACzE,YAAY,EAAE,UAAU,CAAC,MAAM;wBAC/B,gBAAgB,EAAE,CAAC;qBACpB;oBACD,WAAW,EAAE,EAAE;iBAChB,CAAC;YACJ,CAAC;SACF,CAAC;IACF,CAAC;CACF,CAAC;AASF,MAAM,CAAC,MAAM,kBAAkB,GAAyC;IACtE,IAAI,EAAE,aAAa;IACnB,MAAM,CAAC,MAAM;QACX,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;QACrB,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,KAAK,KAAK,CAAC;QAEjD,OAAO;YACL,KAAK,CAAC,OAAO,CAAC,KAAK;gBACjB,MAAM,GAAG,GAAgB,EAAE,CAAC;gBAC5B,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;oBACxB,GAAG,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClE,CAAC;gBAED,MAAM,QAAQ,GAAgB,EAAE,CAAC;gBACjC,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;oBACxB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;wBAC/E,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;4BACtH,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;4BAC5B,IAAI,OAAO;gCAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBACtC,CAAC;oBACH,CAAC;yBAAM,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;wBACjE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACvB,CAAC;gBACH,CAAC;gBAED,IAAI,MAAM,GAAG,QAAQ,CAAC;gBACtB,IAAI,WAAW,EAAE,CAAC;oBAChB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;oBAC/B,MAAM,GAAG,EAAE,CAAC;oBACZ,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;wBAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;wBACjC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;4BAAE,SAAS;wBAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBACd,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACpB,CAAC;gBACH,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;oBACzC,KAAK,EAAE;wBACL,aAAa,EAAE,CAAC;wBAChB,YAAY,EAAE,MAAM,CAAC,MAAM;wBAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC3C,YAAY,EAAE,MAAM,CAAC,MAAM;wBAC3B,gBAAgB,EAAE,CAAC;qBACpB;oBACD,WAAW,EAAE,EAAE;iBAChB,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAaF,MAAM,CAAC,MAAM,mBAAmB,GAA0C;IACxE,IAAI,EAAE,cAAc;IACpB,MAAM,CAAC,MAAM,EAAE,OAAO;QACpB,IAAI,WAAW,GAAoC,IAAI,CAAC;QAExD,KAAK,UAAU,UAAU;YACvB,IAAI,WAAW;gBAAE,OAAO,WAAW,CAAC;YACpC,WAAW,GAAG,IAAI,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;gBACzB,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC7B,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC;gBAC1C,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,EAAE,CAAC;gBACH,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;gBAC1D,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,EAAE;oBAAE,SAAS;gBACtF,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;oBAChD,KAAK,MAAM,WAAW,IAAI,mBAAmB,CAAC,SAAS,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC;wBAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;wBACxC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;wBAC1C,MAAM,CAAC,IAAI,CAAC,WAAwB,CAAC,CAAC;wBACtC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,OAAO;YACL,KAAK,CAAC,OAAO,CAAC,KAAK;gBACjB,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;gBAClC,MAAM,YAAY,GAAgB,EAAE,CAAC;gBACrC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;oBACtC,YAAY,CAAC,IAAI,CAAC,GAAG,mBAAmB,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC3E,CAAC;gBAED,MAAM,QAAQ,GAAgB,EAAE,CAAC;gBACjC,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;oBACvC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;oBAC9D,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;gBAC5B,CAAC;gBACD,MAAM,MAAM,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gBAE7C,OAAO;oBACL,OAAO,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;oBACvE,KAAK,EAAE;wBACL,aAAa,EAAE,CAAC;wBAChB,YAAY,EAAE,YAAY,CAAC,MAAM;wBACjC,cAAc,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACtE,YAAY,EAAE,MAAM,CAAC,MAAM;wBAC3B,gBAAgB,EAAE,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;qBAChG;oBACD,WAAW,EACT,MAAM,CAAC,IAAI,KAAK,CAAC;wBACf,CAAC,CAAC;4BACE;gCACE,KAAK,EAAE,SAAS;gCAChB,IAAI,EAAE,cAAc;gCACpB,OAAO,EAAE,kCAAkC;gCAC3C,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;6BACnC;yBACF;wBACH,CAAC,CAAC,EAAE;iBACT,CAAC;YACJ,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAyB;IACpD,kBAAkB;IAClB,kBAAkB;IAClB,mBAAmB;CACpB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type { JsonObject, JsonPrimitive, JsonValue, RecordRef, Resolver, ResolverContext, ResolverDefinition, ResolverDiagnostic, ResolverDiagnosticLevel, ResolverInput, ResolverOutputValue, ResolverResult, ResolverStats, ResolverStep, ResolverStepResult, RunResolverStepsOptions, RunResolverStepsResult, } from "./types.js";
2
+ export { ResolverRegistry, createResolverRegistry } from "./registry.js";
3
+ export { runResolverSteps } from "./run.js";
4
+ export { builtinResolvers, exactMatchResolver, multiValueResolver, bridgeIndexResolver, type ExactMatchConfig, type MultiValueConfig, type BridgeIndexConfig, } from "./builtins/index.js";
5
+ export { getByPath, setByPath, isPlainObject, isMissingJoinValue, normalizeJoinValues, isAssociatedPropertyName, } from "./utils.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACT,SAAS,EACT,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,SAAS,EACT,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { ResolverRegistry, createResolverRegistry } from "./registry.js";
2
+ export { runResolverSteps } from "./run.js";
3
+ export { builtinResolvers, exactMatchResolver, multiValueResolver, bridgeIndexResolver, } from "./builtins/index.js";
4
+ export { getByPath, setByPath, isPlainObject, isMissingJoinValue, normalizeJoinValues, isAssociatedPropertyName, } from "./utils.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,GAIpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,SAAS,EACT,SAAS,EACT,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ResolverDefinition } from "./types.js";
2
+ export declare class ResolverRegistry {
3
+ private readonly definitions;
4
+ register<TConfig = unknown>(definition: ResolverDefinition<TConfig>): this;
5
+ registerMany(definitions: ResolverDefinition[]): this;
6
+ has(type: string): boolean;
7
+ get(type: string): ResolverDefinition | undefined;
8
+ listTypes(): string[];
9
+ create(type: string, config: unknown, context: Parameters<ResolverDefinition["create"]>[1]): import("./types.js").Resolver;
10
+ }
11
+ export declare function createResolverRegistry(definitions?: ResolverDefinition[]): ResolverRegistry;
12
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAyC;IAErE,QAAQ,CAAC,OAAO,GAAG,OAAO,EAAE,UAAU,EAAE,kBAAkB,CAAC,OAAO,CAAC,GAAG,IAAI;IAQ1E,YAAY,CAAC,WAAW,EAAE,kBAAkB,EAAE,GAAG,IAAI;IAOrD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIjD,SAAS,IAAI,MAAM,EAAE;IAIrB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;CAO3F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,GAAE,kBAAkB,EAAO,GAAG,gBAAgB,CAG/F"}
@@ -0,0 +1,37 @@
1
+ export class ResolverRegistry {
2
+ definitions = new Map();
3
+ register(definition) {
4
+ if (this.definitions.has(definition.type)) {
5
+ throw new Error(`Resolver type already registered: ${definition.type}`);
6
+ }
7
+ this.definitions.set(definition.type, definition);
8
+ return this;
9
+ }
10
+ registerMany(definitions) {
11
+ for (const definition of definitions) {
12
+ this.register(definition);
13
+ }
14
+ return this;
15
+ }
16
+ has(type) {
17
+ return this.definitions.has(type);
18
+ }
19
+ get(type) {
20
+ return this.definitions.get(type);
21
+ }
22
+ listTypes() {
23
+ return [...this.definitions.keys()].sort();
24
+ }
25
+ create(type, config, context) {
26
+ const definition = this.definitions.get(type);
27
+ if (!definition) {
28
+ throw new Error(`Unknown resolver type: ${type}`);
29
+ }
30
+ return definition.create(config, context);
31
+ }
32
+ }
33
+ export function createResolverRegistry(definitions = []) {
34
+ const registry = new ResolverRegistry();
35
+ return registry.registerMany(definitions);
36
+ }
37
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,gBAAgB;IACV,WAAW,GAAG,IAAI,GAAG,EAA8B,CAAC;IAErE,QAAQ,CAAoB,UAAuC;QACjE,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1E,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,UAAgC,CAAC,CAAC;QACxE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,YAAY,CAAC,WAAiC;QAC5C,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;YACrC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,MAAe,EAAE,OAAoD;QACxF,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAAC,cAAoC,EAAE;IAC3E,MAAM,QAAQ,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACxC,OAAO,QAAQ,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;AAC5C,CAAC"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { RunResolverStepsOptions, RunResolverStepsResult } from "./types.js";
2
+ import type { ResolverRegistry } from "./registry.js";
3
+ export declare function runResolverSteps(registry: ResolverRegistry, options: RunResolverStepsOptions): Promise<RunResolverStepsResult>;
4
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAIV,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAkBtD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAsCjC"}
package/dist/run.js ADDED
@@ -0,0 +1,49 @@
1
+ function emptyStats() {
2
+ return {
3
+ inputsScanned: 0,
4
+ valuesParsed: 0,
5
+ valuesRejected: 0,
6
+ matchesFound: 0,
7
+ ambiguousMatches: 0,
8
+ };
9
+ }
10
+ function mergeStats(target, source) {
11
+ for (const [key, value] of Object.entries(source)) {
12
+ target[key] = (target[key] ?? 0) + value;
13
+ }
14
+ }
15
+ export async function runResolverSteps(registry, options) {
16
+ const mergedOutputs = new Map();
17
+ const stats = emptyStats();
18
+ const diagnostics = [];
19
+ const steps = [];
20
+ for (let stepIndex = 0; stepIndex < options.steps.length; stepIndex += 1) {
21
+ const step = options.steps[stepIndex];
22
+ const context = {
23
+ resolverKey: step.resolverKey,
24
+ stepIndex,
25
+ readRecord: options.context?.readRecord,
26
+ scanRecords: options.context?.scanRecords,
27
+ };
28
+ const resolver = registry.create(step.type, step.config ?? {}, context);
29
+ const result = await resolver.resolve({
30
+ record: options.record,
31
+ recordId: options.recordId,
32
+ config: step.config ?? {},
33
+ });
34
+ steps.push({ resolverKey: step.resolverKey, type: step.type, result });
35
+ mergeStats(stats, result.stats);
36
+ diagnostics.push(...result.diagnostics);
37
+ for (const output of result.outputs) {
38
+ const existing = mergedOutputs.get(output.path) ?? [];
39
+ mergedOutputs.set(output.path, [...existing, ...output.values]);
40
+ }
41
+ }
42
+ return {
43
+ steps,
44
+ mergedOutputs: mergedOutputs,
45
+ stats,
46
+ diagnostics,
47
+ };
48
+ }
49
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AASA,SAAS,UAAU;IACjB,OAAO;QACL,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,cAAc,EAAE,CAAC;QACjB,YAAY,EAAE,CAAC;QACf,gBAAgB,EAAE,CAAC;KACpB,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,MAAqB,EAAE,MAAqB;IAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,QAA0B,EAC1B,OAAgC;IAEhC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAqB,CAAC;IACnD,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAyB,EAAE,CAAC;IAC7C,MAAM,KAAK,GAAoC,EAAE,CAAC;IAElD,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,CAAC,EAAE,CAAC;QACzE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAE,CAAC;QACvC,MAAM,OAAO,GAAoB;YAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,SAAS;YACT,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU;YACvC,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW;SAC1C,CAAC;QAEF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC;YACpC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;SAC1B,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACvE,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QAExC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;YACtD,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK;QACL,aAAa,EAAE,aAAwD;QACvE,KAAK;QACL,WAAW;KACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,75 @@
1
+ export type JsonPrimitive = string | number | boolean | null;
2
+ export type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
3
+ export type JsonObject = {
4
+ [key: string]: JsonValue;
5
+ };
6
+ export type ResolverDiagnosticLevel = "info" | "warning" | "error";
7
+ export type ResolverDiagnostic = {
8
+ level: ResolverDiagnosticLevel;
9
+ code: string;
10
+ message: string;
11
+ details?: Record<string, unknown>;
12
+ };
13
+ export type ResolverStats = {
14
+ inputsScanned: number;
15
+ valuesParsed: number;
16
+ valuesRejected: number;
17
+ matchesFound: number;
18
+ ambiguousMatches: number;
19
+ [key: string]: number;
20
+ };
21
+ export type ResolverContext = {
22
+ resolverKey: string;
23
+ stepIndex: number;
24
+ /** Optional store for resolvers that need to read related records */
25
+ readRecord?: (ref: RecordRef) => Promise<JsonObject | null>;
26
+ scanRecords?: (ref: RecordRef, filter?: Record<string, unknown>) => AsyncIterable<JsonObject>;
27
+ };
28
+ export type RecordRef = {
29
+ db: string;
30
+ collection: string;
31
+ };
32
+ export type ResolverInput = {
33
+ record: JsonObject;
34
+ recordId?: string;
35
+ config: unknown;
36
+ };
37
+ export type ResolverOutputValue = {
38
+ path: string;
39
+ values: JsonValue[];
40
+ };
41
+ export type ResolverResult = {
42
+ outputs: ResolverOutputValue[];
43
+ stats: ResolverStats;
44
+ diagnostics: ResolverDiagnostic[];
45
+ };
46
+ export type Resolver = {
47
+ resolve(input: ResolverInput): Promise<ResolverResult>;
48
+ };
49
+ export type ResolverDefinition<TConfig = unknown> = {
50
+ type: string;
51
+ create(config: TConfig, context: ResolverContext): Resolver;
52
+ };
53
+ export type ResolverStep = {
54
+ type: string;
55
+ resolverKey: string;
56
+ config?: unknown;
57
+ };
58
+ export type ResolverStepResult = {
59
+ resolverKey: string;
60
+ type: string;
61
+ result: ResolverResult;
62
+ };
63
+ export type RunResolverStepsOptions = {
64
+ steps: ResolverStep[];
65
+ record: JsonObject;
66
+ recordId?: string;
67
+ context?: Partial<ResolverContext>;
68
+ };
69
+ export type RunResolverStepsResult = {
70
+ steps: ResolverStepResult[];
71
+ mergedOutputs: Map<string, JsonValue[]>;
72
+ stats: ResolverStats;
73
+ diagnostics: ResolverDiagnostic[];
74
+ };
75
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ import type { JsonValue } from "./types.js";
2
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
3
+ export declare function getByPath(obj: unknown, path: string): unknown;
4
+ export declare function setByPath(obj: Record<string, unknown>, path: string, value: unknown): void;
5
+ export declare function isMissingJoinValue(value: unknown): boolean;
6
+ export declare function normalizeJoinValues(value: unknown): JsonValue[];
7
+ export declare function isAssociatedPropertyName(name: string): boolean;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE9E;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAU7D;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAY1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,CAM/D;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D"}
package/dist/utils.js ADDED
@@ -0,0 +1,45 @@
1
+ export function isPlainObject(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ export function getByPath(obj, path) {
5
+ if (!path)
6
+ return obj;
7
+ const parts = path.split(".");
8
+ let current = obj;
9
+ for (const part of parts) {
10
+ if (current === undefined || current === null)
11
+ return undefined;
12
+ if (!isPlainObject(current) && !Array.isArray(current))
13
+ return undefined;
14
+ current = current[part];
15
+ }
16
+ return current;
17
+ }
18
+ export function setByPath(obj, path, value) {
19
+ const parts = path.split(".");
20
+ let current = obj;
21
+ for (let i = 0; i < parts.length - 1; i += 1) {
22
+ const part = parts[i];
23
+ const next = current[part];
24
+ if (!isPlainObject(next)) {
25
+ current[part] = {};
26
+ }
27
+ current = current[part];
28
+ }
29
+ current[parts[parts.length - 1]] = value;
30
+ }
31
+ export function isMissingJoinValue(value) {
32
+ return value === undefined || value === null || value === "";
33
+ }
34
+ export function normalizeJoinValues(value) {
35
+ if (isMissingJoinValue(value))
36
+ return [];
37
+ if (Array.isArray(value)) {
38
+ return value.flatMap((item) => normalizeJoinValues(item));
39
+ }
40
+ return [value];
41
+ }
42
+ export function isAssociatedPropertyName(name) {
43
+ return name.startsWith("associated");
44
+ }
45
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAY,EAAE,IAAY;IAClD,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC;IACtB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAY,GAAG,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QAChE,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAAE,OAAO,SAAS,CAAC;QACzE,OAAO,GAAI,OAAmC,CAAC,IAAI,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAA4B,EAAE,IAAY,EAAE,KAAc;IAClF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,OAAO,GAA4B,GAAG,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACrB,CAAC;QACD,OAAO,GAAG,OAAO,CAAC,IAAI,CAA4B,CAAC;IACrD,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,KAAkB,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,IAAI,kBAAkB,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5D,CAAC;IACD,OAAO,CAAC,KAAkB,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAAY;IACnD,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@x12i/memorix-resolvers",
3
+ "version": "1.0.0",
4
+ "description": "Pluggable resolver APIs for Memorix — normalize join keys, bridge lookups, and domain-specific relationship resolution",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "prebuild": "rm -rf dist",
20
+ "build": "tsc -p tsconfig.build.json",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "prepack": "npm run build"
24
+ },
25
+ "engines": {
26
+ "node": ">=18.0.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^20.14.0",
30
+ "typescript": "^5.6.0",
31
+ "vitest": "^2.1.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+ssh://git@github.com/x12i/memorix-mono-repo.git",
39
+ "directory": "memorix-resolvers"
40
+ },
41
+ "keywords": [
42
+ "memorix",
43
+ "resolvers",
44
+ "join",
45
+ "enrichment"
46
+ ],
47
+ "license": "exellix-license"
48
+ }