@voltro/runtime 0.11.2 → 0.11.4
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 +228 -0
- package/dist/index.d.ts +312 -0
- package/dist/index.js +1380 -1142
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -954,6 +954,14 @@ export declare interface AttachAnalyticsMirrorOptions {
|
|
|
954
954
|
readonly run?: (effect: Effect.Effect<void, unknown>) => Promise<unknown>;
|
|
955
955
|
}
|
|
956
956
|
|
|
957
|
+
/** The descriptor shape the audit needs — a `defineQuery` result carries it. */
|
|
958
|
+
export declare interface AuditableQuery {
|
|
959
|
+
readonly name: string;
|
|
960
|
+
readonly output: Schema.Schema.Any;
|
|
961
|
+
/** Declared source table(s) — the tables whose serverOnly columns must not leak. */
|
|
962
|
+
readonly source?: string | ReadonlyArray<string> | undefined;
|
|
963
|
+
}
|
|
964
|
+
|
|
957
965
|
/**
|
|
958
966
|
* Resolve once a server returned by {@link startRpcServer} has actually
|
|
959
967
|
* bound its port (node `'listening'` event). REJECTS on `'error'`
|
|
@@ -1519,6 +1527,138 @@ export declare const counter: (name: string, description?: string) => Metric.Met
|
|
|
1519
1527
|
*/
|
|
1520
1528
|
export declare const countRunningWorkflows: (store: DataStore) => Promise<number>;
|
|
1521
1529
|
|
|
1530
|
+
/**
|
|
1531
|
+
* Secure-default CRUD executor factories. Each takes the table NAME (not the
|
|
1532
|
+
* table value — that would be a server import in a descriptor) and returns an
|
|
1533
|
+
* `(input, ctx) => …` executor for a `*.server.ts` default export.
|
|
1534
|
+
*/
|
|
1535
|
+
export declare const crud: {
|
|
1536
|
+
/** Tenant-scoped list, redacted — with optional filter / sort / pagination from
|
|
1537
|
+
* the request input, so a real list view doesn't have to be hand-written. */
|
|
1538
|
+
list: (table: string, options?: CrudListOptions) => (input: unknown, ctx: AppContext) => Promise<ReadonlyArray<Row>>;
|
|
1539
|
+
/** One row by id, or `null` when absent — never throws. Redacted, with optional
|
|
1540
|
+
* eager-loaded relations (`include`). */
|
|
1541
|
+
getById: (table: string, options?: CrudReadOptions & {
|
|
1542
|
+
readonly include?: CrudInclude;
|
|
1543
|
+
}) => (input: {
|
|
1544
|
+
readonly id: string;
|
|
1545
|
+
}, ctx: AppContext) => Promise<Row | null>;
|
|
1546
|
+
/** Insert the input as a new row (id / tenant / audit auto-stamped). The echoed
|
|
1547
|
+
* row is redacted. Guard the DESCRIPTOR — this does not gate. */
|
|
1548
|
+
create: (table: string, options?: CrudWriteOptions) => (input: Row, ctx: AppContext) => Promise<Row>;
|
|
1549
|
+
/** Patch a row by id (`{ id, ...patch }`); returns the updated row or `null`.
|
|
1550
|
+
* Redacted. Guard the DESCRIPTOR. */
|
|
1551
|
+
update: (table: string, options?: CrudWriteOptions) => (input: {
|
|
1552
|
+
readonly id: string;
|
|
1553
|
+
} & Record<string, unknown>, ctx: AppContext) => Promise<Row | null>;
|
|
1554
|
+
/**
|
|
1555
|
+
* Tenant-scoped COUNT of the matching rows — the total a page-based UI needs to
|
|
1556
|
+
* render "page 3 of 12". Takes the SAME `filter` as `list` (share the option
|
|
1557
|
+
* object so the two can't disagree about which rows they mean) and ignores
|
|
1558
|
+
* paging: it counts the whole filtered set, not the current page. A real
|
|
1559
|
+
* `COUNT(*)` aggregate, not a fetch-and-length.
|
|
1560
|
+
*
|
|
1561
|
+
* export default crud.count('absenceRequests', { filter: (i) => ({ status: i.status }) })
|
|
1562
|
+
*/
|
|
1563
|
+
count: (table: string, options?: Pick<CrudListOptions, "filter">) => (input: unknown, ctx: AppContext) => Promise<number>;
|
|
1564
|
+
/** Delete a row by id; returns `{ deleted }`. Guard the DESCRIPTOR. */
|
|
1565
|
+
remove: (table: string) => (input: {
|
|
1566
|
+
readonly id: string;
|
|
1567
|
+
}, ctx: AppContext) => Promise<{
|
|
1568
|
+
readonly deleted: boolean;
|
|
1569
|
+
}>;
|
|
1570
|
+
};
|
|
1571
|
+
|
|
1572
|
+
/** The eager-load spec `.with()` accepts — nested relations, each branch taking
|
|
1573
|
+
* its own `where` / `orderBy` / `limit` (nested filtering + sort). Reused as-is
|
|
1574
|
+
* so `crud.list`'s `include` is exactly what a hand-written `.with(...)` takes. */
|
|
1575
|
+
export declare type CrudInclude = Parameters<SelectBuilder['with']>[0];
|
|
1576
|
+
|
|
1577
|
+
/**
|
|
1578
|
+
* Options for `crud.list` — the read ergonomics every real list view needs, so a
|
|
1579
|
+
* generated list isn't limited to "all rows". All optional and additive: a bare
|
|
1580
|
+
* `crud.list('t')` still returns every (tenant-scoped, redacted) row.
|
|
1581
|
+
*/
|
|
1582
|
+
export declare interface CrudListOptions extends CrudReadOptions {
|
|
1583
|
+
/**
|
|
1584
|
+
* Build a WHERE from the request input — return a column→value map. Only
|
|
1585
|
+
* entries whose value is not `undefined` are applied, so an absent filter field
|
|
1586
|
+
* is simply ignored (`{ employeeId: input.employeeId, status: input.status }`).
|
|
1587
|
+
* The descriptor's `input` schema declares those fields; this maps them to a
|
|
1588
|
+
* scoped `.where(column, value)` on the store query.
|
|
1589
|
+
*/
|
|
1590
|
+
readonly filter?: (input: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>>;
|
|
1591
|
+
/**
|
|
1592
|
+
* Page the result from the request. BOTH styles are accepted, so a caller uses
|
|
1593
|
+
* whichever its UI thinks in:
|
|
1594
|
+
*
|
|
1595
|
+
* - **page-based** — `input.page` (1-based) + `input.pageSize` (default 100).
|
|
1596
|
+
* A table UI showing "page 3 of 12" sends `?page=3&pageSize=20`.
|
|
1597
|
+
* - **offset-based** — `input.limit` / `input.offset` (defaults 100 / 0).
|
|
1598
|
+
*
|
|
1599
|
+
* `page` wins when both are present. Pair with `crud.count` for the total a
|
|
1600
|
+
* page-based UI needs to render the last-page number.
|
|
1601
|
+
*/
|
|
1602
|
+
readonly paginate?: boolean;
|
|
1603
|
+
/**
|
|
1604
|
+
* Upper bound on the rows ONE request may ask for (default 1000). The page
|
|
1605
|
+
* size is caller-controlled, so without a cap `?limit=1000000` on a
|
|
1606
|
+
* `publicApi` list is a one-request resource-exhaustion lever for anyone who
|
|
1607
|
+
* can reach the endpoint. Raise it deliberately for an export-style endpoint;
|
|
1608
|
+
* a `limit`/`pageSize` above it is clamped, not rejected.
|
|
1609
|
+
*/
|
|
1610
|
+
readonly maxPageSize?: number;
|
|
1611
|
+
/** Multi-column sort, applied in order (`[{ column: 'createdAt', direction:
|
|
1612
|
+
* 'desc' }, …]`). */
|
|
1613
|
+
readonly sort?: ReadonlyArray<CrudSort>;
|
|
1614
|
+
/**
|
|
1615
|
+
* Eager-load related rows via `.with(...)` — the SAME spec a hand-written query
|
|
1616
|
+
* takes, so nested relations, and per-branch `where` / `orderBy` / `limit`
|
|
1617
|
+
* (nested filtering + sort) all work:
|
|
1618
|
+
*
|
|
1619
|
+
* include: { employee: { with: { team: true } }, tags: { orderBy: 'name' } }
|
|
1620
|
+
*/
|
|
1621
|
+
readonly include?: CrudInclude;
|
|
1622
|
+
/**
|
|
1623
|
+
* SQL column projection — narrow the `SELECT` so wide columns are never READ,
|
|
1624
|
+
* not merely dropped at the wire boundary. The output schema already strips
|
|
1625
|
+
* undeclared columns on encode (so nothing extra ships either way); this is the
|
|
1626
|
+
* PERFORMANCE half: a table with a large `json()` blob or a long text body that
|
|
1627
|
+
* a list view never shows shouldn't cost the read, the transfer from the DB, or
|
|
1628
|
+
* the decode.
|
|
1629
|
+
*
|
|
1630
|
+
* columns: ['id', 'title', 'createdAt'] // the big `body` is never read
|
|
1631
|
+
*
|
|
1632
|
+
* `.serverOnly()` columns are removed from the projection automatically — they
|
|
1633
|
+
* are stripped from the response anyway, so reading them is pure waste.
|
|
1634
|
+
*
|
|
1635
|
+
* TRAP with `include`: an eager branch joins on a foreign key, so a projection
|
|
1636
|
+
* that omits that FK column breaks the relation. Keep the FK in `columns` when
|
|
1637
|
+
* you also pass `include`.
|
|
1638
|
+
*/
|
|
1639
|
+
readonly columns?: ReadonlyArray<string>;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
/** Options common to a generated READ. */
|
|
1643
|
+
export declare interface CrudReadOptions {
|
|
1644
|
+
/** Columns stripped from every returned row — a secret/credential a generated
|
|
1645
|
+
* read must never ship (`bankIban`, `tokenHash`, `salary`). The wire schema on
|
|
1646
|
+
* the descriptor should omit them too, so they never reach the client at all;
|
|
1647
|
+
* this is the runtime half that guarantees it regardless. */
|
|
1648
|
+
readonly redact?: ReadonlyArray<string>;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
/** A single sort term for `crud.list`. */
|
|
1652
|
+
export declare interface CrudSort {
|
|
1653
|
+
readonly column: string;
|
|
1654
|
+
readonly direction?: 'asc' | 'desc';
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
/** Options for a generated WRITE — `redact` applies to the row the write echoes. */
|
|
1658
|
+
export declare interface CrudWriteOptions {
|
|
1659
|
+
readonly redact?: ReadonlyArray<string>;
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1522
1662
|
/** Read the active context, if any. Tests use this to validate the
|
|
1523
1663
|
* propagation; production code uses it only inside this module. */
|
|
1524
1664
|
export declare const currentRoutingContext: () => RoutingContext | undefined;
|
|
@@ -1974,6 +2114,16 @@ export declare interface FieldChange {
|
|
|
1974
2114
|
export declare const fingerprintFor: (table: string, predicate: Predicate, indexHint?: string) => string;
|
|
1975
2115
|
|
|
1976
2116
|
export declare interface FluentStore extends Omit<MutationStore, 'update' | 'delete' | 'query'> {
|
|
2117
|
+
/**
|
|
2118
|
+
* Diff-based many-to-many link writer for a junction table. `anchor` names the
|
|
2119
|
+
* source column and its id (`{ postId: 'p1' }`); the target column is the
|
|
2120
|
+
* junction's other reference column, auto-detected. Only the difference is
|
|
2121
|
+
* written, so reactive consumers see one change per changed row, not a
|
|
2122
|
+
* drop+reinsert of the whole set.
|
|
2123
|
+
*
|
|
2124
|
+
* await ctx.store.links('post_tags', { postId: post.id }).set(tagIds)
|
|
2125
|
+
*/
|
|
2126
|
+
links(junctionTable: string, anchor: Readonly<Record<string, string>>): JunctionLinks;
|
|
1977
2127
|
/**
|
|
1978
2128
|
* Execute a query descriptor and return the matching rows — TYPED.
|
|
1979
2129
|
*
|
|
@@ -2051,6 +2201,9 @@ export declare interface FluentStoreBackend {
|
|
|
2051
2201
|
/** Forget the calling subject's credential. Returns whether a row was removed. */
|
|
2052
2202
|
export declare const forgetCredential: (store: VaultStore, connectionId: string, subjectId: string) => Promise<boolean>;
|
|
2053
2203
|
|
|
2204
|
+
/** A boot-ready message for a set of leaks (empty → `undefined`, i.e. clean). */
|
|
2205
|
+
export declare const formatServerOnlyLeaks: (leaks: ReadonlyArray<ServerOnlyLeak>) => string | undefined;
|
|
2206
|
+
|
|
2054
2207
|
/** Serialise a span's context as a `traceparent` header value. */
|
|
2055
2208
|
export declare const formatTraceparent: (ctx: TraceContext) => string;
|
|
2056
2209
|
|
|
@@ -2454,6 +2607,50 @@ export declare type IvmState = ReadonlyMap<string, GroupState>;
|
|
|
2454
2607
|
/** Project the public aggregate value from a group's accumulator. */
|
|
2455
2608
|
export declare const ivmValue: (shape: AggregateShape, g: GroupState) => number | null;
|
|
2456
2609
|
|
|
2610
|
+
/**
|
|
2611
|
+
* Diff-based writer for a many-to-many JUNCTION table (A2). Reconciles the set
|
|
2612
|
+
* of links from ONE anchor row (`{ [sourceColumn]: id }`) against a target-id
|
|
2613
|
+
* list by writing only the DIFFERENCE — the added rows are inserted, the removed
|
|
2614
|
+
* rows are deleted, and rows already correct are left untouched. That is the
|
|
2615
|
+
* whole point over a drop-all-then-reinsert `setLinks`: a reactive subscription
|
|
2616
|
+
* on the junction sees a change event only for the rows that actually changed
|
|
2617
|
+
* (no flicker, no lost data if two writers overlap), and an unchanged link never
|
|
2618
|
+
* churns. The TARGET column is the junction's OTHER reference column (the one the
|
|
2619
|
+
* anchor doesn't name); a junction with anything but exactly two reference
|
|
2620
|
+
* columns is rejected with a message naming what it found.
|
|
2621
|
+
*/
|
|
2622
|
+
export declare interface JunctionLinks {
|
|
2623
|
+
/** The current target ids linked to the anchor. */
|
|
2624
|
+
list(): Promise<ReadonlyArray<string>>;
|
|
2625
|
+
/** Reconcile the links to EXACTLY `targetIds` — insert the missing, delete the
|
|
2626
|
+
* surplus, leave the rest. Returns what changed. */
|
|
2627
|
+
set(targetIds: ReadonlyArray<string>): Promise<{
|
|
2628
|
+
readonly added: ReadonlyArray<string>;
|
|
2629
|
+
readonly removed: ReadonlyArray<string>;
|
|
2630
|
+
}>;
|
|
2631
|
+
/** Link `targetIds` that aren't linked yet (idempotent — existing links are
|
|
2632
|
+
* not re-inserted, so they emit no event). Returns the ids actually added. */
|
|
2633
|
+
add(targetIds: ReadonlyArray<string>): Promise<ReadonlyArray<string>>;
|
|
2634
|
+
/** Unlink `targetIds` that are currently linked. Returns the ids actually removed. */
|
|
2635
|
+
remove(targetIds: ReadonlyArray<string>): Promise<ReadonlyArray<string>>;
|
|
2636
|
+
/**
|
|
2637
|
+
* Reconcile links that carry PER-ROW PAYLOAD — a junction with business columns
|
|
2638
|
+
* (a membership `role`, a `capacity` value). Each row is
|
|
2639
|
+
* `{ [targetColumn]: id, …payload }`; the diff is on the (source, target) pair:
|
|
2640
|
+
* an added row is inserted with its payload, a removed row deleted, and a
|
|
2641
|
+
* SURVIVING row whose payload actually changed is UPDATED — one whose payload
|
|
2642
|
+
* is unchanged is left untouched, so a reactive consumer sees a change only
|
|
2643
|
+
* where the payload differs (the `set(targetIds)` form can't express payload;
|
|
2644
|
+
* this is the drop+reinsert replacement for a junction that carries data).
|
|
2645
|
+
* Payload is compared by strict equality per column (scalars — capacity, role).
|
|
2646
|
+
*/
|
|
2647
|
+
setRows(rows: ReadonlyArray<Readonly<Record<string, unknown>>>): Promise<{
|
|
2648
|
+
readonly added: ReadonlyArray<string>;
|
|
2649
|
+
readonly removed: ReadonlyArray<string>;
|
|
2650
|
+
readonly updated: ReadonlyArray<string>;
|
|
2651
|
+
}>;
|
|
2652
|
+
}
|
|
2653
|
+
|
|
2457
2654
|
export declare interface KvFacade {
|
|
2458
2655
|
readonly kv: AsyncKv;
|
|
2459
2656
|
/** The resolved Effect-native `Kv` service instance. Its methods close over
|
|
@@ -2714,6 +2911,24 @@ export declare const makeListConnectionsExecutor: (deps: ConnectionBuiltinDeps)
|
|
|
2714
2911
|
*/
|
|
2715
2912
|
export declare const makeMutationRunner: (deps: MutationRunnerDeps) => (mutation: MutationLike, input: unknown, requestContext: ServeRequestContext) => Promise<unknown>;
|
|
2716
2913
|
|
|
2914
|
+
/**
|
|
2915
|
+
* Run a QUERY once and resolve its value — the read counterpart to
|
|
2916
|
+
* `makeMutationRunner` / `makeActionRunner`, for callers that have no
|
|
2917
|
+
* subscription: a descriptor projected to a public REST endpoint.
|
|
2918
|
+
*
|
|
2919
|
+
* It is deliberately built ON TOP of `makeQueryDescriptorProducer` rather than
|
|
2920
|
+
* beside it. That producer is where the declarative `guards:` gate, the
|
|
2921
|
+
* per-request row-filter resolution and the tenant-scoping `finalize` live, so
|
|
2922
|
+
* reusing it makes the one-shot path enforce EXACTLY what the WS path enforces.
|
|
2923
|
+
* A second implementation here would be an authorization bypass waiting to
|
|
2924
|
+
* happen — the REST projection of a guarded query must fail the same way the
|
|
2925
|
+
* socket does, and it does because it runs the same code.
|
|
2926
|
+
*
|
|
2927
|
+
* Both handler shapes resolve: a descriptor-returning (reactive) query is
|
|
2928
|
+
* finalized and executed to rows; a computed query yields its value.
|
|
2929
|
+
*/
|
|
2930
|
+
export declare const makeOneShotQueryRunner: <D>(deps: OneShotQueryRunnerDeps<D>) => (query: MutationLike, input: unknown, requestContext: ServeRequestContext) => Promise<unknown>;
|
|
2931
|
+
|
|
2717
2932
|
export declare const makeOutboxFacade: (deps: OutboxFacadeDeps) => OutboxFacade;
|
|
2718
2933
|
|
|
2719
2934
|
export declare const makePostCommitWorkflowFacade: (base: WorkflowsAppContext, afterCommit: (work: () => Promise<unknown>) => void) => WorkflowsAppContext;
|
|
@@ -2757,6 +2972,25 @@ export declare const makeQueryDescriptorProducer: <D>(deps: QueryProducerDeps<D>
|
|
|
2757
2972
|
*/
|
|
2758
2973
|
export declare const makeQueryReauthorizer: (query: MutationLike, input: unknown) => (subject: Subject) => () => Promise<unknown>;
|
|
2759
2974
|
|
|
2975
|
+
/**
|
|
2976
|
+
* Subscribe a QUERY and stream its events to a non-rpc consumer — the SSE
|
|
2977
|
+
* projection of a `publicApi` query. Like `makeOneShotQueryRunner`, it runs the
|
|
2978
|
+
* shared `makeQueryDescriptorProducer`, so the declarative `guards:`, the row
|
|
2979
|
+
* filter and tenant scoping are the same code the socket path runs: an SSE
|
|
2980
|
+
* endpoint is exactly as gated as the WebSocket one.
|
|
2981
|
+
*
|
|
2982
|
+
* Returns an unsubscribe SYNCHRONOUSLY (the HTTP layer needs one immediately)
|
|
2983
|
+
* while the subscription opens in the background; unsubscribing before it
|
|
2984
|
+
* finishes tears it down as soon as it exists, so a client that disconnects
|
|
2985
|
+
* mid-setup cannot leak a subscription. A setup failure — including a guard
|
|
2986
|
+
* denial — is emitted as one `error` event rather than thrown, because by then
|
|
2987
|
+
* the response headers are already on the wire.
|
|
2988
|
+
*/
|
|
2989
|
+
export declare const makeQuerySubscriber: <D>(deps: QuerySubscriberDeps<D>) => (query: MutationLike, input: unknown, requestContext: ServeRequestContext, emit: (event: {
|
|
2990
|
+
readonly _tag: string;
|
|
2991
|
+
readonly [k: string]: unknown;
|
|
2992
|
+
}) => void) => (() => void);
|
|
2993
|
+
|
|
2760
2994
|
export declare const makeRouterActivity: () => RouterActivity;
|
|
2761
2995
|
|
|
2762
2996
|
/**
|
|
@@ -3145,6 +3379,15 @@ export declare interface OAuth2ConnectionDefinition extends ConnectionDefinition
|
|
|
3145
3379
|
*/
|
|
3146
3380
|
export declare const onBindConnectionSubject: (listener: (clientId: number, subject: Subject) => void) => () => void;
|
|
3147
3381
|
|
|
3382
|
+
export declare interface OneShotQueryRunnerDeps<D> extends QueryProducerDeps<D> {
|
|
3383
|
+
/**
|
|
3384
|
+
* Execute a FINALIZED (tenant-scoped) descriptor → rows. On the WS path the
|
|
3385
|
+
* dispatcher owns this step; a ONE-SHOT read (a `publicApi` REST GET, where
|
|
3386
|
+
* there is no subscription to drive) needs it inline.
|
|
3387
|
+
*/
|
|
3388
|
+
readonly queryRows: (descriptor: D) => Promise<ReadonlyArray<unknown>>;
|
|
3389
|
+
}
|
|
3390
|
+
|
|
3148
3391
|
/** Thrown by `.expectVersion(n).set(...)` when the optimistic-lock guard
|
|
3149
3392
|
* matched no row (the row was concurrently updated or deleted). */
|
|
3150
3393
|
export declare class OptimisticLockError extends OptimisticLockError_base {
|
|
@@ -3449,6 +3692,13 @@ export declare interface QueryProducerDeps<D> {
|
|
|
3449
3692
|
readonly interceptor?: ServeRpcInterceptor;
|
|
3450
3693
|
}
|
|
3451
3694
|
|
|
3695
|
+
export declare interface QuerySubscriberDeps<D> extends QueryProducerDeps<D> {
|
|
3696
|
+
/** Open a dispatcher subscription for a finalized descriptor. */
|
|
3697
|
+
readonly subscribeDescriptor: (descriptor: D, emit: (event: unknown) => void, context: ServeRequestContext) => Promise<() => void>;
|
|
3698
|
+
/** Open a dispatcher subscription for a COMPUTED query (re-runs on source change). */
|
|
3699
|
+
readonly subscribeComputed: (computed: ComputedQuery, emit: (event: unknown) => void, context: ServeRequestContext) => Promise<() => void>;
|
|
3700
|
+
}
|
|
3701
|
+
|
|
3452
3702
|
/** What a reaction does when it fires — run an agent or start a workflow. Both
|
|
3453
3703
|
* identified by name; the serve layer resolves + runs them as `agentActor`. */
|
|
3454
3704
|
export declare type ReactionAct = {
|
|
@@ -3611,6 +3861,13 @@ export declare const recordTimelineEvent: (change: CdcChange & {
|
|
|
3611
3861
|
readonly tenantId?: string | null;
|
|
3612
3862
|
}) => void;
|
|
3613
3863
|
|
|
3864
|
+
/**
|
|
3865
|
+
* Strip `redact` columns from a set of rows. Exposed on its own so a hand-written
|
|
3866
|
+
* handler that isn't a plain CRUD read can still redact declaratively and be
|
|
3867
|
+
* audited the same way. Pure — no store, no context.
|
|
3868
|
+
*/
|
|
3869
|
+
export declare const redactColumns: <R extends Row>(rows: ReadonlyArray<R>, redact: ReadonlyArray<string>) => ReadonlyArray<R>;
|
|
3870
|
+
|
|
3614
3871
|
/** Blank sensitive-looking columns. Returns a new object; null passes through. */
|
|
3615
3872
|
export declare const redactRow: (row: Row_2 | null | undefined) => Row_2 | null;
|
|
3616
3873
|
|
|
@@ -4759,6 +5016,14 @@ export declare interface SchedulerHandle {
|
|
|
4759
5016
|
export declare interface SchedulerLogger {
|
|
4760
5017
|
info: (msg: string, fields?: Record<string, unknown>) => void;
|
|
4761
5018
|
warn: (msg: string, fields?: Record<string, unknown>) => void;
|
|
5019
|
+
/**
|
|
5020
|
+
* Failures. This channel did not exist, which is why a schedule whose handler
|
|
5021
|
+
* failed on EVERY firing was only ever a `warn` — invisible to `voltro logs
|
|
5022
|
+
* --level error`, and a schedule fires unattended, so that log line is the
|
|
5023
|
+
* whole discovery channel. Optional so an embedder passing a two-method logger
|
|
5024
|
+
* still compiles; it falls back to `warn` at the call site.
|
|
5025
|
+
*/
|
|
5026
|
+
error?: (msg: string, fields?: Record<string, unknown>) => void;
|
|
4762
5027
|
/** Optional debug channel for high-frequency expected events
|
|
4763
5028
|
* (lost coordination claims on sub-minute schedules etc.). */
|
|
4764
5029
|
debug?: (msg: string, fields?: Record<string, unknown>) => void;
|
|
@@ -4827,6 +5092,13 @@ export declare interface SchemaInfo {
|
|
|
4827
5092
|
readonly idScheme?: IdScheme;
|
|
4828
5093
|
}
|
|
4829
5094
|
|
|
5095
|
+
/**
|
|
5096
|
+
* Every property NAME that appears anywhere in a schema's shape. Recursive over
|
|
5097
|
+
* the common composition nodes so a column nested under `{ refs: [{ … }] }` or
|
|
5098
|
+
* behind a `NullOr` is still seen. Cycle-guarded via a seen-set on Suspend.
|
|
5099
|
+
*/
|
|
5100
|
+
export declare const schemaPropertyNames: (schema: Schema.Schema.Any) => ReadonlySet<string>;
|
|
5101
|
+
|
|
4830
5102
|
export declare interface SchemaRegistry {
|
|
4831
5103
|
readonly tables: ReadonlyMap<string, SchemaInfo>;
|
|
4832
5104
|
/** True iff the table was composed with the named mixin id. */
|
|
@@ -4974,6 +5246,20 @@ export declare interface ServeRequestContext {
|
|
|
4974
5246
|
readonly rowFilter?: RowFilterScope;
|
|
4975
5247
|
}
|
|
4976
5248
|
|
|
5249
|
+
/** One leak: a wire query that declares a serverOnly column in its output. */
|
|
5250
|
+
export declare interface ServerOnlyLeak {
|
|
5251
|
+
readonly query: string;
|
|
5252
|
+
readonly table: string;
|
|
5253
|
+
readonly column: string;
|
|
5254
|
+
}
|
|
5255
|
+
|
|
5256
|
+
/**
|
|
5257
|
+
* Every serverOnly column a query's output declares. `serverOnlyByTable` maps a
|
|
5258
|
+
* table name to its `.serverOnly()` column names. A query with no `source`, or
|
|
5259
|
+
* whose source has no serverOnly columns, yields nothing.
|
|
5260
|
+
*/
|
|
5261
|
+
export declare const serverOnlyLeaks: (query: AuditableQuery, serverOnlyByTable: ReadonlyMap<string, ReadonlyArray<string>>) => ReadonlyArray<ServerOnlyLeak>;
|
|
5262
|
+
|
|
4977
5263
|
/** A plugin interceptor — wraps the base run Effect (Effect-native chain). */
|
|
4978
5264
|
export declare type ServeRpcInterceptor = (base: Effect.Effect<unknown, unknown, never>, meta: {
|
|
4979
5265
|
readonly tag: string;
|
|
@@ -6106,6 +6392,32 @@ export declare interface WorkflowLayerOptions<Context> {
|
|
|
6106
6392
|
readonly resolveStartContext?: (workflowName: string, executionId: string) => WorkflowCallerContext | undefined | Promise<WorkflowCallerContext | undefined>;
|
|
6107
6393
|
}
|
|
6108
6394
|
|
|
6395
|
+
/**
|
|
6396
|
+
* A start whose PAYLOAD does not match the workflow's schema.
|
|
6397
|
+
*
|
|
6398
|
+
* Distinct from a workflow that ran and failed, and the distinction is the whole
|
|
6399
|
+
* point: `ctx.workflows.start(name, payload)` is typed `(string, unknown)` — the
|
|
6400
|
+
* name is not checked against the registry and the payload is not checked against
|
|
6401
|
+
* anything — so a caller that drifts from the workflow's schema produces a failure
|
|
6402
|
+
* DEEP inside the engine, where it reads like the workflow itself misbehaved.
|
|
6403
|
+
*
|
|
6404
|
+
* A cron firing such a start hit that every single time and looked like a flaky
|
|
6405
|
+
* job. Naming the workflow, the missing fields, and the fact that the payload
|
|
6406
|
+
* (not the workflow) is what's wrong turns it into a one-read fix.
|
|
6407
|
+
*/
|
|
6408
|
+
export declare class WorkflowPayloadError extends Error {
|
|
6409
|
+
readonly workflowName: string;
|
|
6410
|
+
/** Top-level property names the schema requires and the payload omitted.
|
|
6411
|
+
* Empty when the mismatch is a type error rather than a missing key. */
|
|
6412
|
+
readonly missingFields: ReadonlyArray<string>;
|
|
6413
|
+
readonly detail: string;
|
|
6414
|
+
readonly _tag = "WorkflowPayloadError";
|
|
6415
|
+
constructor(workflowName: string,
|
|
6416
|
+
/** Top-level property names the schema requires and the payload omitted.
|
|
6417
|
+
* Empty when the mismatch is a type error rather than a missing key. */
|
|
6418
|
+
missingFields: ReadonlyArray<string>, detail: string);
|
|
6419
|
+
}
|
|
6420
|
+
|
|
6109
6421
|
/** Options for {@link WorkflowsAppContext.retry}. */
|
|
6110
6422
|
export declare interface WorkflowRetryOptions {
|
|
6111
6423
|
/** Re-run the workflow against this payload instead of the original
|