@zackbart/connecta 0.35.0 → 0.36.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/CHANGELOG.md +55 -0
- package/README.md +8 -4
- package/bin/version.mjs +1 -1
- package/dist/auth/downstream-oauth.js +71 -79
- package/dist/auth/static-oauth.js +104 -26
- package/dist/connectors/api-connector.d.ts +17 -0
- package/dist/connectors/api-connector.js +3 -1
- package/dist/http/client.js +1 -1
- package/dist/http/paging.js +1 -2
- package/dist/http/services.js +1 -1
- package/dist/http/tools.js +0 -4
- package/dist/operator-ui/contract.d.ts +1 -0
- package/dist/operator-ui/generated.js +4 -4
- package/dist/providers/_shared/google/kit.js +29 -139
- package/dist/providers/_shared/rest/kit.js +4 -404
- package/dist/providers/docs/tools.js +1 -2
- package/dist/providers/drive/api.js +1 -1
- package/dist/providers/forms/tools.js +1 -2
- package/dist/providers/gmail/tools.js +2 -2
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/quickbooks/api.js +299 -0
- package/dist/providers/quickbooks/index.d.ts +13 -0
- package/dist/providers/quickbooks/index.js +93 -0
- package/dist/providers/quickbooks/lib/query.js +118 -0
- package/dist/providers/quickbooks/lib/writes.js +168 -0
- package/dist/providers/quickbooks/safety.js +222 -0
- package/dist/providers/quickbooks/skill.generated.js +5 -0
- package/dist/providers/quickbooks/tools.js +117 -0
- package/dist/providers/sheets/tools.js +1 -2
- package/dist/providers/slides/tools.js +2 -2
- package/dist/providers/vercel/index.js +1 -2
- package/dist/routes/oauth.js +3 -0
- package/dist/runtime/call.js +0 -4
- package/dist/skills.js +0 -1
- package/dist/types.d.ts +2 -0
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +0 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/README.md +1 -0
- package/documentation/architecture.md +134 -301
- package/documentation/auth.md +47 -17
- package/documentation/integrating.md +1 -1
- package/documentation/meta-tools.md +1 -1
- package/documentation/operator-ui.md +16 -3
- package/documentation/providers.md +382 -0
- package/package.json +7 -8
- package/templates/node/package.json +1 -1
- package/dist/operator-ui/agents.d.ts +0 -75
- package/dist/operator-ui/agents.js +0 -114
- package/dist/operator-ui/config-summary.js +0 -566
- package/dist/operator-ui/connection-map.js +0 -378
- package/dist/operator-ui/endpoints.js +0 -212
- package/dist/operator-ui/fix-prompts.d.ts +0 -18
- package/dist/operator-ui/fix-prompts.js +0 -79
- package/dist/operator-ui/health.js +0 -52
- package/dist/operator-ui/member-page.js +0 -97
- package/dist/operator-ui/overview.js +0 -126
- package/dist/operator-ui/setup-commands.js +0 -47
- package/dist/operator-ui/view.d.ts +0 -378
- package/dist/operator-ui/view.js +0 -631
- package/dist/providers/_shared/rest/dispatch.js +0 -21
- package/dist/providers/_shared/rest/tools.js +0 -592
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import type { OperatorAgent, OperatorUiContractV2 } from "./contract.js";
|
|
2
|
-
import { type Notice, type RequestFailureFacts, type Tone } from "./view.js";
|
|
3
|
-
/**
|
|
4
|
-
* The Tokens page's rows, computed from the slot list and contract v2 alone.
|
|
5
|
-
* Agents are declared in code: a row's only controls are its token's issue,
|
|
6
|
-
* rotate and revoke, so nothing here creates, renames or rebinds one.
|
|
7
|
-
*/
|
|
8
|
-
/** One declared agent's token slot, as `GET /ui/access-tokens` returns it. */
|
|
9
|
-
export type AgentSlot = ({
|
|
10
|
-
name: string;
|
|
11
|
-
state: "none";
|
|
12
|
-
} | {
|
|
13
|
-
name: string;
|
|
14
|
-
state: "issued";
|
|
15
|
-
issuedAt: string;
|
|
16
|
-
} | {
|
|
17
|
-
name: string;
|
|
18
|
-
state: "revoked";
|
|
19
|
-
revokedAt: string;
|
|
20
|
-
}) & {
|
|
21
|
-
/**
|
|
22
|
-
* The route's opaque slot revision; it changes on every slot commit (P3b,
|
|
23
|
-
* #837). A slot read without one is unresolved and never acted on.
|
|
24
|
-
*/
|
|
25
|
-
revision?: string;
|
|
26
|
-
};
|
|
27
|
-
/** Issue and rotate are the same request; the slot's state names it. */
|
|
28
|
-
export type SlotAction = "issue" | "rotate" | "revoke";
|
|
29
|
-
export interface AgentRow {
|
|
30
|
-
name: string;
|
|
31
|
-
/** Pools it belongs to, from `agents[].pools`; empty when the contract does not list it. */
|
|
32
|
-
pools: string[];
|
|
33
|
-
credentialTypes: OperatorAgent["credentialTypes"];
|
|
34
|
-
slot: AgentSlot | null;
|
|
35
|
-
/**
|
|
36
|
-
* Whether `slot` comes from the live slot list. Only a live slot can be
|
|
37
|
-
* acted on: one known only from the contract may be stale, so its controls
|
|
38
|
-
* are disabled until a refresh lists it.
|
|
39
|
-
*/
|
|
40
|
-
live: boolean;
|
|
41
|
-
/** Why its controls are off, or null when they work. */
|
|
42
|
-
blocked: string | null;
|
|
43
|
-
/** Its latest activity row; null is "never" (or history that is off). */
|
|
44
|
-
lastSeenAt: string | null;
|
|
45
|
-
actions: SlotAction[];
|
|
46
|
-
}
|
|
47
|
-
export declare function slotActions(slot: Pick<AgentSlot, "state">): SlotAction[];
|
|
48
|
-
/**
|
|
49
|
-
* One agent's slot, resolved once for both what the row shows and what an
|
|
50
|
-
* action may do. The live slot list is authoritative; the contract's copy is
|
|
51
|
-
* shown only for an agent the list does not have, and is never acted on.
|
|
52
|
-
*/
|
|
53
|
-
export declare function resolveSlot(contract: OperatorUiContractV2 | null, slots: AgentSlot[], name: string): {
|
|
54
|
-
slot: AgentSlot;
|
|
55
|
-
live: boolean;
|
|
56
|
-
} | null;
|
|
57
|
-
/**
|
|
58
|
-
* One row per declared agent, in the slot list's order, then any agent only
|
|
59
|
-
* the contract lists. The contract adds pools and last seen.
|
|
60
|
-
*/
|
|
61
|
-
export declare function agentRows(contract: OperatorUiContractV2 | null, slots: AgentSlot[], unresolved?: readonly string[]): AgentRow[];
|
|
62
|
-
export declare function slotBadge(slot: Pick<AgentSlot, "state"> | null): {
|
|
63
|
-
label: string;
|
|
64
|
-
tone: Tone;
|
|
65
|
-
};
|
|
66
|
-
/** When the slot last changed, issued or revoked (its badge says which); a dash when it never has. */
|
|
67
|
-
export declare function slotSince(slot: AgentSlot | null, format: (value: string) => string): string;
|
|
68
|
-
export declare function lastSeenLabel(lastSeenAt: string | null, format: (value: string) => string): string;
|
|
69
|
-
/**
|
|
70
|
-
* Why a token operation did not land, in fixed sentences keyed by status.
|
|
71
|
-
* `outcome_unknown` (503) and `aborted` (499) are failures like any other and
|
|
72
|
-
* are never retried for the operator: an unknown rotation returned no secret,
|
|
73
|
-
* and only a new, deliberate rotation produces one.
|
|
74
|
-
*/
|
|
75
|
-
export declare function tokenFailureNotice(action: SlotAction, name: string, facts: RequestFailureFacts, productName: string): Notice;
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { failure } from "./view.js";
|
|
2
|
-
/** Why a row's controls are disabled when its slot is not in the live list. */
|
|
3
|
-
const SLOT_UNAVAILABLE = "Token state unknown. Refresh.";
|
|
4
|
-
/** Why a row's controls are disabled until a fresh list read resolves its slot. */
|
|
5
|
-
const SLOT_UNRESOLVED = "Refresh to continue";
|
|
6
|
-
export function slotActions(slot) {
|
|
7
|
-
return slot.state === "issued" ? ["rotate", "revoke"] : ["issue"];
|
|
8
|
-
}
|
|
9
|
-
function contractSlot(agent) {
|
|
10
|
-
return agent.token ? { name: agent.name, ...agent.token } : null;
|
|
11
|
-
}
|
|
12
|
-
function maintainerAgents(contract) {
|
|
13
|
-
return contract?.role === "maintainer" ? contract.agents : [];
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* One agent's slot, resolved once for both what the row shows and what an
|
|
17
|
-
* action may do. The live slot list is authoritative; the contract's copy is
|
|
18
|
-
* shown only for an agent the list does not have, and is never acted on.
|
|
19
|
-
*/
|
|
20
|
-
export function resolveSlot(contract, slots, name) {
|
|
21
|
-
const listed = slots.find((slot) => slot.name === name);
|
|
22
|
-
if (listed)
|
|
23
|
-
return { slot: listed, live: true };
|
|
24
|
-
const agent = maintainerAgents(contract).find((candidate) => candidate.name === name);
|
|
25
|
-
const slot = agent && contractSlot(agent);
|
|
26
|
-
return slot ? { slot, live: false } : null;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* One row per declared agent, in the slot list's order, then any agent only
|
|
30
|
-
* the contract lists. The contract adds pools and last seen.
|
|
31
|
-
*/
|
|
32
|
-
export function agentRows(contract, slots, unresolved = []) {
|
|
33
|
-
const agents = maintainerAgents(contract);
|
|
34
|
-
const declared = new Map(agents.map((agent) => [agent.name, agent]));
|
|
35
|
-
const names = [...slots.map((slot) => slot.name), ...agents.map((agent) => agent.name)];
|
|
36
|
-
return [...new Set(names)].map((name) => {
|
|
37
|
-
const { slot, live } = resolveSlot(contract, slots, name) ?? { slot: null, live: false };
|
|
38
|
-
const agent = declared.get(name);
|
|
39
|
-
return {
|
|
40
|
-
name,
|
|
41
|
-
pools: agent?.pools ?? [],
|
|
42
|
-
credentialTypes: agent?.credentialTypes ?? [],
|
|
43
|
-
slot,
|
|
44
|
-
live,
|
|
45
|
-
blocked: !slot
|
|
46
|
-
? "Agent tokens aren't configured."
|
|
47
|
-
: !live
|
|
48
|
-
? SLOT_UNAVAILABLE
|
|
49
|
-
: unresolved.includes(name) || !slot.revision
|
|
50
|
-
? SLOT_UNRESOLVED
|
|
51
|
-
: null,
|
|
52
|
-
lastSeenAt: agent?.lastSeenAt ?? null,
|
|
53
|
-
actions: slot ? slotActions(slot) : [],
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
export function slotBadge(slot) {
|
|
58
|
-
if (!slot)
|
|
59
|
-
return { label: "Not configured", tone: "neutral" };
|
|
60
|
-
if (slot.state === "issued")
|
|
61
|
-
return { label: "Issued", tone: "ok" };
|
|
62
|
-
if (slot.state === "revoked")
|
|
63
|
-
return { label: "Revoked", tone: "warn" };
|
|
64
|
-
return { label: "No token", tone: "neutral" };
|
|
65
|
-
}
|
|
66
|
-
/** When the slot last changed, issued or revoked (its badge says which); a dash when it never has. */
|
|
67
|
-
export function slotSince(slot, format) {
|
|
68
|
-
if (slot?.state === "issued")
|
|
69
|
-
return format(slot.issuedAt);
|
|
70
|
-
if (slot?.state === "revoked")
|
|
71
|
-
return format(slot.revokedAt);
|
|
72
|
-
return "—";
|
|
73
|
-
}
|
|
74
|
-
export function lastSeenLabel(lastSeenAt, format) {
|
|
75
|
-
return lastSeenAt ? format(lastSeenAt) : "never";
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Why a token operation did not land, in fixed sentences keyed by status.
|
|
79
|
-
* `outcome_unknown` (503) and `aborted` (499) are failures like any other and
|
|
80
|
-
* are never retried for the operator: an unknown rotation returned no secret,
|
|
81
|
-
* and only a new, deliberate rotation produces one.
|
|
82
|
-
*/
|
|
83
|
-
export function tokenFailureNotice(action, name, facts, productName) {
|
|
84
|
-
if (facts.kind === "session")
|
|
85
|
-
return failure("Session ended. Sign in again.");
|
|
86
|
-
if (facts.kind === "forbidden")
|
|
87
|
-
return failure("You can't manage agent tokens.");
|
|
88
|
-
if (facts.kind === "stale") {
|
|
89
|
-
return failure(`${name}'s token changed, so nothing was sent. Try again.`);
|
|
90
|
-
}
|
|
91
|
-
if (facts.kind === "network") {
|
|
92
|
-
return failure(`Couldn't reach ${productName}. Refresh to check ${name}'s token.`);
|
|
93
|
-
}
|
|
94
|
-
if (facts.status === 503) {
|
|
95
|
-
return failure(action === "revoke"
|
|
96
|
-
? `Revoke result unknown for ${name}. Revoke again to be sure.`
|
|
97
|
-
: `${action === "issue" ? "Issue" : "Rotate"} result unknown for ${name}. No secret came back, so rotate again.`);
|
|
98
|
-
}
|
|
99
|
-
if (facts.status === 499) {
|
|
100
|
-
return failure(action === "revoke"
|
|
101
|
-
? `The request ended before ${name}'s revoke finished. Refresh to check its token.`
|
|
102
|
-
: `The request ended before ${name}'s token arrived. Refresh to check its token.`);
|
|
103
|
-
}
|
|
104
|
-
// The route's compare-and-swap refused it: the slot moved after the list was read.
|
|
105
|
-
if (facts.status === 409 && facts.code === "slot_changed")
|
|
106
|
-
return failure("Changed since you looked. Refresh.");
|
|
107
|
-
if (facts.status === 409)
|
|
108
|
-
return failure(`${name}'s token changed. Reload and try again.`);
|
|
109
|
-
if (facts.status === 404)
|
|
110
|
-
return failure(`${name} is no longer declared in code. Reload the page.`);
|
|
111
|
-
return action === "revoke"
|
|
112
|
-
? failure(`Couldn't revoke ${name}'s token. Reload and try again.`)
|
|
113
|
-
: failure(`Couldn't issue a token for ${name}. Reload and try again.`);
|
|
114
|
-
}
|