web-manager 4.1.38 → 4.1.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/CLAUDE.md +5 -5
- package/dist/index.js +1 -1
- package/dist/modules/auth.js +8 -5
- package/dist/modules/utilities.js +16 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
|
14
14
|
- `Fixed` for any bug fixes.
|
|
15
15
|
- `Security` in case of vulnerabilities.
|
|
16
16
|
|
|
17
|
+
---
|
|
18
|
+
## [4.1.40] - 2026-05-10
|
|
19
|
+
### Changed
|
|
20
|
+
- **BREAKING (internal)**: `_resolveUsage()` now reads `config.payment.products` instead of `config.payment.plans`. Aligns with OMEGA's canonical shape (the SSOT) — same key name in BEM, UJM, EM. No backwards-compat shim; consumers must use `payment.products`. Default in `_processConfiguration()` updated from `plans: []` to `products: []`. Renamed local vars `plan`/`plans`/`planConfig` → `productId`/`products`/`product`. CLAUDE.md updated.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
## [4.1.39] - 2026-04-10
|
|
24
|
+
### Changed
|
|
25
|
+
- Converted `Utilities` methods to arrow class fields so `this` is permanently bound to the instance, allowing methods to be destructured, aliased, or passed as callbacks without losing context.
|
|
26
|
+
|
|
17
27
|
---
|
|
18
28
|
## [4.1.38] - 2026-04-08
|
|
19
29
|
### Added
|
package/CLAUDE.md
CHANGED
|
@@ -153,7 +153,7 @@ document.body.addEventListener('click', (e) => {
|
|
|
153
153
|
- **Class**: `Auth`
|
|
154
154
|
- **Key Methods**: `listen(options, callback)`, `isAuthenticated()`, `getUser()`, `signInWithEmailAndPassword()`, `signOut()`, `getIdToken()`, `resolveSubscription(account?)`
|
|
155
155
|
- **Bindings**: Updates `auth` and `usage` context on auth settle
|
|
156
|
-
- **Usage Resolution**: `_resolveUsage(state)` merges `account.usage` (Firestore) with
|
|
156
|
+
- **Usage Resolution**: `_resolveUsage(state)` merges `account.usage` (Firestore) with product limits from `config.payment.products` (OMEGA-canonical shape — same key name in BEM, UJM, and EM) to produce the `usage` bindings key (e.g., `{ credits: { monthly: 5, limit: 100 } }`)
|
|
157
157
|
|
|
158
158
|
#### resolveSubscription(account?)
|
|
159
159
|
Derives calculated subscription fields from raw account data. Returns only fields that require derivation logic — raw data (product.id, status, trial, cancellation) lives on `account.subscription` directly.
|
|
@@ -269,13 +269,13 @@ Current test coverage is minimal - focuses on configuration and storage.
|
|
|
269
269
|
|
|
270
270
|
### Modifying Configuration Defaults
|
|
271
271
|
1. Edit `_processConfiguration()` in `src/index.js`
|
|
272
|
-
2. Add to `defaults` object (e.g., `payment: { processors: {},
|
|
272
|
+
2. Add to `defaults` object (e.g., `payment: { processors: {}, products: [] }`)
|
|
273
273
|
3. Document in README.md Configuration section
|
|
274
274
|
|
|
275
275
|
### Payment Configuration
|
|
276
|
-
Payment config
|
|
277
|
-
- `processors`: Stripe, PayPal,
|
|
278
|
-
- `
|
|
276
|
+
Payment config shape mirrors OMEGA (the SSOT) — same key names used in BEM, UJM, and EM:
|
|
277
|
+
- `processors`: Stripe, PayPal, Chargebee, Coinbase (publishable keys / client IDs)
|
|
278
|
+
- `products`: Array of `{ id, name, type, limits: { feature: N }, prices, trial, paypal, stripe, chargebee }` — used to resolve usage limits on the frontend AND drive checkout flows
|
|
279
279
|
|
|
280
280
|
### Adding a Data Binding Action
|
|
281
281
|
1. Edit `_executeAction()` in `src/modules/bindings.js`
|
package/dist/index.js
CHANGED
package/dist/modules/auth.js
CHANGED
|
@@ -256,14 +256,17 @@ class Auth {
|
|
|
256
256
|
};
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
// Resolve usage bindings from account data +
|
|
259
|
+
// Resolve usage bindings from account data + product limits from config.
|
|
260
260
|
// Returns: { credits: { monthly: 5, limit: 100 }, ... }
|
|
261
|
+
//
|
|
262
|
+
// The product catalog lives at `config.payment.products` (OMEGA canonical
|
|
263
|
+
// shape — matches BEM, UJM, and EM). Each product entry has `{ id, limits: {...} }`.
|
|
261
264
|
_resolveUsage(state) {
|
|
262
265
|
const accountUsage = state.account?.usage || {};
|
|
263
|
-
const
|
|
264
|
-
const
|
|
265
|
-
const
|
|
266
|
-
const limits
|
|
266
|
+
const productId = state.resolved?.plan || 'basic';
|
|
267
|
+
const products = this.manager.config.payment?.products || [];
|
|
268
|
+
const product = products.find(p => p.id === productId) || {};
|
|
269
|
+
const limits = product.limits || {};
|
|
267
270
|
|
|
268
271
|
// Merge current usage with limits for each feature
|
|
269
272
|
const usage = {};
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
// Methods are defined as arrow class fields so `this` is permanently bound to the instance.
|
|
2
|
+
// This means consumers can safely alias or destructure methods without losing context:
|
|
3
|
+
// const { escapeHTML } = webManager.utilities(); // ✓ works
|
|
4
|
+
// const escape = webManager.utilities().escapeHTML; // ✓ works
|
|
5
|
+
// items.map(webManager.utilities().escapeHTML); // ✓ works
|
|
6
|
+
// Safe because webManager.utilities() is a singleton — only one instance ever exists.
|
|
1
7
|
class Utilities {
|
|
2
8
|
constructor(manager) {
|
|
3
9
|
this.manager = manager;
|
|
4
10
|
}
|
|
5
11
|
|
|
6
12
|
// Copy text to clipboard
|
|
7
|
-
clipboardCopy(input) {
|
|
13
|
+
clipboardCopy = (input) => {
|
|
8
14
|
// Get the text from the input
|
|
9
15
|
const text = input && input.nodeType
|
|
10
16
|
? input.value || input.innerText || input.innerHTML
|
|
@@ -38,7 +44,7 @@ class Utilities {
|
|
|
38
44
|
|
|
39
45
|
// Escape HTML to prevent XSS
|
|
40
46
|
// Accepts a string, object, or array — walks recursively, escaping all string values
|
|
41
|
-
escapeHTML(input) {
|
|
47
|
+
escapeHTML = (input) => {
|
|
42
48
|
// Strings — escape and return
|
|
43
49
|
if (typeof input === 'string') {
|
|
44
50
|
this._shadowElement = this._shadowElement || document.createElement('p');
|
|
@@ -83,7 +89,7 @@ class Utilities {
|
|
|
83
89
|
|
|
84
90
|
// Sanitize URL to prevent javascript:, data:, and other dangerous URI schemes
|
|
85
91
|
// Returns the original URL if safe, or '' if rejected
|
|
86
|
-
sanitizeURL(url) {
|
|
92
|
+
sanitizeURL = (url) => {
|
|
87
93
|
if (!url || typeof url !== 'string') {
|
|
88
94
|
return '';
|
|
89
95
|
}
|
|
@@ -102,7 +108,7 @@ class Utilities {
|
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
// Show notification
|
|
105
|
-
showNotification(message, options = {}) {
|
|
111
|
+
showNotification = (message, options = {}) => {
|
|
106
112
|
// Handle different input types
|
|
107
113
|
let text = message;
|
|
108
114
|
let type = options.type || 'info';
|
|
@@ -148,7 +154,7 @@ class Utilities {
|
|
|
148
154
|
}
|
|
149
155
|
|
|
150
156
|
// Get platform (OS)
|
|
151
|
-
getPlatform() {
|
|
157
|
+
getPlatform = () => {
|
|
152
158
|
const ua = navigator.userAgent.toLowerCase();
|
|
153
159
|
const platform = (navigator.userAgentData?.platform || navigator.platform || '').toLowerCase();
|
|
154
160
|
|
|
@@ -178,7 +184,7 @@ class Utilities {
|
|
|
178
184
|
}
|
|
179
185
|
|
|
180
186
|
// Get browser name
|
|
181
|
-
getBrowser() {
|
|
187
|
+
getBrowser = () => {
|
|
182
188
|
const ua = navigator.userAgent;
|
|
183
189
|
|
|
184
190
|
// Order matters - check more specific browsers first
|
|
@@ -217,7 +223,7 @@ class Utilities {
|
|
|
217
223
|
}
|
|
218
224
|
|
|
219
225
|
// Get runtime environment
|
|
220
|
-
getRuntime() {
|
|
226
|
+
getRuntime = () => {
|
|
221
227
|
// Use config runtime if provided
|
|
222
228
|
if (this.manager?.config?.runtime) {
|
|
223
229
|
return this.manager.config.runtime;
|
|
@@ -237,7 +243,7 @@ class Utilities {
|
|
|
237
243
|
}
|
|
238
244
|
|
|
239
245
|
// Check if mobile device
|
|
240
|
-
isMobile() {
|
|
246
|
+
isMobile = () => {
|
|
241
247
|
try {
|
|
242
248
|
// Try modern API first
|
|
243
249
|
const m = navigator.userAgentData?.mobile;
|
|
@@ -257,7 +263,7 @@ class Utilities {
|
|
|
257
263
|
}
|
|
258
264
|
|
|
259
265
|
// Get device based on screen width
|
|
260
|
-
getDevice() {
|
|
266
|
+
getDevice = () => {
|
|
261
267
|
const width = window.innerWidth;
|
|
262
268
|
|
|
263
269
|
// Mobile: < 768px (Bootstrap's md breakpoint)
|
|
@@ -275,7 +281,7 @@ class Utilities {
|
|
|
275
281
|
}
|
|
276
282
|
|
|
277
283
|
// Get context information
|
|
278
|
-
getContext() {
|
|
284
|
+
getContext = () => {
|
|
279
285
|
// Return context information
|
|
280
286
|
return {
|
|
281
287
|
client: {
|
package/package.json
CHANGED