@cotal-ai/core 0.11.6 → 0.13.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/dist/acls.d.ts +31 -7
- package/dist/acls.d.ts.map +1 -1
- package/dist/acls.js +105 -17
- package/dist/acls.js.map +1 -1
- package/dist/agent-file.js +1 -1
- package/dist/agent-file.js.map +1 -1
- package/dist/auth-provider.d.ts +90 -10
- package/dist/auth-provider.d.ts.map +1 -1
- package/dist/auth-provider.js.map +1 -1
- package/dist/backup-config.d.ts +55 -0
- package/dist/backup-config.d.ts.map +1 -0
- package/dist/backup-config.js +243 -0
- package/dist/backup-config.js.map +1 -0
- package/dist/backup.d.ts +86 -0
- package/dist/backup.d.ts.map +1 -0
- package/dist/backup.js +497 -0
- package/dist/backup.js.map +1 -0
- package/dist/broker-floor.d.ts +34 -0
- package/dist/broker-floor.d.ts.map +1 -0
- package/dist/broker-floor.js +39 -0
- package/dist/broker-floor.js.map +1 -0
- package/dist/canonical.d.ts +24 -0
- package/dist/canonical.d.ts.map +1 -0
- package/dist/canonical.js +159 -0
- package/dist/canonical.js.map +1 -0
- package/dist/channels.d.ts.map +1 -1
- package/dist/channels.js +8 -1
- package/dist/channels.js.map +1 -1
- package/dist/connector.d.ts +4 -0
- package/dist/connector.d.ts.map +1 -1
- package/dist/endpoint-action.d.ts +424 -0
- package/dist/endpoint-action.d.ts.map +1 -0
- package/dist/endpoint-action.js +910 -0
- package/dist/endpoint-action.js.map +1 -0
- package/dist/endpoint-binding.d.ts +344 -0
- package/dist/endpoint-binding.d.ts.map +1 -0
- package/dist/endpoint-binding.js +753 -0
- package/dist/endpoint-binding.js.map +1 -0
- package/dist/endpoint-checkpoint.d.ts +292 -0
- package/dist/endpoint-checkpoint.d.ts.map +1 -0
- package/dist/endpoint-checkpoint.js +818 -0
- package/dist/endpoint-checkpoint.js.map +1 -0
- package/dist/endpoint-cluster.d.ts +95 -0
- package/dist/endpoint-cluster.d.ts.map +1 -0
- package/dist/endpoint-cluster.js +194 -0
- package/dist/endpoint-cluster.js.map +1 -0
- package/dist/endpoint-contract-store.d.ts +90 -0
- package/dist/endpoint-contract-store.d.ts.map +1 -0
- package/dist/endpoint-contract-store.js +348 -0
- package/dist/endpoint-contract-store.js.map +1 -0
- package/dist/endpoint-envelope.d.ts +165 -0
- package/dist/endpoint-envelope.d.ts.map +1 -0
- package/dist/endpoint-envelope.js +346 -0
- package/dist/endpoint-envelope.js.map +1 -0
- package/dist/endpoint-grants.d.ts +123 -0
- package/dist/endpoint-grants.d.ts.map +1 -0
- package/dist/endpoint-grants.js +215 -0
- package/dist/endpoint-grants.js.map +1 -0
- package/dist/endpoint-guard.d.ts +222 -0
- package/dist/endpoint-guard.d.ts.map +1 -0
- package/dist/endpoint-guard.js +468 -0
- package/dist/endpoint-guard.js.map +1 -0
- package/dist/endpoint-handle.d.ts +176 -0
- package/dist/endpoint-handle.d.ts.map +1 -0
- package/dist/endpoint-handle.js +608 -0
- package/dist/endpoint-handle.js.map +1 -0
- package/dist/endpoint-journal.d.ts +225 -0
- package/dist/endpoint-journal.d.ts.map +1 -0
- package/dist/endpoint-journal.js +431 -0
- package/dist/endpoint-journal.js.map +1 -0
- package/dist/endpoint-receipt.d.ts +225 -0
- package/dist/endpoint-receipt.d.ts.map +1 -0
- package/dist/endpoint-receipt.js +417 -0
- package/dist/endpoint-receipt.js.map +1 -0
- package/dist/endpoint-records.d.ts +243 -0
- package/dist/endpoint-records.d.ts.map +1 -0
- package/dist/endpoint-records.js +591 -0
- package/dist/endpoint-records.js.map +1 -0
- package/dist/endpoint-serve.d.ts +176 -0
- package/dist/endpoint-serve.d.ts.map +1 -0
- package/dist/endpoint-serve.js +446 -0
- package/dist/endpoint-serve.js.map +1 -0
- package/dist/endpoint-service.d.ts +518 -0
- package/dist/endpoint-service.d.ts.map +1 -0
- package/dist/endpoint-service.js +973 -0
- package/dist/endpoint-service.js.map +1 -0
- package/dist/endpoint-session.d.ts +398 -0
- package/dist/endpoint-session.d.ts.map +1 -0
- package/dist/endpoint-session.js +834 -0
- package/dist/endpoint-session.js.map +1 -0
- package/dist/endpoint-signing.d.ts +105 -0
- package/dist/endpoint-signing.d.ts.map +1 -0
- package/dist/endpoint-signing.js +190 -0
- package/dist/endpoint-signing.js.map +1 -0
- package/dist/endpoint-subjects.d.ts +222 -0
- package/dist/endpoint-subjects.d.ts.map +1 -0
- package/dist/endpoint-subjects.js +381 -0
- package/dist/endpoint-subjects.js.map +1 -0
- package/dist/endpoint-supervisor.d.ts +19 -0
- package/dist/endpoint-supervisor.d.ts.map +1 -0
- package/dist/endpoint-supervisor.js +12 -0
- package/dist/endpoint-supervisor.js.map +1 -0
- package/dist/endpoint-traits.d.ts +225 -0
- package/dist/endpoint-traits.d.ts.map +1 -0
- package/dist/endpoint-traits.js +469 -0
- package/dist/endpoint-traits.js.map +1 -0
- package/dist/endpoint-verbs.d.ts +277 -0
- package/dist/endpoint-verbs.d.ts.map +1 -0
- package/dist/endpoint-verbs.js +576 -0
- package/dist/endpoint-verbs.js.map +1 -0
- package/dist/endpoint-virtual.d.ts +308 -0
- package/dist/endpoint-virtual.d.ts.map +1 -0
- package/dist/endpoint-virtual.js +440 -0
- package/dist/endpoint-virtual.js.map +1 -0
- package/dist/endpoint-work.d.ts +304 -0
- package/dist/endpoint-work.d.ts.map +1 -0
- package/dist/endpoint-work.js +728 -0
- package/dist/endpoint-work.js.map +1 -0
- package/dist/endpoint.d.ts +66 -22
- package/dist/endpoint.d.ts.map +1 -1
- package/dist/endpoint.js +289 -89
- package/dist/endpoint.js.map +1 -1
- package/dist/evict.d.ts +95 -32
- package/dist/evict.d.ts.map +1 -1
- package/dist/evict.js +193 -3
- package/dist/evict.js.map +1 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -1
- package/dist/lease.d.ts +4 -0
- package/dist/lease.d.ts.map +1 -1
- package/dist/lease.js.map +1 -1
- package/dist/members.d.ts +4 -4
- package/dist/members.d.ts.map +1 -1
- package/dist/members.js +12 -12
- package/dist/members.js.map +1 -1
- package/dist/provision.d.ts +78 -20
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +214 -37
- package/dist/provision.js.map +1 -1
- package/dist/runtime.d.ts +3 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/safe-pattern.d.ts +33 -0
- package/dist/safe-pattern.d.ts.map +1 -0
- package/dist/safe-pattern.js +486 -0
- package/dist/safe-pattern.js.map +1 -0
- package/dist/schema-profile.d.ts +93 -0
- package/dist/schema-profile.d.ts.map +1 -0
- package/dist/schema-profile.js +284 -0
- package/dist/schema-profile.js.map +1 -0
- package/dist/secret-store.d.ts +46 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +2 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/space-auth.d.ts +9 -0
- package/dist/space-auth.d.ts.map +1 -0
- package/dist/space-auth.js +126 -0
- package/dist/space-auth.js.map +1 -0
- package/dist/streams.d.ts +14 -10
- package/dist/streams.d.ts.map +1 -1
- package/dist/streams.js +47 -76
- package/dist/streams.js.map +1 -1
- package/dist/subjects.d.ts +100 -40
- package/dist/subjects.d.ts.map +1 -1
- package/dist/subjects.js +136 -60
- package/dist/subjects.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
package/dist/backup.js
ADDED
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import { AckPolicy, DeliverPolicy, ReplayPolicy, } from "@nats-io/jetstream";
|
|
2
|
+
import { nanos } from "@nats-io/transport-node";
|
|
3
|
+
import { canonicalBackupStreamConfig, spaceBackupInventory, validateBackupStreamState, validateCanonicalBackupStreamConfig, } from "./backup-config.js";
|
|
4
|
+
import { dlvDurableConfig, dmDurableConfig, fanoutDurableConfig, inboxReaderConfig, taskDurableConfig, } from "./streams.js";
|
|
5
|
+
import { FANOUT_DURABLE, INBOX_READER_DURABLE, assertInboxConnId, chatStream, dlvStream, dmStream, inboxStream, taskStream, } from "./subjects.js";
|
|
6
|
+
const DEFAULT_TRANSFER_TIMEOUT_MS = 5 * 60 * 1000;
|
|
7
|
+
const DEFAULT_SINK_TIMEOUT_MS = 1_000;
|
|
8
|
+
const MAX_SINK_TIMEOUT_MS = 1_500;
|
|
9
|
+
export class JetStreamBackupError extends Error {
|
|
10
|
+
code;
|
|
11
|
+
errCode;
|
|
12
|
+
constructor(message, code, errCode) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.errCode = errCode;
|
|
16
|
+
this.name = "JetStreamBackupError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function decodeJson(data, context) {
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(new TextDecoder().decode(data));
|
|
22
|
+
}
|
|
23
|
+
catch (cause) {
|
|
24
|
+
throw new JetStreamBackupError(`${context}: invalid JSON response: ${cause.message}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function throwApiError(response, context) {
|
|
28
|
+
if (!response.error)
|
|
29
|
+
return;
|
|
30
|
+
throw new JetStreamBackupError(`${context}: ${response.error.description ?? "JetStream API error"}`, response.error.code, response.error.err_code);
|
|
31
|
+
}
|
|
32
|
+
function statusError(msg, context) {
|
|
33
|
+
const code = msg.headers?.code ?? 0;
|
|
34
|
+
if (code < 300)
|
|
35
|
+
return undefined;
|
|
36
|
+
return new JetStreamBackupError(`${context}: ${code} ${msg.headers?.description || "status error"}`, code);
|
|
37
|
+
}
|
|
38
|
+
function assertExactSubject(subject, label) {
|
|
39
|
+
if (typeof subject !== "string" ||
|
|
40
|
+
subject.length === 0 ||
|
|
41
|
+
subject.startsWith(".") ||
|
|
42
|
+
subject.endsWith(".") ||
|
|
43
|
+
subject.includes("..") ||
|
|
44
|
+
/[\s*>]/.test(subject))
|
|
45
|
+
throw new Error(`${label} must be one exact NATS subject`);
|
|
46
|
+
return subject;
|
|
47
|
+
}
|
|
48
|
+
function assertBackupStream(space, stream) {
|
|
49
|
+
canonicalBackupStreamConfig(space, stream);
|
|
50
|
+
return stream;
|
|
51
|
+
}
|
|
52
|
+
async function withDeadline(promise, timeoutMs, message) {
|
|
53
|
+
let timer;
|
|
54
|
+
try {
|
|
55
|
+
return await Promise.race([
|
|
56
|
+
promise,
|
|
57
|
+
new Promise((_, reject) => {
|
|
58
|
+
timer = setTimeout(() => reject(new JetStreamBackupError(message)), timeoutMs);
|
|
59
|
+
}),
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
if (timer)
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Download a no-consumer native snapshot through one ordered, deadline-bounded sink. Each ackable
|
|
68
|
+
* binary chunk is ACKed only after its sink call succeeds. Completion requires a clean empty EOF
|
|
69
|
+
* after all accepted chunks. */
|
|
70
|
+
export async function downloadStreamSnapshot(nc, stream, opts) {
|
|
71
|
+
assertExactSubject(opts.deliverSubject, "snapshot deliverSubject");
|
|
72
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TRANSFER_TIMEOUT_MS;
|
|
73
|
+
if (!Number.isInteger(timeoutMs) || timeoutMs <= 0)
|
|
74
|
+
throw new Error("snapshot timeoutMs must be positive");
|
|
75
|
+
const sinkTimeoutMs = opts.sinkTimeoutMs ?? DEFAULT_SINK_TIMEOUT_MS;
|
|
76
|
+
if (!Number.isInteger(sinkTimeoutMs) || sinkTimeoutMs <= 0 || sinkTimeoutMs > MAX_SINK_TIMEOUT_MS)
|
|
77
|
+
throw new Error(`snapshot sinkTimeoutMs must be between 1 and ${MAX_SINK_TIMEOUT_MS}`);
|
|
78
|
+
let metadata;
|
|
79
|
+
let eof = false;
|
|
80
|
+
let phase = "active";
|
|
81
|
+
let processing = Promise.resolve();
|
|
82
|
+
let inFlightSink;
|
|
83
|
+
let resolveDone;
|
|
84
|
+
let rejectDone;
|
|
85
|
+
const done = new Promise((resolve, reject) => {
|
|
86
|
+
resolveDone = resolve;
|
|
87
|
+
rejectDone = reject;
|
|
88
|
+
});
|
|
89
|
+
async function sinkChunk(chunk) {
|
|
90
|
+
const sink = Promise.resolve().then(() => opts.onChunk(chunk));
|
|
91
|
+
const sinkSettled = sink.then(() => { }, () => { });
|
|
92
|
+
inFlightSink = sinkSettled;
|
|
93
|
+
void sinkSettled.then(() => {
|
|
94
|
+
if (inFlightSink === sinkSettled)
|
|
95
|
+
inFlightSink = undefined;
|
|
96
|
+
});
|
|
97
|
+
await withDeadline(sink, sinkTimeoutMs, "snapshot sink deadline exceeded");
|
|
98
|
+
}
|
|
99
|
+
// Observe the internal promise immediately; the async function's returned promise adopts it below.
|
|
100
|
+
void done.catch(() => { });
|
|
101
|
+
let timer;
|
|
102
|
+
let sub;
|
|
103
|
+
sub = nc.subscribe(opts.deliverSubject, {
|
|
104
|
+
callback: (error, msg) => {
|
|
105
|
+
if (phase !== "active")
|
|
106
|
+
return;
|
|
107
|
+
if (error)
|
|
108
|
+
return fail(error);
|
|
109
|
+
processing = processing.then(async () => {
|
|
110
|
+
if (phase !== "active")
|
|
111
|
+
return;
|
|
112
|
+
const protocolError = statusError(msg, `snapshot ${stream}`);
|
|
113
|
+
if (protocolError)
|
|
114
|
+
throw protocolError;
|
|
115
|
+
if (msg.data.length === 0) {
|
|
116
|
+
eof = true;
|
|
117
|
+
complete();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// `window_size` arrived in NATS 2.12.5, and legacy flow control can omit replies on several
|
|
121
|
+
// data chunks; only empty data is EOF, while a reply merely makes this chunk ACKable.
|
|
122
|
+
await sinkChunk(msg.data.slice());
|
|
123
|
+
if (phase !== "active")
|
|
124
|
+
return;
|
|
125
|
+
if (msg.reply && !msg.respond())
|
|
126
|
+
throw new JetStreamBackupError(`snapshot ${stream}: chunk ACK failed`);
|
|
127
|
+
}).catch((cause) => fail(cause instanceof Error ? cause : new Error(String(cause))));
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
if (phase === "active")
|
|
131
|
+
timer = setTimeout(() => fail(new JetStreamBackupError(`snapshot ${stream}: transfer deadline exceeded`)), timeoutMs);
|
|
132
|
+
else
|
|
133
|
+
try {
|
|
134
|
+
sub.unsubscribe();
|
|
135
|
+
}
|
|
136
|
+
catch { /* already closed */ }
|
|
137
|
+
function cleanup() {
|
|
138
|
+
if (timer)
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
try {
|
|
141
|
+
sub?.unsubscribe();
|
|
142
|
+
}
|
|
143
|
+
catch { /* already closed */ }
|
|
144
|
+
}
|
|
145
|
+
function fail(error) {
|
|
146
|
+
if (phase !== "active")
|
|
147
|
+
return;
|
|
148
|
+
phase = "failing";
|
|
149
|
+
cleanup();
|
|
150
|
+
const sink = inFlightSink;
|
|
151
|
+
void (async () => {
|
|
152
|
+
if (sink) {
|
|
153
|
+
try {
|
|
154
|
+
await withDeadline(sink, sinkTimeoutMs, "snapshot sink settlement deadline exceeded");
|
|
155
|
+
}
|
|
156
|
+
catch { /* the transfer already has its primary failure */ }
|
|
157
|
+
}
|
|
158
|
+
phase = "settled";
|
|
159
|
+
rejectDone(error);
|
|
160
|
+
})();
|
|
161
|
+
}
|
|
162
|
+
function complete() {
|
|
163
|
+
if (!eof || !metadata || phase !== "active")
|
|
164
|
+
return;
|
|
165
|
+
phase = "settled";
|
|
166
|
+
cleanup();
|
|
167
|
+
resolveDone(metadata);
|
|
168
|
+
}
|
|
169
|
+
const deadline = Date.now() + timeoutMs;
|
|
170
|
+
void (async () => {
|
|
171
|
+
await nc.flush();
|
|
172
|
+
if (phase !== "active")
|
|
173
|
+
return;
|
|
174
|
+
const remaining = deadline - Date.now();
|
|
175
|
+
if (remaining <= 0)
|
|
176
|
+
throw new JetStreamBackupError(`snapshot ${stream}: transfer deadline exceeded`);
|
|
177
|
+
const responseMsg = await nc.request(`$JS.API.STREAM.SNAPSHOT.${stream}`, JSON.stringify({
|
|
178
|
+
deliver_subject: opts.deliverSubject,
|
|
179
|
+
no_consumers: true,
|
|
180
|
+
...(opts.checkMessages ? { jsck: true } : {}),
|
|
181
|
+
}), { timeout: remaining });
|
|
182
|
+
if (phase !== "active")
|
|
183
|
+
return;
|
|
184
|
+
const response = decodeJson(responseMsg.data, `snapshot ${stream} initiation`);
|
|
185
|
+
throwApiError(response, `snapshot ${stream} initiation`);
|
|
186
|
+
if (!response.config || !response.state)
|
|
187
|
+
throw new JetStreamBackupError(`snapshot ${stream} initiation: response omitted config or state`);
|
|
188
|
+
metadata = { config: response.config, state: validateBackupStreamState(response.state) };
|
|
189
|
+
complete();
|
|
190
|
+
})().catch((cause) => fail(cause instanceof Error ? cause : new Error(String(cause))));
|
|
191
|
+
return done;
|
|
192
|
+
}
|
|
193
|
+
/** Initiate restore with caller-supplied, current canonical config and separately validated state.
|
|
194
|
+
* Snapshot-embedded config is never trusted or sent to the target broker. */
|
|
195
|
+
export async function initiateStreamRestore(nc, space, stream, config, state, timeoutMs = DEFAULT_TRANSFER_TIMEOUT_MS) {
|
|
196
|
+
const canonicalConfig = validateCanonicalBackupStreamConfig(space, stream, config);
|
|
197
|
+
const canonicalState = validateBackupStreamState(state);
|
|
198
|
+
const responseMsg = await nc.request(`$JS.API.STREAM.RESTORE.${stream}`, JSON.stringify({ config: canonicalConfig, state: canonicalState }), { timeout: timeoutMs });
|
|
199
|
+
const response = decodeJson(responseMsg.data, `restore ${stream} initiation`);
|
|
200
|
+
throwApiError(response, `restore ${stream} initiation`);
|
|
201
|
+
if (!response.deliver_subject)
|
|
202
|
+
throw new JetStreamBackupError(`restore ${stream} initiation: missing deliver_subject`);
|
|
203
|
+
assertExactSubject(response.deliver_subject, "restore deliver_subject");
|
|
204
|
+
if (!response.deliver_subject.startsWith(`$JS.SNAPSHOT.RESTORE.${stream}.`))
|
|
205
|
+
throw new JetStreamBackupError(`restore ${stream} initiation returned a cross-stream delivery subject`);
|
|
206
|
+
return { stream, deliverSubject: response.deliver_subject };
|
|
207
|
+
}
|
|
208
|
+
/** Upload one non-empty binary restore chunk and await the server's storage ACK. */
|
|
209
|
+
export async function uploadStreamRestoreChunk(nc, session, chunk, timeoutMs = DEFAULT_TRANSFER_TIMEOUT_MS) {
|
|
210
|
+
if (!(chunk instanceof Uint8Array) || chunk.length === 0)
|
|
211
|
+
throw new Error("restore chunks must be non-empty Uint8Array values; empty is reserved for finalization");
|
|
212
|
+
const response = await nc.request(session.deliverSubject, chunk, { timeout: timeoutMs });
|
|
213
|
+
const error = statusError(response, `restore ${session.stream} chunk`);
|
|
214
|
+
if (error)
|
|
215
|
+
throw error;
|
|
216
|
+
if (response.data.length)
|
|
217
|
+
throw new JetStreamBackupError(`restore ${session.stream} chunk: ${new TextDecoder().decode(response.data)}`);
|
|
218
|
+
}
|
|
219
|
+
/** Send the empty EOF request and require the final stream-create response. */
|
|
220
|
+
export async function finalizeStreamRestore(nc, session, timeoutMs = DEFAULT_TRANSFER_TIMEOUT_MS) {
|
|
221
|
+
const responseMsg = await nc.request(session.deliverSubject, new Uint8Array(0), { timeout: timeoutMs });
|
|
222
|
+
const transportError = statusError(responseMsg, `restore ${session.stream} finalization`);
|
|
223
|
+
if (transportError)
|
|
224
|
+
throw transportError;
|
|
225
|
+
const response = decodeJson(responseMsg.data, `restore ${session.stream} finalization`);
|
|
226
|
+
throwApiError(response, `restore ${session.stream} finalization`);
|
|
227
|
+
if (!response.config || !response.state)
|
|
228
|
+
throw new JetStreamBackupError(`restore ${session.stream} finalization: response omitted config or state`);
|
|
229
|
+
return { config: response.config, state: validateBackupStreamState(response.state) };
|
|
230
|
+
}
|
|
231
|
+
function principalFromDurable(name, prefix) {
|
|
232
|
+
if (!name.startsWith(prefix))
|
|
233
|
+
return undefined;
|
|
234
|
+
// Lifecycle-keyed durables (SPEC §13.1): dm_/dlv_ names carry the uid — `<owner>-<actor>-<lifecycleUid>`
|
|
235
|
+
// (owner/actor are `[A-Za-z0-9_]`, the uid is `[a-z0-9]`, so exactly three dash-separated tokens).
|
|
236
|
+
const match = /^([A-Za-z0-9_]+)-([A-Za-z0-9_]+)-([a-z0-9]+)$/.exec(name.slice(prefix.length));
|
|
237
|
+
return match ? { owner: match[1], actor: match[2], lifecycleUid: match[3] } : undefined;
|
|
238
|
+
}
|
|
239
|
+
function expectedConsumerConfig(space, stream, name) {
|
|
240
|
+
if (stream === chatStream(space) && name === FANOUT_DURABLE)
|
|
241
|
+
return fanoutDurableConfig(space);
|
|
242
|
+
if (stream === inboxStream(space) && name === INBOX_READER_DURABLE)
|
|
243
|
+
return inboxReaderConfig(space);
|
|
244
|
+
if (stream === dmStream(space)) {
|
|
245
|
+
const principal = principalFromDurable(name, "dm_");
|
|
246
|
+
if (principal)
|
|
247
|
+
return dmDurableConfig(space, principal.owner, principal.actor, principal.lifecycleUid);
|
|
248
|
+
}
|
|
249
|
+
if (stream === dlvStream(space)) {
|
|
250
|
+
const principal = principalFromDurable(name, "dlv_");
|
|
251
|
+
if (principal)
|
|
252
|
+
return dlvDurableConfig(space, principal.owner, principal.actor, principal.lifecycleUid);
|
|
253
|
+
}
|
|
254
|
+
if (stream === taskStream(space) && /^svc_[A-Za-z0-9_-]+$/.test(name))
|
|
255
|
+
return { ...taskDurableConfig(space, name.slice("svc_".length)), deliver_policy: DeliverPolicy.All };
|
|
256
|
+
throw new Error(`unsupported persistent consumer ${stream}/${name}`);
|
|
257
|
+
}
|
|
258
|
+
const CONSUMER_KEYS = new Set([
|
|
259
|
+
"ack_policy", "ack_wait", "backoff", "deliver_group", "deliver_policy", "deliver_subject",
|
|
260
|
+
"description", "durable_name", "filter_subject", "filter_subjects", "flow_control", "headers_only",
|
|
261
|
+
"idle_heartbeat", "inactive_threshold", "max_ack_pending", "max_batch", "max_bytes", "max_deliver",
|
|
262
|
+
"max_expires", "max_waiting", "mem_storage", "metadata", "name", "num_replicas", "opt_start_seq",
|
|
263
|
+
"opt_start_time", "pause_until", "priority_groups", "priority_policy", "priority_timeout",
|
|
264
|
+
"rate_limit_bps", "replay_policy", "sample_freq",
|
|
265
|
+
]);
|
|
266
|
+
/** Validate one recognized Cotal pull durable. Limits-retention consumers accept the checkpoint
|
|
267
|
+
* migration shape; TASK remains canonical WorkQueue DeliverAll. */
|
|
268
|
+
export function validatePersistentConsumer(space, stream, info) {
|
|
269
|
+
const expected = expectedConsumerConfig(space, stream, info.name);
|
|
270
|
+
const config = info.config;
|
|
271
|
+
const unknown = Object.keys(config).filter((key) => !CONSUMER_KEYS.has(key));
|
|
272
|
+
if (unknown.length)
|
|
273
|
+
throw new Error(`${stream}/${info.name} has unsupported consumer fields: ${unknown.sort().join(", ")}`);
|
|
274
|
+
if (config.name !== undefined && config.name !== info.name)
|
|
275
|
+
throw new Error(`${stream}/${info.name} has a mismatched name`);
|
|
276
|
+
if (config.durable_name !== info.name)
|
|
277
|
+
throw new Error(`${stream}/${info.name} is not a canonical durable`);
|
|
278
|
+
if (config.deliver_subject || config.deliver_group)
|
|
279
|
+
throw new Error(`${stream}/${info.name} is a push consumer`);
|
|
280
|
+
if (config.filter_subject !== expected.filter_subject || (config.filter_subjects?.length ?? 0) !== 0)
|
|
281
|
+
throw new Error(`${stream}/${info.name} has a noncanonical filter`);
|
|
282
|
+
if (config.ack_policy !== AckPolicy.Explicit || config.ack_wait !== expected.ack_wait)
|
|
283
|
+
throw new Error(`${stream}/${info.name} has noncanonical ACK settings`);
|
|
284
|
+
const task = stream === taskStream(space);
|
|
285
|
+
const migrated = !task && config.deliver_policy === DeliverPolicy.StartSequence;
|
|
286
|
+
const implicitTaskAll = task && config.deliver_policy === undefined;
|
|
287
|
+
if (config.deliver_policy !== expected.deliver_policy && !migrated && !implicitTaskAll)
|
|
288
|
+
throw new Error(`${stream}/${info.name} has a noncanonical delivery policy`);
|
|
289
|
+
if (migrated) {
|
|
290
|
+
if (!Number.isSafeInteger(config.opt_start_seq) || (config.opt_start_seq ?? 0) < 1)
|
|
291
|
+
throw new Error(`${stream}/${info.name} has an invalid creation lower bound`);
|
|
292
|
+
}
|
|
293
|
+
else if (config.opt_start_seq !== undefined || config.opt_start_time !== undefined) {
|
|
294
|
+
throw new Error(`${stream}/${info.name} has an unexpected start bound`);
|
|
295
|
+
}
|
|
296
|
+
const expectedMaxAck = expected.max_ack_pending ?? 1000;
|
|
297
|
+
if ((config.max_ack_pending ?? 1000) !== expectedMaxAck)
|
|
298
|
+
throw new Error(`${stream}/${info.name} has noncanonical max_ack_pending`);
|
|
299
|
+
if ((config.max_deliver ?? -1) !== -1 || (config.max_waiting ?? 512) !== 512)
|
|
300
|
+
throw new Error(`${stream}/${info.name} has noncanonical delivery limits`);
|
|
301
|
+
if ((config.replay_policy ?? ReplayPolicy.Instant) !== ReplayPolicy.Instant || (config.num_replicas ?? 0) !== 0)
|
|
302
|
+
throw new Error(`${stream}/${info.name} has noncanonical replay/replica settings`);
|
|
303
|
+
for (const key of [
|
|
304
|
+
"backoff", "description", "flow_control", "headers_only", "idle_heartbeat", "inactive_threshold",
|
|
305
|
+
"max_batch", "max_bytes", "max_expires", "mem_storage", "metadata", "pause_until", "priority_groups",
|
|
306
|
+
"priority_policy", "priority_timeout", "rate_limit_bps", "sample_freq",
|
|
307
|
+
]) {
|
|
308
|
+
const value = config[key];
|
|
309
|
+
if (key === "metadata" && value && typeof value === "object" && !Array.isArray(value) &&
|
|
310
|
+
Object.entries(value)
|
|
311
|
+
.every(([metadataKey, metadataValue]) => metadataKey.startsWith("_nats.") && typeof metadataValue === "string"))
|
|
312
|
+
continue;
|
|
313
|
+
if (value !== undefined && value !== false && value !== 0 && value !== "" &&
|
|
314
|
+
!(Array.isArray(value) && value.length === 0) &&
|
|
315
|
+
!(typeof value === "object" && value !== null && Object.keys(value).length === 0))
|
|
316
|
+
throw new Error(`${stream}/${info.name} has active unsupported setting ${key}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
/** Validate the complete consumer inventory for all eight streams and extract conservative checkpoints. */
|
|
320
|
+
export function validatePersistentConsumerInventory(space, consumersByStream, statesByStream) {
|
|
321
|
+
const expectedStreams = spaceBackupInventory(space).full;
|
|
322
|
+
const supplied = Object.keys(consumersByStream).sort();
|
|
323
|
+
if (JSON.stringify(supplied) !== JSON.stringify([...expectedStreams].sort()))
|
|
324
|
+
throw new Error("consumer inventory must contain exactly the eight backed-up streams");
|
|
325
|
+
const suppliedStates = Object.keys(statesByStream).sort();
|
|
326
|
+
if (JSON.stringify(suppliedStates) !== JSON.stringify([...expectedStreams].sort()))
|
|
327
|
+
throw new Error("stream state inventory must contain exactly the eight backed-up streams");
|
|
328
|
+
const checkpoints = [];
|
|
329
|
+
for (const stream of expectedStreams) {
|
|
330
|
+
const state = validateBackupStreamState(statesByStream[stream]);
|
|
331
|
+
const seen = new Set();
|
|
332
|
+
for (const info of consumersByStream[stream] ?? []) {
|
|
333
|
+
if (seen.has(info.name))
|
|
334
|
+
throw new Error(`duplicate consumer ${stream}/${info.name}`);
|
|
335
|
+
seen.add(info.name);
|
|
336
|
+
validatePersistentConsumer(space, stream, info);
|
|
337
|
+
const ackFloor = info.ack_floor.stream_seq;
|
|
338
|
+
if (!Number.isSafeInteger(ackFloor) || ackFloor < 0)
|
|
339
|
+
throw new Error(`${stream}/${info.name} has an invalid contiguous ACK floor`);
|
|
340
|
+
const creationLowerBound = info.config.deliver_policy === DeliverPolicy.StartSequence
|
|
341
|
+
? info.config.opt_start_seq
|
|
342
|
+
: info.config.deliver_policy === DeliverPolicy.New
|
|
343
|
+
? Math.max(1, ackFloor + 1)
|
|
344
|
+
: 1;
|
|
345
|
+
const checkpoint = {
|
|
346
|
+
stream,
|
|
347
|
+
name: info.name,
|
|
348
|
+
ackFloorStreamSequence: ackFloor,
|
|
349
|
+
creationLowerBound,
|
|
350
|
+
streamState: {
|
|
351
|
+
messages: state.messages,
|
|
352
|
+
first_seq: state.first_seq,
|
|
353
|
+
last_seq: state.last_seq,
|
|
354
|
+
},
|
|
355
|
+
};
|
|
356
|
+
consumerConfigFromCheckpoint(space, checkpoint);
|
|
357
|
+
checkpoints.push(checkpoint);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return checkpoints;
|
|
361
|
+
}
|
|
362
|
+
/** Recreate a validated pull durable. Limits-retention consumers start after the contiguous ACK
|
|
363
|
+
* floor and original lower bound; TASK uses WorkQueue DeliverAll because ACKed entries left the stream. */
|
|
364
|
+
export function consumerConfigFromCheckpoint(space, checkpoint) {
|
|
365
|
+
if (!Number.isSafeInteger(checkpoint.ackFloorStreamSequence) || checkpoint.ackFloorStreamSequence < 0 ||
|
|
366
|
+
!Number.isSafeInteger(checkpoint.creationLowerBound) || checkpoint.creationLowerBound < 1)
|
|
367
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} has an invalid checkpoint`);
|
|
368
|
+
const state = checkpoint.streamState;
|
|
369
|
+
if (!state || typeof state !== "object" || Array.isArray(state) ||
|
|
370
|
+
JSON.stringify(Object.keys(state).sort()) !== JSON.stringify(["first_seq", "last_seq", "messages"]))
|
|
371
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} has an invalid checkpoint stream state`);
|
|
372
|
+
const { messages, first_seq: firstSequence, last_seq: lastSequence } = state;
|
|
373
|
+
validateBackupStreamState({
|
|
374
|
+
messages,
|
|
375
|
+
bytes: 0,
|
|
376
|
+
first_seq: firstSequence,
|
|
377
|
+
last_seq: lastSequence,
|
|
378
|
+
consumer_count: 0,
|
|
379
|
+
});
|
|
380
|
+
if (checkpoint.ackFloorStreamSequence > lastSequence)
|
|
381
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} ACK floor exceeds snapshot last sequence`);
|
|
382
|
+
if (checkpoint.ackFloorStreamSequence === Number.MAX_SAFE_INTEGER)
|
|
383
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} ACK floor has no safe successor`);
|
|
384
|
+
const lastSuccessor = lastSequence === Number.MAX_SAFE_INTEGER
|
|
385
|
+
? Number.MAX_SAFE_INTEGER
|
|
386
|
+
: lastSequence + 1;
|
|
387
|
+
if (checkpoint.creationLowerBound > lastSuccessor)
|
|
388
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} creation lower bound exceeds snapshot sequence window`);
|
|
389
|
+
const expected = expectedConsumerConfig(space, checkpoint.stream, checkpoint.name);
|
|
390
|
+
if (checkpoint.stream === taskStream(space)) {
|
|
391
|
+
if (checkpoint.creationLowerBound !== 1)
|
|
392
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} has a noncanonical TASK creation lower bound`);
|
|
393
|
+
return expected;
|
|
394
|
+
}
|
|
395
|
+
const startSequence = Math.max(checkpoint.ackFloorStreamSequence + 1, checkpoint.creationLowerBound, firstSequence || 1);
|
|
396
|
+
if (!Number.isSafeInteger(startSequence) || startSequence > lastSuccessor)
|
|
397
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} start sequence exceeds snapshot sequence window`);
|
|
398
|
+
return {
|
|
399
|
+
...expected,
|
|
400
|
+
deliver_policy: DeliverPolicy.StartSequence,
|
|
401
|
+
opt_start_seq: startSequence,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
function checkpointCreateSubject(space, checkpoint) {
|
|
405
|
+
const config = consumerConfigFromCheckpoint(space, checkpoint);
|
|
406
|
+
if (!config.filter_subject)
|
|
407
|
+
throw new Error(`${checkpoint.stream}/${checkpoint.name} has no canonical single filter`);
|
|
408
|
+
return {
|
|
409
|
+
subject: `$JS.API.CONSUMER.CREATE.${checkpoint.stream}.${checkpoint.name}.${config.filter_subject}`,
|
|
410
|
+
config: { ...config, name: checkpoint.name },
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
/** Recreate one validated checkpoint through the NATS 2.10 extended create API, whose subject pins
|
|
414
|
+
* stream, durable name, and its canonical single filter. */
|
|
415
|
+
export async function recreateConsumerCheckpoint(nc, space, checkpoint, timeoutMs = DEFAULT_TRANSFER_TIMEOUT_MS) {
|
|
416
|
+
const { subject, config } = checkpointCreateSubject(space, checkpoint);
|
|
417
|
+
const responseMsg = await nc.request(subject, JSON.stringify({ stream_name: checkpoint.stream, config }), { timeout: timeoutMs });
|
|
418
|
+
const response = decodeJson(responseMsg.data, `checkpoint ${checkpoint.stream}/${checkpoint.name}`);
|
|
419
|
+
throwApiError(response, `checkpoint ${checkpoint.stream}/${checkpoint.name}`);
|
|
420
|
+
if (!response.name || !response.stream_name || !response.config || !response.ack_floor)
|
|
421
|
+
throw new JetStreamBackupError(`checkpoint ${checkpoint.stream}/${checkpoint.name}: incomplete consumer response`);
|
|
422
|
+
const info = response;
|
|
423
|
+
if (info.name !== checkpoint.name || info.stream_name !== checkpoint.stream)
|
|
424
|
+
throw new JetStreamBackupError(`checkpoint ${checkpoint.stream}/${checkpoint.name}: response identity mismatch`);
|
|
425
|
+
validatePersistentConsumer(space, checkpoint.stream, info);
|
|
426
|
+
if (info.config.deliver_policy !== config.deliver_policy || info.config.opt_start_seq !== config.opt_start_seq)
|
|
427
|
+
throw new JetStreamBackupError(`checkpoint ${checkpoint.stream}/${checkpoint.name}: response start policy mismatch`);
|
|
428
|
+
return info;
|
|
429
|
+
}
|
|
430
|
+
/** Exact snapshot permission set. It has no stream read/admin verbs beyond one snapshot API; chunk
|
|
431
|
+
* ACK authority is created dynamically for the exact reply received, never granted as a wildcard. */
|
|
432
|
+
export function backupProfilePermissions(space, connId, scope) {
|
|
433
|
+
assertInboxConnId(connId);
|
|
434
|
+
const inbox = `_INBOX_${connId}.>`;
|
|
435
|
+
if (scope.operation === "inspect") {
|
|
436
|
+
if (scope.selection !== "full" && scope.selection !== "registry")
|
|
437
|
+
throw new Error(`unsupported backup selection ${JSON.stringify(scope.selection)}`);
|
|
438
|
+
const streams = spaceBackupInventory(space)[scope.selection];
|
|
439
|
+
return {
|
|
440
|
+
pub: {
|
|
441
|
+
allow: [
|
|
442
|
+
"$JS.API.STREAM.NAMES",
|
|
443
|
+
...streams.flatMap((stream) => [
|
|
444
|
+
`$JS.API.STREAM.INFO.${stream}`,
|
|
445
|
+
`$JS.API.CONSUMER.LIST.${stream}`,
|
|
446
|
+
]),
|
|
447
|
+
],
|
|
448
|
+
},
|
|
449
|
+
sub: { allow: [inbox] },
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
if (scope.operation !== "snapshot")
|
|
453
|
+
throw new Error(`unsupported backup operation ${scope.operation}`);
|
|
454
|
+
assertBackupStream(space, scope.stream);
|
|
455
|
+
assertExactSubject(scope.deliverSubject, "backup deliverSubject");
|
|
456
|
+
if (!scope.deliverSubject.startsWith(`_INBOX_${connId}.`))
|
|
457
|
+
throw new Error("backup deliverSubject must be inside the credential's private inbox");
|
|
458
|
+
return {
|
|
459
|
+
pub: { allow: [`$JS.API.STREAM.SNAPSHOT.${scope.stream}`] },
|
|
460
|
+
sub: { allow: [inbox, scope.deliverSubject] },
|
|
461
|
+
// Each received chunk creates a one-use, short-lived permission for its exact server-generated
|
|
462
|
+
// reply subject. A guessed or wrong snapshot ACK id remains denied.
|
|
463
|
+
resp: { max: 1, ttl: nanos(60_000) },
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
/** Restore initiation, exact-ID upload, stream validation, and one-checkpoint recreation are disjoint
|
|
467
|
+
* credentials. No phase inherits a body-read verb or another phase's mutation authority. */
|
|
468
|
+
export function restoreProfilePermissions(space, connId, scope) {
|
|
469
|
+
assertInboxConnId(connId);
|
|
470
|
+
const inbox = `_INBOX_${connId}.>`;
|
|
471
|
+
if (scope.operation === "checkpoint") {
|
|
472
|
+
const { subject } = checkpointCreateSubject(space, scope.checkpoint);
|
|
473
|
+
return {
|
|
474
|
+
pub: {
|
|
475
|
+
allow: [
|
|
476
|
+
subject,
|
|
477
|
+
`$JS.API.CONSUMER.INFO.${scope.checkpoint.stream}.${scope.checkpoint.name}`,
|
|
478
|
+
],
|
|
479
|
+
},
|
|
480
|
+
sub: { allow: [inbox] },
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
if (scope.operation !== "initiate" && scope.operation !== "upload" && scope.operation !== "validate")
|
|
484
|
+
throw new Error(`unsupported restore operation ${scope.operation}`);
|
|
485
|
+
assertBackupStream(space, scope.stream);
|
|
486
|
+
if (scope.operation === "initiate") {
|
|
487
|
+
return { pub: { allow: [`$JS.API.STREAM.RESTORE.${scope.stream}`] }, sub: { allow: [inbox] } };
|
|
488
|
+
}
|
|
489
|
+
if (scope.operation === "validate") {
|
|
490
|
+
return { pub: { allow: [`$JS.API.STREAM.INFO.${scope.stream}`] }, sub: { allow: [inbox] } };
|
|
491
|
+
}
|
|
492
|
+
assertExactSubject(scope.deliverSubject, "restore deliverSubject");
|
|
493
|
+
if (!scope.deliverSubject.startsWith(`$JS.SNAPSHOT.RESTORE.${scope.stream}.`))
|
|
494
|
+
throw new Error("restore deliverSubject does not belong to the scoped stream");
|
|
495
|
+
return { pub: { allow: [scope.deliverSubject] }, sub: { allow: [inbox] } };
|
|
496
|
+
}
|
|
497
|
+
//# sourceMappingURL=backup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backup.js","sourceRoot":"","sources":["../src/backup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The control-surface broker floor (SPEC §13.12, D10).
|
|
3
|
+
*
|
|
4
|
+
* The endpoint surface REQUIRES NATS server >= 2.12: message schedules back durable timers,
|
|
5
|
+
* and per-subject create-CAS backs canonical acceptance. There is no sweeper fallback and no
|
|
6
|
+
* degraded mode; below the floor (or when a required capability is absent, e.g. the
|
|
7
|
+
* offline-assets downgrade) startup fails loud. Only 2.12 schedule semantics may be assumed
|
|
8
|
+
* (same-subject replacement) — never the 2.14 stop-plus-publish path.
|
|
9
|
+
*/
|
|
10
|
+
/** The minimum broker for the endpoint control surface. Runtime-frozen (the afa715b class): a
|
|
11
|
+
* post-import `minor = 0` would silently bypass the mandatory 2.12 startup gate. */
|
|
12
|
+
export declare const BROKER_FLOOR: Readonly<{
|
|
13
|
+
readonly major: 2;
|
|
14
|
+
readonly minor: 12;
|
|
15
|
+
}>;
|
|
16
|
+
/** Structural slice of a NATS connection: the pre-auth INFO carries the server version. */
|
|
17
|
+
export interface BrokerInfoSource {
|
|
18
|
+
info?: {
|
|
19
|
+
version?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Parse a nats-server version string ("2.12.3", "2.12.0-beta.1") into comparable parts. */
|
|
23
|
+
export declare function parseServerVersion(v: string): {
|
|
24
|
+
major: number;
|
|
25
|
+
minor: number;
|
|
26
|
+
patch: number;
|
|
27
|
+
} | null;
|
|
28
|
+
/** True iff the version meets the control-surface floor. */
|
|
29
|
+
export declare function meetsBrokerFloor(version: string): boolean;
|
|
30
|
+
/** Startup gate: throw (loud, fail-closed) unless the connected broker meets the floor.
|
|
31
|
+
* Call before creating or serving any control-surface resource. A missing/unparseable
|
|
32
|
+
* version is a refusal, not a pass — no fallbacks. */
|
|
33
|
+
export declare function requireBrokerFloor(nc: BrokerInfoSource): void;
|
|
34
|
+
//# sourceMappingURL=broker-floor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-floor.d.ts","sourceRoot":"","sources":["../src/broker-floor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;qFACqF;AACrF,eAAO,MAAM,YAAY;;;EAAkD,CAAC;AAE5E,2FAA2F;AAC3F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIpG;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAKzD;AAED;;uDAEuD;AACvD,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI,CAM7D"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The control-surface broker floor (SPEC §13.12, D10).
|
|
3
|
+
*
|
|
4
|
+
* The endpoint surface REQUIRES NATS server >= 2.12: message schedules back durable timers,
|
|
5
|
+
* and per-subject create-CAS backs canonical acceptance. There is no sweeper fallback and no
|
|
6
|
+
* degraded mode; below the floor (or when a required capability is absent, e.g. the
|
|
7
|
+
* offline-assets downgrade) startup fails loud. Only 2.12 schedule semantics may be assumed
|
|
8
|
+
* (same-subject replacement) — never the 2.14 stop-plus-publish path.
|
|
9
|
+
*/
|
|
10
|
+
/** The minimum broker for the endpoint control surface. Runtime-frozen (the afa715b class): a
|
|
11
|
+
* post-import `minor = 0` would silently bypass the mandatory 2.12 startup gate. */
|
|
12
|
+
export const BROKER_FLOOR = Object.freeze({ major: 2, minor: 12 });
|
|
13
|
+
/** Parse a nats-server version string ("2.12.3", "2.12.0-beta.1") into comparable parts. */
|
|
14
|
+
export function parseServerVersion(v) {
|
|
15
|
+
const m = /^(\d+)\.(\d+)\.(\d+)/.exec(v.trim());
|
|
16
|
+
if (!m)
|
|
17
|
+
return null;
|
|
18
|
+
return { major: Number(m[1]), minor: Number(m[2]), patch: Number(m[3]) };
|
|
19
|
+
}
|
|
20
|
+
/** True iff the version meets the control-surface floor. */
|
|
21
|
+
export function meetsBrokerFloor(version) {
|
|
22
|
+
const p = parseServerVersion(version);
|
|
23
|
+
if (!p)
|
|
24
|
+
return false;
|
|
25
|
+
if (p.major !== BROKER_FLOOR.major)
|
|
26
|
+
return p.major > BROKER_FLOOR.major;
|
|
27
|
+
return p.minor >= BROKER_FLOOR.minor;
|
|
28
|
+
}
|
|
29
|
+
/** Startup gate: throw (loud, fail-closed) unless the connected broker meets the floor.
|
|
30
|
+
* Call before creating or serving any control-surface resource. A missing/unparseable
|
|
31
|
+
* version is a refusal, not a pass — no fallbacks. */
|
|
32
|
+
export function requireBrokerFloor(nc) {
|
|
33
|
+
const version = nc.info?.version;
|
|
34
|
+
if (!version)
|
|
35
|
+
throw new Error("control surface: connected broker reports no server version; refusing to start (floor is nats-server >= 2.12)");
|
|
36
|
+
if (!meetsBrokerFloor(version))
|
|
37
|
+
throw new Error(`control surface: nats-server ${version} is below the required floor 2.12; upgrade the broker (no degraded mode exists)`);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=broker-floor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-floor.js","sourceRoot":"","sources":["../src/broker-floor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;qFACqF;AACrF,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAW,CAAC,CAAC;AAO5E,4FAA4F;AAC5F,MAAM,UAAU,kBAAkB,CAAC,CAAS;IAC1C,MAAM,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAChD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,CAAC,CAAC,KAAK,KAAK,YAAY,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC;IACxE,OAAO,CAAC,CAAC,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC;AACvC,CAAC;AAED;;uDAEuD;AACvD,MAAM,UAAU,kBAAkB,CAAC,EAAoB;IACrD,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC;IACjC,IAAI,CAAC,OAAO;QACV,MAAM,IAAI,KAAK,CAAC,+GAA+G,CAAC,CAAC;IACnI,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,iFAAiF,CAAC,CAAC;AAC9I,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Digest identity form used everywhere a contract artifact is referenced: `sha256:<hex>`. */
|
|
2
|
+
export declare const DIGEST_PREFIX: "sha256:";
|
|
3
|
+
/** True iff `s` is a well-formed `sha256:<hex>` artifact digest. */
|
|
4
|
+
export declare function isContractDigest(s: string): boolean;
|
|
5
|
+
/** True iff the string is well-formed UTF-16 (no unpaired surrogate). A lone surrogate has NO
|
|
6
|
+
* UTF-8 byte encoding — encoders silently substitute U+FFFD, so two distinct malformed strings
|
|
7
|
+
* can collapse to one byte sequence; anything digest- or wire-bound must refuse them. */
|
|
8
|
+
export declare function isWellFormedUnicode(s: string): boolean;
|
|
9
|
+
/** RFC 8785 canonical JSON text of a value (strict: I-JSON enforced, no undefined→null). */
|
|
10
|
+
export declare function canonicalJson(value: unknown): string;
|
|
11
|
+
/** Content address of a contract artifact: `sha256:<hex>` over its RFC 8785 form (SPEC §13.7). */
|
|
12
|
+
export declare function contractDigest(value: unknown): string;
|
|
13
|
+
/** `sha256:<hex>` over RAW bytes (a string digests as its UTF-8 encoding), NEVER re-canonicalized:
|
|
14
|
+
* the digest form for artifacts carried as opaque bytes — the §13.3 `auth` slot (`authDigest`,
|
|
15
|
+
* digested exactly as carried) and the §13.4 raw stored submission bytes (`submissionDigest`).
|
|
16
|
+
* A string input MUST be well-formed UTF-16: a lone surrogate has no UTF-8 encoding, the
|
|
17
|
+
* encoder would substitute U+FFFD, and two DISTINCT carried values would silently share one
|
|
18
|
+
* digest — the opposite of "exactly as carried". Throws instead. */
|
|
19
|
+
export declare function rawDigest(data: Uint8Array | string): string;
|
|
20
|
+
/** Verify fetched artifact BYTES against their advertised digest (verify-on-read, SPEC §13.7):
|
|
21
|
+
* content addressing, not store ACLs, is the tamper boundary. The bytes must parse as JSON and
|
|
22
|
+
* re-canonicalize to the digest; anything else throws. Returns the parsed artifact. */
|
|
23
|
+
export declare function verifyArtifact(bytes: Uint8Array, digest: string): unknown;
|
|
24
|
+
//# sourceMappingURL=canonical.d.ts.map
|