@nifrajs/core 2.9.0 → 2.10.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 CHANGED
@@ -4,6 +4,11 @@ The Bun-native, contract-first HTTP framework at the heart of [nifra](../../READ
4
4
  a radix router, a fully type-inferred server, versionable contracts, lifecycle
5
5
  middleware, and production hardening.
6
6
 
7
+ The Web-standard app can be wrapped for Vercel Edge with `toVercelHandler`, Netlify Functions with
8
+ `toNetlifyHandler`, or API Gateway v1/v2 with `toLambdaHandler` from `@nifrajs/core/server`. These are
9
+ thin event-envelope adapters; application policy, persistence, and platform credentials stay outside
10
+ the core.
11
+
7
12
  ```sh
8
13
  bun add @nifrajs/core
9
14
  ```
@@ -26,6 +31,8 @@ available only from their explicit subpaths, so an ordinary HTTP server never ev
26
31
  import { defineContract, implement } from "@nifrajs/core/contract"
27
32
  import { startCausality } from "@nifrajs/core/causality"
28
33
  import { defineAssurancePolicy } from "@nifrajs/core/assurance"
34
+ import { createDataPort, defineDataContract, diffDataContract } from "@nifrajs/core/data"
35
+ import { defineChannel, memoryChannelHub } from "@nifrajs/core/channel"
29
36
  ```
30
37
 
31
38
  - **Inline or contract-first.** Write routes inline (types inferred from the
@@ -75,6 +82,16 @@ import { defineAssurancePolicy } from "@nifrajs/core/assurance"
75
82
  bounded HTTP representations and supplies the same frame/loader adapters for WebSockets and
76
83
  deferred data. Import `richWireCodec()` from `@nifrajs/core/transport-codec-rich`; the separate
77
84
  subpath keeps rich-wire code out of plain JSON bundles.
85
+ - **Typed data seam (opt in).** `@nifrajs/core/data` defines token-only operation contracts,
86
+ `db.read`/`db.write` capability names, an opaque request-local `RlsScope`, typed adapter requests,
87
+ drift snapshots, and `createDataPort(contract, adapter, { beacon: useCapability })`, which emits the
88
+ operation's capability evidence - derived from the contract, never from the request - before the
89
+ private adapter runs. It contains no database driver, tenant identity, policy, row values, or durable
90
+ store; those belong in the adapter layer.
91
+ - **Typed channels (opt in).** `@nifrajs/core/channel` defines typed message contracts, bounded
92
+ subscriptions, cancellation, per-channel resume cursors, bounded local replay, and a process-local
93
+ in-memory hub for tests. Durable replay, presence, rooms, and multi-instance fan-out remain adapter
94
+ concerns.
78
95
 
79
96
  ```ts
80
97
  import { defineAssurancePolicy, evaluateRouteAssurance, NIFRA_ASSURANCE } from "@nifrajs/core/assurance"
@@ -0,0 +1,52 @@
1
+ /** Typed, runtime-neutral channel contracts. Durable replay, presence, fan-out, and tenant-aware
2
+ * routing belong in an adapter; the bundled hub provides only bounded process-local replay for tests
3
+ * and local development. */
4
+ export interface ChannelContract<Name extends string, Message> {
5
+ readonly name: Name;
6
+ /** Type-only message witness; adapters never materialize it. */
7
+ readonly __message?: (value: Message) => Message;
8
+ }
9
+ export interface ChannelEvent<Message> {
10
+ /** Monotonic within one channel; adapters may use a different opaque cursor representation. */
11
+ readonly sequence: number;
12
+ readonly resumeToken: string;
13
+ readonly data: Message;
14
+ }
15
+ export type ChannelCloseReason = "closed" | "backpressure" | "aborted";
16
+ export interface ChannelSubscription<Message> extends AsyncIterableIterator<ChannelEvent<Message>> {
17
+ readonly channel: string;
18
+ readonly closed: boolean;
19
+ readonly closeReason: ChannelCloseReason | undefined;
20
+ readonly resumeToken: string | undefined;
21
+ close(): void;
22
+ }
23
+ export interface ChannelSubscribeOptions {
24
+ /** Maximum undelivered events retained for this subscriber. Default 64. */
25
+ readonly maxQueue?: number;
26
+ /** Resume after this opaque cursor. The adapter must fail closed when the cursor is unavailable. */
27
+ readonly resumeFrom?: string;
28
+ readonly signal?: AbortSignal;
29
+ }
30
+ export interface ChannelHub {
31
+ subscribe<Name extends string, Message>(channel: ChannelContract<Name, Message>, options?: ChannelSubscribeOptions): ChannelSubscription<Message>;
32
+ publish<Name extends string, Message>(channel: ChannelContract<Name, Message>, data: Message): ChannelEvent<Message>;
33
+ }
34
+ export interface MemoryChannelHubOptions {
35
+ /** Default queue bound per subscriber. Default 64. */
36
+ readonly maxQueue?: number;
37
+ /** Maximum events retained per channel for local cursor replay. Default: the queue bound. */
38
+ readonly historySize?: number;
39
+ }
40
+ /** A requested cursor is malformed, belongs to another channel, or fell outside retained history. */
41
+ export declare class ChannelResumeUnavailableError extends Error {
42
+ readonly channel: string;
43
+ readonly resumeToken: string;
44
+ constructor(channel: string, resumeToken: string);
45
+ }
46
+ /** Define a typed channel name. Message types are erased; adapters own validation at their boundary. */
47
+ export declare function defineChannel<Name extends string, Message>(name: Name): ChannelContract<Name, Message>;
48
+ /** A bounded in-memory hub suitable for tests and local development, never for durable fan-out. */
49
+ export declare function memoryChannelHub(options?: MemoryChannelHubOptions): ChannelHub;
50
+ /** Adapt a channel subscription to a cancellable Web stream for SSE/HTTP adapters. */
51
+ export declare function channelReadableStream<Message>(subscription: ChannelSubscription<Message>): ReadableStream<ChannelEvent<Message>>;
52
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"AAAA;;4BAE4B;AAE5B,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,MAAM,EAAE,OAAO;IAC3D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,gEAAgE;IAChE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;CACjD;AAED,MAAM,WAAW,YAAY,CAAC,OAAO;IACnC,+FAA+F;IAC/F,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,cAAc,GAAG,SAAS,CAAA;AAEtE,MAAM,WAAW,mBAAmB,CAAC,OAAO,CAAE,SAAQ,qBAAqB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IAChG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,kBAAkB,GAAG,SAAS,CAAA;IACpD,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,WAAW,uBAAuB;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,oGAAoG;IACpG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,IAAI,SAAS,MAAM,EAAE,OAAO,EACpC,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EACvC,OAAO,CAAC,EAAE,uBAAuB,GAChC,mBAAmB,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,IAAI,SAAS,MAAM,EAAE,OAAO,EAClC,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,EACvC,IAAI,EAAE,OAAO,GACZ,YAAY,CAAC,OAAO,CAAC,CAAA;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,sDAAsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;IAC1B,6FAA6F;IAC7F,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,qGAAqG;AACrG,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;gBAEhB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;CAMjD;AAMD,wGAAwG;AACxG,wBAAgB,aAAa,CAAC,IAAI,SAAS,MAAM,EAAE,OAAO,EACxD,IAAI,EAAE,IAAI,GACT,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,CAGhC;AAqGD,mGAAmG;AACnG,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,UAAU,CAmGlF;AAED,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,OAAO,EAC3C,YAAY,EAAE,mBAAmB,CAAC,OAAO,CAAC,GACzC,cAAc,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAgBvC"}
@@ -0,0 +1,231 @@
1
+ /** Typed, runtime-neutral channel contracts. Durable replay, presence, fan-out, and tenant-aware
2
+ * routing belong in an adapter; the bundled hub provides only bounded process-local replay for tests
3
+ * and local development. */
4
+ /** A requested cursor is malformed, belongs to another channel, or fell outside retained history. */
5
+ export class ChannelResumeUnavailableError extends Error {
6
+ channel;
7
+ resumeToken;
8
+ constructor(channel, resumeToken) {
9
+ super("channel: resume cursor is unavailable");
10
+ this.name = "ChannelResumeUnavailableError";
11
+ this.channel = channel;
12
+ this.resumeToken = resumeToken;
13
+ }
14
+ }
15
+ function validName(name) {
16
+ return /^[A-Za-z][A-Za-z0-9._:/-]{0,127}$/.test(name);
17
+ }
18
+ /** Define a typed channel name. Message types are erased; adapters own validation at their boundary. */
19
+ export function defineChannel(name) {
20
+ if (!validName(name))
21
+ throw new TypeError("channel: name must be a bounded token");
22
+ return Object.freeze({ name });
23
+ }
24
+ class MemorySubscription {
25
+ channel;
26
+ maxQueue;
27
+ remove;
28
+ queue = [];
29
+ waiters = [];
30
+ isClosed = false;
31
+ reason;
32
+ lastToken;
33
+ abortSignal;
34
+ abortHandler;
35
+ constructor(channel, maxQueue, remove) {
36
+ this.channel = channel;
37
+ this.maxQueue = maxQueue;
38
+ this.remove = remove;
39
+ }
40
+ seed(events) {
41
+ if (events.length > this.maxQueue) {
42
+ throw new RangeError("channel: resume history exceeds subscriber queue bound");
43
+ }
44
+ this.queue.push(...events);
45
+ }
46
+ attachSignal(signal) {
47
+ if (signal === undefined || this.isClosed)
48
+ return;
49
+ const handler = () => this.close("aborted");
50
+ this.abortSignal = signal;
51
+ this.abortHandler = handler;
52
+ signal.addEventListener("abort", handler, { once: true });
53
+ // Check after registration as well: an abort can happen between the initial caller check and
54
+ // listener registration in host implementations. `close()` removes the listener again.
55
+ if (signal.aborted)
56
+ this.close("aborted");
57
+ }
58
+ get closed() {
59
+ return this.isClosed;
60
+ }
61
+ get closeReason() {
62
+ return this.reason;
63
+ }
64
+ get resumeToken() {
65
+ return this.lastToken;
66
+ }
67
+ push(event) {
68
+ if (this.isClosed)
69
+ return;
70
+ const waiter = this.waiters.shift();
71
+ if (waiter !== undefined) {
72
+ this.lastToken = event.resumeToken;
73
+ waiter({ done: false, value: event });
74
+ return;
75
+ }
76
+ if (this.queue.length >= this.maxQueue) {
77
+ this.close("backpressure");
78
+ return;
79
+ }
80
+ this.queue.push(event);
81
+ }
82
+ next() {
83
+ const event = this.queue.shift();
84
+ if (event !== undefined) {
85
+ this.lastToken = event.resumeToken;
86
+ return Promise.resolve({ done: false, value: event });
87
+ }
88
+ if (this.isClosed)
89
+ return Promise.resolve({ done: true, value: undefined });
90
+ return new Promise((resolve) => this.waiters.push(resolve));
91
+ }
92
+ return() {
93
+ this.close("closed");
94
+ return Promise.resolve({ done: true, value: undefined });
95
+ }
96
+ close(reason = "closed") {
97
+ if (this.isClosed)
98
+ return;
99
+ this.isClosed = true;
100
+ this.reason = reason;
101
+ this.queue.length = 0;
102
+ if (this.abortSignal !== undefined && this.abortHandler !== undefined) {
103
+ this.abortSignal.removeEventListener("abort", this.abortHandler);
104
+ this.abortSignal = undefined;
105
+ this.abortHandler = undefined;
106
+ }
107
+ this.remove();
108
+ for (const waiter of this.waiters.splice(0))
109
+ waiter({ done: true, value: undefined });
110
+ }
111
+ [Symbol.asyncIterator]() {
112
+ return this;
113
+ }
114
+ }
115
+ /** A bounded in-memory hub suitable for tests and local development, never for durable fan-out. */
116
+ export function memoryChannelHub(options = {}) {
117
+ const maxQueue = options.maxQueue ?? 64;
118
+ if (!Number.isSafeInteger(maxQueue) || maxQueue < 1) {
119
+ throw new RangeError("channel: maxQueue must be a positive safe integer");
120
+ }
121
+ const historySize = options.historySize ?? maxQueue;
122
+ if (!Number.isSafeInteger(historySize) || historySize < 0) {
123
+ throw new RangeError("channel: historySize must be a non-negative safe integer");
124
+ }
125
+ const subscribers = new Map();
126
+ const sequences = new Map();
127
+ const history = new Map();
128
+ const tokenFor = (channel, sequence) => `${channel}:${sequence.toString(36)}`;
129
+ const sequenceOf = (channel, token) => {
130
+ const prefix = `${channel}:`;
131
+ if (!token.startsWith(prefix))
132
+ return undefined;
133
+ const digits = token.slice(prefix.length);
134
+ if (!/^[0-9a-z]+$/.test(digits))
135
+ return undefined;
136
+ const sequence = Number.parseInt(digits, 36);
137
+ return Number.isSafeInteger(sequence) && sequence > 0 ? sequence : undefined;
138
+ };
139
+ return {
140
+ subscribe(channel, subscriptionOptions = {}) {
141
+ const queue = subscriptionOptions.maxQueue ?? maxQueue;
142
+ if (!Number.isSafeInteger(queue) || queue < 1) {
143
+ throw new RangeError("channel: maxQueue must be a positive safe integer");
144
+ }
145
+ const currentSequence = sequences.get(channel.name) ?? 0;
146
+ const resumeFrom = subscriptionOptions.resumeFrom;
147
+ let replay = [];
148
+ if (resumeFrom !== undefined) {
149
+ const requestedSequence = sequenceOf(channel.name, resumeFrom);
150
+ const channelHistory = history.get(channel.name) ?? [];
151
+ const oldest = channelHistory[0]?.sequence;
152
+ const known = requestedSequence !== undefined &&
153
+ requestedSequence <= currentSequence &&
154
+ (requestedSequence === currentSequence ||
155
+ channelHistory.some((event) => event.sequence === requestedSequence));
156
+ if (!known)
157
+ throw new ChannelResumeUnavailableError(channel.name, resumeFrom);
158
+ replay = channelHistory.filter((event) => event.sequence > requestedSequence);
159
+ // Keep this explicit so a future history representation cannot silently truncate a resume.
160
+ if (oldest !== undefined && requestedSequence < oldest && replay.length === 0) {
161
+ throw new ChannelResumeUnavailableError(channel.name, resumeFrom);
162
+ }
163
+ if (replay.length > queue) {
164
+ throw new ChannelResumeUnavailableError(channel.name, resumeFrom);
165
+ }
166
+ }
167
+ let members = subscribers.get(channel.name);
168
+ if (members === undefined) {
169
+ members = new Set();
170
+ subscribers.set(channel.name, members);
171
+ }
172
+ let subscription;
173
+ const remove = () => {
174
+ members?.delete(subscription);
175
+ if (members?.size === 0)
176
+ subscribers.delete(channel.name);
177
+ };
178
+ subscription = new MemorySubscription(channel.name, queue, remove);
179
+ subscription.seed(replay);
180
+ members.add(subscription);
181
+ subscription.attachSignal(subscriptionOptions.signal);
182
+ return subscription;
183
+ },
184
+ publish(channel, data) {
185
+ const previous = sequences.get(channel.name) ?? 0;
186
+ if (previous === Number.MAX_SAFE_INTEGER) {
187
+ throw new RangeError("channel: sequence space exhausted");
188
+ }
189
+ const sequence = previous + 1;
190
+ sequences.set(channel.name, sequence);
191
+ const event = {
192
+ sequence,
193
+ resumeToken: tokenFor(channel.name, sequence),
194
+ data,
195
+ };
196
+ if (historySize > 0) {
197
+ const channelHistory = history.get(channel.name) ?? [];
198
+ channelHistory.push(event);
199
+ if (channelHistory.length > historySize)
200
+ channelHistory.shift();
201
+ history.set(channel.name, channelHistory);
202
+ }
203
+ for (const subscriber of subscribers.get(channel.name) ?? []) {
204
+ subscriber.push(event);
205
+ }
206
+ return event;
207
+ },
208
+ };
209
+ }
210
+ /** Adapt a channel subscription to a cancellable Web stream for SSE/HTTP adapters. */
211
+ export function channelReadableStream(subscription) {
212
+ const iterator = subscription[Symbol.asyncIterator]();
213
+ return new ReadableStream({
214
+ async pull(controller) {
215
+ try {
216
+ const result = await iterator.next();
217
+ if (result.done)
218
+ controller.close();
219
+ else
220
+ controller.enqueue(result.value);
221
+ }
222
+ catch (error) {
223
+ controller.error(error);
224
+ }
225
+ },
226
+ cancel() {
227
+ subscription.close();
228
+ },
229
+ });
230
+ }
231
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../src/channel.ts"],"names":[],"mappings":"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"}
package/dist/data.d.ts ADDED
@@ -0,0 +1,117 @@
1
+ /** Public, token-only data access contracts. Durable adapters and RLS policy enforcement stay outside
2
+ * this package; this subpath defines the typed seam they implement. */
3
+ export declare const DATA_CAPABILITIES: Readonly<{
4
+ readonly read: "db.read";
5
+ readonly write: "db.write";
6
+ }>;
7
+ export type DataAccess = keyof typeof DATA_CAPABILITIES;
8
+ export type DataCapability = (typeof DATA_CAPABILITIES)[DataAccess];
9
+ export interface DataOperationSpec {
10
+ readonly access: DataAccess;
11
+ readonly input?: unknown;
12
+ readonly output?: unknown;
13
+ }
14
+ export type DataOperationMap = Readonly<Record<string, DataOperationSpec>>;
15
+ export interface DataContract<Operations extends DataOperationMap = DataOperationMap> {
16
+ readonly version: string;
17
+ readonly operations: Operations;
18
+ }
19
+ /** Opaque request-local RLS (or equivalent data-policy) scope passed to an adapter. */
20
+ export interface RlsScope {
21
+ /** Caller-owned scope token. The public seam never interprets, logs, or derives identity from it. */
22
+ readonly token: string;
23
+ /** Optional opaque digest for correlating a scope without exposing tenant or subject data. */
24
+ readonly digest?: string;
25
+ }
26
+ /** Backward-compatible name for the request scope carried by every data operation. */
27
+ export type DataScope = RlsScope;
28
+ export interface DataRequest<Operation extends string = string, Input = unknown> {
29
+ readonly operation: Operation;
30
+ readonly scope: DataScope;
31
+ readonly capability: DataCapability;
32
+ readonly input: Input;
33
+ }
34
+ export interface DataDrift {
35
+ readonly kind: "version" | "added" | "removed" | "access-changed";
36
+ readonly operation?: string;
37
+ readonly declaredAccess?: DataAccess;
38
+ readonly observedAccess?: DataAccess;
39
+ readonly declaredVersion?: string;
40
+ readonly observedVersion?: string;
41
+ }
42
+ type InputOf<Operation> = Operation extends {
43
+ readonly input: infer Input;
44
+ } ? Input : never;
45
+ type OutputOf<Operation> = Operation extends {
46
+ readonly output: infer Output;
47
+ } ? Output : unknown;
48
+ type CapabilityOf<Operation> = Operation extends {
49
+ readonly access: "read";
50
+ } ? typeof DATA_CAPABILITIES.read : Operation extends {
51
+ readonly access: "write";
52
+ } ? typeof DATA_CAPABILITIES.write : DataCapability;
53
+ type InputField<Input> = [Input] extends [never] ? {
54
+ readonly input?: never;
55
+ } : {
56
+ readonly input: Input;
57
+ };
58
+ export type DataInput<Contract extends DataContract, Operation extends keyof Contract["operations"] & string> = Contract["operations"][Operation] extends infer Definition ? InputOf<Definition> : never;
59
+ export type DataOutput<Contract extends DataContract, Operation extends keyof Contract["operations"] & string> = Contract["operations"][Operation] extends infer Definition ? OutputOf<Definition> : unknown;
60
+ export type DataRequestFor<Contract extends DataContract, Operation extends keyof Contract["operations"] & string> = {
61
+ readonly operation: Operation;
62
+ readonly scope: DataScope;
63
+ readonly capability: CapabilityOf<Contract["operations"][Operation]>;
64
+ } & InputField<DataInput<Contract, Operation>>;
65
+ export interface TypedDataPort<Contract extends DataContract> {
66
+ execute<Operation extends keyof Contract["operations"] & string>(request: DataRequestFor<Contract, Operation>): Promise<DataOutput<Contract, Operation>>;
67
+ }
68
+ /** Runtime capability beacon used by a request-bound data port. */
69
+ export type DataCapabilityBeacon = (context: object, capability: DataCapability) => void;
70
+ /** Options for the public request-bound data port wrapper. */
71
+ export interface DataPortOptions {
72
+ /** Usually `useCapability` from `@nifrajs/core/capabilities`. */
73
+ readonly beacon?: DataCapabilityBeacon;
74
+ }
75
+ /** A data port bound to one request context; every operation emits capability evidence first. */
76
+ export interface BoundDataPort<Contract extends DataContract> extends TypedDataPort<Contract> {
77
+ }
78
+ /** Public factory for wiring a private data adapter into Nifra's capability evidence chain. */
79
+ export interface DataPort<Contract extends DataContract> {
80
+ for(context: object): BoundDataPort<Contract>;
81
+ }
82
+ /**
83
+ * Bind a private data adapter to request-local capability evidence.
84
+ *
85
+ * The adapter remains responsible for RLS enforcement and durable storage. This wrapper owns the
86
+ * framework-side proof boundary: it emits exactly the operation's typed `db.read`/`db.write` token
87
+ * before invoking the adapter, and refuses to run when no beacon is configured or the beacon denies
88
+ * the operation. The context is never copied into the request or retained by the port.
89
+ *
90
+ * The emitted token is derived from the **contract**, never from `request.capability`. The typed
91
+ * request narrows that field, but types are erased before this line runs, and a request assembled
92
+ * from decoded input would otherwise let a write operation announce itself as `db.read` - evidence
93
+ * that names the wrong capability is worse than no evidence, because the ledger looks satisfied. An
94
+ * unknown operation, or a declared capability that disagrees with the contract, fails closed.
95
+ */
96
+ export declare function createDataPort<Contract extends DataContract>(contract: Contract, adapter: TypedDataPort<Contract>, options?: DataPortOptions): DataPort<Contract>;
97
+ /** Create a bounded, opaque RLS/equivalent policy scope for a data adapter. */
98
+ export declare function rlsScope(token: string, digest?: string): RlsScope;
99
+ /** Backward-compatible constructor for {@link RlsScope}. */
100
+ export declare function dataScope(token: string, digest?: string): DataScope;
101
+ /** Define and freeze a token-only data contract. Input/output types are erased at runtime. */
102
+ export declare function defineDataContract<const Operations extends DataOperationMap>(input: {
103
+ readonly version: string;
104
+ readonly operations: Operations;
105
+ }): DataContract<Operations>;
106
+ export interface DataContractSnapshot {
107
+ readonly version: string;
108
+ readonly operations: Readonly<Record<string, {
109
+ readonly access: DataAccess;
110
+ }>>;
111
+ }
112
+ /** Strip a contract to its token-only version/access snapshot for CI or adapter drift checks. */
113
+ export declare function snapshotDataContract(contract: DataContract): DataContractSnapshot;
114
+ /** Compare a declared contract with an adapter-observed token-only snapshot. */
115
+ export declare function diffDataContract(declared: DataContract, observed: DataContractSnapshot | DataContract): readonly DataDrift[];
116
+ export {};
117
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
package/dist/data.js ADDED
@@ -0,0 +1,163 @@
1
+ /** Public, token-only data access contracts. Durable adapters and RLS policy enforcement stay outside
2
+ * this package; this subpath defines the typed seam they implement. */
3
+ export const DATA_CAPABILITIES = Object.freeze({
4
+ read: "db.read",
5
+ write: "db.write",
6
+ });
7
+ /**
8
+ * Bind a private data adapter to request-local capability evidence.
9
+ *
10
+ * The adapter remains responsible for RLS enforcement and durable storage. This wrapper owns the
11
+ * framework-side proof boundary: it emits exactly the operation's typed `db.read`/`db.write` token
12
+ * before invoking the adapter, and refuses to run when no beacon is configured or the beacon denies
13
+ * the operation. The context is never copied into the request or retained by the port.
14
+ *
15
+ * The emitted token is derived from the **contract**, never from `request.capability`. The typed
16
+ * request narrows that field, but types are erased before this line runs, and a request assembled
17
+ * from decoded input would otherwise let a write operation announce itself as `db.read` - evidence
18
+ * that names the wrong capability is worse than no evidence, because the ledger looks satisfied. An
19
+ * unknown operation, or a declared capability that disagrees with the contract, fails closed.
20
+ */
21
+ export function createDataPort(contract, adapter, options = {}) {
22
+ if (contract === null || typeof contract !== "object" || contract.operations === undefined) {
23
+ throw new TypeError("data: contract must be a defineDataContract result");
24
+ }
25
+ if (adapter === null || typeof adapter !== "object" || typeof adapter.execute !== "function") {
26
+ throw new TypeError("data: adapter must implement execute(request)");
27
+ }
28
+ function bind(context) {
29
+ if (context === null || typeof context !== "object") {
30
+ throw new TypeError("data: context must be an object");
31
+ }
32
+ const beacon = options.beacon;
33
+ if (beacon === undefined) {
34
+ throw new Error("@nifrajs/core/data: for(context) needs a beacon - pass `beacon: useCapability` to createDataPort");
35
+ }
36
+ return Object.freeze({
37
+ execute(request) {
38
+ const declared = contract.operations[request.operation];
39
+ if (declared === undefined || !isDataAccess(declared.access)) {
40
+ return Promise.reject(new TypeError(`data: ${String(request.operation)} is not declared by this contract`));
41
+ }
42
+ const capability = DATA_CAPABILITIES[declared.access];
43
+ if (request.capability !== capability) {
44
+ return Promise.reject(new TypeError(`data: ${String(request.operation)} requires ${capability}`));
45
+ }
46
+ try {
47
+ beacon(context, capability);
48
+ }
49
+ catch (error) {
50
+ return Promise.reject(error);
51
+ }
52
+ return adapter.execute(request);
53
+ },
54
+ });
55
+ }
56
+ return Object.freeze({ for: bind });
57
+ }
58
+ function assertToken(value, label) {
59
+ if (typeof value !== "string" ||
60
+ value.length === 0 ||
61
+ value.length > 256 ||
62
+ hasControlCharacter(value)) {
63
+ throw new TypeError(`data: ${label} must be a bounded opaque token`);
64
+ }
65
+ return value;
66
+ }
67
+ function hasControlCharacter(value) {
68
+ for (let index = 0; index < value.length; index++) {
69
+ const code = value.charCodeAt(index);
70
+ if (code <= 31 || code === 127)
71
+ return true;
72
+ }
73
+ return false;
74
+ }
75
+ /** Create a bounded, opaque RLS/equivalent policy scope for a data adapter. */
76
+ export function rlsScope(token, digest) {
77
+ const scope = {
78
+ token: assertToken(token, "scope token"),
79
+ ...(digest === undefined ? {} : { digest: assertToken(digest, "scope digest") }),
80
+ };
81
+ return Object.freeze(scope);
82
+ }
83
+ /** Backward-compatible constructor for {@link RlsScope}. */
84
+ export function dataScope(token, digest) {
85
+ return rlsScope(token, digest);
86
+ }
87
+ function isDataAccess(value) {
88
+ return value === "read" || value === "write";
89
+ }
90
+ function validVersion(value) {
91
+ return (typeof value === "string" &&
92
+ value.length > 0 &&
93
+ value.length <= 128 &&
94
+ !hasControlCharacter(value));
95
+ }
96
+ function validOperationName(value) {
97
+ return /^[A-Za-z][A-Za-z0-9._-]{0,127}$/.test(value);
98
+ }
99
+ /** Define and freeze a token-only data contract. Input/output types are erased at runtime. */
100
+ export function defineDataContract(input) {
101
+ if (!validVersion(input.version))
102
+ throw new TypeError("data: version must be a bounded token");
103
+ if (input.operations === null || typeof input.operations !== "object") {
104
+ throw new TypeError("data: operations must be an object");
105
+ }
106
+ const operations = {};
107
+ for (const [name, operation] of Object.entries(input.operations)) {
108
+ if (!validOperationName(name))
109
+ throw new TypeError(`data: invalid operation name ${name}`);
110
+ if (operation === null || typeof operation !== "object" || !isDataAccess(operation.access)) {
111
+ throw new TypeError(`data: ${name} must declare read or write access`);
112
+ }
113
+ // `input` and `output` are type witnesses only. Never retain runtime schemas, defaults, or
114
+ // caller-owned values in the public contract object; adapters receive only token metadata.
115
+ operations[name] = Object.freeze({ access: operation.access });
116
+ }
117
+ return Object.freeze({
118
+ version: input.version,
119
+ operations: Object.freeze(operations),
120
+ });
121
+ }
122
+ /** Strip a contract to its token-only version/access snapshot for CI or adapter drift checks. */
123
+ export function snapshotDataContract(contract) {
124
+ const operations = {};
125
+ for (const [name, operation] of Object.entries(contract.operations)) {
126
+ if (isDataAccess(operation.access))
127
+ operations[name] = { access: operation.access };
128
+ }
129
+ return Object.freeze({ version: contract.version, operations: Object.freeze(operations) });
130
+ }
131
+ /** Compare a declared contract with an adapter-observed token-only snapshot. */
132
+ export function diffDataContract(declared, observed) {
133
+ const left = snapshotDataContract(declared);
134
+ const right = "operations" in observed ? snapshotDataContract(observed) : observed;
135
+ const drift = [];
136
+ if (left.version !== right.version) {
137
+ drift.push({
138
+ kind: "version",
139
+ declaredVersion: left.version,
140
+ observedVersion: right.version,
141
+ });
142
+ }
143
+ for (const [name, operation] of Object.entries(left.operations)) {
144
+ const candidate = right.operations[name];
145
+ if (candidate === undefined) {
146
+ drift.push({ kind: "removed", operation: name });
147
+ }
148
+ else if (candidate.access !== operation.access) {
149
+ drift.push({
150
+ kind: "access-changed",
151
+ operation: name,
152
+ declaredAccess: operation.access,
153
+ observedAccess: candidate.access,
154
+ });
155
+ }
156
+ }
157
+ for (const [name] of Object.entries(right.operations)) {
158
+ if (left.operations[name] === undefined)
159
+ drift.push({ kind: "added", operation: name });
160
+ }
161
+ return Object.freeze(drift);
162
+ }
163
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * read its own package.json at runtime. `scripts/version.ts` rewrites it on every release bump and
10
10
  * `check:publish` asserts it equals `@nifrajs/core`'s package version.
11
11
  */
12
- export declare const VERSION: "2.9.0";
12
+ export declare const VERSION: "2.10.0";
13
13
  export type Version = typeof VERSION;
14
14
  export * from "./server.js";
15
15
  //# sourceMappingURL=index.d.ts.map