@voyant-travel/action-ledger 0.104.10
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/LICENSE +201 -0
- package/dist/canary.d.ts +17 -0
- package/dist/canary.d.ts.map +1 -0
- package/dist/canary.js +77 -0
- package/dist/capability.d.ts +73 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +206 -0
- package/dist/fingerprint.d.ts +26 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +55 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/request-context.d.ts +136 -0
- package/dist/request-context.d.ts.map +1 -0
- package/dist/request-context.js +237 -0
- package/dist/route-schemas.d.ts +745 -0
- package/dist/route-schemas.d.ts.map +1 -0
- package/dist/route-schemas.js +428 -0
- package/dist/routes.d.ts +1602 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +271 -0
- package/dist/schema.d.ts +1759 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +237 -0
- package/dist/service/approval-status.d.ts +3 -0
- package/dist/service/approval-status.d.ts.map +1 -0
- package/dist/service/approval-status.js +14 -0
- package/dist/service/cursors.d.ts +22 -0
- package/dist/service/cursors.d.ts.map +1 -0
- package/dist/service/cursors.js +48 -0
- package/dist/service/entries.d.ts +9 -0
- package/dist/service/entries.d.ts.map +1 -0
- package/dist/service/entries.js +75 -0
- package/dist/service/errors.d.ts +20 -0
- package/dist/service/errors.d.ts.map +1 -0
- package/dist/service/errors.js +36 -0
- package/dist/service/listing.d.ts +7 -0
- package/dist/service/listing.d.ts.map +1 -0
- package/dist/service/listing.js +77 -0
- package/dist/service/predicates.d.ts +8 -0
- package/dist/service/predicates.d.ts.map +1 -0
- package/dist/service/predicates.js +368 -0
- package/dist/service/records.d.ts +6 -0
- package/dist/service/records.d.ts.map +1 -0
- package/dist/service/records.js +51 -0
- package/dist/service/relay-lifecycle.d.ts +7 -0
- package/dist/service/relay-lifecycle.d.ts.map +1 -0
- package/dist/service/relay-lifecycle.js +78 -0
- package/dist/service/relay-outbox.d.ts +15 -0
- package/dist/service/relay-outbox.d.ts.map +1 -0
- package/dist/service/relay-outbox.js +15 -0
- package/dist/service/types.d.ts +249 -0
- package/dist/service/types.d.ts.map +1 -0
- package/dist/service/types.js +1 -0
- package/dist/service.d.ts +40 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +283 -0
- package/dist/timeline.d.ts +67 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +79 -0
- package/package.json +93 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { typeId } from "@voyant-travel/db/lib/typeid-column";
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
3
|
+
import { boolean, index, integer, jsonb, pgEnum, pgTable, text, timestamp, uniqueIndex, } from "drizzle-orm/pg-core";
|
|
4
|
+
export const actionLedgerActionKindEnum = pgEnum("action_ledger_action_kind", [
|
|
5
|
+
"read",
|
|
6
|
+
"create",
|
|
7
|
+
"update",
|
|
8
|
+
"delete",
|
|
9
|
+
"execute",
|
|
10
|
+
"approve",
|
|
11
|
+
"reject",
|
|
12
|
+
"reverse",
|
|
13
|
+
"compensate",
|
|
14
|
+
"duplicate",
|
|
15
|
+
]);
|
|
16
|
+
export const actionLedgerStatusEnum = pgEnum("action_ledger_status", [
|
|
17
|
+
"requested",
|
|
18
|
+
"awaiting_approval",
|
|
19
|
+
"approved",
|
|
20
|
+
"denied",
|
|
21
|
+
"succeeded",
|
|
22
|
+
"failed",
|
|
23
|
+
"reversed",
|
|
24
|
+
"compensated",
|
|
25
|
+
"expired",
|
|
26
|
+
"cancelled",
|
|
27
|
+
"superseded",
|
|
28
|
+
]);
|
|
29
|
+
export const actionLedgerRiskEnum = pgEnum("action_ledger_risk", [
|
|
30
|
+
"low",
|
|
31
|
+
"medium",
|
|
32
|
+
"high",
|
|
33
|
+
"critical",
|
|
34
|
+
]);
|
|
35
|
+
export const actionLedgerPrincipalTypeEnum = pgEnum("action_ledger_principal_type", [
|
|
36
|
+
"user",
|
|
37
|
+
"api_key",
|
|
38
|
+
"agent",
|
|
39
|
+
"workflow",
|
|
40
|
+
"system",
|
|
41
|
+
]);
|
|
42
|
+
export const actionLedgerRelayStatusEnum = pgEnum("action_ledger_relay_status", [
|
|
43
|
+
"pending",
|
|
44
|
+
"processing",
|
|
45
|
+
"succeeded",
|
|
46
|
+
"failed",
|
|
47
|
+
"dead_letter",
|
|
48
|
+
]);
|
|
49
|
+
export const actionLedgerRedactionStatusEnum = pgEnum("action_ledger_redaction_status", [
|
|
50
|
+
"none",
|
|
51
|
+
"redacted",
|
|
52
|
+
"tombstoned",
|
|
53
|
+
"crypto_shredded",
|
|
54
|
+
]);
|
|
55
|
+
export const actionLedgerApprovalStatusEnum = pgEnum("action_ledger_approval_status", [
|
|
56
|
+
"pending",
|
|
57
|
+
"approved",
|
|
58
|
+
"denied",
|
|
59
|
+
"expired",
|
|
60
|
+
"cancelled",
|
|
61
|
+
"superseded",
|
|
62
|
+
]);
|
|
63
|
+
export const actionLedgerReversalKindEnum = pgEnum("action_ledger_reversal_kind", [
|
|
64
|
+
"none",
|
|
65
|
+
"revert",
|
|
66
|
+
"compensate",
|
|
67
|
+
"domain_command",
|
|
68
|
+
]);
|
|
69
|
+
export const actionLedgerReversalStateEnum = pgEnum("action_ledger_reversal_state", [
|
|
70
|
+
"not_reversible",
|
|
71
|
+
"available",
|
|
72
|
+
"requested",
|
|
73
|
+
"running",
|
|
74
|
+
"completed",
|
|
75
|
+
"failed",
|
|
76
|
+
"expired",
|
|
77
|
+
]);
|
|
78
|
+
export const actionLedgerReversalOutcomeEnum = pgEnum("action_ledger_reversal_outcome", [
|
|
79
|
+
"full",
|
|
80
|
+
"partial",
|
|
81
|
+
"failed",
|
|
82
|
+
]);
|
|
83
|
+
export const actionLedgerEntries = pgTable("action_ledger_entries", {
|
|
84
|
+
id: typeId("action_ledger_entries"),
|
|
85
|
+
occurredAt: timestamp("occurred_at", { withTimezone: true }).notNull().defaultNow(),
|
|
86
|
+
actionName: text("action_name").notNull(),
|
|
87
|
+
actionVersion: text("action_version").notNull(),
|
|
88
|
+
actionKind: actionLedgerActionKindEnum("action_kind").notNull(),
|
|
89
|
+
status: actionLedgerStatusEnum("status").notNull(),
|
|
90
|
+
evaluatedRisk: actionLedgerRiskEnum("evaluated_risk").notNull(),
|
|
91
|
+
actorType: text("actor_type"),
|
|
92
|
+
principalType: actionLedgerPrincipalTypeEnum("principal_type").notNull(),
|
|
93
|
+
principalId: text("principal_id").notNull(),
|
|
94
|
+
principalSubtype: text("principal_subtype"),
|
|
95
|
+
sessionId: text("session_id"),
|
|
96
|
+
apiTokenId: text("api_token_id"),
|
|
97
|
+
internalRequest: boolean("internal_request").notNull().default(false),
|
|
98
|
+
delegatedByPrincipalType: actionLedgerPrincipalTypeEnum("delegated_by_principal_type"),
|
|
99
|
+
delegatedByPrincipalId: text("delegated_by_principal_id"),
|
|
100
|
+
delegationId: text("delegation_id"),
|
|
101
|
+
callerType: text("caller_type"),
|
|
102
|
+
organizationId: text("organization_id"),
|
|
103
|
+
routeOrToolName: text("route_or_tool_name"),
|
|
104
|
+
workflowRunId: text("workflow_run_id"),
|
|
105
|
+
workflowStepId: text("workflow_step_id"),
|
|
106
|
+
correlationId: text("correlation_id"),
|
|
107
|
+
causationActionId: text("causation_action_id"),
|
|
108
|
+
idempotencyScope: text("idempotency_scope"),
|
|
109
|
+
idempotencyKey: text("idempotency_key"),
|
|
110
|
+
idempotencyFingerprint: text("idempotency_fingerprint"),
|
|
111
|
+
targetType: text("target_type").notNull(),
|
|
112
|
+
targetId: text("target_id").notNull(),
|
|
113
|
+
capabilityId: text("capability_id"),
|
|
114
|
+
capabilityVersion: text("capability_version"),
|
|
115
|
+
authorizationSource: text("authorization_source"),
|
|
116
|
+
approvalId: text("approval_id"),
|
|
117
|
+
amendsActionId: text("amends_action_id"),
|
|
118
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
119
|
+
}, (table) => [
|
|
120
|
+
index("idx_action_ledger_entries_principal").on(table.principalType, table.principalId, table.occurredAt),
|
|
121
|
+
index("idx_action_ledger_entries_api_token").on(table.apiTokenId, table.occurredAt),
|
|
122
|
+
index("idx_action_ledger_entries_session").on(table.sessionId, table.occurredAt),
|
|
123
|
+
index("idx_action_ledger_entries_target").on(table.targetType, table.targetId, table.occurredAt),
|
|
124
|
+
index("idx_action_ledger_entries_workflow").on(table.workflowRunId, table.workflowStepId, table.occurredAt),
|
|
125
|
+
index("idx_action_ledger_entries_correlation").on(table.correlationId, table.occurredAt),
|
|
126
|
+
index("idx_action_ledger_entries_causation").on(table.causationActionId),
|
|
127
|
+
index("idx_action_ledger_entries_control_state").on(table.evaluatedRisk, table.status, table.occurredAt),
|
|
128
|
+
index("idx_action_ledger_entries_capability").on(table.capabilityId, table.capabilityVersion, table.occurredAt),
|
|
129
|
+
uniqueIndex("idx_action_ledger_entries_idempotency")
|
|
130
|
+
.on(table.idempotencyScope, table.actionName, table.targetType, table.targetId, table.idempotencyKey)
|
|
131
|
+
.where(sql `
|
|
132
|
+
${table.idempotencyKey} IS NOT NULL
|
|
133
|
+
`),
|
|
134
|
+
]);
|
|
135
|
+
export const actionLedgerRelayOutbox = pgTable("action_ledger_outbox", {
|
|
136
|
+
id: typeId("action_ledger_outbox"),
|
|
137
|
+
actionId: text("action_id")
|
|
138
|
+
.notNull()
|
|
139
|
+
.references(() => actionLedgerEntries.id, { onDelete: "cascade" }),
|
|
140
|
+
organizationId: text("organization_id"),
|
|
141
|
+
relayStatus: actionLedgerRelayStatusEnum("relay_status").notNull().default("pending"),
|
|
142
|
+
payloadRef: text("payload_ref"),
|
|
143
|
+
attemptCount: integer("attempt_count").notNull().default(0),
|
|
144
|
+
nextRetryAt: timestamp("next_retry_at", { withTimezone: true }),
|
|
145
|
+
lastError: text("last_error"),
|
|
146
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
147
|
+
processedAt: timestamp("processed_at", { withTimezone: true }),
|
|
148
|
+
}, (table) => [
|
|
149
|
+
index("idx_action_ledger_outbox_action").on(table.actionId),
|
|
150
|
+
index("idx_action_ledger_outbox_status_retry").on(table.relayStatus, table.nextRetryAt),
|
|
151
|
+
]);
|
|
152
|
+
export const actionDelegations = pgTable("action_delegations", {
|
|
153
|
+
id: typeId("action_delegations"),
|
|
154
|
+
rootPrincipalType: actionLedgerPrincipalTypeEnum("root_principal_type").notNull(),
|
|
155
|
+
rootPrincipalId: text("root_principal_id").notNull(),
|
|
156
|
+
parentPrincipalType: actionLedgerPrincipalTypeEnum("parent_principal_type").notNull(),
|
|
157
|
+
parentPrincipalId: text("parent_principal_id").notNull(),
|
|
158
|
+
childPrincipalType: actionLedgerPrincipalTypeEnum("child_principal_type").notNull(),
|
|
159
|
+
childPrincipalId: text("child_principal_id").notNull(),
|
|
160
|
+
grantSource: text("grant_source").notNull(),
|
|
161
|
+
capabilityScopeRef: text("capability_scope_ref"),
|
|
162
|
+
budgetScopeRef: text("budget_scope_ref"),
|
|
163
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
164
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
165
|
+
}, (table) => [
|
|
166
|
+
index("idx_action_delegations_root").on(table.rootPrincipalType, table.rootPrincipalId),
|
|
167
|
+
index("idx_action_delegations_child").on(table.childPrincipalType, table.childPrincipalId),
|
|
168
|
+
index("idx_action_delegations_parent").on(table.parentPrincipalType, table.parentPrincipalId),
|
|
169
|
+
]);
|
|
170
|
+
export const actionMutationDetails = pgTable("action_mutation_details", {
|
|
171
|
+
actionId: text("action_id")
|
|
172
|
+
.primaryKey()
|
|
173
|
+
.references(() => actionLedgerEntries.id, { onDelete: "cascade" }),
|
|
174
|
+
commandInputRef: text("command_input_ref"),
|
|
175
|
+
commandResultRef: text("command_result_ref"),
|
|
176
|
+
summary: text("summary"),
|
|
177
|
+
reversalKind: actionLedgerReversalKindEnum("reversal_kind").notNull().default("none"),
|
|
178
|
+
reversalCommandId: text("reversal_command_id"),
|
|
179
|
+
reversalCommandVersion: text("reversal_command_version"),
|
|
180
|
+
reversalArgsRef: text("reversal_args_ref"),
|
|
181
|
+
reversalStateProjection: actionLedgerReversalStateEnum("reversal_state_projection"),
|
|
182
|
+
reversalOutcomeProjection: actionLedgerReversalOutcomeEnum("reversal_outcome_projection"),
|
|
183
|
+
reversesActionId: text("reverses_action_id"),
|
|
184
|
+
reversedByActionIdProjection: text("reversed_by_action_id_projection"),
|
|
185
|
+
}, (table) => [
|
|
186
|
+
index("idx_action_mutation_details_reverses").on(table.reversesActionId),
|
|
187
|
+
index("idx_action_mutation_details_reversal_state").on(table.reversalStateProjection),
|
|
188
|
+
]);
|
|
189
|
+
export const actionSensitiveReadDetails = pgTable("action_sensitive_read_details", {
|
|
190
|
+
actionId: text("action_id")
|
|
191
|
+
.primaryKey()
|
|
192
|
+
.references(() => actionLedgerEntries.id, { onDelete: "cascade" }),
|
|
193
|
+
reasonCode: text("reason_code"),
|
|
194
|
+
disclosedFieldSet: jsonb("disclosed_field_set").$type(),
|
|
195
|
+
disclosureSummary: text("disclosure_summary"),
|
|
196
|
+
decisionPolicy: text("decision_policy"),
|
|
197
|
+
});
|
|
198
|
+
export const actionApprovals = pgTable("action_approvals", {
|
|
199
|
+
id: typeId("action_approvals"),
|
|
200
|
+
requestedActionId: text("requested_action_id")
|
|
201
|
+
.notNull()
|
|
202
|
+
.references(() => actionLedgerEntries.id, { onDelete: "cascade" }),
|
|
203
|
+
status: actionLedgerApprovalStatusEnum("status").notNull().default("pending"),
|
|
204
|
+
requestedByPrincipalId: text("requested_by_principal_id").notNull(),
|
|
205
|
+
assignedToPrincipalId: text("assigned_to_principal_id"),
|
|
206
|
+
decidedByPrincipalId: text("decided_by_principal_id"),
|
|
207
|
+
delegatedFromPrincipalId: text("delegated_from_principal_id"),
|
|
208
|
+
policyName: text("policy_name").notNull(),
|
|
209
|
+
policyVersion: text("policy_version").notNull(),
|
|
210
|
+
targetSnapshotRef: text("target_snapshot_ref"),
|
|
211
|
+
riskSnapshot: actionLedgerRiskEnum("risk_snapshot").notNull(),
|
|
212
|
+
reasonCode: text("reason_code"),
|
|
213
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
214
|
+
decidedAt: timestamp("decided_at", { withTimezone: true }),
|
|
215
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
216
|
+
}, (table) => [
|
|
217
|
+
index("idx_action_approvals_requested_action").on(table.requestedActionId),
|
|
218
|
+
index("idx_action_approvals_status_expires").on(table.status, table.expiresAt),
|
|
219
|
+
index("idx_action_approvals_assignee").on(table.assignedToPrincipalId, table.createdAt),
|
|
220
|
+
]);
|
|
221
|
+
export const actionLedgerPayloads = pgTable("action_ledger_payloads", {
|
|
222
|
+
id: typeId("action_ledger_payloads"),
|
|
223
|
+
actionId: text("action_id")
|
|
224
|
+
.notNull()
|
|
225
|
+
.references(() => actionLedgerEntries.id, { onDelete: "cascade" }),
|
|
226
|
+
payloadKind: text("payload_kind").notNull(),
|
|
227
|
+
schemaTag: text("schema_tag").notNull(),
|
|
228
|
+
redactionStatus: actionLedgerRedactionStatusEnum("redaction_status").notNull().default("none"),
|
|
229
|
+
retentionPolicy: text("retention_policy").notNull(),
|
|
230
|
+
storageRef: text("storage_ref").notNull(),
|
|
231
|
+
hash: text("hash"),
|
|
232
|
+
createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
|
233
|
+
expiresAt: timestamp("expires_at", { withTimezone: true }),
|
|
234
|
+
}, (table) => [
|
|
235
|
+
index("idx_action_ledger_payloads_action").on(table.actionId),
|
|
236
|
+
index("idx_action_ledger_payloads_expiry").on(table.expiresAt),
|
|
237
|
+
]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-status.d.ts","sourceRoot":"","sources":["../../src/service/approval-status.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAYxD,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,IAAI,sBAAsB,CAG1C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ActionApprovalDecisionStatusError } from "./errors.js";
|
|
2
|
+
const approvalDecisionStatusValues = [
|
|
3
|
+
"approved",
|
|
4
|
+
"denied",
|
|
5
|
+
"expired",
|
|
6
|
+
"cancelled",
|
|
7
|
+
"superseded",
|
|
8
|
+
];
|
|
9
|
+
const approvalDecisionStatusSet = new Set(approvalDecisionStatusValues);
|
|
10
|
+
export function assertApprovalDecisionStatus(status) {
|
|
11
|
+
if (approvalDecisionStatusSet.has(status))
|
|
12
|
+
return;
|
|
13
|
+
throw new ActionApprovalDecisionStatusError(status);
|
|
14
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ActionApproval, ActionDelegation, ActionLedgerEntry, ActionLedgerRelayOutbox } from "../schema.js";
|
|
2
|
+
declare function normalizeListLimit(limit: number | undefined): number;
|
|
3
|
+
declare function toActionLedgerListCursor(entry: Pick<ActionLedgerEntry, "occurredAt" | "id">): {
|
|
4
|
+
occurredAt: string;
|
|
5
|
+
id: string;
|
|
6
|
+
};
|
|
7
|
+
declare function toActionLedgerRelayOutboxListCursor(row: Pick<ActionLedgerRelayOutbox, "createdAt" | "id">): {
|
|
8
|
+
createdAt: string;
|
|
9
|
+
id: string;
|
|
10
|
+
};
|
|
11
|
+
declare function toActionApprovalListCursor(row: Pick<ActionApproval, "createdAt" | "id">): {
|
|
12
|
+
createdAt: string;
|
|
13
|
+
id: string;
|
|
14
|
+
};
|
|
15
|
+
declare function toActionDelegationListCursor(row: Pick<ActionDelegation, "createdAt" | "id">): {
|
|
16
|
+
createdAt: string;
|
|
17
|
+
id: string;
|
|
18
|
+
};
|
|
19
|
+
declare function serializeCursorDate(value: Date | string): string;
|
|
20
|
+
declare function parseCursorDate(value: Date | string): Date;
|
|
21
|
+
export { normalizeListLimit, parseCursorDate, serializeCursorDate, toActionApprovalListCursor, toActionDelegationListCursor, toActionLedgerListCursor, toActionLedgerRelayOutboxListCursor, };
|
|
22
|
+
//# sourceMappingURL=cursors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursors.d.ts","sourceRoot":"","sources":["../../src/service/cursors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,uBAAuB,EACxB,MAAM,cAAc,CAAA;AAKrB,iBAAS,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAI7D;AAED,iBAAS,wBAAwB,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE,YAAY,GAAG,IAAI,CAAC;;;EAKpF;AAED,iBAAS,mCAAmC,CAC1C,GAAG,EAAE,IAAI,CAAC,uBAAuB,EAAE,WAAW,GAAG,IAAI,CAAC;;;EAMvD;AAED,iBAAS,0BAA0B,CAAC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;;;EAKhF;AAED,iBAAS,4BAA4B,CAAC,GAAG,EAAE,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,IAAI,CAAC;;;EAKpF;AAED,iBAAS,mBAAmB,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAMzD;AAED,iBAAS,eAAe,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAMnD;AAED,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,mCAAmC,GACpC,CAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const DEFAULT_LIST_LIMIT = 50;
|
|
2
|
+
const MAX_LIST_LIMIT = 200;
|
|
3
|
+
function normalizeListLimit(limit) {
|
|
4
|
+
if (limit === undefined)
|
|
5
|
+
return DEFAULT_LIST_LIMIT;
|
|
6
|
+
if (!Number.isFinite(limit))
|
|
7
|
+
return DEFAULT_LIST_LIMIT;
|
|
8
|
+
return Math.min(Math.max(Math.trunc(limit), 1), MAX_LIST_LIMIT);
|
|
9
|
+
}
|
|
10
|
+
function toActionLedgerListCursor(entry) {
|
|
11
|
+
return {
|
|
12
|
+
occurredAt: serializeCursorDate(entry.occurredAt),
|
|
13
|
+
id: entry.id,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function toActionLedgerRelayOutboxListCursor(row) {
|
|
17
|
+
return {
|
|
18
|
+
createdAt: serializeCursorDate(row.createdAt),
|
|
19
|
+
id: row.id,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function toActionApprovalListCursor(row) {
|
|
23
|
+
return {
|
|
24
|
+
createdAt: serializeCursorDate(row.createdAt),
|
|
25
|
+
id: row.id,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function toActionDelegationListCursor(row) {
|
|
29
|
+
return {
|
|
30
|
+
createdAt: serializeCursorDate(row.createdAt),
|
|
31
|
+
id: row.id,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function serializeCursorDate(value) {
|
|
35
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
36
|
+
if (Number.isNaN(date.getTime())) {
|
|
37
|
+
throw new Error("Action ledger cursor occurredAt must be a valid timestamp");
|
|
38
|
+
}
|
|
39
|
+
return date.toISOString();
|
|
40
|
+
}
|
|
41
|
+
function parseCursorDate(value) {
|
|
42
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
43
|
+
if (Number.isNaN(date.getTime())) {
|
|
44
|
+
throw new Error("Action ledger cursor occurredAt must be a valid timestamp");
|
|
45
|
+
}
|
|
46
|
+
return date;
|
|
47
|
+
}
|
|
48
|
+
export { normalizeListLimit, parseCursorDate, serializeCursorDate, toActionApprovalListCursor, toActionDelegationListCursor, toActionLedgerListCursor, toActionLedgerRelayOutboxListCursor, };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AnyDrizzleDb } from "@voyant-travel/db";
|
|
2
|
+
import { type ActionApproval, type ActionLedgerEntry } from "../schema.js";
|
|
3
|
+
import type { AppendActionLedgerEntryInput, AppendActionLedgerEntryResult } from "./types.js";
|
|
4
|
+
export declare function insertEntry(db: AnyDrizzleDb, input: AppendActionLedgerEntryInput): Promise<AppendActionLedgerEntryResult>;
|
|
5
|
+
export declare function findExistingIdempotentEntry(db: AnyDrizzleDb, input: AppendActionLedgerEntryInput): Promise<ActionLedgerEntry | null>;
|
|
6
|
+
export declare function findApprovalForRequestedAction(db: AnyDrizzleDb, requestedActionId: string): Promise<ActionApproval | null>;
|
|
7
|
+
export declare function findApprovalById(db: AnyDrizzleDb, id: string): Promise<ActionApproval | null>;
|
|
8
|
+
export declare function assertSameFingerprint(entry: ActionLedgerEntry, fingerprint: string | null): void;
|
|
9
|
+
//# sourceMappingURL=entries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/service/entries.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAGrD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EAOvB,MAAM,cAAc,CAAA;AAErB,OAAO,KAAK,EAAE,4BAA4B,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAA;AAE7F,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,6BAA6B,CAAC,CAgDxC;AAED,wBAAsB,2BAA2B,CAC/C,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAkBnC;AAED,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,YAAY,EAChB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,YAAY,EAChB,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAQhC;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAIhG"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { and, eq } from "drizzle-orm";
|
|
2
|
+
import { actionApprovals, actionLedgerEntries, actionLedgerPayloads, actionLedgerRelayOutbox, actionMutationDetails, actionSensitiveReadDetails, } from "../schema.js";
|
|
3
|
+
import { ActionLedgerIdempotencyConflictError } from "./errors.js";
|
|
4
|
+
export async function insertEntry(db, input) {
|
|
5
|
+
const { enqueueRelay, mutationDetail, payloads, sensitiveReadDetail, ...entryInput } = input;
|
|
6
|
+
const [entry] = await db
|
|
7
|
+
.insert(actionLedgerEntries)
|
|
8
|
+
.values({
|
|
9
|
+
...entryInput,
|
|
10
|
+
occurredAt: input.occurredAt,
|
|
11
|
+
})
|
|
12
|
+
.returning();
|
|
13
|
+
if (!entry) {
|
|
14
|
+
throw new Error("Action ledger insert did not return an entry");
|
|
15
|
+
}
|
|
16
|
+
if (mutationDetail) {
|
|
17
|
+
await db.insert(actionMutationDetails).values({
|
|
18
|
+
actionId: entry.id,
|
|
19
|
+
...mutationDetail,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
if (sensitiveReadDetail) {
|
|
23
|
+
await db.insert(actionSensitiveReadDetails).values({
|
|
24
|
+
actionId: entry.id,
|
|
25
|
+
...sensitiveReadDetail,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (payloads && payloads.length > 0) {
|
|
29
|
+
await db.insert(actionLedgerPayloads).values(payloads.map((payload) => ({
|
|
30
|
+
actionId: entry.id,
|
|
31
|
+
...payload,
|
|
32
|
+
})));
|
|
33
|
+
}
|
|
34
|
+
if (enqueueRelay) {
|
|
35
|
+
const payloadRef = typeof enqueueRelay === "object" ? enqueueRelay.payloadRef : null;
|
|
36
|
+
await db.insert(actionLedgerRelayOutbox).values({
|
|
37
|
+
actionId: entry.id,
|
|
38
|
+
organizationId: entry.organizationId,
|
|
39
|
+
payloadRef: payloadRef ?? null,
|
|
40
|
+
relayStatus: "pending",
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return { entry, replayed: false };
|
|
44
|
+
}
|
|
45
|
+
export async function findExistingIdempotentEntry(db, input) {
|
|
46
|
+
if (!input.idempotencyScope || !input.idempotencyKey)
|
|
47
|
+
return null;
|
|
48
|
+
const [existing] = await db
|
|
49
|
+
.select()
|
|
50
|
+
.from(actionLedgerEntries)
|
|
51
|
+
.where(and(eq(actionLedgerEntries.idempotencyScope, input.idempotencyScope), eq(actionLedgerEntries.actionName, input.actionName), eq(actionLedgerEntries.targetType, input.targetType), eq(actionLedgerEntries.targetId, input.targetId), eq(actionLedgerEntries.idempotencyKey, input.idempotencyKey)))
|
|
52
|
+
.limit(1);
|
|
53
|
+
return existing ?? null;
|
|
54
|
+
}
|
|
55
|
+
export async function findApprovalForRequestedAction(db, requestedActionId) {
|
|
56
|
+
const [approval] = await db
|
|
57
|
+
.select()
|
|
58
|
+
.from(actionApprovals)
|
|
59
|
+
.where(eq(actionApprovals.requestedActionId, requestedActionId))
|
|
60
|
+
.limit(1);
|
|
61
|
+
return approval ?? null;
|
|
62
|
+
}
|
|
63
|
+
export async function findApprovalById(db, id) {
|
|
64
|
+
const [approval] = await db
|
|
65
|
+
.select()
|
|
66
|
+
.from(actionApprovals)
|
|
67
|
+
.where(eq(actionApprovals.id, id))
|
|
68
|
+
.limit(1);
|
|
69
|
+
return approval ?? null;
|
|
70
|
+
}
|
|
71
|
+
export function assertSameFingerprint(entry, fingerprint) {
|
|
72
|
+
if (entry.idempotencyFingerprint !== fingerprint) {
|
|
73
|
+
throw new ActionLedgerIdempotencyConflictError(entry.id);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ActionApproval } from "../schema.js";
|
|
2
|
+
export declare class ActionLedgerIdempotencyConflictError extends Error {
|
|
3
|
+
readonly existingActionId: string;
|
|
4
|
+
constructor(existingActionId: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class ActionApprovalDecisionConflictError extends Error {
|
|
7
|
+
readonly approvalId: string;
|
|
8
|
+
readonly currentStatus: ActionApproval["status"];
|
|
9
|
+
constructor(approvalId: string, currentStatus: ActionApproval["status"]);
|
|
10
|
+
}
|
|
11
|
+
export declare class ActionApprovalDecisionStatusError extends Error {
|
|
12
|
+
readonly status: string;
|
|
13
|
+
constructor(status: string);
|
|
14
|
+
}
|
|
15
|
+
export declare class ActionLedgerReversalTargetError extends Error {
|
|
16
|
+
readonly actionId: string;
|
|
17
|
+
readonly reason: "missing_mutation_detail" | "not_reversible";
|
|
18
|
+
constructor(actionId: string, reason: "missing_mutation_detail" | "not_reversible");
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/service/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAElD,qBAAa,oCAAqC,SAAQ,KAAK;IAC7D,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;gBAErB,gBAAgB,EAAE,MAAM;CAKrC;AAED,qBAAa,mCAAoC,SAAQ,KAAK;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,aAAa,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAA;gBAEpC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,cAAc,CAAC,QAAQ,CAAC;CAMxE;AAED,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;gBAEX,MAAM,EAAE,MAAM;CAK3B;AAED,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,yBAAyB,GAAG,gBAAgB,CAAA;gBAEjD,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,yBAAyB,GAAG,gBAAgB;CAMnF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class ActionLedgerIdempotencyConflictError extends Error {
|
|
2
|
+
existingActionId;
|
|
3
|
+
constructor(existingActionId) {
|
|
4
|
+
super("Action ledger idempotency key was reused with a different fingerprint");
|
|
5
|
+
this.name = "ActionLedgerIdempotencyConflictError";
|
|
6
|
+
this.existingActionId = existingActionId;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class ActionApprovalDecisionConflictError extends Error {
|
|
10
|
+
approvalId;
|
|
11
|
+
currentStatus;
|
|
12
|
+
constructor(approvalId, currentStatus) {
|
|
13
|
+
super(`Action approval ${approvalId} is already ${currentStatus}`);
|
|
14
|
+
this.name = "ActionApprovalDecisionConflictError";
|
|
15
|
+
this.approvalId = approvalId;
|
|
16
|
+
this.currentStatus = currentStatus;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class ActionApprovalDecisionStatusError extends Error {
|
|
20
|
+
status;
|
|
21
|
+
constructor(status) {
|
|
22
|
+
super(`Action approval decision status must be terminal, received ${status}`);
|
|
23
|
+
this.name = "ActionApprovalDecisionStatusError";
|
|
24
|
+
this.status = status;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export class ActionLedgerReversalTargetError extends Error {
|
|
28
|
+
actionId;
|
|
29
|
+
reason;
|
|
30
|
+
constructor(actionId, reason) {
|
|
31
|
+
super(`Action ledger entry ${actionId} cannot be reversed: ${reason}`);
|
|
32
|
+
this.name = "ActionLedgerReversalTargetError";
|
|
33
|
+
this.actionId = actionId;
|
|
34
|
+
this.reason = reason;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AnyDrizzleDb } from "@voyant-travel/db";
|
|
2
|
+
import type { ListActionApprovalsInput, ListActionApprovalsResult, ListActionDelegationsInput, ListActionDelegationsResult, ListActionLedgerEntriesInput, ListActionLedgerEntriesResult, ListActionLedgerRelayOutboxInput, ListActionLedgerRelayOutboxResult } from "./types.js";
|
|
3
|
+
export declare function listEntries(db: AnyDrizzleDb, input?: ListActionLedgerEntriesInput): Promise<ListActionLedgerEntriesResult>;
|
|
4
|
+
export declare function listRelayOutbox(db: AnyDrizzleDb, input?: ListActionLedgerRelayOutboxInput): Promise<ListActionLedgerRelayOutboxResult>;
|
|
5
|
+
export declare function listApprovals(db: AnyDrizzleDb, input?: ListActionApprovalsInput): Promise<ListActionApprovalsResult>;
|
|
6
|
+
export declare function listDelegations(db: AnyDrizzleDb, input?: ListActionDelegationsInput): Promise<ListActionDelegationsResult>;
|
|
7
|
+
//# sourceMappingURL=listing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"listing.d.ts","sourceRoot":"","sources":["../../src/service/listing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAsBrD,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,4BAA4B,EAC5B,6BAA6B,EAC7B,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,YAAY,CAAA;AAEnB,wBAAsB,WAAW,CAC/B,EAAE,EAAE,YAAY,EAChB,KAAK,GAAE,4BAAiC,GACvC,OAAO,CAAC,6BAA6B,CAAC,CAsBxC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,KAAK,GAAE,gCAAqC,GAC3C,OAAO,CAAC,iCAAiC,CAAC,CAqB5C;AAED,wBAAsB,aAAa,CACjC,EAAE,EAAE,YAAY,EAChB,KAAK,GAAE,wBAA6B,GACnC,OAAO,CAAC,yBAAyB,CAAC,CAqBpC;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,YAAY,EAChB,KAAK,GAAE,0BAA+B,GACrC,OAAO,CAAC,2BAA2B,CAAC,CAqBtC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { asc, desc } from "drizzle-orm";
|
|
2
|
+
import { actionApprovals, actionDelegations, actionLedgerEntries, actionLedgerRelayOutbox, } from "../schema.js";
|
|
3
|
+
import { normalizeListLimit, toActionApprovalListCursor, toActionDelegationListCursor, toActionLedgerListCursor, toActionLedgerRelayOutboxListCursor, } from "./cursors.js";
|
|
4
|
+
import { buildActionApprovalsPredicate, buildActionDelegationsPredicate, buildActionLedgerEntriesPredicate, buildActionLedgerRelayOutboxPredicate, } from "./predicates.js";
|
|
5
|
+
export async function listEntries(db, input = {}) {
|
|
6
|
+
const limit = normalizeListLimit(input.limit);
|
|
7
|
+
const predicate = buildActionLedgerEntriesPredicate(input);
|
|
8
|
+
const direction = input.sortDir === "asc" ? asc : desc;
|
|
9
|
+
let query = db.select().from(actionLedgerEntries).$dynamic();
|
|
10
|
+
if (predicate) {
|
|
11
|
+
query = query.where(predicate);
|
|
12
|
+
}
|
|
13
|
+
const rows = await query
|
|
14
|
+
.orderBy(direction(actionLedgerEntries.occurredAt), direction(actionLedgerEntries.id))
|
|
15
|
+
.limit(limit + 1);
|
|
16
|
+
const entries = rows.slice(0, limit);
|
|
17
|
+
return {
|
|
18
|
+
entries,
|
|
19
|
+
nextCursor: rows.length > limit && entries.length > 0
|
|
20
|
+
? toActionLedgerListCursor(entries[entries.length - 1])
|
|
21
|
+
: null,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export async function listRelayOutbox(db, input = {}) {
|
|
25
|
+
const limit = normalizeListLimit(input.limit);
|
|
26
|
+
const predicate = buildActionLedgerRelayOutboxPredicate(input);
|
|
27
|
+
let query = db.select().from(actionLedgerRelayOutbox).$dynamic();
|
|
28
|
+
if (predicate) {
|
|
29
|
+
query = query.where(predicate);
|
|
30
|
+
}
|
|
31
|
+
const rows = await query
|
|
32
|
+
.orderBy(desc(actionLedgerRelayOutbox.createdAt), desc(actionLedgerRelayOutbox.id))
|
|
33
|
+
.limit(limit + 1);
|
|
34
|
+
const visibleRows = rows.slice(0, limit);
|
|
35
|
+
return {
|
|
36
|
+
rows: visibleRows,
|
|
37
|
+
nextCursor: rows.length > limit && visibleRows.length > 0
|
|
38
|
+
? toActionLedgerRelayOutboxListCursor(visibleRows[visibleRows.length - 1])
|
|
39
|
+
: null,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function listApprovals(db, input = {}) {
|
|
43
|
+
const limit = normalizeListLimit(input.limit);
|
|
44
|
+
const predicate = buildActionApprovalsPredicate(input);
|
|
45
|
+
let query = db.select().from(actionApprovals).$dynamic();
|
|
46
|
+
if (predicate) {
|
|
47
|
+
query = query.where(predicate);
|
|
48
|
+
}
|
|
49
|
+
const rows = await query
|
|
50
|
+
.orderBy(desc(actionApprovals.createdAt), desc(actionApprovals.id))
|
|
51
|
+
.limit(limit + 1);
|
|
52
|
+
const approvals = rows.slice(0, limit);
|
|
53
|
+
return {
|
|
54
|
+
approvals,
|
|
55
|
+
nextCursor: rows.length > limit && approvals.length > 0
|
|
56
|
+
? toActionApprovalListCursor(approvals[approvals.length - 1])
|
|
57
|
+
: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export async function listDelegations(db, input = {}) {
|
|
61
|
+
const limit = normalizeListLimit(input.limit);
|
|
62
|
+
const predicate = buildActionDelegationsPredicate(input);
|
|
63
|
+
let query = db.select().from(actionDelegations).$dynamic();
|
|
64
|
+
if (predicate) {
|
|
65
|
+
query = query.where(predicate);
|
|
66
|
+
}
|
|
67
|
+
const rows = await query
|
|
68
|
+
.orderBy(desc(actionDelegations.createdAt), desc(actionDelegations.id))
|
|
69
|
+
.limit(limit + 1);
|
|
70
|
+
const delegations = rows.slice(0, limit);
|
|
71
|
+
return {
|
|
72
|
+
delegations,
|
|
73
|
+
nextCursor: rows.length > limit && delegations.length > 0
|
|
74
|
+
? toActionDelegationListCursor(delegations[delegations.length - 1])
|
|
75
|
+
: null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type SQL } from "drizzle-orm";
|
|
2
|
+
import type { ListActionApprovalsInput, ListActionDelegationsInput, ListActionLedgerEntriesInput, ListActionLedgerRelayOutboxInput } from "./types.js";
|
|
3
|
+
declare function buildActionDelegationsPredicate(input: ListActionDelegationsInput): SQL | undefined;
|
|
4
|
+
declare function buildActionApprovalsPredicate(input: ListActionApprovalsInput): SQL | undefined;
|
|
5
|
+
declare function buildActionLedgerRelayOutboxPredicate(input: ListActionLedgerRelayOutboxInput): SQL | undefined;
|
|
6
|
+
declare function buildActionLedgerEntriesPredicate(input: ListActionLedgerEntriesInput): SQL | undefined;
|
|
7
|
+
export { buildActionApprovalsPredicate, buildActionDelegationsPredicate, buildActionLedgerEntriesPredicate, buildActionLedgerRelayOutboxPredicate, };
|
|
8
|
+
//# sourceMappingURL=predicates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../../src/service/predicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0C,KAAK,GAAG,EAAO,MAAM,aAAa,CAAA;AAenF,OAAO,KAAK,EAKV,wBAAwB,EACxB,0BAA0B,EAC1B,4BAA4B,EAC5B,gCAAgC,EACjC,MAAM,YAAY,CAAA;AAiKnB,iBAAS,+BAA+B,CAAC,KAAK,EAAE,0BAA0B,GAAG,GAAG,GAAG,SAAS,CAiD3F;AAED,iBAAS,6BAA6B,CAAC,KAAK,EAAE,wBAAwB,GAAG,GAAG,GAAG,SAAS,CAwDvF;AAED,iBAAS,qCAAqC,CAC5C,KAAK,EAAE,gCAAgC,GACtC,GAAG,GAAG,SAAS,CAqCjB;AAED,iBAAS,iCAAiC,CAAC,KAAK,EAAE,4BAA4B,GAAG,GAAG,GAAG,SAAS,CAoH/F;AAED,OAAO,EACL,6BAA6B,EAC7B,+BAA+B,EAC/B,iCAAiC,EACjC,qCAAqC,GACtC,CAAA"}
|