@saasicat/core 1.0.0-rc.16 → 1.0.0-rc.18
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/.build-stamp +1 -1
- package/dist/index.cjs +128 -2
- package/dist/index.d.cts +635 -211
- package/dist/index.d.ts +635 -211
- package/dist/index.js +122 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -599,7 +599,10 @@ var SUBSCRIBER_ERROR_CODES = {
|
|
|
599
599
|
SUBSCRIBER_ALREADY_EXISTS: "SUBSCRIBER_ALREADY_EXISTS",
|
|
600
600
|
SUBSCRIBER_NOT_FOUND: "SUBSCRIBER_NOT_FOUND",
|
|
601
601
|
SUBSCRIBER_LEGAL_NAME_REQUIRED: "SUBSCRIBER_LEGAL_NAME_REQUIRED",
|
|
602
|
-
/**
|
|
602
|
+
/**
|
|
603
|
+
* A detail that has a form — the country, the invoice email — is not in it,
|
|
604
|
+
* or one sign-up requires — the billing address — is missing. Carries `field`.
|
|
605
|
+
*/
|
|
603
606
|
SUBSCRIBER_DETAIL_INVALID: "SUBSCRIBER_DETAIL_INVALID",
|
|
604
607
|
/** A contact change named a field of the legal identity. Carries `field`. */
|
|
605
608
|
SUBSCRIBER_IDENTITY_NOT_A_CONTACT: "SUBSCRIBER_IDENTITY_NOT_A_CONTACT",
|
|
@@ -634,6 +637,12 @@ var AUTH_ERROR_CODES = {
|
|
|
634
637
|
/** Neither `tenantId` nor `userId` could be resolved from the request. */
|
|
635
638
|
TENANT_CONTEXT_MISSING: "TENANT_CONTEXT_MISSING",
|
|
636
639
|
TENANT_ADMIN_REQUIRED: "TENANT_ADMIN_REQUIRED",
|
|
640
|
+
/**
|
|
641
|
+
* The tenant's billing area — its payment method, and later its invoices
|
|
642
|
+
* and account — needs the billing permission, which the application maps
|
|
643
|
+
* to its roles and the tenant's administrator holds by default.
|
|
644
|
+
*/
|
|
645
|
+
BILLING_PERMISSION_REQUIRED: "BILLING_PERMISSION_REQUIRED",
|
|
637
646
|
SUPER_ADMIN_REQUIRED: "SUPER_ADMIN_REQUIRED",
|
|
638
647
|
/** TOTP MFA has never been set up for this user. */
|
|
639
648
|
MFA_NOT_SET_UP: "MFA_NOT_SET_UP",
|
|
@@ -661,6 +670,22 @@ var PROMO_ERROR_CODES = {
|
|
|
661
670
|
PROMO_WOULD_PRODUCE_ZERO_INVOICE: "PROMO_WOULD_PRODUCE_ZERO_INVOICE",
|
|
662
671
|
PROMO_MAX_REDEMPTIONS_LOWERED: "PROMO_MAX_REDEMPTIONS_LOWERED"
|
|
663
672
|
};
|
|
673
|
+
var PAYMENT_ERROR_CODES = {
|
|
674
|
+
/**
|
|
675
|
+
* No gateway account takes new payment methods:
|
|
676
|
+
* `config/saas.yaml#payments.newPaymentMethods` names none.
|
|
677
|
+
*/
|
|
678
|
+
PAYMENTS_NOT_CONFIGURED: "PAYMENTS_NOT_CONFIGURED",
|
|
679
|
+
/** A callback arrived for an account `config/saas.yaml#payments.accounts` does not name. Carries `account`. */
|
|
680
|
+
PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "PAYMENT_GATEWAY_ACCOUNT_UNKNOWN",
|
|
681
|
+
/** A callback the gateway did not send: its signature does not verify. */
|
|
682
|
+
PAYMENT_CALLBACK_REJECTED: "PAYMENT_CALLBACK_REJECTED",
|
|
683
|
+
/**
|
|
684
|
+
* A success or cancel URL at an origin `config/saas.yaml#payments.returnUrlOrigins`
|
|
685
|
+
* does not name. Carries `field`.
|
|
686
|
+
*/
|
|
687
|
+
PAYMENT_RETURN_URL_NOT_ALLOWED: "PAYMENT_RETURN_URL_NOT_ALLOWED"
|
|
688
|
+
};
|
|
664
689
|
var SETTINGS_ERROR_CODES = {
|
|
665
690
|
/** No recorded change has this id, or the installation keeps no record at all. */
|
|
666
691
|
SETTINGS_CHANGE_NOT_FOUND: "SETTINGS_CHANGE_NOT_FOUND"
|
|
@@ -674,6 +699,7 @@ var PLATFORM_ERROR_CODES = {
|
|
|
674
699
|
...CONTRACT_ERROR_CODES,
|
|
675
700
|
...SUBSCRIBER_ERROR_CODES,
|
|
676
701
|
...REGISTRATION_ERROR_CODES,
|
|
702
|
+
...PAYMENT_ERROR_CODES,
|
|
677
703
|
...SETTINGS_ERROR_CODES
|
|
678
704
|
};
|
|
679
705
|
|
|
@@ -753,6 +779,19 @@ function selectChargeableBundles(planFeatures, selectedBundles) {
|
|
|
753
779
|
}
|
|
754
780
|
}
|
|
755
781
|
|
|
782
|
+
// src/payment-gateway.types.ts
|
|
783
|
+
var PAYMENT_CALLBACK_REJECTED = "PAYMENT_CALLBACK_REJECTED";
|
|
784
|
+
var PaymentCallbackRejectedError = class extends Error {
|
|
785
|
+
code = PAYMENT_CALLBACK_REJECTED;
|
|
786
|
+
constructor(reason) {
|
|
787
|
+
super(`Payment callback rejected: ${reason}`);
|
|
788
|
+
this.name = "PaymentCallbackRejectedError";
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
function isPaymentCallbackRejectedError(err) {
|
|
792
|
+
return err instanceof Error && err.code === PAYMENT_CALLBACK_REJECTED;
|
|
793
|
+
}
|
|
794
|
+
|
|
756
795
|
// src/registration.types.ts
|
|
757
796
|
var PENDING_EMAIL_TTL_HOURS = 72;
|
|
758
797
|
var PENDING_ONBOARDING_TTL_DAYS = 14;
|
|
@@ -916,7 +955,17 @@ function issuerPartyOf(issuer) {
|
|
|
916
955
|
};
|
|
917
956
|
}
|
|
918
957
|
function subscriberFromRegistration(pending) {
|
|
919
|
-
return {
|
|
958
|
+
return {
|
|
959
|
+
legalName: pending.tenantName,
|
|
960
|
+
invoiceEmail: pending.email,
|
|
961
|
+
addressLine1: pending.addressLine1,
|
|
962
|
+
addressLine2: pending.addressLine2,
|
|
963
|
+
postalCode: pending.postalCode,
|
|
964
|
+
city: pending.city,
|
|
965
|
+
country: pending.country,
|
|
966
|
+
vatId: pending.vatId,
|
|
967
|
+
taxNumber: pending.taxNumber
|
|
968
|
+
};
|
|
920
969
|
}
|
|
921
970
|
function toIdentityValues(value) {
|
|
922
971
|
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
@@ -930,6 +979,59 @@ function toIdentityValues(value) {
|
|
|
930
979
|
return values;
|
|
931
980
|
}
|
|
932
981
|
|
|
982
|
+
// src/subscriber-payment-method-mapping.ts
|
|
983
|
+
var PAYMENT_METHOD_TYPES = ["card", "sepa_debit"];
|
|
984
|
+
var STATUSES = ["ACTIVE", "REPLACED"];
|
|
985
|
+
function toSubscriberPaymentMethodRecord(row) {
|
|
986
|
+
return {
|
|
987
|
+
id: row.id,
|
|
988
|
+
subscriberId: row.subscriberId,
|
|
989
|
+
gatewayAccount: row.gatewayAccount,
|
|
990
|
+
provider: row.provider,
|
|
991
|
+
customerRef: row.customerRef,
|
|
992
|
+
paymentMethodRef: row.paymentMethodRef,
|
|
993
|
+
type: oneOf(PAYMENT_METHOD_TYPES, row.type, "type", row.id),
|
|
994
|
+
brand: row.brand,
|
|
995
|
+
last4: row.last4,
|
|
996
|
+
expiryMonth: row.expiryMonth,
|
|
997
|
+
expiryYear: row.expiryYear,
|
|
998
|
+
country: row.country,
|
|
999
|
+
bankCode: row.bankCode,
|
|
1000
|
+
mandateReference: row.mandateReference,
|
|
1001
|
+
status: oneOf(STATUSES, row.status, "status", row.id),
|
|
1002
|
+
confirmedAt: row.confirmedAt,
|
|
1003
|
+
replacedAt: row.replacedAt,
|
|
1004
|
+
createdAt: row.createdAt
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
1007
|
+
function subscriberPaymentMethodColumns(data) {
|
|
1008
|
+
return {
|
|
1009
|
+
subscriberId: data.subscriberId,
|
|
1010
|
+
gatewayAccount: data.gatewayAccount,
|
|
1011
|
+
provider: data.provider,
|
|
1012
|
+
customerRef: data.customerRef,
|
|
1013
|
+
paymentMethodRef: data.paymentMethodRef,
|
|
1014
|
+
type: data.type,
|
|
1015
|
+
brand: data.brand,
|
|
1016
|
+
last4: data.last4,
|
|
1017
|
+
expiryMonth: data.expiryMonth,
|
|
1018
|
+
expiryYear: data.expiryYear,
|
|
1019
|
+
country: data.country,
|
|
1020
|
+
bankCode: data.bankCode,
|
|
1021
|
+
mandateReference: data.mandateReference,
|
|
1022
|
+
confirmedAt: data.confirmedAt
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
function oneOf(allowed, value, column, id) {
|
|
1026
|
+
const match = allowed.find((entry) => entry === value);
|
|
1027
|
+
if (match === void 0) {
|
|
1028
|
+
throw new Error(
|
|
1029
|
+
`subscriber_payment_methods row '${id}' holds ${column} '${value}', which is none of ${allowed.join(", ")}.`
|
|
1030
|
+
);
|
|
1031
|
+
}
|
|
1032
|
+
return match;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
933
1035
|
// src/subscription-contract-mapping.ts
|
|
934
1036
|
function toSubscriptionContractRecord(row, lineItems) {
|
|
935
1037
|
return {
|
|
@@ -1080,6 +1182,7 @@ var ERROR_MESSAGES_EN = {
|
|
|
1080
1182
|
NO_TENANT_ASSIGNED: "No tenant assigned",
|
|
1081
1183
|
TENANT_CONTEXT_MISSING: "No tenant ID found on the request",
|
|
1082
1184
|
TENANT_ADMIN_REQUIRED: "This action requires the TENANT_ADMIN role.",
|
|
1185
|
+
BILLING_PERMISSION_REQUIRED: "This part of the billing area requires the billing permission.",
|
|
1083
1186
|
SUPER_ADMIN_REQUIRED: "Only the SUPER_ADMIN role is allowed",
|
|
1084
1187
|
MFA_NOT_SET_UP: "Run the MFA setup via the CLI first.",
|
|
1085
1188
|
MFA_REQUIRED: "TOTP code required in the X-Mfa-Code header.",
|
|
@@ -1247,6 +1350,11 @@ var ERROR_MESSAGES_EN = {
|
|
|
1247
1350
|
PLAN_NOT_AVAILABLE: "This plan is not available.",
|
|
1248
1351
|
PLAN_NOT_SELECTED: "Please select a plan first.",
|
|
1249
1352
|
MODEL_NOT_AVAILABLE: "This option is not available.",
|
|
1353
|
+
// ── payments ──
|
|
1354
|
+
PAYMENTS_NOT_CONFIGURED: "Payment methods cannot be set up here yet.",
|
|
1355
|
+
PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "No payment gateway account is configured under '{account}'.",
|
|
1356
|
+
PAYMENT_CALLBACK_REJECTED: "The payment callback could not be verified.",
|
|
1357
|
+
PAYMENT_RETURN_URL_NOT_ALLOWED: "The {field} leads to a site this installation does not return to.",
|
|
1250
1358
|
// ── entitlement (code lives in upsell.types.ts) ──
|
|
1251
1359
|
[FEATURE_NOT_LICENSED]: "Feature {featureKeys} is not included in the current plan.",
|
|
1252
1360
|
// ── settings ──
|
|
@@ -1281,6 +1389,7 @@ var ERROR_MESSAGES_DE = {
|
|
|
1281
1389
|
NO_TENANT_ASSIGNED: "Kein Mandant zugeordnet",
|
|
1282
1390
|
TENANT_CONTEXT_MISSING: "Am Request wurde keine Mandanten-ID gefunden",
|
|
1283
1391
|
TENANT_ADMIN_REQUIRED: "Diese Aktion erfordert die Rolle TENANT_ADMIN.",
|
|
1392
|
+
BILLING_PERMISSION_REQUIRED: "Dieser Teil der Abrechnung erfordert die Abrechnungs-Berechtigung.",
|
|
1284
1393
|
SUPER_ADMIN_REQUIRED: "Nur die Rolle SUPER_ADMIN ist zugelassen",
|
|
1285
1394
|
MFA_NOT_SET_UP: "Richte MFA zuerst \xFCber die CLI ein.",
|
|
1286
1395
|
MFA_REQUIRED: "TOTP-Code im Header X-Mfa-Code erforderlich.",
|
|
@@ -1448,6 +1557,11 @@ var ERROR_MESSAGES_DE = {
|
|
|
1448
1557
|
PLAN_NOT_AVAILABLE: "Dieser Plan steht nicht zur Verf\xFCgung.",
|
|
1449
1558
|
PLAN_NOT_SELECTED: "Bitte w\xE4hle zuerst einen Plan aus.",
|
|
1450
1559
|
MODEL_NOT_AVAILABLE: "Diese Option steht nicht zur Verf\xFCgung.",
|
|
1560
|
+
// ── payments ──
|
|
1561
|
+
PAYMENTS_NOT_CONFIGURED: "Zahlungsmethoden k\xF6nnen hier noch nicht hinterlegt werden.",
|
|
1562
|
+
PAYMENT_GATEWAY_ACCOUNT_UNKNOWN: "Unter '{account}' ist kein Konto eines Zahlungsanbieters eingerichtet.",
|
|
1563
|
+
PAYMENT_CALLBACK_REJECTED: "Die R\xFCckmeldung des Zahlungsanbieters lie\xDF sich nicht pr\xFCfen.",
|
|
1564
|
+
PAYMENT_RETURN_URL_NOT_ALLOWED: "Die {field} f\xFChrt auf eine Seite, zu der diese Installation nicht zur\xFCckleitet.",
|
|
1451
1565
|
// ── entitlement (code lives in upsell.types.ts) ──
|
|
1452
1566
|
[FEATURE_NOT_LICENSED]: "Das Feature {featureKeys} ist im aktuellen Plan nicht enthalten.",
|
|
1453
1567
|
// ── settings ──
|
|
@@ -1471,11 +1585,14 @@ export {
|
|
|
1471
1585
|
OTP_TTL_MINUTES,
|
|
1472
1586
|
OTP_VERIFY_MAX_ATTEMPTS,
|
|
1473
1587
|
PASSWORD_RESET_TTL_MINUTES,
|
|
1588
|
+
PAYMENT_ERROR_CODES,
|
|
1589
|
+
PAYMENT_METHOD_TYPES,
|
|
1474
1590
|
PENDING_CHECKOUT_TTL_DAYS,
|
|
1475
1591
|
PENDING_EMAIL_TTL_HOURS,
|
|
1476
1592
|
PENDING_ONBOARDING_TTL_DAYS,
|
|
1477
1593
|
PLATFORM_ERROR_CODES,
|
|
1478
1594
|
PROMO_ERROR_CODES,
|
|
1595
|
+
PaymentCallbackRejectedError,
|
|
1479
1596
|
PersistenceCapabilityError,
|
|
1480
1597
|
PlatformUserExistsError,
|
|
1481
1598
|
REGISTRATION_ERROR_CODES,
|
|
@@ -1504,6 +1621,7 @@ export {
|
|
|
1504
1621
|
formatErrorMessage,
|
|
1505
1622
|
identityCorrectionDelta,
|
|
1506
1623
|
isBundleRedundant,
|
|
1624
|
+
isPaymentCallbackRejectedError,
|
|
1507
1625
|
isPlatformUserExistsError,
|
|
1508
1626
|
isVersionEditable,
|
|
1509
1627
|
keepOneRecommended,
|
|
@@ -1520,11 +1638,13 @@ export {
|
|
|
1520
1638
|
settingsSubtreeOf,
|
|
1521
1639
|
startOfUtcDay,
|
|
1522
1640
|
subscriberFromRegistration,
|
|
1641
|
+
subscriberPaymentMethodColumns,
|
|
1523
1642
|
toBundleStemRow,
|
|
1524
1643
|
toContractLineItemRecord,
|
|
1525
1644
|
toPlanRow,
|
|
1526
1645
|
toPlanVersionRow,
|
|
1527
1646
|
toSubscriberCorrectionRecord,
|
|
1647
|
+
toSubscriberPaymentMethodRecord,
|
|
1528
1648
|
toSubscriberRecord,
|
|
1529
1649
|
toSubscriptionContractRecord
|
|
1530
1650
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saasicat/core",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.18",
|
|
4
4
|
"description": "TypeScript contracts for SaaSiCat — capabilities, catalogs, subscriptions, entitlements, admin manifests, persistence ports — and the pure domain logic both server and browser run: error catalogues, plan-diff classification, promo arithmetic, feature requirements.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|