@nommos/core 0.0.40 → 0.0.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -120,6 +120,7 @@ Represents the platform (Social Media, SMS or direct access) the user used to ha
120
120
  interface ConnectionConfig {
121
121
  token: string;
122
122
  mode: string;
123
+ baseUrl?: string;
123
124
  }
124
125
  ```
125
126
  #### Description
@@ -129,7 +130,12 @@ An Interface representing the required information for initializing the tracking
129
130
  | Field | type | Description |
130
131
  |--------|-------|-------------|
131
132
  | `token` | `string` | The access token for fetching configuration |
132
- | `mode` | `string` | Run tracking module in 'dev' or 'prod' mode |
133
+ | `mode` | `string` | Which stack to talk to, and how loudly to log. `'dev'` targets the test backend and enables console diagnostics; anything else targets production and stays silent. |
134
+ | `baseUrl` | `string?` | Overrides the backend URL `mode` would select. For local or self-hosted deployments only. |
135
+
136
+ > **Tokens are issued per environment.** The test and production stacks have separate databases,
137
+ > so a token minted on one is not valid on the other — `mode` must match wherever the token came
138
+ > from. An unrecognised `mode` falls back to production rather than failing closed.
133
139
  ---
134
140
 
135
141
  ### `Interface: UrlTrackingKey`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nommos/core",
3
- "version": "0.0.40",
3
+ "version": "0.0.42",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "module": "./src/index.js",
@@ -20,4 +20,4 @@
20
20
  "devDependencies": {
21
21
  "@types/pako": "^2.0.4"
22
22
  }
23
- }
23
+ }
package/src/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { EventTracker } from './lib/event-tracker';
2
2
  export { ANALYTICS_ACTION, ANALYTICS_ACTION_STATE, SITE_SOURCE, } from './lib/enums';
3
- export type { ConnectionConfig, UrlTrackingKey, AnalyticsEvent, TrackingControls, AdsEventsConfig, AdEventConfig, GoogleAdsConfig, GoogleConversionAction, } from './lib/types';
3
+ export type { ConnectionConfig, UrlTrackingKey, AnalyticsEvent, TrackingControls, AdsEventsConfig, AdEventConfig, GoogleAdsConfig, GoogleConversionAction, ConsentConfig, ConsentPermission, ConsentPermissionState, ConsentStoredState, ConsentAwareModule, WebPopupItem, WebPopupButton, WebPopupContent, WebPopupInboxState, } from './lib/types';
@@ -0,0 +1,136 @@
1
+ import { ConsentStoredState, OptionalConsentCategory } from './types';
2
+ type RenderableCategory = 'necessary' | OptionalConsentCategory;
3
+ interface ConsentManagerCallbacks {
4
+ onConsentProof: (state: ConsentStoredState | null) => void;
5
+ onAnalyticsGranted: () => void;
6
+ onAnalyticsRevoked: () => void;
7
+ onSessionRecordingGranted: () => void;
8
+ onSessionRecordingRevoked: () => void;
9
+ onMarketingGranted: () => void;
10
+ onMarketingRevoked: () => void;
11
+ }
12
+ declare global {
13
+ interface Window {
14
+ NommosConsent?: {
15
+ openPreferences: () => void;
16
+ getState: () => ConsentStoredState | null;
17
+ };
18
+ }
19
+ interface Navigator {
20
+ globalPrivacyControl?: boolean;
21
+ }
22
+ }
23
+ export declare class ConsentManager {
24
+ private readonly siteKey;
25
+ private readonly subjectId;
26
+ private readonly cmpEndpoint;
27
+ private readonly callbacks;
28
+ private cmpConfig;
29
+ private currentState;
30
+ private root;
31
+ private toast;
32
+ private summary;
33
+ private readonly storageKey;
34
+ private readonly cookieName;
35
+ private readonly channel;
36
+ private readonly storageListener;
37
+ private draft;
38
+ constructor(siteKey: string, subjectId: string, cmpEndpoint: string, callbacks: ConsentManagerCallbacks);
39
+ init(): Promise<void>;
40
+ openPreferences(): void;
41
+ /** True when a stored decision carries an expiry that has passed. */
42
+ private isExpired;
43
+ getState(): ConsentStoredState | null;
44
+ destroy(): void;
45
+ private fetchConfig;
46
+ private saveConsent;
47
+ private applyConsent;
48
+ private applyOptionalPermissions;
49
+ private loadStoredConsent;
50
+ private persistConsent;
51
+ private broadcastState;
52
+ private handleExternalState;
53
+ private renderBanner;
54
+ private renderPreferencePanel;
55
+ private renderReconsent;
56
+ private renderFloatingControl;
57
+ private renderSummaryBar;
58
+ private renderPersistentPrivacyControl;
59
+ private showToast;
60
+ private bindCommonActions;
61
+ private bindToggles;
62
+ /**
63
+ * Every category, in display order. The backend's per-category `enabled` flag is a tenant
64
+ * activation setting — whether that consent, once granted, is actually stored and enforced —
65
+ * not a UI visibility switch. A visitor can express a preference for a category the tenant
66
+ * hasn't activated yet; the backend clamps the *effect* of that preference independently.
67
+ */
68
+ private enabledCategories;
69
+ /**
70
+ * Whether the tenant has switched this category on — the other half of the server's rule that a
71
+ * permission needs both tenant activation and a visitor grant.
72
+ *
73
+ * <p>Deliberately not used to filter {@link enabledCategories}: a visitor may still express a
74
+ * preference for a category the tenant has not activated. It exists for callers that would
75
+ * otherwise ask the server for something it is certain to refuse with `FEATURE_DISABLED`.
76
+ */
77
+ isCategoryActivated(category: RenderableCategory): boolean;
78
+ private preferenceRow;
79
+ private permissionChip;
80
+ private createRoot;
81
+ /**
82
+ * Run after any innerHTML assignment on the root: replaces logo placeholders with elements
83
+ * built via DOM APIs, so tenant-supplied branding never passes through markup parsing.
84
+ */
85
+ private finalizeRoot;
86
+ private closeRoot;
87
+ private installGlobalApi;
88
+ /** A Global Privacy Control signal only forces Marketing off; other opt-out categories stay user-controlled. */
89
+ private applyGlobalPrivacyControl;
90
+ private hasGlobalPrivacyControl;
91
+ private shouldShowPersistentPrivacyControl;
92
+ /**
93
+ * The raw configured value. Only for callers that sanitise it themselves — everything that
94
+ * lands in markup must go through {@link text} or {@link url} instead.
95
+ */
96
+ private rawText;
97
+ /**
98
+ * Content escaped for interpolation into markup.
99
+ *
100
+ * Escaping here rather than at each of the ~40 call sites means a newly added string is safe
101
+ * by default; the unsafe path has to be asked for explicitly.
102
+ */
103
+ private text;
104
+ /** Content sanitised for use in `href`/`src`. Returns '' when the URL is not safe. */
105
+ private url;
106
+ private language;
107
+ /**
108
+ * Built with DOM APIs rather than interpolated markup: `logoUrl` and `companyName` come from
109
+ * tenant configuration, and this renders on the tenant's own customers' pages.
110
+ */
111
+ private logoElement;
112
+ /** Placeholder replaced with {@link logoElement} after the markup is parsed. */
113
+ private logoBlock;
114
+ /** Swaps every logo placeholder for a safely constructed element. */
115
+ private hydrateLogos;
116
+ private floatingHtml;
117
+ private policyLinks;
118
+ private configUrl;
119
+ private poweredBy;
120
+ private categoryName;
121
+ private categoryDescription;
122
+ private categoryIcon;
123
+ private storageSafeKey;
124
+ private iconShield;
125
+ private iconScreen;
126
+ private iconMegaphone;
127
+ private iconBars;
128
+ private iconCheck;
129
+ private iconX;
130
+ private iconGear;
131
+ private iconLock;
132
+ private iconCheckCircle;
133
+ private iconMinusCircle;
134
+ private injectStyles;
135
+ }
136
+ export {};