@saasicat/core 1.0.0-rc.6 → 1.0.0-rc.7
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/README.md +2 -1
- package/dist/.build-stamp +1 -1
- package/dist/index.cjs +229 -12
- package/dist/index.d.cts +679 -448
- package/dist/index.d.ts +679 -448
- package/dist/index.js +217 -11
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -74,5 +74,6 @@ Produces `dist/index.{js,cjs,d.ts,d.cts}` via `tsup`.
|
|
|
74
74
|
## Next
|
|
75
75
|
|
|
76
76
|
- [The vocabulary](../../docs/explanation/concepts.md) — capability, feature, quota, plan, contract
|
|
77
|
-
- [Codegen](../../docs/explanation/adr/0006-spec-to-types-codegen.md) — what is generated, and what
|
|
77
|
+
- [Codegen](../../docs/explanation/adr/0006-spec-to-types-codegen.md) — what is generated, and what
|
|
78
|
+
is not
|
|
78
79
|
- [`@saasicat/spec`](../spec/README.md) — the schemas these types come from
|
package/dist/.build-stamp
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
9ad6205a66054b865cdec958983f004f58c3ac359b6eedffa9c8bfa91414741d
|
package/dist/index.cjs
CHANGED
|
@@ -20,8 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES: () => ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES,
|
|
23
24
|
AUTH_ERROR_CODES: () => AUTH_ERROR_CODES,
|
|
24
25
|
BILLING_ERROR_CODES: () => BILLING_ERROR_CODES,
|
|
26
|
+
BUNDLE_PRICE_LOOKUP_LIMIT: () => BUNDLE_PRICE_LOOKUP_LIMIT,
|
|
25
27
|
CATALOG_ERROR_CODES: () => CATALOG_ERROR_CODES,
|
|
26
28
|
CONTRACT_ERROR_CODES: () => CONTRACT_ERROR_CODES,
|
|
27
29
|
ERROR_MESSAGES_DE: () => ERROR_MESSAGES_DE,
|
|
@@ -50,21 +52,30 @@ __export(index_exports, {
|
|
|
50
52
|
buildActivePlanVersionWhere: () => buildActivePlanVersionWhere,
|
|
51
53
|
buildActiveVersionWhere: () => buildActiveVersionWhere,
|
|
52
54
|
buildFeatureRequiresIndex: () => buildFeatureRequiresIndex,
|
|
55
|
+
bundleDraftDefaults: () => bundleDraftDefaults,
|
|
56
|
+
bundleStemDefaults: () => bundleStemDefaults,
|
|
53
57
|
classifyBundleVersionDiff: () => classifyBundleVersionDiff,
|
|
54
58
|
classifyPlanDiff: () => classifyPlanDiff,
|
|
55
59
|
collectUnsatisfiedRequires: () => collectUnsatisfiedRequires,
|
|
56
60
|
coverageExcludingSelf: () => coverageExcludingSelf,
|
|
61
|
+
definedFields: () => definedFields,
|
|
57
62
|
formatErrorMessage: () => formatErrorMessage,
|
|
58
63
|
isBundleRedundant: () => isBundleRedundant,
|
|
59
64
|
isPlatformUserExistsError: () => isPlatformUserExistsError,
|
|
60
65
|
isVersionEditable: () => isVersionEditable,
|
|
61
66
|
missingRequiresFor: () => missingRequiresFor,
|
|
62
67
|
pickActivePromo: () => pickActivePromo,
|
|
68
|
+
previousUtcDay: () => previousUtcDay,
|
|
63
69
|
promoStatus: () => promoStatus,
|
|
64
70
|
resolveBundleAvailability: () => resolveBundleAvailability,
|
|
65
71
|
resolveErrorMessage: () => resolveErrorMessage,
|
|
66
72
|
selectChargeableBundles: () => selectChargeableBundles,
|
|
67
|
-
startOfUtcDay: () => startOfUtcDay
|
|
73
|
+
startOfUtcDay: () => startOfUtcDay,
|
|
74
|
+
toBundleStemRow: () => toBundleStemRow,
|
|
75
|
+
toContractLineItemRecord: () => toContractLineItemRecord,
|
|
76
|
+
toPlanRow: () => toPlanRow,
|
|
77
|
+
toPlanVersionRow: () => toPlanVersionRow,
|
|
78
|
+
toSubscriptionContractRecord: () => toSubscriptionContractRecord
|
|
68
79
|
});
|
|
69
80
|
module.exports = __toCommonJS(index_exports);
|
|
70
81
|
|
|
@@ -72,6 +83,11 @@ module.exports = __toCommonJS(index_exports);
|
|
|
72
83
|
function startOfUtcDay(date) {
|
|
73
84
|
return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
|
|
74
85
|
}
|
|
86
|
+
function previousUtcDay(value) {
|
|
87
|
+
const result = new Date(value);
|
|
88
|
+
result.setUTCDate(result.getUTCDate() - 1);
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
75
91
|
function buildActivePlanVersionWhere(asOf, options = {}) {
|
|
76
92
|
const asOfDayStart = startOfUtcDay(asOf);
|
|
77
93
|
const validityWindow = [
|
|
@@ -88,6 +104,53 @@ function buildActivePlanVersionWhere(asOf, options = {}) {
|
|
|
88
104
|
}
|
|
89
105
|
var buildActiveVersionWhere = buildActivePlanVersionWhere;
|
|
90
106
|
|
|
107
|
+
// src/bundle-draft-defaults.ts
|
|
108
|
+
function bundleDraftDefaults(data) {
|
|
109
|
+
return {
|
|
110
|
+
baseVersionId: data.baseVersionId ?? null,
|
|
111
|
+
features: data.features,
|
|
112
|
+
quotas: data.quotas ?? {},
|
|
113
|
+
compatibility: data.compatibility ?? {},
|
|
114
|
+
pricingOverrides: data.pricingOverrides ?? [],
|
|
115
|
+
monthlyNet: data.monthlyNet ?? null,
|
|
116
|
+
yearlyNet: data.yearlyNet ?? null,
|
|
117
|
+
marketed: data.marketed ?? true,
|
|
118
|
+
changeNote: data.changeNote ?? "",
|
|
119
|
+
createdByUserId: data.createdByUserId ?? null
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function bundleStemDefaults(data) {
|
|
123
|
+
return {
|
|
124
|
+
bundleKey: data.bundleKey,
|
|
125
|
+
label: data.label,
|
|
126
|
+
description: data.description ?? null,
|
|
127
|
+
icon: data.icon ?? null,
|
|
128
|
+
sortOrder: data.sortOrder ?? 0,
|
|
129
|
+
i18n: data.i18n ?? {}
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function toBundleStemRow(row) {
|
|
133
|
+
return {
|
|
134
|
+
id: row.id,
|
|
135
|
+
bundleKey: row.bundleKey,
|
|
136
|
+
label: row.label,
|
|
137
|
+
description: row.description,
|
|
138
|
+
icon: row.icon,
|
|
139
|
+
sortOrder: row.sortOrder,
|
|
140
|
+
i18n: row.i18n !== null && typeof row.i18n === "object" && !Array.isArray(row.i18n) ? row.i18n : {},
|
|
141
|
+
createdAt: row.createdAt.toISOString(),
|
|
142
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
143
|
+
deletedAt: row.deletedAt?.toISOString() ?? null
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function definedFields(data, keys) {
|
|
147
|
+
const patch = {};
|
|
148
|
+
for (const key of keys) {
|
|
149
|
+
if (data[key] !== void 0) patch[key] = data[key];
|
|
150
|
+
}
|
|
151
|
+
return patch;
|
|
152
|
+
}
|
|
153
|
+
|
|
91
154
|
// src/catalog-entry.types.ts
|
|
92
155
|
var MARKETING_PRIORITY_MIN = 0;
|
|
93
156
|
var MARKETING_PRIORITY_MAX = 1e4;
|
|
@@ -343,6 +406,8 @@ var CATALOG_ERROR_CODES = {
|
|
|
343
406
|
BUNDLE_VERSION_SUPERSEDED: "BUNDLE_VERSION_SUPERSEDED",
|
|
344
407
|
BUNDLE_VERSION_REGRESSION: "BUNDLE_VERSION_REGRESSION",
|
|
345
408
|
BUNDLE_VERSION_ZERO_PRICE: "BUNDLE_VERSION_ZERO_PRICE",
|
|
409
|
+
BUNDLE_VERSION_NO_PRICE: "BUNDLE_VERSION_NO_PRICE",
|
|
410
|
+
BUNDLE_VERSION_NOT_PRICED_FOR_PLAN: "BUNDLE_VERSION_NOT_PRICED_FOR_PLAN",
|
|
346
411
|
BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED: "BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED",
|
|
347
412
|
BUNDLE_VERSION_VALID_FROM_REQUIRED: "BUNDLE_VERSION_VALID_FROM_REQUIRED",
|
|
348
413
|
BUNDLE_VERSION_VALID_FROM_INVALID: "BUNDLE_VERSION_VALID_FROM_INVALID",
|
|
@@ -389,6 +454,8 @@ var BILLING_ERROR_CODES = {
|
|
|
389
454
|
BUNDLE_ALREADY_SUBSCRIBED: "BUNDLE_ALREADY_SUBSCRIBED",
|
|
390
455
|
BUNDLE_INCOMPATIBLE_WITH_PLAN: "BUNDLE_INCOMPATIBLE_WITH_PLAN",
|
|
391
456
|
BUNDLE_NOT_SELF_SERVICE: "BUNDLE_NOT_SELF_SERVICE",
|
|
457
|
+
BUNDLE_CYCLE_EXCEEDS_PLAN: "BUNDLE_CYCLE_EXCEEDS_PLAN",
|
|
458
|
+
BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "BUNDLE_NOT_PRICED_FOR_THIS_PLAN",
|
|
392
459
|
SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED",
|
|
393
460
|
SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SUBSCRIPTION_BUNDLE_NOT_CANCELLED",
|
|
394
461
|
SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE",
|
|
@@ -595,6 +662,137 @@ var REGISTRATION_STEP_BY_STATUS = {
|
|
|
595
662
|
};
|
|
596
663
|
var REGISTRATION_RESUME_TTL_MINUTES = 60;
|
|
597
664
|
|
|
665
|
+
// src/plan-mapping.ts
|
|
666
|
+
function toPlanRow(row) {
|
|
667
|
+
return {
|
|
668
|
+
id: row.id,
|
|
669
|
+
planKey: row.planKey,
|
|
670
|
+
label: row.label,
|
|
671
|
+
description: row.description,
|
|
672
|
+
icon: row.icon,
|
|
673
|
+
sortOrder: row.sortOrder,
|
|
674
|
+
createdAt: row.createdAt.toISOString(),
|
|
675
|
+
updatedAt: row.updatedAt.toISOString(),
|
|
676
|
+
deletedAt: toIsoOrNull(row.deletedAt)
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
function toPlanVersionRow(row, planKey, fields) {
|
|
680
|
+
const mapped = {
|
|
681
|
+
id: row.id,
|
|
682
|
+
version: row.version,
|
|
683
|
+
baseVersionId: row.baseVersionId,
|
|
684
|
+
planId: planKey,
|
|
685
|
+
features: toFeatureKeys(row.features),
|
|
686
|
+
quotas: toQuotaEffects(row.quotas),
|
|
687
|
+
monthlyNet: String(row.monthlyNet),
|
|
688
|
+
yearlyNet: String(row.yearlyNet),
|
|
689
|
+
marketed: row.marketed,
|
|
690
|
+
publishedAt: toIsoOrNull(row.publishedAt),
|
|
691
|
+
supersededAt: toIsoOrNull(row.supersededAt),
|
|
692
|
+
publishedChanges: Array.isArray(row.publishedChanges) ? row.publishedChanges : null,
|
|
693
|
+
changeNote: row.changeNote,
|
|
694
|
+
nonRegressive: row.nonRegressive,
|
|
695
|
+
validFrom: fields.validityWindows ? toIsoOrNull(row.validFrom) : null,
|
|
696
|
+
validUntil: fields.validityWindows ? toIsoOrNull(row.validUntil) : null,
|
|
697
|
+
createdByUserId: row.createdByUserId,
|
|
698
|
+
publishedByUserId: row.publishedByUserId,
|
|
699
|
+
createdAt: row.createdAt.toISOString(),
|
|
700
|
+
updatedAt: row.updatedAt.toISOString()
|
|
701
|
+
};
|
|
702
|
+
if (fields.endsAt) {
|
|
703
|
+
mapped.endsAt = toIsoOrNull(row.endsAt);
|
|
704
|
+
}
|
|
705
|
+
return mapped;
|
|
706
|
+
}
|
|
707
|
+
function toIsoOrNull(value) {
|
|
708
|
+
return value ? value.toISOString() : null;
|
|
709
|
+
}
|
|
710
|
+
function toFeatureKeys(value) {
|
|
711
|
+
if (!Array.isArray(value)) return [];
|
|
712
|
+
return value.filter((entry) => typeof entry === "string");
|
|
713
|
+
}
|
|
714
|
+
function toQuotaEffects(value) {
|
|
715
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
716
|
+
return {};
|
|
717
|
+
}
|
|
718
|
+
const quotas = {};
|
|
719
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
720
|
+
if (typeof entry === "number") quotas[key] = entry;
|
|
721
|
+
}
|
|
722
|
+
return quotas;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// src/subscription-contract-mapping.ts
|
|
726
|
+
function toSubscriptionContractRecord(row, lineItems) {
|
|
727
|
+
return {
|
|
728
|
+
id: row.id,
|
|
729
|
+
tenantId: row.tenantId,
|
|
730
|
+
status: row.status,
|
|
731
|
+
effectiveFrom: row.effectiveFrom,
|
|
732
|
+
effectiveUntil: row.effectiveUntil,
|
|
733
|
+
originalOfferId: row.originalOfferId,
|
|
734
|
+
originalPlanVersionId: row.originalPlanVersionId,
|
|
735
|
+
originalBundleVersionIds: toStringArray(row.originalBundleVersionIds),
|
|
736
|
+
entitlementSnapshot: isPlainObject(row.entitlementSnapshot) ? row.entitlementSnapshot : null,
|
|
737
|
+
priceSnapshot: row.priceSnapshot,
|
|
738
|
+
promotionSnapshots: toUnknownArray(row.promotionSnapshots),
|
|
739
|
+
promoCodeSnapshots: toUnknownArray(row.promoCodeSnapshots),
|
|
740
|
+
termsSnapshot: toRecordOrNull(row.termsSnapshot),
|
|
741
|
+
lineItems: lineItems.map(toContractLineItemRecord),
|
|
742
|
+
createdAt: row.createdAt,
|
|
743
|
+
updatedAt: row.updatedAt
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function toContractLineItemRecord(row) {
|
|
747
|
+
return {
|
|
748
|
+
id: row.id,
|
|
749
|
+
contractId: row.contractId,
|
|
750
|
+
kind: row.kind,
|
|
751
|
+
sourceKey: row.sourceKey,
|
|
752
|
+
sourceVersionId: row.sourceVersionId,
|
|
753
|
+
titleSnapshot: row.titleSnapshot,
|
|
754
|
+
descriptionSnapshot: row.descriptionSnapshot,
|
|
755
|
+
quantity: row.quantity,
|
|
756
|
+
unit: row.unit,
|
|
757
|
+
priceNet: Number(row.priceNet),
|
|
758
|
+
priceGross: Number(row.priceGross),
|
|
759
|
+
billingCycle: row.billingCycle,
|
|
760
|
+
minimumTermUntil: row.minimumTermUntil,
|
|
761
|
+
featuresSnapshot: toStringArray(row.featuresSnapshot),
|
|
762
|
+
quotaEffectsSnapshot: toQuotaEffects2(row.quotaEffectsSnapshot),
|
|
763
|
+
metadata: toRecordOrNull(row.metadata),
|
|
764
|
+
createdAt: row.createdAt
|
|
765
|
+
};
|
|
766
|
+
}
|
|
767
|
+
function isPlainObject(value) {
|
|
768
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
769
|
+
}
|
|
770
|
+
function toUnknownArray(value) {
|
|
771
|
+
return Array.isArray(value) ? value : [];
|
|
772
|
+
}
|
|
773
|
+
function toRecordOrNull(value) {
|
|
774
|
+
return isPlainObject(value) ? value : null;
|
|
775
|
+
}
|
|
776
|
+
function toStringArray(value) {
|
|
777
|
+
if (!Array.isArray(value)) return [];
|
|
778
|
+
return value.filter((entry) => typeof entry === "string");
|
|
779
|
+
}
|
|
780
|
+
function toQuotaEffects2(value) {
|
|
781
|
+
if (!isPlainObject(value)) return {};
|
|
782
|
+
const effects = {};
|
|
783
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
784
|
+
if (typeof entry === "number") effects[key] = entry;
|
|
785
|
+
}
|
|
786
|
+
return effects;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
// src/subscription-contract.types.ts
|
|
790
|
+
var BUNDLE_PRICE_LOOKUP_LIMIT = 200;
|
|
791
|
+
var ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES = [
|
|
792
|
+
"active",
|
|
793
|
+
"scheduled"
|
|
794
|
+
];
|
|
795
|
+
|
|
598
796
|
// src/version-editability.ts
|
|
599
797
|
function isVersionEditable(v, now = /* @__PURE__ */ new Date()) {
|
|
600
798
|
if (v.publishedAt === null) {
|
|
@@ -666,6 +864,8 @@ var ERROR_MESSAGES_EN = {
|
|
|
666
864
|
BUNDLE_VERSION_SUPERSEDED: "BundleVersion '{bundleVersionId}' has been superseded by a newer version.",
|
|
667
865
|
BUNDLE_VERSION_REGRESSION: "This bundle version is regressive (feature removed / quota lowered / price raised). Publishing requires an explicit `forceRegressive: true` (UI confirmation dialog with MFA).",
|
|
668
866
|
BUNDLE_VERSION_ZERO_PRICE: "A bundle version cannot be published with an explicit price of 0.00 (guard against seed placeholders). For free bundles leave it null, or set allowZeroPrice.",
|
|
867
|
+
BUNDLE_VERSION_NO_PRICE: "This bundle version cannot be published without a price: neither a base price nor any plan override resolves one.",
|
|
868
|
+
BUNDLE_VERSION_NOT_PRICED_FOR_PLAN: "This bundle is offered to plan '{planKey}', which is sold {billingCycle}, and no {billingCycle} price resolves for it \u2014 neither a base price nor a plan override.",
|
|
669
869
|
BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED: "Discard is not implemented in the current repository. Implement BundleRepository.deleteDraft.",
|
|
670
870
|
BUNDLE_VERSION_VALID_FROM_REQUIRED: "Published bundle versions must keep a validFrom. Set a new future date, or edit the draft before publishing.",
|
|
671
871
|
BUNDLE_VERSION_VALID_FROM_INVALID: "validFrom '{validFrom}' is not a valid date",
|
|
@@ -679,12 +879,12 @@ var ERROR_MESSAGES_EN = {
|
|
|
679
879
|
PLAN_VERSION_NOT_FOUND: "PlanVersion '{versionId}' not found",
|
|
680
880
|
BUNDLE_NOT_FOUND: "Bundle '{bundleId}' not found",
|
|
681
881
|
BUNDLE_VERSION_NOT_FOUND: "BundleVersion '{bundleVersionId}' not found",
|
|
682
|
-
FEATURE_NOT_FOUND: "Feature '{featureKey}' not found
|
|
683
|
-
QUOTA_NOT_FOUND: "Quota '{quotaKey}' not found
|
|
882
|
+
FEATURE_NOT_FOUND: "Feature '{featureKey}' not found",
|
|
883
|
+
QUOTA_NOT_FOUND: "Quota '{quotaKey}' not found",
|
|
684
884
|
PROMOTION_NOT_FOUND: "Promotion '{promotionId}' not found",
|
|
685
885
|
MARKETING_PROJECTION_NOT_FOUND: "MarketingProjection '{projectionId}' not found",
|
|
686
|
-
PLAN_ALREADY_EXISTS: "Plan '{planKey}' already exists
|
|
687
|
-
BUNDLE_ALREADY_EXISTS: "Bundle '{bundleKey}' already exists
|
|
886
|
+
PLAN_ALREADY_EXISTS: "Plan '{planKey}' already exists",
|
|
887
|
+
BUNDLE_ALREADY_EXISTS: "Bundle '{bundleKey}' already exists",
|
|
688
888
|
MARKETING_PROJECTION_ALREADY_EXISTS: "Marketing projection for {targetType}/{targetVersionId}/{locale} already exists \u2014 use PATCH to edit it",
|
|
689
889
|
PLAN_DRAFT_ALREADY_EXISTS: "Plan '{planKey}' already has a draft version v{draftVersion}; publish or discard it first",
|
|
690
890
|
BUNDLE_DRAFT_ALREADY_EXISTS: "Bundle '{bundleKey}' already has a draft version v{draftVersion}; publish or discard it first",
|
|
@@ -698,6 +898,8 @@ var ERROR_MESSAGES_EN = {
|
|
|
698
898
|
BUNDLE_ALREADY_SUBSCRIBED: "Subscription '{subscriptionId}' has already actively booked this bundle.",
|
|
699
899
|
BUNDLE_INCOMPATIBLE_WITH_PLAN: "BundleVersion '{bundleVersionId}' is not compatible with plan '{planKey}'. Allowed: [{allowedPlanKeys}].",
|
|
700
900
|
BUNDLE_NOT_SELF_SERVICE: "Bundle '{bundleKey}' is only activated via a special contract. Please contact the contract manager.",
|
|
901
|
+
BUNDLE_CYCLE_EXCEEDS_PLAN: "A {billingCycle} bundle cannot run beside a {planCycle} plan: it would still be committed on every day the plan could end.",
|
|
902
|
+
BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "This bundle has no {billingCycle} price for the {planKey} plan, so it cannot be booked from here.",
|
|
701
903
|
SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SubscriptionBundle '{subscriptionBundleId}' is already cancelled.",
|
|
702
904
|
SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SubscriptionBundle '{subscriptionBundleId}' is not cancelled.",
|
|
703
905
|
SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "Cancellation already in effect \u2014 book the bundle again.",
|
|
@@ -706,7 +908,7 @@ var ERROR_MESSAGES_EN = {
|
|
|
706
908
|
SUBSCRIPTION_BUNDLE_NOT_FOUND: "SubscriptionBundle '{subscriptionBundleId}' not found",
|
|
707
909
|
TENANT_NOT_FOUND: "Tenant {slug} not found",
|
|
708
910
|
NO_ACTIVE_PLAN_VERSION: "No plan version for {planId} active as of {asOf} \u2014 neither the validFrom window is satisfied nor is a latest-live version available.",
|
|
709
|
-
PLAN_NOT_IN_CATALOG: 'Plan "{planKey}" is not in the catalog
|
|
911
|
+
PLAN_NOT_IN_CATALOG: 'Plan "{planKey}" is not in the catalog',
|
|
710
912
|
PLAN_NOT_SELF_SERVICE: "{planKey} is not activated via self-service.",
|
|
711
913
|
PLAN_CHANGE_BLOCKED: "Plan change during onboarding is blocked.",
|
|
712
914
|
NO_PENDING_PLAN_VERSION: "There is no pending plan version awaiting confirmation.",
|
|
@@ -826,6 +1028,8 @@ var ERROR_MESSAGES_DE = {
|
|
|
826
1028
|
BUNDLE_VERSION_SUPERSEDED: "BundleVersion '{bundleVersionId}' wurde durch eine neuere Version abgel\xF6st.",
|
|
827
1029
|
BUNDLE_VERSION_REGRESSION: "Diese Bundle-Version ist regressiv (Feature entfernt / Quota gesenkt / Preis erh\xF6ht). Das Ver\xF6ffentlichen erfordert ein ausdr\xFCckliches `forceRegressive: true` (Best\xE4tigungsdialog in der UI mit MFA).",
|
|
828
1030
|
BUNDLE_VERSION_ZERO_PRICE: "Eine Bundle-Version l\xE4sst sich nicht mit einem ausdr\xFCcklichen Preis von 0,00 ver\xF6ffentlichen (Schutz vor Seed-Platzhaltern). Kostenlose Bundles l\xE4sst du auf null, oder du setzt allowZeroPrice.",
|
|
1031
|
+
BUNDLE_VERSION_NO_PRICE: "Diese Bundle-Version kann ohne Preis nicht ver\xF6ffentlicht werden: weder ein Grundpreis noch eine Plan-\xDCberschreibung ergibt einen.",
|
|
1032
|
+
BUNDLE_VERSION_NOT_PRICED_FOR_PLAN: "Dieses Bundle wird dem Plan '{planKey}' angeboten, der {billingCycle} verkauft wird, und daf\xFCr ergibt sich kein {billingCycle} Preis \u2014 weder als Grundpreis noch als Plan-\xDCberschreibung.",
|
|
829
1033
|
BUNDLE_VERSION_DISCARD_NOT_IMPLEMENTED: "Das Verwerfen ist im aktuellen Repository nicht implementiert. Implementiere BundleRepository.deleteDraft.",
|
|
830
1034
|
BUNDLE_VERSION_VALID_FROM_REQUIRED: "Ver\xF6ffentlichte Bundle-Versionen m\xFCssen ein validFrom behalten. Setze ein neues Datum in der Zukunft, oder bearbeite den Entwurf vor dem Ver\xF6ffentlichen.",
|
|
831
1035
|
BUNDLE_VERSION_VALID_FROM_INVALID: "validFrom '{validFrom}' ist kein g\xFCltiges Datum",
|
|
@@ -839,12 +1043,12 @@ var ERROR_MESSAGES_DE = {
|
|
|
839
1043
|
PLAN_VERSION_NOT_FOUND: "PlanVersion '{versionId}' nicht gefunden",
|
|
840
1044
|
BUNDLE_NOT_FOUND: "Bundle '{bundleId}' nicht gefunden",
|
|
841
1045
|
BUNDLE_VERSION_NOT_FOUND: "BundleVersion '{bundleVersionId}' nicht gefunden",
|
|
842
|
-
FEATURE_NOT_FOUND: "Feature '{featureKey}'
|
|
843
|
-
QUOTA_NOT_FOUND: "Quota '{quotaKey}'
|
|
1046
|
+
FEATURE_NOT_FOUND: "Feature '{featureKey}' nicht gefunden",
|
|
1047
|
+
QUOTA_NOT_FOUND: "Quota '{quotaKey}' nicht gefunden",
|
|
844
1048
|
PROMOTION_NOT_FOUND: "Promotion '{promotionId}' nicht gefunden",
|
|
845
1049
|
MARKETING_PROJECTION_NOT_FOUND: "MarketingProjection '{projectionId}' nicht gefunden",
|
|
846
|
-
PLAN_ALREADY_EXISTS: "Plan '{planKey}' gibt es
|
|
847
|
-
BUNDLE_ALREADY_EXISTS: "Bundle '{bundleKey}' gibt es
|
|
1050
|
+
PLAN_ALREADY_EXISTS: "Plan '{planKey}' gibt es bereits",
|
|
1051
|
+
BUNDLE_ALREADY_EXISTS: "Bundle '{bundleKey}' gibt es bereits",
|
|
848
1052
|
MARKETING_PROJECTION_ALREADY_EXISTS: "F\xFCr {targetType}/{targetVersionId}/{locale} gibt es bereits eine Marketing-Projektion \u2014 bearbeite sie per PATCH",
|
|
849
1053
|
PLAN_DRAFT_ALREADY_EXISTS: "Plan '{planKey}' hat bereits die Entwurfsversion v{draftVersion}; ver\xF6ffentliche oder verwirf sie zuerst",
|
|
850
1054
|
BUNDLE_DRAFT_ALREADY_EXISTS: "Bundle '{bundleKey}' hat bereits die Entwurfsversion v{draftVersion}; ver\xF6ffentliche oder verwirf sie zuerst",
|
|
@@ -858,6 +1062,8 @@ var ERROR_MESSAGES_DE = {
|
|
|
858
1062
|
BUNDLE_ALREADY_SUBSCRIBED: "Abonnement '{subscriptionId}' hat dieses Bundle bereits aktiv gebucht.",
|
|
859
1063
|
BUNDLE_INCOMPATIBLE_WITH_PLAN: "BundleVersion '{bundleVersionId}' passt nicht zum Plan '{planKey}'. Erlaubt: [{allowedPlanKeys}].",
|
|
860
1064
|
BUNDLE_NOT_SELF_SERVICE: "Bundle '{bundleKey}' wird nur \xFCber einen Sondervertrag freigeschaltet. Bitte wende dich an die Vertragsverwaltung.",
|
|
1065
|
+
BUNDLE_CYCLE_EXCEEDS_PLAN: "Ein {billingCycle} abgerechnetes Bundle passt nicht zu einem {planCycle} abgerechneten Plan: es w\xE4re an jedem Tag gebunden, an dem der Plan enden kann.",
|
|
1066
|
+
BUNDLE_NOT_PRICED_FOR_THIS_PLAN: "F\xFCr dieses Bundle ist im Plan {planKey} kein {billingCycle} Preis hinterlegt, es kann hier deshalb nicht gebucht werden.",
|
|
861
1067
|
SUBSCRIPTION_BUNDLE_ALREADY_CANCELLED: "SubscriptionBundle '{subscriptionBundleId}' ist bereits gek\xFCndigt.",
|
|
862
1068
|
SUBSCRIPTION_BUNDLE_NOT_CANCELLED: "SubscriptionBundle '{subscriptionBundleId}' ist nicht gek\xFCndigt.",
|
|
863
1069
|
SUBSCRIPTION_BUNDLE_CANCELLATION_EFFECTIVE: "Die K\xFCndigung ist bereits wirksam \u2014 buche das Bundle einfach neu.",
|
|
@@ -866,7 +1072,7 @@ var ERROR_MESSAGES_DE = {
|
|
|
866
1072
|
SUBSCRIPTION_BUNDLE_NOT_FOUND: "SubscriptionBundle '{subscriptionBundleId}' nicht gefunden",
|
|
867
1073
|
TENANT_NOT_FOUND: "Mandant {slug} nicht gefunden",
|
|
868
1074
|
NO_ACTIVE_PLAN_VERSION: "Zum {asOf} ist keine Planversion f\xFCr {planId} aktiv \u2014 weder ist das validFrom-Fenster erf\xFCllt, noch steht eine j\xFCngste Live-Version bereit.",
|
|
869
|
-
PLAN_NOT_IN_CATALOG: 'Plan "{planKey}" steht nicht im Katalog
|
|
1075
|
+
PLAN_NOT_IN_CATALOG: 'Plan "{planKey}" steht nicht im Katalog',
|
|
870
1076
|
PLAN_NOT_SELF_SERVICE: "{planKey} wird nicht per Self-Service freigeschaltet.",
|
|
871
1077
|
PLAN_CHANGE_BLOCKED: "W\xE4hrend des Onboardings ist ein Planwechsel gesperrt.",
|
|
872
1078
|
NO_PENDING_PLAN_VERSION: "Es wartet keine Planversion auf eine Best\xE4tigung.",
|
|
@@ -928,8 +1134,10 @@ var ERROR_MESSAGES_DE = {
|
|
|
928
1134
|
};
|
|
929
1135
|
// Annotate the CommonJS export names for ESM import in node:
|
|
930
1136
|
0 && (module.exports = {
|
|
1137
|
+
ACTIVE_SUBSCRIPTION_CONTRACT_STATUSES,
|
|
931
1138
|
AUTH_ERROR_CODES,
|
|
932
1139
|
BILLING_ERROR_CODES,
|
|
1140
|
+
BUNDLE_PRICE_LOOKUP_LIMIT,
|
|
933
1141
|
CATALOG_ERROR_CODES,
|
|
934
1142
|
CONTRACT_ERROR_CODES,
|
|
935
1143
|
ERROR_MESSAGES_DE,
|
|
@@ -958,19 +1166,28 @@ var ERROR_MESSAGES_DE = {
|
|
|
958
1166
|
buildActivePlanVersionWhere,
|
|
959
1167
|
buildActiveVersionWhere,
|
|
960
1168
|
buildFeatureRequiresIndex,
|
|
1169
|
+
bundleDraftDefaults,
|
|
1170
|
+
bundleStemDefaults,
|
|
961
1171
|
classifyBundleVersionDiff,
|
|
962
1172
|
classifyPlanDiff,
|
|
963
1173
|
collectUnsatisfiedRequires,
|
|
964
1174
|
coverageExcludingSelf,
|
|
1175
|
+
definedFields,
|
|
965
1176
|
formatErrorMessage,
|
|
966
1177
|
isBundleRedundant,
|
|
967
1178
|
isPlatformUserExistsError,
|
|
968
1179
|
isVersionEditable,
|
|
969
1180
|
missingRequiresFor,
|
|
970
1181
|
pickActivePromo,
|
|
1182
|
+
previousUtcDay,
|
|
971
1183
|
promoStatus,
|
|
972
1184
|
resolveBundleAvailability,
|
|
973
1185
|
resolveErrorMessage,
|
|
974
1186
|
selectChargeableBundles,
|
|
975
|
-
startOfUtcDay
|
|
1187
|
+
startOfUtcDay,
|
|
1188
|
+
toBundleStemRow,
|
|
1189
|
+
toContractLineItemRecord,
|
|
1190
|
+
toPlanRow,
|
|
1191
|
+
toPlanVersionRow,
|
|
1192
|
+
toSubscriptionContractRecord
|
|
976
1193
|
});
|