@antasphere/chassis-contract 1.0.0 → 1.0.1
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/entitlements.d.ts +9 -230
- package/dist/entitlements.d.ts.map +1 -1
- package/dist/entitlements.js +20 -209
- package/dist/entitlements.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/entitlements.ts +46 -233
- package/src/index.ts +0 -1
- package/dist/wire.d.ts +0 -101
- package/dist/wire.d.ts.map +0 -1
- package/dist/wire.js +0 -161
- package/dist/wire.js.map +0 -1
- package/src/wire.ts +0 -246
- package/test/hub-wire.test.ts +0 -114
package/src/entitlements.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { BILLING_PLANS, billingPlanSchema, type BillingPlan } from '@antasphere/contract';
|
|
2
3
|
import type { HeaderReader, Principal } from './seams.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -15,241 +16,53 @@ import type { HeaderReader, Principal } from './seams.js';
|
|
|
15
16
|
* read the same declarations without pulling the server.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
// ── The hub's half: the messages the tool exchanges with the hub ──────────
|
|
20
|
+
//
|
|
21
|
+
// The hub owns these shapes and publishes them as `@antasphere/contract`
|
|
22
|
+
// (the hub's own contract package, on npm at the hub's version); this file
|
|
23
|
+
// re-exports them under the names the chassis has always used, so a tool
|
|
24
|
+
// reads exactly what the hub wrote and a change at the hub reaches every
|
|
25
|
+
// tool through one dependency bump (PRDCT-3325; before it, a hand copy checked
|
|
26
|
+
// against the hub's wire snapshot). The chassis's OWN half — the
|
|
27
|
+
// declaration layer below — stays here.
|
|
28
|
+
export {
|
|
29
|
+
BILLING_PLANS,
|
|
30
|
+
USAGE_CHECK_REASONS,
|
|
31
|
+
USAGE_EVENT_MAX_FUTURE_MS,
|
|
32
|
+
USAGE_EVENT_MAX_PAST_MS,
|
|
33
|
+
USAGE_EVENTS_BATCH_MAX,
|
|
34
|
+
USAGE_REJECT_REASONS,
|
|
35
|
+
USAGE_ROUTE_ERRORS,
|
|
36
|
+
USAGE_WRITE_SCOPE,
|
|
37
|
+
usageCheckRequestSchema,
|
|
38
|
+
usageCheckSchema,
|
|
39
|
+
usageEventOccurrenceIssue,
|
|
40
|
+
usageEventResultSchema,
|
|
41
|
+
usageEventSchema,
|
|
42
|
+
usageEventsBatchSchema,
|
|
43
|
+
usageIngestResultSchema,
|
|
44
|
+
usageRejectReasonSchema
|
|
45
|
+
} from '@antasphere/contract';
|
|
46
|
+
export type {
|
|
47
|
+
UsageCheck,
|
|
48
|
+
UsageCheckReason,
|
|
49
|
+
UsageCheckRequest,
|
|
50
|
+
UsageEventResult,
|
|
51
|
+
UsageEventsBatch,
|
|
52
|
+
UsageIngestResult,
|
|
53
|
+
UsageRejectReason,
|
|
54
|
+
UsageRouteError
|
|
55
|
+
} from '@antasphere/contract';
|
|
29
56
|
|
|
30
57
|
/**
|
|
31
|
-
* The
|
|
32
|
-
*
|
|
58
|
+
* The plan tiers, a CLOSED enum the hub owns (`BILLING_PLANS` in
|
|
59
|
+
* `@antasphere/contract`), under the chassis's own names (§8b): `free` is the
|
|
60
|
+
* default with no subscription; `pro` is the paid plan. "Enterprise" is not
|
|
61
|
+
* a tier but a per-account override the hub serves.
|
|
33
62
|
*/
|
|
34
|
-
export const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* The error codes the three tool routes of the hub (`POST /usage/events`,
|
|
38
|
-
* `GET /usage/entitlements`, `POST /usage/check`) answer with, and the status
|
|
39
|
-
* each rides on: the hub's `USAGE_ROUTE_ERRORS` (PRDCT-2677).
|
|
40
|
-
* `tool_credential_required`: the caller is not a registry tool's machine
|
|
41
|
-
* credential. `unknown_account`: no organization holds the `accountRef` (the
|
|
42
|
-
* check and the entitlements read; the ingest answers it per event instead).
|
|
43
|
-
* `validation_error`: the body or the query does not parse. The chassis maps
|
|
44
|
-
* the check's two (`check.ts`): a 404 `unknown_account` and a 400 are the
|
|
45
|
-
* hub's judgement, allowed and logged, never an outage.
|
|
46
|
-
*/
|
|
47
|
-
export const USAGE_ROUTE_ERRORS = {
|
|
48
|
-
tool_credential_required: 401,
|
|
49
|
-
unknown_account: 404,
|
|
50
|
-
validation_error: 400
|
|
51
|
-
} as const;
|
|
52
|
-
export type UsageRouteError = keyof typeof USAGE_ROUTE_ERRORS;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The wire shape of one usage event as the hub ingests it: the hub's
|
|
56
|
-
* `usageEventSchema` (`packages/contract/src/schemas/billing.ts` of the hub,
|
|
57
|
-
* PRDCT-2625), copied here and checked against the hub's wire snapshot
|
|
58
|
-
* (`wire.ts`, `pnpm --filter @antasphere/chassis-contract wire:check`, the
|
|
59
|
-
* `hub-wire` CI job; PRDCT-2677), so the fake hub of the test kit refuses
|
|
60
|
-
* exactly what the real hub refuses (PRDCT-2629). `userId` is the HUB user
|
|
61
|
-
* (the SSO `sub`), never the tool's local id, and null when the actor is a
|
|
62
|
-
* resource owner the tool could not name; `accountRef` is the hub
|
|
63
|
-
* organization id (a uuid) the tool carries as its workspace's central
|
|
64
|
-
* account id. `toolSlug` is accepted by the hub only when it equals the
|
|
65
|
-
* calling token's registry slug — the chassis NEVER sends it: the token is
|
|
66
|
-
* the only authority on the tool's name, the body never names the tool
|
|
67
|
-
* (PRDCT-2629; `UsageEvent` in seams.ts has no such field).
|
|
68
|
-
*/
|
|
69
|
-
export const usageEventSchema = z
|
|
70
|
-
.object({
|
|
71
|
-
id: z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/, 'a ULID'),
|
|
72
|
-
actionKey: z.string().min(1).max(120).optional(),
|
|
73
|
-
meter: z.string().min(1).max(120).optional(),
|
|
74
|
-
quantity: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
75
|
-
unit: z.string().min(1).max(40),
|
|
76
|
-
occurredAt: z.iso.datetime({ offset: true }),
|
|
77
|
-
workspaceId: z.string().min(1).max(128),
|
|
78
|
-
accountRef: z.uuid(),
|
|
79
|
-
userId: z.string().min(1).max(128).nullable().optional(),
|
|
80
|
-
via: z.enum(['session', 'api_key', 'oauth']),
|
|
81
|
-
resourceType: z.string().min(1).max(80).nullable().optional(),
|
|
82
|
-
resourceId: z.string().min(1).max(256).nullable().optional(),
|
|
83
|
-
toolSlug: z.string().min(1).max(64).optional(),
|
|
84
|
-
source: z.object({
|
|
85
|
-
instanceId: z.string().min(1).max(128),
|
|
86
|
-
edition: z.string().min(1).max(32),
|
|
87
|
-
version: z.string().min(1).max(64)
|
|
88
|
-
})
|
|
89
|
-
})
|
|
90
|
-
.refine((e) => e.actionKey !== undefined || e.meter !== undefined, {
|
|
91
|
-
message: 'actionKey (or its legacy alias meter) is required',
|
|
92
|
-
path: ['actionKey']
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
/** The batch cap of `POST /usage/events` (the hub's `USAGE_EVENTS_BATCH_MAX`): at most this many events per post. */
|
|
96
|
-
export const USAGE_EVENTS_BATCH_MAX = 500;
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* The body of `POST /usage/events` as the hub parses it (its
|
|
100
|
-
* `usageEventsBatchSchema`): one to `USAGE_EVENTS_BATCH_MAX` elements, each
|
|
101
|
-
* judged on its own against `usageEventSchema` afterwards.
|
|
102
|
-
*/
|
|
103
|
-
export const usageEventsBatchSchema = z.object({
|
|
104
|
-
events: z.array(z.unknown()).min(1).max(USAGE_EVENTS_BATCH_MAX)
|
|
105
|
-
});
|
|
106
|
-
export type UsageEventsBatch = z.infer<typeof usageEventsBatchSchema>;
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Why the hub did not accept an event (its `USAGE_REJECT_REASONS`, a closed
|
|
110
|
-
* list): `unknown_account`, `unknown_user`, `tool_mismatch`, and
|
|
111
|
-
* `invalid_event` (the element does not parse, its `occurredAt` falls outside
|
|
112
|
-
* the window, or its price exceeds `Number.MAX_SAFE_INTEGER`; `details` names
|
|
113
|
-
* the field).
|
|
114
|
-
*/
|
|
115
|
-
export const USAGE_REJECT_REASONS = [
|
|
116
|
-
'unknown_account',
|
|
117
|
-
'unknown_user',
|
|
118
|
-
'tool_mismatch',
|
|
119
|
-
'invalid_event'
|
|
120
|
-
] as const;
|
|
121
|
-
export const usageRejectReasonSchema = z.enum(USAGE_REJECT_REASONS);
|
|
122
|
-
export type UsageRejectReason = z.infer<typeof usageRejectReasonSchema>;
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* One element's answer. Since phase 2 an `accepted` result carries the
|
|
126
|
-
* `credits` the hub debited for it (0 when the action has no price).
|
|
127
|
-
*/
|
|
128
|
-
export const usageEventResultSchema = z.object({
|
|
129
|
-
id: z.string().nullable(),
|
|
130
|
-
status: z.enum(['accepted', 'duplicate', 'rejected']),
|
|
131
|
-
reason: usageRejectReasonSchema.optional(),
|
|
132
|
-
details: z.unknown().optional(),
|
|
133
|
-
credits: z.number().int().optional()
|
|
134
|
-
});
|
|
135
|
-
export type UsageEventResult = z.infer<typeof usageEventResultSchema>;
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* The hub's answer to `POST /usage/events`: one result per element, in the
|
|
139
|
-
* batch's order, and the three counts (always sent).
|
|
140
|
-
*/
|
|
141
|
-
export const usageIngestResultSchema = z.object({
|
|
142
|
-
results: z.array(usageEventResultSchema),
|
|
143
|
-
accepted: z.number().int(),
|
|
144
|
-
duplicate: z.number().int(),
|
|
145
|
-
rejected: z.number().int()
|
|
146
|
-
});
|
|
147
|
-
export type UsageIngestResult = z.infer<typeof usageIngestResultSchema>;
|
|
148
|
-
|
|
149
|
-
// ── The hub's window on an event's date (PRDCT-2630 at the hub, PRDCT-2644 here) ──
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* The window an event's `occurredAt` must fall in, measured against the
|
|
153
|
-
* moment the hub receives it: the hub's `USAGE_EVENT_MAX_PAST_MS` and
|
|
154
|
-
* `USAGE_EVENT_MAX_FUTURE_MS` (`packages/contract/src/schemas/billing.ts`
|
|
155
|
-
* of the hub), same names and values, checked against the hub's wire
|
|
156
|
-
* snapshot (`wire.ts`, `wire:check`, the `hub-wire` CI job; PRDCT-2677). Backward, seven days:
|
|
157
|
-
* the queue's retry budget is about eight and a half hours, so an outage of
|
|
158
|
-
* a night is covered many times over, and a week also covers an operator
|
|
159
|
-
* re-driving held jobs by hand. Forward, five minutes: the skew every JWT
|
|
160
|
-
* verifier already tolerates; anything further is a clock that is wrong.
|
|
161
|
-
* Outside the window the hub answers `rejected(invalid_event)` naming
|
|
162
|
-
* `occurredAt` and never clamps, so the poster refuses BEFORE posting: an
|
|
163
|
-
* event the hub would refuse on its date is held where it was made, never
|
|
164
|
-
* counted as a rejection at the hub (PRDCT-2644).
|
|
165
|
-
*/
|
|
166
|
-
export const USAGE_EVENT_MAX_PAST_MS = 7 * 24 * 60 * 60 * 1000;
|
|
167
|
-
export const USAGE_EVENT_MAX_FUTURE_MS = 5 * 60 * 1000;
|
|
168
|
-
|
|
169
|
-
/**
|
|
170
|
-
* Why an event's `occurredAt` is refused against the receipt time, or null
|
|
171
|
-
* when it falls inside the window (both bounds INCLUSIVE). The hub's
|
|
172
|
-
* `usageEventOccurrenceIssue`, copied (the wire snapshot's occurrence table
|
|
173
|
-
* checks it on the hub's offsets): the one comparison both
|
|
174
|
-
* halves run, the hub at ingest against its own clock, the chassis before
|
|
175
|
-
* posting against its best estimate of the receipt (its own clock), so the
|
|
176
|
-
* two never disagree on the sign or the edge.
|
|
177
|
-
*/
|
|
178
|
-
export function usageEventOccurrenceIssue(
|
|
179
|
-
occurredAt: Date,
|
|
180
|
-
receivedAt: Date
|
|
181
|
-
): { path: 'occurredAt'; message: string } | null {
|
|
182
|
-
const delta = occurredAt.getTime() - receivedAt.getTime();
|
|
183
|
-
if (delta < -USAGE_EVENT_MAX_PAST_MS) {
|
|
184
|
-
return {
|
|
185
|
-
path: 'occurredAt',
|
|
186
|
-
message: `more than ${USAGE_EVENT_MAX_PAST_MS / 86_400_000} days before the hub received the event`
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
if (delta > USAGE_EVENT_MAX_FUTURE_MS) {
|
|
190
|
-
return {
|
|
191
|
-
path: 'occurredAt',
|
|
192
|
-
message: `more than ${USAGE_EVENT_MAX_FUTURE_MS / 60_000} minutes after the hub received the event`
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
return null;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// ── POST /usage/check: the price and the balance before an action (§5, §7 step 3) ──
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* The request of `POST /usage/check` (the hub's `UsageCheckRequest`,
|
|
202
|
-
* PRDCT-2663): the paying account, the action key and the quantity of THIS
|
|
203
|
-
* request. `unit` is accepted and ignored by the hub, which prices by its
|
|
204
|
-
* own row; it is sent so the answer's unit can be compared and a mismatch
|
|
205
|
-
* logged.
|
|
206
|
-
*/
|
|
207
|
-
export const usageCheckRequestSchema = z.object({
|
|
208
|
-
accountRef: z.uuid(),
|
|
209
|
-
actionKey: z.string().min(1).max(120),
|
|
210
|
-
quantity: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
211
|
-
unit: z.string().min(1).max(40).optional()
|
|
212
|
-
});
|
|
213
|
-
export type UsageCheckRequest = z.infer<typeof usageCheckRequestSchema>;
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* The three reasons a check refuses (`null` when allowed), the hub's
|
|
217
|
-
* `USAGE_CHECK_REASONS`: `account_suspended` (checked first, whatever the
|
|
218
|
-
* price), `unpriceable` (the price of this quantity exceeds
|
|
219
|
-
* `Number.MAX_SAFE_INTEGER`: the hub clamps `credits` to that bound, and the
|
|
220
|
-
* ingest would reject the same event on its `quantity`) and
|
|
221
|
-
* `insufficient_credits` (`balance < credits`). Each is a refusal, never an
|
|
222
|
-
* outage (PRDCT-2677).
|
|
223
|
-
*/
|
|
224
|
-
export const USAGE_CHECK_REASONS = ['insufficient_credits', 'account_suspended', 'unpriceable'] as const;
|
|
225
|
-
export type UsageCheckReason = (typeof USAGE_CHECK_REASONS)[number];
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* The hub's answer to `POST /usage/check` (its `UsageCheck`, PRDCT-2663),
|
|
229
|
-
* checked against the hub's wire snapshot (PRDCT-2677): advisory, no side effect. `credits` is the price of
|
|
230
|
-
* this quantity from the price book row effective now (0 and `priced:
|
|
231
|
-
* false` when the tool has no row for the action: views are never priced,
|
|
232
|
-
* an unknown key is not a refusal); `balance` the account's; `allowed` is
|
|
233
|
-
* `balance >= credits` unless the organization is suspended, which refuses
|
|
234
|
-
* whatever the price. `topUpUrl` is always present: the hub's billing page
|
|
235
|
-
* for that organization, what a `402 entitlement_denied` carries straight
|
|
236
|
-
* off the answer. No lower bound on `quantity` or `credits`, as at the hub: a
|
|
237
|
-
* copy stricter than the hub reads a valid answer as an outage.
|
|
238
|
-
*/
|
|
239
|
-
export const usageCheckSchema = z.object({
|
|
240
|
-
accountRef: z.uuid(),
|
|
241
|
-
actionKey: z.string(),
|
|
242
|
-
quantity: z.number().int(),
|
|
243
|
-
allowed: z.boolean(),
|
|
244
|
-
credits: z.number().int(),
|
|
245
|
-
balance: z.number().int(),
|
|
246
|
-
unit: z.string().nullable(),
|
|
247
|
-
priced: z.boolean(),
|
|
248
|
-
plan: entitlementTierSchema,
|
|
249
|
-
reason: z.enum(USAGE_CHECK_REASONS).nullable(),
|
|
250
|
-
topUpUrl: z.string()
|
|
251
|
-
});
|
|
252
|
-
export type UsageCheck = z.infer<typeof usageCheckSchema>;
|
|
63
|
+
export const ENTITLEMENT_TIERS = BILLING_PLANS;
|
|
64
|
+
export type EntitlementTier = BillingPlan;
|
|
65
|
+
export const entitlementTierSchema = billingPlanSchema;
|
|
253
66
|
|
|
254
67
|
/** The wire code of a credit refusal (§7 step 4), and its `details`. */
|
|
255
68
|
export const ENTITLEMENT_DENIED = 'entitlement_denied';
|
|
@@ -492,7 +305,7 @@ export type ToolEntitlements = z.infer<typeof toolEntitlementsSchema>;
|
|
|
492
305
|
|
|
493
306
|
/**
|
|
494
307
|
* The hub's answer to `GET /usage/entitlements?accountRef=` (§5): the hub's
|
|
495
|
-
* `usageEntitlementsSchema` (PRDCT-2636),
|
|
308
|
+
* `usageEntitlementsSchema` (PRDCT-2636), the hub's own shape in
|
|
496
309
|
* snapshot (PRDCT-2677). The account's
|
|
497
310
|
* plan, resolved from the tier's defaults and the account's overrides; in
|
|
498
311
|
* phase 1 `limits` and `features` are empty and the tool's own declared
|
package/src/index.ts
CHANGED
|
@@ -33,6 +33,5 @@ export * from './schemas/teams.js';
|
|
|
33
33
|
export * from './schemas/demo-passes.js';
|
|
34
34
|
export * from './seams.js';
|
|
35
35
|
export * from './entitlements.js';
|
|
36
|
-
export * from './wire.js';
|
|
37
36
|
export * from './define.js';
|
|
38
37
|
export type { ToolIdentity } from './identity.js';
|
package/dist/wire.d.ts
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
/**
|
|
3
|
-
* The chassis's side of the hub–tool wire check (PRDCT-2677). The hub owns
|
|
4
|
-
* the messages the tools exchange with it and publishes them as ONE
|
|
5
|
-
* generated snapshot, `packages/contract/wire/hub-tool-messages.json` of the
|
|
6
|
-
* hub, built by its `packages/contract/src/wire.ts`. The block below, from
|
|
7
|
-
* `WIRE_SCHEMA_KEYS` to `buildWireSnapshot`, is the chassis's copy of that
|
|
8
|
-
* builder, kept VERBATIM so both sides compute the same picture: the same
|
|
9
|
-
* JSON Schema export, the same probe verdicts, the same occurrence table.
|
|
10
|
-
* The hub's inputs (its offsets and probe payloads) and its definitions are
|
|
11
|
-
* NOT copied: the inputs are read back from the hub's file
|
|
12
|
-
* (`wireInputsOf`), the definitions are this package's own copies
|
|
13
|
-
* (`CHASSIS_WIRE_DEFINITIONS`, from `entitlements.ts`).
|
|
14
|
-
*
|
|
15
|
-
* `compareWireSnapshots` names every difference by its dotted path;
|
|
16
|
-
* `scripts/hub-wire-check.mjs` (`pnpm --filter @antasphere/chassis-contract
|
|
17
|
-
* wire:check`, the `hub-wire` CI job against the hub's `dev`) fails on any.
|
|
18
|
-
* The check runs one way: the hub changes first, the chassis follows.
|
|
19
|
-
*/
|
|
20
|
-
/** The keys of the six shapes, the same on both sides. */
|
|
21
|
-
export declare const WIRE_SCHEMA_KEYS: readonly ["usageEvent", "usageEventsBatch", "usageIngestResult", "usageEntitlements", "usageCheckRequest", "usageCheck"];
|
|
22
|
-
export type WireSchemaKey = (typeof WIRE_SCHEMA_KEYS)[number];
|
|
23
|
-
export interface WireConstants {
|
|
24
|
-
USAGE_WRITE_SCOPE: string;
|
|
25
|
-
BILLING_PLANS: readonly string[];
|
|
26
|
-
USAGE_EVENTS_BATCH_MAX: number;
|
|
27
|
-
USAGE_EVENT_MAX_PAST_MS: number;
|
|
28
|
-
USAGE_EVENT_MAX_FUTURE_MS: number;
|
|
29
|
-
USAGE_CHECK_REASONS: readonly string[];
|
|
30
|
-
USAGE_REJECT_REASONS: readonly string[];
|
|
31
|
-
USAGE_ROUTE_ERRORS: Readonly<Record<string, number>>;
|
|
32
|
-
}
|
|
33
|
-
export interface WireProbe {
|
|
34
|
-
name: string;
|
|
35
|
-
input: unknown;
|
|
36
|
-
}
|
|
37
|
-
export interface WireProbeResult extends WireProbe {
|
|
38
|
-
/** Whether the schema accepts the input. */
|
|
39
|
-
ok: boolean;
|
|
40
|
-
}
|
|
41
|
-
export interface WireOccurrence {
|
|
42
|
-
/** The event's `occurredAt` minus the receipt time, in milliseconds. */
|
|
43
|
-
offsetMs: number;
|
|
44
|
-
issue: {
|
|
45
|
-
path: 'occurredAt';
|
|
46
|
-
message: string;
|
|
47
|
-
} | null;
|
|
48
|
-
}
|
|
49
|
-
/** What one side feeds the builder: its own definitions. */
|
|
50
|
-
export interface WireDefinitions {
|
|
51
|
-
constants: WireConstants;
|
|
52
|
-
schemas: Record<WireSchemaKey, z.ZodType>;
|
|
53
|
-
occurrenceIssue: (occurredAt: Date, receivedAt: Date) => {
|
|
54
|
-
path: 'occurredAt';
|
|
55
|
-
message: string;
|
|
56
|
-
} | null;
|
|
57
|
-
}
|
|
58
|
-
/** The inputs the snapshot is computed on: the hub's, read back by the chassis from the hub's file. */
|
|
59
|
-
export interface WireInputs {
|
|
60
|
-
occurrenceOffsetsMs: readonly number[];
|
|
61
|
-
probes: Record<WireSchemaKey, readonly WireProbe[]>;
|
|
62
|
-
}
|
|
63
|
-
export interface HubToolWireSnapshot {
|
|
64
|
-
v: 1;
|
|
65
|
-
constants: WireConstants;
|
|
66
|
-
schemas: Record<WireSchemaKey, unknown>;
|
|
67
|
-
occurrence: WireOccurrence[];
|
|
68
|
-
probes: Record<WireSchemaKey, WireProbeResult[]>;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Build the snapshot from one side's definitions on the given inputs. The
|
|
72
|
-
* SAME function runs on both sides (the chassis carries a verbatim copy):
|
|
73
|
-
* the hub with its own inputs, the chassis with the inputs read from the
|
|
74
|
-
* hub's file. Deterministic: no clock, no randomness, no environment.
|
|
75
|
-
*/
|
|
76
|
-
export declare function buildWireSnapshot(defs: WireDefinitions, inputs: WireInputs): HubToolWireSnapshot;
|
|
77
|
-
/** The chassis's definitions: this package's copies of the hub's shapes, under the hub's keys. */
|
|
78
|
-
export declare const CHASSIS_WIRE_DEFINITIONS: WireDefinitions;
|
|
79
|
-
/** The inputs the hub computed its snapshot on, read back from its file: the offsets and the probe payloads. */
|
|
80
|
-
export declare function wireInputsOf(reference: HubToolWireSnapshot): WireInputs;
|
|
81
|
-
/** The snapshot the chassis's copies give on the hub's own inputs: what must equal the hub's file. */
|
|
82
|
-
export declare function chassisWireSnapshot(reference: HubToolWireSnapshot): HubToolWireSnapshot;
|
|
83
|
-
/** One place where the hub's snapshot and the chassis's differ: its dotted path and the two values. */
|
|
84
|
-
export interface WireDifference {
|
|
85
|
-
path: string;
|
|
86
|
-
hub: unknown;
|
|
87
|
-
chassis: unknown;
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Every difference between the hub's snapshot and the chassis's, by dotted
|
|
91
|
-
* path (`constants.USAGE_CHECK_REASONS[2]`,
|
|
92
|
-
* `schemas.usageCheck.properties.reason.anyOf[0].enum`,
|
|
93
|
-
* `probes.usageCheck[3].ok`). Objects compare by the union of their keys,
|
|
94
|
-
* order ignored, an absent key and `undefined` being the same; arrays by
|
|
95
|
-
* index, a length difference being one difference at the array's path.
|
|
96
|
-
* Deterministic: keys sorted, arrays in order. Empty when they agree.
|
|
97
|
-
*/
|
|
98
|
-
export declare function compareWireSnapshots(hub: HubToolWireSnapshot, chassis: HubToolWireSnapshot): WireDifference[];
|
|
99
|
-
/** One line of figures for a snapshot: `6 shapes, N constants, M probes, K occurrence offsets`. */
|
|
100
|
-
export declare function describeWireSnapshot(snapshot: HubToolWireSnapshot): string;
|
|
101
|
-
//# sourceMappingURL=wire.d.ts.map
|
package/dist/wire.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAmBxB;;;;;;;;;;;;;;;;;GAiBG;AAIH,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,0HAOnB,CAAC;AACX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,MAAM,WAAW,aAAa;IAC5B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,yBAAyB,EAAE,MAAM,CAAC;IAClC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,oBAAoB,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,eAAgB,SAAQ,SAAS;IAChD,4CAA4C;IAC5C,EAAE,EAAE,OAAO,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACvD;AAED,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;IAC1C,eAAe,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,KAAK;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACzG;AAED,uGAAuG;AACvG,MAAM,WAAW,UAAU;IACzB,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,SAAS,SAAS,EAAE,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,mBAAmB;IAClC,CAAC,EAAE,CAAC,CAAC;IACL,SAAS,EAAE,aAAa,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,eAAe,EAAE,CAAC,CAAC;CAClD;AAKD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,UAAU,GAAG,mBAAmB,CAiChG;AAID,kGAAkG;AAClG,eAAO,MAAM,wBAAwB,EAAE,eAoBtC,CAAC;AAEF,gHAAgH;AAChH,wBAAgB,YAAY,CAAC,SAAS,EAAE,mBAAmB,GAAG,UAAU,CASvE;AAED,sGAAsG;AACtG,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,mBAAmB,GAAG,mBAAmB,CAEvF;AAED,uGAAuG;AACvG,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AA+BD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,mBAAmB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,cAAc,EAAE,CAIlB;AAED,mGAAmG;AACnG,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAK1E"}
|
package/dist/wire.js
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { BILLING_PLANS, USAGE_CHECK_REASONS, USAGE_EVENT_MAX_FUTURE_MS, USAGE_EVENT_MAX_PAST_MS, USAGE_EVENTS_BATCH_MAX, USAGE_REJECT_REASONS, USAGE_ROUTE_ERRORS, USAGE_WRITE_SCOPE, entitlementProfileSchema, usageCheckRequestSchema, usageCheckSchema, usageEventOccurrenceIssue, usageEventSchema, usageEventsBatchSchema, usageIngestResultSchema } from './entitlements.js';
|
|
3
|
-
/**
|
|
4
|
-
* The chassis's side of the hub–tool wire check (PRDCT-2677). The hub owns
|
|
5
|
-
* the messages the tools exchange with it and publishes them as ONE
|
|
6
|
-
* generated snapshot, `packages/contract/wire/hub-tool-messages.json` of the
|
|
7
|
-
* hub, built by its `packages/contract/src/wire.ts`. The block below, from
|
|
8
|
-
* `WIRE_SCHEMA_KEYS` to `buildWireSnapshot`, is the chassis's copy of that
|
|
9
|
-
* builder, kept VERBATIM so both sides compute the same picture: the same
|
|
10
|
-
* JSON Schema export, the same probe verdicts, the same occurrence table.
|
|
11
|
-
* The hub's inputs (its offsets and probe payloads) and its definitions are
|
|
12
|
-
* NOT copied: the inputs are read back from the hub's file
|
|
13
|
-
* (`wireInputsOf`), the definitions are this package's own copies
|
|
14
|
-
* (`CHASSIS_WIRE_DEFINITIONS`, from `entitlements.ts`).
|
|
15
|
-
*
|
|
16
|
-
* `compareWireSnapshots` names every difference by its dotted path;
|
|
17
|
-
* `scripts/hub-wire-check.mjs` (`pnpm --filter @antasphere/chassis-contract
|
|
18
|
-
* wire:check`, the `hub-wire` CI job against the hub's `dev`) fails on any.
|
|
19
|
-
* The check runs one way: the hub changes first, the chassis follows.
|
|
20
|
-
*/
|
|
21
|
-
// ── Copied VERBATIM from the hub's packages/contract/src/wire.ts ──────────
|
|
22
|
-
/** The keys of the six shapes, the same on both sides. */
|
|
23
|
-
export const WIRE_SCHEMA_KEYS = [
|
|
24
|
-
'usageEvent',
|
|
25
|
-
'usageEventsBatch',
|
|
26
|
-
'usageIngestResult',
|
|
27
|
-
'usageEntitlements',
|
|
28
|
-
'usageCheckRequest',
|
|
29
|
-
'usageCheck'
|
|
30
|
-
];
|
|
31
|
-
/** A fixed receipt time, so the occurrence table is the same on every run. */
|
|
32
|
-
const RECEIVED_AT = new Date('2026-09-23T12:00:00.000Z');
|
|
33
|
-
/**
|
|
34
|
-
* Build the snapshot from one side's definitions on the given inputs. The
|
|
35
|
-
* SAME function runs on both sides (the chassis carries a verbatim copy):
|
|
36
|
-
* the hub with its own inputs, the chassis with the inputs read from the
|
|
37
|
-
* hub's file. Deterministic: no clock, no randomness, no environment.
|
|
38
|
-
*/
|
|
39
|
-
export function buildWireSnapshot(defs, inputs) {
|
|
40
|
-
const schemas = {};
|
|
41
|
-
const probes = {};
|
|
42
|
-
for (const key of WIRE_SCHEMA_KEYS) {
|
|
43
|
-
const schema = defs.schemas[key];
|
|
44
|
-
// A refinement has no JSON Schema form and is dropped on both sides
|
|
45
|
-
// alike; the probes below carry what it decides.
|
|
46
|
-
schemas[key] = z.toJSONSchema(schema, { unrepresentable: 'any' });
|
|
47
|
-
probes[key] = inputs.probes[key].map((probe) => ({
|
|
48
|
-
name: probe.name,
|
|
49
|
-
input: probe.input,
|
|
50
|
-
ok: schema.safeParse(probe.input).success
|
|
51
|
-
}));
|
|
52
|
-
}
|
|
53
|
-
return {
|
|
54
|
-
v: 1,
|
|
55
|
-
constants: {
|
|
56
|
-
USAGE_WRITE_SCOPE: defs.constants.USAGE_WRITE_SCOPE,
|
|
57
|
-
BILLING_PLANS: [...defs.constants.BILLING_PLANS],
|
|
58
|
-
USAGE_EVENTS_BATCH_MAX: defs.constants.USAGE_EVENTS_BATCH_MAX,
|
|
59
|
-
USAGE_EVENT_MAX_PAST_MS: defs.constants.USAGE_EVENT_MAX_PAST_MS,
|
|
60
|
-
USAGE_EVENT_MAX_FUTURE_MS: defs.constants.USAGE_EVENT_MAX_FUTURE_MS,
|
|
61
|
-
USAGE_CHECK_REASONS: [...defs.constants.USAGE_CHECK_REASONS],
|
|
62
|
-
USAGE_REJECT_REASONS: [...defs.constants.USAGE_REJECT_REASONS],
|
|
63
|
-
USAGE_ROUTE_ERRORS: { ...defs.constants.USAGE_ROUTE_ERRORS }
|
|
64
|
-
},
|
|
65
|
-
schemas,
|
|
66
|
-
occurrence: inputs.occurrenceOffsetsMs.map((offsetMs) => ({
|
|
67
|
-
offsetMs,
|
|
68
|
-
issue: defs.occurrenceIssue(new Date(RECEIVED_AT.getTime() + offsetMs), RECEIVED_AT)
|
|
69
|
-
})),
|
|
70
|
-
probes
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
// ── The chassis's own half ─────────────────────────────────────────────────
|
|
74
|
-
/** The chassis's definitions: this package's copies of the hub's shapes, under the hub's keys. */
|
|
75
|
-
export const CHASSIS_WIRE_DEFINITIONS = {
|
|
76
|
-
constants: {
|
|
77
|
-
USAGE_WRITE_SCOPE,
|
|
78
|
-
BILLING_PLANS,
|
|
79
|
-
USAGE_EVENTS_BATCH_MAX,
|
|
80
|
-
USAGE_EVENT_MAX_PAST_MS,
|
|
81
|
-
USAGE_EVENT_MAX_FUTURE_MS,
|
|
82
|
-
USAGE_CHECK_REASONS,
|
|
83
|
-
USAGE_REJECT_REASONS,
|
|
84
|
-
USAGE_ROUTE_ERRORS
|
|
85
|
-
},
|
|
86
|
-
schemas: {
|
|
87
|
-
usageEvent: usageEventSchema,
|
|
88
|
-
usageEventsBatch: usageEventsBatchSchema,
|
|
89
|
-
usageIngestResult: usageIngestResultSchema,
|
|
90
|
-
usageEntitlements: entitlementProfileSchema,
|
|
91
|
-
usageCheckRequest: usageCheckRequestSchema,
|
|
92
|
-
usageCheck: usageCheckSchema
|
|
93
|
-
},
|
|
94
|
-
occurrenceIssue: usageEventOccurrenceIssue
|
|
95
|
-
};
|
|
96
|
-
/** The inputs the hub computed its snapshot on, read back from its file: the offsets and the probe payloads. */
|
|
97
|
-
export function wireInputsOf(reference) {
|
|
98
|
-
const probes = {};
|
|
99
|
-
for (const key of WIRE_SCHEMA_KEYS) {
|
|
100
|
-
probes[key] = (reference.probes[key] ?? []).map((probe) => ({ name: probe.name, input: probe.input }));
|
|
101
|
-
}
|
|
102
|
-
return {
|
|
103
|
-
occurrenceOffsetsMs: reference.occurrence.map((row) => row.offsetMs),
|
|
104
|
-
probes
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
/** The snapshot the chassis's copies give on the hub's own inputs: what must equal the hub's file. */
|
|
108
|
-
export function chassisWireSnapshot(reference) {
|
|
109
|
-
return buildWireSnapshot(CHASSIS_WIRE_DEFINITIONS, wireInputsOf(reference));
|
|
110
|
-
}
|
|
111
|
-
function isPlainObject(value) {
|
|
112
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
113
|
-
}
|
|
114
|
-
function childPath(parent, key) {
|
|
115
|
-
return /^[A-Za-z_$][\w$]*$/.test(key)
|
|
116
|
-
? parent === ''
|
|
117
|
-
? key
|
|
118
|
-
: `${parent}.${key}`
|
|
119
|
-
: `${parent}[${JSON.stringify(key)}]`;
|
|
120
|
-
}
|
|
121
|
-
function compareAt(path, hub, chassis, out) {
|
|
122
|
-
if (Array.isArray(hub) && Array.isArray(chassis)) {
|
|
123
|
-
if (hub.length !== chassis.length) {
|
|
124
|
-
out.push({ path, hub, chassis });
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
for (let i = 0; i < hub.length; i += 1)
|
|
128
|
-
compareAt(`${path}[${i}]`, hub[i], chassis[i], out);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
if (isPlainObject(hub) && isPlainObject(chassis)) {
|
|
132
|
-
const keys = [...new Set([...Object.keys(hub), ...Object.keys(chassis)])].sort();
|
|
133
|
-
for (const key of keys)
|
|
134
|
-
compareAt(childPath(path, key), hub[key], chassis[key], out);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
if (!Object.is(hub, chassis))
|
|
138
|
-
out.push({ path, hub, chassis });
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* Every difference between the hub's snapshot and the chassis's, by dotted
|
|
142
|
-
* path (`constants.USAGE_CHECK_REASONS[2]`,
|
|
143
|
-
* `schemas.usageCheck.properties.reason.anyOf[0].enum`,
|
|
144
|
-
* `probes.usageCheck[3].ok`). Objects compare by the union of their keys,
|
|
145
|
-
* order ignored, an absent key and `undefined` being the same; arrays by
|
|
146
|
-
* index, a length difference being one difference at the array's path.
|
|
147
|
-
* Deterministic: keys sorted, arrays in order. Empty when they agree.
|
|
148
|
-
*/
|
|
149
|
-
export function compareWireSnapshots(hub, chassis) {
|
|
150
|
-
const out = [];
|
|
151
|
-
compareAt('', hub, chassis, out);
|
|
152
|
-
return out;
|
|
153
|
-
}
|
|
154
|
-
/** One line of figures for a snapshot: `6 shapes, N constants, M probes, K occurrence offsets`. */
|
|
155
|
-
export function describeWireSnapshot(snapshot) {
|
|
156
|
-
const shapes = Object.keys(snapshot.schemas).length;
|
|
157
|
-
const constants = Object.keys(snapshot.constants).length;
|
|
158
|
-
const probes = Object.values(snapshot.probes).reduce((n, list) => n + list.length, 0);
|
|
159
|
-
return `${shapes} shapes, ${constants} constants, ${probes} probes, ${snapshot.occurrence.length} occurrence offsets`;
|
|
160
|
-
}
|
|
161
|
-
//# sourceMappingURL=wire.js.map
|
package/dist/wire.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wire.js","sourceRoot":"","sources":["../src/wire.ts"],"names":[],"mappings":"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"}
|