@xemahq/kernel-contracts 0.39.0 → 0.40.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/dist/connector/index.d.ts +1 -0
- package/dist/connector/index.d.ts.map +1 -1
- package/dist/connector/index.js +1 -0
- package/dist/connector/index.js.map +1 -1
- package/dist/connector/lib/canonical-operation-binding.d.ts +18 -0
- package/dist/connector/lib/canonical-operation-binding.d.ts.map +1 -0
- package/dist/connector/lib/canonical-operation-binding.js +76 -0
- package/dist/connector/lib/canonical-operation-binding.js.map +1 -0
- package/dist/connector/lib/connector-descriptor.d.ts +4 -0
- package/dist/connector/lib/connector-descriptor.d.ts.map +1 -1
- package/dist/connector/lib/connector-descriptor.js +12 -0
- package/dist/connector/lib/connector-descriptor.js.map +1 -1
- package/dist/connector/lib/integration-provider-contribution.d.ts +1 -0
- package/dist/connector/lib/integration-provider-contribution.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/connector/index.ts +1 -0
- package/src/connector/lib/canonical-operation-binding.ts +160 -0
- package/src/connector/lib/connector-descriptor.ts +29 -0
|
@@ -3,6 +3,7 @@ export * from './lib/connector-adapter-kind';
|
|
|
3
3
|
export * from './lib/connector-http-request';
|
|
4
4
|
export * from './lib/capability';
|
|
5
5
|
export * from './lib/credential-kind';
|
|
6
|
+
export * from './lib/canonical-operation-binding';
|
|
6
7
|
export * from './lib/credential-strategy-contribution';
|
|
7
8
|
export * from './lib/onboarding-manifest';
|
|
8
9
|
export * from './lib/provider-descriptor';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mCAAmC,CAAC;AAClD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC;AACtC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC"}
|
package/dist/connector/index.js
CHANGED
|
@@ -19,6 +19,7 @@ __exportStar(require("./lib/connector-adapter-kind"), exports);
|
|
|
19
19
|
__exportStar(require("./lib/connector-http-request"), exports);
|
|
20
20
|
__exportStar(require("./lib/capability"), exports);
|
|
21
21
|
__exportStar(require("./lib/credential-kind"), exports);
|
|
22
|
+
__exportStar(require("./lib/canonical-operation-binding"), exports);
|
|
22
23
|
__exportStar(require("./lib/credential-strategy-contribution"), exports);
|
|
23
24
|
__exportStar(require("./lib/onboarding-manifest"), exports);
|
|
24
25
|
__exportStar(require("./lib/provider-descriptor"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,+DAA6C;AAC7C,+DAA6C;AAC7C,mDAAiC;AACjC,wDAAsC;AACtC,yEAAuD;AACvD,4DAA0C;AAC1C,4DAA0C;AAC1C,wDAAsC;AACtC,6DAA2C;AAC3C,wDAAsC;AACtC,oDAAkC;AAClC,2DAAyC;AACzC,6DAA2C;AAC3C,0EAAwD"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connector/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,+DAA6C;AAC7C,+DAA6C;AAC7C,mDAAiC;AACjC,wDAAsC;AACtC,oEAAkD;AAClD,yEAAuD;AACvD,4DAA0C;AAC1C,4DAA0C;AAC1C,wDAAsC;AACtC,6DAA2C;AAC3C,wDAAsC;AACtC,oDAAkC;AAClC,2DAAyC;AACzC,6DAA2C;AAC3C,0EAAwD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type CanonicalObjectTypeRef } from '../../canonical-object/lib/canonical-object-type';
|
|
3
|
+
export declare enum CanonicalMappingDirection {
|
|
4
|
+
Read = "read",
|
|
5
|
+
Write = "write"
|
|
6
|
+
}
|
|
7
|
+
export declare const CanonicalMappingDirectionSchema: z.ZodEnum<typeof CanonicalMappingDirection>;
|
|
8
|
+
export interface CanonicalOperationBinding {
|
|
9
|
+
readonly objectType: CanonicalObjectTypeRef;
|
|
10
|
+
readonly direction: CanonicalMappingDirection;
|
|
11
|
+
readonly fieldMap?: Readonly<Record<string, string>>;
|
|
12
|
+
}
|
|
13
|
+
export declare const CanonicalOperationBindingSchema: z.ZodType<CanonicalOperationBinding>;
|
|
14
|
+
export declare function getByPath(source: unknown, path: string): unknown;
|
|
15
|
+
export declare function setByPath(target: Record<string, unknown>, path: string, value: unknown): void;
|
|
16
|
+
export declare function projectProviderToCanonical(providerRecord: unknown, fieldMap: Readonly<Record<string, string>>): Record<string, unknown>;
|
|
17
|
+
export declare function projectCanonicalToProvider(canonicalObject: Readonly<Record<string, unknown>>, fieldMap: Readonly<Record<string, string>>): Record<string, unknown>;
|
|
18
|
+
//# sourceMappingURL=canonical-operation-binding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-operation-binding.d.ts","sourceRoot":"","sources":["../../../src/connector/lib/canonical-operation-binding.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,kDAAkD,CAAC;AAG1D,oBAAY,yBAAyB;IAEnC,IAAI,SAAS;IAEb,KAAK,UAAU;CAChB;AAED,eAAO,MAAM,+BAA+B,6CAA0C,CAAC;AAqCvF,MAAM,WAAW,yBAAyB;IAExC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAE5C,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC;IAM9C,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD;AAED,eAAO,MAAM,+BAA+B,EAAE,CAAC,CAAC,OAAO,CAAC,yBAAyB,CAK1B,CAAC;AAGxD,wBAAgB,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAShE;AAGD,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACb,IAAI,CAYN;AAOD,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,OAAO,EACvB,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB;AAMD,wBAAgB,0BAA0B,CACxC,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAClD,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACzC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASzB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CanonicalOperationBindingSchema = exports.CanonicalMappingDirectionSchema = exports.CanonicalMappingDirection = void 0;
|
|
4
|
+
exports.getByPath = getByPath;
|
|
5
|
+
exports.setByPath = setByPath;
|
|
6
|
+
exports.projectProviderToCanonical = projectProviderToCanonical;
|
|
7
|
+
exports.projectCanonicalToProvider = projectCanonicalToProvider;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const canonical_object_type_1 = require("../../canonical-object/lib/canonical-object-type");
|
|
10
|
+
var CanonicalMappingDirection;
|
|
11
|
+
(function (CanonicalMappingDirection) {
|
|
12
|
+
CanonicalMappingDirection["Read"] = "read";
|
|
13
|
+
CanonicalMappingDirection["Write"] = "write";
|
|
14
|
+
})(CanonicalMappingDirection || (exports.CanonicalMappingDirection = CanonicalMappingDirection = {}));
|
|
15
|
+
exports.CanonicalMappingDirectionSchema = zod_1.z.nativeEnum(CanonicalMappingDirection);
|
|
16
|
+
const CANONICAL_FIELD_MAP_MAX = 100;
|
|
17
|
+
const CanonicalFieldMapSchema = zod_1.z
|
|
18
|
+
.record(zod_1.z
|
|
19
|
+
.string()
|
|
20
|
+
.min(1)
|
|
21
|
+
.max(200)
|
|
22
|
+
.regex(/^[A-Za-z][A-Za-z0-9_]*$/, 'canonical field name must be identifier-like'), zod_1.z
|
|
23
|
+
.string()
|
|
24
|
+
.min(1)
|
|
25
|
+
.max(400)
|
|
26
|
+
.regex(/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/, 'provider path must be a dot-path of identifier segments'))
|
|
27
|
+
.refine((m) => Object.keys(m).length <= CANONICAL_FIELD_MAP_MAX, `at most ${CANONICAL_FIELD_MAP_MAX} mapped fields`);
|
|
28
|
+
exports.CanonicalOperationBindingSchema = zod_1.z.strictObject({
|
|
29
|
+
objectType: canonical_object_type_1.CanonicalObjectTypeRefSchema,
|
|
30
|
+
direction: exports.CanonicalMappingDirectionSchema,
|
|
31
|
+
fieldMap: CanonicalFieldMapSchema.optional(),
|
|
32
|
+
});
|
|
33
|
+
function getByPath(source, path) {
|
|
34
|
+
let cursor = source;
|
|
35
|
+
for (const segment of path.split('.')) {
|
|
36
|
+
if (cursor === null || typeof cursor !== 'object') {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
cursor = cursor[segment];
|
|
40
|
+
}
|
|
41
|
+
return cursor;
|
|
42
|
+
}
|
|
43
|
+
function setByPath(target, path, value) {
|
|
44
|
+
const segments = path.split('.');
|
|
45
|
+
let cursor = target;
|
|
46
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
47
|
+
const key = segments[i];
|
|
48
|
+
const next = cursor[key];
|
|
49
|
+
if (next === null || typeof next !== 'object' || Array.isArray(next)) {
|
|
50
|
+
cursor[key] = {};
|
|
51
|
+
}
|
|
52
|
+
cursor = cursor[key];
|
|
53
|
+
}
|
|
54
|
+
cursor[segments[segments.length - 1]] = value;
|
|
55
|
+
}
|
|
56
|
+
function projectProviderToCanonical(providerRecord, fieldMap) {
|
|
57
|
+
const out = {};
|
|
58
|
+
for (const [canonicalField, providerPath] of Object.entries(fieldMap)) {
|
|
59
|
+
const value = getByPath(providerRecord, providerPath);
|
|
60
|
+
if (value !== undefined) {
|
|
61
|
+
out[canonicalField] = value;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
function projectCanonicalToProvider(canonicalObject, fieldMap) {
|
|
67
|
+
const out = {};
|
|
68
|
+
for (const [canonicalField, providerPath] of Object.entries(fieldMap)) {
|
|
69
|
+
const value = canonicalObject[canonicalField];
|
|
70
|
+
if (value !== undefined) {
|
|
71
|
+
setByPath(out, providerPath, value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=canonical-operation-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-operation-binding.js","sourceRoot":"","sources":["../../../src/connector/lib/canonical-operation-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { type CapabilityRef } from '../../capability';
|
|
3
|
+
import { type CanonicalOperationBinding } from './canonical-operation-binding';
|
|
3
4
|
import { type CredentialKindRef } from './credential-kind';
|
|
4
5
|
import { ConnectorAdapterKind } from './connector-adapter-kind';
|
|
5
6
|
import { type ConnectorHttpRequestTemplate } from './connector-http-request';
|
|
@@ -10,6 +11,7 @@ export interface ConnectorOperationDescriptor {
|
|
|
10
11
|
readonly scopes: readonly string[];
|
|
11
12
|
readonly requiresConnection: boolean;
|
|
12
13
|
readonly httpRequest?: ConnectorHttpRequestTemplate;
|
|
14
|
+
readonly canonical?: CanonicalOperationBinding;
|
|
13
15
|
}
|
|
14
16
|
export declare const ConnectorOperationDescriptorSchema: z.ZodObject<{
|
|
15
17
|
capabilityRef: z.ZodType<CapabilityRef, unknown, z.core.$ZodTypeInternals<CapabilityRef, unknown>>;
|
|
@@ -29,6 +31,7 @@ export declare const ConnectorOperationDescriptorSchema: z.ZodObject<{
|
|
|
29
31
|
queryParamName: z.ZodOptional<z.ZodString>;
|
|
30
32
|
}, z.core.$strict>;
|
|
31
33
|
}, z.core.$strict>>;
|
|
34
|
+
canonical: z.ZodOptional<z.ZodType<CanonicalOperationBinding, unknown, z.core.$ZodTypeInternals<CanonicalOperationBinding, unknown>>>;
|
|
32
35
|
}, z.core.$strict>;
|
|
33
36
|
export interface ConnectorDescriptor {
|
|
34
37
|
readonly connectorKey: string;
|
|
@@ -68,6 +71,7 @@ export declare const ConnectorDescriptorSchema: z.ZodObject<{
|
|
|
68
71
|
queryParamName: z.ZodOptional<z.ZodString>;
|
|
69
72
|
}, z.core.$strict>;
|
|
70
73
|
}, z.core.$strict>>;
|
|
74
|
+
canonical: z.ZodOptional<z.ZodType<CanonicalOperationBinding, unknown, z.core.$ZodTypeInternals<CanonicalOperationBinding, unknown>>>;
|
|
71
75
|
}, z.core.$strict>>>>;
|
|
72
76
|
}, z.core.$strict>;
|
|
73
77
|
type AssertExtends<T extends U, U> = T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector-descriptor.d.ts","sourceRoot":"","sources":["../../../src/connector/lib/connector-descriptor.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EAErB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkBrD,MAAM,WAAW,4BAA4B;IAO3C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAKtC,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAQ3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAQnC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IASrC,QAAQ,CAAC,WAAW,CAAC,EAAE,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"connector-descriptor.d.ts","sourceRoot":"","sources":["../../../src/connector/lib/connector-descriptor.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,oBAAoB,EAErB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkBrD,MAAM,WAAW,4BAA4B;IAO3C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAKtC,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC;IAQ3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAQnC,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IASrC,QAAQ,CAAC,WAAW,CAAC,EAAE,4BAA4B,CAAC;IASpD,QAAQ,CAAC,SAAS,CAAC,EAAE,yBAAyB,CAAC;CAChD;AAOD,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;kBA2C3C,CAAC;AASL,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAG1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAU7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAanC,QAAQ,CAAC,wBAAwB,EAAE,iBAAiB,CAAC;IAOrD,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IAQrC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,4BAA4B,EAAE,CAAC;CAC/D;AASD,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAUpC,CAAC;AAOH,KAAK,aAAa,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;AACvC,KAAK,uBAAuB,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,GAC5D,SAAS,uBAAuB,CAAC,CAAC,CAAC,EAAE,GACrC,CAAC,SAAS,MAAM,GACd;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAAE,GAC7D,CAAC,CAAC;AACR,MAAM,MAAM,+CAA+C,GAAG;IAC5D,aAAa,CACX,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,EAClD,uBAAuB,CAAC,4BAA4B,CAAC,CACtD;IACD,aAAa,CACX,4BAA4B,EAC5B,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CACnD;CACF,CAAC;AACF,MAAM,MAAM,sCAAsC,GAAG;IACnD,aAAa,CACX,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,EACzC,uBAAuB,CAAC,mBAAmB,CAAC,CAC7C;IACD,aAAa,CAAC,mBAAmB,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;CAC9E,CAAC"}
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ConnectorDescriptorSchema = exports.ConnectorOperationDescriptorSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const capability_1 = require("../../capability");
|
|
6
|
+
const canonical_operation_binding_1 = require("./canonical-operation-binding");
|
|
6
7
|
const credential_kind_1 = require("./credential-kind");
|
|
7
8
|
const connector_adapter_kind_1 = require("./connector-adapter-kind");
|
|
8
9
|
const connector_http_request_1 = require("./connector-http-request");
|
|
@@ -13,6 +14,7 @@ exports.ConnectorOperationDescriptorSchema = zod_1.z
|
|
|
13
14
|
scopes: zod_1.z.array(zod_1.z.string()).readonly(),
|
|
14
15
|
requiresConnection: zod_1.z.boolean(),
|
|
15
16
|
httpRequest: connector_http_request_1.ConnectorHttpRequestTemplateSchema.optional(),
|
|
17
|
+
canonical: canonical_operation_binding_1.CanonicalOperationBindingSchema.optional(),
|
|
16
18
|
})
|
|
17
19
|
.superRefine((op, ctx) => {
|
|
18
20
|
const isDeclarative = op.adapterKind === connector_adapter_kind_1.ConnectorAdapterKind.DeclarativeHttp;
|
|
@@ -31,6 +33,16 @@ exports.ConnectorOperationDescriptorSchema = zod_1.z
|
|
|
31
33
|
message: `httpRequest is only valid for adapterKind="declarative-http" (got "${op.adapterKind}").`,
|
|
32
34
|
});
|
|
33
35
|
}
|
|
36
|
+
if (isDeclarative &&
|
|
37
|
+
op.canonical !== undefined &&
|
|
38
|
+
op.canonical.fieldMap === undefined) {
|
|
39
|
+
ctx.addIssue({
|
|
40
|
+
code: 'custom',
|
|
41
|
+
path: ['canonical', 'fieldMap'],
|
|
42
|
+
message: 'A declarative-http operation bound to a canonical type MUST declare ' +
|
|
43
|
+
'canonical.fieldMap (there is no code path to map records).',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
34
46
|
});
|
|
35
47
|
exports.ConnectorDescriptorSchema = zod_1.z.strictObject({
|
|
36
48
|
connectorKey: zod_1.z.string().min(1),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector-descriptor.js","sourceRoot":"","sources":["../../../src/connector/lib/connector-descriptor.ts"],"names":[],"mappings":";;;AAoBA,6BAAwB;AAExB,iDAA2E;AAE3E,uDAG2B;AAC3B,qEAGkC;AAClC,qEAGkC;
|
|
1
|
+
{"version":3,"file":"connector-descriptor.js","sourceRoot":"","sources":["../../../src/connector/lib/connector-descriptor.ts"],"names":[],"mappings":";;;AAoBA,6BAAwB;AAExB,iDAA2E;AAE3E,+EAGuC;AACvC,uDAG2B;AAC3B,qEAGkC;AAClC,qEAGkC;AA0ErB,QAAA,kCAAkC,GAAG,OAAC;KAChD,YAAY,CAAC;IACZ,aAAa,EAAE,gCAAmB;IAClC,WAAW,EAAE,mDAA0B;IACvC,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,kBAAkB,EAAE,OAAC,CAAC,OAAO,EAAE;IAC/B,WAAW,EAAE,2DAAkC,CAAC,QAAQ,EAAE;IAC1D,SAAS,EAAE,6DAA+B,CAAC,QAAQ,EAAE;CACtD,CAAC;KACD,WAAW,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;IACvB,MAAM,aAAa,GACjB,EAAE,CAAC,WAAW,KAAK,6CAAoB,CAAC,eAAe,CAAC;IAC1D,IAAI,aAAa,IAAI,EAAE,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,aAAa,CAAC;YACrB,OAAO,EACL,qEAAqE;gBACrE,6CAA6C;SAChD,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACnD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,aAAa,CAAC;YACrB,OAAO,EAAE,sEAAsE,EAAE,CAAC,WAAW,KAAK;SACnG,CAAC,CAAC;IACL,CAAC;IAGD,IACE,aAAa;QACb,EAAE,CAAC,SAAS,KAAK,SAAS;QAC1B,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,SAAS,EACnC,CAAC;QACD,GAAG,CAAC,QAAQ,CAAC;YACX,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC;YAC/B,OAAO,EACL,sEAAsE;gBACtE,4DAA4D;SAC/D,CAAC,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAoEQ,QAAA,yBAAyB,GAAG,OAAC,CAAC,YAAY,CAAC;IACtD,YAAY,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3B,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,MAAM,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;IACtC,wBAAwB,EAAE,yCAAuB;IACjD,WAAW,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,UAAU,EAAE,OAAC,CAAC,KAAK,CAAC,0CAAkC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC9E,CAAC,CAAC"}
|
|
@@ -81,6 +81,7 @@ export declare const IntegrationProviderContributionManifestSchema: z.ZodObject<
|
|
|
81
81
|
queryParamName: z.ZodOptional<z.ZodString>;
|
|
82
82
|
}, z.core.$strict>;
|
|
83
83
|
}, z.core.$strict>>;
|
|
84
|
+
canonical: z.ZodOptional<z.ZodType<import("./canonical-operation-binding").CanonicalOperationBinding, unknown, z.core.$ZodTypeInternals<import("./canonical-operation-binding").CanonicalOperationBinding, unknown>>>;
|
|
84
85
|
}, z.core.$strict>>>>;
|
|
85
86
|
}, z.core.$strict>>>;
|
|
86
87
|
}, z.core.$strict>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-provider-contribution.d.ts","sourceRoot":"","sources":["../../../src/connector/lib/integration-provider-contribution.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AA0BhE,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;kBACK,CAAC;AAEtD,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CACjD,OAAO,mCAAmC,CAC3C,CAAC;AAQF,eAAO,MAAM,6CAA6C
|
|
1
|
+
{"version":3,"file":"integration-provider-contribution.d.ts","sourceRoot":"","sources":["../../../src/connector/lib/integration-provider-contribution.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AA0BhE,eAAO,MAAM,mCAAmC;;;;;;;;;;;;;;;;;;;;;;;;;kBACK,CAAC;AAEtD,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CACjD,OAAO,mCAAmC,CAC3C,CAAC;AAQF,eAAO,MAAM,6CAA6C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAqEtD,CAAC;AAEL,MAAM,MAAM,uCAAuC,GAAG,CAAC,CAAC,KAAK,CAC3D,OAAO,6CAA6C,CACrD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/kernel-contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"description": "Consolidated Xema OS kernel wire contracts — pure types + zod schemas for the kernel protocol surfaces. One package, one npm scope, wildcard per-surface subpath exports. No framework/runtime deps.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|
package/src/connector/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './lib/connector-adapter-kind';
|
|
|
3
3
|
export * from './lib/connector-http-request';
|
|
4
4
|
export * from './lib/capability';
|
|
5
5
|
export * from './lib/credential-kind';
|
|
6
|
+
export * from './lib/canonical-operation-binding';
|
|
6
7
|
export * from './lib/credential-strategy-contribution';
|
|
7
8
|
export * from './lib/onboarding-manifest';
|
|
8
9
|
export * from './lib/provider-descriptor';
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
3
|
+
* Canonical operation binding — the connector↔CDM mapping seam (B1b)
|
|
4
|
+
*
|
|
5
|
+
* A connector operation can BIND to a canonical business-object type (declared
|
|
6
|
+
* via `ContributionKind.CanonicalObjectType`) so the gateway maps between the
|
|
7
|
+
* provider's shape and the shared Common Data Model:
|
|
8
|
+
*
|
|
9
|
+
* - direction `read` — the operation FETCHES provider records; the gateway
|
|
10
|
+
* projects each provider record → a canonical object (provider → canonical).
|
|
11
|
+
* - direction `write` — the operation CREATES/UPDATES; the gateway projects
|
|
12
|
+
* the caller's canonical object → the provider payload (canonical → provider).
|
|
13
|
+
*
|
|
14
|
+
* For DECLARATIVE-HTTP operations (no code) the mapping is the declarative
|
|
15
|
+
* `fieldMap`: canonical-field → provider JSON dot-path. For NATIVE code modules
|
|
16
|
+
* the module's `toCanonical`/`fromCanonical` functions take precedence and the
|
|
17
|
+
* `fieldMap` is optional. This is the counterpart to the inbound `EventMapper`
|
|
18
|
+
* (raw event → canonical envelope): here it's raw record ↔ canonical object.
|
|
19
|
+
* ─────────────────────────────────────────────────────────────────────────
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { z } from 'zod';
|
|
23
|
+
|
|
24
|
+
import {
|
|
25
|
+
CanonicalObjectTypeRefSchema,
|
|
26
|
+
type CanonicalObjectTypeRef,
|
|
27
|
+
} from '../../canonical-object/lib/canonical-object-type';
|
|
28
|
+
|
|
29
|
+
/** Which way a bound operation maps between provider records and canonical objects. */
|
|
30
|
+
export enum CanonicalMappingDirection {
|
|
31
|
+
/** Operation reads provider records → gateway emits canonical objects. */
|
|
32
|
+
Read = 'read',
|
|
33
|
+
/** Operation writes; caller supplies a canonical object → gateway emits provider payload. */
|
|
34
|
+
Write = 'write',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const CanonicalMappingDirectionSchema = z.nativeEnum(CanonicalMappingDirection);
|
|
38
|
+
|
|
39
|
+
/** Cap on the number of mapped fields, keeping the binding small + bounded. */
|
|
40
|
+
const CANONICAL_FIELD_MAP_MAX = 100;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Declarative field mapping: canonical-object field-name → a dot-path into the
|
|
44
|
+
* provider record (read) or the provider payload (write). e.g.
|
|
45
|
+
* `{ "name": "attributes.customer_name", "amount": "value.total" }`.
|
|
46
|
+
* Dot segments address nested objects; bracket/array indexing is out of scope
|
|
47
|
+
* (deliberately — keep the DSL deterministic and small).
|
|
48
|
+
*/
|
|
49
|
+
const CanonicalFieldMapSchema = z
|
|
50
|
+
.record(
|
|
51
|
+
z
|
|
52
|
+
.string()
|
|
53
|
+
.min(1)
|
|
54
|
+
.max(200)
|
|
55
|
+
.regex(/^[A-Za-z][A-Za-z0-9_]*$/, 'canonical field name must be identifier-like'),
|
|
56
|
+
z
|
|
57
|
+
.string()
|
|
58
|
+
.min(1)
|
|
59
|
+
.max(400)
|
|
60
|
+
.regex(
|
|
61
|
+
/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/,
|
|
62
|
+
'provider path must be a dot-path of identifier segments',
|
|
63
|
+
),
|
|
64
|
+
)
|
|
65
|
+
.refine(
|
|
66
|
+
(m) => Object.keys(m).length <= CANONICAL_FIELD_MAP_MAX,
|
|
67
|
+
`at most ${CANONICAL_FIELD_MAP_MAX} mapped fields`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Binds a connector operation to a canonical object type + the mapping applied
|
|
72
|
+
* at the gateway seam.
|
|
73
|
+
*/
|
|
74
|
+
export interface CanonicalOperationBinding {
|
|
75
|
+
/** The canonical business-object type this operation reads or writes. */
|
|
76
|
+
readonly objectType: CanonicalObjectTypeRef;
|
|
77
|
+
/** Read (provider → canonical) or write (canonical → provider). */
|
|
78
|
+
readonly direction: CanonicalMappingDirection;
|
|
79
|
+
/**
|
|
80
|
+
* canonical-field → provider dot-path. REQUIRED for declarative-http
|
|
81
|
+
* operations (there is no code); OPTIONAL for native modules whose
|
|
82
|
+
* `toCanonical`/`fromCanonical` map instead.
|
|
83
|
+
*/
|
|
84
|
+
readonly fieldMap?: Readonly<Record<string, string>>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export const CanonicalOperationBindingSchema: z.ZodType<CanonicalOperationBinding> =
|
|
88
|
+
z.strictObject({
|
|
89
|
+
objectType: CanonicalObjectTypeRefSchema,
|
|
90
|
+
direction: CanonicalMappingDirectionSchema,
|
|
91
|
+
fieldMap: CanonicalFieldMapSchema.optional(),
|
|
92
|
+
}) as unknown as z.ZodType<CanonicalOperationBinding>;
|
|
93
|
+
|
|
94
|
+
/** Read a dot-path (`a.b.c`) out of a record; `undefined` if any segment is missing. */
|
|
95
|
+
export function getByPath(source: unknown, path: string): unknown {
|
|
96
|
+
let cursor: unknown = source;
|
|
97
|
+
for (const segment of path.split('.')) {
|
|
98
|
+
if (cursor === null || typeof cursor !== 'object') {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
cursor = (cursor as Record<string, unknown>)[segment];
|
|
102
|
+
}
|
|
103
|
+
return cursor;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Set a dot-path (`a.b.c`) on a plain object, creating intermediate objects. */
|
|
107
|
+
export function setByPath(
|
|
108
|
+
target: Record<string, unknown>,
|
|
109
|
+
path: string,
|
|
110
|
+
value: unknown,
|
|
111
|
+
): void {
|
|
112
|
+
const segments = path.split('.');
|
|
113
|
+
let cursor: Record<string, unknown> = target;
|
|
114
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
115
|
+
const key = segments[i]!;
|
|
116
|
+
const next = cursor[key];
|
|
117
|
+
if (next === null || typeof next !== 'object' || Array.isArray(next)) {
|
|
118
|
+
cursor[key] = {};
|
|
119
|
+
}
|
|
120
|
+
cursor = cursor[key] as Record<string, unknown>;
|
|
121
|
+
}
|
|
122
|
+
cursor[segments[segments.length - 1]!] = value;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Project a provider record into a canonical object using a `read` fieldMap.
|
|
127
|
+
* Deterministic + pure; a missing provider path yields an absent canonical
|
|
128
|
+
* field (never throws). Centralized so the gateway + any validator agree.
|
|
129
|
+
*/
|
|
130
|
+
export function projectProviderToCanonical(
|
|
131
|
+
providerRecord: unknown,
|
|
132
|
+
fieldMap: Readonly<Record<string, string>>,
|
|
133
|
+
): Record<string, unknown> {
|
|
134
|
+
const out: Record<string, unknown> = {};
|
|
135
|
+
for (const [canonicalField, providerPath] of Object.entries(fieldMap)) {
|
|
136
|
+
const value = getByPath(providerRecord, providerPath);
|
|
137
|
+
if (value !== undefined) {
|
|
138
|
+
out[canonicalField] = value;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Project a canonical object into a provider payload using a `write` fieldMap.
|
|
146
|
+
* Deterministic + pure; an absent canonical field is skipped.
|
|
147
|
+
*/
|
|
148
|
+
export function projectCanonicalToProvider(
|
|
149
|
+
canonicalObject: Readonly<Record<string, unknown>>,
|
|
150
|
+
fieldMap: Readonly<Record<string, string>>,
|
|
151
|
+
): Record<string, unknown> {
|
|
152
|
+
const out: Record<string, unknown> = {};
|
|
153
|
+
for (const [canonicalField, providerPath] of Object.entries(fieldMap)) {
|
|
154
|
+
const value = canonicalObject[canonicalField];
|
|
155
|
+
if (value !== undefined) {
|
|
156
|
+
setByPath(out, providerPath, value);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
@@ -22,6 +22,10 @@ import { z } from 'zod';
|
|
|
22
22
|
|
|
23
23
|
import { CapabilityRefSchema, type CapabilityRef } from '../../capability';
|
|
24
24
|
|
|
25
|
+
import {
|
|
26
|
+
CanonicalOperationBindingSchema,
|
|
27
|
+
type CanonicalOperationBinding,
|
|
28
|
+
} from './canonical-operation-binding';
|
|
25
29
|
import {
|
|
26
30
|
CredentialKindRefSchema,
|
|
27
31
|
type CredentialKindRef,
|
|
@@ -91,6 +95,15 @@ export interface ConnectorOperationDescriptor {
|
|
|
91
95
|
* fails fast at the contribution boundary.
|
|
92
96
|
*/
|
|
93
97
|
readonly httpRequest?: ConnectorHttpRequestTemplate;
|
|
98
|
+
/**
|
|
99
|
+
* Optional binding to a canonical business-object type (the CDM seam, B1b).
|
|
100
|
+
* When present, the gateway maps between the provider shape and the canonical
|
|
101
|
+
* object: `read` projects fetched provider records → canonical objects,
|
|
102
|
+
* `write` projects a caller's canonical object → the provider payload. A
|
|
103
|
+
* declarative-http operation with a binding MUST carry a `fieldMap` (there is
|
|
104
|
+
* no code to map); a native operation may omit it (its module maps).
|
|
105
|
+
*/
|
|
106
|
+
readonly canonical?: CanonicalOperationBinding;
|
|
94
107
|
}
|
|
95
108
|
|
|
96
109
|
/**
|
|
@@ -105,6 +118,7 @@ export const ConnectorOperationDescriptorSchema = z
|
|
|
105
118
|
scopes: z.array(z.string()).readonly(),
|
|
106
119
|
requiresConnection: z.boolean(),
|
|
107
120
|
httpRequest: ConnectorHttpRequestTemplateSchema.optional(),
|
|
121
|
+
canonical: CanonicalOperationBindingSchema.optional(),
|
|
108
122
|
})
|
|
109
123
|
.superRefine((op, ctx) => {
|
|
110
124
|
const isDeclarative =
|
|
@@ -125,6 +139,21 @@ export const ConnectorOperationDescriptorSchema = z
|
|
|
125
139
|
message: `httpRequest is only valid for adapterKind="declarative-http" (got "${op.adapterKind}").`,
|
|
126
140
|
});
|
|
127
141
|
}
|
|
142
|
+
// A declarative-http operation bound to a canonical type has no code to map
|
|
143
|
+
// with — it MUST carry a declarative fieldMap.
|
|
144
|
+
if (
|
|
145
|
+
isDeclarative &&
|
|
146
|
+
op.canonical !== undefined &&
|
|
147
|
+
op.canonical.fieldMap === undefined
|
|
148
|
+
) {
|
|
149
|
+
ctx.addIssue({
|
|
150
|
+
code: 'custom',
|
|
151
|
+
path: ['canonical', 'fieldMap'],
|
|
152
|
+
message:
|
|
153
|
+
'A declarative-http operation bound to a canonical type MUST declare ' +
|
|
154
|
+
'canonical.fieldMap (there is no code path to map records).',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
128
157
|
});
|
|
129
158
|
|
|
130
159
|
/**
|