@fayz-ai/core 0.9.0 → 0.11.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 +2 -2
- package/dist/access/index.js.map +1 -1
- package/dist/chunk-BEGXYHS4.js +566 -0
- package/dist/chunk-BEGXYHS4.js.map +1 -0
- package/dist/chunk-ED6NBH6U.js +348 -0
- package/dist/chunk-ED6NBH6U.js.map +1 -0
- package/dist/chunk-EWKX4VUM.js +429 -0
- package/dist/chunk-EWKX4VUM.js.map +1 -0
- package/dist/chunk-LARZWDHA.js +319 -0
- package/dist/chunk-LARZWDHA.js.map +1 -0
- package/dist/chunk-OXQGRJZT.js +125 -0
- package/dist/chunk-OXQGRJZT.js.map +1 -0
- package/dist/chunk-RRYFXUQX.js +1247 -0
- package/dist/chunk-RRYFXUQX.js.map +1 -0
- package/dist/{chunk-5RJVUC6J.js → chunk-TDI6F6PT.js} +373 -25
- package/dist/chunk-TDI6F6PT.js.map +1 -0
- package/dist/{chunk-V2MSAUHO.js → chunk-UVKH6RDX.js} +211 -335
- package/dist/chunk-UVKH6RDX.js.map +1 -0
- package/dist/chunk-V53GR4UT.js +289 -0
- package/dist/chunk-V53GR4UT.js.map +1 -0
- package/dist/connector-runtime/index.d.ts +15 -0
- package/dist/connector-runtime/index.d.ts.map +1 -0
- package/dist/connector-runtime/index.js +3 -0
- package/dist/connector-runtime/index.js.map +1 -0
- package/dist/data/archetype.d.ts.map +1 -1
- package/dist/data/backend-env.d.ts +38 -0
- package/dist/data/backend-env.d.ts.map +1 -0
- package/dist/data/bulk.d.ts +24 -0
- package/dist/data/bulk.d.ts.map +1 -1
- package/dist/data/cached.d.ts.map +1 -1
- package/dist/data/custom-fields.d.ts +5 -0
- package/dist/data/custom-fields.d.ts.map +1 -0
- package/dist/data/index.d.ts +2 -1
- package/dist/data/index.d.ts.map +1 -1
- package/dist/data/index.js +3 -1
- package/dist/data/mock.d.ts.map +1 -1
- package/dist/data/platform-api.d.ts.map +1 -1
- package/dist/data/resolve.d.ts.map +1 -1
- package/dist/data/supabase.d.ts.map +1 -1
- package/dist/data/types.d.ts +8 -0
- package/dist/data/types.d.ts.map +1 -1
- package/dist/entity/events.d.ts +14 -0
- package/dist/entity/events.d.ts.map +1 -0
- package/dist/events/envelope.d.ts +31 -0
- package/dist/events/envelope.d.ts.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/log.d.ts +44 -0
- package/dist/events/log.d.ts.map +1 -0
- package/dist/events/types.d.ts +40 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/fields/store.d.ts +45 -0
- package/dist/fields/store.d.ts.map +1 -0
- package/dist/i18n/index.d.ts +10 -0
- package/dist/i18n/index.d.ts.map +1 -1
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/shell-translations.en.d.ts.map +1 -1
- package/dist/i18n/shell-translations.pt-br.d.ts.map +1 -1
- package/dist/index.d.ts +45 -21
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +543 -56
- package/dist/index.js.map +1 -1
- package/dist/integrations/events.d.ts +7 -0
- package/dist/integrations/events.d.ts.map +1 -0
- package/dist/integrations/index.d.ts +533 -29
- package/dist/integrations/index.d.ts.map +1 -1
- package/dist/integrations/index.js +3 -1
- package/dist/integrations/permissions.d.ts +132 -0
- package/dist/integrations/permissions.d.ts.map +1 -0
- package/dist/integrations/request.d.ts +170 -0
- package/dist/integrations/request.d.ts.map +1 -0
- package/dist/integrations/runtime-token.d.ts +33 -0
- package/dist/integrations/runtime-token.d.ts.map +1 -0
- package/dist/integrations/runtime.d.ts +398 -0
- package/dist/integrations/runtime.d.ts.map +1 -0
- package/dist/integrations/settings.d.ts +102 -0
- package/dist/integrations/settings.d.ts.map +1 -0
- package/dist/integrations/store.d.ts +145 -0
- package/dist/integrations/store.d.ts.map +1 -0
- package/dist/{address/index.d.ts → lib/address.d.ts} +1 -1
- package/dist/{address/index.d.ts.map → lib/address.d.ts.map} +1 -1
- package/dist/{phone/index.d.ts → lib/phone.d.ts} +1 -1
- package/dist/lib/phone.d.ts.map +1 -0
- package/dist/{seo/index.d.ts → lib/seo.d.ts} +18 -1
- package/dist/lib/seo.d.ts.map +1 -0
- package/dist/{tenant/index.d.ts → lib/tenant.d.ts} +1 -1
- package/dist/lib/tenant.d.ts.map +1 -0
- package/dist/manifest/index.d.ts +1 -1
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/messaging/index.d.ts +3 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/registry.d.ts +35 -0
- package/dist/messaging/registry.d.ts.map +1 -0
- package/dist/messaging/types.d.ts +67 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/plugin/index.js +3 -1
- package/dist/plugin/runtime.d.ts +17 -0
- package/dist/plugin/runtime.d.ts.map +1 -1
- package/dist/registry/block-catalog.d.ts +78 -0
- package/dist/registry/block-catalog.d.ts.map +1 -0
- package/dist/registry/block-constraints.d.ts +64 -0
- package/dist/registry/block-constraints.d.ts.map +1 -0
- package/dist/registry/block-schema.d.ts +69 -0
- package/dist/registry/block-schema.d.ts.map +1 -0
- package/dist/registry/blocks.d.ts +84 -0
- package/dist/registry/blocks.d.ts.map +1 -0
- package/dist/registry/entities.d.ts +179 -0
- package/dist/registry/entities.d.ts.map +1 -0
- package/dist/registry/extension-points.d.ts +117 -0
- package/dist/registry/extension-points.d.ts.map +1 -0
- package/dist/registry/handles.d.ts +41 -0
- package/dist/registry/handles.d.ts.map +1 -0
- package/dist/registry/index.d.ts +41 -41
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/loaders.d.ts +55 -0
- package/dist/registry/loaders.d.ts.map +1 -0
- package/dist/registry/registry-class.d.ts +157 -0
- package/dist/registry/registry-class.d.ts.map +1 -0
- package/dist/registry/schema-check.d.ts +14 -0
- package/dist/registry/schema-check.d.ts.map +1 -0
- package/dist/router/index.d.ts +78 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +1 -1
- package/dist/{shell-translations.pt-br-2GWRQRRP.js → shell-translations.pt-br-BM5ZFSKJ.js} +72 -3
- package/dist/shell-translations.pt-br-BM5ZFSKJ.js.map +1 -0
- package/dist/telemetry/errors.d.ts +87 -0
- package/dist/telemetry/errors.d.ts.map +1 -0
- package/dist/testing/index.js +4 -1
- package/dist/{testing/index.d.ts → testing.d.ts} +5 -3
- package/dist/testing.d.ts.map +1 -0
- package/dist/types/analytics.d.ts +213 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/crud.d.ts +37 -3
- package/dist/types/crud.d.ts.map +1 -1
- package/dist/types/plugins.d.ts +138 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/package.json +9 -17
- package/dist/blocks/index.d.ts +0 -25
- package/dist/blocks/index.d.ts.map +0 -1
- package/dist/chunk-5RJVUC6J.js.map +0 -1
- package/dist/chunk-L4TLMYGC.js +0 -42
- package/dist/chunk-L4TLMYGC.js.map +0 -1
- package/dist/chunk-V2MSAUHO.js.map +0 -1
- package/dist/chunk-X5THHG6T.js +0 -77
- package/dist/chunk-X5THHG6T.js.map +0 -1
- package/dist/chunk-Y2C2FBQP.js +0 -35
- package/dist/chunk-Y2C2FBQP.js.map +0 -1
- package/dist/chunk-YH25Y4FW.js +0 -311
- package/dist/chunk-YH25Y4FW.js.map +0 -1
- package/dist/phone/index.d.ts.map +0 -1
- package/dist/seo/index.d.ts.map +0 -1
- package/dist/shell-translations.pt-br-2GWRQRRP.js.map +0 -1
- package/dist/tenant/index.d.ts.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/src/access/denial.ts +0 -33
- package/src/access/engine.test.ts +0 -48
- package/src/access/engine.ts +0 -136
- package/src/access/index.ts +0 -14
- package/src/access/limits.ts +0 -18
- package/src/address/index.ts +0 -188
- package/src/app/render.tsx +0 -69
- package/src/blocks/index.tsx +0 -68
- package/src/data/archetype.ts +0 -255
- package/src/data/bulk.ts +0 -35
- package/src/data/cached.ts +0 -55
- package/src/data/count.test.ts +0 -152
- package/src/data/count.ts +0 -131
- package/src/data/filters.test.ts +0 -70
- package/src/data/filters.ts +0 -90
- package/src/data/index.ts +0 -11
- package/src/data/mock.ts +0 -90
- package/src/data/platform-api.ts +0 -209
- package/src/data/refresh.ts +0 -115
- package/src/data/resolve.ts +0 -126
- package/src/data/supabase.ts +0 -230
- package/src/data/types.ts +0 -50
- package/src/entity/index.ts +0 -2
- package/src/entity/registry.ts +0 -49
- package/src/events/index.tsx +0 -82
- package/src/i18n/index.ts +0 -476
- package/src/i18n/shell-translations.en.ts +0 -875
- package/src/i18n/shell-translations.pt-br.ts +0 -873
- package/src/index.ts +0 -217
- package/src/integrations/index.ts +0 -237
- package/src/lib/cache.ts +0 -118
- package/src/lib/csv.ts +0 -54
- package/src/lib/format.ts +0 -58
- package/src/manifest/app-manifest.schema.json +0 -676
- package/src/manifest/index.ts +0 -518
- package/src/manifest/serialize.ts +0 -52
- package/src/phone/index.ts +0 -85
- package/src/plugin/createSafeDataProvider.ts +0 -30
- package/src/plugin/index.ts +0 -1
- package/src/plugin/runtime.ts +0 -331
- package/src/registry/index.ts +0 -163
- package/src/router/history.ts +0 -86
- package/src/router/index.ts +0 -29
- package/src/runtime/index.ts +0 -15
- package/src/runtime/oauth.ts +0 -219
- package/src/search/engine.ts +0 -559
- package/src/search/index.ts +0 -25
- package/src/search/text.ts +0 -206
- package/src/search/types.ts +0 -75
- package/src/seo/index.ts +0 -128
- package/src/tenant/index.ts +0 -38
- package/src/testing/index.ts +0 -116
- package/src/types/auth.ts +0 -41
- package/src/types/billing.ts +0 -39
- package/src/types/crud.ts +0 -184
- package/src/types/entities.ts +0 -142
- package/src/types/entitlements.ts +0 -45
- package/src/types/i18n.ts +0 -7
- package/src/types/index.ts +0 -11
- package/src/types/org.ts +0 -137
- package/src/types/payment.ts +0 -44
- package/src/types/permissions.ts +0 -32
- package/src/types/plugins.ts +0 -480
- package/src/types/theme.ts +0 -8
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a subscription pattern covers an event key. One implementation on
|
|
3
|
+
* purpose: the ingress, the settings UI and the docs' examples all have to agree
|
|
4
|
+
* on what `blog.post.*` means, and a second matcher is a silent divergence.
|
|
5
|
+
*/
|
|
6
|
+
export declare function eventKeyMatches(pattern: string, key: string): boolean;
|
|
7
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/integrations/events.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAKrE"}
|
|
@@ -1,7 +1,29 @@
|
|
|
1
1
|
import type * as React from 'react';
|
|
2
|
+
import type { ConnectorPermission } from './permissions';
|
|
3
|
+
import type { RequestFailureMode } from './request';
|
|
4
|
+
import type { Completeness, Cursor, RateLimitBudget } from './runtime';
|
|
5
|
+
import type { ConnectorSetting, ConnectorSettingValue } from './settings';
|
|
6
|
+
export { permissionActions, isDataPermission, isEventPermission, grants, connectorPermissions, connectorEntities, connectorSubscribesTo, connectorSubscribes, permissionsWrite, hasSensitivePermission, sortedPermissions, groupedPermissions, connectorGrantScopes, } from './permissions';
|
|
7
|
+
export type { ConnectorPermission, ConnectorPermissionAction, ConnectorResourceKind, PermissionBearing, } from './permissions';
|
|
8
|
+
export { eventKeyMatches } from './events';
|
|
9
|
+
export { CONNECTOR_RUNTIME_TOKEN_HEADER, ConnectorRuntimeTokenUnavailableError, connectorRuntimeToken, getConnectorRuntimeTokenSource, setConnectorRuntimeTokenSource, } from './runtime-token';
|
|
10
|
+
export type { ConnectorRuntimeTokenRequest, ConnectorRuntimeTokenSource } from './runtime-token';
|
|
11
|
+
export { createConnectionStore, listConnections, connectionKey, connectionStatus, connectionSettings, connectionRuns, assertSettingsAllowed, ConnectionSettingsError, CONNECTIONS_TABLE, SYNC_RUNS_TABLE, } from './store';
|
|
12
|
+
export type { ConnectionStore, ConnectionStoreOptions, ConnectionSaveInput, ConnectionBackedStatus, ConnectionSettingsIO, ConnectionRunsIO, ListConnectionsOptions, } from './store';
|
|
13
|
+
export { connectorSettings, isSettingSet, missingRequiredSettings, settingsStatus, setupStatusDetail, } from './settings';
|
|
14
|
+
export type { ConnectorSetting, ConnectorSettingType, ConnectorSettingOption, ConnectorSettingValue, SettingsReadiness, } from './settings';
|
|
15
|
+
export { runRequest, runEffect, requestPlaneSpec, hasRequestPlane, buyerIdempotencyKey, createRpcEffectLedger, RequestBlockedError, RequestPlaneError, } from './request';
|
|
16
|
+
export type { RequestFailureMode, DegradeReason, RequestOutcome, RequestAttempt, ResolvedRequestPlane, EffectLedger, EffectClaim, EffectClaimInput, EffectOutcome, EffectStatus, } from './request';
|
|
17
|
+
export { ConnectorHttpError, RateLimitExceededError, parseRetryAfter, backoffDelay, classify, statusNeedsBody, fetchWithRetry, isExpiring, paginate, createRateLimiter, sliceWindow, advanceWindow, serializeCursor, reconcileMirror, cursorCompleteness, } from './runtime';
|
|
18
|
+
export type { Cursor, Completeness, Verdict, AttemptOutcome, ClassifyOptions, BackoffOptions, FetchWithRetryOptions, MinimalResponse, PageResult, PaginateOptions, PaginateResult, RateLimitBudget, RateLimiter, RateLimiterOptions, MirrorRecord, ReconcileInput, ReconcileResult, } from './runtime';
|
|
2
19
|
/** How a connector authenticates to its provider. */
|
|
3
20
|
export type IntegrationAuthKind = 'oauth' | 'api-key' | 'mtls';
|
|
4
|
-
export
|
|
21
|
+
export declare const CONNECTOR_CATEGORIES: readonly ["database", "payments", "banking", "erp", "logistics", "marketplace", "ecommerce", "crm", "courses", "scheduling", "messaging", "analytics", "local", "ai", "automation"];
|
|
22
|
+
/** A shelf in the connector catalogue. See {@link CONNECTOR_CATEGORIES}. */
|
|
23
|
+
export type ConnectorCategory = (typeof CONNECTOR_CATEGORIES)[number];
|
|
24
|
+
/** Whether a string is a category the catalogue knows. */
|
|
25
|
+
export declare function isConnectorCategory(value: unknown): value is ConnectorCategory;
|
|
26
|
+
export type ConnectorPlane = 'agentic' | 'sync' | 'request';
|
|
5
27
|
/** Which side reaches for the other, from this app's point of view. */
|
|
6
28
|
export type ConnectorDirection = 'inbound' | 'outbound';
|
|
7
29
|
/** A tool the assistant gains once a connector is resolved on the agentic plane. */
|
|
@@ -20,32 +42,84 @@ export interface ConnectorCapability {
|
|
|
20
42
|
direction: SyncDirection;
|
|
21
43
|
triggers: SyncTrigger[];
|
|
22
44
|
}
|
|
23
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* One row of `public.plg_connections` (migration 029) — a tenant's connection to
|
|
47
|
+
* ONE account at one provider. Two accounts are two rows, separated by
|
|
48
|
+
* `instanceKey`; two resources inside one account are two streams of one row.
|
|
49
|
+
*
|
|
50
|
+
* There is no credential field because the table has no credential column.
|
|
51
|
+
*/
|
|
24
52
|
export interface ConnectionConfig {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/**
|
|
53
|
+
id?: string;
|
|
54
|
+
tenantId?: string;
|
|
55
|
+
/** Connector id, e.g. 'google-calendar', 'plugbank'. */
|
|
56
|
+
connectorId: string;
|
|
57
|
+
/** Which account at the provider. `''` for the connectors that only ever have one. */
|
|
58
|
+
instanceKey: string;
|
|
59
|
+
displayName?: string | null;
|
|
60
|
+
/** The tenant's switch. */
|
|
28
61
|
active: boolean;
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
62
|
+
/** Health, observed server-side — not a mirror of `active`. */
|
|
63
|
+
status: ConnectionStatusValue;
|
|
64
|
+
statusDetail?: string | null;
|
|
65
|
+
/** Provider-specific config, restricted to the connector's declared field keys. Never secrets. */
|
|
66
|
+
settings: Record<string, unknown>;
|
|
67
|
+
/** The provider's own id for the account — how an inbound webhook finds the tenant. */
|
|
68
|
+
providerAccountKey?: string | null;
|
|
69
|
+
/** Resume state keyed BY STREAM: Google keeps a syncToken per calendar, not per connection. */
|
|
70
|
+
cursors: Record<string, Cursor>;
|
|
71
|
+
lastSyncAt?: string | null;
|
|
72
|
+
createdAt?: string;
|
|
73
|
+
updatedAt?: string;
|
|
33
74
|
}
|
|
34
|
-
/**
|
|
75
|
+
/** Server-observed health of a connection (`plg_connections.status`). */
|
|
76
|
+
export type ConnectionStatusValue = 'pending' | 'connected' | 'error' | 'revoked';
|
|
77
|
+
/** One row of `public.plg_sync_runs` (migration 029) — one execution of the sync plane. */
|
|
35
78
|
export interface SyncRun {
|
|
36
79
|
id?: string;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
80
|
+
tenantId?: string;
|
|
81
|
+
/** Which connection ran. Without it two bank accounts share one history. */
|
|
82
|
+
connectionId: string;
|
|
83
|
+
connectorId: string;
|
|
84
|
+
direction: ConnectorDirection;
|
|
85
|
+
/** `trigger` is a reserved word in Postgres; the column is `trigger_kind`. */
|
|
86
|
+
triggerKind: SyncTrigger;
|
|
87
|
+
status: 'running' | 'success' | 'partial' | 'error';
|
|
88
|
+
/** Which resource inside the account this run touched. */
|
|
89
|
+
stream?: string | null;
|
|
90
|
+
fetched?: number;
|
|
91
|
+
written?: number;
|
|
92
|
+
/** Counters that are the connector's own: duplicates, discovered, period_from/to. */
|
|
93
|
+
stats?: Record<string, unknown>;
|
|
94
|
+
/** The cursor this run advanced to, serialised. */
|
|
95
|
+
cursor?: string | null;
|
|
96
|
+
/** Ties an outbound push to the inbound echo it will provoke. */
|
|
97
|
+
correlationId?: string | null;
|
|
98
|
+
/**
|
|
99
|
+
* What the run has to SAY, on any status (migration 031). `error` is what went
|
|
100
|
+
* WRONG; a successful run with something to report used to smuggle it through
|
|
101
|
+
* `stats.message`, which is the ad-hoc convention the generic table exists to
|
|
102
|
+
* prevent.
|
|
103
|
+
*/
|
|
104
|
+
message?: string | null;
|
|
105
|
+
error?: string | null;
|
|
106
|
+
startedAt?: string;
|
|
107
|
+
finishedAt?: string | null;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* What a connector's sync returns. Distinct from {@link SyncRun}: `completeness`
|
|
111
|
+
* is not a column, it is the verdict the engine needs BEFORE it decides whether
|
|
112
|
+
* records missing from this result may be cancelled locally.
|
|
113
|
+
*/
|
|
114
|
+
export interface SyncResult {
|
|
40
115
|
status: 'success' | 'partial' | 'error';
|
|
41
|
-
|
|
116
|
+
completeness: Completeness;
|
|
42
117
|
fetched?: number;
|
|
43
118
|
written?: number;
|
|
44
|
-
/**
|
|
45
|
-
cursor?:
|
|
119
|
+
/** Advanced cursor, to be written back under its stream key. */
|
|
120
|
+
cursor?: Cursor;
|
|
121
|
+
stats?: Record<string, unknown>;
|
|
46
122
|
error?: string;
|
|
47
|
-
startedAt?: string;
|
|
48
|
-
finishedAt?: string;
|
|
49
123
|
}
|
|
50
124
|
export interface TestConnectionResult {
|
|
51
125
|
ok: boolean;
|
|
@@ -67,35 +141,194 @@ export interface Connector {
|
|
|
67
141
|
capabilities: ConnectorCapability[];
|
|
68
142
|
/** Validate the stored credentials/config without syncing. */
|
|
69
143
|
testConnection?(config: ConnectionConfig): Promise<TestConnectionResult>;
|
|
70
|
-
/** Run a sync for the given direction;
|
|
144
|
+
/** Run a sync for the given direction; the caller files the run server-side. */
|
|
71
145
|
sync?(input: {
|
|
72
146
|
config: ConnectionConfig;
|
|
73
147
|
direction: SyncDirection;
|
|
74
148
|
trigger: SyncTrigger;
|
|
75
|
-
}): Promise<
|
|
149
|
+
}): Promise<SyncResult>;
|
|
76
150
|
}
|
|
77
|
-
/**
|
|
151
|
+
/**
|
|
152
|
+
* An input the connect step renders — **what authorizes the connection**, and
|
|
153
|
+
* nothing else.
|
|
154
|
+
*
|
|
155
|
+
* The rule, in one line: if the connection cannot be established without it, it
|
|
156
|
+
* is a field; if it changes how a live connection behaves, it is a
|
|
157
|
+
* {@link ConnectorSetting}. An API key is a field. The account identifier the
|
|
158
|
+
* key is scoped to is a field. Which payment methods the store accepts, or which
|
|
159
|
+
* postcode it ships from, is not — see ./settings.ts.
|
|
160
|
+
*
|
|
161
|
+
* `type: 'password'` is the marker the credential seam reads: a password field
|
|
162
|
+
* never reaches connector-author code and never reaches
|
|
163
|
+
* `plg_connections.settings`.
|
|
164
|
+
*/
|
|
78
165
|
export interface ConnectorField {
|
|
79
166
|
key: string;
|
|
80
167
|
label: string;
|
|
81
168
|
type: 'text' | 'password';
|
|
82
169
|
placeholder?: string;
|
|
170
|
+
/**
|
|
171
|
+
* Route this to the credential sink even though it is not masked.
|
|
172
|
+
*
|
|
173
|
+
* For the half of a credential PAIR that is not itself confidential — AppMax
|
|
174
|
+
* issues `client_id` alongside `client_secret`, and the id is useless to
|
|
175
|
+
* anyone without the secret. Masking it would only stop the merchant checking
|
|
176
|
+
* they pasted the right one; letting it fall through to the connector's own
|
|
177
|
+
* `saveConnection` would split one credential across two stores, which is
|
|
178
|
+
* how half of it ends up in a pool table.
|
|
179
|
+
*/
|
|
180
|
+
secret?: boolean;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* A door the merchant goes through AT THE PROVIDER before the connect step can
|
|
184
|
+
* be finished — and the reason the hub does not have to know which provider.
|
|
185
|
+
*
|
|
186
|
+
* Not every partner hands back a code on a redirect. AppMax issues the
|
|
187
|
+
* `client_id`/`client_secret` pair when the merchant INSTALLS our app inside
|
|
188
|
+
* their own AppMax admin ("chaves emitidas na instalação do app"), and only
|
|
189
|
+
* then shows them something to copy. An OAuth button there would be a button
|
|
190
|
+
* that lies: nothing comes back, and pressing it could never connect anything.
|
|
191
|
+
* What is true is a two-step gesture — go install it there, come back and paste
|
|
192
|
+
* what it showed you — so the gesture is declared and the panel renders it
|
|
193
|
+
* above {@link ConnectorDefinition.fields}.
|
|
194
|
+
*
|
|
195
|
+
* Declared and not hardcoded in the UI because the address is a fact about
|
|
196
|
+
* THIS app's registration at that provider, which the hub cannot know and a
|
|
197
|
+
* second connector with the same gesture will spell differently.
|
|
198
|
+
*
|
|
199
|
+
* An OAuth connector declares none: consent is the install.
|
|
200
|
+
*/
|
|
201
|
+
export interface ConnectorProviderInstall {
|
|
202
|
+
/** Where the merchant installs this app at the provider. Opened in a new tab. */
|
|
203
|
+
url: string;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* What the hub knows about who is connecting, handed to
|
|
207
|
+
* {@link ConnectorDefinition.startOAuth}.
|
|
208
|
+
*
|
|
209
|
+
* `tenantId` is a SELECTOR and never an assertion: the platform proves
|
|
210
|
+
* membership from the token it was called with and refuses anything outside it,
|
|
211
|
+
* so naming an organization here narrows which of the caller's own orgs the
|
|
212
|
+
* consent is for and can never widen it. Without it a merchant who belongs to
|
|
213
|
+
* two organizations cannot be told apart from one who belongs to neither.
|
|
214
|
+
*/
|
|
215
|
+
export interface ConnectorConnectContext {
|
|
216
|
+
tenantId?: string;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* An automation the connector owns rather than the tenant.
|
|
220
|
+
*
|
|
221
|
+
* "New sale → send it to Bling" is not a preference someone chose; it is what
|
|
222
|
+
* the integration IS. So it appears in the automations screen only while the
|
|
223
|
+
* connection is live, and the screen must not offer to delete it — a deleted
|
|
224
|
+
* row would leave the integration connected and silently half-wired, which
|
|
225
|
+
* reads as "Bling stopped working" weeks later. Disconnecting is the way out.
|
|
226
|
+
*/
|
|
227
|
+
export interface ConnectorManagedAutomation {
|
|
228
|
+
/** Domain event that fires it. Must be covered by `subscribesTo`. */
|
|
229
|
+
eventKey: string;
|
|
230
|
+
/** What the tenant is told it does ("Send the sale to Bling"). */
|
|
231
|
+
label: string;
|
|
232
|
+
/** Whether the tenant may switch it off and stay connected. Default false. */
|
|
233
|
+
optional?: boolean;
|
|
234
|
+
}
|
|
235
|
+
/** One call site that invokes a connector, and what happens there. */
|
|
236
|
+
export interface ConnectorInvocation {
|
|
237
|
+
/**
|
|
238
|
+
* Stable call-site key, `<plugin>.<surface>.<verb>` —
|
|
239
|
+
* `shop.checkout.shipping_quote`. Not an event key: nothing publishes it, it
|
|
240
|
+
* names a place in the code, and it is what a support conversation and a trace
|
|
241
|
+
* will call the same call.
|
|
242
|
+
*/
|
|
243
|
+
key: string;
|
|
244
|
+
/** What the tenant is told happens there ("O cliente pede as opções de frete"). */
|
|
245
|
+
label: string;
|
|
246
|
+
/**
|
|
247
|
+
* Which plane carries the call. Default `'request'` — the buyer is waiting.
|
|
248
|
+
* `'sync'` for the effects a request leads to (capture the payment, buy the
|
|
249
|
+
* label), which DO file a run.
|
|
250
|
+
*/
|
|
251
|
+
plane?: Extract<ConnectorPlane, 'request' | 'sync'>;
|
|
252
|
+
/** Sync moments only: what fires it, in `plg_sync_runs.trigger_kind`'s words. */
|
|
253
|
+
trigger?: SyncTrigger;
|
|
254
|
+
/**
|
|
255
|
+
* Which declared resources this call reaches — `permissions[].resource` names.
|
|
256
|
+
*
|
|
257
|
+
* The half of "quando ele age" that was missing: the section said *when* a
|
|
258
|
+
* connector is called and never *what it gets at*. Naming the resource rather
|
|
259
|
+
* than restating the access is what keeps the two from disagreeing — a moment
|
|
260
|
+
* cannot reach something the connector did not ask for, and the contract check
|
|
261
|
+
* enforces exactly that.
|
|
262
|
+
*/
|
|
263
|
+
touches?: string[];
|
|
264
|
+
}
|
|
265
|
+
/** The plane a moment runs on when it does not say. */
|
|
266
|
+
export declare function invocationPlane(moment: ConnectorInvocation): Extract<ConnectorPlane, 'request' | 'sync'>;
|
|
267
|
+
/**
|
|
268
|
+
* The two entries a first load has when the provider's catalogue is big enough
|
|
269
|
+
* that pulling it in line is not an option.
|
|
270
|
+
*
|
|
271
|
+
* Keeping them apart is forced by the budget, not by taste: at 3 req/s a
|
|
272
|
+
* ten-thousand-product catalogue is nearly an hour, and a connect screen that
|
|
273
|
+
* waits for it is a connect screen nobody finishes.
|
|
274
|
+
*/
|
|
275
|
+
export interface ConnectorFirstLoad {
|
|
276
|
+
/** How many records the fast phase pulls before answering. */
|
|
277
|
+
sampleSize: number;
|
|
278
|
+
/** Pages the fast phase may spend. A sample that pages forever is a backfill. */
|
|
279
|
+
samplePages?: number;
|
|
280
|
+
/** Which stream the phases walk (`'products'`, `'orders'`). */
|
|
281
|
+
stream: string;
|
|
83
282
|
}
|
|
84
283
|
export interface ConnectorStatus {
|
|
85
284
|
connected: boolean;
|
|
86
285
|
detail?: string;
|
|
286
|
+
/**
|
|
287
|
+
* What is wrong with a live connection, in sentences a merchant can act on.
|
|
288
|
+
*
|
|
289
|
+
* `detail` is one line and is what a LIST row has room for; a connection can
|
|
290
|
+
* be unwell in more than one way at once (the watch expired AND the timezone
|
|
291
|
+
* drifted), and a connector that had more to say used to say it in its own
|
|
292
|
+
* panel — which put status on the settings tab and left `detail` repeating the
|
|
293
|
+
* first item. Declaring both is what lets the surface render the list once and
|
|
294
|
+
* fall back to `detail` when there is nothing to enumerate.
|
|
295
|
+
*/
|
|
296
|
+
issues?: string[];
|
|
87
297
|
/** Which plane the live connection is running on (when connected). */
|
|
88
298
|
plane?: ConnectorPlane;
|
|
299
|
+
/**
|
|
300
|
+
* Connected, and unable to do its job until a required-to-operate setting is
|
|
301
|
+
* chosen — `plg_connections.status = 'pending'`.
|
|
302
|
+
*
|
|
303
|
+
* Not a third kind of "connected": the connection is real, the authorization
|
|
304
|
+
* happened, and nothing about it needs redoing. What is missing is
|
|
305
|
+
* configuration, which is why it is reported here rather than by pretending
|
|
306
|
+
* the connect step failed. See {@link settingsStatus}.
|
|
307
|
+
*/
|
|
308
|
+
needsSetup?: boolean;
|
|
309
|
+
/** Which setting keys are missing. Keys only — never what the tenant typed. */
|
|
310
|
+
missingSettings?: string[];
|
|
89
311
|
}
|
|
90
312
|
/**
|
|
91
313
|
* UI-facing connector descriptor. Built on the data-plane `Connector` concept
|
|
92
314
|
* (`pluginId` → `hostPluginId`), plus the control-plane hooks the unified
|
|
93
315
|
* Integrations hub calls. Lives in core so `PluginManifest.connectors` can type
|
|
94
|
-
* it; the rendering hub lives in `@fayz-ai/
|
|
316
|
+
* it; the rendering hub lives in `@fayz-ai/admin`.
|
|
95
317
|
*/
|
|
96
318
|
export interface ConnectorDefinition {
|
|
97
319
|
/** Stable connector id, e.g. 'google-calendar', 'plugbank'. */
|
|
98
320
|
id: string;
|
|
321
|
+
/**
|
|
322
|
+
* The platform catalogue slug this connector IS, when it differs from `id`.
|
|
323
|
+
*
|
|
324
|
+
* `id` names the implementation and `slug` names the provider, and they are
|
|
325
|
+
* only usually the same word: `plugbank` is the catalogue's `tecnospeed`.
|
|
326
|
+
* The tie matters twice — it is what lends
|
|
327
|
+
* an installed connector the catalogue's localized copy and brand mark, and
|
|
328
|
+
* what tells a slug a module declared in {@link PluginManifest.integrations}
|
|
329
|
+
* apart from one still to be built.
|
|
330
|
+
*/
|
|
331
|
+
catalogSlug?: string;
|
|
99
332
|
/** The plugin this connector extends, e.g. 'financial', 'agenda'. */
|
|
100
333
|
hostPluginId: string;
|
|
101
334
|
name: string;
|
|
@@ -111,33 +344,304 @@ export interface ConnectorDefinition {
|
|
|
111
344
|
authKind: IntegrationAuthKind;
|
|
112
345
|
/** Planes this connector can be honoured on. Default: `['sync']`. */
|
|
113
346
|
planes?: ConnectorPlane[];
|
|
347
|
+
/**
|
|
348
|
+
* Request plane only, and required there: how long the buyer may wait before
|
|
349
|
+
* `onFailure` applies. No default — see {@link requestPlaneSpec}.
|
|
350
|
+
*/
|
|
351
|
+
latencyBudgetMs?: number;
|
|
352
|
+
/**
|
|
353
|
+
* Request plane only, and required there. `'degrade'` serves a worse answer
|
|
354
|
+
* and the sale continues; `'block'` refuses the step and the buyer is told
|
|
355
|
+
* why. A field, not a decision re-taken in every screen that calls it.
|
|
356
|
+
*/
|
|
357
|
+
onFailure?: RequestFailureMode;
|
|
114
358
|
/** Default `'outbound'` — this app reaching a provider. */
|
|
115
359
|
direction?: ConnectorDirection;
|
|
116
360
|
/** What the assistant gains on the agentic plane — shown before connecting. */
|
|
117
361
|
agentTools?: ConnectorAgentTool[];
|
|
118
|
-
/**
|
|
362
|
+
/**
|
|
363
|
+
* **What this connector needs access to, and why** — the one declaration the
|
|
364
|
+
* consent view, "quando ele age" and (eventually) the minted credential all
|
|
365
|
+
* read. See ./permissions.ts.
|
|
366
|
+
*
|
|
367
|
+
* It SUBSUMES {@link entities} and {@link subscribesTo}: declare permissions
|
|
368
|
+
* and both are derived ({@link connectorEntities}, {@link connectorSubscribesTo}).
|
|
369
|
+
* Declaring a permission and a contradicting legacy field fails the contract
|
|
370
|
+
* check rather than being merged — a connector that says it writes `booking`
|
|
371
|
+
* in one field and never mentions `booking` in the other has a bug, and
|
|
372
|
+
* picking a winner would hide it.
|
|
373
|
+
*/
|
|
374
|
+
permissions?: ConnectorPermission[];
|
|
375
|
+
/**
|
|
376
|
+
* Canonical entities this connector touches ('booking', 'movement').
|
|
377
|
+
*
|
|
378
|
+
* Superseded by {@link permissions}, which says read or write rather than only
|
|
379
|
+
* the name. Still read for connectors built against an older core; when both
|
|
380
|
+
* are present they must name the same set. Read it through
|
|
381
|
+
* {@link connectorEntities}, never off the field.
|
|
382
|
+
*/
|
|
119
383
|
entities?: string[];
|
|
120
|
-
/**
|
|
121
|
-
|
|
384
|
+
/**
|
|
385
|
+
* The catalogue shelf, from the closed vocabulary in
|
|
386
|
+
* {@link CONNECTOR_CATEGORIES}. Typed rather than free-form because the badge
|
|
387
|
+
* that renders it is keyed by this exact string: an unlisted one renders no
|
|
388
|
+
* badge at all, which is invisible in review and invisible in the screenshot.
|
|
389
|
+
*/
|
|
390
|
+
category?: ConnectorCategory;
|
|
391
|
+
/**
|
|
392
|
+
* The provider's call budget for ONE account, declared rather than discovered.
|
|
393
|
+
*
|
|
394
|
+
* The scheduler owns the clock ({@link createRateLimiter}); a `sleep` inside a
|
|
395
|
+
* connector's fetch helper cannot express a daily ceiling and cannot be shared
|
|
396
|
+
* between two streams pulling at the same time. Declaring it is also what
|
|
397
|
+
* makes "never one request per product" a checkable statement instead of a
|
|
398
|
+
* habit — see {@link firstLoad}.
|
|
399
|
+
*/
|
|
400
|
+
rateLimit?: RateLimitBudget;
|
|
401
|
+
/**
|
|
402
|
+
* How the first load enters, when the catalogue is too large to fetch in line.
|
|
403
|
+
*
|
|
404
|
+
* Two phases, because they answer different questions: `sample` returns in
|
|
405
|
+
* seconds and is what a briefing or a generated storefront is designed
|
|
406
|
+
* against; `backfill` runs in the background against the budget and is what
|
|
407
|
+
* makes the mirror complete. Absent = the first load is just a sync.
|
|
408
|
+
*/
|
|
409
|
+
firstLoad?: ConnectorFirstLoad;
|
|
122
410
|
/** Provider documentation, linked from the connector's detail. */
|
|
123
411
|
docsUrl?: string;
|
|
124
|
-
/**
|
|
412
|
+
/**
|
|
413
|
+
* What AUTHORIZES the connection — the connect step renders exactly these and
|
|
414
|
+
* nothing more (api-key / mtls). An OAuth connector declares none: consent is
|
|
415
|
+
* the whole form.
|
|
416
|
+
*
|
|
417
|
+
* A connector whose credential lives in the Fayz platform declares none
|
|
418
|
+
* either, and the connect step says so rather than drawing an empty grid.
|
|
419
|
+
*/
|
|
125
420
|
fields?: ConnectorField[];
|
|
421
|
+
/**
|
|
422
|
+
* The provider-side install the merchant must do first, when there is one.
|
|
423
|
+
* Rendered above `fields`. See {@link ConnectorProviderInstall}.
|
|
424
|
+
*/
|
|
425
|
+
providerInstall?: ConnectorProviderInstall;
|
|
426
|
+
/**
|
|
427
|
+
* How the live connection BEHAVES — asked for only after it exists.
|
|
428
|
+
*
|
|
429
|
+
* The split is the point. Everything here changes with the season and none of
|
|
430
|
+
* it belongs in front of someone who has not connected yet; see ./settings.ts.
|
|
431
|
+
* Declaring a setting also allow-lists its key for
|
|
432
|
+
* `plg_connections.settings`, so a connector needs it in one place, not two.
|
|
433
|
+
*/
|
|
434
|
+
settings?: ConnectorSetting[];
|
|
435
|
+
/** Current values for the settings form. Required whenever `settings` is declared. */
|
|
436
|
+
getSettings?(): Promise<Record<string, unknown>>;
|
|
437
|
+
/** Persist a settings patch — merged by key, never replacing the jsonb. */
|
|
438
|
+
saveSettings?(values: Record<string, ConnectorSettingValue>): Promise<void>;
|
|
439
|
+
/**
|
|
440
|
+
* The moments this connector is CALLED at — the request plane's answer to
|
|
441
|
+
* "acionado quando?". See {@link ConnectorInvocation}.
|
|
442
|
+
*/
|
|
443
|
+
invokedAt?: ConnectorInvocation[];
|
|
444
|
+
/**
|
|
445
|
+
* Domain-event keys this connector reacts to — exact keys or `*`-suffixed
|
|
446
|
+
* prefixes (`agenda.booking_created`, `blog.post.*`). The ingress reads it to
|
|
447
|
+
* decide which facts are worth waking the connector for; without it every
|
|
448
|
+
* connector would have to be handed every event and filter it itself.
|
|
449
|
+
*
|
|
450
|
+
* Superseded by a `kind: 'event'` {@link permissions} entry carrying `listen`,
|
|
451
|
+
* which says the same thing plus why. Same agreement rule as {@link entities}.
|
|
452
|
+
* Read it through {@link connectorSubscribesTo}, never off the field.
|
|
453
|
+
*/
|
|
454
|
+
subscribesTo?: string[];
|
|
455
|
+
/** Automations this connector owns. See {@link ConnectorManagedAutomation}. */
|
|
456
|
+
managedAutomations?: ConnectorManagedAutomation[];
|
|
126
457
|
/** Current connection state for the status badge. */
|
|
127
458
|
getStatus(): Promise<ConnectorStatus>;
|
|
459
|
+
/**
|
|
460
|
+
* The same answer as {@link getStatus}, derived from a `plg_connections` row a
|
|
461
|
+
* caller already holds.
|
|
462
|
+
*
|
|
463
|
+
* Declaring it is what lets a list of N connectors resolve in ONE batched read
|
|
464
|
+
* (`listConnections`) instead of N `getStatus()` round trips — the connectors
|
|
465
|
+
* screen used to issue one request per row. Pure by contract: it is handed a
|
|
466
|
+
* row, it must not fetch.
|
|
467
|
+
*
|
|
468
|
+
* Absent means "my truth is not in that table" (Stripe Connect derives from
|
|
469
|
+
* the provider), and the list falls back to calling `getStatus()`. Use
|
|
470
|
+
* {@link connectionStatus} to write both from one function.
|
|
471
|
+
*/
|
|
472
|
+
statusFromConnection?(connection: ConnectionConfig | null): ConnectorStatus;
|
|
473
|
+
/** Which account at the provider `statusFromConnection` reads. Default `''`. */
|
|
474
|
+
instanceKey?: string;
|
|
128
475
|
/** Validate credentials without persisting (api-key / mtls). */
|
|
129
476
|
testConnection?(values: Record<string, string>): Promise<TestConnectionResult>;
|
|
130
477
|
/** Persist the connection (api-key / mtls). */
|
|
131
478
|
saveConnection?(values: Record<string, string>): Promise<void>;
|
|
132
|
-
/**
|
|
133
|
-
|
|
479
|
+
/**
|
|
480
|
+
* Begin an OAuth connect flow — returns the consent URL to redirect to.
|
|
481
|
+
*
|
|
482
|
+
* `context` is optional so a connector written against an older core keeps
|
|
483
|
+
* compiling; the hub always passes it. See {@link ConnectorConnectContext}.
|
|
484
|
+
*/
|
|
485
|
+
startOAuth?(redirectTo?: string, context?: ConnectorConnectContext): Promise<string>;
|
|
134
486
|
/** Tear down the connection. */
|
|
135
487
|
disconnect?(): Promise<void>;
|
|
488
|
+
/**
|
|
489
|
+
* What unplugging costs, when the answer is not obvious.
|
|
490
|
+
*
|
|
491
|
+
* A mirror that freezes is not a catalogue that is deleted, and a merchant
|
|
492
|
+
* who cannot tell the two apart never presses the button. Rendered beside
|
|
493
|
+
* Desconectar, which is the only place the question is ever asked.
|
|
494
|
+
*/
|
|
495
|
+
disconnectNote?: string;
|
|
496
|
+
/**
|
|
497
|
+
* When this connector syncs, in the merchant's words.
|
|
498
|
+
*
|
|
499
|
+
* The first question anyone has after connecting, and one the screen could
|
|
500
|
+
* not answer: the cadence lives in `plg_connector_schedules`, the on-write
|
|
501
|
+
* wake in a database trigger, the manual run in a button — three places, none
|
|
502
|
+
* of them a sentence. Rendered on Visão geral.
|
|
503
|
+
*/
|
|
504
|
+
howItSyncs?: string[];
|
|
136
505
|
/** Move an existing connection between planes (only when `planes` has both). */
|
|
137
506
|
setPlane?(plane: ConnectorPlane): Promise<void>;
|
|
138
|
-
/**
|
|
507
|
+
/**
|
|
508
|
+
* What this connection has DONE — newest first.
|
|
509
|
+
*
|
|
510
|
+
* The surface renders one history for every connector, so a connector
|
|
511
|
+
* declares where its runs are and nothing about how they look. Store-backed
|
|
512
|
+
* connectors get it from {@link connectionRuns}; a connector whose runs live
|
|
513
|
+
* in its own table maps them onto {@link SyncRun} here, which is the only
|
|
514
|
+
* shape the view knows.
|
|
515
|
+
*
|
|
516
|
+
* Absent means "I keep no history", and the surface offers no history tab —
|
|
517
|
+
* never an empty one, which would read as "nothing ever ran".
|
|
518
|
+
*/
|
|
519
|
+
listRuns?(options?: {
|
|
520
|
+
limit?: number;
|
|
521
|
+
}): Promise<SyncRun[]>;
|
|
522
|
+
/**
|
|
523
|
+
* The connector's own actions that PRODUCE a run — sync now, import a
|
|
524
|
+
* statement, pull events from a date.
|
|
525
|
+
*
|
|
526
|
+
* Deliberately separate from {@link ExtraPanel}: an import is something
|
|
527
|
+
* somebody does once, and it was rendered beside a settings form, which is
|
|
528
|
+
* where the two got confused. Rendered above the history, because the history
|
|
529
|
+
* is where its effect shows up.
|
|
530
|
+
*
|
|
531
|
+
* `onRan` reloads that history — call it after the action lands.
|
|
532
|
+
*/
|
|
533
|
+
RunActions?: React.ComponentType<{
|
|
534
|
+
onRan?: () => void;
|
|
535
|
+
}>;
|
|
536
|
+
/**
|
|
537
|
+
* The same thing as {@link RunActions}, DECLARED instead of drawn.
|
|
538
|
+
*
|
|
539
|
+
* What differs between two connectors is the sentence on the button and the
|
|
540
|
+
* call behind it. Spinner, toast, reloading the history, confirming a write at
|
|
541
|
+
* the provider — the surface owns all of it, or two integrations end up
|
|
542
|
+
* feeling like two products.
|
|
543
|
+
*
|
|
544
|
+
* Both seams render, so a connector can migrate one action at a time.
|
|
545
|
+
*/
|
|
546
|
+
syncActions?: ConnectorSyncAction[];
|
|
547
|
+
/**
|
|
548
|
+
* Record by record: what reached the provider, what is queued, what was
|
|
549
|
+
* refused. The seam the automations screen reads — a managed automation could
|
|
550
|
+
* only show that the fact FIRED, never that anything arrived.
|
|
551
|
+
*/
|
|
552
|
+
listDeliveries?(options?: {
|
|
553
|
+
eventKey?: string;
|
|
554
|
+
limit?: number;
|
|
555
|
+
}): Promise<ConnectorDelivery[]>;
|
|
556
|
+
/**
|
|
557
|
+
* The connector's own CONFIGURATION UI, rendered on the Settings tab.
|
|
558
|
+
*
|
|
559
|
+
* Configuration only: which Google calendar maps to which professional, which
|
|
560
|
+
* warehouse a stream belongs to. Status belongs in {@link ConnectorStatus},
|
|
561
|
+
* history in {@link listRuns}, and a one-off action in {@link RunActions} —
|
|
562
|
+
* this panel used to hold all four at once.
|
|
563
|
+
*/
|
|
139
564
|
ExtraPanel?: React.ComponentType;
|
|
140
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* One RECORD's journey to the provider — "cadastrei aqui, foi?".
|
|
568
|
+
*
|
|
569
|
+
* A {@link SyncRun} says "12 of 20 filed", which is the number that does not
|
|
570
|
+
* help the person holding order 1042 in their hand.
|
|
571
|
+
*/
|
|
572
|
+
export interface ConnectorDelivery {
|
|
573
|
+
/** The record, as the merchant would name it: "Pedido 1042", "Costela defumada". */
|
|
574
|
+
subject: string;
|
|
575
|
+
/** This app's id for it, when a screen wants to link back to the record. */
|
|
576
|
+
subjectId?: string;
|
|
577
|
+
/** `pending` is a real answer: queued, not yet sent — what the merchant sees
|
|
578
|
+
* in the fifteen minutes between a sale and the clock. */
|
|
579
|
+
status: 'delivered' | 'pending' | 'failed';
|
|
580
|
+
/** Why it is pending or failed, in the merchant's language. */
|
|
581
|
+
detail?: string;
|
|
582
|
+
/** The id or number it got at the provider. The one thing checkable on both screens. */
|
|
583
|
+
externalId?: string;
|
|
584
|
+
/** When it was delivered, or when the record was created if it was not. */
|
|
585
|
+
at?: string;
|
|
586
|
+
}
|
|
587
|
+
/** What a run actually did. `partial` and `error` are toasted as such. */
|
|
588
|
+
export interface ConnectorSyncOutcome {
|
|
589
|
+
message: string;
|
|
590
|
+
status?: 'success' | 'partial' | 'error';
|
|
591
|
+
}
|
|
592
|
+
/** One thing a merchant can make a connection DO. Declared rather than drawn —
|
|
593
|
+
* see {@link ConnectorDefinition.syncActions}. */
|
|
594
|
+
export interface ConnectorSyncAction {
|
|
595
|
+
/** Stable, for React keys and for telling two actions apart in a test. */
|
|
596
|
+
key: string;
|
|
597
|
+
/** The button. A verb, in the merchant's language: "Trazer catálogo do Bling". */
|
|
598
|
+
label: string;
|
|
599
|
+
/** Which way the data moves. Outbound is a write the merchant cannot undo
|
|
600
|
+
* from this screen, which is what `confirm` is for. */
|
|
601
|
+
direction: 'inbound' | 'outbound';
|
|
602
|
+
/** One line under the label, when the label alone cannot carry it. */
|
|
603
|
+
description?: string;
|
|
604
|
+
/**
|
|
605
|
+
* The action somebody came here to press — the one that is right on an
|
|
606
|
+
* ordinary day. At most one. The rest fold under "Outras ações": five equal
|
|
607
|
+
* buttons is a menu the reader has to grade themselves.
|
|
608
|
+
*/
|
|
609
|
+
primary?: boolean;
|
|
610
|
+
/** Ask first. Only for what cannot be taken back. */
|
|
611
|
+
confirm?: {
|
|
612
|
+
title: string;
|
|
613
|
+
body: string;
|
|
614
|
+
cta: string;
|
|
615
|
+
};
|
|
616
|
+
/**
|
|
617
|
+
* Do it. What it returns becomes the toast — use the run's own sentence, so
|
|
618
|
+
* the merchant reads the same words here and in the history below.
|
|
619
|
+
*
|
|
620
|
+
* Return a {@link ConnectorSyncOutcome} when the run can partly fail: a push
|
|
621
|
+
* that filed 0 of 9 answers 200 with a sentence, and a surface that reads only
|
|
622
|
+
* "it did not throw" celebrates it. The verdict is already computed where the
|
|
623
|
+
* work happened; this is how it reaches the screen.
|
|
624
|
+
*/
|
|
625
|
+
run(): Promise<string | ConnectorSyncOutcome | void>;
|
|
626
|
+
/**
|
|
627
|
+
* How many records are still waiting for this action.
|
|
628
|
+
*
|
|
629
|
+
* `0` means there is nothing left to send, and the surface says so — a check
|
|
630
|
+
* and a spent button, not a live control that would file nothing. A push whose
|
|
631
|
+
* queue is an absence can always answer this; a pull cannot know what changed
|
|
632
|
+
* at the provider, so it declares nothing and stays enabled.
|
|
633
|
+
*/
|
|
634
|
+
pending?(): Promise<number | null> | number | null;
|
|
635
|
+
/** Whether to offer it at all. Hidden, not disabled: a greyed button reads as
|
|
636
|
+
* something the reader failed to do. Absent means always. */
|
|
637
|
+
available?(): Promise<boolean> | boolean;
|
|
638
|
+
/** A screen of its own, for an action that needs choices first. Replaces the
|
|
639
|
+
* row while open; call `onRan` when something actually happened. */
|
|
640
|
+
Component?: React.ComponentType<{
|
|
641
|
+
onClose(): void;
|
|
642
|
+
onRan?(): void;
|
|
643
|
+
}>;
|
|
644
|
+
}
|
|
141
645
|
/** Planes a connector supports — the contract's default is the sync pipeline. */
|
|
142
646
|
export declare function connectorPlanes(def: Pick<ConnectorDefinition, 'planes'>): ConnectorPlane[];
|
|
143
647
|
/**
|