@vritti/api-sdk 0.3.3 → 0.3.6
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 +337 -140
- package/dist/catalog-resolver.cjs.map +1 -1
- package/dist/catalog-resolver.d.cts +70 -45
- package/dist/catalog-resolver.d.ts +70 -45
- package/dist/catalog-resolver.js +322 -135
- 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-BBK6MG-U.d.cts} +37 -6
- package/dist/{types-DQRwj5rr.d.ts → types-BBK6MG-U.d.ts} +37 -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,152 @@ 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
|
+
SERVICE_CODES: () => SERVICE_CODES,
|
|
26
|
+
SITE_TYPES: () => SITE_TYPES,
|
|
25
27
|
SNAPSHOT_SCHEMA_VERSION: () => SNAPSHOT_SCHEMA_VERSION,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
buildDependsMap: () => buildDependsMap,
|
|
29
|
+
buildPlanMatrix: () => buildPlanMatrix,
|
|
30
|
+
buildSiteCatalog: () => buildSiteCatalog,
|
|
31
|
+
buildSiteMatrix: () => buildSiteMatrix,
|
|
32
|
+
buildSiteRoles: () => buildSiteRoles,
|
|
33
|
+
cascadeLocked: () => cascadeLocked,
|
|
29
34
|
composeRoleGrants: () => composeRoleGrants,
|
|
30
|
-
|
|
35
|
+
featureAppliesAtNode: () => featureAppliesAtNode,
|
|
36
|
+
filterGrantedByDeps: () => filterGrantedByDeps,
|
|
37
|
+
findFeatureByCode: () => findFeatureByCode,
|
|
31
38
|
isPlanMember: () => isPlanMember,
|
|
39
|
+
isSiteLockedOnPlatform: () => isSiteLockedOnPlatform,
|
|
32
40
|
pickRouteForPlatform: () => pickRouteForPlatform,
|
|
33
|
-
|
|
41
|
+
prereqClosure: () => prereqClosure,
|
|
42
|
+
resolveUserFeatures: () => resolveUserFeatures,
|
|
43
|
+
snapshotFeatureKey: () => snapshotFeatureKey
|
|
34
44
|
});
|
|
35
45
|
module.exports = __toCommonJS(catalog_resolver_exports);
|
|
36
46
|
|
|
47
|
+
// src/catalog-resolver/permission-deps.ts
|
|
48
|
+
function buildDependsMap(permissions) {
|
|
49
|
+
const present = new Set(permissions.map((p) => p.code));
|
|
50
|
+
const map = /* @__PURE__ */ new Map();
|
|
51
|
+
for (const p of permissions) {
|
|
52
|
+
map.set(p.code, (p.dependsOn ?? []).filter((dep) => dep !== p.code && present.has(dep)));
|
|
53
|
+
}
|
|
54
|
+
return map;
|
|
55
|
+
}
|
|
56
|
+
__name(buildDependsMap, "buildDependsMap");
|
|
57
|
+
function prereqClosure(code, deps) {
|
|
58
|
+
const out = /* @__PURE__ */ new Set();
|
|
59
|
+
const seen = /* @__PURE__ */ new Set([
|
|
60
|
+
code
|
|
61
|
+
]);
|
|
62
|
+
const stack = [
|
|
63
|
+
code
|
|
64
|
+
];
|
|
65
|
+
while (stack.length > 0) {
|
|
66
|
+
const current = stack.pop();
|
|
67
|
+
for (const dep of deps.get(current) ?? []) {
|
|
68
|
+
if (seen.has(dep)) continue;
|
|
69
|
+
seen.add(dep);
|
|
70
|
+
out.add(dep);
|
|
71
|
+
stack.push(dep);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return [
|
|
75
|
+
...out
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
__name(prereqClosure, "prereqClosure");
|
|
79
|
+
function cascadeLocked(codes, directlyLocked, deps) {
|
|
80
|
+
const locked = /* @__PURE__ */ new Set();
|
|
81
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
82
|
+
const check = /* @__PURE__ */ __name((code) => {
|
|
83
|
+
if (locked.has(code)) return true;
|
|
84
|
+
if (directlyLocked.has(code)) {
|
|
85
|
+
locked.add(code);
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
if (visiting.has(code)) return false;
|
|
89
|
+
visiting.add(code);
|
|
90
|
+
const viaDep = (deps.get(code) ?? []).some(check);
|
|
91
|
+
visiting.delete(code);
|
|
92
|
+
if (viaDep) locked.add(code);
|
|
93
|
+
return viaDep;
|
|
94
|
+
}, "check");
|
|
95
|
+
for (const code of codes) check(code);
|
|
96
|
+
return locked;
|
|
97
|
+
}
|
|
98
|
+
__name(cascadeLocked, "cascadeLocked");
|
|
99
|
+
function filterGrantedByDeps(granted, deps) {
|
|
100
|
+
const ok = /* @__PURE__ */ new Set();
|
|
101
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
102
|
+
const check = /* @__PURE__ */ __name((code) => {
|
|
103
|
+
if (ok.has(code)) return true;
|
|
104
|
+
if (!granted.has(code)) return false;
|
|
105
|
+
if (visiting.has(code)) return true;
|
|
106
|
+
visiting.add(code);
|
|
107
|
+
const satisfied = (deps.get(code) ?? []).every(check);
|
|
108
|
+
visiting.delete(code);
|
|
109
|
+
if (satisfied) ok.add(code);
|
|
110
|
+
return satisfied;
|
|
111
|
+
}, "check");
|
|
112
|
+
for (const code of granted) check(code);
|
|
113
|
+
return ok;
|
|
114
|
+
}
|
|
115
|
+
__name(filterGrantedByDeps, "filterGrantedByDeps");
|
|
116
|
+
|
|
117
|
+
// src/catalog-resolver/types.ts
|
|
118
|
+
var PLATFORMS = [
|
|
119
|
+
"web",
|
|
120
|
+
"mobile"
|
|
121
|
+
];
|
|
122
|
+
var SITE_TYPES = [
|
|
123
|
+
"OUTLET",
|
|
124
|
+
"WAREHOUSE",
|
|
125
|
+
"PRODUCTION"
|
|
126
|
+
];
|
|
127
|
+
var SERVICE_CODES = [
|
|
128
|
+
"GITEA"
|
|
129
|
+
];
|
|
130
|
+
function snapshotFeatureKey(code, scope) {
|
|
131
|
+
return `${scope}.${code}`;
|
|
132
|
+
}
|
|
133
|
+
__name(snapshotFeatureKey, "snapshotFeatureKey");
|
|
134
|
+
var SNAPSHOT_SCHEMA_VERSION = 2;
|
|
135
|
+
|
|
37
136
|
// src/catalog-resolver/catalog.builder.ts
|
|
38
|
-
function
|
|
137
|
+
function featureAppliesAtNode(applicableSiteTypes, siteType) {
|
|
138
|
+
return applicableSiteTypes.includes(siteType);
|
|
139
|
+
}
|
|
140
|
+
__name(featureAppliesAtNode, "featureAppliesAtNode");
|
|
141
|
+
function findFeatureByCode(snapshot, code) {
|
|
142
|
+
for (const feature of Object.values(snapshot.features ?? {})) {
|
|
143
|
+
if (feature?.code === code) return feature;
|
|
144
|
+
}
|
|
145
|
+
return void 0;
|
|
146
|
+
}
|
|
147
|
+
__name(findFeatureByCode, "findFeatureByCode");
|
|
148
|
+
function buildSiteCatalog(snapshot, businessCode, planCode, siteLocks, bucket, siteType, scope, availableServices = []) {
|
|
39
149
|
if (!businessCode) return [];
|
|
40
150
|
const business = snapshot.businesses?.[businessCode];
|
|
41
151
|
if (!business) return [];
|
|
42
152
|
const plan = planCode ? business.plans?.[planCode] : void 0;
|
|
43
153
|
const plans = business.plans ?? {};
|
|
44
154
|
const catalog = [];
|
|
45
|
-
|
|
46
|
-
|
|
155
|
+
const sortedApps = [
|
|
156
|
+
...business.apps
|
|
157
|
+
].sort((a, b) => a.name.localeCompare(b.name));
|
|
158
|
+
for (const app of sortedApps) {
|
|
159
|
+
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
160
|
if (businessAppFeatures.length === 0) continue;
|
|
48
161
|
for (const feature of businessAppFeatures) {
|
|
49
162
|
const membership = plan?.unlockedPermissions?.[feature.code];
|
|
50
163
|
const web = feature.microfrontends?.web;
|
|
51
164
|
const mobile = feature.microfrontends?.mobile;
|
|
52
|
-
const permissions = buildPermissions(feature, businessCode, membership, buLocks, plans, bucket);
|
|
53
165
|
const memberOnBucket = membership?.[bucket] !== void 0;
|
|
54
|
-
const
|
|
55
|
-
const
|
|
56
|
-
const
|
|
166
|
+
const sitePlatformLocked = siteLocks?.[feature.code]?.[bucket] === null;
|
|
167
|
+
const missingServices = unmetServices(feature, availableServices);
|
|
168
|
+
const permissions = buildPermissions(feature, businessCode, membership, siteLocks, plans, bucket, missingServices);
|
|
169
|
+
const lockReason = resolveLockReason(!memberOnBucket, sitePlatformLocked, missingServices);
|
|
170
|
+
const locked = lockReason !== null;
|
|
57
171
|
const unlockPlans = lockReason === "PLAN" ? plansIncludingFeature(plans, feature.code, bucket) : [];
|
|
58
172
|
catalog.push({
|
|
59
173
|
code: feature.code,
|
|
@@ -79,48 +193,81 @@ function buildBuCatalog(snapshot, businessCode, planCode, buLocks, bucket) {
|
|
|
79
193
|
locked,
|
|
80
194
|
lockReason,
|
|
81
195
|
unlockPlans,
|
|
196
|
+
missingServices,
|
|
82
197
|
permissions
|
|
83
198
|
});
|
|
84
199
|
}
|
|
85
200
|
}
|
|
86
201
|
return catalog;
|
|
87
202
|
}
|
|
88
|
-
__name(
|
|
203
|
+
__name(buildSiteCatalog, "buildSiteCatalog");
|
|
89
204
|
function isPlanMember(entry) {
|
|
90
205
|
return !!entry && (entry.web !== void 0 || entry.mobile !== void 0);
|
|
91
206
|
}
|
|
92
207
|
__name(isPlanMember, "isPlanMember");
|
|
93
|
-
function
|
|
208
|
+
function resolveLockReason(planLocked, siteLocked, missingServices) {
|
|
209
|
+
if (planLocked) return "PLAN";
|
|
210
|
+
if (siteLocked) return "SITE";
|
|
211
|
+
if (missingServices.length > 0) return "SERVICE";
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
__name(resolveLockReason, "resolveLockReason");
|
|
215
|
+
function unmetServices(feature, availableServices) {
|
|
216
|
+
return (feature.requiredServices ?? []).filter((service) => !availableServices.includes(service));
|
|
217
|
+
}
|
|
218
|
+
__name(unmetServices, "unmetServices");
|
|
219
|
+
function isSiteLockedOnPlatform(entry, platform, code) {
|
|
94
220
|
const locks = entry?.[platform];
|
|
95
221
|
return locks === null || (locks?.includes(code) ?? false);
|
|
96
222
|
}
|
|
97
|
-
__name(
|
|
98
|
-
function buildPermissions(feature, businessCode, planMembership,
|
|
223
|
+
__name(isSiteLockedOnPlatform, "isSiteLockedOnPlatform");
|
|
224
|
+
function buildPermissions(feature, businessCode, planMembership, siteLocks, plans, bucket, missingServices = []) {
|
|
99
225
|
const planUnlocked = new Set(planMembership?.[bucket] ?? []);
|
|
100
|
-
const lockEntry =
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
226
|
+
const lockEntry = siteLocks?.[feature.code];
|
|
227
|
+
const perms = (feature.permissions ?? []).filter((p) => p.isGlobal || p.businesses.includes(businessCode));
|
|
228
|
+
const deps = buildDependsMap(perms);
|
|
229
|
+
const codes = perms.map((p) => p.code);
|
|
230
|
+
const directlyPlanLocked = /* @__PURE__ */ new Set();
|
|
231
|
+
const directlySiteLocked = /* @__PURE__ */ new Set();
|
|
232
|
+
for (const p of perms) {
|
|
233
|
+
if (!planUnlocked.has(p.code)) directlyPlanLocked.add(p.code);
|
|
234
|
+
if (isSiteLockedOnPlatform(lockEntry, bucket, p.code)) directlySiteLocked.add(p.code);
|
|
235
|
+
}
|
|
236
|
+
const directlyLocked = /* @__PURE__ */ new Set([
|
|
237
|
+
...directlyPlanLocked,
|
|
238
|
+
...directlySiteLocked
|
|
239
|
+
]);
|
|
240
|
+
const lockedSet = cascadeLocked(codes, directlyLocked, deps);
|
|
241
|
+
return perms.map((p) => {
|
|
242
|
+
const closure = [
|
|
243
|
+
p.code,
|
|
244
|
+
...prereqClosure(p.code, deps)
|
|
245
|
+
];
|
|
246
|
+
const cascaded = lockedSet.has(p.code);
|
|
247
|
+
const planReason = cascaded && closure.some((c) => directlyPlanLocked.has(c));
|
|
248
|
+
const siteReason = cascaded && closure.some((c) => directlySiteLocked.has(c));
|
|
249
|
+
const lockReason = resolveLockReason(planReason, siteReason, missingServices);
|
|
250
|
+
const locked = lockReason !== null;
|
|
251
|
+
const unlockPlans = lockReason === "PLAN" ? plansUnlockingClosure(plans, feature.code, closure, bucket) : [];
|
|
107
252
|
return {
|
|
108
253
|
code: p.code,
|
|
109
254
|
locked,
|
|
110
255
|
lockReason,
|
|
111
|
-
unlockPlans
|
|
256
|
+
unlockPlans,
|
|
257
|
+
missingServices
|
|
112
258
|
};
|
|
113
259
|
});
|
|
114
260
|
}
|
|
115
261
|
__name(buildPermissions, "buildPermissions");
|
|
116
|
-
function
|
|
262
|
+
function plansUnlockingClosure(plans, featureCode, closure, bucket) {
|
|
117
263
|
const result = [];
|
|
118
264
|
for (const [code, plan] of Object.entries(plans)) {
|
|
119
|
-
|
|
265
|
+
const unlocked = plan.unlockedPermissions?.[featureCode]?.[bucket];
|
|
266
|
+
if (unlocked && closure.every((c) => unlocked.includes(c))) result.push(code);
|
|
120
267
|
}
|
|
121
268
|
return result;
|
|
122
269
|
}
|
|
123
|
-
__name(
|
|
270
|
+
__name(plansUnlockingClosure, "plansUnlockingClosure");
|
|
124
271
|
function plansIncludingFeature(plans, featureCode, bucket) {
|
|
125
272
|
const result = [];
|
|
126
273
|
for (const [code, plan] of Object.entries(plans)) {
|
|
@@ -129,115 +276,13 @@ function plansIncludingFeature(plans, featureCode, bucket) {
|
|
|
129
276
|
return result;
|
|
130
277
|
}
|
|
131
278
|
__name(plansIncludingFeature, "plansIncludingFeature");
|
|
132
|
-
function
|
|
279
|
+
function buildSiteRoles(snapshot, businessCode) {
|
|
133
280
|
if (!businessCode) return [];
|
|
134
281
|
const business = snapshot.businesses?.[businessCode];
|
|
135
282
|
if (!business) return [];
|
|
136
283
|
return Object.values(business.roleTemplates ?? {});
|
|
137
284
|
}
|
|
138
|
-
__name(
|
|
139
|
-
|
|
140
|
-
// src/catalog-resolver/types.ts
|
|
141
|
-
var PLATFORMS = [
|
|
142
|
-
"web",
|
|
143
|
-
"mobile"
|
|
144
|
-
];
|
|
145
|
-
var SNAPSHOT_SCHEMA_VERSION = 1;
|
|
146
|
-
|
|
147
|
-
// src/catalog-resolver/bu-matrix.builder.ts
|
|
148
|
-
function buildBuMatrix(snapshot, businessCode, planCode, buLocks) {
|
|
149
|
-
const business = businessCode ? snapshot.businesses?.[businessCode] : void 0;
|
|
150
|
-
const plans = business?.plans ?? {};
|
|
151
|
-
const plan = planCode ? plans[planCode] : void 0;
|
|
152
|
-
const planMeta = {
|
|
153
|
-
code: planCode ?? "",
|
|
154
|
-
name: plan?.name ?? planCode ?? ""
|
|
155
|
-
};
|
|
156
|
-
const locks = buLocks ?? {};
|
|
157
|
-
if (!business || !plan) return {
|
|
158
|
-
plan: planMeta,
|
|
159
|
-
apps: [],
|
|
160
|
-
locks
|
|
161
|
-
};
|
|
162
|
-
const apps = [];
|
|
163
|
-
for (const app of business.apps) {
|
|
164
|
-
let unlockedCount = 0;
|
|
165
|
-
let totalCount = 0;
|
|
166
|
-
const features = [];
|
|
167
|
-
for (const code of app.features) {
|
|
168
|
-
const feature = snapshot.features?.[code];
|
|
169
|
-
if (!feature) continue;
|
|
170
|
-
const platforms = PLATFORMS.filter((p) => !!feature.microfrontends?.[p]);
|
|
171
|
-
if (platforms.length === 0) continue;
|
|
172
|
-
const membership = plan.unlockedPermissions?.[code];
|
|
173
|
-
const featureInPlan = isPlanMember(membership);
|
|
174
|
-
const buEntry = buLocks?.[code];
|
|
175
|
-
const permissions = (feature.permissions ?? []).filter((p) => p.isGlobal || p.businesses.includes(businessCode ?? "")).map((p) => {
|
|
176
|
-
const cell = /* @__PURE__ */ __name((plat) => {
|
|
177
|
-
if (!platforms.includes(plat)) return null;
|
|
178
|
-
const planCodes = membership?.[plat];
|
|
179
|
-
const inPlan = featureInPlan && planCodes !== void 0 && planCodes.includes(p.code);
|
|
180
|
-
const selected = inPlan && !isBuLockedOnPlatform(buEntry, plat, p.code);
|
|
181
|
-
const availableIn = inPlan ? [] : plansUnlockingPerm(plans, code, p.code, plat, planCode);
|
|
182
|
-
totalCount += 1;
|
|
183
|
-
if (inPlan) unlockedCount += 1;
|
|
184
|
-
return {
|
|
185
|
-
inPlan,
|
|
186
|
-
selected,
|
|
187
|
-
availableIn
|
|
188
|
-
};
|
|
189
|
-
}, "cell");
|
|
190
|
-
return {
|
|
191
|
-
code: p.code,
|
|
192
|
-
label: p.label,
|
|
193
|
-
web: cell("web"),
|
|
194
|
-
mobile: cell("mobile")
|
|
195
|
-
};
|
|
196
|
-
});
|
|
197
|
-
features.push({
|
|
198
|
-
code: feature.code,
|
|
199
|
-
name: feature.name,
|
|
200
|
-
icon: feature.lucideIcon ?? null,
|
|
201
|
-
platforms,
|
|
202
|
-
inPlan: featureInPlan,
|
|
203
|
-
availableIn: featureInPlan ? [] : plansIncludingFeature2(plans, code, planCode),
|
|
204
|
-
permissions
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
apps.push({
|
|
208
|
-
code: app.code,
|
|
209
|
-
name: app.name,
|
|
210
|
-
icon: app.icon ?? null,
|
|
211
|
-
unlockedCount,
|
|
212
|
-
totalCount,
|
|
213
|
-
features
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
return {
|
|
217
|
-
plan: planMeta,
|
|
218
|
-
apps,
|
|
219
|
-
locks
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
__name(buildBuMatrix, "buildBuMatrix");
|
|
223
|
-
function plansUnlockingPerm(plans, featureCode, permCode, platform, excludeCode) {
|
|
224
|
-
const names = [];
|
|
225
|
-
for (const [code, p] of Object.entries(plans)) {
|
|
226
|
-
if (code === excludeCode) continue;
|
|
227
|
-
if ((p.unlockedPermissions?.[featureCode]?.[platform] ?? []).includes(permCode)) names.push(p.name);
|
|
228
|
-
}
|
|
229
|
-
return names;
|
|
230
|
-
}
|
|
231
|
-
__name(plansUnlockingPerm, "plansUnlockingPerm");
|
|
232
|
-
function plansIncludingFeature2(plans, featureCode, excludeCode) {
|
|
233
|
-
const names = [];
|
|
234
|
-
for (const [code, p] of Object.entries(plans)) {
|
|
235
|
-
if (code === excludeCode) continue;
|
|
236
|
-
if (isPlanMember(p.unlockedPermissions?.[featureCode])) names.push(p.name);
|
|
237
|
-
}
|
|
238
|
-
return names;
|
|
239
|
-
}
|
|
240
|
-
__name(plansIncludingFeature2, "plansIncludingFeature");
|
|
285
|
+
__name(buildSiteRoles, "buildSiteRoles");
|
|
241
286
|
|
|
242
287
|
// src/catalog-resolver/compose-role-grants.ts
|
|
243
288
|
function unionBucket(base, add) {
|
|
@@ -278,13 +323,35 @@ __name(composeRoleGrants, "composeRoleGrants");
|
|
|
278
323
|
|
|
279
324
|
// src/catalog-resolver/resolve-user-features.ts
|
|
280
325
|
function resolveUserFeatures(params) {
|
|
281
|
-
const { snapshot, businessCode, planCode,
|
|
326
|
+
const { snapshot, businessCode, planCode, siteLocks, roleFeatures, platform, siteType, scope, availableServices } = params;
|
|
282
327
|
const bucket = platform === "web" ? "web" : "mobile";
|
|
283
|
-
const
|
|
328
|
+
const featureByCode = /* @__PURE__ */ __name((code) => scope ? snapshot.features?.[snapshotFeatureKey(code, scope)] : findFeatureByCode(snapshot, code), "featureByCode");
|
|
329
|
+
const catalog = buildSiteCatalog(snapshot, businessCode, planCode, siteLocks, bucket, siteType, scope, availableServices);
|
|
284
330
|
const catalogMap = new Map(catalog.map((f) => [
|
|
285
331
|
f.code,
|
|
286
332
|
f
|
|
287
333
|
]));
|
|
334
|
+
const businessPlans = snapshot.businesses[businessCode]?.plans ?? {};
|
|
335
|
+
const currentUnlockedCodes = /* @__PURE__ */ new Set();
|
|
336
|
+
if (planCode && businessPlans[planCode]) {
|
|
337
|
+
for (const [featureCode, platforms] of Object.entries(businessPlans[planCode].unlockedPermissions ?? {})) {
|
|
338
|
+
if (platforms?.[bucket] !== void 0) currentUnlockedCodes.add(featureCode);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
const planAdds = /* @__PURE__ */ new Map();
|
|
342
|
+
for (const [planKey, plan] of Object.entries(businessPlans)) {
|
|
343
|
+
if (planKey === planCode) continue;
|
|
344
|
+
const adds = [];
|
|
345
|
+
for (const [featureCode, platforms] of Object.entries(plan.unlockedPermissions ?? {})) {
|
|
346
|
+
if (platforms?.[bucket] === void 0 || currentUnlockedCodes.has(featureCode)) continue;
|
|
347
|
+
const name = featureByCode(featureCode)?.name;
|
|
348
|
+
if (name) adds.push({
|
|
349
|
+
code: featureCode,
|
|
350
|
+
name
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
planAdds.set(planKey, adds);
|
|
354
|
+
}
|
|
288
355
|
const grantedFeatures = /* @__PURE__ */ new Map();
|
|
289
356
|
for (const [code, grant] of Object.entries(roleFeatures ?? {})) {
|
|
290
357
|
const granted = grant?.[bucket];
|
|
@@ -298,18 +365,24 @@ function resolveUserFeatures(params) {
|
|
|
298
365
|
if (!catalogEntry) continue;
|
|
299
366
|
const route = pickRouteForPlatform(catalogEntry, platform);
|
|
300
367
|
if (!route) continue;
|
|
368
|
+
const featureDeps = buildDependsMap(featureByCode(code)?.permissions ?? []);
|
|
301
369
|
const permByCode = new Map((catalogEntry.permissions ?? []).map((p) => [
|
|
302
370
|
p.code,
|
|
303
371
|
p
|
|
304
372
|
]));
|
|
305
373
|
const grantedPerms = [
|
|
306
|
-
...permsSet
|
|
374
|
+
...filterGrantedByDeps(permsSet, featureDeps)
|
|
307
375
|
];
|
|
308
376
|
const lockedPermissions = grantedPerms.map((c) => permByCode.get(c)).filter((p) => !!p?.locked).map((p) => ({
|
|
309
377
|
code: p.code,
|
|
310
378
|
reason: p.lockReason ?? null,
|
|
311
|
-
unlockPlans: p.unlockPlans ?? []
|
|
379
|
+
unlockPlans: p.unlockPlans ?? [],
|
|
380
|
+
missingServices: p.missingServices ?? []
|
|
312
381
|
}));
|
|
382
|
+
const upsell = catalogEntry.locked && catalogEntry.lockReason === "PLAN" ? (catalogEntry.unlockPlans ?? []).map((plan) => ({
|
|
383
|
+
plan,
|
|
384
|
+
features: (planAdds.get(plan) ?? []).filter((f) => f.code !== code).map((f) => f.name)
|
|
385
|
+
})).filter((group) => group.features.length > 0) : [];
|
|
313
386
|
features.push({
|
|
314
387
|
code,
|
|
315
388
|
name: catalogEntry.name,
|
|
@@ -320,7 +393,9 @@ function resolveUserFeatures(params) {
|
|
|
320
393
|
locked: catalogEntry.locked ?? false,
|
|
321
394
|
lockReason: catalogEntry.lockReason ?? null,
|
|
322
395
|
unlockPlans: catalogEntry.unlockPlans ?? [],
|
|
396
|
+
missingServices: catalogEntry.missingServices ?? [],
|
|
323
397
|
lockedPermissions,
|
|
398
|
+
upsell,
|
|
324
399
|
route,
|
|
325
400
|
appCode: catalogEntry.appCode,
|
|
326
401
|
appName: catalogEntry.appName,
|
|
@@ -328,6 +403,7 @@ function resolveUserFeatures(params) {
|
|
|
328
403
|
appSortOrder: catalogEntry.appSortOrder
|
|
329
404
|
});
|
|
330
405
|
}
|
|
406
|
+
features.sort((a, b) => a.appName.localeCompare(b.appName));
|
|
331
407
|
return features;
|
|
332
408
|
}
|
|
333
409
|
__name(resolveUserFeatures, "resolveUserFeatures");
|
|
@@ -348,17 +424,138 @@ function pickRouteForPlatform(entry, platform) {
|
|
|
348
424
|
};
|
|
349
425
|
}
|
|
350
426
|
__name(pickRouteForPlatform, "pickRouteForPlatform");
|
|
427
|
+
|
|
428
|
+
// src/catalog-resolver/site-matrix.builder.ts
|
|
429
|
+
function buildSiteMatrix(snapshot, businessCode, planCode, siteLocks, siteType) {
|
|
430
|
+
return buildMatrix(snapshot, businessCode, planCode, siteLocks, false, siteType);
|
|
431
|
+
}
|
|
432
|
+
__name(buildSiteMatrix, "buildSiteMatrix");
|
|
433
|
+
function buildPlanMatrix(snapshot, businessCode, planCode, siteLocks) {
|
|
434
|
+
return buildMatrix(snapshot, businessCode, planCode, siteLocks, true);
|
|
435
|
+
}
|
|
436
|
+
__name(buildPlanMatrix, "buildPlanMatrix");
|
|
437
|
+
function buildMatrix(snapshot, businessCode, planCode, siteLocks, allScopes, siteType) {
|
|
438
|
+
const business = businessCode ? snapshot.businesses?.[businessCode] : void 0;
|
|
439
|
+
const plans = business?.plans ?? {};
|
|
440
|
+
const plan = planCode ? plans[planCode] : void 0;
|
|
441
|
+
const planMeta = {
|
|
442
|
+
code: planCode ?? "",
|
|
443
|
+
name: plan?.name ?? planCode ?? ""
|
|
444
|
+
};
|
|
445
|
+
const locks = siteLocks ?? {};
|
|
446
|
+
if (!business || !plan) return {
|
|
447
|
+
plan: planMeta,
|
|
448
|
+
apps: [],
|
|
449
|
+
locks
|
|
450
|
+
};
|
|
451
|
+
const apps = [];
|
|
452
|
+
for (const app of business.apps) {
|
|
453
|
+
let unlockedCount = 0;
|
|
454
|
+
let totalCount = 0;
|
|
455
|
+
const features = [];
|
|
456
|
+
for (const ref of app.features) {
|
|
457
|
+
if (!allScopes && ref.scope !== "SITE") continue;
|
|
458
|
+
const code = ref.code;
|
|
459
|
+
const feature = snapshot.features?.[snapshotFeatureKey(code, ref.scope)];
|
|
460
|
+
if (!feature) continue;
|
|
461
|
+
if (siteType !== void 0 && !featureAppliesAtNode(feature.applicableSiteTypes, siteType)) continue;
|
|
462
|
+
const platforms = PLATFORMS.filter((p) => !!feature.microfrontends?.[p]);
|
|
463
|
+
if (platforms.length === 0) continue;
|
|
464
|
+
const membership = plan.unlockedPermissions?.[code];
|
|
465
|
+
const featureInPlan = isPlanMember(membership);
|
|
466
|
+
const siteEntry = siteLocks?.[code];
|
|
467
|
+
const permissions = (feature.permissions ?? []).filter((p) => p.isGlobal || p.businesses.includes(businessCode ?? "")).map((p) => {
|
|
468
|
+
const cell = /* @__PURE__ */ __name((plat) => {
|
|
469
|
+
if (!platforms.includes(plat)) return null;
|
|
470
|
+
const planCodes = membership?.[plat];
|
|
471
|
+
const inPlan = featureInPlan && planCodes !== void 0 && planCodes.includes(p.code);
|
|
472
|
+
const selected = inPlan && !isSiteLockedOnPlatform(siteEntry, plat, p.code);
|
|
473
|
+
const availableIn = inPlan ? [] : plansUnlockingPerm(plans, code, p.code, plat, planCode);
|
|
474
|
+
totalCount += 1;
|
|
475
|
+
if (inPlan) unlockedCount += 1;
|
|
476
|
+
return {
|
|
477
|
+
inPlan,
|
|
478
|
+
selected,
|
|
479
|
+
availableIn
|
|
480
|
+
};
|
|
481
|
+
}, "cell");
|
|
482
|
+
return {
|
|
483
|
+
code: p.code,
|
|
484
|
+
label: p.label,
|
|
485
|
+
dependsOn: p.dependsOn ?? [],
|
|
486
|
+
web: cell("web"),
|
|
487
|
+
mobile: cell("mobile")
|
|
488
|
+
};
|
|
489
|
+
});
|
|
490
|
+
features.push({
|
|
491
|
+
code: feature.code,
|
|
492
|
+
name: feature.name,
|
|
493
|
+
icon: feature.lucideIcon ?? null,
|
|
494
|
+
scope: feature.scope,
|
|
495
|
+
applicableSiteTypes: feature.applicableSiteTypes,
|
|
496
|
+
platforms,
|
|
497
|
+
inPlan: featureInPlan,
|
|
498
|
+
availableIn: featureInPlan ? [] : plansIncludingFeature2(plans, code, planCode),
|
|
499
|
+
permissions
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
if (features.length === 0) continue;
|
|
503
|
+
apps.push({
|
|
504
|
+
code: app.code,
|
|
505
|
+
name: app.name,
|
|
506
|
+
icon: app.icon ?? null,
|
|
507
|
+
unlockedCount,
|
|
508
|
+
totalCount,
|
|
509
|
+
features
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
apps.sort((a, b) => a.name.localeCompare(b.name));
|
|
513
|
+
return {
|
|
514
|
+
plan: planMeta,
|
|
515
|
+
apps,
|
|
516
|
+
locks
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
__name(buildMatrix, "buildMatrix");
|
|
520
|
+
function plansUnlockingPerm(plans, featureCode, permCode, platform, excludeCode) {
|
|
521
|
+
const names = [];
|
|
522
|
+
for (const [code, p] of Object.entries(plans)) {
|
|
523
|
+
if (code === excludeCode) continue;
|
|
524
|
+
if ((p.unlockedPermissions?.[featureCode]?.[platform] ?? []).includes(permCode)) names.push(p.name);
|
|
525
|
+
}
|
|
526
|
+
return names;
|
|
527
|
+
}
|
|
528
|
+
__name(plansUnlockingPerm, "plansUnlockingPerm");
|
|
529
|
+
function plansIncludingFeature2(plans, featureCode, excludeCode) {
|
|
530
|
+
const names = [];
|
|
531
|
+
for (const [code, p] of Object.entries(plans)) {
|
|
532
|
+
if (code === excludeCode) continue;
|
|
533
|
+
if (isPlanMember(p.unlockedPermissions?.[featureCode])) names.push(p.name);
|
|
534
|
+
}
|
|
535
|
+
return names;
|
|
536
|
+
}
|
|
537
|
+
__name(plansIncludingFeature2, "plansIncludingFeature");
|
|
351
538
|
// Annotate the CommonJS export names for ESM import in node:
|
|
352
539
|
0 && (module.exports = {
|
|
353
540
|
PLATFORMS,
|
|
541
|
+
SERVICE_CODES,
|
|
542
|
+
SITE_TYPES,
|
|
354
543
|
SNAPSHOT_SCHEMA_VERSION,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
544
|
+
buildDependsMap,
|
|
545
|
+
buildPlanMatrix,
|
|
546
|
+
buildSiteCatalog,
|
|
547
|
+
buildSiteMatrix,
|
|
548
|
+
buildSiteRoles,
|
|
549
|
+
cascadeLocked,
|
|
358
550
|
composeRoleGrants,
|
|
359
|
-
|
|
551
|
+
featureAppliesAtNode,
|
|
552
|
+
filterGrantedByDeps,
|
|
553
|
+
findFeatureByCode,
|
|
360
554
|
isPlanMember,
|
|
555
|
+
isSiteLockedOnPlatform,
|
|
361
556
|
pickRouteForPlatform,
|
|
362
|
-
|
|
557
|
+
prereqClosure,
|
|
558
|
+
resolveUserFeatures,
|
|
559
|
+
snapshotFeatureKey
|
|
363
560
|
});
|
|
364
561
|
//# sourceMappingURL=catalog-resolver.cjs.map
|