web-manager 4.3.2 → 4.3.4
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/CLAUDE.md +3 -0
- package/dist/index.js +11 -1
- package/docs/cdp-debugging.md +29 -0
- package/package.json +7 -1
- package/src/index.js +712 -0
- package/src/modules/analytics.js +250 -0
- package/src/modules/auth.js +420 -0
- package/src/modules/bindings.js +314 -0
- package/src/modules/dom.js +96 -0
- package/src/modules/firestore.js +306 -0
- package/src/modules/notifications.js +391 -0
- package/src/modules/sentry.js +199 -0
- package/src/modules/service-worker.js +196 -0
- package/src/modules/storage.js +133 -0
- package/src/modules/usage.js +264 -0
- package/src/modules/utilities.js +310 -0
- package/CHANGELOG.md +0 -242
- package/TODO.md +0 -59
- package/_legacy/helpers/auth-pages.js +0 -24
- package/_legacy/index.js +0 -1854
- package/_legacy/lib/account.js +0 -666
- package/_legacy/lib/debug.js +0 -56
- package/_legacy/lib/dom.js +0 -351
- package/_legacy/lib/require.js +0 -5
- package/_legacy/lib/storage.js +0 -78
- package/_legacy/lib/utilities.js +0 -180
- package/_legacy/service-worker copy.js +0 -347
- package/_legacy/test/test.js +0 -158
|
@@ -0,0 +1,310 @@
|
|
|
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.
|
|
7
|
+
class Utilities {
|
|
8
|
+
constructor(manager) {
|
|
9
|
+
this.manager = manager;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// Copy text to clipboard
|
|
13
|
+
clipboardCopy = (input) => {
|
|
14
|
+
// Get the text from the input
|
|
15
|
+
const text = input && input.nodeType
|
|
16
|
+
? input.value || input.innerText || input.innerHTML
|
|
17
|
+
: input;
|
|
18
|
+
|
|
19
|
+
// Try to use the modern clipboard API
|
|
20
|
+
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
21
|
+
return navigator.clipboard.writeText(text).catch(() => {
|
|
22
|
+
fallbackCopy(text);
|
|
23
|
+
});
|
|
24
|
+
} else {
|
|
25
|
+
fallbackCopy(text);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fallbackCopy(text) {
|
|
29
|
+
const el = document.createElement('textarea');
|
|
30
|
+
el.setAttribute('style', 'width:1px;border:0;opacity:0;');
|
|
31
|
+
el.value = text;
|
|
32
|
+
document.body.appendChild(el);
|
|
33
|
+
el.select();
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
document.execCommand('copy');
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.error('Failed to copy to clipboard');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
document.body.removeChild(el);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Escape HTML to prevent XSS
|
|
46
|
+
// Accepts a string, object, or array — walks recursively, escaping all string values
|
|
47
|
+
escapeHTML = (input) => {
|
|
48
|
+
// Strings — escape and return
|
|
49
|
+
if (typeof input === 'string') {
|
|
50
|
+
this._shadowElement = this._shadowElement || document.createElement('p');
|
|
51
|
+
this._shadowElement.innerHTML = '';
|
|
52
|
+
|
|
53
|
+
// This automatically escapes HTML entities like <, >, &, etc.
|
|
54
|
+
this._shadowElement.appendChild(document.createTextNode(input));
|
|
55
|
+
|
|
56
|
+
// This is needed to escape quotes to prevent attribute injection
|
|
57
|
+
return this._shadowElement.innerHTML.replace(/["']/g, (m) => {
|
|
58
|
+
switch (m) {
|
|
59
|
+
case '"':
|
|
60
|
+
return '"';
|
|
61
|
+
default:
|
|
62
|
+
return ''';
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Null/undefined — pass through
|
|
68
|
+
if (input == null) {
|
|
69
|
+
return input;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Arrays — recurse each item
|
|
73
|
+
if (Array.isArray(input)) {
|
|
74
|
+
return input.map(item => this.escapeHTML(item));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Objects — shallow clone, recurse each value
|
|
78
|
+
if (typeof input === 'object') {
|
|
79
|
+
const result = {};
|
|
80
|
+
for (const [key, value] of Object.entries(input)) {
|
|
81
|
+
result[key] = this.escapeHTML(value);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Numbers, booleans, etc. — pass through unchanged
|
|
87
|
+
return input;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Sanitize URL to prevent javascript:, data:, and other dangerous URI schemes
|
|
91
|
+
// Returns the original URL if safe, or '' if rejected
|
|
92
|
+
sanitizeURL = (url) => {
|
|
93
|
+
if (!url || typeof url !== 'string') {
|
|
94
|
+
return '';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const parsed = new URL(url, window.location.origin);
|
|
99
|
+
|
|
100
|
+
if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
|
|
101
|
+
return '';
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return url;
|
|
105
|
+
} catch (e) {
|
|
106
|
+
return '';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Show notification
|
|
111
|
+
showNotification = (message, options = {}) => {
|
|
112
|
+
// Handle different input types
|
|
113
|
+
let text = message;
|
|
114
|
+
let type = options.type || 'info';
|
|
115
|
+
|
|
116
|
+
// If message is an Error object, extract message and default to danger
|
|
117
|
+
if (message instanceof Error) {
|
|
118
|
+
text = message.message;
|
|
119
|
+
type = options.type || 'danger';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Handle string as second parameter for backwards compatibility
|
|
123
|
+
if (typeof options === 'string') {
|
|
124
|
+
options = { type: options };
|
|
125
|
+
type = options.type;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Extract options
|
|
129
|
+
const timeout = options.timeout !== undefined ? options.timeout : 5000;
|
|
130
|
+
|
|
131
|
+
const $notification = document.createElement('div');
|
|
132
|
+
$notification.className = `alert alert-${type} alert-dismissible fade show position-fixed`;
|
|
133
|
+
$notification.style.cssText = 'z-index: 9999; top: 1rem; left: 50%; transform: translateX(-50%); width: calc(100% - 2rem); max-width: 500px;';
|
|
134
|
+
|
|
135
|
+
const $text = document.createElement('span');
|
|
136
|
+
$text.textContent = text;
|
|
137
|
+
|
|
138
|
+
const $closeBtn = document.createElement('button');
|
|
139
|
+
$closeBtn.type = 'button';
|
|
140
|
+
$closeBtn.className = 'btn-close';
|
|
141
|
+
$closeBtn.setAttribute('data-bs-dismiss', 'alert');
|
|
142
|
+
|
|
143
|
+
$notification.appendChild($text);
|
|
144
|
+
$notification.appendChild($closeBtn);
|
|
145
|
+
|
|
146
|
+
document.body.appendChild($notification);
|
|
147
|
+
|
|
148
|
+
// Auto-remove after timeout (unless timeout is 0)
|
|
149
|
+
if (timeout > 0) {
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
$notification.remove();
|
|
152
|
+
}, timeout);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Get platform (OS)
|
|
157
|
+
getPlatform = () => {
|
|
158
|
+
const ua = navigator.userAgent.toLowerCase();
|
|
159
|
+
const platform = (navigator.userAgentData?.platform || navigator.platform || '').toLowerCase();
|
|
160
|
+
|
|
161
|
+
// Check userAgent for mobile platforms (more reliable than platform string)
|
|
162
|
+
if (/iphone|ipad|ipod/.test(ua)) {
|
|
163
|
+
return 'ios';
|
|
164
|
+
}
|
|
165
|
+
if (/android/.test(ua)) {
|
|
166
|
+
return 'android';
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Check platform string for desktop OS
|
|
170
|
+
if (/win/.test(platform)) {
|
|
171
|
+
return 'windows';
|
|
172
|
+
}
|
|
173
|
+
if (/mac/.test(platform)) {
|
|
174
|
+
return 'mac';
|
|
175
|
+
}
|
|
176
|
+
if (/cros/.test(ua)) {
|
|
177
|
+
return 'chromeos';
|
|
178
|
+
}
|
|
179
|
+
if (/linux/.test(platform)) {
|
|
180
|
+
return 'linux';
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return 'unknown';
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Get browser name
|
|
187
|
+
getBrowser = () => {
|
|
188
|
+
const ua = navigator.userAgent;
|
|
189
|
+
|
|
190
|
+
// Order matters - check more specific browsers first
|
|
191
|
+
// Edge before Chrome (Edge includes "Chrome" in UA)
|
|
192
|
+
if (/edg/i.test(ua)) {
|
|
193
|
+
return 'edge';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Opera before Chrome (Opera includes "Chrome" in UA)
|
|
197
|
+
if (/opera|opr/i.test(ua)) {
|
|
198
|
+
return 'opera';
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Brave before Chrome (Brave includes "Chrome" in UA)
|
|
202
|
+
if (navigator.brave || /brave/i.test(ua)) {
|
|
203
|
+
return 'brave';
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Chrome (including Chromium-based browsers)
|
|
207
|
+
if (/chrome|chromium|crios/i.test(ua)) {
|
|
208
|
+
return 'chrome';
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Firefox
|
|
212
|
+
if (/firefox|fxios/i.test(ua)) {
|
|
213
|
+
return 'firefox';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Safari last (most browsers include "Safari" in UA)
|
|
217
|
+
if (/safari/i.test(ua)) {
|
|
218
|
+
return 'safari';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Fallback
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Get runtime environment
|
|
226
|
+
getRuntime = () => {
|
|
227
|
+
// Use config runtime if provided
|
|
228
|
+
if (this.manager?.config?.runtime) {
|
|
229
|
+
return this.manager.config.runtime;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Browser extension (Chrome, Edge, Opera, Brave, Firefox, Safari, etc.)
|
|
233
|
+
if (
|
|
234
|
+
(typeof chrome !== 'undefined' && chrome.runtime?.id)
|
|
235
|
+
|| (typeof browser !== 'undefined' && browser.runtime?.id)
|
|
236
|
+
|| (typeof safari !== 'undefined' && safari.extension)
|
|
237
|
+
) {
|
|
238
|
+
return 'browser-extension';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// Default: web browser
|
|
242
|
+
return 'web';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Check if mobile device
|
|
246
|
+
isMobile = () => {
|
|
247
|
+
try {
|
|
248
|
+
// Try modern API first
|
|
249
|
+
const m = navigator.userAgentData?.mobile;
|
|
250
|
+
if (typeof m !== 'undefined') {
|
|
251
|
+
return m === true;
|
|
252
|
+
}
|
|
253
|
+
} catch (e) {
|
|
254
|
+
// Silent fail
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Fallback to media query
|
|
258
|
+
try {
|
|
259
|
+
return window.matchMedia('(max-width: 767px)').matches;
|
|
260
|
+
} catch (e) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Get device based on screen width
|
|
266
|
+
getDevice = () => {
|
|
267
|
+
const width = window.innerWidth;
|
|
268
|
+
|
|
269
|
+
// Mobile: < 768px (Bootstrap's md breakpoint)
|
|
270
|
+
if (width < 768) {
|
|
271
|
+
return 'mobile';
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Tablet: 768px - 1199px (between md and xl)
|
|
275
|
+
if (width < 1200) {
|
|
276
|
+
return 'tablet';
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Desktop: >= 1200px
|
|
280
|
+
return 'desktop';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Get context information
|
|
284
|
+
getContext = () => {
|
|
285
|
+
// Return context information
|
|
286
|
+
return {
|
|
287
|
+
client: {
|
|
288
|
+
language: navigator.language,
|
|
289
|
+
mobile: this.isMobile(),
|
|
290
|
+
device: this.getDevice(),
|
|
291
|
+
platform: this.getPlatform(),
|
|
292
|
+
browser: this.getBrowser(),
|
|
293
|
+
vendor: navigator.vendor,
|
|
294
|
+
runtime: this.getRuntime(),
|
|
295
|
+
userAgent: navigator.userAgent,
|
|
296
|
+
url: window.location.href,
|
|
297
|
+
},
|
|
298
|
+
geolocation: {
|
|
299
|
+
ip: null,
|
|
300
|
+
country: null,
|
|
301
|
+
region: null,
|
|
302
|
+
city: null,
|
|
303
|
+
latitude: null,
|
|
304
|
+
longitude: null,
|
|
305
|
+
},
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export default Utilities;
|
package/CHANGELOG.md
DELETED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
# CHANGELOG
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
6
|
-
|
|
7
|
-
## Changelog Categories
|
|
8
|
-
|
|
9
|
-
- `BREAKING` for breaking changes.
|
|
10
|
-
- `Added` for new features.
|
|
11
|
-
- `Changed` for changes in existing functionality.
|
|
12
|
-
- `Deprecated` for soon-to-be removed features.
|
|
13
|
-
- `Removed` for now removed features.
|
|
14
|
-
- `Fixed` for any bug fixes.
|
|
15
|
-
- `Security` in case of vulnerabilities.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
## [4.3.2] - 2026-06-11
|
|
19
|
-
|
|
20
|
-
### Added
|
|
21
|
-
- **`docs/bindings.md`**: full `data-wm-bind` deep reference migrated from the `omega:ujm` skill into the repo (the module that implements the feature) — actions table, comma-separated multi-binding syntax + parser caveat, condition operators, auth/usage/custom state paths, JS API, skeleton-loader lifecycle (`wm-binding-skeleton` → `wm-bound`), multi-phase binding, composite-text pattern, and root-key update filtering. Linked from CLAUDE.md and `docs/modules.md`. Part of the skills-as-routers refactor: framework facts live in repo docs (version-matched via `node_modules`).
|
|
22
|
-
|
|
23
|
-
### Changed
|
|
24
|
-
- **Dependency bumps**: `@sentry/browser` `^10.54.0` → `^10.57.0`, `firebase` `^12.13.0` → `^12.14.0`.
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
## [4.2.0] - 2026-05-21
|
|
28
|
-
### Added
|
|
29
|
-
- **Consent defaults in `DEFAULT_ACCOUNT`.** Phase A companion to `backend-manager` v5.2.0's marketing-consent system. `src/modules/auth.js` now defaults `account.consent.{legal,marketing}` to the canonical shape (`status: 'revoked'`, `grantedAt`/`revokedAt` with null leaves) so `resolveAccount()` always populates the field for legacy users whose Firestore doc predates the consent system. Without this, the account-page email-preferences toggle would read `undefined` for pre-migration users and mis-state.
|
|
30
|
-
- **`docs/<topic>.md` deep references.** New `docs/architecture.md`, `docs/build-system.md`, `docs/code-patterns.md`, `docs/common-tasks.md`, `docs/dependencies.md`, `docs/modules.md`, `docs/testing.md`. Mirrors the architectural-overview-plus-deep-references pattern used in `backend-manager` and `electron-manager`.
|
|
31
|
-
|
|
32
|
-
### Changed
|
|
33
|
-
- **`CLAUDE.md` refactored to the architectural-overview pattern.** Trimmed from 301 lines to ~80; per-subsystem detail moved to the new `docs/*.md` files. Keeps Claude's loaded-context cost down on every conversation.
|
|
34
|
-
|
|
35
|
-
### Fixed
|
|
36
|
-
- **Toast notification width.** `src/modules/utilities.js`: notifications now have `width: calc(100% - 2rem); max-width: 500px` so longer text doesn't render as a narrow cramped strip at the top of the page.
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
## [4.1.42] - 2026-05-11
|
|
40
|
-
### Changed
|
|
41
|
-
- **Firebase config: presence-driven + flat shape canonical.** Firebase now initializes when a `firebaseConfig` blob is present in config (matching BEM/BXM/EM/OMEGA shape) — no separate `firebase.app.enabled` flag needed. Removes the `enabled` redundancy where consumers had to set both a credentials blob AND flip a flag.
|
|
42
|
-
- New internal helper `_resolveFirebaseConfig()` reads flat `config.firebaseConfig` first (canonical), falls back to nested `config.firebase.app.config` (UJM legacy yaml). Used by `_initializeFirebase`, `getFunctionsUrl`, `getApiUrl`, `service-worker.js`, and `auth.js#listen` (Firebase-not-configured short-circuit).
|
|
43
|
-
- `_initializeFirebase` now reuses an existing `[DEFAULT]` Firebase app if present (via `getApps()` / `getApp()`) instead of throwing `app/duplicate-app` on re-init (live reload, test re-runs).
|
|
44
|
-
- No backwards-compat shim needed for UJM: both shapes resolve. UJM can migrate to the flat `firebaseConfig` shape on its own schedule; until then, its `firebase.app.config` keeps working.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
## [4.1.41] - 2026-05-10
|
|
48
|
-
### Changed
|
|
49
|
-
- Bumped dependencies: `@sentry/browser` ^10.47.0 → ^10.52.0, `firebase` ^12.11.0 → ^12.13.0, `prepare-package` ^2.0.7 → ^2.1.0.
|
|
50
|
-
- Added empty `hooks: {}` to `preparePackage` config to align with prepare-package 2.1.0 schema.
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
## [4.1.40] - 2026-05-10
|
|
54
|
-
### Changed
|
|
55
|
-
- **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.
|
|
56
|
-
|
|
57
|
-
---
|
|
58
|
-
## [4.1.39] - 2026-04-10
|
|
59
|
-
### Changed
|
|
60
|
-
- 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.
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
## [4.1.38] - 2026-04-08
|
|
64
|
-
### Added
|
|
65
|
-
- Added `sanitizeURL()` utility method that validates URLs against dangerous URI schemes (javascript:, data:, etc.), allowing only http: and https: protocols.
|
|
66
|
-
|
|
67
|
-
## [4.1.37] - 2026-04-05
|
|
68
|
-
### Added
|
|
69
|
-
- Added `_resolveUsage()` to auth module that merges account usage data with plan limits from config, exposed as a top-level `usage` binding context.
|
|
70
|
-
- Added `payment.processors` and `payment.plans` defaults to configuration.
|
|
71
|
-
|
|
72
|
-
## [4.1.36] - 2026-04-02
|
|
73
|
-
### Fixed
|
|
74
|
-
- Fixed mocha binary path preventing `npm test` from running.
|
|
75
|
-
- Fixed lodash ESM named import incompatibility with Node.js (`storage.js`).
|
|
76
|
-
- Fixed test suite calling nonexistent API methods (`init` → `initialize`, `storage('local')` → `storage()`).
|
|
77
|
-
- Fixed mocha hanging after tests due to `setInterval` in version checker (added `--exit` flag).
|
|
78
|
-
|
|
79
|
-
### Changed
|
|
80
|
-
- Enhanced `escapeHTML` to recursively handle objects, arrays, and pass through non-string types.
|
|
81
|
-
- Rewrote `showNotification` to use safe DOM construction (`textContent`) instead of `innerHTML`.
|
|
82
|
-
- Split monolithic `test.js` into 8 modular test files under `test/tests/`.
|
|
83
|
-
- Expanded test coverage from ~10 broken tests to 70 passing tests.
|
|
84
|
-
|
|
85
|
-
### Security
|
|
86
|
-
- Blocked `javascript:` protocol in `@attr` bindings for URL attributes (`href`, `src`, `action`, `formaction`).
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
## [4.1.35] - 2026-04-02
|
|
90
|
-
### Changed
|
|
91
|
-
- Bumped `chatsy` from `^2.0.13` to `^2.0.14`.
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
## [4.1.34] - 2026-04-01
|
|
95
|
-
### Changed
|
|
96
|
-
- Bumped `@sentry/browser` from `^10.46.0` to `^10.47.0`.
|
|
97
|
-
- Bumped `lodash` from `^4.17.23` to `^4.18.1`.
|
|
98
|
-
- Improved CLAUDE.md singleton pattern documentation with clearer usage examples and explicit anti-patterns.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
## [4.1.31] - 2026-03-24
|
|
102
|
-
### Changed
|
|
103
|
-
- Switched from `getFirestore` to `initializeFirestore` in `index.js` to support custom Firestore configuration options.
|
|
104
|
-
- Removed redundant `getFirestore` from firestore module's stored methods since the instance is already initialized in `index.js`.
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
## [4.1.30] - 2026-03-20
|
|
108
|
-
### Changed
|
|
109
|
-
- Bumped `@sentry/browser` from `^10.43.0` to `^10.45.0`.
|
|
110
|
-
- Bumped `chatsy` from `^2.0.9` to `^2.0.11`.
|
|
111
|
-
- Bumped `firebase` from `^12.10.0` to `^12.11.0`.
|
|
112
|
-
|
|
113
|
-
---
|
|
114
|
-
## [4.1.29] - 2026-03-19
|
|
115
|
-
### Changed
|
|
116
|
-
- Restructured notification subscription documents to use nested `metadata.created` and `metadata.updated` timestamps instead of top-level fields.
|
|
117
|
-
- Update operations now use dot-notation (`metadata.updated`) to preserve `metadata.created` when updating existing subscriptions.
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
## [4.1.28] - 2026-03-15
|
|
121
|
-
### Changed
|
|
122
|
-
- Bumped `chatsy` from `^2.0.5` to `^2.0.8`.
|
|
123
|
-
- Upgraded `prepare-package` from `^1.2.6` to `^2.0.7` (major version with esbuild bundler).
|
|
124
|
-
- Added `preparePackage.type = "copy"` config option.
|
|
125
|
-
|
|
126
|
-
---
|
|
127
|
-
## [4.1.27] - 2026-03-14
|
|
128
|
-
### Changed
|
|
129
|
-
- Renamed default brand config values from `id:'app'`/`name:'Application'` to `id:'brand'`/`name:'Brand'`.
|
|
130
|
-
- Renamed service worker config key from `app` to `brand` to align with brand terminology.
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
## [4.1.25] - 2026-03-13
|
|
134
|
-
### Added
|
|
135
|
-
- Automatically attach resolved subscription state (`state.resolved`) to auth state during processing, making `plan`, `active`, `trialing`, and `cancelling` available to bindings and consumers without manual calls.
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
## [4.1.24] - 2026-03-13
|
|
139
|
-
### Added
|
|
140
|
-
- Added `resolveSubscription()` method to Auth module that derives calculated subscription fields (plan, active, trialing, cancelling) from raw backend data.
|
|
141
|
-
|
|
142
|
-
---
|
|
143
|
-
## [4.1.22] - 2026-03-11
|
|
144
|
-
### Changed
|
|
145
|
-
- Renamed `config.tracking` to `config.analytics` with simplified property names: `google-analytics` → `google`, `google-analytics-secret` → `googleSecret`, `meta-pixel` → `meta`, `tiktok-pixel` → `tiktok`.
|
|
146
|
-
|
|
147
|
-
---
|
|
148
|
-
## [4.1.19] - 2026-03-11
|
|
149
|
-
### Added
|
|
150
|
-
- Added new chatsy import.
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
## [4.1.15] - 2026-02-26
|
|
154
|
-
### Fixed
|
|
155
|
-
- Fixed bindings skeleton removal happening prematurely when partial context updates didn't match any of the element's bindings.
|
|
156
|
-
|
|
157
|
-
### Changed
|
|
158
|
-
- `_executeAction` now returns a boolean indicating whether the action was processed, allowing `update()` to defer skeleton removal until at least one binding runs.
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
## [4.1.10] - 2026-02-17
|
|
162
|
-
### Changed
|
|
163
|
-
- Refactored auth to use promise-based settler pattern (`_authReady`) for reliable auth state detection, eliminating race conditions with late-registered listeners.
|
|
164
|
-
- Split `listen()` into two clear paths: `once` (waits for settler, fires once) and persistent (subscribes to all changes, catches up if already settled).
|
|
165
|
-
- Renamed `onAuthStateChanged` to `_subscribe` (internal-only).
|
|
166
|
-
- Removed unused `_readyCallbacks`.
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
## [4.1.1] - 2025-12-17
|
|
170
|
-
### Added
|
|
171
|
-
- Added `getBrowser()` utility to detect browser type (chrome, firefox, safari, edge, opera, brave).
|
|
172
|
-
- Added `data-browser` HTML attribute set during initialization.
|
|
173
|
-
- Added `browser` and `vendor` fields to `getContext().client`.
|
|
174
|
-
- Added `geolocation` object to `getContext()` with placeholder fields (ip, country, region, city, latitude, longitude).
|
|
175
|
-
|
|
176
|
-
### Changed
|
|
177
|
-
- Moved `vendor` from `browser` object to `client` object in `getContext()`.
|
|
178
|
-
- Replaced `browser` object with `geolocation` object in `getContext()` return structure.
|
|
179
|
-
|
|
180
|
-
---
|
|
181
|
-
## [4.1.0] - 2025-12-16
|
|
182
|
-
### Added
|
|
183
|
-
- Added `analytics.js` module for Google Analytics 4 Measurement Protocol support (browser extensions and Electron).
|
|
184
|
-
- Added `usage.js` module to track install date, session count, session duration, and version history.
|
|
185
|
-
- Added `tracking` config section for analytics credentials (`google-analytics`, `google-analytics-secret`, `meta-pixel`, `tiktok-pixel`).
|
|
186
|
-
- Added `runtime` config option for explicit runtime override.
|
|
187
|
-
- Added `buildTimeISO` auto-calculated from `buildTime`.
|
|
188
|
-
- Added `usage` data to bindings context for UI display.
|
|
189
|
-
|
|
190
|
-
### Changed
|
|
191
|
-
- Refactored `utilities.js` from standalone functions to class pattern for consistency with other modules.
|
|
192
|
-
- Simplified `getApiUrl()` to always prepend `api.` subdomain instead of replacing first subdomain.
|
|
193
|
-
|
|
194
|
-
## [4.0.33] - 2025-12-12
|
|
195
|
-
### BREAKING
|
|
196
|
-
- `@text` binding action no longer auto-detects input/textarea elements. Use `@value` for inputs instead.
|
|
197
|
-
|
|
198
|
-
### Added
|
|
199
|
-
- Added `@value` binding action for explicitly setting input/textarea values.
|
|
200
|
-
|
|
201
|
-
## [4.0.31] - 2025-12-03
|
|
202
|
-
### Added
|
|
203
|
-
- Added HTML data attributes (`data-platform`, `data-runtime`, `data-device`) on initialization for CSS targeting.
|
|
204
|
-
- Added `getPlatform()`, `getRuntime()`, `isMobile()`, and `getDeviceType()` as standalone exported utility functions.
|
|
205
|
-
|
|
206
|
-
### Changed
|
|
207
|
-
- Refactored `getContext()` to use the new standalone functions and include `deviceType` and `runtime` in client info.
|
|
208
|
-
|
|
209
|
-
## [4.0.29] - 2025-12-02
|
|
210
|
-
### Fixed
|
|
211
|
-
- Fixed notification subscription storing to incorrect Firestore path (`users/{uid}/notifications/{token}` → `notifications/{token}`).
|
|
212
|
-
|
|
213
|
-
### Changed
|
|
214
|
-
- Refactored `_saveSubscription` to use internal Firestore wrapper instead of direct Firebase imports.
|
|
215
|
-
|
|
216
|
-
## [4.0.28] - 2025-12-01
|
|
217
|
-
### Added
|
|
218
|
-
- Added `exports` field to package.json for explicit module resolution support.
|
|
219
|
-
|
|
220
|
-
### Changed
|
|
221
|
-
- Updated `@sentry/browser` from pinned `10.11.0` to `^10.27.0`.
|
|
222
|
-
- Updated `firebase` from `^12.3.0` to `^12.6.0`.
|
|
223
|
-
- Updated `prepare-package` dev dependency from `^1.2.2` to `^1.2.5`.
|
|
224
|
-
|
|
225
|
-
## [4.0.0] - 2025-09-11
|
|
226
|
-
### ⚠️ BREAKING
|
|
227
|
-
- Updated to ITW 3.0 standard.
|
|
228
|
-
|
|
229
|
-
### Added
|
|
230
|
-
- Updated `@sentry/browser` to `10.11.0` to avoid breaking changes in `10.12.0` that affect Ultimate-Jekyll.
|
|
231
|
-
> When installing from NPM:
|
|
232
|
-
> lighthouse → @sentry/node@9.46.0 → @sentry/core@9.46.0
|
|
233
|
-
> web-manager → @sentry/browser@10.15.0 → expects
|
|
234
|
-
> @sentry/core@10.15.0
|
|
235
|
-
|
|
236
|
-
## [3.2.74] - 2025-07-17
|
|
237
|
-
### Added
|
|
238
|
-
- Now looks for `build.json` in the `/@output/build/` directory to ensure it works with Vite's output structure.
|
|
239
|
-
|
|
240
|
-
## [1.0.0] - 2024-06-19
|
|
241
|
-
### Added
|
|
242
|
-
- Initial release of the project 🚀
|
package/TODO.md
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
RADOM
|
|
2
|
-
Remove this remove this eventually once we test the VAPDI push notificationx issue
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const tokenOptions = { serviceWorkerRegistration: swRegistration };
|
|
6
|
-
if (this._vapidKey) { tokenOptions.vapidKey = this._vapidKey; }
|
|
7
|
-
return await getToken(messaging, tokenOptions);
|
|
8
|
-
|
|
9
|
-
Do we need to use polyfill? the project that consumes this is using webpack and compiles to es5. we need to ensure we have
|
|
10
|
-
- fetch api
|
|
11
|
-
- promises
|
|
12
|
-
- async
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Eventually update auth.js to have an intelligent schema for user object
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
UTM management
|
|
19
|
-
|
|
20
|
-
LOCALSTORAGE
|
|
21
|
-
|
|
22
|
-
WRAPPERS FOR COMMON FUNCITONS LIKE FIRESTORE DOC READ and QUERY AND WRITE
|
|
23
|
-
|
|
24
|
-
// Chrome extension Sentry integration
|
|
25
|
-
// Extract only the functions we need (enables tree-shaking)
|
|
26
|
-
// This is REQUIRED for browser extensions to avoid bundling the entire Sentry SDK
|
|
27
|
-
// https://github.com/getsentry/sentry-javascript/issues/14010
|
|
28
|
-
const {
|
|
29
|
-
init,
|
|
30
|
-
captureException,
|
|
31
|
-
browserTracingIntegration,
|
|
32
|
-
replayIntegration,
|
|
33
|
-
browserApiErrorsIntegration,
|
|
34
|
-
breadcrumbsIntegration,
|
|
35
|
-
globalHandlersIntegration,
|
|
36
|
-
} = module;
|
|
37
|
-
|
|
38
|
-
// Store references
|
|
39
|
-
this.Sentry = {
|
|
40
|
-
init,
|
|
41
|
-
captureException,
|
|
42
|
-
browserTracingIntegration,
|
|
43
|
-
replayIntegration,
|
|
44
|
-
browserApiErrorsIntegration,
|
|
45
|
-
breadcrumbsIntegration,
|
|
46
|
-
globalHandlersIntegration,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// Expose limited API globally (only what's needed)
|
|
50
|
-
window.Sentry = this.Sentry;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
what if in web-manager we put a special thing like
|
|
54
|
-
|
|
55
|
-
// Precedence: passed environment > query string > config.environment
|
|
56
|
-
const searchParams = new URLSearchParams(window.location.search);
|
|
57
|
-
const queryEnv = searchParams.get('_dev_loudLogs');
|
|
58
|
-
|
|
59
|
-
and this will set a property of webManager to true that enables copious logs
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*/
|
|
3
|
-
var dom;
|
|
4
|
-
|
|
5
|
-
function AuthPages() {
|
|
6
|
-
var self = this;
|
|
7
|
-
dom = window.Manager.dom();
|
|
8
|
-
var pageQueryString = window.Manager.properties.page.queryString;
|
|
9
|
-
|
|
10
|
-
dom.select('a[href*=signin], a[href*=signup], a[href*=forgot]').each(function (el) {
|
|
11
|
-
var href = el.getAttribute('href');
|
|
12
|
-
try {
|
|
13
|
-
var newURL = new URL(href);
|
|
14
|
-
pageQueryString.forEach(function(value, key) {
|
|
15
|
-
newURL.searchParams.set(key, value)
|
|
16
|
-
})
|
|
17
|
-
el.setAttribute('href', newURL.toString())
|
|
18
|
-
} catch (e) {
|
|
19
|
-
console.warn('Failed to set auth URL', e);
|
|
20
|
-
}
|
|
21
|
-
})
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
module.exports = AuthPages;
|