@openrails/billing-ui 0.230.0 → 0.234.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/CHANGELOG.md +117 -9
- package/README.md +88 -39
- package/dist/account/account-billing.d.ts +3 -3
- package/dist/account/cancel-dialog.d.ts +2 -2
- package/dist/account/format.d.ts +4 -4
- package/dist/account/payment-methods-panel.d.ts +7 -9
- package/dist/account/section.d.ts +3 -1
- package/dist/checkout-page.d.ts +6 -1
- package/dist/client/client.d.ts +81 -62
- package/dist/client/generated/currencies.d.ts +1 -0
- package/dist/client/generated/error-codes.d.ts +7 -0
- package/dist/client/generated/routes.d.ts +764 -0
- package/dist/client/generated/wire.d.ts +772 -0
- package/dist/client/index.d.ts +3 -3
- package/dist/client/types.d.ts +498 -393
- package/dist/client-CWX6QpLa.js +920 -0
- package/dist/client-CWX6QpLa.js.map +1 -0
- package/dist/client.js +2 -3
- package/dist/components/methods.d.ts +3 -3
- package/dist/config-DZ97SQG2.js +341 -0
- package/dist/config-DZ97SQG2.js.map +1 -0
- package/dist/frame.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1447 -1539
- package/dist/index.js.map +1 -1
- package/dist/lib/billing.d.ts +14 -0
- package/dist/lib/money.d.ts +1 -0
- package/dist/lib/period.d.ts +0 -2
- package/dist/lib/rail-meta.d.ts +4 -4
- package/dist/locales/de.js +11 -8
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/en.d.ts +8 -5
- package/dist/locales/en.js +11 -8
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +11 -8
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/ja.js +11 -8
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +11 -8
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/zh.js +11 -8
- package/dist/locales/zh.js.map +1 -1
- package/dist/psp.d.ts +10 -21
- package/dist/react/config.d.ts +34 -0
- package/dist/react/context.d.ts +5 -8
- package/dist/react/hooks.d.ts +20 -14
- package/dist/react/index.d.ts +1 -0
- package/dist/react/provider.d.ts +1 -9
- package/dist/react/remote.d.ts +0 -1
- package/dist/react.js +24 -28
- package/dist/react.js.map +1 -1
- package/dist/save-payment-method.d.ts +1 -1
- package/dist/source.d.ts +0 -9
- package/dist/styles.css +1 -1
- package/dist/types.d.ts +114 -55
- package/docs/payment-form-contract.md +23 -40
- package/package.json +3 -3
- package/dist/client/generated/openrails-routes.d.ts +0 -2
- package/dist/client-DhG2jv34.js +0 -771
- package/dist/client-DhG2jv34.js.map +0 -1
- package/dist/errors-T-PRm3vV.js +0 -54
- package/dist/errors-T-PRm3vV.js.map +0 -1
- package/dist/hooks-DLFF-zx5.js +0 -285
- package/dist/hooks-DLFF-zx5.js.map +0 -1
- package/docs/1055-nmi-host-integration.md +0 -28
package/dist/client/client.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CheckoutSource } from '../source';
|
|
2
|
-
import {
|
|
2
|
+
import { Account, CardSetup, CheckoutSessionLink, PublicConfig, PaymentAuthentication, CurrencyScales, Invoice, ListPage, NewCard, NextAction, Page, Payment, PaymentMethod, Product, SolanaToken, Subscription, TierChange, TierChangePreview } from './types';
|
|
3
3
|
export interface BillingClientOptions {
|
|
4
4
|
/** OpenRails embedded mount. Default "/billing/v1". */
|
|
5
5
|
baseUrl?: string;
|
|
@@ -18,12 +18,29 @@ export interface BillingClientOptions {
|
|
|
18
18
|
*/
|
|
19
19
|
currencies?: CurrencyScales;
|
|
20
20
|
}
|
|
21
|
+
export interface CheckoutSourceOptions {
|
|
22
|
+
/**
|
|
23
|
+
* A customer surface's base: its `/me` prefix, such as `/billing/v1/me` or
|
|
24
|
+
* a host's own `/api/v1/merchants/acme/billing/me`. The session is read and
|
|
25
|
+
* paid there with this client's credential, which proves the session's
|
|
26
|
+
* customer, so its saved cards pay. Default: the session id alone, at
|
|
27
|
+
* `{baseUrl}/checkout-sessions`.
|
|
28
|
+
*/
|
|
29
|
+
customerBase?: string;
|
|
30
|
+
}
|
|
21
31
|
export interface ListOptions {
|
|
22
32
|
limit?: number;
|
|
23
33
|
offset?: number;
|
|
34
|
+
/** A cursor list's next page: the previous page's `next_cursor`. */
|
|
35
|
+
cursor?: string;
|
|
36
|
+
signal?: AbortSignal;
|
|
37
|
+
}
|
|
38
|
+
/** A cursor list read: pass the previous page's `next_cursor` for the next. */
|
|
39
|
+
export interface CursorOptions {
|
|
40
|
+
limit?: number;
|
|
41
|
+
cursor?: string | null;
|
|
24
42
|
signal?: AbortSignal;
|
|
25
43
|
}
|
|
26
|
-
export type SolanaCancelStage = "preparing" | "signing" | "confirming";
|
|
27
44
|
/**
|
|
28
45
|
* Signs and submits a base64 transaction with the customer's wallet and
|
|
29
46
|
* returns its signature. Throw `WalletRejectedError` when the user declines.
|
|
@@ -32,27 +49,39 @@ export type SendSolanaTransaction = (transactionBase64: string) => Promise<strin
|
|
|
32
49
|
export declare class WalletRejectedError extends Error {
|
|
33
50
|
constructor(message?: string);
|
|
34
51
|
}
|
|
35
|
-
export declare const
|
|
36
|
-
export declare const
|
|
52
|
+
export declare const CANCEL_REASON_MIN = 4;
|
|
53
|
+
export declare const CANCEL_REASON_MAX = 500;
|
|
54
|
+
/** A next action the customer's wallet completes. */
|
|
55
|
+
export declare const isWalletAction: (next: NextAction | null | undefined) => boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Signs and sends a `solana_sign_transactions` next action's transactions in
|
|
58
|
+
* order and returns the last signature, the value the action is repeated
|
|
59
|
+
* with. A declined prompt is a local `wallet_rejected` error.
|
|
60
|
+
*/
|
|
61
|
+
export declare function signWalletAction(next: NextAction, sendTransaction: SendSolanaTransaction): Promise<string>;
|
|
37
62
|
/** Total wait a GET may spend on its one retry. */
|
|
38
63
|
export declare const RETRY_BUDGET_MS = 2000;
|
|
39
64
|
export declare function createBillingClient(options?: BillingClientOptions): {
|
|
40
65
|
baseUrl: string;
|
|
41
|
-
|
|
66
|
+
/** One page of the customer's subscriptions, newest first. */
|
|
67
|
+
listSubscriptions(opts?: CursorOptions & {
|
|
42
68
|
status?: string;
|
|
43
|
-
}): Promise<
|
|
69
|
+
}): Promise<ListPage<Subscription>>;
|
|
44
70
|
/** Includes `recovery` (list rows do not). */
|
|
45
71
|
getSubscription(subscriptionId: string, signal?: AbortSignal): Promise<Subscription>;
|
|
46
72
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
73
|
+
* Cancels at period end and answers the subscription. When the rail needs
|
|
74
|
+
* the customer's step (`next_action`, a Solana wallet signature), the
|
|
75
|
+
* subscription is unchanged: complete it with `signWalletAction` and
|
|
76
|
+
* repeat with `signature`.
|
|
49
77
|
*/
|
|
50
78
|
cancelSubscription(subscriptionId: string, input: {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
79
|
+
reason: string;
|
|
80
|
+
signature?: string;
|
|
81
|
+
}): Promise<Subscription>;
|
|
82
|
+
/** Undoes a scheduled cancel before the period ends. */
|
|
83
|
+
resumeSubscription(subscriptionId: string): Promise<Subscription>;
|
|
84
|
+
setSubscriptionPaymentMethod(subscriptionId: string, paymentMethodId: string): Promise<Subscription>;
|
|
56
85
|
/** What `changeTier` would charge now and at the next renewal. */
|
|
57
86
|
previewTierChange(subscriptionId: string, priceId: string, signal?: AbortSignal): Promise<TierChangePreview>;
|
|
58
87
|
/**
|
|
@@ -60,35 +89,19 @@ export declare function createBillingClient(options?: BillingClientOptions): {
|
|
|
60
89
|
* charges the saved card now, a downgrade applies at period end.
|
|
61
90
|
* `idempotencyKey` identifies this attempt; reuse it until the change
|
|
62
91
|
* resolves (`processing`, a `tier_change_in_flight` refusal or a lost
|
|
63
|
-
* response) so the stored result replays instead of charging twice.
|
|
92
|
+
* response) so the stored result replays instead of charging twice. A
|
|
93
|
+
* wallet next action (Solana) is completed with `signWalletAction` and
|
|
94
|
+
* the change repeated with `signature`.
|
|
64
95
|
*/
|
|
65
96
|
changeTier(subscriptionId: string, input: {
|
|
66
97
|
priceId: string;
|
|
67
98
|
idempotencyKey: string;
|
|
99
|
+
signature?: string;
|
|
68
100
|
}): Promise<TierChange>;
|
|
101
|
+
listPaymentMethods(opts?: CursorOptions): Promise<ListPage<PaymentMethod>>;
|
|
69
102
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*/
|
|
73
|
-
prepareSolanaTierChange(subscriptionId: string, newPriceId: string): Promise<SolanaTierChangeTx>;
|
|
74
|
-
/**
|
|
75
|
-
* Records the landed transaction. Keep the signature until this succeeds:
|
|
76
|
-
* confirming it again replays the result (`already_confirmed`).
|
|
77
|
-
*/
|
|
78
|
-
confirmSolanaTierChange(subscriptionId: string, input: {
|
|
79
|
-
signature: string;
|
|
80
|
-
newPriceId: string;
|
|
81
|
-
}): Promise<SolanaTierChange>;
|
|
82
|
-
/**
|
|
83
|
-
* On-chain cancellation for the solana rail: the server prepares an
|
|
84
|
-
* unsigned transaction, the wallet signs and submits it, the server
|
|
85
|
-
* verifies the signature and records the cancel.
|
|
86
|
-
*/
|
|
87
|
-
cancelSubscriptionOnChain(subscriptionId: string, sendTransaction: SendSolanaTransaction, onStage?: (stage: SolanaCancelStage) => void): Promise<void>;
|
|
88
|
-
listPaymentMethods(opts?: ListOptions): Promise<Page<PaymentMethod>>;
|
|
89
|
-
/**
|
|
90
|
-
* Stores a card entered in the page: a Collect.js token
|
|
91
|
-
* (`cardSetupDriver` "collect_js") or the card itself ("card").
|
|
103
|
+
* Stores a card entered in the page with the PSP `psp_id`: a Collect.js
|
|
104
|
+
* token (`cardSetupDriver` "collect_js") or the card itself ("card").
|
|
92
105
|
*/
|
|
93
106
|
addPaymentMethod(card: NewCard): Promise<PaymentMethod>;
|
|
94
107
|
/**
|
|
@@ -107,56 +120,62 @@ export declare function createBillingClient(options?: BillingClientOptions): {
|
|
|
107
120
|
confirmPaymentAuthentication(operationId: string): Promise<void>;
|
|
108
121
|
/** `pending` when the provider is still converging (202). */
|
|
109
122
|
removePaymentMethod(paymentMethodId: string): Promise<"removed" | "pending">;
|
|
110
|
-
/** Makes the
|
|
111
|
-
|
|
123
|
+
/** Makes the card the one that collects one currency's invoices. */
|
|
124
|
+
setCollectionPaymentMethod(input: {
|
|
112
125
|
currency: string;
|
|
113
126
|
paymentMethodId: string;
|
|
114
127
|
}): Promise<void>;
|
|
115
128
|
/** Charges and refunds, newest first. `rail` filters by rail. */
|
|
116
|
-
listPayments(opts?:
|
|
129
|
+
listPayments(opts?: CursorOptions & {
|
|
117
130
|
rail?: string;
|
|
118
|
-
}): Promise<
|
|
119
|
-
listInvoices(opts?:
|
|
131
|
+
}): Promise<ListPage<Payment>>;
|
|
132
|
+
listInvoices(opts?: CursorOptions): Promise<ListPage<Invoice>>;
|
|
133
|
+
/**
|
|
134
|
+
* The customer's summary: balance and amount owed per currency, the card
|
|
135
|
+
* that pays each currency, and unread notices.
|
|
136
|
+
*/
|
|
137
|
+
getAccount(signal?: AbortSignal): Promise<Account>;
|
|
120
138
|
getInvoice(invoiceId: string, signal?: AbortSignal): Promise<Invoice>;
|
|
121
|
-
|
|
122
|
-
/** Active products with their active prices. */
|
|
139
|
+
/** Products on sale, each with its current prices. */
|
|
123
140
|
listProducts(opts?: ListOptions): Promise<Page<Product>>;
|
|
124
|
-
/** Active prices. `product` is a `prod_` id; `type` is `recurring | one_time`. */
|
|
125
|
-
listPrices(opts?: ListOptions & {
|
|
126
|
-
currency?: string;
|
|
127
|
-
product?: string;
|
|
128
|
-
type?: string;
|
|
129
|
-
}): Promise<Page<Price>>;
|
|
130
|
-
/** The server's currency registry; `currencies` is the pinned copy. */
|
|
131
|
-
listCurrencies(signal?: AbortSignal): Promise<Currency[]>;
|
|
132
141
|
/**
|
|
133
142
|
* Mints a hosted checkout session for the signed-in customer and one
|
|
134
143
|
* price. Render it with `<CheckoutFrame url>` when the session has a
|
|
135
144
|
* `url`, else with `<Checkout source={client.checkoutSource(id)}>`.
|
|
145
|
+
* Select a price by `priceId`, or by both `productKey` and `priceKey`.
|
|
136
146
|
* `successUrl` brings the buyer back from a redirect rail; it must be on
|
|
137
147
|
* one of this app's return origins.
|
|
138
148
|
*/
|
|
139
149
|
createCheckoutSession(input: {
|
|
140
150
|
priceKey?: string;
|
|
151
|
+
productKey?: string;
|
|
141
152
|
priceId?: string;
|
|
153
|
+
/** Customer-selected deposit in the price currency’s native units. */
|
|
154
|
+
amount?: string;
|
|
155
|
+
/** Defaults to true for recurring prices; false buys the initial term only. */
|
|
156
|
+
autoRenew?: boolean;
|
|
142
157
|
successUrl?: string;
|
|
143
|
-
}): Promise<
|
|
158
|
+
}): Promise<CheckoutSessionLink>;
|
|
159
|
+
/**
|
|
160
|
+
* Reads and pays one hosted checkout session. By default the id is the
|
|
161
|
+
* only credential: no bearer is sent. With `customerBase` the session's
|
|
162
|
+
* customer reads and pays it on that customer surface, signed in. A
|
|
163
|
+
* refusal the buyer can answer (an invalid card form, too many attempts)
|
|
164
|
+
* resolves as `failed`; an expired or unknown session as `expired`.
|
|
165
|
+
*/
|
|
166
|
+
checkoutSource(sessionId: string, opts?: CheckoutSourceOptions): CheckoutSource;
|
|
144
167
|
/**
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
* or unknown session as `expired`.
|
|
168
|
+
* The deployment's public configuration: what the mount serves, the
|
|
169
|
+
* currency registry and the merchant's payment setup. React components
|
|
170
|
+
* share one copy through `useConfig()`.
|
|
149
171
|
*/
|
|
150
|
-
|
|
151
|
-
/** Network and accepted tokens; served only with a Solana PSP. */
|
|
152
|
-
getSolanaConfig(signal?: AbortSignal): Promise<SolanaConfig>;
|
|
172
|
+
getConfig(signal?: AbortSignal): Promise<PublicConfig>;
|
|
153
173
|
/**
|
|
154
|
-
* Accepted tokens with live prices. `priceId`
|
|
155
|
-
*
|
|
174
|
+
* Accepted tokens with live prices. `priceId` adds each token's `quote`;
|
|
175
|
+
* `wallet` adds its `balance`.
|
|
156
176
|
*/
|
|
157
177
|
listSolanaTokens(opts?: {
|
|
158
178
|
priceId?: string;
|
|
159
|
-
checkoutSessionId?: string;
|
|
160
179
|
wallet?: string;
|
|
161
180
|
signal?: AbortSignal;
|
|
162
181
|
}): Promise<SolanaToken[]>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const OPENRAILS_CURRENCY_SCALES: Readonly<Record<string, number>>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type OpenRailsErrorCode = "access_token_invalid" | "access_token_issuer_unknown" | "access_token_merchant_not_bound" | "admission_captured" | "admission_not_found" | "allowance_meter_not_found" | "allowance_source_in_use" | "allowance_source_invalid" | "already_owned" | "api_host_claim_missing" | "api_host_reserved" | "api_host_taken" | "api_host_unproven" | "as_of_required" | "authentication_required" | "authentication_unavailable" | "authorization_unavailable" | "billing_archive_integrity" | "billing_archive_invalid_artifact" | "billing_archive_merchant_mismatch" | "billing_archive_not_empty" | "billing_archive_unavailable" | "billing_archive_unsupported_state" | "billing_policy_not_found" | "cancel_unsupported_on_rail" | "captcha_invalid" | "captcha_required" | "card_attempts_blocked" | "card_declined" | "card_not_saved" | "card_requires_https" | "catalog_benefit_overlap" | "catalog_revision_conflict" | "catalog_updates_disabled" | "checkout_attempt_closed" | "checkout_attempt_expired" | "checkout_offer_unavailable" | "checkout_payment_in_progress" | "checkout_request_invalid" | "checkout_session_expired" | "checkout_session_not_found" | "checkout_session_unavailable" | "collection_payment_method_invalid" | "collection_payment_method_required" | "creation_refused" | "credential_custody_transition_required" | "credential_expired" | "credential_identity_mismatch" | "credential_operation_conflict" | "credential_revoked" | "credential_source_read_only" | "credential_store_read_only" | "credentials_manage_required" | "credit_grant_held" | "credit_grant_not_found" | "credit_grant_unavailable" | "csrf_origin_denied" | "currency_unsupported" | "custodian_capture_unavailable" | "customer_action_required" | "customer_email_required" | "customer_not_found" | "customer_payment_unsupported" | "customer_proof_required" | "customer_session_required" | "dashboard_invalid" | "database_busy" | "default_rate_card_not_found" | "default_rate_card_required" | "delegated_principal_invalid" | "email_unverified" | "finding_action_failed" | "finding_not_actionable" | "hold_not_found" | "host_event_not_found" | "host_merchant_mismatch" | "host_principal_invalid" | "idempotency_key_in_use" | "idempotency_key_required" | "idempotency_key_reused" | "insufficient_credits" | "insufficient_funds" | "insufficient_scope" | "internal_error" | "invalid_api_host" | "invalid_cursor" | "invalid_customer_id" | "invalid_email" | "invalid_host_event_request" | "invalid_name" | "invalid_param" | "invalid_payment_method" | "invalid_psp_reference" | "invalid_query" | "invalid_request_body" | "invalid_settlement_status_request" | "invalid_user" | "invites_disabled" | "invoice_action_not_allowed" | "invoice_not_retryable" | "invoice_retry_idempotency_conflict" | "invoice_retry_in_progress" | "invoice_retry_outcome_unknown" | "invoker_scoped_principal" | "last_owner" | "members_manage_required" | "merchant_binding_mismatch" | "merchant_configuration_application_conflict" | "merchant_configuration_revision_conflict" | "merchant_context_mismatch" | "merchant_creation_payment_method_required" | "merchant_directory_unavailable" | "merchant_not_found" | "merchant_selector_invalid" | "merchant_unresolved" | "meter_in_use" | "meter_rate_card_conflict" | "method_not_allowed" | "metrics_query_invalid" | "model_unavailable" | "name_reserved" | "name_taken" | "order_has_recurring_line" | "order_line_unavailable" | "order_not_cancelable" | "order_not_payable" | "order_payment_in_progress" | "order_total_changed" | "payment_duplicate_refused" | "payment_exceeds_due" | "payment_failed" | "payment_idempotency_conflict" | "payment_in_progress" | "payment_method_delete_failed" | "payment_method_delete_unsupported" | "payment_method_not_psp_vaulted" | "payment_method_not_usable" | "payment_method_psp_mismatch" | "payment_method_required" | "payment_method_same_vault" | "payment_method_stale" | "payment_method_update_failed" | "payment_method_update_retry_required" | "payment_method_update_unsupported" | "payment_not_found" | "payment_not_refundable" | "payment_not_retryable" | "payment_option_unavailable" | "payment_provider_rejected" | "permission_required" | "price_change_currency_mismatch" | "price_change_target_archived" | "price_increase_notice_too_short" | "price_key_cadence_conflict" | "price_key_not_found" | "price_migration_not_found" | "price_not_found" | "price_not_sellable" | "product_not_found" | "product_tier_group_conflict" | "product_tier_group_in_use" | "provider_billing_observation_conflict" | "provider_cancel_held" | "provider_operation_conflict" | "provider_operation_has_billing_evidence" | "provider_operation_not_found" | "provider_operation_not_open" | "provider_operation_not_refused" | "provider_operation_refused" | "provider_outcome_unknown" | "psp_claim_requires_proof" | "psp_credentials_rejected" | "psp_exists" | "psp_key_taken" | "psp_last_active" | "psp_not_found" | "purchase_review_resolved" | "quantity_not_allowed" | "rate_card_currency_mismatch" | "rate_card_has_overrides" | "rate_card_product_not_found" | "rate_limit_exceeded" | "rebill_terms_committed" | "refund_failed" | "refund_rail_unavailable" | "refund_unsupported" | "rename_too_soon" | "renames_disabled" | "request_body_too_large" | "resource_access_denied" | "resource_conflict" | "resource_not_found" | "role_escalation" | "route_not_found" | "scheduled_change_exists" | "sender_proof_required" | "service_credential_customer_scope_denied" | "service_credential_invalid" | "service_credential_merchant_unresolved" | "service_credential_resource_scope_denied" | "service_unavailable" | "solana_rpc_unavailable" | "solana_transaction_refused" | "spend_delegation_not_found" | "step_up_required" | "step_up_unavailable" | "subscription_not_active" | "subscription_not_found" | "subscription_paid_through" | "subscription_resumable" | "tier_change_already_scheduled" | "tier_change_cadence_unsupported" | "tier_change_credit_exceeds_price" | "tier_change_cycle_unknown" | "tier_change_idempotency_conflict" | "tier_change_idempotency_key_required" | "tier_change_in_flight" | "tier_change_period_unknown" | "tier_change_provider_conflict" | "tier_change_refused" | "tier_change_renewal_due" | "tier_change_requires_linked_plan" | "tier_change_target_inactive" | "tier_change_unsupported_on_rail" | "trial_unsupported_on_rail" | "unknown_field" | "unknown_role" | "unsupported_media_type" | "usage_meter_invalid" | "usage_meter_not_found" | "usage_rate_card_invalid" | "use_dpop_nonce" | "webhook_account_mismatch" | "webhook_invalid" | "widget_generation_invalid";
|
|
2
|
+
export type OpenRailsErrorType = "api_error" | "authentication_error" | "authorization_error" | "card_error" | "invalid_request_error" | "rate_limit_error";
|
|
3
|
+
export declare const OPENRAILS_ERROR_CODES: Readonly<Record<OpenRailsErrorCode, {
|
|
4
|
+
status: number;
|
|
5
|
+
type: OpenRailsErrorType;
|
|
6
|
+
meaning: string;
|
|
7
|
+
}>>;
|