@oxy.so/contracts 4.11.0-oxy-one.0 → 4.11.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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/accountGraph.js +5 -3
- package/dist/cjs/agency.js +178 -96
- package/dist/cjs/agentKeys.js +80 -26
- package/dist/cjs/capabilityBindings.js +2 -2
- package/dist/cjs/capabilityInvocation.js +3 -1
- package/dist/cjs/commonsSignIn.js +2 -2
- package/dist/cjs/deviceSession.js +5 -1
- package/dist/cjs/email/messages.js +70 -4
- package/dist/cjs/emailAgentContext.js +16 -8
- package/dist/cjs/externalIdentity.js +30 -12
- package/dist/cjs/identity.js +14 -6
- package/dist/cjs/identityLink.js +7 -2
- package/dist/cjs/identityProof.js +2 -1
- package/dist/cjs/index.js +5 -3
- package/dist/cjs/inference/catalogue.js +2 -12
- package/dist/cjs/inference/decisions.js +102 -83
- package/dist/cjs/inference/economics.js +15 -5
- package/dist/cjs/inference/embeddings.js +44 -6
- package/dist/cjs/inference/inbox.js +33 -2
- package/dist/cjs/inference/providerConnection.js +21 -6
- package/dist/cjs/inference/realtime.js +114 -107
- package/dist/cjs/inference/scopedExecution.js +12 -12
- package/dist/cjs/inference/usage.js +2 -9
- package/dist/cjs/notifications.js +25 -5
- package/dist/cjs/oauth.js +30 -14
- package/dist/cjs/oxyRecordTypes.js +2 -2
- package/dist/cjs/products/access.js +146 -57
- package/dist/cjs/products/billing.js +71 -17
- package/dist/cjs/products/checkout.js +24 -6
- package/dist/cjs/products/plans.js +22 -7
- package/dist/cjs/recommendations.js +4 -6
- package/dist/cjs/reputation.js +3 -6
- package/dist/cjs/sessionStatus.js +1 -6
- package/dist/cjs/signIn.js +17 -4
- package/dist/cjs/transparency.js +3 -1
- package/dist/cjs/updates.js +2 -4
- package/dist/cjs/userResponse.js +27 -7
- package/dist/cjs/username.js +3 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/accountGraph.js +5 -3
- package/dist/esm/agency.js +178 -96
- package/dist/esm/agentKeys.js +80 -26
- package/dist/esm/capabilityBindings.js +2 -2
- package/dist/esm/capabilityInvocation.js +3 -1
- package/dist/esm/commonsSignIn.js +2 -2
- package/dist/esm/deviceSession.js +5 -1
- package/dist/esm/email/messages.js +69 -3
- package/dist/esm/emailAgentContext.js +16 -8
- package/dist/esm/externalIdentity.js +30 -12
- package/dist/esm/identity.js +14 -6
- package/dist/esm/identityLink.js +7 -2
- package/dist/esm/identityProof.js +2 -1
- package/dist/esm/index.js +7 -7
- package/dist/esm/inference/aliaModelRelease.js +1 -1
- package/dist/esm/inference/catalogue.js +3 -13
- package/dist/esm/inference/decisions.js +108 -89
- package/dist/esm/inference/economics.js +16 -6
- package/dist/esm/inference/embeddings.js +44 -6
- package/dist/esm/inference/inbox.js +32 -1
- package/dist/esm/inference/providerConnection.js +21 -6
- package/dist/esm/inference/realtime.js +123 -116
- package/dist/esm/inference/scopedExecution.js +15 -15
- package/dist/esm/inference/usage.js +2 -9
- package/dist/esm/notifications.js +25 -5
- package/dist/esm/oauth.js +30 -14
- package/dist/esm/oxyRecordTypes.js +2 -2
- package/dist/esm/products/access.js +146 -57
- package/dist/esm/products/billing.js +71 -17
- package/dist/esm/products/checkout.js +24 -6
- package/dist/esm/products/plans.js +22 -7
- package/dist/esm/recommendations.js +4 -6
- package/dist/esm/reputation.js +3 -6
- package/dist/esm/sessionStatus.js +1 -6
- package/dist/esm/signIn.js +17 -4
- package/dist/esm/transparency.js +3 -1
- package/dist/esm/updates.js +2 -4
- package/dist/esm/userResponse.js +27 -7
- package/dist/esm/username.js +3 -1
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/accountGraph.d.ts +1 -1
- package/dist/types/commonsSignIn.d.ts +2 -2
- package/dist/types/email/messages.d.ts +208 -2
- package/dist/types/identity.d.ts +1 -1
- package/dist/types/index.d.ts +8 -8
- package/dist/types/inference/decisions.d.ts +1 -1
- package/dist/types/inference/inbox.d.ts +129 -5
- package/dist/types/inference/realtime.d.ts +1 -1
- package/dist/types/inference/scopedExecution.d.ts +1 -1
- package/dist/types/moderationReputation.d.ts +1 -1
- package/dist/types/oxyRecordTypes.d.ts +2 -2
- package/dist/types/products/access.d.ts +102 -102
- package/dist/types/products/checkout.d.ts +3 -3
- package/dist/types/products/plans.d.ts +40 -40
- package/dist/types/reputation.d.ts +4 -4
- package/dist/types/updates.d.ts +1 -1
- package/dist/types/userResponse.d.ts +22 -23
- package/package.json +1 -2
|
@@ -65,12 +65,7 @@ exports.usageReservationRequestSchema = zod_1.z.object({
|
|
|
65
65
|
expiresInSeconds: zod_1.z.number().int().positive().max(86400),
|
|
66
66
|
});
|
|
67
67
|
/** Lifecycle of a hold. Terminal states are `settled`, `released`, `expired`. */
|
|
68
|
-
exports.usageReservationStatusSchema = zod_1.z.enum([
|
|
69
|
-
'held',
|
|
70
|
-
'settled',
|
|
71
|
-
'released',
|
|
72
|
-
'expired',
|
|
73
|
-
]);
|
|
68
|
+
exports.usageReservationStatusSchema = zod_1.z.enum(['held', 'settled', 'released', 'expired']);
|
|
74
69
|
/**
|
|
75
70
|
* A hold placed against an account's balance.
|
|
76
71
|
*
|
|
@@ -270,9 +265,7 @@ exports.usageReceiptSchema = zod_1.z
|
|
|
270
265
|
* ledger accounts and only the second one is visible on an invoice.
|
|
271
266
|
*/
|
|
272
267
|
exports.usageRefundSubjectSchema = zod_1.z.discriminatedUnion('kind', [
|
|
273
|
-
zod_1.z
|
|
274
|
-
.object({ kind: zod_1.z.literal('reservation'), reservationId: zod_1.z.string().min(1).max(128) })
|
|
275
|
-
.strict(),
|
|
268
|
+
zod_1.z.object({ kind: zod_1.z.literal('reservation'), reservationId: zod_1.z.string().min(1).max(128) }).strict(),
|
|
276
269
|
zod_1.z.object({ kind: zod_1.z.literal('receipt'), receiptId: zod_1.z.string().min(1).max(128) }).strict(),
|
|
277
270
|
]);
|
|
278
271
|
/** Why money was given back or a hold was released. */
|
|
@@ -64,18 +64,38 @@ exports.createOxyNotificationRequestSchema = zod_1.z
|
|
|
64
64
|
.superRefine((value, context) => {
|
|
65
65
|
if (value.type === 'system') {
|
|
66
66
|
if (value.actorId !== value.recipientId)
|
|
67
|
-
context.addIssue({
|
|
67
|
+
context.addIssue({
|
|
68
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
69
|
+
path: ['actorId'],
|
|
70
|
+
message: "a system notification is from the recipient's own account",
|
|
71
|
+
});
|
|
68
72
|
if (!value.title)
|
|
69
|
-
context.addIssue({
|
|
73
|
+
context.addIssue({
|
|
74
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
75
|
+
path: ['title'],
|
|
76
|
+
message: 'title is required for a system notification',
|
|
77
|
+
});
|
|
70
78
|
if (!value.message)
|
|
71
|
-
context.addIssue({
|
|
79
|
+
context.addIssue({
|
|
80
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
81
|
+
path: ['message'],
|
|
82
|
+
message: 'message is required for a system notification',
|
|
83
|
+
});
|
|
72
84
|
}
|
|
73
85
|
else {
|
|
74
86
|
if (value.url !== undefined) {
|
|
75
|
-
context.addIssue({
|
|
87
|
+
context.addIssue({
|
|
88
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
89
|
+
path: ['url'],
|
|
90
|
+
message: 'url is only stored for a system notification',
|
|
91
|
+
});
|
|
76
92
|
}
|
|
77
93
|
if (value.entityType === 'app') {
|
|
78
|
-
context.addIssue({
|
|
94
|
+
context.addIssue({
|
|
95
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
96
|
+
path: ['entityType'],
|
|
97
|
+
message: "entityType 'app' is only valid for a system notification",
|
|
98
|
+
});
|
|
79
99
|
}
|
|
80
100
|
}
|
|
81
101
|
});
|
package/dist/cjs/oauth.js
CHANGED
|
@@ -71,45 +71,61 @@ exports.oauthAuthorizeCodeResponseSchema = zod_1.z.object({
|
|
|
71
71
|
* Reuses the ordinary public application projection and adds only the public
|
|
72
72
|
* DCR client id needed to bind the consent surface to the request.
|
|
73
73
|
*/
|
|
74
|
-
exports.mcpOAuthClientApplicationSchema = sessionStatus_1.publicApplicationSchema
|
|
74
|
+
exports.mcpOAuthClientApplicationSchema = sessionStatus_1.publicApplicationSchema
|
|
75
|
+
.extend({
|
|
75
76
|
clientId: zod_1.z.string().min(1),
|
|
76
|
-
})
|
|
77
|
+
})
|
|
78
|
+
.strict();
|
|
77
79
|
/**
|
|
78
80
|
* An effectful MCP action the requested capability set can actually invoke.
|
|
79
81
|
* Every field is picked from the canonical catalog tool schema so consent can
|
|
80
82
|
* never maintain a second tool description or effect classification.
|
|
81
83
|
*/
|
|
82
|
-
exports.mcpOAuthWriteActionSchema = agency_1.catalogToolSchema
|
|
84
|
+
exports.mcpOAuthWriteActionSchema = agency_1.catalogToolSchema
|
|
85
|
+
.innerType()
|
|
86
|
+
.pick({
|
|
83
87
|
name: true,
|
|
84
88
|
version: true,
|
|
85
89
|
description: true,
|
|
86
90
|
requiredCapabilities: true,
|
|
87
91
|
effect: true,
|
|
88
|
-
})
|
|
92
|
+
})
|
|
93
|
+
.strict()
|
|
94
|
+
.refine((action) => action.effect !== 'read', {
|
|
89
95
|
message: 'MCP consent write actions must be effectful',
|
|
90
96
|
path: ['effect'],
|
|
91
97
|
});
|
|
92
98
|
/** Exact, server-resolved context rendered before an external MCP grant. */
|
|
93
|
-
exports.mcpOAuthConsentContextSchema = zod_1.z
|
|
99
|
+
exports.mcpOAuthConsentContextSchema = zod_1.z
|
|
100
|
+
.object({
|
|
94
101
|
client: exports.mcpOAuthClientApplicationSchema,
|
|
95
|
-
account: zod_1.z
|
|
102
|
+
account: zod_1.z
|
|
103
|
+
.object({
|
|
96
104
|
id: zod_1.z.string().min(1),
|
|
97
105
|
displayName: zod_1.z.string().min(1).optional(),
|
|
98
106
|
handle: zod_1.z.string().min(1).optional(),
|
|
99
107
|
avatar: zod_1.z.string().min(1).optional(),
|
|
100
|
-
})
|
|
101
|
-
|
|
108
|
+
})
|
|
109
|
+
.strict(),
|
|
110
|
+
resource: zod_1.z
|
|
111
|
+
.object({
|
|
102
112
|
appId: zod_1.z.string().min(1),
|
|
103
113
|
uri: zod_1.z.string().url(),
|
|
104
114
|
application: sessionStatus_1.publicApplicationSchema,
|
|
105
|
-
})
|
|
115
|
+
})
|
|
116
|
+
.strict(),
|
|
106
117
|
capabilities: zod_1.z.array(zod_1.z.string().min(1)).min(1),
|
|
107
118
|
writeActions: zod_1.z.array(exports.mcpOAuthWriteActionSchema),
|
|
108
|
-
})
|
|
109
|
-
|
|
119
|
+
})
|
|
120
|
+
.strict();
|
|
121
|
+
exports.mcpOAuthClientInfoResponseSchema = zod_1.z
|
|
122
|
+
.object({
|
|
110
123
|
application: exports.mcpOAuthClientApplicationSchema,
|
|
111
|
-
})
|
|
112
|
-
|
|
124
|
+
})
|
|
125
|
+
.strict();
|
|
126
|
+
exports.mcpOAuthConsentResponseSchema = zod_1.z
|
|
127
|
+
.object({
|
|
113
128
|
consentRequired: zod_1.z.boolean(),
|
|
114
129
|
context: exports.mcpOAuthConsentContextSchema,
|
|
115
|
-
})
|
|
130
|
+
})
|
|
131
|
+
.strict();
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* is rejected as `invalid_envelope`.
|
|
9
9
|
*
|
|
10
10
|
* `oxySignedRecordTypeSchema` is that runtime gate (the API's `verifyEnvelope`
|
|
11
|
-
* re-narrows with it; the
|
|
12
|
-
*
|
|
11
|
+
* re-narrows with it; the Postgres CHECK on `signed_records.type` is derived
|
|
12
|
+
* from `.options`);
|
|
13
13
|
* `OxySignedRecordType` is the matching compile-time union the SDK
|
|
14
14
|
* identity/civic mixins type against.
|
|
15
15
|
*
|
|
@@ -5,86 +5,175 @@ const zod_1 = require("zod");
|
|
|
5
5
|
const identifiers_1 = require("../inference/identifiers");
|
|
6
6
|
const identifier = zod_1.z.string().min(1).max(160);
|
|
7
7
|
const count = zod_1.z.number().int().nonnegative().safe();
|
|
8
|
-
const period = zod_1.z
|
|
9
|
-
.
|
|
8
|
+
const period = zod_1.z
|
|
9
|
+
.object({ start: zod_1.z.string().datetime(), end: zod_1.z.string().datetime() })
|
|
10
|
+
.strict()
|
|
11
|
+
.refine((value) => Date.parse(value.end) > Date.parse(value.start), 'period end must follow start');
|
|
10
12
|
/** Product ownership and audience are registered together; branding grants no trust. */
|
|
11
|
-
exports.productDefinitionSchema = zod_1.z
|
|
12
|
-
|
|
13
|
+
exports.productDefinitionSchema = zod_1.z
|
|
14
|
+
.object({
|
|
15
|
+
schemaVersion: zod_1.z.literal(1),
|
|
16
|
+
id: identifier,
|
|
17
|
+
ownerAccountId: identifiers_1.oxyAccountIdSchema,
|
|
13
18
|
applicationId: identifiers_1.oxyApplicationIdSchema,
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
})
|
|
20
|
+
.strict();
|
|
21
|
+
exports.subjectProductAccessQuerySchema = zod_1.z
|
|
22
|
+
.object({
|
|
23
|
+
schemaVersion: zod_1.z.literal(1),
|
|
24
|
+
subjectAccountId: identifiers_1.oxyAccountIdSchema,
|
|
25
|
+
productId: identifier,
|
|
26
|
+
})
|
|
27
|
+
.strict();
|
|
18
28
|
/** Every quota declares its combination rule; there is no commercial default. */
|
|
19
29
|
exports.productBenefitSchema = zod_1.z.discriminatedUnion('kind', [
|
|
20
30
|
zod_1.z.object({ kind: zod_1.z.literal('capability'), productId: identifier, key: identifier }).strict(),
|
|
21
|
-
zod_1.z
|
|
22
|
-
|
|
31
|
+
zod_1.z
|
|
32
|
+
.object({
|
|
33
|
+
kind: zod_1.z.literal('quota'),
|
|
34
|
+
productId: identifier,
|
|
35
|
+
key: identifier,
|
|
36
|
+
unit: identifier,
|
|
37
|
+
included: count,
|
|
38
|
+
combination: zod_1.z.enum(['maximum', 'sum', 'exclusive']),
|
|
39
|
+
})
|
|
40
|
+
.strict(),
|
|
23
41
|
]);
|
|
24
42
|
/** A version names a frozen offer. An empty bundle grants nothing. */
|
|
25
|
-
exports.productOfferSchema = zod_1.z
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
exports.productOfferSchema = zod_1.z
|
|
44
|
+
.object({
|
|
45
|
+
schemaVersion: zod_1.z.literal(1),
|
|
46
|
+
id: identifier,
|
|
47
|
+
version: zod_1.z.number().int().positive().safe(),
|
|
48
|
+
kind: zod_1.z.enum(['individual', 'bundle']),
|
|
49
|
+
benefits: zod_1.z.array(exports.productBenefitSchema),
|
|
50
|
+
})
|
|
51
|
+
.strict()
|
|
52
|
+
.refine((value) => value.kind === 'bundle' ||
|
|
53
|
+
new Set(value.benefits.map((benefit) => benefit.productId)).size <= 1, 'individual offers cannot cover multiple products');
|
|
54
|
+
exports.productSubscriptionSourceSchema = zod_1.z
|
|
55
|
+
.object({
|
|
56
|
+
schemaVersion: zod_1.z.literal(1),
|
|
57
|
+
id: identifier,
|
|
58
|
+
beneficiaryAccountId: identifiers_1.oxyAccountIdSchema,
|
|
59
|
+
payerAccountId: identifiers_1.oxyAccountIdSchema,
|
|
60
|
+
provider: zod_1.z.enum(['stripe', 'peable']),
|
|
61
|
+
providerSubscriptionId: identifier,
|
|
62
|
+
status: zod_1.z.enum([
|
|
63
|
+
'active',
|
|
64
|
+
'trialing',
|
|
65
|
+
'past_due',
|
|
66
|
+
'unpaid',
|
|
67
|
+
'canceled',
|
|
68
|
+
'paused',
|
|
69
|
+
'incomplete',
|
|
70
|
+
'incomplete_expired',
|
|
71
|
+
]),
|
|
72
|
+
period,
|
|
73
|
+
cancelAtPeriodEnd: zod_1.z.boolean(),
|
|
74
|
+
})
|
|
75
|
+
.strict();
|
|
36
76
|
/** A frozen paid-period/offer segment; upgrades append, never rewrite it. */
|
|
37
|
-
exports.productOfferSegmentSchema = zod_1.z
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
77
|
+
exports.productOfferSegmentSchema = zod_1.z
|
|
78
|
+
.object({
|
|
79
|
+
schemaVersion: zod_1.z.literal(1),
|
|
80
|
+
id: identifier,
|
|
81
|
+
subscriptionId: identifier,
|
|
82
|
+
beneficiaryAccountId: identifiers_1.oxyAccountIdSchema,
|
|
83
|
+
offerId: identifier,
|
|
84
|
+
offerVersion: zod_1.z.number().int().positive().safe(),
|
|
85
|
+
origin: zod_1.z.enum(['individual', 'bundle']),
|
|
86
|
+
period,
|
|
87
|
+
})
|
|
88
|
+
.strict();
|
|
42
89
|
/** Provenance survives cancellation: deactivate a source, never delete history. */
|
|
43
|
-
exports.productAccessGrantSchema = zod_1.z
|
|
44
|
-
|
|
45
|
-
|
|
90
|
+
exports.productAccessGrantSchema = zod_1.z
|
|
91
|
+
.object({
|
|
92
|
+
schemaVersion: zod_1.z.literal(1),
|
|
93
|
+
id: identifier,
|
|
94
|
+
sourceSegmentId: identifier,
|
|
95
|
+
beneficiaryAccountId: identifiers_1.oxyAccountIdSchema,
|
|
96
|
+
offerId: identifier,
|
|
46
97
|
offerVersion: zod_1.z.number().int().positive().safe(),
|
|
47
|
-
origin: zod_1.z.enum(['individual', 'bundle']),
|
|
48
|
-
|
|
49
|
-
|
|
98
|
+
origin: zod_1.z.enum(['individual', 'bundle']),
|
|
99
|
+
benefit: exports.productBenefitSchema,
|
|
100
|
+
period,
|
|
101
|
+
revokedAt: zod_1.z.string().datetime().nullable(),
|
|
102
|
+
})
|
|
103
|
+
.strict();
|
|
50
104
|
/** Access answers contain no payer, provider reference, price or account balance. */
|
|
51
|
-
exports.subjectProductAccessSchema = zod_1.z
|
|
52
|
-
|
|
105
|
+
exports.subjectProductAccessSchema = zod_1.z
|
|
106
|
+
.object({
|
|
107
|
+
schemaVersion: zod_1.z.literal(1),
|
|
108
|
+
subjectAccountId: identifiers_1.oxyAccountIdSchema,
|
|
109
|
+
productId: identifier,
|
|
53
110
|
evaluatedAt: zod_1.z.string().datetime(),
|
|
54
111
|
capabilities: zod_1.z.array(zod_1.z.object({ key: identifier, grantIds: zod_1.z.array(identifier) }).strict()),
|
|
55
|
-
quotas: zod_1.z.array(zod_1.z
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
112
|
+
quotas: zod_1.z.array(zod_1.z
|
|
113
|
+
.object({
|
|
114
|
+
key: identifier,
|
|
115
|
+
unit: identifier,
|
|
116
|
+
included: count,
|
|
117
|
+
combination: zod_1.z.enum(['maximum', 'sum', 'exclusive']),
|
|
118
|
+
grantIds: zod_1.z.array(identifier),
|
|
119
|
+
})
|
|
120
|
+
.strict()),
|
|
121
|
+
conflicts: zod_1.z.array(zod_1.z
|
|
122
|
+
.object({
|
|
123
|
+
key: identifier,
|
|
124
|
+
reason: zod_1.z.enum([
|
|
125
|
+
'combination_mismatch',
|
|
126
|
+
'unit_mismatch',
|
|
127
|
+
'exclusive_overlap',
|
|
128
|
+
'unsafe_total',
|
|
129
|
+
]),
|
|
130
|
+
grantIds: zod_1.z.array(identifier),
|
|
131
|
+
})
|
|
132
|
+
.strict()),
|
|
133
|
+
})
|
|
134
|
+
.strict();
|
|
61
135
|
/** Active grant periods for metering adapters; no financial/provider identity. */
|
|
62
|
-
exports.subjectProductGrantSnapshotSchema = zod_1.z
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
136
|
+
exports.subjectProductGrantSnapshotSchema = zod_1.z
|
|
137
|
+
.object({
|
|
138
|
+
schemaVersion: zod_1.z.literal(1),
|
|
139
|
+
access: exports.subjectProductAccessSchema,
|
|
140
|
+
grants: zod_1.z.array(exports.productAccessGrantSchema),
|
|
141
|
+
})
|
|
142
|
+
.strict()
|
|
143
|
+
.superRefine((value, ctx) => {
|
|
144
|
+
const active = new Set([...value.access.capabilities, ...value.access.quotas].flatMap((entry) => entry.grantIds));
|
|
145
|
+
if (active.size !== value.grants.length ||
|
|
146
|
+
new Set(value.grants.map((g) => g.id)).size !== value.grants.length ||
|
|
147
|
+
value.grants.some((g) => g.beneficiaryAccountId !== value.access.subjectAccountId ||
|
|
148
|
+
g.benefit.productId !== value.access.productId ||
|
|
149
|
+
!active.has(g.id) ||
|
|
69
150
|
// A future revocation is still active at evaluation time, as in access composition.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
151
|
+
(g.revokedAt !== null &&
|
|
152
|
+
Date.parse(g.revokedAt) <= Date.parse(value.access.evaluatedAt)) ||
|
|
153
|
+
Date.parse(g.period.start) > Date.parse(value.access.evaluatedAt) ||
|
|
154
|
+
Date.parse(g.period.end) <= Date.parse(value.access.evaluatedAt)))
|
|
73
155
|
ctx.addIssue({ code: 'custom', message: 'Active grant snapshot attribution differs' });
|
|
74
156
|
for (const quota of value.access.quotas) {
|
|
75
|
-
const benefits = quota.grantIds.map(id => value.grants.find(g => g.id === id)?.benefit);
|
|
76
|
-
if (benefits.some(b => !b ||
|
|
157
|
+
const benefits = quota.grantIds.map((id) => value.grants.find((g) => g.id === id)?.benefit);
|
|
158
|
+
if (benefits.some((b) => !b ||
|
|
159
|
+
b.kind !== 'quota' ||
|
|
160
|
+
b.key !== quota.key ||
|
|
161
|
+
b.unit !== quota.unit ||
|
|
162
|
+
b.combination !== quota.combination)) {
|
|
77
163
|
ctx.addIssue({ code: 'custom', message: 'Grant quota terms differ' });
|
|
78
164
|
continue;
|
|
79
165
|
}
|
|
80
|
-
const amounts = benefits.map(b => b?.kind === 'quota' ? BigInt(b.included) : 0n);
|
|
81
|
-
const included = quota.combination === 'sum'
|
|
82
|
-
|
|
166
|
+
const amounts = benefits.map((b) => (b?.kind === 'quota' ? BigInt(b.included) : 0n));
|
|
167
|
+
const included = quota.combination === 'sum'
|
|
168
|
+
? amounts.reduce((sum, n) => sum + n, 0n)
|
|
169
|
+
: amounts.reduce((maximum, n) => (n > maximum ? n : maximum), 0n);
|
|
170
|
+
if (included !== BigInt(quota.included) ||
|
|
171
|
+
(quota.combination === 'exclusive' && benefits.length > 1))
|
|
83
172
|
ctx.addIssue({ code: 'custom', message: 'Grant quota composition differs' });
|
|
84
173
|
}
|
|
85
174
|
for (const capability of value.access.capabilities)
|
|
86
|
-
if (capability.grantIds.some(id => {
|
|
87
|
-
const benefit = value.grants.find(g => g.id === id)?.benefit;
|
|
175
|
+
if (capability.grantIds.some((id) => {
|
|
176
|
+
const benefit = value.grants.find((g) => g.id === id)?.benefit;
|
|
88
177
|
return benefit?.kind !== 'capability' || benefit.key !== capability.key;
|
|
89
178
|
}))
|
|
90
179
|
ctx.addIssue({ code: 'custom', message: 'Grant capability terms differ' });
|
|
@@ -6,25 +6,79 @@ const identifiers_1 = require("../inference/identifiers");
|
|
|
6
6
|
const id = zod_1.z.string().min(1).max(160);
|
|
7
7
|
const name = zod_1.z.string().min(1).max(100);
|
|
8
8
|
const count = zod_1.z.number().int().nonnegative().safe();
|
|
9
|
-
const period = zod_1.z
|
|
10
|
-
.
|
|
9
|
+
const period = zod_1.z
|
|
10
|
+
.object({ start: zod_1.z.string().datetime(), end: zod_1.z.string().datetime() })
|
|
11
|
+
.strict()
|
|
12
|
+
.refine((value) => Date.parse(value.end) > Date.parse(value.start), 'Period end must follow start');
|
|
11
13
|
/** Self-service provenance; no payer/provider identifiers or balances in access metadata. */
|
|
12
|
-
exports.productSubscriptionSummarySchema = zod_1.z
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
exports.productSubscriptionSummarySchema = zod_1.z
|
|
15
|
+
.object({
|
|
16
|
+
sourceId: id,
|
|
17
|
+
status: zod_1.z.enum([
|
|
18
|
+
'active',
|
|
19
|
+
'trialing',
|
|
20
|
+
'past_due',
|
|
21
|
+
'unpaid',
|
|
22
|
+
'canceled',
|
|
23
|
+
'paused',
|
|
24
|
+
'incomplete',
|
|
25
|
+
'incomplete_expired',
|
|
26
|
+
]),
|
|
27
|
+
period,
|
|
28
|
+
cancelAtPeriodEnd: zod_1.z.boolean(),
|
|
29
|
+
canCancel: zod_1.z.boolean(),
|
|
30
|
+
offers: zod_1.z.array(zod_1.z
|
|
31
|
+
.object({
|
|
32
|
+
segmentId: id,
|
|
33
|
+
offerId: id,
|
|
34
|
+
offerVersion: zod_1.z.number().int().positive().safe(),
|
|
35
|
+
displayName: name,
|
|
36
|
+
origin: zod_1.z.enum(['individual', 'bundle']),
|
|
37
|
+
period,
|
|
38
|
+
current: zod_1.z.boolean(),
|
|
17
39
|
products: zod_1.z.array(zod_1.z.object({ id, displayName: name }).strict()),
|
|
18
|
-
})
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
})
|
|
41
|
+
.strict()),
|
|
42
|
+
})
|
|
43
|
+
.strict();
|
|
44
|
+
exports.productSubscriptionsResponseSchema = zod_1.z
|
|
45
|
+
.object({ subscriptions: zod_1.z.array(exports.productSubscriptionSummarySchema) })
|
|
46
|
+
.strict();
|
|
47
|
+
exports.subscriptionCreditGrantSchema = zod_1.z
|
|
48
|
+
.object({
|
|
49
|
+
id,
|
|
50
|
+
invoiceId: id,
|
|
51
|
+
origin: zod_1.z.enum([
|
|
52
|
+
'subscription_payment',
|
|
53
|
+
'subscription_proration',
|
|
54
|
+
'subscription_promotional_grant',
|
|
55
|
+
]),
|
|
56
|
+
period,
|
|
57
|
+
granted: count,
|
|
58
|
+
consumed: count,
|
|
59
|
+
clawed: count,
|
|
60
|
+
remaining: count,
|
|
61
|
+
promotionId: id.nullable(),
|
|
62
|
+
createdAt: zod_1.z.string().datetime(),
|
|
63
|
+
})
|
|
64
|
+
.strict()
|
|
65
|
+
.refine((value) => BigInt(value.consumed) + BigInt(value.clawed) + BigInt(value.remaining) ===
|
|
66
|
+
BigInt(value.granted), 'Grant conservation differs');
|
|
67
|
+
exports.subscriptionCreditGrantsResponseSchema = zod_1.z
|
|
68
|
+
.object({ grants: zod_1.z.array(exports.subscriptionCreditGrantSchema) })
|
|
69
|
+
.strict();
|
|
70
|
+
exports.cancelProductSubscriptionSchema = zod_1.z
|
|
71
|
+
.object({
|
|
72
|
+
sourceId: id,
|
|
73
|
+
actionId: zod_1.z
|
|
74
|
+
.string()
|
|
75
|
+
.min(8)
|
|
76
|
+
.max(160)
|
|
77
|
+
.regex(/^[a-zA-Z0-9_-]+$/)
|
|
78
|
+
.optional(),
|
|
79
|
+
expectedSubjectAccountId: identifiers_1.oxyAccountIdSchema.optional(),
|
|
80
|
+
})
|
|
81
|
+
.strict();
|
|
28
82
|
/** Remote acceptance is distinct from completed local reconciliation. */
|
|
29
83
|
exports.productSubscriptionCancellationResultSchema = zod_1.z.union([
|
|
30
84
|
zod_1.z.object({ sourceId: id, cancelAtPeriodEnd: zod_1.z.literal(true) }).strict(),
|
|
@@ -3,15 +3,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.personalPlanCheckoutResultSchema = exports.personalPlanCheckoutRequestSchema = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const identifiers_1 = require("../inference/identifiers");
|
|
6
|
-
exports.personalPlanCheckoutRequestSchema = zod_1.z
|
|
6
|
+
exports.personalPlanCheckoutRequestSchema = zod_1.z
|
|
7
|
+
.object({
|
|
7
8
|
expectedSubjectAccountId: identifiers_1.oxyAccountIdSchema,
|
|
8
|
-
offerId: zod_1.z.string().min(1).max(160),
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
offerId: zod_1.z.string().min(1).max(160),
|
|
10
|
+
offerVersion: zod_1.z.number().int().positive().safe(),
|
|
11
|
+
idempotencyKey: zod_1.z
|
|
12
|
+
.string()
|
|
13
|
+
.min(8)
|
|
14
|
+
.max(160)
|
|
15
|
+
.regex(/^[a-zA-Z0-9_-]+$/),
|
|
16
|
+
})
|
|
17
|
+
.strict();
|
|
11
18
|
/** No grant or subscription is created by checkout completion in the browser. */
|
|
12
19
|
exports.personalPlanCheckoutResultSchema = zod_1.z.discriminatedUnion('state', [
|
|
13
|
-
zod_1.z
|
|
14
|
-
|
|
20
|
+
zod_1.z
|
|
21
|
+
.object({
|
|
22
|
+
state: zod_1.z.literal('unconfigured'),
|
|
23
|
+
reason: zod_1.z.enum(['provider_unconfigured', 'offer_unconfigured', 'price_unconfigured']),
|
|
24
|
+
})
|
|
25
|
+
.strict(),
|
|
26
|
+
zod_1.z
|
|
27
|
+
.object({
|
|
28
|
+
state: zod_1.z.literal('pending'),
|
|
29
|
+
intentId: zod_1.z.string().min(1).max(160),
|
|
30
|
+
checkoutUrl: zod_1.z.string().url().startsWith('https://').optional(),
|
|
31
|
+
})
|
|
32
|
+
.strict(),
|
|
15
33
|
zod_1.z.object({ state: zod_1.z.literal('closed'), intentId: zod_1.z.string().min(1).max(160) }).strict(),
|
|
16
34
|
zod_1.z.object({ state: zod_1.z.literal('fulfilled'), intentId: zod_1.z.string().min(1).max(160) }).strict(),
|
|
17
35
|
]);
|
|
@@ -4,20 +4,35 @@ exports.personalPlanCatalogueSchema = exports.personalPlanDisplayPriceSchema = v
|
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const access_1 = require("./access");
|
|
6
6
|
/** Approved display terms never identify or activate a billing-provider price. */
|
|
7
|
-
exports.personalPlanDisplayPriceSchema = zod_1.z
|
|
8
|
-
|
|
7
|
+
exports.personalPlanDisplayPriceSchema = zod_1.z
|
|
8
|
+
.object({
|
|
9
|
+
currency: zod_1.z.string().regex(/^[A-Z]{3}$/),
|
|
10
|
+
amountMinorUnits: zod_1.z.number().int().positive().safe(),
|
|
11
|
+
interval: zod_1.z.literal('month'),
|
|
12
|
+
trial: zod_1.z.literal('none'),
|
|
13
|
+
taxTreatment: zod_1.z.literal('inclusive'),
|
|
14
|
+
merchantTotal: zod_1.z.literal('final'),
|
|
15
|
+
})
|
|
16
|
+
.strict();
|
|
9
17
|
/** Public discovery is separate from customer access. No provider or owner IDs. */
|
|
10
|
-
exports.personalPlanCatalogueSchema = zod_1.z
|
|
18
|
+
exports.personalPlanCatalogueSchema = zod_1.z
|
|
19
|
+
.object({
|
|
11
20
|
schemaVersion: zod_1.z.literal(1),
|
|
12
21
|
state: zod_1.z.enum(['unconfigured', 'configured']),
|
|
13
22
|
purchase: zod_1.z.literal('unavailable'),
|
|
14
|
-
plans: zod_1.z.array(zod_1.z
|
|
23
|
+
plans: zod_1.z.array(zod_1.z
|
|
24
|
+
.object({
|
|
15
25
|
offerId: zod_1.z.string().min(1).max(160),
|
|
16
26
|
offerVersion: zod_1.z.number().int().positive().safe(),
|
|
17
27
|
displayName: zod_1.z.string().min(1).max(100),
|
|
18
28
|
audience: zod_1.z.literal('personal'),
|
|
19
29
|
kind: zod_1.z.literal('oxy_one'),
|
|
20
30
|
price: exports.personalPlanDisplayPriceSchema.optional(),
|
|
21
|
-
benefits: zod_1.z.array(zod_1.z
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
benefits: zod_1.z.array(zod_1.z
|
|
32
|
+
.object({ displayName: zod_1.z.string().min(1).max(100), benefit: access_1.productBenefitSchema })
|
|
33
|
+
.strict()),
|
|
34
|
+
})
|
|
35
|
+
.strict()),
|
|
36
|
+
})
|
|
37
|
+
.strict()
|
|
38
|
+
.refine((value) => (value.state === 'unconfigured') === (value.plans.length === 0), 'Catalogue state must match published plans');
|
|
@@ -16,11 +16,7 @@ exports.appAffinityEventsIngestSchema = exports.appAffinityEventSchema = exports
|
|
|
16
16
|
const zod_1 = require("zod");
|
|
17
17
|
const userResponse_1 = require("./userResponse");
|
|
18
18
|
/** User-type filters a caller may exclude from the recommendation surface. */
|
|
19
|
-
exports.recommendationExcludeTypeSchema = zod_1.z.enum([
|
|
20
|
-
'federated',
|
|
21
|
-
'agent',
|
|
22
|
-
'automated',
|
|
23
|
-
]);
|
|
19
|
+
exports.recommendationExcludeTypeSchema = zod_1.z.enum(['federated', 'agent', 'automated']);
|
|
24
20
|
/**
|
|
25
21
|
* A caller-supplied editorial boost. `userIds` are nudged up (or down, for a
|
|
26
22
|
* negative weight) in the ranking; the optional `reason` is for audit/telemetry
|
|
@@ -125,7 +121,9 @@ exports.appUserSignalIngestSchema = zod_1.z
|
|
|
125
121
|
endorsements: zod_1.z.array(exports.appEndorsementInputSchema).max(500).optional(),
|
|
126
122
|
interests: zod_1.z.array(exports.appInterestInputSchema).max(500).optional(),
|
|
127
123
|
})
|
|
128
|
-
.refine((value) => (value.endorsements?.length ?? 0) > 0 || (value.interests?.length ?? 0) > 0, {
|
|
124
|
+
.refine((value) => (value.endorsements?.length ?? 0) > 0 || (value.interests?.length ?? 0) > 0, {
|
|
125
|
+
message: 'At least one of endorsements or interests must be non-empty',
|
|
126
|
+
});
|
|
129
127
|
/**
|
|
130
128
|
* The directed interaction types a consuming app may report between two users.
|
|
131
129
|
* Each type carries a server-side default weight (see the API's
|
package/dist/cjs/reputation.js
CHANGED
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
* - **The balance has two views, and the union is the contract.** See
|
|
26
26
|
* {@link ReputationBalanceView} — the compile-time assertions below are what
|
|
27
27
|
* stop the private view's fields becoming reachable on a stranger's balance.
|
|
28
|
-
* - **The closed value sets live here, not beside the
|
|
29
|
-
* API's
|
|
28
|
+
* - **The closed value sets live here, not beside the database schema.** The
|
|
29
|
+
* API's column enums and the SDK's unions are the same `as const` tuple, so a
|
|
30
30
|
* seventh category cannot be added on one side only.
|
|
31
31
|
*
|
|
32
32
|
* The response entities are declared as explicit `interface`s with their runtime
|
|
@@ -78,10 +78,7 @@ exports.reputationCategorySchema = zod_1.z.enum(exports.REPUTATION_CATEGORIES);
|
|
|
78
78
|
* only by policy-driven code, never by a person); the pair nets
|
|
79
79
|
* to zero.
|
|
80
80
|
*/
|
|
81
|
-
exports.REPUTATION_TRANSACTION_STATUSES = [
|
|
82
|
-
'active',
|
|
83
|
-
'reversed',
|
|
84
|
-
];
|
|
81
|
+
exports.REPUTATION_TRANSACTION_STATUSES = ['active', 'reversed'];
|
|
85
82
|
exports.reputationTransactionStatusSchema = zod_1.z.enum(exports.REPUTATION_TRANSACTION_STATUSES);
|
|
86
83
|
/**
|
|
87
84
|
* Trust tiers, lowest → highest trust, plus the punitive `restricted`.
|
|
@@ -43,12 +43,7 @@ const zod_1 = require("zod");
|
|
|
43
43
|
* `packages/api/src/models/Application.ts` (`first_party` | `third_party` |
|
|
44
44
|
* `internal` | `system`).
|
|
45
45
|
*/
|
|
46
|
-
exports.applicationTypeSchema = zod_1.z.enum([
|
|
47
|
-
'first_party',
|
|
48
|
-
'third_party',
|
|
49
|
-
'internal',
|
|
50
|
-
'system',
|
|
51
|
-
]);
|
|
46
|
+
exports.applicationTypeSchema = zod_1.z.enum(['first_party', 'third_party', 'internal', 'system']);
|
|
52
47
|
/**
|
|
53
48
|
* The display-safe public identity of a requesting application, exactly as
|
|
54
49
|
* `serializePublicApplication` emits it. Returned by the API inside
|