@kubun/plugin-connector 0.14.1 → 0.14.2
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/lib/action.d.ts +9 -0
- package/lib/action.js +9 -1
- package/lib/auth-required.d.ts +11 -0
- package/lib/auth-required.js +17 -0
- package/lib/credential-refresh-bridge.d.ts +11 -0
- package/lib/credential-refresh-bridge.js +27 -0
- package/lib/credential.d.ts +2 -2
- package/lib/credential.js +1 -1
- package/lib/index.d.ts +8 -2
- package/lib/index.js +284 -62
- package/lib/manager.d.ts +71 -3
- package/lib/manager.js +41 -6
- package/lib/oauth.d.ts +5 -1
- package/lib/oauth.js +5 -2
- package/lib/periodic-sync.d.ts +4 -0
- package/lib/periodic-sync.js +12 -0
- package/lib/schema.d.ts +45 -1
- package/lib/schema.js +122 -0
- package/lib/sync/orchestrate.d.ts +11 -1
- package/lib/sync/orchestrate.js +6 -0
- package/lib/sync/workflow.d.ts +11 -0
- package/lib/sync/workflow.js +26 -2
- package/lib/write-grants.d.ts +10 -2
- package/lib/write-grants.js +10 -1
- package/package.json +5 -5
package/lib/action.d.ts
CHANGED
|
@@ -34,5 +34,14 @@ export type ExecuteActionDeps = {
|
|
|
34
34
|
* import binary content (e.g. a Gmail attachment) on demand.
|
|
35
35
|
*/
|
|
36
36
|
writeAttachment?: WriteAttachment;
|
|
37
|
+
/**
|
|
38
|
+
* Signal that this action cannot run because the provider credential is absent,
|
|
39
|
+
* so a consumer can prompt (re)authorization. Fired only for a genuinely
|
|
40
|
+
* missing credential, alongside the thrown error the caller surfaces.
|
|
41
|
+
*/
|
|
42
|
+
emitAuthRequired?: (params: {
|
|
43
|
+
provider: string;
|
|
44
|
+
ownerDID: string;
|
|
45
|
+
}) => void;
|
|
37
46
|
};
|
|
38
47
|
export declare function executeAction(params: ExecuteActionParams, deps: ExecuteActionDeps): Promise<ExecuteActionResult>;
|
package/lib/action.js
CHANGED
|
@@ -2,7 +2,7 @@ import { DocumentID, DocumentModelID } from '@kubun/id';
|
|
|
2
2
|
import { getGraphStore } from '@kubun/store-graph';
|
|
3
3
|
import { EntityProcessor } from './sync/processor.js';
|
|
4
4
|
export async function executeAction(params, deps) {
|
|
5
|
-
const { stores, registry, credentialProvider, ownerDID, logger, writeDocument, writeAttachment } = deps;
|
|
5
|
+
const { stores, registry, credentialProvider, ownerDID, logger, writeDocument, writeAttachment, emitAuthRequired } = deps;
|
|
6
6
|
const { connector: connectorName, action: actionName, model: modelName, input, sourceID } = params;
|
|
7
7
|
const connector = registry.get(connectorName);
|
|
8
8
|
if (connector == null) {
|
|
@@ -19,6 +19,14 @@ export async function executeAction(params, deps) {
|
|
|
19
19
|
const providerName = connector.auth.provider;
|
|
20
20
|
const credential = await credentialProvider.get(providerName, ownerDID);
|
|
21
21
|
if (credential == null) {
|
|
22
|
+
// A device connector carries no OAuth credential, so its absence is not an
|
|
23
|
+
// authorization gap — only a real provider asks for (re)authorization.
|
|
24
|
+
if (providerName !== 'device') {
|
|
25
|
+
emitAuthRequired?.({
|
|
26
|
+
provider: providerName,
|
|
27
|
+
ownerDID
|
|
28
|
+
});
|
|
29
|
+
}
|
|
22
30
|
throw new Error(`No credential found for provider "${providerName}"`);
|
|
23
31
|
}
|
|
24
32
|
// Check write scopes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ConnectorAuthRequiredEvent } from './manager.js';
|
|
2
|
+
import type { ConnectorRegistry } from './registry.js';
|
|
3
|
+
/**
|
|
4
|
+
* Assemble the `connector:authRequired` payload for a genuinely missing
|
|
5
|
+
* credential: the provider's registered connectors, the owner folded to its
|
|
6
|
+
* normalized (short) form — the same folding the credential row is keyed on —
|
|
7
|
+
* and `reason: 'absent'`. The deep sync sites (workflow, orchestrate, action)
|
|
8
|
+
* only signal `{ provider, ownerDID }`; the connector mapping and normalization
|
|
9
|
+
* live here so those sites carry no manager or registry knowledge.
|
|
10
|
+
*/
|
|
11
|
+
export declare function connectorAuthRequiredPayload(registry: ConnectorRegistry, provider: string, ownerDID: string): ConnectorAuthRequiredEvent;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { normalizeDID } from '@kokuin/token';
|
|
2
|
+
/**
|
|
3
|
+
* Assemble the `connector:authRequired` payload for a genuinely missing
|
|
4
|
+
* credential: the provider's registered connectors, the owner folded to its
|
|
5
|
+
* normalized (short) form — the same folding the credential row is keyed on —
|
|
6
|
+
* and `reason: 'absent'`. The deep sync sites (workflow, orchestrate, action)
|
|
7
|
+
* only signal `{ provider, ownerDID }`; the connector mapping and normalization
|
|
8
|
+
* live here so those sites carry no manager or registry knowledge.
|
|
9
|
+
*/ export function connectorAuthRequiredPayload(registry, provider, ownerDID) {
|
|
10
|
+
const connectors = registry.getAll().filter((connector)=>connector.auth.provider === provider).map((connector)=>connector.name);
|
|
11
|
+
return {
|
|
12
|
+
provider,
|
|
13
|
+
connectors,
|
|
14
|
+
ownerDID: normalizeDID(ownerDID),
|
|
15
|
+
reason: 'absent'
|
|
16
|
+
};
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { EventsSource } from '@sozai/event';
|
|
2
|
+
import type { RefreshEvents } from './credential.js';
|
|
3
|
+
import type { ConnectorManager } from './manager.js';
|
|
4
|
+
import type { ConnectorRegistry } from './registry.js';
|
|
5
|
+
export type BridgeCredentialRefreshEventsParams = {
|
|
6
|
+
source: EventsSource<RefreshEvents>;
|
|
7
|
+
manager: ConnectorManager;
|
|
8
|
+
registry: ConnectorRegistry;
|
|
9
|
+
defer: (fn: () => void) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function bridgeCredentialRefreshEvents(params: BridgeCredentialRefreshEventsParams): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { normalizeDID } from '@kokuin/token';
|
|
2
|
+
export function bridgeCredentialRefreshEvents(params) {
|
|
3
|
+
const { source, manager, registry, defer } = params;
|
|
4
|
+
const connectorsFor = (provider)=>registry.getAll().filter((connector)=>connector.auth.provider === provider).map((connector)=>connector.name);
|
|
5
|
+
source.on('refreshed', ({ providerName, ownerDID, scopes, expiresAt })=>{
|
|
6
|
+
defer(()=>{
|
|
7
|
+
manager.emitLifecycle('connector:credentialRefreshed', {
|
|
8
|
+
provider: providerName,
|
|
9
|
+
connectors: connectorsFor(providerName),
|
|
10
|
+
ownerDID: normalizeDID(ownerDID),
|
|
11
|
+
scopes,
|
|
12
|
+
expiresAt: expiresAt?.getTime()
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
source.on('refreshFailed', ({ providerName, ownerDID, category })=>{
|
|
17
|
+
if (category !== 'invalid_grant') return;
|
|
18
|
+
defer(()=>{
|
|
19
|
+
manager.emitLifecycle('connector:authRequired', {
|
|
20
|
+
provider: providerName,
|
|
21
|
+
connectors: connectorsFor(providerName),
|
|
22
|
+
ownerDID: normalizeDID(ownerDID),
|
|
23
|
+
reason: 'invalid_grant'
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
package/lib/credential.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export type { DBCredentialProviderParams } from '@kubun/credential';
|
|
2
|
-
export { DBCredentialProvider } from '@kubun/credential';
|
|
1
|
+
export type { DBCredentialProviderParams, RefreshEvents, RefreshingCredentialProviderParams, RefreshOutcome, } from '@kubun/credential';
|
|
2
|
+
export { DBCredentialProvider, RefreshingCredentialProvider } from '@kubun/credential';
|
package/lib/credential.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// The DB-backed credential provider moved to @kubun/credential; re-exported here
|
|
2
2
|
// so existing importers of `../src/credential.js` and the package index keep
|
|
3
3
|
// resolving it.
|
|
4
|
-
export { DBCredentialProvider } from '@kubun/credential';
|
|
4
|
+
export { DBCredentialProvider, RefreshingCredentialProvider } from '@kubun/credential';
|
package/lib/index.d.ts
CHANGED
|
@@ -2,8 +2,10 @@ import type { ConnectorDefinition, SyncBoundary } from '@kubun/connector';
|
|
|
2
2
|
import type { OAuthProviderDefinition } from '@kubun/credential-types';
|
|
3
3
|
import type { KubunPlugin, PluginFactoryParams } from '@kubun/engine';
|
|
4
4
|
import type { AdaptivePolicy } from '@kubun/plugin-workflow-api';
|
|
5
|
+
import type { EventsSource } from '@sozai/event';
|
|
5
6
|
import { type ConnectorAPI, type CredentialAPI, type SetSyncStateParams, type SyncStateData } from './api.js';
|
|
6
|
-
import { DBCredentialProvider, type DBCredentialProviderParams } from './credential.js';
|
|
7
|
+
import { DBCredentialProvider, type DBCredentialProviderParams, RefreshingCredentialProvider, type RefreshingCredentialProviderParams } from './credential.js';
|
|
8
|
+
import { type ConnectorManagerEvents } from './manager.js';
|
|
7
9
|
export { type ExecuteActionDeps, type ExecuteActionParams, type ExecuteActionResult, executeAction, } from './action.js';
|
|
8
10
|
export { type ConnectorActivatedEvent, type ConnectorDeactivatedEvent, ConnectorManager, type ConnectorManagerEvents, type ConnectorManagerParams, } from './manager.js';
|
|
9
11
|
export { OAuthService, type OAuthServiceParams } from './oauth.js';
|
|
@@ -16,7 +18,10 @@ export { EntityProcessor, type EntityProcessorParams, type MutateDocuments, type
|
|
|
16
18
|
export { DBSyncStateStore } from './sync/state.js';
|
|
17
19
|
export { CONNECTOR_SYNC_CONCURRENCY, CONNECTOR_SYNC_WORKFLOW, type ConnectorSyncWorkflowDefinition, type ConnectorSyncWorkflowParams, createConnectorSyncWorkflow, } from './sync/workflow.js';
|
|
18
20
|
export type { ConnectorAPI, CredentialAPI, SetSyncStateParams, SyncStateData };
|
|
19
|
-
export
|
|
21
|
+
export type ConnectorPluginAPI = ConnectorAPI & {
|
|
22
|
+
events: EventsSource<ConnectorManagerEvents>;
|
|
23
|
+
};
|
|
24
|
+
export { DBCredentialProvider, type DBCredentialProviderParams, RefreshingCredentialProvider, type RefreshingCredentialProviderParams, };
|
|
20
25
|
export type ConnectorPluginOptions = {
|
|
21
26
|
connectors: Array<ConnectorDefinition>;
|
|
22
27
|
providers?: Array<OAuthProviderDefinition>;
|
|
@@ -24,5 +29,6 @@ export type ConnectorPluginOptions = {
|
|
|
24
29
|
boundary?: SyncBoundary;
|
|
25
30
|
periodicSyncPolicy?: AdaptivePolicy;
|
|
26
31
|
};
|
|
32
|
+
autoEnablePeriodicSync?: boolean;
|
|
27
33
|
};
|
|
28
34
|
export declare function createConnectorPlugin(options: ConnectorPluginOptions): (params: PluginFactoryParams) => KubunPlugin;
|