@nuanu-ai/agentify-contracts 0.3.2

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.
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The question "how much is this and is it there", and the merchant's answer.
3
+ *
4
+ * One shape, two transports. By default the question rides the same outgoing
5
+ * channel as the orders and is answered by a handler in the merchant's own
6
+ * process; a merchant whose prices come from a separate service answers the
7
+ * same question over https at an address their card names. The fields do not
8
+ * differ between the two, which is what lets a merchant switch transports
9
+ * without touching the code that answers.
10
+ *
11
+ * What the schema deliberately does not describe is silence. A missing answer,
12
+ * a timeout, a broken connection and an answer that did not parse against the
13
+ * shape below are all the same thing to the gateway, and what it does about
14
+ * them depends on the card's mode rather than on the shape of anything on this
15
+ * page.
16
+ *
17
+ * One field an order has and this does not: a price question carries no test
18
+ * marker. For a card with a price check the question rides the same channel as
19
+ * the order it precedes, and it arrives looking like every other question — so
20
+ * a handler that routes test orders to a test environment, which the portal
21
+ * tells merchants they may do, has nothing to route the question by. Whether that wants a field here or is better
22
+ * answered by however the sandbox is eventually separated from live is not
23
+ * decided, and inventing the field ahead of that decision would answer it.
24
+ */
25
+ import { z } from "zod";
26
+ /**
27
+ * Why we are asking.
28
+ *
29
+ * `purchase` means an agent is standing at the till right now; `poll` means we
30
+ * are refreshing what we know between purchases and nobody is buying. The
31
+ * distinction is there so an expensive stock lookup can be spent on the first
32
+ * and skipped on the second.
33
+ */
34
+ export declare const QuotePurposeSchema: z.ZodEnum<{
35
+ purchase: "purchase";
36
+ poll: "poll";
37
+ }>;
38
+ export declare const QuoteRequestSchema: z.ZodObject<{
39
+ merchant_item_id: z.ZodString;
40
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
41
+ price_id: z.ZodString;
42
+ purpose: z.ZodEnum<{
43
+ purchase: "purchase";
44
+ poll: "poll";
45
+ }>;
46
+ expires_at: z.ZodISODateTime;
47
+ }, z.core.$strict>;
48
+ /**
49
+ * The answer, in the only two shapes it has.
50
+ *
51
+ * A price and an availability of `false` cannot travel together, and neither
52
+ * can availability of `true` and no price. Both would be two answers at once:
53
+ * whichever the gateway then acted on, the merchant would have grounds to say
54
+ * it acted on the wrong one — and in the first case the sale would quietly
55
+ * fall back to the price in the card, at a price the merchant never quoted.
56
+ *
57
+ * `as_of` is on both branches because it is what separates "I went and looked"
58
+ * from "here is what was in the cache". The gateway carries that moment and
59
+ * does not weigh it: it travels into the order the handler is given and into
60
+ * the record of the sale, so whoever reconciles a charge afterwards can see how
61
+ * old the number behind it was, and nothing anywhere compares it against
62
+ * anything. A price's life runs from the moment the answer reached us rather
63
+ * than from the moment it says it was true, so an answer stamped a year ago is
64
+ * honoured exactly as long as one stamped a second ago.
65
+ */
66
+ export declare const QuoteResponseSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
67
+ available: z.ZodLiteral<true>;
68
+ price: z.ZodObject<{
69
+ amount: z.ZodString;
70
+ currency: z.ZodString;
71
+ }, z.core.$strict>;
72
+ as_of: z.ZodISODateTime;
73
+ }, z.core.$strict>, z.ZodObject<{
74
+ available: z.ZodLiteral<false>;
75
+ as_of: z.ZodISODateTime;
76
+ }, z.core.$strict>], "available">;
77
+ export type QuotePurpose = z.infer<typeof QuotePurposeSchema>;
78
+ export type QuoteRequest = z.infer<typeof QuoteRequestSchema>;
79
+ export type QuoteResponse = z.infer<typeof QuoteResponseSchema>;
package/dist/quote.js ADDED
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The question "how much is this and is it there", and the merchant's answer.
3
+ *
4
+ * One shape, two transports. By default the question rides the same outgoing
5
+ * channel as the orders and is answered by a handler in the merchant's own
6
+ * process; a merchant whose prices come from a separate service answers the
7
+ * same question over https at an address their card names. The fields do not
8
+ * differ between the two, which is what lets a merchant switch transports
9
+ * without touching the code that answers.
10
+ *
11
+ * What the schema deliberately does not describe is silence. A missing answer,
12
+ * a timeout, a broken connection and an answer that did not parse against the
13
+ * shape below are all the same thing to the gateway, and what it does about
14
+ * them depends on the card's mode rather than on the shape of anything on this
15
+ * page.
16
+ *
17
+ * One field an order has and this does not: a price question carries no test
18
+ * marker. For a card with a price check the question rides the same channel as
19
+ * the order it precedes, and it arrives looking like every other question — so
20
+ * a handler that routes test orders to a test environment, which the portal
21
+ * tells merchants they may do, has nothing to route the question by. Whether that wants a field here or is better
22
+ * answered by however the sandbox is eventually separated from live is not
23
+ * decided, and inventing the field ahead of that decision would answer it.
24
+ */
25
+ import { z } from "zod";
26
+ import { ParamNameSchema } from "./param-spec.js";
27
+ import { IdentifierSchema, MoneySchema, TimestampSchema } from "./primitives.js";
28
+ /**
29
+ * Why we are asking.
30
+ *
31
+ * `purchase` means an agent is standing at the till right now; `poll` means we
32
+ * are refreshing what we know between purchases and nobody is buying. The
33
+ * distinction is there so an expensive stock lookup can be spent on the first
34
+ * and skipped on the second.
35
+ */
36
+ export const QuotePurposeSchema = z.enum(["purchase", "poll"]);
37
+ export const QuoteRequestSchema = z.strictObject({
38
+ /** The merchant's own key for the product being asked about. */
39
+ merchant_item_id: IdentifierSchema,
40
+ /**
41
+ * The purchase parameters, where the price depends on them. Absent for a
42
+ * card that takes no input, and for a scheduled poll of such a card.
43
+ */
44
+ // Same dropped key as everywhere this contract parses free-form names; see
45
+ // `PROTOTYPE_KEY_IS_DROPPED` in `param-spec.ts`.
46
+ params: z.record(ParamNameSchema, z.unknown()).optional(),
47
+ /**
48
+ * The identifier of this question, which comes back attached to the order.
49
+ *
50
+ * It is good for one order: a merchant who set stock aside under it can
51
+ * release it when the order arrives or when the price expires. That "one
52
+ * order" is a rule the gateway keeps — no schema can see a second use of an
53
+ * identifier it is shown once.
54
+ */
55
+ price_id: IdentifierSchema,
56
+ purpose: QuotePurposeSchema,
57
+ /**
58
+ * Until when the price the merchant names will be honoured, so a merchant
59
+ * holding stock against it knows when to stop. There is no separate message
60
+ * when it passes; this moment is the whole notice.
61
+ */
62
+ expires_at: TimestampSchema,
63
+ });
64
+ /**
65
+ * The answer, in the only two shapes it has.
66
+ *
67
+ * A price and an availability of `false` cannot travel together, and neither
68
+ * can availability of `true` and no price. Both would be two answers at once:
69
+ * whichever the gateway then acted on, the merchant would have grounds to say
70
+ * it acted on the wrong one — and in the first case the sale would quietly
71
+ * fall back to the price in the card, at a price the merchant never quoted.
72
+ *
73
+ * `as_of` is on both branches because it is what separates "I went and looked"
74
+ * from "here is what was in the cache". The gateway carries that moment and
75
+ * does not weigh it: it travels into the order the handler is given and into
76
+ * the record of the sale, so whoever reconciles a charge afterwards can see how
77
+ * old the number behind it was, and nothing anywhere compares it against
78
+ * anything. A price's life runs from the moment the answer reached us rather
79
+ * than from the moment it says it was true, so an answer stamped a year ago is
80
+ * honoured exactly as long as one stamped a second ago.
81
+ */
82
+ export const QuoteResponseSchema = z.discriminatedUnion("available", [
83
+ z.strictObject({
84
+ available: z.literal(true),
85
+ price: MoneySchema,
86
+ as_of: TimestampSchema,
87
+ }),
88
+ z.strictObject({
89
+ available: z.literal(false),
90
+ as_of: TimestampSchema,
91
+ }),
92
+ ]);
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The receipt: the record left by a purchase that was paid for.
3
+ *
4
+ * It exists from the moment the money moves, which in two of the three modes
5
+ * is before the product is delivered — so a receipt has to be able to say
6
+ * "paid, delivery still running" without that being mistaken for either "you
7
+ * have it" or "you paid and never got it". A purchase that ends before any
8
+ * payment leaves no receipt at all: nothing moved, and there is nothing for it
9
+ * to be proof of. Which of the order's endings a receipt can carry is worked
10
+ * out at `ReceiptOutcomeSchema` below.
11
+ *
12
+ * The price on a receipt is the price the sale went through at, and it stays
13
+ * what it was even after the merchant's price changes.
14
+ */
15
+ import { z } from "zod";
16
+ /**
17
+ * What became of the purchase behind this receipt.
18
+ *
19
+ * The words are the order's own — a receipt saying `pending` where the order
20
+ * said `in_progress` would be two names for one state, and whichever an agent
21
+ * happened to read would look like the whole truth.
22
+ *
23
+ * The set is narrower than the order's, and the reason is what a receipt is: a
24
+ * record of a payment that executed. Work through the endings and six of the
25
+ * ten cannot reach one. `rejected`, `declined` and `expired` all close before
26
+ * any money moves. `cancelled` is the merchant leaving, which for a paid order
27
+ * is a debt and arrives here as `refund_due` instead. `delivered_unpaid` is
28
+ * the case where the merchant produced the goods and the charge came back
29
+ * failed — no payment, so no receipt to carry the outcome.
30
+ *
31
+ * `payment_unresolved` is the one worth arguing rather than asserting, because
32
+ * the purchase behind it can have a verified payment behind it and still end
33
+ * there. It is excluded, and the reason is the receipt's own job. That value
34
+ * means nobody can say whether the buyer was charged; a receipt is the
35
+ * evidence that they were. A receipt carrying it would be a proof of payment
36
+ * whose own outcome says it does not know there was a payment — the one
37
+ * artifact in this contract that cannot hold that sentence. So no receipt is
38
+ * written while the question is open. If the answer arrives and the money did
39
+ * move, the receipt is written then and carries whatever the delivery reached;
40
+ * if it did not, there was never anything to record. That is the same promise
41
+ * the portal makes to the buyer in words: we say so when we learn.
42
+ *
43
+ * That leaves four: paid and still running, paid and delivered, paid and owed
44
+ * back, paid and paid back.
45
+ *
46
+ * What this list does not say is when a receipt is written at all, and a reader
47
+ * should not infer it from here. That is the gateway's, and a gateway that
48
+ * writes one only as goods are released will only ever produce `delivered` —
49
+ * so a consumer must not read the presence of these four as a promise that a
50
+ * receipt exists for every payment that executed.
51
+ */
52
+ export declare const ReceiptOutcomeSchema: z.ZodEnum<{
53
+ delivered: "delivered";
54
+ in_progress: "in_progress";
55
+ refund_due: "refund_due";
56
+ refunded: "refunded";
57
+ }>;
58
+ export declare const ReceiptSchema: z.ZodObject<{
59
+ id: z.ZodString;
60
+ order_id: z.ZodString;
61
+ item_id: z.ZodString;
62
+ price: z.ZodObject<{
63
+ amount: z.ZodString;
64
+ currency: z.ZodString;
65
+ at: z.ZodISODateTime;
66
+ as_of: z.ZodISODateTime;
67
+ }, z.core.$strict>;
68
+ price_id: z.ZodOptional<z.ZodString>;
69
+ paid_at: z.ZodISODateTime;
70
+ outcome: z.ZodEnum<{
71
+ delivered: "delivered";
72
+ in_progress: "in_progress";
73
+ refund_due: "refund_due";
74
+ refunded: "refunded";
75
+ }>;
76
+ test: z.ZodBoolean;
77
+ }, z.core.$strict>;
78
+ export type ReceiptOutcome = z.infer<typeof ReceiptOutcomeSchema>;
79
+ export type Receipt = z.infer<typeof ReceiptSchema>;
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The receipt: the record left by a purchase that was paid for.
3
+ *
4
+ * It exists from the moment the money moves, which in two of the three modes
5
+ * is before the product is delivered — so a receipt has to be able to say
6
+ * "paid, delivery still running" without that being mistaken for either "you
7
+ * have it" or "you paid and never got it". A purchase that ends before any
8
+ * payment leaves no receipt at all: nothing moved, and there is nothing for it
9
+ * to be proof of. Which of the order's endings a receipt can carry is worked
10
+ * out at `ReceiptOutcomeSchema` below.
11
+ *
12
+ * The price on a receipt is the price the sale went through at, and it stays
13
+ * what it was even after the merchant's price changes.
14
+ */
15
+ import { z } from "zod";
16
+ import { IdentifierSchema, SalePriceSchema, TimestampSchema } from "./primitives.js";
17
+ /**
18
+ * What became of the purchase behind this receipt.
19
+ *
20
+ * The words are the order's own — a receipt saying `pending` where the order
21
+ * said `in_progress` would be two names for one state, and whichever an agent
22
+ * happened to read would look like the whole truth.
23
+ *
24
+ * The set is narrower than the order's, and the reason is what a receipt is: a
25
+ * record of a payment that executed. Work through the endings and six of the
26
+ * ten cannot reach one. `rejected`, `declined` and `expired` all close before
27
+ * any money moves. `cancelled` is the merchant leaving, which for a paid order
28
+ * is a debt and arrives here as `refund_due` instead. `delivered_unpaid` is
29
+ * the case where the merchant produced the goods and the charge came back
30
+ * failed — no payment, so no receipt to carry the outcome.
31
+ *
32
+ * `payment_unresolved` is the one worth arguing rather than asserting, because
33
+ * the purchase behind it can have a verified payment behind it and still end
34
+ * there. It is excluded, and the reason is the receipt's own job. That value
35
+ * means nobody can say whether the buyer was charged; a receipt is the
36
+ * evidence that they were. A receipt carrying it would be a proof of payment
37
+ * whose own outcome says it does not know there was a payment — the one
38
+ * artifact in this contract that cannot hold that sentence. So no receipt is
39
+ * written while the question is open. If the answer arrives and the money did
40
+ * move, the receipt is written then and carries whatever the delivery reached;
41
+ * if it did not, there was never anything to record. That is the same promise
42
+ * the portal makes to the buyer in words: we say so when we learn.
43
+ *
44
+ * That leaves four: paid and still running, paid and delivered, paid and owed
45
+ * back, paid and paid back.
46
+ *
47
+ * What this list does not say is when a receipt is written at all, and a reader
48
+ * should not infer it from here. That is the gateway's, and a gateway that
49
+ * writes one only as goods are released will only ever produce `delivered` —
50
+ * so a consumer must not read the presence of these four as a promise that a
51
+ * receipt exists for every payment that executed.
52
+ */
53
+ export const ReceiptOutcomeSchema = z.enum(["in_progress", "delivered", "refund_due", "refunded"]);
54
+ export const ReceiptSchema = z.strictObject({
55
+ /**
56
+ * The receipt's own identifier. In the modes where the payment goes first,
57
+ * this is what an agent repeats a purchase by.
58
+ */
59
+ id: IdentifierSchema,
60
+ /** The order this purchase produced. */
61
+ order_id: IdentifierSchema,
62
+ /** Our catalog identifier for the card that was bought. */
63
+ item_id: IdentifierSchema,
64
+ /** The price the sale went through at, with the moment behind it. */
65
+ price: SalePriceSchema,
66
+ /** The price question the sale came out of, absent when there was none. */
67
+ price_id: IdentifierSchema.optional(),
68
+ /**
69
+ * When the payment executed — which is neither of the moments in `price`. In
70
+ * the synchronous mode the payment is the last step, after the delivery, and
71
+ * on a card with a price check the agent can spend as long as it likes
72
+ * between the price being struck and paying it, so folding any two of the
73
+ * three together would misdate one of them.
74
+ */
75
+ paid_at: TimestampSchema,
76
+ outcome: ReceiptOutcomeSchema,
77
+ /**
78
+ * Whether the money behind this receipt was real. A receipt is proof of
79
+ * payment, and an unmarked receipt for a test purchase is proof of a payment
80
+ * that never happened.
81
+ */
82
+ test: z.boolean(),
83
+ });
@@ -0,0 +1,230 @@
1
+ /**
2
+ * What our calls hand back — the successes as well as the failures.
3
+ *
4
+ * None of it travels as an exception. A merchant's integration code has to
5
+ * read these, branch on them and write some of them down, and an exception is
6
+ * the wrong shape for something you are expected to handle rather than to be
7
+ * surprised by. That is a rule about the whole surface, which is why publishing
8
+ * a card and answering for an order share a file even though they are
9
+ * different calls.
10
+ *
11
+ * The words below are wire names, not prose: a merchant's code branches on
12
+ * them, so rewording one is changing the contract.
13
+ *
14
+ * Every one of those answers arrives in one envelope. `ok` is `true` or it is
15
+ * `false` and nothing else says which; a success carries its own fields beside
16
+ * it, and a failure carries `error`. That `ok` is a value and not a key that
17
+ * may or may not be present is the part worth arguing, because the two look
18
+ * alike from inside TypeScript and do not behave alike anywhere else. A key
19
+ * with an object under it reads as false in Python and in PHP — `{"ok": {}}`
20
+ * is falsy in both — so the one idiom an engineer would write says yes to one
21
+ * answer and no to another, and the JSON Schema export exists for exactly that
22
+ * engineer. As a literal it is also a discriminator: it crosses into the export
23
+ * as a `const` on each branch, which a generator can switch on, where
24
+ * "whichever key happens to be present" is something a reader has to work out.
25
+ *
26
+ * Two words carry what went wrong, and they are not two names for one thing.
27
+ * `error` is why a call did not go through: one object, always, with a code to
28
+ * branch on, a sentence to print, and a flag saying whether repeating the call
29
+ * could change the outcome. `problems` is the list of findings about what was
30
+ * sent — the fields at fault — and it rides inside `error` wherever there are
31
+ * any. A call fails for one reason; a document can be wrong in several places
32
+ * at once, and that is the whole of the difference between the singular and the
33
+ * plural here.
34
+ */
35
+ import { z } from "zod";
36
+ /**
37
+ * How answering for an order can succeed.
38
+ *
39
+ * "Answering" rather than "delivering or refusing", because two of these reach
40
+ * us from a third surface — a handler's own return — rather than from either
41
+ * call. `accepted` is how an asynchronous handler answers while the delivery
42
+ * is still ahead of it, and `purchase_already_closed` belongs to the
43
+ * synchronous mode, where neither `deliver` nor `refuse` exists at all, as the
44
+ * error code `not_applicable_in_mode` says from the other direction.
45
+ *
46
+ * Each one is a different thing for the merchant to do next, which is why none
47
+ * of them collapses into another. `accepted` is a handler taking the order on: the
48
+ * goods are owed and will follow through the separate `deliver` call, and the
49
+ * merchant's own record of the order should say it is under way. It is a
50
+ * success and belongs among these rather than among the error codes, and that
51
+ * placement is the whole of what it does for a merchant: every handler answer
52
+ * is posted to the answer route by the SDK without being asked to, and an
53
+ * integration that reads anything but a success as trouble would otherwise
54
+ * open a case on every asynchronous order it sells.
55
+ *
56
+ * `delivered` is the sale closing. `already_delivered` is their own retry
57
+ * landing twice — safe, and no second delivery is wanted.
58
+ *
59
+ * That one is worth a warning, because the merchant-facing pages say a
60
+ * repeated call returns "the same success" and this returns a different word
61
+ * for it. Both are true of the effect — nothing is delivered twice and nothing
62
+ * is charged twice — but a merchant who reads that sentence and writes
63
+ * `if (result === "delivered")` turns their own safe retry into a failure
64
+ * branch. The answer these words travel in is built so that nobody has to: a
65
+ * consumer branches on `ok` and records the word, which stays right when this
66
+ * list grows another entry.
67
+ *
68
+ * One kind of consumer it does not stay right for, said here because the list
69
+ * has grown once already and will again. A client that checks the answer
70
+ * against its own copy of this schema — our own SDK does, and so does anything
71
+ * generated from the JSON Schema export — reads an unknown word as a document
72
+ * it cannot parse rather than as a success it cannot name, and reports the
73
+ * call as having gone wrong. So a word added here has to reach those clients
74
+ * before the gateway starts sending it. The version handshake would be the
75
+ * place to catch that. The published SDK keeps this schema strict, and every
76
+ * new word moves `CONTRACT_VERSION` before the gateway sends it. An old worker
77
+ * then stops at its version handshake rather than calling a successful answer
78
+ * unreadable after the merchant has already acted on it (ADR-0006).
79
+ *
80
+ * `debt_closed_by_delivery` says the delivery deadline had already passed and
81
+ * the goods went out anyway, closing a debt instead of completing a sale; the
82
+ * merchant may want to know that happened. `refused` is the refusal taking
83
+ * effect. `purchase_already_closed` is the synchronous handler that came back
84
+ * after its deadline: not an error, because nothing went wrong on their side —
85
+ * the work exists and a repeat purchase will collect it, and the only thing to
86
+ * do is write the case down.
87
+ */
88
+ export declare const ORDER_CALL_RESULTS: readonly ["accepted", "delivered", "already_delivered", "debt_closed_by_delivery", "refused", "purchase_already_closed"];
89
+ export declare const OrderCallResultSchema: z.ZodEnum<{
90
+ refused: "refused";
91
+ delivered: "delivered";
92
+ accepted: "accepted";
93
+ already_delivered: "already_delivered";
94
+ debt_closed_by_delivery: "debt_closed_by_delivery";
95
+ purchase_already_closed: "purchase_already_closed";
96
+ }>;
97
+ /**
98
+ * The error codes those calls answer with.
99
+ *
100
+ * A list of what we promise to mean the same way, not a gate: the code below
101
+ * stays an open string, because an error nobody anticipated has to reach the
102
+ * merchant in its own words rather than be flattened into the nearest of
103
+ * three. `refund_already_settled` — the debt was paid back, so there is
104
+ * nothing left to deliver against. `order_already_closed` — the order reached
105
+ * an ending that no call reopens. `not_applicable_in_mode` — the call does not
106
+ * exist for this card's mode, as refusing separately does not in the
107
+ * synchronous one, where the handler's own answer is the refusal.
108
+ * `delivery_does_not_match_card` — the goods are not the ones the card for
109
+ * this order declares it delivers, so nothing was written down; the message
110
+ * says whether the order still stands or has already ended, and the fields
111
+ * that did not fit are named one by one in the error's `problems`.
112
+ *
113
+ * The fourth is the only one of them a merchant fixes rather than records, and
114
+ * it is the reason it is promised rather than left to the open set. It is
115
+ * marked retryable where the order is still open, and that retry is not the
116
+ * same retry the other three mean: those say "the call may not have reached
117
+ * us, send it again", while this says the call arrived and was understood and
118
+ * the goods in it were wrong. Sending the same delivery again produces the
119
+ * same refusal until the goods change, and a merchant told only "retryable"
120
+ * would loop on it — which is why the code is named and the message says which
121
+ * field is wrong.
122
+ *
123
+ * On an order that has already ended it is not retryable, and the message says
124
+ * the ending. The goods being wrong and the sale being over are both true
125
+ * there, and only the second decides what he can do next: told the order still
126
+ * stood, a merchant would make the goods a second time for a purchase nobody
127
+ * can complete.
128
+ *
129
+ * Adding to this list is safe in a way that adding a success word is not: the
130
+ * code is an open string on the wire, so an older client parses an unfamiliar
131
+ * one and reads it as the failure it is. What it loses is the meaning, which is
132
+ * what this list and the dictionary below carry.
133
+ */
134
+ export declare const ORDER_CALL_ERROR_CODES: readonly ["refund_already_settled", "order_already_closed", "not_applicable_in_mode", "delivery_does_not_match_card"];
135
+ /**
136
+ * One thing wrong with what was sent, in a place, in a code and in words.
137
+ *
138
+ * This is one finding and never a whole answer. Wherever a call refuses what it
139
+ * was handed, the findings travel as a list of these under `problems` inside
140
+ * the error: a card that could not be published names every field standing
141
+ * between it and the catalog, a delivery that is not what its card declares
142
+ * names the fields that did not fit, and the local check a merchant runs before
143
+ * publishing — `checkCard` in the SDK — answers in this same shape, so a
144
+ * finding read on their own machine and a finding read off the wire need no
145
+ * two readers.
146
+ *
147
+ * The empty path is the part two readers were left to infer differently, so it
148
+ * is said in the exported description as well as here.
149
+ */
150
+ export declare const ProblemSchema: z.ZodObject<{
151
+ path: z.ZodArray<z.ZodString>;
152
+ code: z.ZodString;
153
+ message: z.ZodString;
154
+ }, z.core.$strict>;
155
+ /**
156
+ * Why a call did not go through: a code to branch on, a sentence to print, and
157
+ * whether repeating it could change the outcome.
158
+ *
159
+ * One shape for every call on the merchant's surface. Publishing a card and
160
+ * delivering an order fail for entirely different reasons, and a merchant who
161
+ * had to learn two shapes for "this did not happen" would be learning the same
162
+ * lesson twice.
163
+ *
164
+ * The flag is the reason this shape exists at all. "The connection dropped,
165
+ * call again — the call is idempotent" and "nothing you do will change this,
166
+ * write the case down" need different code on the merchant's side, and a
167
+ * merchant left to guess turns one of them into a retry loop and the other into
168
+ * an order nobody comes back to. The refund that has already been paid out is
169
+ * the example of the second kind. It is required rather than defaulted for the
170
+ * same reason: both readings of a missing flag are expensive.
171
+ *
172
+ * `problems` is present where the call is refusing what it was handed rather
173
+ * than reporting a state of the world, and it is the field that turns "no" into
174
+ * an edit. It is optional because most failures have nothing to point at: a
175
+ * refund already settled is about the order and not about a field of the
176
+ * request. Where it is there it is never empty, and a call whose whole answer
177
+ * is "refused, and here is nothing" — a publish — requires it.
178
+ */
179
+ export declare const CallErrorSchema: z.ZodObject<{
180
+ code: z.ZodString;
181
+ message: z.ZodString;
182
+ retryable: z.ZodBoolean;
183
+ problems: z.ZodOptional<z.ZodArray<z.ZodObject<{
184
+ path: z.ZodArray<z.ZodString>;
185
+ code: z.ZodString;
186
+ message: z.ZodString;
187
+ }, z.core.$strict>>>;
188
+ }, z.core.$strict>;
189
+ /**
190
+ * The code a refused publish comes back under.
191
+ *
192
+ * Promised rather than left to the open set, because it is the one refusal of
193
+ * this surface a merchant meets on their first afternoon, and every one of them
194
+ * writes the branch that reads it.
195
+ */
196
+ export declare const CARD_REJECTED = "card_rejected";
197
+ /**
198
+ * The answer to publishing a card: the catalog id, or what stands in its way.
199
+ *
200
+ * `ok` says which, as it does on every other call of this surface, and the
201
+ * catalog identifier sits at the top level of the success beside it rather than
202
+ * nested under a word. There is one fact in a successful publish and this is
203
+ * it.
204
+ *
205
+ * The refusal is `CARD_REJECTED` and it is not retryable: publishing the same
206
+ * card again gets the same answer, and what changes the outcome is fixing what
207
+ * the findings name. That is a different thing from the retry a dropped
208
+ * connection asks for, which is why the flag says no here rather than being
209
+ * left for the merchant to infer from the code.
210
+ */
211
+ export declare const PublishResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
212
+ ok: z.ZodLiteral<true>;
213
+ id: z.ZodString;
214
+ }, z.core.$strict>, z.ZodObject<{
215
+ ok: z.ZodLiteral<false>;
216
+ error: z.ZodObject<{
217
+ code: z.ZodString;
218
+ message: z.ZodString;
219
+ retryable: z.ZodBoolean;
220
+ problems: z.ZodArray<z.ZodObject<{
221
+ path: z.ZodArray<z.ZodString>;
222
+ code: z.ZodString;
223
+ message: z.ZodString;
224
+ }, z.core.$strict>>;
225
+ }, z.core.$strict>;
226
+ }, z.core.$strict>], "ok">;
227
+ export type Problem = z.infer<typeof ProblemSchema>;
228
+ export type PublishResult = z.infer<typeof PublishResultSchema>;
229
+ export type OrderCallResult = z.infer<typeof OrderCallResultSchema>;
230
+ export type CallError = z.infer<typeof CallErrorSchema>;