@baukit/integrations-client 0.2.0 → 0.3.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
CHANGED
|
@@ -69,21 +69,52 @@ parameters.
|
|
|
69
69
|
|
|
70
70
|
## Provider registry
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
Register static product data once. The connector type belongs to the product, so it can hold an
|
|
73
|
+
OAuth starter, product hooks, icons, or other UI-specific values without adding those dependencies
|
|
74
|
+
to Baukit:
|
|
73
75
|
|
|
74
76
|
```ts
|
|
75
77
|
import { createProviderRegistry } from '@baukit/integrations-client';
|
|
76
78
|
|
|
77
|
-
const
|
|
79
|
+
const providerDefinitions = createProviderRegistry([
|
|
78
80
|
{
|
|
79
81
|
id: 'calendar',
|
|
80
82
|
labelKey: 'integrations.calendar',
|
|
81
83
|
capabilities: ['read_events'],
|
|
82
|
-
|
|
84
|
+
connector: {
|
|
85
|
+
startOAuth: startCalendarOAuth,
|
|
86
|
+
useConnection: useCalendarConnection,
|
|
87
|
+
icon: CalendarIcon,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: 'storage',
|
|
92
|
+
labelKey: 'integrations.storage',
|
|
93
|
+
capabilities: ['read_files'],
|
|
94
|
+
connector: {
|
|
95
|
+
startOAuth: startStorageOAuth,
|
|
96
|
+
useConnection: useStorageConnection,
|
|
97
|
+
icon: StorageIcon,
|
|
98
|
+
},
|
|
83
99
|
},
|
|
84
100
|
] as const);
|
|
101
|
+
|
|
102
|
+
const providers = providerDefinitions.withConnectionStates(
|
|
103
|
+
new Map([
|
|
104
|
+
['calendar', calendarConnectionState],
|
|
105
|
+
['storage', storageConnectionState],
|
|
106
|
+
]),
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
await providers.get('calendar')?.connector?.startOAuth();
|
|
85
110
|
```
|
|
86
111
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
112
|
+
`list()` keeps registration order. `get()` returns the typed connector and returns `undefined` for an
|
|
113
|
+
unknown ID. `withConnectionStates()` accepts a read-only map or partial record and returns a new
|
|
114
|
+
registry; it does not change `providerDefinitions`. A provider omitted from the state collection has
|
|
115
|
+
state `disconnected` and no available actions. Passing `connection` in a registration still works
|
|
116
|
+
for callers using the 0.2.0 API.
|
|
117
|
+
|
|
118
|
+
The registry copies capability and action arrays and rejects duplicate IDs. It keeps connector
|
|
119
|
+
objects by reference so hooks, functions, and component identities remain stable. Persistence,
|
|
120
|
+
provider OAuth parameters, identity, copy, and policy stay in the product.
|
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import type { ConnectionAction, ConnectionState, ConnectionStatus } from './connection-health.js';
|
|
2
|
-
export interface ProviderRegistration<ProviderId extends string, LabelKey extends string, Capability extends string> {
|
|
2
|
+
export interface ProviderRegistration<ProviderId extends string, LabelKey extends string, Capability extends string, Connector = undefined> {
|
|
3
3
|
readonly id: ProviderId;
|
|
4
4
|
readonly labelKey: LabelKey;
|
|
5
5
|
readonly capabilities: readonly Capability[];
|
|
6
|
-
readonly
|
|
6
|
+
readonly connector?: Connector;
|
|
7
|
+
readonly connection?: ConnectionState;
|
|
7
8
|
}
|
|
8
|
-
export interface RegisteredProvider<ProviderId extends string, LabelKey extends string, Capability extends string> {
|
|
9
|
+
export interface RegisteredProvider<ProviderId extends string, LabelKey extends string, Capability extends string, Connector = undefined> {
|
|
9
10
|
readonly id: ProviderId;
|
|
10
11
|
readonly labelKey: LabelKey;
|
|
11
12
|
readonly capabilities: readonly Capability[];
|
|
13
|
+
readonly connector?: Connector;
|
|
12
14
|
readonly currentState: ConnectionStatus;
|
|
13
15
|
readonly availableActions: readonly ConnectionAction[];
|
|
14
16
|
}
|
|
15
|
-
export
|
|
17
|
+
export type ProviderConnectionStates<ProviderId extends string> = ReadonlyMap<ProviderId, ConnectionState> | Readonly<Partial<Record<ProviderId, ConnectionState>>>;
|
|
18
|
+
export declare class ProviderRegistry<ProviderId extends string, LabelKey extends string, Capability extends string, Connector = undefined> {
|
|
16
19
|
#private;
|
|
17
|
-
constructor(registrations: readonly ProviderRegistration<ProviderId, LabelKey, Capability>[]);
|
|
18
|
-
list(): readonly RegisteredProvider<ProviderId, LabelKey, Capability>[];
|
|
19
|
-
get(providerId:
|
|
20
|
+
constructor(registrations: readonly ProviderRegistration<ProviderId, LabelKey, Capability, Connector>[]);
|
|
21
|
+
list(): readonly RegisteredProvider<ProviderId, LabelKey, Capability, Connector>[];
|
|
22
|
+
get(providerId: string): RegisteredProvider<ProviderId, LabelKey, Capability, Connector> | undefined;
|
|
23
|
+
withConnectionStates(states: ProviderConnectionStates<ProviderId>): ProviderRegistry<ProviderId, LabelKey, Capability, Connector>;
|
|
20
24
|
}
|
|
21
|
-
export declare function createProviderRegistry<ProviderId extends string, LabelKey extends string, Capability extends string>(registrations: readonly ProviderRegistration<ProviderId, LabelKey, Capability>[]): ProviderRegistry<ProviderId, LabelKey, Capability>;
|
|
25
|
+
export declare function createProviderRegistry<ProviderId extends string, LabelKey extends string, Capability extends string, Connector = undefined>(registrations: readonly ProviderRegistration<ProviderId, LabelKey, Capability, Connector>[]): ProviderRegistry<ProviderId, LabelKey, Capability, Connector>;
|
|
22
26
|
//# sourceMappingURL=provider-registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAElG,MAAM,WAAW,oBAAoB,CACnC,UAAU,SAAS,MAAM,EACzB,QAAQ,SAAS,MAAM,EACvB,UAAU,SAAS,MAAM;
|
|
1
|
+
{"version":3,"file":"provider-registry.d.ts","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAElG,MAAM,WAAW,oBAAoB,CACnC,UAAU,SAAS,MAAM,EACzB,QAAQ,SAAS,MAAM,EACvB,UAAU,SAAS,MAAM,EACzB,SAAS,GAAG,SAAS;IAErB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;CACvC;AAED,MAAM,WAAW,kBAAkB,CACjC,UAAU,SAAS,MAAM,EACzB,QAAQ,SAAS,MAAM,EACvB,UAAU,SAAS,MAAM,EACzB,SAAS,GAAG,SAAS;IAErB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxC,QAAQ,CAAC,gBAAgB,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACxD;AAED,MAAM,MAAM,wBAAwB,CAAC,UAAU,SAAS,MAAM,IAC5D,WAAW,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;AASpG,qBAAa,gBAAgB,CAC3B,UAAU,SAAS,MAAM,EACzB,QAAQ,SAAS,MAAM,EACvB,UAAU,SAAS,MAAM,EACzB,SAAS,GAAG,SAAS;;gBAUnB,aAAa,EAAE,SAAS,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE;IA4BtF,IAAI,IAAI,SAAS,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE;IAIlF,GAAG,CACR,UAAU,EAAE,MAAM,GACjB,kBAAkB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,SAAS;IAIvE,oBAAoB,CACzB,MAAM,EAAE,wBAAwB,CAAC,UAAU,CAAC,GAC3C,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC;CAUjE;AAED,wBAAgB,sBAAsB,CACpC,UAAU,SAAS,MAAM,EACzB,QAAQ,SAAS,MAAM,EACvB,UAAU,SAAS,MAAM,EACzB,SAAS,GAAG,SAAS,EAErB,aAAa,EAAE,SAAS,oBAAoB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,EAAE,GAC1F,gBAAgB,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,CAAC,CAE/D"}
|
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
export class ProviderRegistry {
|
|
2
|
+
#definitions;
|
|
2
3
|
#providers;
|
|
3
4
|
#byId;
|
|
4
5
|
constructor(registrations) {
|
|
5
|
-
const
|
|
6
|
+
const definitions = registrations.map((registration) => Object.freeze({
|
|
6
7
|
id: registration.id,
|
|
7
8
|
labelKey: registration.labelKey,
|
|
8
9
|
capabilities: Object.freeze([...registration.capabilities]),
|
|
9
|
-
|
|
10
|
-
availableActions: Object.freeze([...registration.connection.availableActions]),
|
|
10
|
+
...('connector' in registration ? { connector: registration.connector } : {}),
|
|
11
11
|
}));
|
|
12
|
-
const
|
|
13
|
-
if (
|
|
12
|
+
const ids = new Set(definitions.map((definition) => definition.id));
|
|
13
|
+
if (ids.size !== definitions.length)
|
|
14
14
|
throw new TypeError('Provider IDs must be unique.');
|
|
15
|
+
const providers = definitions.map((definition, index) => {
|
|
16
|
+
const connection = registrations[index]?.connection;
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
...definition,
|
|
19
|
+
currentState: connection?.status ?? 'disconnected',
|
|
20
|
+
availableActions: Object.freeze(connection === undefined ? [] : [...connection.availableActions]),
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
this.#definitions = Object.freeze(definitions);
|
|
15
24
|
this.#providers = Object.freeze(providers);
|
|
16
|
-
this.#byId =
|
|
25
|
+
this.#byId = new Map(providers.map((provider) => [provider.id, provider]));
|
|
17
26
|
}
|
|
18
27
|
list() {
|
|
19
28
|
return this.#providers;
|
|
@@ -21,8 +30,28 @@ export class ProviderRegistry {
|
|
|
21
30
|
get(providerId) {
|
|
22
31
|
return this.#byId.get(providerId);
|
|
23
32
|
}
|
|
33
|
+
withConnectionStates(states) {
|
|
34
|
+
const registrations = this.#definitions.map((definition) => {
|
|
35
|
+
const connection = getConnectionState(states, definition.id);
|
|
36
|
+
return {
|
|
37
|
+
...definition,
|
|
38
|
+
...(connection === undefined ? {} : { connection }),
|
|
39
|
+
};
|
|
40
|
+
});
|
|
41
|
+
return new ProviderRegistry(registrations);
|
|
42
|
+
}
|
|
24
43
|
}
|
|
25
44
|
export function createProviderRegistry(registrations) {
|
|
26
45
|
return new ProviderRegistry(registrations);
|
|
27
46
|
}
|
|
47
|
+
function getConnectionState(states, providerId) {
|
|
48
|
+
if (isReadonlyMap(states))
|
|
49
|
+
return states.get(providerId);
|
|
50
|
+
if (!Object.hasOwn(states, providerId))
|
|
51
|
+
return undefined;
|
|
52
|
+
return states[providerId];
|
|
53
|
+
}
|
|
54
|
+
function isReadonlyMap(states) {
|
|
55
|
+
return typeof Reflect.get(states, 'get') === 'function';
|
|
56
|
+
}
|
|
28
57
|
//# sourceMappingURL=provider-registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider-registry.js","sourceRoot":"","sources":["../src/provider-registry.ts"],"names":[],"mappings":"AAuCA,MAAM,OAAO,gBAAgB;IAMlB,YAAY,CAA6E;IACzF,UAAU,CAA6E;IACvF,KAAK,CAGZ;IAEF,YACE,aAA2F;QAE3F,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,EAAE,CACrD,MAAM,CAAC,MAAM,CAAC;YACZ,EAAE,EAAE,YAAY,CAAC,EAAE;YACnB,QAAQ,EAAE,YAAY,CAAC,QAAQ;YAC/B,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,YAAY,CAAC,YAAY,CAAC,CAAC;YAC3D,GAAG,CAAC,WAAW,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9E,CAAC,CACH,CAAC;QACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;QACpE,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC,MAAM;YAAE,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAC;QAEzF,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;YACtD,MAAM,UAAU,GAAG,aAAa,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;YACpD,OAAO,MAAM,CAAC,MAAM,CAAC;gBACnB,GAAG,UAAU;gBACb,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,cAAc;gBAClD,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAC7B,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,gBAAgB,CAAC,CACjE;aACF,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IAEM,IAAI;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAEM,GAAG,CACR,UAAkB;QAElB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpC,CAAC;IAEM,oBAAoB,CACzB,MAA4C;QAE5C,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;YACzD,MAAM,UAAU,GAAG,kBAAkB,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;YAC7D,OAAO;gBACL,GAAG,UAAU;gBACb,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;aACpD,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,gBAAgB,CAA8C,aAAa,CAAC,CAAC;IAC1F,CAAC;CACF;AAED,MAAM,UAAU,sBAAsB,CAMpC,aAA2F;IAE3F,OAAO,IAAI,gBAAgB,CAAC,aAAa,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB,CACzB,MAA4C,EAC5C,UAAsB;IAEtB,IAAI,aAAa,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACzD,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,aAAa,CACpB,MAA4C;IAE5C,OAAO,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,KAAK,UAAU,CAAC;AAC1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@baukit/integrations-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Provider-neutral connection state, OAuth session coordination, and provider registration for web and native clients.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Patrick Koss",
|
|
@@ -32,15 +32,14 @@
|
|
|
32
32
|
"README.md",
|
|
33
33
|
"LICENSE"
|
|
34
34
|
],
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typescript": "6.0.3",
|
|
37
|
+
"vitest": "4.1.10"
|
|
38
|
+
},
|
|
35
39
|
"scripts": {
|
|
36
40
|
"build": "tsc -p tsconfig.json",
|
|
37
|
-
"prepare": "pnpm run build",
|
|
38
41
|
"test": "vitest run --config ../../vitest.config.ts",
|
|
39
42
|
"lint": "eslint src --max-warnings=0",
|
|
40
43
|
"format:check": "prettier --check src package.json tsconfig.json"
|
|
41
|
-
},
|
|
42
|
-
"devDependencies": {
|
|
43
|
-
"typescript": "6.0.3",
|
|
44
|
-
"vitest": "4.1.10"
|
|
45
44
|
}
|
|
46
|
-
}
|
|
45
|
+
}
|