@lobu/connector-sdk 6.0.1
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/api-paginated.d.ts +79 -0
- package/dist/api-paginated.d.ts.map +1 -0
- package/dist/api-paginated.js +120 -0
- package/dist/api-paginated.js.map +1 -0
- package/dist/base.d.ts +66 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +122 -0
- package/dist/base.js.map +1 -0
- package/dist/browser/acquire.d.ts +66 -0
- package/dist/browser/acquire.d.ts.map +1 -0
- package/dist/browser/acquire.js +109 -0
- package/dist/browser/acquire.js.map +1 -0
- package/dist/browser/cdp-page.d.ts +48 -0
- package/dist/browser/cdp-page.d.ts.map +1 -0
- package/dist/browser/cdp-page.js +165 -0
- package/dist/browser/cdp-page.js.map +1 -0
- package/dist/browser/cdp.d.ts +44 -0
- package/dist/browser/cdp.d.ts.map +1 -0
- package/dist/browser/cdp.js +252 -0
- package/dist/browser/cdp.js.map +1 -0
- package/dist/browser/launcher.d.ts +29 -0
- package/dist/browser/launcher.d.ts.map +1 -0
- package/dist/browser/launcher.js +157 -0
- package/dist/browser/launcher.js.map +1 -0
- package/dist/browser/stealth.d.ts +55 -0
- package/dist/browser/stealth.d.ts.map +1 -0
- package/dist/browser/stealth.js +170 -0
- package/dist/browser/stealth.js.map +1 -0
- package/dist/browser-network.d.ts +51 -0
- package/dist/browser-network.d.ts.map +1 -0
- package/dist/browser-network.js +175 -0
- package/dist/browser-network.js.map +1 -0
- package/dist/browser-paginated.d.ts +141 -0
- package/dist/browser-paginated.d.ts.map +1 -0
- package/dist/browser-paginated.js +269 -0
- package/dist/browser-paginated.js.map +1 -0
- package/dist/connector-runtime.d.ts +70 -0
- package/dist/connector-runtime.d.ts.map +1 -0
- package/dist/connector-runtime.js +48 -0
- package/dist/connector-runtime.js.map +1 -0
- package/dist/connector-types.d.ts +613 -0
- package/dist/connector-types.d.ts.map +1 -0
- package/dist/connector-types.js +27 -0
- package/dist/connector-types.js.map +1 -0
- package/dist/event-taxonomy.d.ts +3 -0
- package/dist/event-taxonomy.d.ts.map +1 -0
- package/dist/event-taxonomy.js +30 -0
- package/dist/event-taxonomy.js.map +1 -0
- package/dist/http.d.ts +18 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +74 -0
- package/dist/http.js.map +1 -0
- package/dist/identity-normalize.d.ts +53 -0
- package/dist/identity-normalize.d.ts.map +1 -0
- package/dist/identity-normalize.js +146 -0
- package/dist/identity-normalize.js.map +1 -0
- package/dist/identity-types.d.ts +214 -0
- package/dist/identity-types.d.ts.map +1 -0
- package/dist/identity-types.js +217 -0
- package/dist/identity-types.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +10 -0
- package/dist/logger.js.map +1 -0
- package/dist/paginated.d.ts +93 -0
- package/dist/paginated.d.ts.map +1 -0
- package/dist/paginated.js +167 -0
- package/dist/paginated.js.map +1 -0
- package/dist/reaction-sdk.d.ts +43 -0
- package/dist/reaction-sdk.d.ts.map +1 -0
- package/dist/reaction-sdk.js +9 -0
- package/dist/reaction-sdk.js.map +1 -0
- package/dist/retry.d.ts +19 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +131 -0
- package/dist/retry.js.map +1 -0
- package/dist/scoring.d.ts +17 -0
- package/dist/scoring.d.ts.map +1 -0
- package/dist/scoring.js +28 -0
- package/dist/scoring.js.map +1 -0
- package/dist/types.d.ts +280 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/watcher-time.d.ts +14 -0
- package/dist/watcher-time.d.ts.map +1 -0
- package/dist/watcher-time.js +112 -0
- package/dist/watcher-time.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const SOURCE_NATIVE_EVENT_TYPES = [
|
|
2
|
+
'article',
|
|
3
|
+
'ask_hn',
|
|
4
|
+
'comment',
|
|
5
|
+
'commit',
|
|
6
|
+
'discussion',
|
|
7
|
+
'email',
|
|
8
|
+
'file',
|
|
9
|
+
'issue',
|
|
10
|
+
'issue_comment',
|
|
11
|
+
'message',
|
|
12
|
+
'photo',
|
|
13
|
+
'post',
|
|
14
|
+
'pr_comment',
|
|
15
|
+
'pull_request',
|
|
16
|
+
'reply',
|
|
17
|
+
'repository',
|
|
18
|
+
'review',
|
|
19
|
+
'section',
|
|
20
|
+
'show_hn',
|
|
21
|
+
'story',
|
|
22
|
+
'thread',
|
|
23
|
+
'tweet',
|
|
24
|
+
'video',
|
|
25
|
+
];
|
|
26
|
+
const SOURCE_NATIVE_EVENT_TYPE_SET = new Set(SOURCE_NATIVE_EVENT_TYPES);
|
|
27
|
+
export function isSourceNativeEventType(value) {
|
|
28
|
+
return typeof value === 'string' && SOURCE_NATIVE_EVENT_TYPE_SET.has(value);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=event-taxonomy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-taxonomy.js","sourceRoot":"","sources":["../src/event-taxonomy.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,SAAS;IACT,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,MAAM;IACN,OAAO;IACP,eAAe;IACf,SAAS;IACT,OAAO;IACP,MAAM;IACN,YAAY;IACZ,cAAc;IACd,OAAO;IACP,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,SAAS;IACT,OAAO;IACP,QAAQ;IACR,OAAO;IACP,OAAO;CACC,CAAC;AAEX,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAS,yBAAyB,CAAC,CAAC;AAEhF,MAAM,UAAU,uBAAuB,CAAC,KAAgC;IACtE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,4BAA4B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type KyInstance, type Options } from 'ky';
|
|
2
|
+
/**
|
|
3
|
+
* Create a configured ky instance with custom options
|
|
4
|
+
*/
|
|
5
|
+
export declare function createHttpClient(options?: Options): KyInstance;
|
|
6
|
+
/**
|
|
7
|
+
* Default HTTP client for feeds with standard User-Agent
|
|
8
|
+
*/
|
|
9
|
+
export declare const httpClient: KyInstance;
|
|
10
|
+
/**
|
|
11
|
+
* Create an HTTP client with authentication headers
|
|
12
|
+
*/
|
|
13
|
+
export declare function createAuthenticatedClient(authHeader: string, additionalHeaders?: Record<string, string>): KyInstance;
|
|
14
|
+
/**
|
|
15
|
+
* HTTP client for JSON APIs
|
|
16
|
+
*/
|
|
17
|
+
export declare const jsonHttpClient: KyInstance;
|
|
18
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,IAAI,CAAC;AA8BvD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,UAAU,CAY9D;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,YAIrB,CAAC;AAEH;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,UAAU,CAQZ;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,YAMzB,CAAC"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import ky from 'ky';
|
|
2
|
+
/**
|
|
3
|
+
* Shared HTTP client configuration for all feeds
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default retry configuration
|
|
7
|
+
* - Max 2 retries (3 total attempts)
|
|
8
|
+
* - Only retry transient errors (429, 5xx)
|
|
9
|
+
* - Exponential backoff up to 5 seconds
|
|
10
|
+
* - 30s timeout per request
|
|
11
|
+
*/
|
|
12
|
+
const defaultRetryConfig = {
|
|
13
|
+
retry: {
|
|
14
|
+
limit: 2, // Max 2 retries (3 total attempts)
|
|
15
|
+
methods: ['get', 'post'],
|
|
16
|
+
statusCodes: [
|
|
17
|
+
408, // Request Timeout
|
|
18
|
+
429, // Too Many Requests (rate limit)
|
|
19
|
+
500, // Internal Server Error
|
|
20
|
+
502, // Bad Gateway
|
|
21
|
+
503, // Service Unavailable
|
|
22
|
+
504, // Gateway Timeout
|
|
23
|
+
],
|
|
24
|
+
backoffLimit: 5000, // Max 5 seconds delay between retries
|
|
25
|
+
},
|
|
26
|
+
timeout: 30000, // 30 second timeout per request
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Create a configured ky instance with custom options
|
|
30
|
+
*/
|
|
31
|
+
export function createHttpClient(options) {
|
|
32
|
+
return ky.create({
|
|
33
|
+
...defaultRetryConfig,
|
|
34
|
+
...options,
|
|
35
|
+
// Merge retry config if provided
|
|
36
|
+
retry: options?.retry
|
|
37
|
+
? {
|
|
38
|
+
...defaultRetryConfig.retry,
|
|
39
|
+
...(typeof options.retry === 'number' ? { limit: options.retry } : options.retry),
|
|
40
|
+
}
|
|
41
|
+
: defaultRetryConfig.retry,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Default HTTP client for feeds with standard User-Agent
|
|
46
|
+
*/
|
|
47
|
+
export const httpClient = createHttpClient({
|
|
48
|
+
headers: {
|
|
49
|
+
'User-Agent': 'UserResearchBot/1.0',
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
/**
|
|
53
|
+
* Create an HTTP client with authentication headers
|
|
54
|
+
*/
|
|
55
|
+
export function createAuthenticatedClient(authHeader, additionalHeaders) {
|
|
56
|
+
return createHttpClient({
|
|
57
|
+
headers: {
|
|
58
|
+
'User-Agent': 'UserResearchBot/1.0',
|
|
59
|
+
Authorization: authHeader,
|
|
60
|
+
...additionalHeaders,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* HTTP client for JSON APIs
|
|
66
|
+
*/
|
|
67
|
+
export const jsonHttpClient = createHttpClient({
|
|
68
|
+
headers: {
|
|
69
|
+
'User-Agent': 'UserResearchBot/1.0',
|
|
70
|
+
Accept: 'application/json',
|
|
71
|
+
'Content-Type': 'application/json',
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqC,MAAM,IAAI,CAAC;AAEvD;;GAEG;AAEH;;;;;;GAMG;AACH,MAAM,kBAAkB,GAAG;IACzB,KAAK,EAAE;QACL,KAAK,EAAE,CAAC,EAAE,mCAAmC;QAC7C,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC;QACxB,WAAW,EAAE;YACX,GAAG,EAAE,kBAAkB;YACvB,GAAG,EAAE,iCAAiC;YACtC,GAAG,EAAE,wBAAwB;YAC7B,GAAG,EAAE,cAAc;YACnB,GAAG,EAAE,sBAAsB;YAC3B,GAAG,EAAE,kBAAkB;SACxB;QACD,YAAY,EAAE,IAAI,EAAE,sCAAsC;KAC3D;IACD,OAAO,EAAE,KAAK,EAAE,gCAAgC;CACjD,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAiB;IAChD,OAAO,EAAE,CAAC,MAAM,CAAC;QACf,GAAG,kBAAkB;QACrB,GAAG,OAAO;QACV,iCAAiC;QACjC,KAAK,EAAE,OAAO,EAAE,KAAK;YACnB,CAAC,CAAC;gBACE,GAAG,kBAAkB,CAAC,KAAK;gBAC3B,GAAG,CAAC,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;aAClF;YACH,CAAC,CAAC,kBAAkB,CAAC,KAAK;KAC7B,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,gBAAgB,CAAC;IACzC,OAAO,EAAE;QACP,YAAY,EAAE,qBAAqB;KACpC;CACF,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAAkB,EAClB,iBAA0C;IAE1C,OAAO,gBAAgB,CAAC;QACtB,OAAO,EAAE;YACP,YAAY,EAAE,qBAAqB;YACnC,aAAa,EAAE,UAAU;YACzB,GAAG,iBAAiB;SACrB;KACF,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,gBAAgB,CAAC;IAC7C,OAAO,EAAE;QACP,YAAY,EAAE,qBAAqB;QACnC,MAAM,EAAE,kBAAkB;QAC1B,cAAc,EAAE,kBAAkB;KACnC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical normalization for identity values written to entity_identities.
|
|
3
|
+
*
|
|
4
|
+
* Connectors call these before emitting identifiers on events. The ingestion
|
|
5
|
+
* pipeline also re-runs normalization as a defensive pass, so mismatched
|
|
6
|
+
* connector behavior can't poison cross-channel matching.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Return the E.164-style digit string for a phone number, or null when the
|
|
10
|
+
* input doesn't look like a phone. Strips all non-digit characters (including
|
|
11
|
+
* the leading `+`); does not attempt country-code inference.
|
|
12
|
+
*
|
|
13
|
+
* Connectors should pass in values that already represent a specific E.164
|
|
14
|
+
* number. The normalizer's job is cleanup (spaces, dashes, parens, `+`),
|
|
15
|
+
* not country-code guessing.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizePhone(raw: string | null | undefined): string | null;
|
|
18
|
+
export declare function normalizeEmail(raw: string | null | undefined): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* WhatsApp JIDs carry one of these suffixes:
|
|
21
|
+
* @s.whatsapp.net — individual, backed by an e164 phone
|
|
22
|
+
* @lid — privacy-protected individual (no phone)
|
|
23
|
+
* @g.us — group chat
|
|
24
|
+
* @broadcast — broadcast list
|
|
25
|
+
* @newsletter — channel / newsletter
|
|
26
|
+
*
|
|
27
|
+
* Multi-device messages arrive with a device suffix: `14155551234:5@s.whatsapp.net`.
|
|
28
|
+
* We strip it so the same person on phone + linked devices collapses to one
|
|
29
|
+
* identity. We lowercase, trim, and validate shape; invalid inputs return null.
|
|
30
|
+
* This is a *cleanup* function, not a person-vs-non-person filter — callers
|
|
31
|
+
* decide whether a normalized wa_jid is appropriate to use as a member identity.
|
|
32
|
+
*/
|
|
33
|
+
export declare function normalizeWaJid(raw: string | null | undefined): string | null;
|
|
34
|
+
/**
|
|
35
|
+
* Slack user IDs aren't globally unique — two workspaces can both have
|
|
36
|
+
* `U12345`. Prefix with the workspace (team) id so identities don't bleed
|
|
37
|
+
* across orgs: `T0XYZ:U12345`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function normalizeSlackUserId(teamId: string | null | undefined, userId: string | null | undefined): string | null;
|
|
40
|
+
export declare function normalizeGithubLogin(raw: string | null | undefined): string | null;
|
|
41
|
+
export declare function normalizeGoogleContactId(raw: string | null | undefined): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Normalize `auth_user_id` (Better Auth user id). Trim + lowercase so the
|
|
44
|
+
* same user id from different clients collapses consistently.
|
|
45
|
+
*/
|
|
46
|
+
export declare function normalizeAuthUserId(raw: string | null | undefined): string | null;
|
|
47
|
+
/**
|
|
48
|
+
* Look up the normalizer for a given namespace. Returns a noop-trimmer when
|
|
49
|
+
* the namespace is unknown so custom connector namespaces still get basic
|
|
50
|
+
* hygiene without special-casing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function normalizeIdentifier(namespace: string, raw: string | null | undefined): string | null;
|
|
53
|
+
//# sourceMappingURL=identity-normalize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-normalize.d.ts","sourceRoot":"","sources":["../src/identity-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAK5E;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAa5E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAS5E;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAChC,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAMlF;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKtF;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAKjF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC7B,MAAM,GAAG,IAAI,CAoBf"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical normalization for identity values written to entity_identities.
|
|
3
|
+
*
|
|
4
|
+
* Connectors call these before emitting identifiers on events. The ingestion
|
|
5
|
+
* pipeline also re-runs normalization as a defensive pass, so mismatched
|
|
6
|
+
* connector behavior can't poison cross-channel matching.
|
|
7
|
+
*/
|
|
8
|
+
const PHONE_MIN_DIGITS = 7;
|
|
9
|
+
const PHONE_MAX_DIGITS = 15;
|
|
10
|
+
/**
|
|
11
|
+
* Return the E.164-style digit string for a phone number, or null when the
|
|
12
|
+
* input doesn't look like a phone. Strips all non-digit characters (including
|
|
13
|
+
* the leading `+`); does not attempt country-code inference.
|
|
14
|
+
*
|
|
15
|
+
* Connectors should pass in values that already represent a specific E.164
|
|
16
|
+
* number. The normalizer's job is cleanup (spaces, dashes, parens, `+`),
|
|
17
|
+
* not country-code guessing.
|
|
18
|
+
*/
|
|
19
|
+
export function normalizePhone(raw) {
|
|
20
|
+
if (typeof raw !== 'string')
|
|
21
|
+
return null;
|
|
22
|
+
const digits = raw.replace(/\D+/g, '');
|
|
23
|
+
if (digits.length < PHONE_MIN_DIGITS || digits.length > PHONE_MAX_DIGITS)
|
|
24
|
+
return null;
|
|
25
|
+
return digits;
|
|
26
|
+
}
|
|
27
|
+
export function normalizeEmail(raw) {
|
|
28
|
+
if (typeof raw !== 'string')
|
|
29
|
+
return null;
|
|
30
|
+
const trimmed = raw.trim().toLowerCase();
|
|
31
|
+
if (!trimmed)
|
|
32
|
+
return null;
|
|
33
|
+
const atIndex = trimmed.indexOf('@');
|
|
34
|
+
if (atIndex <= 0 || atIndex === trimmed.length - 1)
|
|
35
|
+
return null;
|
|
36
|
+
if (trimmed.indexOf('@', atIndex + 1) !== -1)
|
|
37
|
+
return null;
|
|
38
|
+
const local = trimmed.slice(0, atIndex);
|
|
39
|
+
const domain = trimmed.slice(atIndex + 1);
|
|
40
|
+
if (!local || !domain)
|
|
41
|
+
return null;
|
|
42
|
+
if (domain.indexOf('.') === -1)
|
|
43
|
+
return null;
|
|
44
|
+
if (/\s/.test(trimmed))
|
|
45
|
+
return null;
|
|
46
|
+
return trimmed;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* WhatsApp JIDs carry one of these suffixes:
|
|
50
|
+
* @s.whatsapp.net — individual, backed by an e164 phone
|
|
51
|
+
* @lid — privacy-protected individual (no phone)
|
|
52
|
+
* @g.us — group chat
|
|
53
|
+
* @broadcast — broadcast list
|
|
54
|
+
* @newsletter — channel / newsletter
|
|
55
|
+
*
|
|
56
|
+
* Multi-device messages arrive with a device suffix: `14155551234:5@s.whatsapp.net`.
|
|
57
|
+
* We strip it so the same person on phone + linked devices collapses to one
|
|
58
|
+
* identity. We lowercase, trim, and validate shape; invalid inputs return null.
|
|
59
|
+
* This is a *cleanup* function, not a person-vs-non-person filter — callers
|
|
60
|
+
* decide whether a normalized wa_jid is appropriate to use as a member identity.
|
|
61
|
+
*/
|
|
62
|
+
export function normalizeWaJid(raw) {
|
|
63
|
+
if (typeof raw !== 'string')
|
|
64
|
+
return null;
|
|
65
|
+
const trimmed = raw.trim().toLowerCase();
|
|
66
|
+
if (!trimmed)
|
|
67
|
+
return null;
|
|
68
|
+
const match = trimmed.match(/^([a-z0-9._-]+)(?::\d+)?@(s\.whatsapp\.net|lid|g\.us|broadcast|newsletter)$/i);
|
|
69
|
+
if (!match)
|
|
70
|
+
return null;
|
|
71
|
+
return `${match[1]}@${match[2]}`;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Slack user IDs aren't globally unique — two workspaces can both have
|
|
75
|
+
* `U12345`. Prefix with the workspace (team) id so identities don't bleed
|
|
76
|
+
* across orgs: `T0XYZ:U12345`.
|
|
77
|
+
*/
|
|
78
|
+
export function normalizeSlackUserId(teamId, userId) {
|
|
79
|
+
if (typeof teamId !== 'string' || typeof userId !== 'string')
|
|
80
|
+
return null;
|
|
81
|
+
const t = teamId.trim();
|
|
82
|
+
const u = userId.trim();
|
|
83
|
+
if (!t || !u)
|
|
84
|
+
return null;
|
|
85
|
+
if (!/^[a-z0-9_-]+$/i.test(t) || !/^[a-z0-9_-]+$/i.test(u))
|
|
86
|
+
return null;
|
|
87
|
+
return `${t}:${u}`.toUpperCase();
|
|
88
|
+
}
|
|
89
|
+
export function normalizeGithubLogin(raw) {
|
|
90
|
+
if (typeof raw !== 'string')
|
|
91
|
+
return null;
|
|
92
|
+
const trimmed = raw.trim().toLowerCase();
|
|
93
|
+
if (!trimmed)
|
|
94
|
+
return null;
|
|
95
|
+
if (!/^[a-z0-9](?:[a-z0-9]|-(?=[a-z0-9])){0,38}$/.test(trimmed))
|
|
96
|
+
return null;
|
|
97
|
+
return trimmed;
|
|
98
|
+
}
|
|
99
|
+
export function normalizeGoogleContactId(raw) {
|
|
100
|
+
if (typeof raw !== 'string')
|
|
101
|
+
return null;
|
|
102
|
+
const trimmed = raw.trim();
|
|
103
|
+
if (!trimmed)
|
|
104
|
+
return null;
|
|
105
|
+
return trimmed;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Normalize `auth_user_id` (Better Auth user id). Trim + lowercase so the
|
|
109
|
+
* same user id from different clients collapses consistently.
|
|
110
|
+
*/
|
|
111
|
+
export function normalizeAuthUserId(raw) {
|
|
112
|
+
if (typeof raw !== 'string')
|
|
113
|
+
return null;
|
|
114
|
+
const trimmed = raw.trim();
|
|
115
|
+
if (!trimmed)
|
|
116
|
+
return null;
|
|
117
|
+
return trimmed;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Look up the normalizer for a given namespace. Returns a noop-trimmer when
|
|
121
|
+
* the namespace is unknown so custom connector namespaces still get basic
|
|
122
|
+
* hygiene without special-casing.
|
|
123
|
+
*/
|
|
124
|
+
export function normalizeIdentifier(namespace, raw) {
|
|
125
|
+
switch (namespace) {
|
|
126
|
+
case 'phone':
|
|
127
|
+
return normalizePhone(raw);
|
|
128
|
+
case 'email':
|
|
129
|
+
return normalizeEmail(raw);
|
|
130
|
+
case 'wa_jid':
|
|
131
|
+
return normalizeWaJid(raw);
|
|
132
|
+
case 'github_login':
|
|
133
|
+
return normalizeGithubLogin(raw);
|
|
134
|
+
case 'google_contact_id':
|
|
135
|
+
return normalizeGoogleContactId(raw);
|
|
136
|
+
case 'auth_user_id':
|
|
137
|
+
return normalizeAuthUserId(raw);
|
|
138
|
+
default: {
|
|
139
|
+
if (typeof raw !== 'string')
|
|
140
|
+
return null;
|
|
141
|
+
const trimmed = raw.trim();
|
|
142
|
+
return trimmed ? trimmed : null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=identity-normalize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-normalize.js","sourceRoot":"","sources":["../src/identity-normalize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,UAAU,cAAc,CAAC,GAA8B;IAC3D,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB,IAAI,MAAM,CAAC,MAAM,GAAG,gBAAgB;QAAE,OAAO,IAAI,CAAC;IACtF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAA8B;IAC3D,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,KAAK,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAChE,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IAC1C,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,cAAc,CAAC,GAA8B;IAC3D,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CACzB,8EAA8E,CAC/E,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACnC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAiC,EACjC,MAAiC;IAEjC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC1E,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IACxB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAA8B;IACjE,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC,4CAA4C,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAA8B;IACrE,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAA8B;IAChE,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAiB,EACjB,GAA8B;IAE9B,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,OAAO;YACV,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,OAAO;YACV,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,QAAQ;YACX,OAAO,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7B,KAAK,cAAc;YACjB,OAAO,oBAAoB,CAAC,GAAG,CAAC,CAAC;QACnC,KAAK,mBAAmB;YACtB,OAAO,wBAAwB,CAAC,GAAG,CAAC,CAAC;QACvC,KAAK,cAAc;YACjB,OAAO,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAClC,OAAO,CAAC,CAAC,CAAC;YACR,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACzC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;QAClC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity-engine SDK contracts.
|
|
3
|
+
*
|
|
4
|
+
* Connectors emit `ConnectorFact[]` for the authenticated subject; catalog
|
|
5
|
+
* YAMLs declare `AutoCreateWhenRule[]` on relationship types; the engine
|
|
6
|
+
* matches facts against rules and writes derivations.
|
|
7
|
+
*
|
|
8
|
+
* Schemas are TypeBox so they double as runtime validators at every write
|
|
9
|
+
* boundary (seeder, engine, MCP tools). Validation is mandatory — the
|
|
10
|
+
* collapsed model puts a lot in `metadata jsonb`, so without validation the
|
|
11
|
+
* engine silently corrupts on malformed input.
|
|
12
|
+
*/
|
|
13
|
+
import { type Static } from '@sinclair/typebox';
|
|
14
|
+
/**
|
|
15
|
+
* How strongly the connector vouches for a fact. Rules require a minimum
|
|
16
|
+
* assurance to fire. The order is total: `oauth_verified_admin_role` >
|
|
17
|
+
* `oauth_verified` > `cookie_session` > `self_attested`.
|
|
18
|
+
*/
|
|
19
|
+
export declare const AssuranceLevel: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
20
|
+
export type AssuranceLevel = Static<typeof AssuranceLevel>;
|
|
21
|
+
export declare function assuranceMeets(actual: AssuranceLevel, required: AssuranceLevel): boolean;
|
|
22
|
+
export declare const ConnectorFact: import("@sinclair/typebox").TObject<{
|
|
23
|
+
/** The attribute kind. Each connector declares which namespaces it produces. */
|
|
24
|
+
namespace: import("@sinclair/typebox").TString;
|
|
25
|
+
/** Raw value as the provider returned it. Audit-friendly. */
|
|
26
|
+
identifier: import("@sinclair/typebox").TString;
|
|
27
|
+
/**
|
|
28
|
+
* Canonicalised form used for index lookups. Connectors run normalize* on
|
|
29
|
+
* the value before emitting; the engine re-normalises defensively.
|
|
30
|
+
*/
|
|
31
|
+
normalizedValue: import("@sinclair/typebox").TString;
|
|
32
|
+
/** How the connector verified this fact. */
|
|
33
|
+
assurance: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
34
|
+
/**
|
|
35
|
+
* Provider's immutable account identifier — the primary binding key
|
|
36
|
+
* that survives email changes and account-row reissues.
|
|
37
|
+
*/
|
|
38
|
+
providerStableId: import("@sinclair/typebox").TString;
|
|
39
|
+
/**
|
|
40
|
+
* Which connector account row produced this fact. Lets the engine diff
|
|
41
|
+
* facts per session for revocation.
|
|
42
|
+
*/
|
|
43
|
+
sourceAccountId: import("@sinclair/typebox").TString;
|
|
44
|
+
/** ISO-8601 timestamp. Optional; required for high-assurance facts in production. */
|
|
45
|
+
validTo: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
46
|
+
/**
|
|
47
|
+
* Optional human-readable note about trust caveats this fact carries.
|
|
48
|
+
* Surfaced in audit logs and admin UIs; never used by the engine.
|
|
49
|
+
*/
|
|
50
|
+
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
51
|
+
}>;
|
|
52
|
+
export type ConnectorFact = Static<typeof ConnectorFact>;
|
|
53
|
+
/**
|
|
54
|
+
* Each connector exports a static capability declaration. CI lints that the
|
|
55
|
+
* namespaces it actually emits at runtime are a subset of `produces`.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ConnectorIdentityCapability: import("@sinclair/typebox").TObject<{
|
|
58
|
+
connectorKey: import("@sinclair/typebox").TString;
|
|
59
|
+
produces: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
60
|
+
namespace: import("@sinclair/typebox").TString;
|
|
61
|
+
assurance: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
62
|
+
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
63
|
+
}>>;
|
|
64
|
+
}>;
|
|
65
|
+
export type ConnectorIdentityCapability = Static<typeof ConnectorIdentityCapability>;
|
|
66
|
+
/**
|
|
67
|
+
* `unique_only` rejects ambiguity (writes a collision event for admin
|
|
68
|
+
* resolution); `all_matches` fans out to every match and is only safe for
|
|
69
|
+
* weak relationships. `first_match` is deliberately excluded — silently
|
|
70
|
+
* picking a winner on collision would open adoption-takeover paths.
|
|
71
|
+
*/
|
|
72
|
+
export declare const MatchStrategy: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"unique_only">, import("@sinclair/typebox").TLiteral<"all_matches">]>;
|
|
73
|
+
export type MatchStrategy = Static<typeof MatchStrategy>;
|
|
74
|
+
export declare const AutoCreateWhenRule: import("@sinclair/typebox").TObject<{
|
|
75
|
+
/** The fact namespace this rule listens for. */
|
|
76
|
+
sourceNamespace: import("@sinclair/typebox").TString;
|
|
77
|
+
/**
|
|
78
|
+
* The metadata field on the target entity-type whose normalized value
|
|
79
|
+
* must equal the fact's normalizedValue.
|
|
80
|
+
*/
|
|
81
|
+
targetField: import("@sinclair/typebox").TString;
|
|
82
|
+
/**
|
|
83
|
+
* Minimum assurance the fact must carry to fire this rule. The engine
|
|
84
|
+
* enforces `assuranceMeets(fact.assurance, rule.assuranceRequired)`.
|
|
85
|
+
*/
|
|
86
|
+
assuranceRequired: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
87
|
+
matchStrategy: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"unique_only">, import("@sinclair/typebox").TLiteral<"all_matches">]>;
|
|
88
|
+
/**
|
|
89
|
+
* Optional notes for review tooling — not consumed by the engine.
|
|
90
|
+
*/
|
|
91
|
+
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
92
|
+
}>;
|
|
93
|
+
export type AutoCreateWhenRule = Static<typeof AutoCreateWhenRule>;
|
|
94
|
+
/**
|
|
95
|
+
* The shape stored on `entity_relationship_types.metadata`. Includes the
|
|
96
|
+
* declared rules plus a version+hash so derivations can pin to the rule
|
|
97
|
+
* version that fired them and reconciliation can detect drift.
|
|
98
|
+
*/
|
|
99
|
+
export declare const RelationshipTypeIdentityMetadata: import("@sinclair/typebox").TObject<{
|
|
100
|
+
autoCreateWhen: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TObject<{
|
|
101
|
+
/** The fact namespace this rule listens for. */
|
|
102
|
+
sourceNamespace: import("@sinclair/typebox").TString;
|
|
103
|
+
/**
|
|
104
|
+
* The metadata field on the target entity-type whose normalized value
|
|
105
|
+
* must equal the fact's normalizedValue.
|
|
106
|
+
*/
|
|
107
|
+
targetField: import("@sinclair/typebox").TString;
|
|
108
|
+
/**
|
|
109
|
+
* Minimum assurance the fact must carry to fire this rule. The engine
|
|
110
|
+
* enforces `assuranceMeets(fact.assurance, rule.assuranceRequired)`.
|
|
111
|
+
*/
|
|
112
|
+
assuranceRequired: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
113
|
+
matchStrategy: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"unique_only">, import("@sinclair/typebox").TLiteral<"all_matches">]>;
|
|
114
|
+
/**
|
|
115
|
+
* Optional notes for review tooling — not consumed by the engine.
|
|
116
|
+
*/
|
|
117
|
+
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
118
|
+
}>>;
|
|
119
|
+
/** Monotonically increasing per relationship-type. Bumped by the seeder on every YAML change. */
|
|
120
|
+
ruleVersion: import("@sinclair/typebox").TInteger;
|
|
121
|
+
/** sha256 of the canonicalised auto_create_when array. Drift detection. */
|
|
122
|
+
ruleHash: import("@sinclair/typebox").TString;
|
|
123
|
+
}>;
|
|
124
|
+
export type RelationshipTypeIdentityMetadata = Static<typeof RelationshipTypeIdentityMetadata>;
|
|
125
|
+
/**
|
|
126
|
+
* Stored on `events.metadata` for `semantic_type='identity_fact'` rows.
|
|
127
|
+
*
|
|
128
|
+
* Tombstone facts (written when a connector refresh stops emitting a
|
|
129
|
+
* namespace) carry empty `identifier`/`normalizedValue`/`providerStableId`,
|
|
130
|
+
* which is why those fields allow empty strings here even though
|
|
131
|
+
* `ConnectorFact` (the connector-side input) requires non-empty.
|
|
132
|
+
*/
|
|
133
|
+
export declare const FactEventMetadata: import("@sinclair/typebox").TObject<{
|
|
134
|
+
namespace: import("@sinclair/typebox").TString;
|
|
135
|
+
identifier: import("@sinclair/typebox").TString;
|
|
136
|
+
normalizedValue: import("@sinclair/typebox").TString;
|
|
137
|
+
assurance: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
138
|
+
providerStableId: import("@sinclair/typebox").TString;
|
|
139
|
+
sourceAccountId: import("@sinclair/typebox").TString;
|
|
140
|
+
/** ISO-8601 timestamp string. Optional; required for high-assurance facts in production. */
|
|
141
|
+
validTo: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
142
|
+
notes: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
|
|
143
|
+
}>;
|
|
144
|
+
export type FactEventMetadata = Static<typeof FactEventMetadata>;
|
|
145
|
+
export declare const DerivedFromProvenance: import("@sinclair/typebox").TObject<{
|
|
146
|
+
/** events.id of the fact that produced this derivation. */
|
|
147
|
+
sourceEventId: import("@sinclair/typebox").TInteger;
|
|
148
|
+
/** Which relationship-type rule fired (entity_relationship_types.id). */
|
|
149
|
+
relationshipTypeId: import("@sinclair/typebox").TInteger;
|
|
150
|
+
/** Snapshot of the rule version that fired. Drift signal for reconcile. */
|
|
151
|
+
ruleVersion: import("@sinclair/typebox").TInteger;
|
|
152
|
+
/** Hash matching ruleHash on the relationship-type at fire time. */
|
|
153
|
+
ruleHash: import("@sinclair/typebox").TString;
|
|
154
|
+
/** Echoed for fast assurance audits without joining back to the event. */
|
|
155
|
+
factAssurance: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
156
|
+
/** ISO-8601 timestamp. Echoes events.created_at; convenience for relationship-only audits. */
|
|
157
|
+
derivedAt: import("@sinclair/typebox").TString;
|
|
158
|
+
}>;
|
|
159
|
+
export type DerivedFromProvenance = Static<typeof DerivedFromProvenance>;
|
|
160
|
+
/**
|
|
161
|
+
* The metadata blob stored on entity_relationships.metadata for derived
|
|
162
|
+
* rows. Closed shape — extra keys are rejected so the engine can never
|
|
163
|
+
* accidentally land junk alongside the provenance.
|
|
164
|
+
*/
|
|
165
|
+
export declare const DerivedRelationshipMetadata: import("@sinclair/typebox").TObject<{
|
|
166
|
+
derivedFrom: import("@sinclair/typebox").TObject<{
|
|
167
|
+
/** events.id of the fact that produced this derivation. */
|
|
168
|
+
sourceEventId: import("@sinclair/typebox").TInteger;
|
|
169
|
+
/** Which relationship-type rule fired (entity_relationship_types.id). */
|
|
170
|
+
relationshipTypeId: import("@sinclair/typebox").TInteger;
|
|
171
|
+
/** Snapshot of the rule version that fired. Drift signal for reconcile. */
|
|
172
|
+
ruleVersion: import("@sinclair/typebox").TInteger;
|
|
173
|
+
/** Hash matching ruleHash on the relationship-type at fire time. */
|
|
174
|
+
ruleHash: import("@sinclair/typebox").TString;
|
|
175
|
+
/** Echoed for fast assurance audits without joining back to the event. */
|
|
176
|
+
factAssurance: import("@sinclair/typebox").TUnion<[import("@sinclair/typebox").TLiteral<"oauth_verified_admin_role">, import("@sinclair/typebox").TLiteral<"oauth_verified">, import("@sinclair/typebox").TLiteral<"cookie_session">, import("@sinclair/typebox").TLiteral<"self_attested">]>;
|
|
177
|
+
/** ISO-8601 timestamp. Echoes events.created_at; convenience for relationship-only audits. */
|
|
178
|
+
derivedAt: import("@sinclair/typebox").TString;
|
|
179
|
+
}>;
|
|
180
|
+
}>;
|
|
181
|
+
export type DerivedRelationshipMetadata = Static<typeof DerivedRelationshipMetadata>;
|
|
182
|
+
/**
|
|
183
|
+
* When a fact match would adopt a `$member` row that's already bound to a
|
|
184
|
+
* different user (or vice versa), the engine writes a pending-approval event
|
|
185
|
+
* with this shape. Resolution = a privileged user flips
|
|
186
|
+
* `interaction_status='approved'` after merging entities, or 'rejected' to
|
|
187
|
+
* dismiss without action.
|
|
188
|
+
*/
|
|
189
|
+
export declare const ClaimCollisionPayload: import("@sinclair/typebox").TObject<{
|
|
190
|
+
kind: import("@sinclair/typebox").TLiteral<"identity_match">;
|
|
191
|
+
namespace: import("@sinclair/typebox").TString;
|
|
192
|
+
identifier: import("@sinclair/typebox").TString;
|
|
193
|
+
normalizedValue: import("@sinclair/typebox").TString;
|
|
194
|
+
/**
|
|
195
|
+
* Catalog entity ids that all match this fact's normalized value.
|
|
196
|
+
* Despite the historical name suggesting `$member`, these are general
|
|
197
|
+
* catalog entities (founders, companies, etc.) — the resolver picks
|
|
198
|
+
* which one the user intends to claim.
|
|
199
|
+
*/
|
|
200
|
+
candidateEntityIds: import("@sinclair/typebox").TArray<import("@sinclair/typebox").TInteger>;
|
|
201
|
+
/** Total number of matching candidates; candidateEntityIds may be capped for UI payload size. */
|
|
202
|
+
candidateCount: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
203
|
+
/**
|
|
204
|
+
* Which fact (events.id) raised the collision. Lets the resolver replay
|
|
205
|
+
* the binding once the human picks a winner.
|
|
206
|
+
*/
|
|
207
|
+
triggeringEventId: import("@sinclair/typebox").TInteger;
|
|
208
|
+
/** Rule that would have fired if the match were unambiguous. */
|
|
209
|
+
relationshipTypeId: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TInteger>;
|
|
210
|
+
}>;
|
|
211
|
+
export type ClaimCollisionPayload = Static<typeof ClaimCollisionPayload>;
|
|
212
|
+
export declare const IDENTITY_FACT_SEMANTIC_TYPE: "identity_fact";
|
|
213
|
+
export declare const CLAIM_COLLISION_SEMANTIC_TYPE: "claim_collision";
|
|
214
|
+
//# sourceMappingURL=identity-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity-types.d.ts","sourceRoot":"","sources":["../src/identity-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAQ,KAAK,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAMtD;;;;GAIG;AACH,eAAO,MAAM,cAAc,gRAQ1B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAS3D,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAExF;AAMD,eAAO,MAAM,aAAa;IAEtB,gFAAgF;;IAEhF,6DAA6D;;IAE7D;;;OAGG;;IAEH,4CAA4C;;IAE5C;;;OAGG;;IAEH;;;OAGG;;IAEH,qFAAqF;;IAErF;;;OAGG;;EAIN,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAMzD;;;GAGG;AACH,eAAO,MAAM,2BAA2B;;;;;;;EAavC,CAAC;AACF,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAOrF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,gJAGzB,CAAC;AACF,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAEzD,eAAO,MAAM,kBAAkB;IAE3B,gDAAgD;;IAEhD;;;OAGG;;IAEH;;;OAGG;;;IAGH;;OAEG;;EAIN,CAAC;AACF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEnE;;;;GAIG;AACH,eAAO,MAAM,gCAAgC;;QA3BzC,gDAAgD;;QAEhD;;;WAGG;;QAEH;;;WAGG;;;QAGH;;WAEG;;;IAeH,iGAAiG;;IAEjG,2EAA2E;;EAI9E,CAAC;AACF,MAAM,MAAM,gCAAgC,GAAG,MAAM,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAO/F;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB;;;;;;;IAQ1B,4FAA4F;;;EAK/F,CAAC;AACF,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAOjE,eAAO,MAAM,qBAAqB;IAE9B,2DAA2D;;IAE3D,yEAAyE;;IAEzE,2EAA2E;;IAE3E,oEAAoE;;IAEpE,0EAA0E;;IAE1E,8FAA8F;;EAIjG,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEzE;;;;GAIG;AACH,eAAO,MAAM,2BAA2B;;QAtBpC,2DAA2D;;QAE3D,yEAAyE;;QAEzE,2EAA2E;;QAE3E,oEAAoE;;QAEpE,0EAA0E;;QAE1E,8FAA8F;;;EAiBjG,CAAC;AACF,MAAM,MAAM,2BAA2B,GAAG,MAAM,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAMrF;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB;;;;;IAM9B;;;;;OAKG;;IAKH,iGAAiG;;IAEjG;;;OAGG;;IAEH,gEAAgE;;EAInE,CAAC;AACF,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAOzE,eAAO,MAAM,2BAA2B,EAAG,eAAwB,CAAC;AACpE,eAAO,MAAM,6BAA6B,EAAG,iBAA0B,CAAC"}
|