@vritti/api-sdk 0.3.3 → 0.3.5
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/auth.cjs +942 -0
- package/dist/auth.cjs.map +1 -0
- package/dist/auth.d.cts +95 -0
- package/dist/auth.d.ts +95 -0
- package/dist/auth.js +884 -0
- package/dist/auth.js.map +1 -0
- package/dist/cache.cjs +182 -14
- package/dist/cache.cjs.map +1 -1
- package/dist/cache.d.cts +48 -4
- package/dist/cache.d.ts +48 -4
- package/dist/cache.js +177 -12
- package/dist/cache.js.map +1 -1
- package/dist/catalog-resolver.cjs +226 -51
- package/dist/catalog-resolver.cjs.map +1 -1
- package/dist/catalog-resolver.d.cts +41 -19
- package/dist/catalog-resolver.d.ts +41 -19
- package/dist/catalog-resolver.js +212 -46
- package/dist/catalog-resolver.js.map +1 -1
- package/dist/code-pattern-BP4zkNtT.d.cts +12 -0
- package/dist/code-pattern-BP4zkNtT.d.ts +12 -0
- package/dist/context.cjs +93 -0
- package/dist/context.cjs.map +1 -0
- package/dist/context.d.cts +19 -0
- package/dist/context.d.ts +19 -0
- package/dist/context.js +64 -0
- package/dist/context.js.map +1 -0
- package/dist/countries.cjs +1559 -0
- package/dist/countries.cjs.map +1 -0
- package/dist/countries.d.cts +13 -0
- package/dist/countries.d.ts +13 -0
- package/dist/countries.js +1532 -0
- package/dist/countries.js.map +1 -0
- package/dist/data-table.cjs +1280 -0
- package/dist/data-table.cjs.map +1 -0
- package/dist/data-table.d.cts +123 -0
- package/dist/data-table.d.ts +123 -0
- package/dist/data-table.js +1260 -0
- package/dist/data-table.js.map +1 -0
- package/dist/database.cjs +1510 -0
- package/dist/database.cjs.map +1 -0
- package/dist/database.d.cts +287 -0
- package/dist/database.d.ts +287 -0
- package/dist/database.js +1469 -0
- package/dist/database.js.map +1 -0
- package/dist/decimal.d.cts +0 -1
- package/dist/decimal.d.ts +0 -1
- package/dist/decorators.cjs +1817 -0
- package/dist/decorators.cjs.map +1 -0
- package/dist/decorators.d.cts +24 -0
- package/dist/decorators.d.ts +24 -0
- package/dist/decorators.js +1780 -0
- package/dist/decorators.js.map +1 -0
- package/dist/drizzle-pg-core.cjs +25 -0
- package/dist/drizzle-pg-core.cjs.map +1 -1
- package/dist/drizzle-pg-core.d.cts +7 -0
- package/dist/drizzle-pg-core.d.ts +7 -0
- package/dist/drizzle-pg-core.js +22 -0
- package/dist/drizzle-pg-core.js.map +1 -1
- package/dist/exceptions.cjs +301 -0
- package/dist/exceptions.cjs.map +1 -0
- package/dist/exceptions.d.cts +90 -0
- package/dist/exceptions.d.ts +90 -0
- package/dist/exceptions.js +257 -0
- package/dist/exceptions.js.map +1 -0
- package/dist/filter.types-PuARU9XD.d.cts +50 -0
- package/dist/filter.types-PuARU9XD.d.ts +50 -0
- package/dist/filters.cjs +407 -0
- package/dist/filters.cjs.map +1 -0
- package/dist/filters.d.cts +55 -0
- package/dist/filters.d.ts +55 -0
- package/dist/filters.js +377 -0
- package/dist/filters.js.map +1 -0
- package/dist/index.cjs +0 -5423
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -854
- package/dist/index.d.ts +93 -854
- package/dist/index.js +0 -5301
- package/dist/index.js.map +1 -1
- package/dist/is-country.decorator-CcNwSSr5.d.cts +5 -0
- package/dist/is-country.decorator-CcNwSSr5.d.ts +5 -0
- package/dist/license.d.cts +1 -1
- package/dist/license.d.ts +1 -1
- package/dist/lodash.cjs.map +1 -1
- package/dist/lodash.js.map +1 -1
- package/dist/logger.cjs +862 -0
- package/dist/logger.cjs.map +1 -0
- package/dist/logger.d.cts +118 -0
- package/dist/logger.d.ts +118 -0
- package/dist/logger.js +816 -0
- package/dist/logger.js.map +1 -0
- package/dist/migrate.cjs +2 -2
- package/dist/migrate.cjs.map +1 -1
- package/dist/migrate.d.cts +2 -0
- package/dist/migrate.d.ts +2 -0
- package/dist/migrate.js +2 -2
- package/dist/migrate.js.map +1 -1
- package/dist/money.cjs +18 -3
- package/dist/money.cjs.map +1 -1
- package/dist/money.d.cts +13 -13
- package/dist/money.d.ts +13 -13
- package/dist/money.js +18 -3
- package/dist/money.js.map +1 -1
- package/dist/nats.cjs +34 -35
- package/dist/nats.cjs.map +1 -1
- package/dist/nats.d.cts +14 -14
- package/dist/nats.d.ts +14 -14
- package/dist/nats.js +32 -33
- package/dist/nats.js.map +1 -1
- package/dist/root.cjs +225 -0
- package/dist/root.cjs.map +1 -0
- package/dist/root.d.cts +4 -0
- package/dist/root.d.ts +4 -0
- package/dist/root.js +200 -0
- package/dist/root.js.map +1 -0
- package/dist/{types-DQRwj5rr.d.cts → types-C9jPdQqH.d.cts} +32 -6
- package/dist/{types-DQRwj5rr.d.ts → types-C9jPdQqH.d.ts} +32 -6
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +1 -0
- package/dist/types.d.cts +17 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.cjs +273 -0
- package/dist/utils.cjs.map +1 -0
- package/dist/utils.d.cts +8 -0
- package/dist/utils.d.ts +8 -0
- package/dist/utils.js +245 -0
- package/dist/utils.js.map +1 -0
- package/package.json +122 -1
- package/dist/cache.service-_SuJIcNA.d.cts +0 -20
- package/dist/cache.service-_SuJIcNA.d.ts +0 -20
- package/dist/fastify-augmentation-CQPBNS5a.d.cts +0 -105
- package/dist/fastify-augmentation-CQPBNS5a.d.ts +0 -105
|
@@ -22,38 +22,147 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
22
22
|
var catalog_resolver_exports = {};
|
|
23
23
|
__export(catalog_resolver_exports, {
|
|
24
24
|
PLATFORMS: () => PLATFORMS,
|
|
25
|
+
SITE_TYPES: () => SITE_TYPES,
|
|
25
26
|
SNAPSHOT_SCHEMA_VERSION: () => SNAPSHOT_SCHEMA_VERSION,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
buildDependsMap: () => buildDependsMap,
|
|
28
|
+
buildPlanMatrix: () => buildPlanMatrix,
|
|
29
|
+
buildSiteCatalog: () => buildSiteCatalog,
|
|
30
|
+
buildSiteMatrix: () => buildSiteMatrix,
|
|
31
|
+
buildSiteRoles: () => buildSiteRoles,
|
|
32
|
+
cascadeLocked: () => cascadeLocked,
|
|
29
33
|
composeRoleGrants: () => composeRoleGrants,
|
|
30
|
-
|
|
34
|
+
featureAppliesAtNode: () => featureAppliesAtNode,
|
|
35
|
+
filterGrantedByDeps: () => filterGrantedByDeps,
|
|
36
|
+
findFeatureByCode: () => findFeatureByCode,
|
|
31
37
|
isPlanMember: () => isPlanMember,
|
|
38
|
+
isSiteLockedOnPlatform: () => isSiteLockedOnPlatform,
|
|
32
39
|
pickRouteForPlatform: () => pickRouteForPlatform,
|
|
33
|
-
|
|
40
|
+
prereqClosure: () => prereqClosure,
|
|
41
|
+
resolveUserFeatures: () => resolveUserFeatures,
|
|
42
|
+
snapshotFeatureKey: () => snapshotFeatureKey
|
|
34
43
|
});
|
|
35
44
|
module.exports = __toCommonJS(catalog_resolver_exports);
|
|
36
45
|
|
|
46
|
+
// src/catalog-resolver/permission-deps.ts
|
|
47
|
+
function buildDependsMap(permissions) {
|
|
48
|
+
const present = new Set(permissions.map((p) => p.code));
|
|
49
|
+
const map = /* @__PURE__ */ new Map();
|
|
50
|
+
for (const p of permissions) {
|
|
51
|
+
map.set(p.code, (p.dependsOn ?? []).filter((dep) => dep !== p.code && present.has(dep)));
|
|
52
|
+
}
|
|
53
|
+
return map;
|
|
54
|
+
}
|
|
55
|
+
__name(buildDependsMap, "buildDependsMap");
|
|
56
|
+
function prereqClosure(code, deps) {
|
|
57
|
+
const out = /* @__PURE__ */ new Set();
|
|
58
|
+
const seen = /* @__PURE__ */ new Set([
|
|
59
|
+
code
|
|
60
|
+
]);
|
|
61
|
+
const stack = [
|
|
62
|
+
code
|
|
63
|
+
];
|
|
64
|
+
while (stack.length > 0) {
|
|
65
|
+
const current = stack.pop();
|
|
66
|
+
for (const dep of deps.get(current) ?? []) {
|
|
67
|
+
if (seen.has(dep)) continue;
|
|
68
|
+
seen.add(dep);
|
|
69
|
+
out.add(dep);
|
|
70
|
+
stack.push(dep);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return [
|
|
74
|
+
...out
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
__name(prereqClosure, "prereqClosure");
|
|
78
|
+
function cascadeLocked(codes, directlyLocked, deps) {
|
|
79
|
+
const locked = /* @__PURE__ */ new Set();
|
|
80
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
81
|
+
const check = /* @__PURE__ */ __name((code) => {
|
|
82
|
+
if (locked.has(code)) return true;
|
|
83
|
+
if (directlyLocked.has(code)) {
|
|
84
|
+
locked.add(code);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (visiting.has(code)) return false;
|
|
88
|
+
visiting.add(code);
|
|
89
|
+
const viaDep = (deps.get(code) ?? []).some(check);
|
|
90
|
+
visiting.delete(code);
|
|
91
|
+
if (viaDep) locked.add(code);
|
|
92
|
+
return viaDep;
|
|
93
|
+
}, "check");
|
|
94
|
+
for (const code of codes) check(code);
|
|
95
|
+
return locked;
|
|
96
|
+
}
|
|
97
|
+
__name(cascadeLocked, "cascadeLocked");
|
|
98
|
+
function filterGrantedByDeps(granted, deps) {
|
|
99
|
+
const ok = /* @__PURE__ */ new Set();
|
|
100
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
101
|
+
const check = /* @__PURE__ */ __name((code) => {
|
|
102
|
+
if (ok.has(code)) return true;
|
|
103
|
+
if (!granted.has(code)) return false;
|
|
104
|
+
if (visiting.has(code)) return true;
|
|
105
|
+
visiting.add(code);
|
|
106
|
+
const satisfied = (deps.get(code) ?? []).every(check);
|
|
107
|
+
visiting.delete(code);
|
|
108
|
+
if (satisfied) ok.add(code);
|
|
109
|
+
return satisfied;
|
|
110
|
+
}, "check");
|
|
111
|
+
for (const code of granted) check(code);
|
|
112
|
+
return ok;
|
|
113
|
+
}
|
|
114
|
+
__name(filterGrantedByDeps, "filterGrantedByDeps");
|
|
115
|
+
|
|
116
|
+
// src/catalog-resolver/types.ts
|
|
117
|
+
var PLATFORMS = [
|
|
118
|
+
"web",
|
|
119
|
+
"mobile"
|
|
120
|
+
];
|
|
121
|
+
var SITE_TYPES = [
|
|
122
|
+
"OUTLET",
|
|
123
|
+
"WAREHOUSE",
|
|
124
|
+
"PRODUCTION"
|
|
125
|
+
];
|
|
126
|
+
function snapshotFeatureKey(code, scope) {
|
|
127
|
+
return `${scope}.${code}`;
|
|
128
|
+
}
|
|
129
|
+
__name(snapshotFeatureKey, "snapshotFeatureKey");
|
|
130
|
+
var SNAPSHOT_SCHEMA_VERSION = 2;
|
|
131
|
+
|
|
37
132
|
// src/catalog-resolver/catalog.builder.ts
|
|
38
|
-
function
|
|
133
|
+
function featureAppliesAtNode(applicableSiteTypes, siteType) {
|
|
134
|
+
return applicableSiteTypes.includes(siteType);
|
|
135
|
+
}
|
|
136
|
+
__name(featureAppliesAtNode, "featureAppliesAtNode");
|
|
137
|
+
function findFeatureByCode(snapshot, code) {
|
|
138
|
+
for (const feature of Object.values(snapshot.features ?? {})) {
|
|
139
|
+
if (feature?.code === code) return feature;
|
|
140
|
+
}
|
|
141
|
+
return void 0;
|
|
142
|
+
}
|
|
143
|
+
__name(findFeatureByCode, "findFeatureByCode");
|
|
144
|
+
function buildSiteCatalog(snapshot, businessCode, planCode, siteLocks, bucket, siteType, scope) {
|
|
39
145
|
if (!businessCode) return [];
|
|
40
146
|
const business = snapshot.businesses?.[businessCode];
|
|
41
147
|
if (!business) return [];
|
|
42
148
|
const plan = planCode ? business.plans?.[planCode] : void 0;
|
|
43
149
|
const plans = business.plans ?? {};
|
|
44
150
|
const catalog = [];
|
|
45
|
-
|
|
46
|
-
|
|
151
|
+
const sortedApps = [
|
|
152
|
+
...business.apps
|
|
153
|
+
].sort((a, b) => a.name.localeCompare(b.name));
|
|
154
|
+
for (const app of sortedApps) {
|
|
155
|
+
const businessAppFeatures = app.features.filter((ref) => scope === void 0 || ref.scope === scope).map((ref) => snapshot.features?.[snapshotFeatureKey(ref.code, ref.scope)]).filter((f) => !!f && !!(f.microfrontends?.web || f.microfrontends?.mobile) && (siteType === void 0 || featureAppliesAtNode(f.applicableSiteTypes, siteType)));
|
|
47
156
|
if (businessAppFeatures.length === 0) continue;
|
|
48
157
|
for (const feature of businessAppFeatures) {
|
|
49
158
|
const membership = plan?.unlockedPermissions?.[feature.code];
|
|
50
159
|
const web = feature.microfrontends?.web;
|
|
51
160
|
const mobile = feature.microfrontends?.mobile;
|
|
52
|
-
const permissions = buildPermissions(feature, businessCode, membership,
|
|
161
|
+
const permissions = buildPermissions(feature, businessCode, membership, siteLocks, plans, bucket);
|
|
53
162
|
const memberOnBucket = membership?.[bucket] !== void 0;
|
|
54
|
-
const
|
|
55
|
-
const locked = !memberOnBucket ||
|
|
56
|
-
const lockReason = !memberOnBucket ? "PLAN" :
|
|
163
|
+
const sitePlatformLocked = siteLocks?.[feature.code]?.[bucket] === null;
|
|
164
|
+
const locked = !memberOnBucket || sitePlatformLocked;
|
|
165
|
+
const lockReason = !memberOnBucket ? "PLAN" : sitePlatformLocked ? "SITE" : null;
|
|
57
166
|
const unlockPlans = lockReason === "PLAN" ? plansIncludingFeature(plans, feature.code, bucket) : [];
|
|
58
167
|
catalog.push({
|
|
59
168
|
code: feature.code,
|
|
@@ -85,25 +194,43 @@ function buildBuCatalog(snapshot, businessCode, planCode, buLocks, bucket) {
|
|
|
85
194
|
}
|
|
86
195
|
return catalog;
|
|
87
196
|
}
|
|
88
|
-
__name(
|
|
197
|
+
__name(buildSiteCatalog, "buildSiteCatalog");
|
|
89
198
|
function isPlanMember(entry) {
|
|
90
199
|
return !!entry && (entry.web !== void 0 || entry.mobile !== void 0);
|
|
91
200
|
}
|
|
92
201
|
__name(isPlanMember, "isPlanMember");
|
|
93
|
-
function
|
|
202
|
+
function isSiteLockedOnPlatform(entry, platform, code) {
|
|
94
203
|
const locks = entry?.[platform];
|
|
95
204
|
return locks === null || (locks?.includes(code) ?? false);
|
|
96
205
|
}
|
|
97
|
-
__name(
|
|
98
|
-
function buildPermissions(feature, businessCode, planMembership,
|
|
206
|
+
__name(isSiteLockedOnPlatform, "isSiteLockedOnPlatform");
|
|
207
|
+
function buildPermissions(feature, businessCode, planMembership, siteLocks, plans, bucket) {
|
|
99
208
|
const planUnlocked = new Set(planMembership?.[bucket] ?? []);
|
|
100
|
-
const lockEntry =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
209
|
+
const lockEntry = siteLocks?.[feature.code];
|
|
210
|
+
const perms = (feature.permissions ?? []).filter((p) => p.isGlobal || p.businesses.includes(businessCode));
|
|
211
|
+
const deps = buildDependsMap(perms);
|
|
212
|
+
const codes = perms.map((p) => p.code);
|
|
213
|
+
const directlyPlanLocked = /* @__PURE__ */ new Set();
|
|
214
|
+
const directlySiteLocked = /* @__PURE__ */ new Set();
|
|
215
|
+
for (const p of perms) {
|
|
216
|
+
if (!planUnlocked.has(p.code)) directlyPlanLocked.add(p.code);
|
|
217
|
+
if (isSiteLockedOnPlatform(lockEntry, bucket, p.code)) directlySiteLocked.add(p.code);
|
|
218
|
+
}
|
|
219
|
+
const directlyLocked = /* @__PURE__ */ new Set([
|
|
220
|
+
...directlyPlanLocked,
|
|
221
|
+
...directlySiteLocked
|
|
222
|
+
]);
|
|
223
|
+
const lockedSet = cascadeLocked(codes, directlyLocked, deps);
|
|
224
|
+
return perms.map((p) => {
|
|
225
|
+
const locked = lockedSet.has(p.code);
|
|
226
|
+
const closure = [
|
|
227
|
+
p.code,
|
|
228
|
+
...prereqClosure(p.code, deps)
|
|
229
|
+
];
|
|
230
|
+
const planReason = closure.some((c) => directlyPlanLocked.has(c));
|
|
231
|
+
const siteReason = closure.some((c) => directlySiteLocked.has(c));
|
|
232
|
+
const lockReason = !locked ? null : planReason ? "PLAN" : siteReason ? "SITE" : null;
|
|
233
|
+
const unlockPlans = locked && lockReason === "PLAN" ? plansUnlockingClosure(plans, feature.code, closure, bucket) : [];
|
|
107
234
|
return {
|
|
108
235
|
code: p.code,
|
|
109
236
|
locked,
|
|
@@ -113,14 +240,15 @@ function buildPermissions(feature, businessCode, planMembership, buLocks, plans,
|
|
|
113
240
|
});
|
|
114
241
|
}
|
|
115
242
|
__name(buildPermissions, "buildPermissions");
|
|
116
|
-
function
|
|
243
|
+
function plansUnlockingClosure(plans, featureCode, closure, bucket) {
|
|
117
244
|
const result = [];
|
|
118
245
|
for (const [code, plan] of Object.entries(plans)) {
|
|
119
|
-
|
|
246
|
+
const unlocked = plan.unlockedPermissions?.[featureCode]?.[bucket];
|
|
247
|
+
if (unlocked && closure.every((c) => unlocked.includes(c))) result.push(code);
|
|
120
248
|
}
|
|
121
249
|
return result;
|
|
122
250
|
}
|
|
123
|
-
__name(
|
|
251
|
+
__name(plansUnlockingClosure, "plansUnlockingClosure");
|
|
124
252
|
function plansIncludingFeature(plans, featureCode, bucket) {
|
|
125
253
|
const result = [];
|
|
126
254
|
for (const [code, plan] of Object.entries(plans)) {
|
|
@@ -129,23 +257,24 @@ function plansIncludingFeature(plans, featureCode, bucket) {
|
|
|
129
257
|
return result;
|
|
130
258
|
}
|
|
131
259
|
__name(plansIncludingFeature, "plansIncludingFeature");
|
|
132
|
-
function
|
|
260
|
+
function buildSiteRoles(snapshot, businessCode) {
|
|
133
261
|
if (!businessCode) return [];
|
|
134
262
|
const business = snapshot.businesses?.[businessCode];
|
|
135
263
|
if (!business) return [];
|
|
136
264
|
return Object.values(business.roleTemplates ?? {});
|
|
137
265
|
}
|
|
138
|
-
__name(
|
|
266
|
+
__name(buildSiteRoles, "buildSiteRoles");
|
|
139
267
|
|
|
140
|
-
// src/catalog-resolver/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
268
|
+
// src/catalog-resolver/site-matrix.builder.ts
|
|
269
|
+
function buildSiteMatrix(snapshot, businessCode, planCode, siteLocks, siteType) {
|
|
270
|
+
return buildMatrix(snapshot, businessCode, planCode, siteLocks, false, siteType);
|
|
271
|
+
}
|
|
272
|
+
__name(buildSiteMatrix, "buildSiteMatrix");
|
|
273
|
+
function buildPlanMatrix(snapshot, businessCode, planCode, siteLocks) {
|
|
274
|
+
return buildMatrix(snapshot, businessCode, planCode, siteLocks, true);
|
|
275
|
+
}
|
|
276
|
+
__name(buildPlanMatrix, "buildPlanMatrix");
|
|
277
|
+
function buildMatrix(snapshot, businessCode, planCode, siteLocks, allScopes, siteType) {
|
|
149
278
|
const business = businessCode ? snapshot.businesses?.[businessCode] : void 0;
|
|
150
279
|
const plans = business?.plans ?? {};
|
|
151
280
|
const plan = planCode ? plans[planCode] : void 0;
|
|
@@ -153,7 +282,7 @@ function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
|
153
282
|
code: planCode ?? "",
|
|
154
283
|
name: plan?.name ?? planCode ?? ""
|
|
155
284
|
};
|
|
156
|
-
const locks =
|
|
285
|
+
const locks = siteLocks ?? {};
|
|
157
286
|
if (!business || !plan) return {
|
|
158
287
|
plan: planMeta,
|
|
159
288
|
apps: [],
|
|
@@ -164,20 +293,23 @@ function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
|
164
293
|
let unlockedCount = 0;
|
|
165
294
|
let totalCount = 0;
|
|
166
295
|
const features = [];
|
|
167
|
-
for (const
|
|
168
|
-
|
|
296
|
+
for (const ref of app.features) {
|
|
297
|
+
if (!allScopes && ref.scope !== "SITE") continue;
|
|
298
|
+
const code = ref.code;
|
|
299
|
+
const feature = snapshot.features?.[snapshotFeatureKey(code, ref.scope)];
|
|
169
300
|
if (!feature) continue;
|
|
301
|
+
if (siteType !== void 0 && !featureAppliesAtNode(feature.applicableSiteTypes, siteType)) continue;
|
|
170
302
|
const platforms = PLATFORMS.filter((p) => !!feature.microfrontends?.[p]);
|
|
171
303
|
if (platforms.length === 0) continue;
|
|
172
304
|
const membership = plan.unlockedPermissions?.[code];
|
|
173
305
|
const featureInPlan = isPlanMember(membership);
|
|
174
|
-
const
|
|
306
|
+
const siteEntry = siteLocks?.[code];
|
|
175
307
|
const permissions = (feature.permissions ?? []).filter((p) => p.isGlobal || p.businesses.includes(businessCode ?? "")).map((p) => {
|
|
176
308
|
const cell = /* @__PURE__ */ __name((plat) => {
|
|
177
309
|
if (!platforms.includes(plat)) return null;
|
|
178
310
|
const planCodes = membership?.[plat];
|
|
179
311
|
const inPlan = featureInPlan && planCodes !== void 0 && planCodes.includes(p.code);
|
|
180
|
-
const selected = inPlan && !
|
|
312
|
+
const selected = inPlan && !isSiteLockedOnPlatform(siteEntry, plat, p.code);
|
|
181
313
|
const availableIn = inPlan ? [] : plansUnlockingPerm(plans, code, p.code, plat, planCode);
|
|
182
314
|
totalCount += 1;
|
|
183
315
|
if (inPlan) unlockedCount += 1;
|
|
@@ -190,6 +322,7 @@ function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
|
190
322
|
return {
|
|
191
323
|
code: p.code,
|
|
192
324
|
label: p.label,
|
|
325
|
+
dependsOn: p.dependsOn ?? [],
|
|
193
326
|
web: cell("web"),
|
|
194
327
|
mobile: cell("mobile")
|
|
195
328
|
};
|
|
@@ -198,12 +331,15 @@ function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
|
198
331
|
code: feature.code,
|
|
199
332
|
name: feature.name,
|
|
200
333
|
icon: feature.lucideIcon ?? null,
|
|
334
|
+
scope: feature.scope,
|
|
335
|
+
applicableSiteTypes: feature.applicableSiteTypes,
|
|
201
336
|
platforms,
|
|
202
337
|
inPlan: featureInPlan,
|
|
203
338
|
availableIn: featureInPlan ? [] : plansIncludingFeature2(plans, code, planCode),
|
|
204
339
|
permissions
|
|
205
340
|
});
|
|
206
341
|
}
|
|
342
|
+
if (features.length === 0) continue;
|
|
207
343
|
apps.push({
|
|
208
344
|
code: app.code,
|
|
209
345
|
name: app.name,
|
|
@@ -213,13 +349,14 @@ function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
|
213
349
|
features
|
|
214
350
|
});
|
|
215
351
|
}
|
|
352
|
+
apps.sort((a, b) => a.name.localeCompare(b.name));
|
|
216
353
|
return {
|
|
217
354
|
plan: planMeta,
|
|
218
355
|
apps,
|
|
219
356
|
locks
|
|
220
357
|
};
|
|
221
358
|
}
|
|
222
|
-
__name(
|
|
359
|
+
__name(buildMatrix, "buildMatrix");
|
|
223
360
|
function plansUnlockingPerm(plans, featureCode, permCode, platform, excludeCode) {
|
|
224
361
|
const names = [];
|
|
225
362
|
for (const [code, p] of Object.entries(plans)) {
|
|
@@ -278,13 +415,35 @@ __name(composeRoleGrants, "composeRoleGrants");
|
|
|
278
415
|
|
|
279
416
|
// src/catalog-resolver/resolve-user-features.ts
|
|
280
417
|
function resolveUserFeatures(params) {
|
|
281
|
-
const { snapshot, businessCode, planCode,
|
|
418
|
+
const { snapshot, businessCode, planCode, siteLocks, roleFeatures, platform, siteType, scope } = params;
|
|
282
419
|
const bucket = platform === "web" ? "web" : "mobile";
|
|
283
|
-
const
|
|
420
|
+
const featureByCode = /* @__PURE__ */ __name((code) => scope ? snapshot.features?.[snapshotFeatureKey(code, scope)] : findFeatureByCode(snapshot, code), "featureByCode");
|
|
421
|
+
const catalog = buildSiteCatalog(snapshot, businessCode, planCode, siteLocks, bucket, siteType, scope);
|
|
284
422
|
const catalogMap = new Map(catalog.map((f) => [
|
|
285
423
|
f.code,
|
|
286
424
|
f
|
|
287
425
|
]));
|
|
426
|
+
const businessPlans = snapshot.businesses[businessCode]?.plans ?? {};
|
|
427
|
+
const currentUnlockedCodes = /* @__PURE__ */ new Set();
|
|
428
|
+
if (planCode && businessPlans[planCode]) {
|
|
429
|
+
for (const [featureCode, platforms] of Object.entries(businessPlans[planCode].unlockedPermissions ?? {})) {
|
|
430
|
+
if (platforms?.[bucket] !== void 0) currentUnlockedCodes.add(featureCode);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
const planAdds = /* @__PURE__ */ new Map();
|
|
434
|
+
for (const [planKey, plan] of Object.entries(businessPlans)) {
|
|
435
|
+
if (planKey === planCode) continue;
|
|
436
|
+
const adds = [];
|
|
437
|
+
for (const [featureCode, platforms] of Object.entries(plan.unlockedPermissions ?? {})) {
|
|
438
|
+
if (platforms?.[bucket] === void 0 || currentUnlockedCodes.has(featureCode)) continue;
|
|
439
|
+
const name = featureByCode(featureCode)?.name;
|
|
440
|
+
if (name) adds.push({
|
|
441
|
+
code: featureCode,
|
|
442
|
+
name
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
planAdds.set(planKey, adds);
|
|
446
|
+
}
|
|
288
447
|
const grantedFeatures = /* @__PURE__ */ new Map();
|
|
289
448
|
for (const [code, grant] of Object.entries(roleFeatures ?? {})) {
|
|
290
449
|
const granted = grant?.[bucket];
|
|
@@ -298,18 +457,23 @@ function resolveUserFeatures(params) {
|
|
|
298
457
|
if (!catalogEntry) continue;
|
|
299
458
|
const route = pickRouteForPlatform(catalogEntry, platform);
|
|
300
459
|
if (!route) continue;
|
|
460
|
+
const featureDeps = buildDependsMap(featureByCode(code)?.permissions ?? []);
|
|
301
461
|
const permByCode = new Map((catalogEntry.permissions ?? []).map((p) => [
|
|
302
462
|
p.code,
|
|
303
463
|
p
|
|
304
464
|
]));
|
|
305
465
|
const grantedPerms = [
|
|
306
|
-
...permsSet
|
|
466
|
+
...filterGrantedByDeps(permsSet, featureDeps)
|
|
307
467
|
];
|
|
308
468
|
const lockedPermissions = grantedPerms.map((c) => permByCode.get(c)).filter((p) => !!p?.locked).map((p) => ({
|
|
309
469
|
code: p.code,
|
|
310
470
|
reason: p.lockReason ?? null,
|
|
311
471
|
unlockPlans: p.unlockPlans ?? []
|
|
312
472
|
}));
|
|
473
|
+
const upsell = catalogEntry.locked && catalogEntry.lockReason === "PLAN" ? (catalogEntry.unlockPlans ?? []).map((plan) => ({
|
|
474
|
+
plan,
|
|
475
|
+
features: (planAdds.get(plan) ?? []).filter((f) => f.code !== code).map((f) => f.name)
|
|
476
|
+
})).filter((group) => group.features.length > 0) : [];
|
|
313
477
|
features.push({
|
|
314
478
|
code,
|
|
315
479
|
name: catalogEntry.name,
|
|
@@ -321,6 +485,7 @@ function resolveUserFeatures(params) {
|
|
|
321
485
|
lockReason: catalogEntry.lockReason ?? null,
|
|
322
486
|
unlockPlans: catalogEntry.unlockPlans ?? [],
|
|
323
487
|
lockedPermissions,
|
|
488
|
+
upsell,
|
|
324
489
|
route,
|
|
325
490
|
appCode: catalogEntry.appCode,
|
|
326
491
|
appName: catalogEntry.appName,
|
|
@@ -328,6 +493,7 @@ function resolveUserFeatures(params) {
|
|
|
328
493
|
appSortOrder: catalogEntry.appSortOrder
|
|
329
494
|
});
|
|
330
495
|
}
|
|
496
|
+
features.sort((a, b) => a.appName.localeCompare(b.appName));
|
|
331
497
|
return features;
|
|
332
498
|
}
|
|
333
499
|
__name(resolveUserFeatures, "resolveUserFeatures");
|
|
@@ -351,14 +517,23 @@ __name(pickRouteForPlatform, "pickRouteForPlatform");
|
|
|
351
517
|
// Annotate the CommonJS export names for ESM import in node:
|
|
352
518
|
0 && (module.exports = {
|
|
353
519
|
PLATFORMS,
|
|
520
|
+
SITE_TYPES,
|
|
354
521
|
SNAPSHOT_SCHEMA_VERSION,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
522
|
+
buildDependsMap,
|
|
523
|
+
buildPlanMatrix,
|
|
524
|
+
buildSiteCatalog,
|
|
525
|
+
buildSiteMatrix,
|
|
526
|
+
buildSiteRoles,
|
|
527
|
+
cascadeLocked,
|
|
358
528
|
composeRoleGrants,
|
|
359
|
-
|
|
529
|
+
featureAppliesAtNode,
|
|
530
|
+
filterGrantedByDeps,
|
|
531
|
+
findFeatureByCode,
|
|
360
532
|
isPlanMember,
|
|
533
|
+
isSiteLockedOnPlatform,
|
|
361
534
|
pickRouteForPlatform,
|
|
362
|
-
|
|
535
|
+
prereqClosure,
|
|
536
|
+
resolveUserFeatures,
|
|
537
|
+
snapshotFeatureKey
|
|
363
538
|
});
|
|
364
539
|
//# sourceMappingURL=catalog-resolver.cjs.map
|